summaryrefslogtreecommitdiff
path: root/choice.c
diff options
context:
space:
mode:
Diffstat (limited to 'choice.c')
-rw-r--r--choice.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/choice.c b/choice.c
new file mode 100644
index 0000000..57cf80d
--- /dev/null
+++ b/choice.c
@@ -0,0 +1,282 @@
+/*
+** 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(
+#if NeedFunctionPrototypes
+ Widget, caddr_t, caddr_t
+#endif
+);
+extern void interpret();
+
+extern XStuff X;
+
+/* 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(w,info)
+ 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(choice,togglenum)
+ 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(descs,numdescs)
+ 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(descs,numdescs)
+ 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(w,closure,call_data)
+ Widget w;
+ caddr_t closure; /* contains the string */
+ caddr_t call_data;
+{
+ interpret((char *) closure); /* Gee, that was easy */
+}