move the keyboard and mouse plugins into the kernel for mucho sexiness.
[dana/openbox.git] / openbox / menu.h
1 #ifndef __menu_h
2 #define __menu_h
3
4 #include "action.h"
5 #include "window.h"
6 #include "render/render.h"
7 #include "geom.h"
8
9 #include <glib.h>
10
11 struct _ObClient;
12
13 typedef struct _ObMenu ObMenu;
14 typedef struct _ObMenuEntry ObMenuEntry;
15
16 typedef void(*menu_controller_show)(ObMenu *self, int x, int y,
17                                     struct _ObClient *);
18 typedef void(*menu_controller_update)(ObMenu *self);
19 typedef void(*menu_controller_mouseover)(ObMenuEntry *self, gboolean enter);
20 typedef void(*menu_controller_selected)(ObMenuEntry *entry,
21                                         unsigned int button,
22                                         unsigned int x, unsigned int y);
23 typedef void(*menu_controller_hide)(ObMenu *self);
24
25
26 extern GHashTable *menu_hash;
27 extern GList *menu_visible;
28
29 struct _ObMenu
30 {
31     ObWindow obwin;
32
33     /* The title displayed above the menu.
34        NULL for no titlebar */
35     gchar *label;
36
37     /* Name of the menu.
38        Used in the action showmenu */
39     gchar *name;
40
41     /* ObMenuEntry list */
42     GList *entries;
43
44     /* If the menu is currently displayed */
45     gboolean shown;
46
47     /* If the rendering of the menu has changed and needs to be rerendered. */
48     gboolean invalid;
49
50     /* Kind of lame.Each menu can only be a submenu, and each menu can only
51        have one submenu open */
52     ObMenu *parent;
53     ObMenu *open_submenu;
54     GList *over;
55     
56     /* behaviour callbacks
57        TODO: Document and split code that HAS to be in the overridden callback */
58     /* place a menu on screen */
59     menu_controller_show show;
60     /* Hide the menu */
61     menu_controller_hide hide;
62     /* render a menu */
63     menu_controller_update update;
64     /* Event for a mouse enter/exit on an entry
65        TODO: May have to split from simple render updating?
66     */
67     menu_controller_mouseover mouseover;
68     /* Entry is clicked/hit enter on */
69     menu_controller_selected selected;
70
71
72     /* render stuff */
73     struct _ObClient *client;
74     Window frame;
75     Window title;
76     RrAppearance *a_title;
77     gint title_min_w, title_h;
78     Window items;
79     RrAppearance *a_items;
80     gint bullet_w;
81     gint item_h;
82     Point location;
83     Size size;
84     guint xin_area; /* index of the xinerama head/area */
85
86     /* Name of plugin for menu */
87     char *plugin;
88     /* plugin's data */
89     void *plugin_data;
90 };
91
92 typedef enum
93 {
94     OB_MENU_ENTRY_RENDER_TYPE_NONE,
95     OB_MENU_ENTRY_RENDER_TYPE_SUBMENU,
96     OB_MENU_ENTRY_RENDER_TYPE_BOOLEAN,
97     OB_MENU_ENTRY_RENDER_TYPE_SEPARATOR,
98     OB_MENU_ENTRY_RENDER_TYPE_OTHER /* XXX what is this? */
99 } ObMenuEntryRenderType;
100
101 struct _ObMenuEntry
102 {
103     char *label;
104     ObMenu *parent;
105
106     ObAction *action;    
107     
108     ObMenuEntryRenderType render_type;
109     gboolean hilite;
110     gboolean enabled;
111     gboolean boolean_value;
112
113     ObMenu *submenu;
114
115     /* render stuff */
116     Window item;
117     Window submenu_pic;
118     
119     RrAppearance *a_item;
120     RrAppearance *a_disabled;
121     RrAppearance *a_hilite;
122     RrAppearance *a_submenu;
123     gint y;
124     gint min_w;
125 } MenuEntry;
126
127 typedef struct PluginMenuCreateData{
128     xmlDocPtr doc;
129     xmlNodePtr node;
130     ObMenu *parent;
131 } PluginMenuCreateData;
132
133
134 void menu_startup();
135 void menu_shutdown();
136
137 void menu_noop();
138
139 #define menu_new(l, n, p) \
140   menu_new_full(l, n, p, menu_show_full, menu_render, menu_entry_fire, \
141                 menu_hide, menu_control_mouseover)
142
143 ObMenu *menu_new_full(char *label, char *name, ObMenu *parent, 
144                       menu_controller_show show, menu_controller_update update,
145                       menu_controller_selected selected,
146                       menu_controller_hide hide,
147                       menu_controller_mouseover mouseover);
148
149 void menu_free(char *name);
150
151 void menu_show(char *name, int x, int y, struct _ObClient *client);
152 void menu_show_full(ObMenu *menu, int x, int y, struct _ObClient *client);
153
154 void menu_hide(ObMenu *self);
155
156 void menu_clear(ObMenu *self);
157
158 ObMenuEntry *menu_entry_new_full(char *label, ObAction *action,
159                                ObMenuEntryRenderType render_type,
160                                gpointer submenu);
161
162 #define menu_entry_new(label, action) \
163 menu_entry_new_full(label, action, OB_MENU_ENTRY_RENDER_TYPE_NONE, NULL)
164
165 #define menu_entry_new_separator(label) \
166 menu_entry_new_full(label, NULL, OB_MENU_ENTRY_RENDER_TYPE_SEPARATOR, NULL)
167
168 #define menu_entry_new_submenu(label, submenu) \
169 menu_entry_new_full(label, NULL, OB_MENU_ENTRY_RENDER_TYPE_SUBMENU, submenu)
170
171 #define menu_entry_new_boolean(label, action) \
172 menu_entry_new_full(label, action, OB_MENU_ENTRY_RENDER_TYPE_BOOLEAN, NULL)
173
174 void menu_entry_free(ObMenuEntry *entry);
175
176 void menu_entry_set_submenu(ObMenuEntry *entry, ObMenu *submenu);
177
178 void menu_add_entry(ObMenu *menu, ObMenuEntry *entry);
179
180 ObMenuEntry *menu_find_entry(ObMenu *menu, Window win);
181 ObMenuEntry *menu_find_entry_by_submenu(ObMenu *menu, ObMenu *submenu);
182 ObMenuEntry *menu_find_entry_by_pos(ObMenu *menu, int x, int y);
183
184 void menu_entry_render(ObMenuEntry *self);
185
186 void menu_entry_fire(ObMenuEntry *entry,
187                      unsigned int button, unsigned int x, unsigned int y);
188
189 void menu_render(ObMenu *self);
190 void menu_render_full(ObMenu *self);
191
192 /*so plugins can call it? */
193 void parse_menu_full(xmlDocPtr doc, xmlNodePtr node, void *data, gboolean new);
194 void menu_control_mouseover(ObMenuEntry *entry, gboolean enter);
195 void menu_control_keyboard_nav(unsigned int key);
196 #endif