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 } |