Commit | Line | Data |
---|---|---|
40a6a4dd RS |
1 | #include "lwlib-Xol.h" |
2 | #include <X11/StringDefs.h> | |
3 | #include <X11/IntrinsicP.h> | |
4 | #include <X11/CompositeP.h> | |
5 | #include <X11/Shell.h> | |
6 | #include <Xol/Menu.h> | |
7 | #include <Xol/OpenLook.h> | |
8 | #include <Xol/MenuButton.h> | |
9 | #include <Xol/OblongButt.h> | |
10 | #include <Xol/ControlAre.h> | |
11 | #include <Xol/Stub.h> | |
12 | #include <Xol/StaticText.h> | |
13 | ||
14 | \f/* forward declarations */ | |
15 | static void | |
16 | update_menu_widget (widget_instance* instance, Widget widget, | |
17 | widget_value* val); | |
18 | ||
19 | \f/* Menu callbacks */ | |
20 | static void | |
21 | pre_hook (Widget w, caddr_t client_data, caddr_t call_data) | |
22 | { | |
23 | OlVirtualEvent ve = (OlVirtualEvent)call_data; | |
24 | widget_instance* instance = (widget_instance*)client_data; | |
25 | ||
26 | if (w->core.being_destroyed) | |
27 | return; | |
28 | ||
29 | if (XtParent (w) == instance->widget) | |
30 | { | |
31 | if (ve->xevent->type == ButtonPress && instance->info->pre_activate_cb) | |
32 | instance->info->pre_activate_cb (instance->widget, instance->info->id, | |
33 | NULL); | |
34 | } | |
35 | } | |
36 | ||
37 | static void | |
38 | post_hook (Widget w, caddr_t client_data, caddr_t call_data) | |
39 | { | |
40 | widget_instance* instance = (widget_instance*)client_data; | |
41 | ||
42 | if (w->core.being_destroyed) | |
43 | return; | |
44 | ||
45 | if (instance->info->post_activate_cb) | |
46 | instance->info->post_activate_cb (w, instance->info->id, NULL); | |
47 | } | |
48 | ||
49 | static void | |
50 | pick_hook (Widget w, caddr_t client_data, caddr_t call_data) | |
51 | { | |
52 | widget_instance* instance = 0; | |
53 | widget_value* val = (widget_value*)client_data; | |
54 | ||
55 | if (w->core.being_destroyed) | |
56 | return; | |
57 | ||
58 | XtVaGetValues (w, XtNuserData, &instance, 0); | |
59 | ||
60 | if (!instance) | |
61 | return; | |
62 | ||
63 | if (instance->info->selection_cb && val && val->enabled | |
64 | && !val->contents) | |
65 | instance->info->selection_cb (w, instance->info->id, val->call_data); | |
66 | } | |
67 | ||
68 | \f/* creation functions */ | |
69 | static Widget | |
70 | xol_create_menubar (widget_instance* instance) | |
71 | { | |
72 | Widget widget = | |
73 | XtVaCreateWidget (instance->info->name, controlAreaWidgetClass, | |
74 | instance->parent, 0); | |
75 | return widget; | |
76 | } | |
77 | ||
78 | static Widget | |
79 | xol_create_popup_menu (widget_instance* instance) | |
80 | { | |
81 | Widget popup_shell = | |
82 | XtCreatePopupShell (instance->info->name, menuShellWidgetClass, | |
83 | instance->parent, NULL, 0); | |
84 | return popup_shell; | |
85 | } | |
86 | ||
87 | widget_creation_entry | |
88 | xol_creation_table [] = | |
89 | { | |
90 | {"menubar", xol_create_menubar}, | |
91 | {"popup", xol_create_popup_menu}, | |
92 | {NULL, NULL} | |
93 | }; | |
94 | ||
95 | Widget | |
96 | xol_create_dialog (widget_instance* instance) | |
97 | { | |
98 | return NULL; | |
99 | } | |
100 | ||
101 | Boolean | |
102 | lw_olit_widget_p (Widget widget) | |
103 | { | |
104 | return True; | |
105 | } | |
106 | ||
107 | \f/* update functions */ | |
108 | static void | |
109 | destroy_all_children (Widget widget) | |
110 | { | |
111 | Widget* children; | |
112 | unsigned int number; | |
113 | int i; | |
114 | ||
115 | children = (Widget *) XtCompositeChildren (widget, &number); | |
116 | if (children) | |
117 | { | |
118 | /* Unmanage all children and destroy them. They will only be | |
119 | * really destroyed when we get out of DispatchEvent. */ | |
120 | for (i = 0; i < number; i++) | |
121 | { | |
122 | Widget child = children [i]; | |
123 | if (!child->core.being_destroyed) | |
124 | { | |
125 | XtUnmanageChild (child); | |
126 | XtDestroyWidget (child); | |
127 | } | |
128 | } | |
129 | XtFree (children); | |
130 | } | |
131 | } | |
132 | ||
133 | static Boolean | |
134 | all_dashes_p (char* s) | |
135 | { | |
136 | char* t; | |
137 | for (t = s; *t; t++) | |
138 | if (*t != '-') | |
139 | return False; | |
140 | return True; | |
141 | } | |
142 | ||
143 | static void | |
144 | make_menu_in_widget (widget_instance* instance, Widget widget, | |
145 | widget_value* val) | |
146 | { | |
147 | widget_value* cur; | |
148 | Widget button; | |
149 | Arg al [256]; | |
150 | int ac; | |
151 | String label; | |
152 | ||
153 | for (cur = val; cur; cur = cur->next) | |
154 | { | |
155 | ac = 0; | |
156 | XtSetArg (al [ac], XtNsensitive, cur->enabled); ac++; | |
157 | XtSetArg (al [ac], XtNuserData, instance); ac++; | |
158 | XtSetArg (al [ac], XtNacceleratorText, cur->key); ac++; | |
159 | ||
160 | /* label = (char *) resource_string (widget, cur->name);*/ | |
161 | label = cur->name; | |
162 | if (label) | |
163 | { | |
164 | XtSetArg (al [ac], XtNlabel, label); ac++; | |
165 | } | |
166 | ||
167 | if (all_dashes_p (cur->name)) | |
168 | { | |
169 | /* no separator in OpenLook just make some space. */ | |
170 | XtSetArg (al [ac], XtNheight, 5); ac++; | |
171 | XtSetArg (al [ac], XtNwidth, 5); ac++; | |
172 | button = XtCreateWidget (cur->name, stubWidgetClass, widget, al, ac); | |
173 | } | |
174 | else if (!cur->contents) | |
175 | { | |
176 | if (!cur->call_data) | |
177 | button = | |
178 | XtCreateManagedWidget (cur->name, staticTextWidgetClass, widget, | |
179 | al, ac); | |
180 | else | |
181 | { | |
182 | button = | |
183 | XtCreateManagedWidget (cur->name, oblongButtonWidgetClass, | |
184 | widget, al, ac); | |
185 | XtAddCallback (button, XtNselect, pick_hook, cur); | |
186 | } | |
187 | } | |
188 | else | |
189 | { | |
190 | Widget menu = NULL; | |
191 | button = | |
192 | XtCreateManagedWidget (cur->name, menuButtonWidgetClass, widget, | |
193 | al, ac); | |
194 | XtVaGetValues (button, XtNmenuPane, &menu, 0); | |
195 | if (!menu) | |
196 | abort (); | |
197 | make_menu_in_widget (instance, menu, cur->contents); | |
198 | OlAddCallback (button, XtNconsumeEvent, pre_hook, instance); | |
199 | } | |
200 | } | |
201 | } | |
202 | ||
203 | static void | |
204 | update_one_menu_entry (widget_instance* instance, Widget widget, | |
205 | widget_value* val) | |
206 | { | |
207 | Arg al [256]; | |
208 | int ac; | |
209 | Widget menu; | |
210 | widget_value* contents; | |
211 | ||
212 | if (val->change == NO_CHANGE) | |
213 | return; | |
214 | ||
215 | /* update the sensitivity */ | |
216 | XtVaSetValues (widget, XtNsensitive, val->enabled, 0); | |
217 | ||
218 | /* update the pulldown/pullaside as needed */ | |
219 | ac = 0; | |
220 | menu = NULL; | |
221 | XtVaGetValues (widget, XtNmenuPane, &menu, 0); | |
222 | contents = val->contents; | |
223 | ||
224 | if (!menu) | |
225 | { | |
226 | if (contents) | |
227 | { | |
908ff139 | 228 | /* in OLIT this would have to be a structural change on the |
40a6a4dd RS |
229 | button. */ |
230 | abort (); | |
231 | } | |
232 | } | |
233 | else if (!contents) | |
234 | { | |
908ff139 | 235 | /* in OLIT this would have to be a structural change on the button. */ |
40a6a4dd RS |
236 | abort (); |
237 | } | |
238 | else if (contents->change != NO_CHANGE) | |
239 | update_menu_widget (instance, menu, val); | |
240 | } | |
241 | ||
242 | static void | |
243 | update_menu_widget (widget_instance* instance, Widget widget, | |
244 | widget_value* val) | |
245 | ||
246 | { | |
247 | if (val->change == STRUCTURAL_CHANGE | |
248 | || val->contents->change == STRUCTURAL_CHANGE) | |
249 | { | |
250 | destroy_all_children (widget); | |
251 | make_menu_in_widget (instance, widget, val->contents); | |
252 | } | |
253 | else | |
254 | { | |
255 | /* Update all the buttons of the composite widget in order. */ | |
256 | Widget* children; | |
257 | unsigned int num_children; | |
258 | int i; | |
259 | widget_value* cur; | |
260 | ||
261 | children = (Widget *) XtCompositeChildren (widget, &num_children); | |
262 | if (children) | |
263 | { | |
264 | for (i = 0, cur = val->contents; i < num_children; i++) | |
265 | { | |
266 | if (!cur) | |
267 | abort (); | |
268 | if (children [i]->core.being_destroyed | |
269 | || strcmp (XtName (children [i]), cur->name)) | |
270 | continue; | |
271 | update_one_menu_entry (instance, children [i], cur); | |
272 | cur = cur->next; | |
273 | } | |
274 | XtFree (children); | |
275 | } | |
276 | if (cur) | |
277 | abort (); | |
278 | } | |
279 | } | |
280 | ||
281 | void | |
282 | xol_update_one_widget (widget_instance* instance, Widget widget, | |
283 | widget_value* val, Boolean deep_p) | |
284 | { | |
285 | Widget menu = widget; | |
286 | ||
287 | if (XtIsShell (widget)) | |
288 | XtVaGetValues (widget, XtNmenuPane, &menu, 0); | |
289 | ||
290 | update_menu_widget (instance, menu, val); | |
291 | } | |
292 | ||
293 | void | |
294 | xol_update_one_value (widget_instance* instance, Widget widget, | |
295 | widget_value* val) | |
296 | { | |
297 | return; | |
298 | } | |
299 | ||
300 | void | |
301 | xol_pop_instance (widget_instance* instance, Boolean up) | |
302 | { | |
303 | } | |
304 | ||
305 | void | |
306 | xol_popup_menu (Widget widget) | |
307 | { | |
308 | OlMenuPost (widget); | |
309 | } | |
310 | ||
311 | \f/* Destruction of instances */ | |
312 | void | |
313 | xol_destroy_instance (widget_instance* instance) | |
314 | { | |
315 | XtDestroyWidget (instance->widget); | |
316 | } | |
317 |