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 const 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 const 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 const 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 = XtReallocArray(buttonbox->button, 102 buttonbox->numbuttons, sizeof(Button)); 103 button = buttonbox->button[buttonbox->numbuttons - 1] = XtNew(ButtonRec); 104 button->buttonbox = buttonbox; 105 button->name = XtNewString(name); 106 button->menu = (Widget) NULL; 107 108 i = 0; 109 if (!enabled) { 110 XtSetArg(args[i], XtNsensitive, False); i++; 111 } 112 113 if (radio && kind == toggleWidgetClass) { 114 if (buttonbox->numbuttons > 1) 115 radio_group = (button == buttonbox->button[0]) 116 ? (buttonbox->button[1]->widget) 117 : (buttonbox->button[0]->widget); 118 else radio_group = NULL; 119 XtSetArg(args[i], XtNradioGroup, radio_group); i++; 120 XtSetArg(args[i], XtNradioData, button->name); i++; 121 } 122 123 /* Prevent the folder buttons from picking up labels from resources */ 124 125 if (buttonbox == buttonbox->scrn->folderbuttons) { 126 XtSetArg(args[i], XtNlabel, button->name); i++; 127 } 128 129 button->widget = 130 XtCreateManagedWidget(name, kind, buttonbox->inner, args, i); 131 132 if (radio) 133 XtOverrideTranslations(button->widget, RadioButtonTranslations); 134} 135 136 137void BBoxAddButton( 138 ButtonBox buttonbox, 139 const char *name, 140 WidgetClass kind, 141 Boolean enabled) 142{ 143 bboxAddButton(buttonbox, name, kind, enabled, False); 144} 145 146 147void RadioBBoxAddButton( 148 ButtonBox buttonbox, 149 const char *name, 150 Boolean enabled) 151{ 152 bboxAddButton(buttonbox, name, toggleWidgetClass, enabled, True); 153} 154 155 156/* Set the current button in a radio buttonbox. */ 157 158void RadioBBoxSet( 159 Button button) 160{ 161 XawToggleSetCurrent(button->widget, button->name); 162} 163 164 165/* Get the name of the current button in a radio buttonbox. */ 166 167char *RadioBBoxGetCurrent( 168 ButtonBox buttonbox) 169{ 170 return ((char *) XawToggleGetCurrent(buttonbox->button[0]->widget)); 171} 172 173 174/* Remove the given button from its buttonbox, and free all resources 175 * used in association with the button. If the button was the current 176 * button in a radio buttonbox, the current button becomes the first 177 * button in the box. 178 */ 179 180void BBoxDeleteButton( 181 Button button) 182{ 183 ButtonBox buttonbox; 184 int i, found; 185 186 if (button == NULL) return; 187 buttonbox = button->buttonbox; 188 found = False; 189 190 for (i=0 ; i<buttonbox->numbuttons; i++) { 191 if (found) 192 buttonbox->button[i-1] = buttonbox->button[i]; 193 else if (buttonbox->button[i] == button) { 194 found = True; 195 196 /* Free the resources used by the given button. */ 197 198 if (button->menu != NULL && button->menu != NoMenuForButton) 199 XtDestroyWidget(button->menu); 200 XtDestroyWidget(button->widget); 201 XtFree(button->name); 202 XtFree((char *) button); 203 } 204 } 205 if (found) 206 buttonbox->numbuttons--; 207} 208 209 210void RadioBBoxDeleteButton( 211 Button button) 212{ 213 ButtonBox buttonbox; 214 Boolean reradio = False; 215 char * current; 216 217 if (button == NULL) return; 218 buttonbox = button->buttonbox; 219 current = RadioBBoxGetCurrent(buttonbox); 220 if (current) reradio = ! strcmp(current, button->name); 221 BBoxDeleteButton(button); 222 223 if (reradio && BBoxNumButtons(buttonbox)) 224 RadioBBoxSet(buttonbox->button[0]); 225} 226 227 228/* Enable or disable the given button widget. */ 229 230static void SendEnableMsg( 231 Widget widget, 232 int value) /* TRUE for enable, FALSE for disable. */ 233{ 234 static Arg arglist[] = {{XtNsensitive, (XtArgVal)False}}; 235 arglist[0].value = (XtArgVal) value; 236 XtSetValues(widget, arglist, XtNumber(arglist)); 237} 238 239 240/* Enable the given button (if it's not already). */ 241 242void BBoxEnable( 243 Button button) 244{ 245 SendEnableMsg(button->widget, True); 246} 247 248 249/* Disable the given button (if it's not already). */ 250 251void BBoxDisable( 252 Button button) 253{ 254 SendEnableMsg(button->widget, False); 255} 256 257 258/* Given a buttonbox and a button name, find the button in the box with that 259 name. */ 260 261Button BBoxFindButtonNamed( 262 ButtonBox buttonbox, 263 const char *name) 264{ 265 register int i; 266 for (i=0 ; i<buttonbox->numbuttons; i++) 267 if (strcmp(name, buttonbox->button[i]->name) == 0) 268 return buttonbox->button[i]; 269 return (Button) NULL; 270} 271 272 273/* Given a buttonbox and a widget, find the button which is that widget. */ 274 275Button BBoxFindButton( 276 ButtonBox buttonbox, 277 Widget w) 278{ 279 register int i; 280 for (i=0; i < buttonbox->numbuttons; i++) 281 if (buttonbox->button[i]->widget == w) 282 return buttonbox->button[i]; 283 return (Button) NULL; 284} 285 286 287/* Return the nth button in the given buttonbox. */ 288 289Button BBoxButtonNumber( 290 ButtonBox buttonbox, 291 int n) 292{ 293 return buttonbox->button[n]; 294} 295 296 297/* Return how many buttons are in a buttonbox. */ 298 299int BBoxNumButtons( 300 ButtonBox buttonbox) 301{ 302 return buttonbox->numbuttons; 303} 304 305 306/* Given a button, return its name. */ 307 308char *BBoxNameOfButton( 309 Button button) 310{ 311 return button->name; 312} 313 314 315/* Given a button, return its menu. */ 316 317Widget BBoxMenuOfButton( 318 Button button) 319{ 320 return button->menu; 321} 322 323 324/* Set maximum size for a bbox so that it cannot be resized any taller 325 * than the space needed to stack all the buttons on top of each other. 326 * Allow the user to set the minimum size. 327 */ 328 329void BBoxLockSize( 330 ButtonBox buttonbox) 331{ 332 Dimension maxheight; 333 Arg args[1]; 334 335 if (buttonbox == NULL) return; 336 maxheight = (Dimension) GetHeight(buttonbox->inner); 337 XtSetArg(args[0], XtNmax, maxheight); /* for Paned widget */ 338 XtSetValues(buttonbox->outer, args, (Cardinal) 1); 339} 340 341 342Boolean BBoxIsGrandparent( 343 ButtonBox buttonbox, 344 Widget widget) 345{ 346 return (XtParent(XtParent(widget)) == buttonbox->inner); 347} 348 349 350void BBoxMailFlag( 351 ButtonBox buttonbox, 352 const char* name, 353 int up) 354{ 355 Arg args[1]; 356 Pixel flag; 357 Button button = BBoxFindButtonNamed(buttonbox, name); 358 359 if (button) { 360 /* avoid unnecessary exposures */ 361 XtSetArg(args[0], XtNleftBitmap, &flag); 362 XtGetValues(button->widget, args, (Cardinal)1); 363 if (up && flag != app_resources.flag_up) { 364 XtSetArg(args[0], XtNleftBitmap, app_resources.flag_up); 365 XtSetValues(button->widget, args, (Cardinal)1); 366 } 367 else if (!up && flag != app_resources.flag_down) { 368 XtSetArg(args[0], XtNleftBitmap, app_resources.flag_down); 369 XtSetValues(button->widget, args, (Cardinal)1); 370 } 371 } 372} 373