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