comparison finch/libgnt/gntmenu.c @ 15818:0e3a8505ebbe

renamed gaim-text to finch
author Sean Egan <seanegan@gmail.com>
date Sun, 18 Mar 2007 19:38:15 +0000
parents
children f00f2e283ffb
comparison
equal deleted inserted replaced
15817:317e7613e581 15818:0e3a8505ebbe
1 #include "gntmenu.h"
2 #include "gntmenuitemcheck.h"
3
4 #include <string.h>
5
6 enum
7 {
8 SIGS = 1,
9 };
10
11 static GntTreeClass *parent_class = NULL;
12
13 static void (*org_draw)(GntWidget *wid);
14 static void (*org_destroy)(GntWidget *wid);
15 static void (*org_map)(GntWidget *wid);
16 static gboolean (*org_key_pressed)(GntWidget *w, const char *t);
17
18 static void
19 gnt_menu_draw(GntWidget *widget)
20 {
21 GntMenu *menu = GNT_MENU(widget);
22 GList *iter;
23 chtype type;
24 int i;
25
26 if (menu->type == GNT_MENU_TOPLEVEL) {
27 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT));
28 werase(widget->window);
29
30 for (i = 0, iter = menu->list; iter; iter = iter->next, i++) {
31 GntMenuItem *item = GNT_MENUITEM(iter->data);
32 type = ' ' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT);
33 if (i == menu->selected)
34 type |= A_REVERSE;
35 item->priv.x = getcurx(widget->window) + widget->priv.x;
36 item->priv.y = getcury(widget->window) + widget->priv.y + 1;
37 wbkgdset(widget->window, type);
38 wprintw(widget->window, " %s ", item->text);
39 }
40 } else {
41 org_draw(widget);
42 }
43
44 GNTDEBUG;
45 }
46
47 static void
48 gnt_menu_size_request(GntWidget *widget)
49 {
50 GntMenu *menu = GNT_MENU(widget);
51
52 if (menu->type == GNT_MENU_TOPLEVEL) {
53 widget->priv.height = 1;
54 widget->priv.width = getmaxx(stdscr);
55 } else {
56 widget->priv.height = g_list_length(menu->list) + 2;
57 widget->priv.width = 25; /* XXX: */
58 }
59 }
60
61 static void
62 menu_tree_add(GntMenu *menu, GntMenuItem *item, GntMenuItem *parent)
63 {
64 if (GNT_IS_MENUITEM_CHECK(item)) {
65 gnt_tree_add_choice(GNT_TREE(menu), item,
66 gnt_tree_create_row(GNT_TREE(menu), item->text, " "), parent, NULL);
67 gnt_tree_set_choice(GNT_TREE(menu), item, gnt_menuitem_check_get_checked(GNT_MENUITEM_CHECK(item)));
68 } else
69 gnt_tree_add_row_last(GNT_TREE(menu), item,
70 gnt_tree_create_row(GNT_TREE(menu), item->text, item->submenu ? ">" : " "), parent);
71
72 if (0 && item->submenu) {
73 GntMenu *sub = GNT_MENU(item->submenu);
74 GList *iter;
75 for (iter = sub->list; iter; iter = iter->next) {
76 GntMenuItem *it = GNT_MENUITEM(iter->data);
77 menu_tree_add(menu, it, item);
78 }
79 }
80 }
81
82 static void
83 gnt_menu_map(GntWidget *widget)
84 {
85 GntMenu *menu = GNT_MENU(widget);
86
87 if (menu->type == GNT_MENU_TOPLEVEL) {
88 gnt_widget_size_request(widget);
89 } else {
90 /* Populate the tree */
91 GList *iter;
92 gnt_tree_remove_all(GNT_TREE(widget));
93 for (iter = menu->list; iter; iter = iter->next) {
94 GntMenuItem *item = GNT_MENUITEM(iter->data);
95 menu_tree_add(menu, item, NULL);
96 }
97 org_map(widget);
98 gnt_tree_adjust_columns(GNT_TREE(widget));
99 }
100 GNTDEBUG;
101 }
102
103 static void
104 menuitem_activate(GntMenu *menu, GntMenuItem *item)
105 {
106 if (item) {
107 if (item->submenu) {
108 GntMenu *sub = GNT_MENU(item->submenu);
109 menu->submenu = sub;
110 sub->type = GNT_MENU_POPUP; /* Submenus are *never* toplevel */
111 sub->parentmenu = menu;
112 if (menu->type != GNT_MENU_TOPLEVEL) {
113 GntWidget *widget = GNT_WIDGET(menu);
114 item->priv.x = widget->priv.x + widget->priv.width - 1;
115 item->priv.y = widget->priv.y + gnt_tree_get_selection_visible_line(GNT_TREE(menu));
116 }
117 gnt_widget_set_position(GNT_WIDGET(sub), item->priv.x, item->priv.y);
118 GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(sub), GNT_WIDGET_INVISIBLE);
119 gnt_widget_draw(GNT_WIDGET(sub));
120 } else if (item->callback) {
121 item->callback(item, item->callbackdata);
122 while (menu) {
123 gnt_widget_hide(GNT_WIDGET(menu));
124 menu = menu->parentmenu;
125 }
126 }
127 }
128 }
129
130 static gboolean
131 gnt_menu_key_pressed(GntWidget *widget, const char *text)
132 {
133 GntMenu *menu = GNT_MENU(widget);
134 int current = menu->selected;
135
136 if (menu->submenu) {
137 do menu = menu->submenu; while (menu->submenu);
138 return (gnt_widget_key_pressed(GNT_WIDGET(menu), text));
139 }
140
141 if (text[0] == 27 && text[1] == 0) {
142 /* Escape closes menu */
143 GntMenu *par = menu->parentmenu;
144 if (par != NULL) {
145 par->submenu = NULL;
146 gnt_widget_hide(widget);
147 } else
148 gnt_widget_hide(widget);
149 return TRUE;
150 }
151
152 if (menu->type == GNT_MENU_TOPLEVEL) {
153 if (strcmp(text, GNT_KEY_LEFT) == 0) {
154 menu->selected--;
155 if (menu->selected < 0)
156 menu->selected = g_list_length(menu->list) - 1;
157 } else if (strcmp(text, GNT_KEY_RIGHT) == 0) {
158 menu->selected++;
159 if (menu->selected >= g_list_length(menu->list))
160 menu->selected = 0;
161 } else if (strcmp(text, GNT_KEY_ENTER) == 0) {
162 gnt_widget_activate(widget);
163 }
164
165 if (current != menu->selected) {
166 gnt_widget_draw(widget);
167 return TRUE;
168 }
169 } else {
170 return org_key_pressed(widget, text);
171 }
172
173 return FALSE;
174 }
175
176 static void
177 gnt_menu_destroy(GntWidget *widget)
178 {
179 GntMenu *menu = GNT_MENU(widget);
180 g_list_foreach(menu->list, (GFunc)g_object_unref, NULL);
181 g_list_free(menu->list);
182 org_destroy(widget);
183 }
184
185 static void
186 gnt_menu_toggled(GntTree *tree, gpointer key)
187 {
188 GntMenuItem *item = GNT_MENUITEM(key);
189 GntMenu *menu = GNT_MENU(tree);
190 gboolean check = gnt_menuitem_check_get_checked(GNT_MENUITEM_CHECK(item));
191 gnt_menuitem_check_set_checked(GNT_MENUITEM_CHECK(item), !check);
192 if (item->callback)
193 item->callback(item, item->callbackdata);
194 while (menu) {
195 gnt_widget_hide(GNT_WIDGET(menu));
196 menu = menu->parentmenu;
197 }
198 }
199
200 static void
201 gnt_menu_activate(GntWidget *widget)
202 {
203 GntMenu *menu = GNT_MENU(widget);
204 GntMenuItem *item;
205
206 if (menu->type == GNT_MENU_TOPLEVEL) {
207 item = g_list_nth_data(menu->list, menu->selected);
208 } else {
209 item = gnt_tree_get_selection_data(GNT_TREE(menu));
210 }
211
212 if (item) {
213 if (GNT_IS_MENUITEM_CHECK(item))
214 gnt_menu_toggled(GNT_TREE(widget), item);
215 else
216 menuitem_activate(menu, item);
217 }
218 }
219
220 static void
221 gnt_menu_hide(GntWidget *widget)
222 {
223 GntMenu *menu = GNT_MENU(widget);
224 if (menu->parentmenu)
225 menu->parentmenu->submenu = NULL;
226 }
227
228 static void
229 gnt_menu_class_init(GntMenuClass *klass)
230 {
231 GntWidgetClass *wid_class = GNT_WIDGET_CLASS(klass);
232 parent_class = GNT_TREE_CLASS(klass);
233
234 org_destroy = wid_class->destroy;
235 org_map = wid_class->map;
236 org_draw = wid_class->draw;
237 org_key_pressed = wid_class->key_pressed;
238
239 wid_class->destroy = gnt_menu_destroy;
240 wid_class->draw = gnt_menu_draw;
241 wid_class->map = gnt_menu_map;
242 wid_class->size_request = gnt_menu_size_request;
243 wid_class->key_pressed = gnt_menu_key_pressed;
244 wid_class->activate = gnt_menu_activate;
245 wid_class->hide = gnt_menu_hide;
246
247 parent_class->toggled = gnt_menu_toggled;
248
249 GNTDEBUG;
250 }
251
252 static void
253 gnt_menu_init(GTypeInstance *instance, gpointer class)
254 {
255 GntWidget *widget = GNT_WIDGET(instance);
256 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER |
257 GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_TRANSIENT);
258 GNTDEBUG;
259 }
260
261 /******************************************************************************
262 * GntMenu API
263 *****************************************************************************/
264 GType
265 gnt_menu_get_gtype(void)
266 {
267 static GType type = 0;
268
269 if(type == 0)
270 {
271 static const GTypeInfo info = {
272 sizeof(GntMenuClass),
273 NULL, /* base_init */
274 NULL, /* base_finalize */
275 (GClassInitFunc)gnt_menu_class_init,
276 NULL, /* class_finalize */
277 NULL, /* class_data */
278 sizeof(GntMenu),
279 0, /* n_preallocs */
280 gnt_menu_init, /* instance_init */
281 NULL /* value_table */
282 };
283
284 type = g_type_register_static(GNT_TYPE_TREE,
285 "GntMenu",
286 &info, 0);
287 }
288
289 return type;
290 }
291
292 GntWidget *gnt_menu_new(GntMenuType type)
293 {
294 GntWidget *widget = g_object_new(GNT_TYPE_MENU, NULL);
295 GntMenu *menu = GNT_MENU(widget);
296 menu->list = NULL;
297 menu->selected = 0;
298 menu->type = type;
299
300 if (type == GNT_MENU_TOPLEVEL) {
301 widget->priv.x = 0;
302 widget->priv.y = 0;
303 } else {
304 GNT_TREE(widget)->show_separator = FALSE;
305 _gnt_tree_init_internals(GNT_TREE(widget), 2);
306 gnt_tree_set_col_width(GNT_TREE(widget), 1, 1); /* The second column is to indicate that it has a submenu */
307 GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER);
308 }
309
310 return widget;
311 }
312
313 void gnt_menu_add_item(GntMenu *menu, GntMenuItem *item)
314 {
315 menu->list = g_list_append(menu->list, item);
316 }
317