update uwproj
[mizunara.git] / ui / motif / toolbar.c
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 #include <string.h>
32 #include <stdarg.h>
33
34 #include "toolbar.h"
35 #include "button.h"
36 #include "stock.h"
37 #include "list.h"
38 #include <ucx/mempool.h>
39 #include "../common/context.h"
40
41 static UcxMap *toolbar_items;
42 static UcxList *defaults;
43
44 void ui_toolbar_init() {
45     toolbar_items = ucx_map_new(16);
46 }
47
48 void ui_toolitem(char *name, char *label, ui_callback f, void *userdata) {
49     UiToolItem *item = malloc(sizeof(UiToolItem));
50     item->item.add_to = (ui_toolbar_add_f)add_toolitem_widget;
51     item->label = label;
52     item->image = NULL;
53     item->callback = f;
54     item->userdata = userdata;
55     item->groups = NULL;
56     item->isimportant = FALSE;
57     
58     ucx_map_cstr_put(toolbar_items, name, item);
59 }
60
61 void ui_toolitem_st(char *name, char *stockid, ui_callback f, void *userdata) {
62     ui_toolitem_stgr(name, stockid, f, userdata, -1);
63 }
64
65 void ui_toolitem_stgr(char *name, char *stockid, ui_callback f, void *userdata, ...) {
66     UiStToolItem *item = malloc(sizeof(UiStToolItem));
67     item->item.add_to = (ui_toolbar_add_f)add_toolitem_st_widget;
68     item->stockid = stockid;
69     item->callback = f;
70     item->userdata = userdata;
71     item->groups = NULL;
72     item->isimportant = FALSE;
73     
74     // add groups
75     va_list ap;
76     va_start(ap, userdata);
77     int group;
78     while((group = va_arg(ap, int)) != -1) {
79         item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group);
80     }
81     va_end(ap);
82     
83     ucx_map_cstr_put(toolbar_items, name, item);
84 }
85
86 void ui_toolitem_img(char *name, char *label, char *img, ui_callback f, void *udata) {
87     // TODO
88     
89     UiToolItem *item = malloc(sizeof(UiToolItem));
90     item->item.add_to = (ui_toolbar_add_f)add_toolitem_widget;
91     item->label = label;
92     item->image = img;
93     item->callback = f;
94     item->userdata = udata;
95     item->groups = NULL;
96     item->isimportant = FALSE;
97     
98     ucx_map_cstr_put(toolbar_items, name, item);
99 }
100
101
102 void ui_toolitem_toggle_stgr(char *name, char *stockid, ui_callback f, void *udata, ...) {
103     // TODO
104     
105     UiStToolItem *item = malloc(sizeof(UiStToolItem));
106     item->item.add_to = (ui_toolbar_add_f)add_toolitem_st_toggle_widget;
107     item->stockid = stockid;
108     item->callback = f;
109     item->userdata = udata;
110     item->groups = NULL;
111     item->isimportant = FALSE;
112     
113     // add groups
114     va_list ap;
115     va_start(ap, udata);
116     int group;
117     while((group = va_arg(ap, int)) != -1) {
118         item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group);
119     }
120     va_end(ap);
121     
122     ucx_map_cstr_put(toolbar_items, name, item);
123 }
124
125 void ui_toolitem_toggle_imggr(char *name, char *label, char *img, ui_callback f, void *udata, ...) {
126     // TODO
127     
128     UiToolItem *item = malloc(sizeof(UiToolItem));
129     item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
130     item->label = label;
131     item->image = img;
132     item->callback = f;
133     item->userdata = udata;
134     item->groups = NULL;
135     item->isimportant = FALSE;
136     
137     // add groups
138     va_list ap;
139     va_start(ap, udata);
140     int group;
141     while((group = va_arg(ap, int)) != -1) {
142         item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group);
143     }
144     va_end(ap);
145     
146     ucx_map_cstr_put(toolbar_items, name, item);
147 }
148
149 void ui_toolbar_combobox(
150         char *name,
151         UiList *list,
152         ui_getvaluefunc getvalue,
153         ui_callback f,
154         void *udata)
155 {
156     UiToolbarComboBox *cb = malloc(sizeof(UiToolbarComboBox));
157     cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox;  
158     cb->list = list;
159     cb->getvalue = getvalue;
160     cb->callback = f;
161     cb->userdata = udata;
162     
163     ucx_map_cstr_put(toolbar_items, name, cb);
164 }
165
166 void ui_toolbar_combobox_str(
167         char *name,
168         UiList *list,
169         ui_callback f,
170         void *udata)
171 {
172     ui_toolbar_combobox(name, list, ui_strmodel_getvalue, f, udata);
173 }
174
175 void ui_toolbar_combobox_nv(
176         char *name,
177         char *listname,
178         ui_getvaluefunc getvalue,
179         ui_callback f,
180         void *udata)
181 {
182     UiToolbarComboBoxNV *cb = malloc(sizeof(UiToolbarComboBoxNV));
183     cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox_nv;  
184     cb->listname = listname;
185     cb->getvalue = getvalue;
186     cb->callback = f;
187     cb->userdata = udata;
188     
189     ucx_map_cstr_put(toolbar_items, name, cb);
190 }
191
192
193 void ui_toolbar_add_default(char *name) {
194     char *s = strdup(name);
195     defaults = ucx_list_append(defaults, s);
196 }
197
198 Widget ui_create_toolbar(UiObject *obj, Widget parent) {
199     if(!defaults) {
200         return NULL;
201     }
202     
203     Arg args[8];
204     XtSetArg(args[0], XmNshadowType, XmSHADOW_ETCHED_OUT);
205     XtSetArg(args[1], XmNshadowThickness, 1);
206     XtSetArg(args[2], XmNtopAttachment, XmATTACH_FORM);
207     XtSetArg(args[3], XmNleftAttachment, XmATTACH_FORM);
208     XtSetArg(args[4], XmNrightAttachment, XmATTACH_FORM);
209     Widget frame = XmCreateFrame(parent, "toolbar_frame", args, 5);
210     
211     XtSetArg(args[0], XmNorientation, XmHORIZONTAL);
212     XtSetArg(args[1], XmNpacking, XmPACK_TIGHT);
213     XtSetArg(args[2], XmNspacing, 1);
214     Widget toolbar = XmCreateRowColumn (frame, "toolbar", args, 3);
215     
216     UCX_FOREACH(elm, defaults) {
217         UiToolItemI *item = ucx_map_cstr_get(toolbar_items, elm->data);
218         if(item) {
219             item->add_to(toolbar, item, obj);
220         } else if(!strcmp(elm->data, "@separator")) {
221             // TODO
222         } else {
223             fprintf(stderr, "UI Error: Unknown toolbar item: %s\n", elm->data);
224         }
225     }
226     
227     XtManageChild(toolbar);
228     XtManageChild(frame);
229     
230     return frame;
231 }
232
233 void add_toolitem_widget(Widget parent, UiToolItem *item, UiObject *obj) {
234     Arg args[4];
235     
236     XmString label = XmStringCreateLocalized(item->label);
237     XtSetArg(args[0], XmNlabelString, label);
238     XtSetArg(args[1], XmNshadowThickness, 1);
239     XtSetArg(args[2], XmNtraversalOn, FALSE);
240     Widget button = XmCreatePushButton(parent, "toolbar_button", args, 3);
241     
242     XmStringFree(label);
243     
244     if(item->callback) {
245         UiEventData *event = ucx_mempool_malloc(
246                 obj->ctx->mempool,
247                 sizeof(UiEventData));
248         event->obj = obj;
249         event->userdata = item->userdata;
250         event->callback = item->callback;
251         XtAddCallback(
252                 button,
253                 XmNactivateCallback,
254                 (XtCallbackProc)ui_push_button_callback,
255                 event);
256     }
257     
258     XtManageChild(button);
259     
260     if(item->groups) {
261         uic_add_group_widget(obj->ctx, button, (ui_enablefunc)XtSetSensitive, item->groups);
262     }
263 }
264
265 void add_toolitem_st_widget(Widget parent, UiStToolItem *item, UiObject *obj) {
266     Arg args[8];
267     
268     UiStockItem *stock_item = ui_get_stock_item(item->stockid);
269      
270     XmString label = XmStringCreateLocalized(stock_item->label);
271     XtSetArg(args[0], XmNlabelString, label);
272     XtSetArg(args[1], XmNshadowThickness, 1);
273     XtSetArg(args[2], XmNtraversalOn, FALSE);
274     Widget button = XmCreatePushButton(parent, "toolbar_button", args, 3);
275  
276     XmStringFree(label);
277     
278     if(item->callback) {
279         UiEventData *event = ucx_mempool_malloc(
280                 obj->ctx->mempool,
281                 sizeof(UiEventData));
282         event->obj = obj;
283         event->userdata = item->userdata;
284         event->callback = item->callback;
285         XtAddCallback(
286                 button,
287                 XmNactivateCallback,
288                 (XtCallbackProc)ui_push_button_callback,
289                 event);
290     }
291     
292     XtManageChild(button);
293     
294     if(item->groups) {
295         uic_add_group_widget(obj->ctx, button, (ui_enablefunc)XtSetSensitive, item->groups);
296     }
297 }
298
299 void add_toolitem_toggle_widget(Widget parent, UiToolItem *item, UiObject *obj) {
300     Arg args[8];
301     
302     XmString label = XmStringCreateLocalized(item->label);
303     XtSetArg(args[0], XmNlabelString, label);
304     XtSetArg(args[1], XmNshadowThickness, 1);
305     XtSetArg(args[2], XmNtraversalOn, FALSE);
306     XtSetArg(args[3], XmNindicatorOn, XmINDICATOR_NONE);
307     Widget button = XmCreateToggleButton(parent, "toolbar_toggle_button", args, 4);
308     
309     XmStringFree(label);
310     
311     if(item->callback) {
312         UiEventData *event = ucx_mempool_malloc(
313                 obj->ctx->mempool,
314                 sizeof(UiEventData));
315         event->obj = obj;
316         event->userdata = item->userdata;
317         event->callback = item->callback;
318         XtAddCallback(
319                 button,
320                 XmNvalueChangedCallback,
321                 (XtCallbackProc)ui_toggle_button_callback,
322                 event);
323     }
324     
325     XtManageChild(button);
326     
327     if(item->groups) {
328         uic_add_group_widget(obj->ctx, button, (ui_enablefunc)XtSetSensitive, item->groups);
329     }
330 }
331
332 void add_toolitem_st_toggle_widget(Widget parent, UiStToolItem *item, UiObject *obj) {
333     
334 }
335
336 void add_toolbar_combobox(Widget tb, UiToolbarComboBox *item, UiObject *obj) {
337     UiListView *listview = ucx_mempool_malloc(
338                 obj->ctx->mempool,
339                 sizeof(UiListView));
340     
341     UiVar *var = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiVar));
342     var->value = item->list;
343     var->type = UI_VAR_SPECIAL;
344     
345     Arg args[8];
346     XtSetArg(args[0], XmNshadowThickness, 1);
347     XtSetArg(args[1], XmNindicatorOn, XmINDICATOR_NONE);
348     XtSetArg(args[2], XmNtraversalOn, FALSE);
349     XtSetArg(args[3], XmNwidth, 120);
350     Widget combobox = XmCreateDropDownList(tb, "toolbar_combobox", args, 4);
351     XtManageChild(combobox);
352     listview->widget = combobox;
353     listview->list = var;
354     listview->getvalue = item->getvalue;
355     
356     ui_listview_update(NULL, listview);
357     
358     if(item->callback) {
359         // TODO:
360         
361     }
362 }
363
364 void add_toolbar_combobox_nv(Widget tb, UiToolbarComboBoxNV *item, UiObject *obj) {
365     
366 }