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 /* $XFree86: xc/programs/xmh/bbox.c,v 1.2 2001/10/28 03:34:38 tsi Exp $ */
28 
29 /* bbox.c -- management of buttons and buttonboxes.
30  *
31  * This module implements a simple interface to buttonboxes, allowing a client
32  * to create new buttonboxes and manage their contents.
33  */
34 
35 #include "xmh.h"
36 #include "bboxint.h"
37 
38 static XtTranslations	RadioButtonTranslations = NULL;
39 
40 
BBoxInit(void)41 void BBoxInit(void)
42 {
43     RadioButtonTranslations =
44 	XtParseTranslationTable("<Btn1Down>,<Btn1Up>:set()\n");
45 }
46 
47 
48 /*
49  * Create a new button box.  The widget for it will be a child of the given
50  * scrn's widget, and it will be added to the scrn's pane.
51  */
52 
BBoxCreate(Scrn scrn,char * name)53 ButtonBox BBoxCreate(
54     Scrn	scrn,
55     char	*name)	/* name of the buttonbox widgets */
56 {
57     Cardinal	n;
58     ButtonBox	buttonbox = XtNew(ButtonBoxRec);
59     Arg		args[5];
60 
61     n = 0;
62     XtSetArg(args[n], XtNallowVert, True);	n++;
63     XtSetArg(args[n], XtNskipAdjust, True);	n++;
64 
65     buttonbox->outer =
66 	XtCreateManagedWidget(name, viewportWidgetClass, scrn->widget,
67 			      args, n);
68     buttonbox->inner =
69 	XtCreateManagedWidget(name, boxWidgetClass, buttonbox->outer,
70 			      args, (Cardinal) 0);
71     buttonbox->numbuttons = 0;
72     buttonbox->button = (Button *) NULL;
73     buttonbox->scrn = scrn;
74     return buttonbox;
75 }
76 
77 
RadioBBoxCreate(Scrn scrn,char * name)78 ButtonBox RadioBBoxCreate(
79     Scrn	scrn,
80     char	*name)	/* name of the buttonbox widgets */
81 {
82     return BBoxCreate(scrn, name);
83 }
84 
85 
86 /* Create a new button, and add it to a buttonbox. */
87 
bboxAddButton(ButtonBox buttonbox,char * name,WidgetClass kind,Boolean enabled,Boolean radio)88 static void bboxAddButton(
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 
BBoxAddButton(ButtonBox buttonbox,char * name,WidgetClass kind,Boolean enabled)138 void BBoxAddButton(
139     ButtonBox	buttonbox,
140     char	*name,
141     WidgetClass	kind,
142     Boolean	enabled)
143 {
144     bboxAddButton(buttonbox, name, kind, enabled, False);
145 }
146 
147 
RadioBBoxAddButton(ButtonBox buttonbox,char * name,Boolean enabled)148 void RadioBBoxAddButton(
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 
RadioBBoxSet(Button button)159 void RadioBBoxSet(
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 
RadioBBoxGetCurrent(ButtonBox buttonbox)168 char *RadioBBoxGetCurrent(
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 
BBoxDeleteButton(Button button)181 void BBoxDeleteButton(
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 
RadioBBoxDeleteButton(Button button)211 void RadioBBoxDeleteButton(
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 
SendEnableMsg(Widget widget,int value)231 static void SendEnableMsg(
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 
BBoxEnable(Button button)243 void BBoxEnable(
244     Button button)
245 {
246     SendEnableMsg(button->widget, True);
247 }
248 
249 
250 /* Disable the given button (if it's not already). */
251 
BBoxDisable(Button button)252 void BBoxDisable(
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 
BBoxFindButtonNamed(ButtonBox buttonbox,char * name)262 Button BBoxFindButtonNamed(
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 
BBoxFindButton(ButtonBox buttonbox,Widget w)276 Button BBoxFindButton(
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 
BBoxButtonNumber(ButtonBox buttonbox,int n)290 Button BBoxButtonNumber(
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 
BBoxNumButtons(ButtonBox buttonbox)300 int BBoxNumButtons(
301     ButtonBox buttonbox)
302 {
303     return buttonbox->numbuttons;
304 }
305 
306 
307 /* Given a button, return its name. */
308 
BBoxNameOfButton(Button button)309 char *BBoxNameOfButton(
310     Button button)
311 {
312     return button->name;
313 }
314 
315 
316 /* Given a button, return its menu. */
317 
BBoxMenuOfButton(Button button)318 Widget	BBoxMenuOfButton(
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 
BBoxLockSize(ButtonBox buttonbox)330 void BBoxLockSize(
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 
BBoxIsGrandparent(ButtonBox buttonbox,Widget widget)343 Boolean BBoxIsGrandparent(
344     ButtonBox	buttonbox,
345     Widget	widget)
346 {
347     return (XtParent(XtParent(widget)) == buttonbox->inner);
348 }
349 
350 
BBoxMailFlag(ButtonBox buttonbox,char * name,int up)351 void BBoxMailFlag(
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 }
374