bbox.c revision d859ff80
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
38static XtTranslations	RadioButtonTranslations = NULL;
39
40
41void 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
53ButtonBox 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
78ButtonBox 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
88static 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
138void BBoxAddButton(
139    ButtonBox	buttonbox,
140    char	*name,
141    WidgetClass	kind,
142    Boolean	enabled)
143{
144    bboxAddButton(buttonbox, name, kind, enabled, False);
145}
146
147
148void 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
159void 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
168char *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
181void 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
211void 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
231static 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
243void BBoxEnable(
244    Button button)
245{
246    SendEnableMsg(button->widget, True);
247}
248
249
250/* Disable the given button (if it's not already). */
251
252void 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
262Button 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
276Button 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
290Button 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
300int BBoxNumButtons(
301    ButtonBox buttonbox)
302{
303    return buttonbox->numbuttons;
304}
305
306
307/* Given a button, return its name. */
308
309char *BBoxNameOfButton(
310    Button button)
311{
312    return button->name;
313}
314
315
316/* Given a button, return its menu. */
317
318Widget	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
330void 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
343Boolean BBoxIsGrandparent(
344    ButtonBox	buttonbox,
345    Widget	widget)
346{
347    return (XtParent(XtParent(widget)) == buttonbox->inner);
348}
349
350
351void 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