1 | /* |
---|
2 | * $XConsortium: bbox.c,v 2.35 91/07/10 19:34:59 converse Exp $ |
---|
3 | * |
---|
4 | * |
---|
5 | * COPYRIGHT 1987, 1989 |
---|
6 | * DIGITAL EQUIPMENT CORPORATION |
---|
7 | * MAYNARD, MASSACHUSETTS |
---|
8 | * ALL RIGHTS RESERVED. |
---|
9 | * |
---|
10 | * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND |
---|
11 | * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. |
---|
12 | * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR |
---|
13 | * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. |
---|
14 | * |
---|
15 | * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT |
---|
16 | * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN |
---|
17 | * ADDITION TO THAT SET FORTH ABOVE. |
---|
18 | * |
---|
19 | * Permission to use, copy, modify, and distribute this software and its |
---|
20 | * documentation for any purpose and without fee is hereby granted, provided |
---|
21 | * that the above copyright notice appear in all copies and that both that |
---|
22 | * copyright notice and this permission notice appear in supporting |
---|
23 | * documentation, and that the name of Digital Equipment Corporation not be |
---|
24 | * used in advertising or publicity pertaining to distribution of the software |
---|
25 | * without specific, written prior permission. |
---|
26 | */ |
---|
27 | |
---|
28 | /* bbox.c -- management of buttons and buttonboxes. |
---|
29 | * |
---|
30 | * This module implements a simple interface to buttonboxes, allowing a client |
---|
31 | * to create new buttonboxes and manage their contents. |
---|
32 | */ |
---|
33 | |
---|
34 | #include "xmh.h" |
---|
35 | #include "bboxint.h" |
---|
36 | |
---|
37 | static XtTranslations RadioButtonTranslations = NULL; |
---|
38 | |
---|
39 | |
---|
40 | void BBoxInit() |
---|
41 | { |
---|
42 | RadioButtonTranslations = |
---|
43 | XtParseTranslationTable("<Btn1Down>,<Btn1Up>:set()\n"); |
---|
44 | } |
---|
45 | |
---|
46 | |
---|
47 | /* |
---|
48 | * Create a new button box. The widget for it will be a child of the given |
---|
49 | * scrn's widget, and it will be added to the scrn's pane. |
---|
50 | */ |
---|
51 | |
---|
52 | ButtonBox BBoxCreate(scrn, name) |
---|
53 | Scrn scrn; |
---|
54 | char *name; /* name of the buttonbox widgets */ |
---|
55 | { |
---|
56 | Cardinal n; |
---|
57 | ButtonBox buttonbox = XtNew(ButtonBoxRec); |
---|
58 | Arg args[5]; |
---|
59 | |
---|
60 | n = 0; |
---|
61 | XtSetArg(args[n], XtNallowVert, True); n++; |
---|
62 | XtSetArg(args[n], XtNskipAdjust, True); n++; |
---|
63 | |
---|
64 | buttonbox->outer = |
---|
65 | XtCreateManagedWidget(name, viewportWidgetClass, scrn->widget, |
---|
66 | args, n); |
---|
67 | buttonbox->inner = |
---|
68 | XtCreateManagedWidget(name, boxWidgetClass, buttonbox->outer, |
---|
69 | args, (Cardinal) 0); |
---|
70 | buttonbox->numbuttons = 0; |
---|
71 | buttonbox->button = (Button *) NULL; |
---|
72 | buttonbox->scrn = scrn; |
---|
73 | return buttonbox; |
---|
74 | } |
---|
75 | |
---|
76 | |
---|
77 | ButtonBox RadioBBoxCreate(scrn, name) |
---|
78 | Scrn scrn; |
---|
79 | char *name; /* name of the buttonbox widgets */ |
---|
80 | { |
---|
81 | return BBoxCreate(scrn, name); |
---|
82 | } |
---|
83 | |
---|
84 | |
---|
85 | /* Create a new button, and add it to a buttonbox. */ |
---|
86 | |
---|
87 | static void bboxAddButton(buttonbox, name, kind, enabled, radio) |
---|
88 | |
---|
89 | ButtonBox buttonbox; |
---|
90 | char *name; |
---|
91 | WidgetClass kind; |
---|
92 | Boolean enabled; |
---|
93 | Boolean radio; |
---|
94 | { |
---|
95 | Button button; |
---|
96 | Cardinal i; |
---|
97 | Widget radio_group; |
---|
98 | Arg args[5]; |
---|
99 | |
---|
100 | buttonbox->numbuttons++; |
---|
101 | buttonbox->button = (Button *) |
---|
102 | XtRealloc((char *) buttonbox->button, |
---|
103 | (unsigned) buttonbox->numbuttons * sizeof(Button)); |
---|
104 | button = buttonbox->button[buttonbox->numbuttons - 1] = XtNew(ButtonRec); |
---|
105 | button->buttonbox = buttonbox; |
---|
106 | button->name = XtNewString(name); |
---|
107 | button->menu = (Widget) NULL; |
---|
108 | |
---|
109 | i = 0; |
---|
110 | if (!enabled) { |
---|
111 | XtSetArg(args[i], XtNsensitive, False); i++; |
---|
112 | } |
---|
113 | |
---|
114 | if (radio && kind == toggleWidgetClass) { |
---|
115 | if (buttonbox->numbuttons > 1) |
---|
116 | radio_group = (button == buttonbox->button[0]) |
---|
117 | ? (buttonbox->button[1]->widget) |
---|
118 | : (buttonbox->button[0]->widget); |
---|
119 | else radio_group = NULL; |
---|
120 | XtSetArg(args[i], XtNradioGroup, radio_group); i++; |
---|
121 | XtSetArg(args[i], XtNradioData, button->name); i++; |
---|
122 | } |
---|
123 | |
---|
124 | /* Prevent the folder buttons from picking up labels from resources */ |
---|
125 | |
---|
126 | if (buttonbox == buttonbox->scrn->folderbuttons) { |
---|
127 | XtSetArg(args[i], XtNlabel, button->name); i++; |
---|
128 | } |
---|
129 | |
---|
130 | button->widget = |
---|
131 | XtCreateManagedWidget(name, kind, buttonbox->inner, args, i); |
---|
132 | |
---|
133 | if (radio) |
---|
134 | XtOverrideTranslations(button->widget, RadioButtonTranslations); |
---|
135 | } |
---|
136 | |
---|
137 | |
---|
138 | void BBoxAddButton(buttonbox, name, kind, enabled) |
---|
139 | ButtonBox buttonbox; |
---|
140 | char *name; |
---|
141 | WidgetClass kind; |
---|
142 | Boolean enabled; |
---|
143 | { |
---|
144 | bboxAddButton(buttonbox, name, kind, enabled, False); |
---|
145 | } |
---|
146 | |
---|
147 | |
---|
148 | void RadioBBoxAddButton(buttonbox, name, enabled) |
---|
149 | ButtonBox buttonbox; |
---|
150 | char *name; |
---|
151 | Boolean enabled; |
---|
152 | { |
---|
153 | bboxAddButton(buttonbox, name, toggleWidgetClass, enabled, True); |
---|
154 | } |
---|
155 | |
---|
156 | |
---|
157 | /* Set the current button in a radio buttonbox. */ |
---|
158 | |
---|
159 | void RadioBBoxSet(button) |
---|
160 | Button button; |
---|
161 | { |
---|
162 | XawToggleSetCurrent(button->widget, button->name); |
---|
163 | } |
---|
164 | |
---|
165 | |
---|
166 | /* Get the name of the current button in a radio buttonbox. */ |
---|
167 | |
---|
168 | char *RadioBBoxGetCurrent(buttonbox) |
---|
169 | ButtonBox buttonbox; |
---|
170 | { |
---|
171 | return ((char *) XawToggleGetCurrent(buttonbox->button[0]->widget)); |
---|
172 | } |
---|
173 | |
---|
174 | |
---|
175 | /* Remove the given button from its buttonbox, and free all resources |
---|
176 | * used in association with the button. If the button was the current |
---|
177 | * button in a radio buttonbox, the current button becomes the first |
---|
178 | * button in the box. |
---|
179 | */ |
---|
180 | |
---|
181 | void BBoxDeleteButton(button) |
---|
182 | Button button; |
---|
183 | { |
---|
184 | ButtonBox buttonbox; |
---|
185 | int i, found; |
---|
186 | |
---|
187 | if (button == NULL) return; |
---|
188 | buttonbox = button->buttonbox; |
---|
189 | found = False; |
---|
190 | |
---|
191 | for (i=0 ; i<buttonbox->numbuttons; i++) { |
---|
192 | if (found) |
---|
193 | buttonbox->button[i-1] = buttonbox->button[i]; |
---|
194 | else if (buttonbox->button[i] == button) { |
---|
195 | found = True; |
---|
196 | |
---|
197 | /* Free the resources used by the given button. */ |
---|
198 | |
---|
199 | if (button->menu != NULL && button->menu != NoMenuForButton) |
---|
200 | XtDestroyWidget(button->menu); |
---|
201 | XtDestroyWidget(button->widget); |
---|
202 | XtFree(button->name); |
---|
203 | XtFree((char *) button); |
---|
204 | } |
---|
205 | } |
---|
206 | if (found) |
---|
207 | buttonbox->numbuttons--; |
---|
208 | } |
---|
209 | |
---|
210 | |
---|
211 | void RadioBBoxDeleteButton(button) |
---|
212 | Button button; |
---|
213 | { |
---|
214 | ButtonBox buttonbox; |
---|
215 | Boolean reradio = False; |
---|
216 | char * current; |
---|
217 | |
---|
218 | if (button == NULL) return; |
---|
219 | buttonbox = button->buttonbox; |
---|
220 | current = RadioBBoxGetCurrent(buttonbox); |
---|
221 | if (current) reradio = ! strcmp(current, button->name); |
---|
222 | BBoxDeleteButton(button); |
---|
223 | |
---|
224 | if (reradio && BBoxNumButtons(buttonbox)) |
---|
225 | RadioBBoxSet(buttonbox->button[0]); |
---|
226 | } |
---|
227 | |
---|
228 | |
---|
229 | /* Enable or disable the given button widget. */ |
---|
230 | |
---|
231 | static void SendEnableMsg(widget, value) |
---|
232 | Widget widget; |
---|
233 | int value; /* TRUE for enable, FALSE for disable. */ |
---|
234 | { |
---|
235 | static Arg arglist[] = {XtNsensitive, (XtArgVal)False}; |
---|
236 | arglist[0].value = (XtArgVal) value; |
---|
237 | XtSetValues(widget, arglist, XtNumber(arglist)); |
---|
238 | } |
---|
239 | |
---|
240 | |
---|
241 | /* Enable the given button (if it's not already). */ |
---|
242 | |
---|
243 | void BBoxEnable(button) |
---|
244 | Button button; |
---|
245 | { |
---|
246 | SendEnableMsg(button->widget, True); |
---|
247 | } |
---|
248 | |
---|
249 | |
---|
250 | /* Disable the given button (if it's not already). */ |
---|
251 | |
---|
252 | void BBoxDisable(button) |
---|
253 | Button button; |
---|
254 | { |
---|
255 | SendEnableMsg(button->widget, False); |
---|
256 | } |
---|
257 | |
---|
258 | |
---|
259 | /* Given a buttonbox and a button name, find the button in the box with that |
---|
260 | name. */ |
---|
261 | |
---|
262 | Button BBoxFindButtonNamed(buttonbox, name) |
---|
263 | ButtonBox buttonbox; |
---|
264 | char *name; |
---|
265 | { |
---|
266 | register int i; |
---|
267 | for (i=0 ; i<buttonbox->numbuttons; i++) |
---|
268 | if (strcmp(name, buttonbox->button[i]->name) == 0) |
---|
269 | return buttonbox->button[i]; |
---|
270 | return (Button) NULL; |
---|
271 | } |
---|
272 | |
---|
273 | |
---|
274 | /* Given a buttonbox and a widget, find the button which is that widget. */ |
---|
275 | |
---|
276 | Button BBoxFindButton(buttonbox, w) |
---|
277 | ButtonBox buttonbox; |
---|
278 | Widget w; |
---|
279 | { |
---|
280 | register int i; |
---|
281 | for (i=0; i < buttonbox->numbuttons; i++) |
---|
282 | if (buttonbox->button[i]->widget == w) |
---|
283 | return buttonbox->button[i]; |
---|
284 | return (Button) NULL; |
---|
285 | } |
---|
286 | |
---|
287 | |
---|
288 | /* Return the nth button in the given buttonbox. */ |
---|
289 | |
---|
290 | Button BBoxButtonNumber(buttonbox, n) |
---|
291 | ButtonBox buttonbox; |
---|
292 | int n; |
---|
293 | { |
---|
294 | return buttonbox->button[n]; |
---|
295 | } |
---|
296 | |
---|
297 | |
---|
298 | /* Return how many buttons are in a buttonbox. */ |
---|
299 | |
---|
300 | int BBoxNumButtons(buttonbox) |
---|
301 | ButtonBox buttonbox; |
---|
302 | { |
---|
303 | return buttonbox->numbuttons; |
---|
304 | } |
---|
305 | |
---|
306 | |
---|
307 | /* Given a button, return its name. */ |
---|
308 | |
---|
309 | char *BBoxNameOfButton(button) |
---|
310 | Button button; |
---|
311 | { |
---|
312 | return button->name; |
---|
313 | } |
---|
314 | |
---|
315 | |
---|
316 | /* Given a button, return its menu. */ |
---|
317 | |
---|
318 | Widget BBoxMenuOfButton(button) |
---|
319 | Button button; |
---|
320 | { |
---|
321 | return button->menu; |
---|
322 | } |
---|
323 | |
---|
324 | |
---|
325 | /* Set maximum size for a bbox so that it cannot be resized any taller |
---|
326 | * than the space needed to stack all the buttons on top of each other. |
---|
327 | * Allow the user to set the minimum size. |
---|
328 | */ |
---|
329 | |
---|
330 | void BBoxLockSize(buttonbox) |
---|
331 | ButtonBox buttonbox; |
---|
332 | { |
---|
333 | Dimension maxheight; |
---|
334 | Arg args[1]; |
---|
335 | |
---|
336 | if (buttonbox == NULL) return; |
---|
337 | maxheight = (Dimension) GetHeight(buttonbox->inner); |
---|
338 | XtSetArg(args[0], XtNmax, maxheight); /* for Paned widget */ |
---|
339 | XtSetValues(buttonbox->outer, args, (Cardinal) 1); |
---|
340 | } |
---|
341 | |
---|
342 | |
---|
343 | Boolean BBoxIsGrandparent(buttonbox, widget) |
---|
344 | ButtonBox buttonbox; |
---|
345 | Widget widget; |
---|
346 | { |
---|
347 | return (XtParent(XtParent(widget)) == buttonbox->inner); |
---|
348 | } |
---|
349 | |
---|
350 | |
---|
351 | void BBoxMailFlag(buttonbox, name, up) |
---|
352 | ButtonBox buttonbox; |
---|
353 | char* name; |
---|
354 | int up; |
---|
355 | { |
---|
356 | Arg args[1]; |
---|
357 | Pixel flag; |
---|
358 | Button button = BBoxFindButtonNamed(buttonbox, name); |
---|
359 | |
---|
360 | if (button) { |
---|
361 | /* avoid unnecessary exposures */ |
---|
362 | XtSetArg(args[0], XtNleftBitmap, &flag); |
---|
363 | XtGetValues(button->widget, args, (Cardinal)1); |
---|
364 | if (up && flag != app_resources.flag_up) { |
---|
365 | XtSetArg(args[0], XtNleftBitmap, app_resources.flag_up); |
---|
366 | XtSetValues(button->widget, args, (Cardinal)1); |
---|
367 | } |
---|
368 | else if (!up && flag != app_resources.flag_down) { |
---|
369 | XtSetArg(args[0], XtNleftBitmap, app_resources.flag_down); |
---|
370 | XtSetValues(button->widget, args, (Cardinal)1); |
---|
371 | } |
---|
372 | } |
---|
373 | } |
---|