ui/motif/menu.c

changeset 101
7b3a3130be44
parent 100
d2bd73d28ff1
equal deleted inserted replaced
100:d2bd73d28ff1 101:7b3a3130be44
34 #include "button.h" 34 #include "button.h"
35 #include "toolkit.h" 35 #include "toolkit.h"
36 #include "stock.h" 36 #include "stock.h"
37 #include "container.h" 37 #include "container.h"
38 #include "../common/context.h" 38 #include "../common/context.h"
39 #include "../common/menu.h"
40 #include "../common/types.h"
39 #include "../ui/window.h" 41 #include "../ui/window.h"
40 42
41 #include <cx/linked_list.h> 43 #include <cx/linked_list.h>
42 #include <cx/array_list.h> 44 #include <cx/array_list.h>
43 45
46
47 static ui_menu_add_f createMenuItem[] = {
48 /* UI_MENU */ add_menu_widget,
49 /* UI_MENU_ITEM */ add_menuitem_widget,
50 /* UI_MENU_CHECK_ITEM */ add_checkitem_widget,
51 /* UI_MENU_RADIO_ITEM */ add_radioitem_widget,
52 /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget,
53 /* UI_MENU_CHECKITEM_LIST */ add_menuitem_list_widget,
54 /* UI_MENU_RADIOITEM_LIST */ add_menuitem_list_widget,
55 /* UI_MENU_SEPARATOR */ add_menuseparator_widget
56 };
57
58 void ui_create_menubar(UiObject *obj, Widget window) {
59 UiMenu *menus_begin = uic_get_menu_list();
60 if(!menus_begin) {
61 return;
62 }
63
64 Widget menubar = XmCreateMenuBar(window, "menubar", NULL, 0);
65 XtManageChild(menubar);
66
67 UiMenu *ls = menus_begin;
68 while(ls) {
69 UiMenu *menu = ls;
70 add_menu_widget(menubar, 0, &menu->item, obj);
71 ls = (UiMenu*)ls->item.next;
72 }
73 }
74
75 void ui_add_menu_items(Widget parent, int i, UiMenu *menu, UiObject *obj) {
76 UiMenuItemI *it = menu->items_begin;
77 int index = 0;
78 while(it) {
79 createMenuItem[it->type](parent, index, it, obj);
80 it = it->next;
81 index++;
82 }
83 }
84
85 void add_menu_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) {
86 UiMenu *menu = (UiMenu*)item;
87 Arg args[4];
88 int n = 0;
89
90 XmString s = NULL;
91 if(menu->label) {
92 s = XmStringCreateLocalized((char*)menu->label);
93 XtSetArg(args[n], XmNlabelString, s); n++;
94 }
95
96 Widget submenu = XmVaCreateSimplePulldownMenu(parent, "menu_pulldown", i, NULL, NULL);
97 XtSetArg(args[n], XmNsubMenuId, submenu); n++;
98 Widget menuItem = XtCreateManagedWidget(
99 "menuitem",
100 xmCascadeButtonWidgetClass,
101 parent,
102 args,
103 n);
104
105
106 if(s) {
107 XmStringFree(s);
108 }
109
110 ui_add_menu_items(submenu, i, menu, obj);
111 }
112
113 void add_menuitem_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj) {
114 UiMenuItem *it = (UiMenuItem*)item;
115
116 XmString s = NULL;
117 Arg args[4];
118 int n = 0;
119 if(it->label) {
120 s = XmStringCreateLocalized((char*)it->label);
121 XtSetArg(args[n], XmNlabelString, s); n++;
122 }
123
124 Widget mitem = XtCreateManagedWidget(
125 "menubutton",
126 xmPushButtonWidgetClass,
127 parent,
128 args,
129 n);
130 if(s) {
131 XmStringFree(s);
132 }
133
134 if(it->callback) {
135 UiEventData *eventdata = malloc(sizeof(UiEventData));
136 eventdata->callback = it->callback;
137 eventdata->userdata = it->userdata;
138 eventdata->obj = obj;
139 eventdata->value = 0;
140 XtAddCallback(
141 mitem,
142 XmNactivateCallback,
143 (XtCallbackProc)ui_push_button_callback,
144 eventdata);
145 XtAddCallback(
146 mitem,
147 XmNdestroyCallback,
148 (XtCallbackProc)ui_destroy_eventdata,
149 eventdata);
150 }
151
152 ui_set_widget_groups(obj->ctx, mitem, it->groups);
153 }
154
155 void add_menuseparator_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) {
156 Widget s = XmCreateSeparatorGadget (p, "menuseparator", NULL, 0);
157 XtManageChild(s);
158 }
159
160 void add_checkitem_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) {
161 UiMenuCheckItem *it = (UiMenuCheckItem*)item;
162
163 Arg args[4];
164 int n = 0;
165 XmString s = NULL;
166 if(it->label) {
167 s = XmStringCreateLocalized(it->label);
168 XtSetArg(args[n], XmNlabelString, s); n++;
169 }
170
171 //XtSetArg(args[n], XmNvisibleWhenOff, 0); n++;
172 Widget checkbox = XtCreateManagedWidget(
173 "menutogglebutton",
174 xmToggleButtonWidgetClass,
175 p,
176 args,
177 n);
178 if(s) {
179 XmStringFree(s);
180 }
181
182 ui_bind_togglebutton(obj, checkbox, it->varname, NULL, it->callback, it->userdata, 0);
183
184 ui_set_widget_groups(obj->ctx, checkbox, it->groups);
185 }
186
187 void add_radioitem_widget(Widget p, int index, UiMenuItemI *item, UiObject *obj) {
188 UiMenuRadioItem *it = (UiMenuRadioItem*)item;
189
190 Arg args[4];
191 int n = 0;
192 XmString s = NULL;
193 if(it->label) {
194 s = XmStringCreateLocalized(it->label);
195 XtSetArg(args[n], XmNlabelString, s); n++;
196 }
197 XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY_ROUND); n++;
198
199 Widget button = XmCreateToggleButton(p, "menuradiobutton", args, n);
200 XtManageChild(button);
201
202 ui_bind_radiobutton(obj, button, NULL, it->varname, it->callback, it->userdata, 0);
203 }
204
205 void add_menuitem_list_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) {
206 UiMenuItemList *il = (UiMenuItemList*)item;
207 const CxAllocator *a = obj->ctx->allocator;
208
209 UiActiveMenuItemList *ls = cxMalloc(
210 a,
211 sizeof(UiActiveMenuItemList));
212 ls->object = obj;
213 ls->menu = p;
214 ls->index = i;
215 ls->oldcount = 0;
216 ls->getvalue = il->getvalue;
217 ls->callback = il->callback;
218 ls->userdata = il->userdata;
219 ls->addseparator = il->addseparator;
220
221 ls->var = uic_create_var(ui_global_context(), il->varname, UI_VAR_LIST); //uic_widget_var(obj->ctx, obj->ctx, NULL, il->varname, UI_VAR_LIST);
222 UiList *list = ls->var->value;
223
224 UiObserver *observer = ui_observer_new((ui_callback)ui_update_menuitem_list, ls);
225 list->observers = ui_obsvlist_add(list->observers, observer);
226 uic_list_register_observer_destructor(obj->ctx, list, observer);
227
228 ui_update_menuitem_list(NULL, ls);
229 }
230
231 void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list) {
232 XmString s = NULL;
233 Arg args[4];
234 int n;
235
236 UiList *ls;
237 if(list->var && list->var->value) {
238 ls = list->var->value;
239 } else {
240 return;
241 }
242
243 if(list->oldcount > 0) {
244 Widget *children;
245 int nc;
246
247 XtVaGetValues(
248 list->menu,
249 XmNchildren,
250 &children,
251 XmNnumChildren,
252 &nc,
253 NULL);
254
255 for(int i=0;i<list->oldcount;i++) {
256 XtDestroyWidget(children[list->index + i]);
257 }
258 }
259
260 void* elm = ui_list_first(ls);
261 int i = 0;
262 if(elm && list->addseparator) {
263 XtSetArg(args[0], XmNpositionIndex, list->index);
264 Widget s = XmCreateSeparatorGadget(list->menu, "menuseparator", args, 1);
265 XtManageChild(s);
266 i++;
267 }
268
269 ui_getvaluefunc getvalue = list->getvalue;
270 int pos = list->index;
271 while(elm) {
272 n = 0;
273 char *label = (char*) (getvalue ? getvalue(elm, 0) : elm);
274 if(label) {
275 s = XmStringCreateLocalized(label);
276 XtSetArg(args[n], XmNlabelString, s); n++;
277 }
278 XtSetArg(args[n], XmNpositionIndex, pos+i); n++;
279
280 Widget mitem = XtCreateManagedWidget(
281 "menubutton",
282 xmPushButtonWidgetClass,
283 list->menu,
284 args,
285 n);
286 if(s) {
287 XmStringFree(s);
288 }
289
290 if(list->callback) {
291 UiEventData *eventdata = malloc(sizeof(UiEventData));
292 eventdata->callback = list->callback;
293 eventdata->userdata = list->userdata;
294 eventdata->obj = list->object;
295 eventdata->value = 0;
296 XtAddCallback(
297 mitem,
298 XmNactivateCallback,
299 (XtCallbackProc)ui_push_button_callback,
300 eventdata);
301 XtAddCallback(
302 mitem,
303 XmNdestroyCallback,
304 (XtCallbackProc)ui_destroy_eventdata,
305 eventdata);
306 }
307
308 elm = ui_list_next(ls);
309 i++;
310 }
311
312 list->oldcount = i;
313 }

mercurial