123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- /*
- ** xgc
- **
- ** choice.c
- **
- ** All the generic stuff for dealing with choice widgets.
- */
- #include <stdio.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/Label.h>
- #include <X11/Xaw/Toggle.h>
- #include "xgc.h"
- static void print_text_to_buffer(Widget, caddr_t, caddr_t);
- /* create_choice(w,info)
- ** ---------------------
- ** What a choice widget is: A collection of toggle buttons placed inside
- ** a form widget. Exactly one of these toggle buttons can be "on" at
- ** any given time; the rest are "off". "On" toggle buttons have
- ** the foreground and background colors reversed.
- ** Also, specifically because it comes in handy in xgc, choosing one
- ** of the buttons causes a string associated with it to be printed out
- ** (and interpreted). Half of the string is global to the whole form
- ** and the other half is local to each button.
- **
- ** For example, pressing the "xor" button in the "function" form would
- ** cause xgc to interpret the string "function xor", thus changing the
- ** function in the GC to xor.
- **
- ** There's also a label widget to the left of that mess, with an
- ** incredibly descriptive title.
- **
- ** create_choice() makes one.
- **
- ** w is the form widget (already created) into which we will place the
- ** toggle buttons. info contains lots of useful information, such
- ** as the names of the buttons and their strings (see xgc.h).
- */
- ChoiceDesc *
- create_choice(Widget w, XgcStuff *info)
- {
- ChoiceDesc *choice; /* What we will return. Contains
- ** Widget ID's of the label and toggles. */
- int i; /* Counter */
- char *text; /* Text to be interpreted when the
- ** toggle widget is selected. */
- /* ArgList for the label widget */
- static Arg labelargs[] = {
- {XtNborderWidth, (XtArgVal) 0},
- {XtNjustify, (XtArgVal) XtJustifyRight},
- {XtNvertDistance, (XtArgVal) 4}
- };
- /* ArgList for the toggle widgets */
- static Arg toggleargs[] = {
- {XtNfromHoriz, (XtArgVal) NULL},
- {XtNfromVert, (XtArgVal) NULL},
- {XtNhorizDistance, (XtArgVal) 4},
- {XtNvertDistance, (XtArgVal) 4},
- {XtNradioGroup, (XtArgVal) NULL},
- {XtNcallback, (XtArgVal) NULL}
- };
- /* Callback list for the toggle widgets */
- static XtCallbackRec callbacklist[] = {
- {(XtCallbackProc) print_text_to_buffer, NULL},
- {NULL, NULL}
- };
- /* Allocate space for the widgets and initialize choice */
- choice = (ChoiceDesc *) XtMalloc(sizeof(ChoiceDesc));
- choice->widgets = (WidgetList) XtMalloc(sizeof(Widget) *
- info->choice.num_toggles);
- choice->size = info->choice.num_toggles;
- choice->label = XtCreateManagedWidget(info->choice.name,labelWidgetClass,w,
- labelargs,XtNumber(labelargs));
- /* set up the toggle widgets */
- toggleargs[5].value = (XtArgVal) callbacklist;
- for (i = 0; i < info->choice.num_toggles; ++i) {
- if (i == 0) {
- /* the upper left toggle; put it next to the label
- and don't worry about radio groups */
- toggleargs[0].value = (XtArgVal) choice->label;
- toggleargs[1].value = (XtArgVal) NULL;
- toggleargs[2].value = (XtArgVal) 10;
- toggleargs[3].value = (XtArgVal) 4;
- toggleargs[4].value = (XtArgVal) NULL;
- }
- else {
- toggleargs[4].value = (XtArgVal) choice->widgets[0];
- /* are we starting a new row? */
- if (info->choice.columns > 0 &&
- i > 1 &&
- (i % (info->choice.columns) == 0)) {
- toggleargs[0].value = (XtArgVal) choice->label;
- /* under the appropriate toggle */
- toggleargs[1].value = (XtArgVal) choice->widgets[i - info->choice.columns];
- toggleargs[2].value = (XtArgVal) 10;
- toggleargs[3].value = (XtArgVal) 4;
- }
- else { /* we're in the middle of a row */
- /* to the right of the previous toggle */
- toggleargs[0].value = (XtArgVal) choice->widgets[i - 1];
- toggleargs[1].value = (XtArgVal) NULL;
- toggleargs[2].value = (XtArgVal) -1; /* overlapping slightly */
- toggleargs[3].value = (XtArgVal) 4;
- }
- if (info->choice.columns > 0 &&
- i >= info->choice.columns) {
- /* correct vertical spacing */
- toggleargs[1].value = (XtArgVal) choice->widgets[i - info->choice.columns];
- toggleargs[3].value = (XtArgVal) -1;
- }
- }
- /* Put the correct stuff in the text field */
- text = (char *) XtMalloc((unsigned) (strlen(info->choice.text) +
- strlen((info->data)[i].text) + 3));
- strcpy(text, info->choice.text);
- strcat(text, " ");
- strcat(text, (info->data)[i].text);
- strcat(text, "\n");
- callbacklist[0].closure = (caddr_t) text;
-
- /* Create it finally */
- choice->widgets[i] = XtCreateManagedWidget((info->data[i]).name,
- toggleWidgetClass,
- w,
- toggleargs,
- XtNumber(toggleargs));
- }
-
- /* The toggle widgets have all been created;
- ** now make the all the same width if that's
- ** what we want to do. */
- if (info->choice.columns > 0) {
- Dimension maxwidth = 0; /* maximum width we've found */
- Dimension width; /* width of the current widget */
- static Arg args[] = { /* for getting and setting the width */
- {XtNwidth, (XtArgVal) NULL}
- };
- args[0].value = (XtArgVal) &width;
- /* Find the maximum width of any toggle widget */
- for (i = 0; i < info->choice.num_toggles; ++i) {
- XtGetValues(choice->widgets[i],args,1);
- maxwidth = max(maxwidth,width);
- }
- /* Now set them all to that width */
- args[0].value = (XtArgVal) maxwidth;
- for (i = 0; i < info->choice.num_toggles; ++i)
- XtSetValues(choice->widgets[i],args,1);
- }
- /* return the list of toggles that were just created */
- return (choice);
- }
- /* select_button(choice,togglenum)
- ** -------------------------------
- ** "Selects" the togglenumth toggle widget in the choice layout
- ** represented by choice. It simply turns the widget on, as if the
- ** user had selected it, without calling any callbacks. It's used
- ** to give feedback when reading from a script.
- */
- void
- select_button(ChoiceDesc *choice, int togglenum)
- {
- static Arg toggleargs[] = {
- {XtNstate, (XtArgVal) True}
- };
- XtSetValues(choice->widgets[togglenum],toggleargs,XtNumber(toggleargs));
- }
- /* line_up_labels(descs,numdescs)
- ** ------------------------------
- ** descs represents a bunch of choice layouts (numdescs is the size of
- ** descs). This function sets each label in descs to the same width,
- ** thus making them line up nicely since they're all on the left margin.
- */
- void
- line_up_labels(ChoiceDesc *descs[], int numdescs)
- {
- int i; /* counter */
- Dimension width; /* current width */
- Dimension maxwidth = (Dimension) 0; /* max width found */
- static Arg widthargs[] = {
- {XtNwidth, (XtArgVal) NULL }
- };
- widthargs[0].value = (XtArgVal) &width;
- /* Find the maximum width */
- for (i = 0; i < numdescs; ++i) {
- XtGetValues(descs[i]->label, widthargs, XtNumber(widthargs));
- maxwidth = max(maxwidth,width);
- }
- /* Set all labels to that width */
- widthargs[0].value = (XtArgVal) maxwidth;
- for (i = 0; i < numdescs; ++i) {
- XtSetValues(descs[i]->label, widthargs, XtNumber(widthargs));
- }
- }
- /* choose_defaults(descs,numdescs)
- ** -------------------------------
- ** descs represents a bunch of choice layouts (numdescs is the size of
- ** descs). This function goes through all of descs and selects the
- ** appropriate toggle widget for each one. This includes calling
- ** the callbacks associated with that widget.
- **
- ** This function ends up initializing both the screen and the GC, and
- ** ensures that they are consistent.
- */
- void
- choose_defaults(ChoiceDesc *descs[], int numdescs)
- {
- int i; /* which choice layout */
- int j; /* which toggle within it */
- for (i = 0; i < numdescs; ++i) {
- j = 0;
- if (i == 0)
- j = 3;
- select_button(descs[i],j);
- XtCallCallbacks(descs[i]->widgets[j], XtNcallback, (caddr_t) NULL);
- }
- }
- /* print_text_to_buffer(w,closure,call_data)
- ** -----------------------------------------
- ** This is also in the list of callbacks for the toggle buttons in a
- ** choice widget. It sends the string contained in closure (which
- ** was set way back in create_choice()) over to interpret(), which
- ** decides what to do with it.
- */
- /*ARGSUSED*/
- static void
- print_text_to_buffer(
- Widget w,
- caddr_t closure, /* contains the string */
- caddr_t call_data)
- {
- interpret((char *) closure); /* Gee, that was easy */
- }
|