29 #include <stdio.h> |
29 #include <stdio.h> |
30 #include <stdlib.h> |
30 #include <stdlib.h> |
31 #include <string.h> |
31 #include <string.h> |
32 |
32 |
33 #include "toolbar.h" |
33 #include "toolbar.h" |
|
34 #include "menu.h" |
34 #include "button.h" |
35 #include "button.h" |
35 #include "image.h" |
36 #include "image.h" |
36 #include "tree.h" |
37 #include "tree.h" |
37 #include <cx/mempool.h> |
38 #include <cx/mempool.h> |
38 #include <cx/hash_map.h> |
39 #include <cx/hash_map.h> |
39 #include <cx/linked_list.h> |
40 #include <cx/linked_list.h> |
40 #include <cx/array_list.h> |
41 #include <cx/array_list.h> |
41 #include "../common/context.h" |
42 #include "../common/context.h" |
42 |
43 |
43 static CxMap *toolbar_items; |
|
44 static CxList *defaults; |
|
45 |
|
46 void ui_toolbar_init() { |
|
47 toolbar_items = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); |
|
48 defaults = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
|
49 } |
|
50 |
|
51 void ui_toolitem(char *name, char *label, ui_callback f, void *udata) { |
|
52 ui_toolitem_img(name, label, NULL, f, udata); |
|
53 } |
|
54 |
|
55 void ui_toolitem_st(char *name, char *stockid, ui_callback f, void *userdata) { |
|
56 ui_toolitem_stgr(name, stockid, f, userdata, -1); |
|
57 } |
|
58 |
|
59 void ui_toolitem_sti(char *name, char *stockid, ui_callback f, void *userdata) { |
|
60 ui_toolitem_stgri(name, stockid, f, userdata, -1); |
|
61 } |
|
62 |
|
63 void ui_toolitem_stgr(char *name, char *stockid, ui_callback f, void *userdata, ...) { |
|
64 va_list ap; |
|
65 va_start(ap, userdata); |
|
66 ui_toolitem_vstgr(name, stockid, 0, f, userdata, ap); |
|
67 va_end(ap); |
|
68 } |
|
69 |
|
70 void ui_toolitem_stgri(char *name, char *stockid, ui_callback f, void *userdata, ...) { |
|
71 va_list ap; |
|
72 va_start(ap, userdata); |
|
73 ui_toolitem_vstgr(name, stockid, 1, f, userdata, ap); |
|
74 va_end(ap); |
|
75 } |
|
76 |
|
77 void ui_toolitem_img(char *name, char *label, char *img, ui_callback f, void *udata) { |
|
78 UiToolItem *item = malloc(sizeof(UiToolItem)); |
|
79 item->item.add_to = (ui_toolbar_add_f)add_toolitem_widget; |
|
80 item->label = label; |
|
81 item->image = img; |
|
82 item->callback = f; |
|
83 item->userdata = udata; |
|
84 item->isimportant = 0; |
|
85 item->groups = NULL; |
|
86 |
|
87 cxMapPut(toolbar_items, name, item); |
|
88 } |
|
89 |
|
90 void ui_toolitem_vstgr( |
|
91 char *name, |
|
92 char *stockid, |
|
93 int isimportant, |
|
94 ui_callback f, |
|
95 void *userdata, |
|
96 va_list ap) |
|
97 { |
|
98 UiStToolItem *item = malloc(sizeof(UiStToolItem)); |
|
99 item->item.add_to = (ui_toolbar_add_f)add_toolitem_st_widget; |
|
100 item->stockid = stockid; |
|
101 item->callback = f; |
|
102 item->userdata = userdata; |
|
103 item->groups = NULL; |
|
104 item->isimportant = isimportant; |
|
105 |
|
106 // add groups |
|
107 int group; |
|
108 while((group = va_arg(ap, int)) != -1) { |
|
109 if(!item->groups) { |
|
110 item->groups = cxArrayListCreateSimple(sizeof(int), 16); |
|
111 } |
|
112 cxListAdd(item->groups, &group); |
|
113 } |
|
114 |
|
115 cxMapPut(toolbar_items, name, item); |
|
116 } |
|
117 |
|
118 void ui_toolitem_toggle(const char *name, const char *label, const char *img, UiInteger *i) { |
|
119 UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem)); |
|
120 item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget; |
|
121 item->label = label; |
|
122 item->image = img; |
|
123 item->stockid = NULL; |
|
124 item->groups = NULL; |
|
125 item->isimportant = 0; |
|
126 item->value = i; |
|
127 item->var = NULL; |
|
128 |
|
129 cxMapPut(toolbar_items, name, item); |
|
130 } |
|
131 |
|
132 void ui_toolitem_toggle_st(const char *name, const char *stockid, UiInteger *i) { |
|
133 UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem)); |
|
134 item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget; |
|
135 item->label = NULL; |
|
136 item->image = NULL; |
|
137 item->stockid = stockid; |
|
138 item->groups = NULL; |
|
139 item->isimportant = 0; |
|
140 item->value = i; |
|
141 item->var = NULL; |
|
142 |
|
143 cxMapPut(toolbar_items, name, item); |
|
144 } |
|
145 |
|
146 void ui_toolitem_toggle_nv(const char *name, const char *label, const char *img, const char *intvar) { |
|
147 UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem)); |
|
148 item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget; |
|
149 item->label = label; |
|
150 item->image = img; |
|
151 item->stockid = NULL; |
|
152 item->groups = NULL; |
|
153 item->isimportant = 0; |
|
154 item->value = NULL; |
|
155 item->var = intvar; |
|
156 |
|
157 cxMapPut(toolbar_items, name, item); |
|
158 } |
|
159 |
|
160 void ui_toolitem_toggle_stnv(const char *name, const char *stockid, const char *intvar) { |
|
161 UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem)); |
|
162 item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget; |
|
163 item->label = NULL; |
|
164 item->image = NULL; |
|
165 item->stockid = stockid; |
|
166 item->groups = NULL; |
|
167 item->isimportant = 0; |
|
168 item->value = NULL; |
|
169 item->var = intvar; |
|
170 |
|
171 cxMapPut(toolbar_items, name, item); |
|
172 } |
|
173 |
|
174 |
|
175 void ui_toolbar_combobox( |
|
176 char *name, |
|
177 UiList *list, |
|
178 ui_getvaluefunc getvalue, |
|
179 ui_callback f, |
|
180 void *udata) |
|
181 { |
|
182 UiToolbarComboBox *cb = malloc(sizeof(UiToolbarComboBox)); |
|
183 cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox; |
|
184 UiVar *var = malloc(sizeof(UiVar)); |
|
185 var->value = list; |
|
186 var->type = UI_VAR_SPECIAL; |
|
187 var->from = NULL; |
|
188 var->from_ctx = NULL; |
|
189 cb->var = var; |
|
190 cb->getvalue = getvalue; |
|
191 cb->callback = f; |
|
192 cb->userdata = udata; |
|
193 |
|
194 cxMapPut(toolbar_items, name, cb); |
|
195 } |
|
196 |
|
197 void ui_toolbar_combobox_str( |
|
198 char *name, |
|
199 UiList *list, |
|
200 ui_callback f, |
|
201 void *udata) |
|
202 { |
|
203 ui_toolbar_combobox(name, list, ui_strmodel_getvalue, f, udata); |
|
204 } |
|
205 |
|
206 void ui_toolbar_combobox_nv( |
|
207 char *name, |
|
208 char *listname, |
|
209 ui_getvaluefunc getvalue, |
|
210 ui_callback f, |
|
211 void *udata) |
|
212 { |
|
213 UiToolbarComboBoxNV *cb = malloc(sizeof(UiToolbarComboBoxNV)); |
|
214 cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox_nv; |
|
215 cb->listname = listname; |
|
216 cb->getvalue = getvalue; |
|
217 cb->callback = f; |
|
218 cb->userdata = udata; |
|
219 |
|
220 cxMapPut(toolbar_items, name, cb); |
|
221 } |
|
222 |
|
223 |
44 |
224 GtkWidget* ui_create_toolbar(UiObject *obj) { |
45 GtkWidget* ui_create_toolbar(UiObject *obj) { |
225 if(!defaults) { |
|
226 return NULL; |
|
227 } |
|
228 |
|
229 GtkWidget *toolbar = gtk_toolbar_new(); |
46 GtkWidget *toolbar = gtk_toolbar_new(); |
230 #ifdef UI_GTK3 |
47 #ifdef UI_GTK3 |
231 gtk_style_context_add_class( |
48 gtk_style_context_add_class( |
232 gtk_widget_get_style_context(toolbar), |
49 gtk_widget_get_style_context(toolbar), |
233 GTK_STYLE_CLASS_PRIMARY_TOOLBAR); |
50 GTK_STYLE_CLASS_PRIMARY_TOOLBAR); |
234 #endif |
51 #endif |
235 |
52 |
|
53 CxMap *items = uic_get_toolbar_items(); |
|
54 CxList *left_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_LEFT); |
|
55 CxList *center_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_CENTER); |
|
56 CxList *right_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_RIGHT); |
|
57 |
|
58 ui_toolbar_add_items(obj, toolbar, items, left_defaults); |
|
59 ui_toolbar_add_items(obj, toolbar, items, center_defaults); |
|
60 ui_toolbar_add_items(obj, toolbar, items, right_defaults); |
|
61 |
|
62 /* |
236 GtkToolbar *tb = GTK_TOOLBAR(toolbar); |
63 GtkToolbar *tb = GTK_TOOLBAR(toolbar); |
237 CxIterator i = cxListIterator(defaults); |
64 CxIterator i = cxListIterator(defaults); |
238 cx_foreach(char *, def, i) { |
65 cx_foreach(char *, def, i) { |
239 UiToolItemI *item = cxMapGet(toolbar_items, def); |
66 UiToolItemI *item = cxMapGet(toolbar_items, def); |
240 if(item) { |
67 if(item) { |
243 gtk_toolbar_insert(tb, gtk_separator_tool_item_new(), -1); |
70 gtk_toolbar_insert(tb, gtk_separator_tool_item_new(), -1); |
244 } else { |
71 } else { |
245 fprintf(stderr, "UI Error: Unknown toolbar item: %s\n", def); |
72 fprintf(stderr, "UI Error: Unknown toolbar item: %s\n", def); |
246 } |
73 } |
247 } |
74 } |
|
75 */ |
248 |
76 |
249 return toolbar; |
77 return toolbar; |
250 } |
78 } |
251 |
79 |
252 void add_toolitem_widget(GtkToolbar *tb, UiToolItem *item, UiObject *obj) { |
80 static void create_item(UiObject *obj, GtkWidget *toolbar, UiToolbarItemI *i) { |
253 GtkToolItem *button = gtk_tool_button_new(NULL, item->label); |
81 GtkToolbar *tb = GTK_TOOLBAR(toolbar); |
|
82 switch(i->type) { |
|
83 case UI_TOOLBAR_ITEM: { |
|
84 add_toolitem_widget(tb, (UiToolbarItem*)i, obj); |
|
85 break; |
|
86 } |
|
87 case UI_TOOLBAR_TOGGLEITEM: { |
|
88 add_toolitem_toggle_widget(tb, (UiToolbarToggleItem*)i, obj); |
|
89 break; |
|
90 } |
|
91 case UI_TOOLBAR_MENU: { |
|
92 add_toolitem_menu_widget(tb, (UiToolbarMenuItem*)i, obj); |
|
93 break; |
|
94 } |
|
95 default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type); |
|
96 } |
|
97 } |
|
98 |
|
99 void ui_toolbar_add_items(UiObject *obj, GtkWidget *toolbar, CxMap *items, CxList *defaults) { |
|
100 // add pre-configured items |
|
101 CxIterator i = cxListIterator(defaults); |
|
102 cx_foreach(char*, def, i) { |
|
103 UiToolbarItemI* item = uic_toolbar_get_item(def); |
|
104 if (!item) { |
|
105 fprintf(stderr, "unknown toolbar item: %s\n", def); |
|
106 continue; |
|
107 } |
|
108 create_item(obj, toolbar, item); |
|
109 } |
|
110 } |
|
111 |
|
112 static void set_toolbutton_icon(GtkToolItem *item, const char *icon_name) { |
|
113 #if GTK_MAJOR_VERSION >= 3 |
|
114 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item), icon_name); |
|
115 #else |
|
116 UiIcon *icon = ui_icon(icon_name, 24); |
|
117 if(icon) { |
|
118 GdkPixbuf *pixbuf = ui_icon_pixbuf(icon); |
|
119 if(pixbuf) { |
|
120 GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); |
|
121 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item), image); |
|
122 } |
|
123 } |
|
124 #endif |
|
125 } |
|
126 |
|
127 void add_toolitem_widget(GtkToolbar *tb, UiToolbarItem *item, UiObject *obj) { |
|
128 GtkToolItem *button; |
|
129 if(item->args.stockid) { |
|
130 #ifdef UI_GTK2 |
|
131 button = gtk_tool_button_new_from_stock(item->args.stockid); |
|
132 #else |
|
133 // TODO: gtk3 stock |
|
134 button = gtk_tool_button_new(NULL, item->args.label); |
|
135 #endif |
|
136 } else { |
|
137 button = gtk_tool_button_new(NULL, item->args.label); |
|
138 } |
|
139 |
254 gtk_tool_item_set_homogeneous(button, FALSE); |
140 gtk_tool_item_set_homogeneous(button, FALSE); |
255 if(item->image) { |
141 if(item->args.icon) { |
256 GdkPixbuf *pixbuf = ui_get_image(item->image); |
142 set_toolbutton_icon(button, item->args.icon); |
257 GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); |
143 } |
258 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(button), image); |
144 gtk_tool_item_set_is_important(button, TRUE); |
259 } else { |
145 |
260 gtk_tool_item_set_is_important(button, TRUE); |
146 if(item->args.onclick) { |
261 } |
|
262 |
|
263 if(item->callback) { |
|
264 UiEventData *event = cxMalloc( |
147 UiEventData *event = cxMalloc( |
265 obj->ctx->allocator, |
148 obj->ctx->allocator, |
266 sizeof(UiEventData)); |
149 sizeof(UiEventData)); |
267 event->obj = obj; |
150 event->obj = obj; |
268 event->userdata = item->userdata; |
151 event->callback = item->args.onclick; |
269 event->callback = item->callback; |
152 event->userdata = item->args.onclickdata; |
|
153 event->customdata = NULL; |
|
154 event->value = 0; |
270 |
155 |
271 g_signal_connect( |
156 g_signal_connect( |
272 button, |
157 button, |
273 "clicked", |
158 "clicked", |
274 G_CALLBACK(ui_button_clicked), |
159 G_CALLBACK(ui_button_clicked), |
275 event); |
160 event); |
276 } |
161 } |
277 |
162 |
278 gtk_toolbar_insert(tb, button, -1); |
163 gtk_toolbar_insert(tb, button, -1); |
279 |
164 |
|
165 /* |
280 if(item->groups) { |
166 if(item->groups) { |
281 uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups); |
167 uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups); |
282 } |
168 } |
283 } |
169 */ |
284 |
170 } |
285 void add_toolitem_st_widget(GtkToolbar *tb, UiStToolItem *item, UiObject *obj) { |
171 |
286 GtkToolItem *button = gtk_tool_button_new_from_stock(item->stockid); |
172 void add_toolitem_toggle_widget(GtkToolbar *tb, UiToolbarToggleItem *item, UiObject *obj) { |
287 gtk_tool_item_set_homogeneous(button, FALSE); |
|
288 if(item->isimportant) { |
|
289 gtk_tool_item_set_is_important(button, TRUE); |
|
290 } |
|
291 |
|
292 if(item->callback) { |
|
293 UiEventData *event = cxMalloc( |
|
294 obj->ctx->allocator, |
|
295 sizeof(UiEventData)); |
|
296 event->obj = obj; |
|
297 event->userdata = item->userdata; |
|
298 event->callback = item->callback; |
|
299 |
|
300 g_signal_connect( |
|
301 button, |
|
302 "clicked", |
|
303 G_CALLBACK(ui_button_clicked), |
|
304 event); |
|
305 } |
|
306 |
|
307 gtk_toolbar_insert(tb, button, -1); |
|
308 |
|
309 if(item->groups) { |
|
310 uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups); |
|
311 } |
|
312 } |
|
313 |
|
314 void add_toolitem_toggle_widget(GtkToolbar *tb, UiToggleToolItem *item, UiObject *obj) { |
|
315 GtkToolItem *button; |
173 GtkToolItem *button; |
316 if(item->stockid) { |
174 if(item->args.stockid) { |
317 button = gtk_toggle_tool_button_new_from_stock(item->stockid); |
175 #ifdef UI_GTK2 |
|
176 button = gtk_toggle_tool_button_new_from_stock(item->args.stockid); |
|
177 #else |
|
178 button = gtk_toggle_tool_button_new_from_stock(item->args.stockid); // TODO: gtk3 stock |
|
179 #endif |
318 } else { |
180 } else { |
319 button = gtk_toggle_tool_button_new(); |
181 button = gtk_toggle_tool_button_new(); |
320 gtk_tool_item_set_homogeneous(button, FALSE); |
182 gtk_tool_item_set_homogeneous(button, FALSE); |
321 if(item->label) { |
183 if(item->args.label) { |
322 gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), item->label); |
184 gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), item->args.label); |
323 } |
185 } |
324 if(item->image) { |
186 if(item->args.icon) { |
325 GdkPixbuf *pixbuf = ui_get_image(item->image); |
187 set_toolbutton_icon(button, item->args.icon); |
326 GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); |
|
327 gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(button), image); |
|
328 } |
188 } |
329 } |
189 } |
330 |
190 |
331 UiVar *var; |
191 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, NULL, item->args.varname, UI_VAR_INTEGER); |
332 if(item->value) { |
192 if(var) { |
333 var = malloc(sizeof(UiVar)); |
193 UiInteger *i = (UiInteger*)var->value; |
334 var->value = item->value; |
194 if(i) { |
335 var->type = UI_VAR_SPECIAL; |
195 i->get = ui_tool_toggle_button_get; |
336 var->from = NULL; |
196 i->set = ui_tool_toggle_button_set; |
337 var->from_ctx = NULL; |
197 i->obj = button; |
338 } else { |
198 |
339 var = uic_create_var(obj->ctx, item->var, UI_VAR_INTEGER); |
199 if(i->value != 0) { |
340 } |
200 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), TRUE); |
341 |
201 } |
342 if(var->value) { |
202 } |
343 UiInteger *i = var->value; |
203 } |
344 i->get = ui_tool_toggle_button_get; |
204 |
345 i->set = ui_tool_toggle_button_set; |
205 UiVarEventData *event = cxMalloc( |
346 i->obj = button; |
206 obj->ctx->allocator, |
347 |
207 sizeof(UiVarEventData)); |
348 if(i->value != 0) { |
|
349 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), TRUE); |
|
350 } |
|
351 } |
|
352 |
|
353 // register event |
|
354 // the event func will call the UiInteger observer callbacks |
|
355 UiEventData *event = cxMalloc( |
|
356 obj->ctx->allocator, |
|
357 sizeof(UiEventData)); |
|
358 event->obj = obj; |
208 event->obj = obj; |
359 event->userdata = var; |
209 event->callback = item->args.onchange; |
360 event->callback = NULL; |
210 event->userdata = item->args.onchangedata; |
|
211 event->var = var; |
361 |
212 |
362 g_signal_connect( |
213 g_signal_connect( |
363 button, |
214 button, |
364 "toggled", |
215 "toggled", |
365 G_CALLBACK(ui_tool_button_toggled), |
216 G_CALLBACK(ui_tool_button_toggled), |
366 event); |
217 event); |
367 |
218 |
368 // add item to toolbar |
219 // add item to toolbar |
369 gtk_toolbar_insert(tb, button, -1); |
220 gtk_toolbar_insert(tb, button, -1); |
370 |
221 |
|
222 /* |
371 if(item->groups) { |
223 if(item->groups) { |
372 uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups); |
224 uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups); |
373 } |
225 } |
374 } |
226 */ |
375 |
227 } |
376 void ui_tool_button_toggled(GtkToggleToolButton *widget, UiEventData *event) { |
228 |
|
229 void ui_tool_button_toggled(GtkToggleToolButton *widget, UiVarEventData *event) { |
377 UiEvent e; |
230 UiEvent e; |
378 e.obj = event->obj; |
231 e.obj = event->obj; |
379 e.window = event->obj->window; |
232 e.window = event->obj->window; |
380 e.document = event->obj->ctx->document; |
233 e.document = event->obj->ctx->document; |
381 e.eventdata = NULL; |
234 e.eventdata = NULL; |
382 e.intval = gtk_toggle_tool_button_get_active(widget); |
235 e.intval = gtk_toggle_tool_button_get_active(widget); |
383 |
236 |
384 UiVar *var = event->userdata; |
237 if(event->callback) { |
385 UiInteger *i = var->value; |
238 event->callback(&e, event->userdata); |
386 |
239 } |
387 ui_notify_evt(i->observers, &e); |
240 |
|
241 UiVar *var = event->var; |
|
242 UiInteger *i = var ? var->value : NULL; |
|
243 |
|
244 if(i) { |
|
245 ui_notify_evt(i->observers, &e); |
|
246 } |
388 } |
247 } |
389 |
248 |
390 int64_t ui_tool_toggle_button_get(UiInteger *integer) { |
249 int64_t ui_tool_toggle_button_get(UiInteger *integer) { |
391 integer->value = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(integer->obj)); |
250 integer->value = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(integer->obj)); |
392 return integer->value; |
251 return integer->value; |
396 gboolean s = value != 0 ? TRUE : FALSE; |
255 gboolean s = value != 0 ? TRUE : FALSE; |
397 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(integer->obj), s); |
256 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(integer->obj), s); |
398 integer->value = s; |
257 integer->value = s; |
399 } |
258 } |
400 |
259 |
|
260 |
|
261 |
|
262 typedef struct UiToolbarMenuWidget { |
|
263 GtkWidget *button; |
|
264 GtkMenu *menu; |
|
265 } UiToolbarMenuWidget; |
|
266 |
|
267 static void ui_toolbar_menubutton_clicked(GtkWidget *widget, UiToolbarMenuWidget *menu) { |
|
268 int x; |
|
269 gtk_menu_popup_at_widget(menu->menu, menu->button, GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL); |
|
270 } |
|
271 |
|
272 static void ui_toolbar_menubutton_destroy(GtkWidget *widget, UiToolbarMenuWidget *menu) { |
|
273 free(menu); |
|
274 } |
|
275 |
|
276 void add_toolitem_menu_widget(GtkToolbar *tb, UiToolbarMenuItem *item, UiObject *obj) { |
|
277 GtkToolItem *button; |
|
278 if(item->args.stockid) { |
|
279 #ifdef UI_GTK2 |
|
280 button = gtk_tool_button_new_from_stock(item->args.stockid); |
|
281 #else |
|
282 // TODO: gtk3 stock |
|
283 button = gtk_tool_button_new(NULL, item->args.label); |
|
284 #endif |
|
285 } else { |
|
286 button = gtk_tool_button_new(NULL, item->args.label); |
|
287 } |
|
288 |
|
289 gtk_tool_item_set_homogeneous(button, FALSE); |
|
290 if(item->args.icon) { |
|
291 set_toolbutton_icon(button, item->args.icon); |
|
292 } |
|
293 gtk_tool_item_set_is_important(button, TRUE); |
|
294 |
|
295 gtk_toolbar_insert(tb, button, -1); |
|
296 |
|
297 // menu |
|
298 GtkWidget *menu_widget = gtk_menu_new(); |
|
299 ui_add_menu_items(menu_widget, 0, &item->menu, obj); |
|
300 gtk_widget_show_all(menu_widget); |
|
301 |
|
302 UiToolbarMenuWidget *tbmenu = malloc(sizeof(UiToolbarMenuWidget)); |
|
303 tbmenu->button = GTK_WIDGET(button); |
|
304 tbmenu->menu = GTK_MENU(menu_widget); |
|
305 |
|
306 g_signal_connect( |
|
307 button, |
|
308 "clicked", |
|
309 G_CALLBACK(ui_toolbar_menubutton_clicked), |
|
310 tbmenu); |
|
311 |
|
312 g_signal_connect( |
|
313 button, |
|
314 "destroy", |
|
315 G_CALLBACK(ui_toolbar_menubutton_destroy), |
|
316 tbmenu); |
|
317 } |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 // deprecated / unsupported |
|
323 /* |
401 void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj) { |
324 void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj) { |
402 UiModel *modelinfo = ui_model(obj->ctx, UI_STRING, "", -1); |
325 UiModel *modelinfo = ui_model(obj->ctx, UI_STRING, "", -1); |
403 modelinfo->getvalue = cb->getvalue; |
326 modelinfo->getvalue = cb->getvalue; |
404 UiListModel *model = ui_list_model_new(obj, cb->var, modelinfo); |
327 UiListModel *model = ui_list_model_new(obj, cb->var, modelinfo); |
405 |
328 |
420 GtkToolItem *item = gtk_tool_item_new(); |
343 GtkToolItem *item = gtk_tool_item_new(); |
421 gtk_container_add(GTK_CONTAINER(item), combobox); |
344 gtk_container_add(GTK_CONTAINER(item), combobox); |
422 gtk_toolbar_insert(tb, item, -1); |
345 gtk_toolbar_insert(tb, item, -1); |
423 } |
346 } |
424 } |
347 } |
425 |
348 */ |
|
349 |
|
350 |
|
351 |
|
352 #ifdef UI_GTK3 |
|
353 |
|
354 GtkWidget* ui_create_headerbar(UiObject *obj) { |
|
355 GtkWidget *headerbar = gtk_header_bar_new(); |
|
356 |
|
357 CxMap *items = uic_get_toolbar_items(); |
|
358 CxList *left_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_LEFT); |
|
359 CxList *center_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_CENTER); |
|
360 CxList *right_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_RIGHT); |
|
361 |
|
362 ui_headerbar_add_items(obj, headerbar, items, left_defaults); |
|
363 ui_headerbar_add_items(obj, headerbar, items, center_defaults); |
|
364 ui_headerbar_add_items(obj, headerbar, items, right_defaults); |
|
365 |
|
366 return headerbar; |
|
367 } |
|
368 |
|
369 static void hb_create_item(UiObject *obj, GtkWidget *toolbar, UiToolbarItemI *i) { |
|
370 GtkHeaderBar *tb = GTK_HEADER_BAR(toolbar); |
|
371 switch(i->type) { |
|
372 case UI_TOOLBAR_ITEM: { |
|
373 add_headerbar_item_widget(tb, (UiToolbarItem*)i, obj); |
|
374 break; |
|
375 } |
|
376 case UI_TOOLBAR_TOGGLEITEM: { |
|
377 add_headerbar_item_toggle_widget(tb, (UiToolbarToggleItem*)i, obj); |
|
378 break; |
|
379 } |
|
380 case UI_TOOLBAR_MENU: { |
|
381 add_headerbar_item_menu_widget(tb, (UiToolbarMenuItem*)i, obj); |
|
382 break; |
|
383 } |
|
384 default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type); |
|
385 } |
|
386 } |
|
387 |
|
388 |
|
389 void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxMap *items, CxList *defaults) { |
|
390 // add pre-configured items |
|
391 CxIterator i = cxListIterator(defaults); |
|
392 cx_foreach(char*, def, i) { |
|
393 UiToolbarItemI* item = uic_toolbar_get_item(def); |
|
394 if (!item) { |
|
395 fprintf(stderr, "unknown toolbar item: %s\n", def); |
|
396 continue; |
|
397 } |
|
398 hb_create_item(obj, headerbar, item); |
|
399 } |
|
400 } |
|
401 |
|
402 void add_headerbar_item_widget(GtkHeaderBar *hb, UiToolbarItem *item, UiObject *obj) { |
|
403 GtkWidget *button = gtk_button_new_with_label(item->args.label); |
|
404 if(item->args.icon) { |
|
405 ui_button_set_icon_name(button, item->args.icon); |
|
406 } |
|
407 |
|
408 gtk_header_bar_pack_start(hb, button); |
|
409 |
|
410 } |
|
411 |
|
412 void add_headerbar_item_toggle_widget(GtkHeaderBar *hb, UiToolbarToggleItem *item, UiObject *obj) { |
|
413 |
|
414 } |
|
415 |
|
416 void add_headerbar_item_menu_widget(GtkHeaderBar *hb, UiToolbarMenuItem *item, UiObject *obj) { |
|
417 |
|
418 } |
|
419 |
|
420 #endif |