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