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