ui/gtk/menu.c

changeset 0
1f419bd32da1
child 2
eeb50c534497
equal deleted inserted replaced
-1:000000000000 0:1f419bd32da1
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2014 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "menu.h"
33 #include "toolkit.h"
34 #include "../common/context.h"
35 #include "../ui/window.h"
36
37 UcxList *menus;
38 UcxList *current;
39
40 void ui_menu(char *label) {
41 // free current menu hierarchy
42 ucx_list_free(current);
43
44 // create menu
45 UiMenu *menu = malloc(sizeof(UiMenu));
46 menu->item.add_to = (ui_menu_add_f)add_menu_widget;
47
48 menu->label = label;
49 menu->items = NULL;
50 menu->parent = NULL;
51
52 current = ucx_list_prepend(NULL, menu);
53 menus = ucx_list_append(menus, menu);
54
55 }
56
57 void ui_submenu(char *label) {
58 UiMenu *menu = malloc(sizeof(UiMenu));
59 menu->item.add_to = (ui_menu_add_f)add_menu_widget;
60
61 menu->label = label;
62 menu->items = NULL;
63 menu->parent = NULL;
64
65 // add submenu to current menu
66 UiMenu *cm = current->data;
67 cm->items = ucx_list_append(cm->items, menu);
68
69 // set the submenu to current menu
70 current = ucx_list_prepend(current, menu);
71 }
72
73 void ui_submenu_end() {
74 if(ucx_list_size(current) < 2) {
75 return;
76 }
77 current = ucx_list_remove(current, current);
78 UcxList *c = current;
79 }
80
81 void ui_menuitem(char *label, ui_callback f, void *userdata) {
82 if(!current) {
83 return;
84 }
85
86 UiMenuItem *item = malloc(sizeof(UiMenuItem));
87 item->item.add_to = (ui_menu_add_f)add_menuitem_widget;
88
89 item->label = label;
90 item->userdata = userdata;
91 item->callback = f;
92
93 UiMenu *cm = current->data;
94 cm->items = ucx_list_append(cm->items, item);
95 }
96
97 void ui_menuseparator() {
98 if(!current) {
99 return;
100 }
101
102 UiMenuItemI *item = malloc(sizeof(UiMenuItemI));
103 item->add_to = (ui_menu_add_f)add_menuseparator_widget;
104
105 UiMenu *cm = current->data;
106 cm->items = ucx_list_append(cm->items, item);
107 }
108
109 void ui_checkitem(char *label, ui_callback f, void *userdata) {
110 if(!current) {
111 return;
112 }
113
114 UiCheckItem *item = malloc(sizeof(UiCheckItem));
115 item->item.add_to = (ui_menu_add_f)add_checkitem_widget;
116 item->label = label;
117 item->callback = f;
118 item->userdata = userdata;
119
120 UiMenu *cm = current->data;
121 cm->items = ucx_list_append(cm->items, item);
122 }
123
124 void ui_checkitem_nv(char *label, char *vname) {
125 if(!current) {
126 return;
127 }
128
129 UiCheckItemNV *item = malloc(sizeof(UiCheckItemNV));
130 item->item.add_to = (ui_menu_add_f)add_checkitemnv_widget;
131 item->varname = vname;
132 item->label = label;
133
134 UiMenu *cm = current->data;
135 cm->items = ucx_list_append(cm->items, item);
136 }
137
138 // private menu functions
139 GtkWidget *ui_create_menubar(UiObject *obj) {
140 if(menus == NULL) {
141 return NULL;
142 }
143
144 GtkWidget *mb = gtk_menu_bar_new();
145
146 UcxList *ls = menus;
147 while(ls) {
148 UiMenu *menu = ls->data;
149 menu->item.add_to(mb, &menu->item, obj);
150
151 ls = ls->next;
152 }
153
154 return mb;
155 }
156
157 void add_menu_widget(GtkWidget *parent, UiMenuItemI *item, UiObject *obj) {
158 UiMenu *menu = (UiMenu*)item;
159
160 GtkWidget *menu_widget = gtk_menu_new();
161 GtkWidget *menu_item = gtk_menu_item_new_with_label(menu->label);
162 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu_widget);
163
164 UcxList *ls = menu->items;
165 while(ls) {
166 UiMenuItemI *i = ls->data;
167 i->add_to(menu_widget, i, obj);
168
169 ls = ls->next;
170 }
171
172 gtk_menu_shell_append(GTK_MENU_SHELL(parent), menu_item);
173 }
174
175 void add_menuitem_widget(GtkWidget *parent, UiMenuItemI *item, UiObject *obj) {
176 UiMenuItem *i = (UiMenuItem*)item;
177
178 //GtkWidget *widget = gtk_menu_item_new_with_label(i->title);
179 GtkWidget *widget = gtk_menu_item_new_with_mnemonic(i->label);
180
181 if(i->callback != NULL) {
182 UiEventData *event = malloc(sizeof(UiEventData));
183 event->obj = obj;
184 event->user_data = i->userdata;
185 event->callback = i->callback;
186
187 g_signal_connect(
188 widget,
189 "activate",
190 G_CALLBACK(ui_menu_event_wrapper),
191 event);
192 }
193
194 gtk_menu_shell_append(GTK_MENU_SHELL(parent), widget);
195 }
196
197 void add_menuitem_st_widget(
198 GtkWidget *parent,
199 UiMenuItemI *item,
200 UiObject *obj)
201 {
202 UiStMenuItem *i = (UiStMenuItem*)item;
203
204 GtkWidget *widget = gtk_image_menu_item_new_from_stock(i->stockid, NULL);
205
206 if(i->callback != NULL) {
207 UiEventData *event = malloc(sizeof(UiEventData));
208 event->obj = obj;
209 event->user_data = i->userdata;
210 event->callback = i->callback;
211
212 g_signal_connect(
213 widget,
214 "activate",
215 G_CALLBACK(ui_menu_event_wrapper),
216 event);
217 }
218
219 gtk_menu_shell_append(GTK_MENU_SHELL(parent), widget);
220 }
221
222 void add_menuseparator_widget(
223 GtkWidget *parent,
224 UiMenuItemI *item,
225 UiObject *obj)
226 {
227 gtk_menu_shell_append(
228 GTK_MENU_SHELL(parent),
229 gtk_separator_menu_item_new());
230 }
231
232 void add_checkitem_widget(GtkWidget *p, UiMenuItemI *item, UiObject *obj) {
233 UiCheckItem *ci = (UiCheckItem*)item;
234 GtkWidget *widget = gtk_check_menu_item_new_with_mnemonic(ci->label);
235 gtk_menu_shell_append(GTK_MENU_SHELL(p), widget);
236
237 if(ci->callback) {
238 UiEventData *event = malloc(sizeof(UiEventData));
239 event->obj = obj;
240 event->user_data = ci->userdata;
241 event->callback = ci->callback;
242
243 g_signal_connect(
244 widget,
245 "toggled",
246 G_CALLBACK(ui_menu_event_toggled),
247 event);
248 }
249 }
250
251 void add_checkitemnv_widget(GtkWidget *p, UiMenuItemI *item, UiObject *obj) {
252 UiCheckItemNV *ci = (UiCheckItemNV*)item;
253 GtkWidget *widget = gtk_check_menu_item_new_with_mnemonic(ci->label);
254 gtk_menu_shell_append(GTK_MENU_SHELL(p), widget);
255
256 UiVar *var = uic_getvar(obj, ci->varname);
257 if(!var) {
258 ui_window_addint(obj, ci->varname);
259 var = uic_getvar(obj, ci->varname);
260 }
261 if(var->type == 1) {
262 UiInteger *value = var->value;
263 value->obj = widget;
264 value->get = ui_checkitem_get;
265 value->set = ui_checkitem_set;
266 value = 0;
267 } else {
268 // TODO: error message
269 }
270 }
271
272
273
274 void ui_menu_event_wrapper(GtkMenuItem *item, UiEventData *event) {
275 UiEvent evt;
276 evt.obj = event->obj;
277 evt.window = event->obj->window;
278 evt.document = NULL;
279 evt.intval = 0;
280 event->callback(&evt, event->user_data);
281 }
282
283 void ui_menu_event_toggled(GtkCheckMenuItem *ci, UiEventData *event) {
284 UiEvent evt;
285 evt.obj = event->obj;
286 evt.window = event->obj->window;
287 evt.document = NULL;
288 evt.intval = gtk_check_menu_item_get_active(ci);
289 event->callback(&evt, event->user_data);
290 }
291
292 int ui_checkitem_get(UiInteger *i) {
293 int state = gtk_check_menu_item_get_active(i->obj);
294 i->value = state;
295 return state;
296 }
297
298 void ui_checkitem_set(UiInteger *i, int value) {
299 i->value = value;
300 gtk_check_menu_item_set_active(i->obj, value);
301 }

mercurial