1/*
2** testfrac.c
3**
4** How to make a widget to choose the fraction of tests to be run.
5**
6*/
7
8#include <stdio.h>
9#include <X11/Intrinsic.h>
10#include <X11/StringDefs.h>
11#include <X11/Xaw/Form.h>
12#include <X11/Xaw/Label.h>
13#include <X11/Xaw/Scrollbar.h>
14#include "xgc.h"
15
16#define SCROLLBAR_LENGTH 125
17#define SLIDER_LENGTH 0.2	/* proportion of scrollbar taken up
18				   by the slider */
19
20static Widget label;		/* the label */
21static Widget slider;		/* the scrollbar */
22static Widget percent;	/* label with chosen percentage */
23
24static float fraction;		/* what percent has been chosen */
25static int   oldpercent = -1;	/* so we only update when the slider has
26				   been moved */
27
28/* slider_jump(w,data,position)
29** ----------------------------
30** This function is called if the user moves the scrollbar to a new
31** position (generally, by using the middle button).  It updates
32** information about where the scrollbar is.
33*/
34
35/*ARGSUSED*/
36static void
37slider_jump(Widget w, caddr_t data, caddr_t position)
38{
39  static Arg percentargs[] = {
40    {XtNlabel,   (XtArgVal) NULL}
41  };
42
43  float oldpercent;		/* where the scrollbar is */
44  float newpercent;		/* normalized scrollbar */
45  char snewpercent[4];		/* string representation of scrollbar */
46
47  oldpercent = *(float *) position;
48
49  /* We want the scrollbar to be at 100% when the right edge of the slider
50  ** hits the end of the scrollbar, not the left edge.  When the right edge
51  ** is at 1.0, the left edge is at 1.0 - SLIDER_LENGTH.  Normalize
52  ** accordingly.  */
53
54  newpercent = oldpercent / (1.0 - SLIDER_LENGTH);
55
56  /* If the slider's partially out of the scrollbar, move it back in. */
57
58  if (newpercent > 1.0) {
59    newpercent = 1.0;
60    XawScrollbarSetThumb( slider, 1.0 - SLIDER_LENGTH, SLIDER_LENGTH);
61  }
62
63  /* Store the position of the silder where it can be found */
64
65  *(float *)data = newpercent;
66
67  /* Update the label widget */
68
69  snprintf(snewpercent, sizeof snewpercent, "%d",(int)(newpercent*100));
70  percentargs[0].value = (XtArgVal) snewpercent;
71  XtSetValues(percent, percentargs, XtNumber(percentargs));
72}
73
74/* slider_scroll(w,data,position)
75** ------------------------------
76** This function is called when the user does incremental scrolling,
77** generally with the left or right button.  Right now it just ignores it.
78*/
79
80/*ARGSUSED*/
81static void
82slider_scroll(Widget w, caddr_t data, caddr_t position)
83{
84}
85
86/*ARGSUSED*/
87static void
88update(Widget w, XEvent *event, String *params, int *num_params)
89{
90  char buf[80];
91  int newpercent;
92
93  newpercent = (int)(fraction * 100.0);
94  if (newpercent != oldpercent) {
95    snprintf(buf, sizeof buf, "percent %d\n", (int)(fraction * 100.0));
96    interpret(buf);
97    oldpercent = newpercent;
98  }
99}
100
101/* create_testfrac_choice(w)
102** -------------------------
103** Inside w (a form widget), creates:
104**   1. A label "Percentage of Test"
105**   2. A scrollbar for the user to choose the percentage (from 0 to 100)
106**   3. A label with the current percentage displayed on it.
107** The percentage starts at 100.
108**
109** When the pointer leaves the scrollbar, a string is sent to interpret()
110** so that it knows the position of the scrollbar.
111*/
112
113void
114create_testfrac_choice(Widget w)
115{
116  static XtCallbackRec jumpcallbacks[] = {
117    {(XtCallbackProc) slider_jump, NULL},
118    {NULL,                         NULL}
119  };
120
121  static XtCallbackRec scrollcallbacks[] = {
122    {(XtCallbackProc) slider_scroll, NULL},
123    {NULL,                           NULL}
124  };
125
126  static Arg labelargs[] = {
127    {XtNborderWidth,  (XtArgVal) 0},
128    {XtNjustify,      (XtArgVal) XtJustifyRight},
129    {XtNvertDistance, (XtArgVal) 4}
130  };
131
132  static Arg percentargs[] = {
133    {XtNhorizDistance,  (XtArgVal) 10},
134    {XtNfromHoriz,      (XtArgVal) NULL}
135  };
136
137  static Arg scrollargs[] = {
138    {XtNorientation,     (XtArgVal) XtorientHorizontal},
139    {XtNlength,          (XtArgVal) SCROLLBAR_LENGTH},
140    {XtNthickness,       (XtArgVal) 10},
141    {XtNshown,           (XtArgVal) 10},
142    {XtNhorizDistance,   (XtArgVal) 10},
143    {XtNfromHoriz,       (XtArgVal) NULL},
144    {XtNjumpProc,        (XtArgVal) NULL},
145    {XtNscrollProc,      (XtArgVal) NULL}
146  };
147
148  static const char *translationtable = "<Leave>: Update()";
149
150  static XtActionsRec actiontable[] = {
151    {"Update",  (XtActionProc) update},
152    {NULL,      NULL}
153  };
154
155  /* Let the scrollbar know where to store information where we
156  ** can see it */
157
158  jumpcallbacks[0].closure = (caddr_t) &fraction;
159
160  label = XtCreateManagedWidget("Percentage of Test",labelWidgetClass,w,
161				labelargs,XtNumber(labelargs));
162
163  percentargs[1].value = (XtArgVal) label;
164
165  percent = XtCreateManagedWidget("100",labelWidgetClass,w,
166				  percentargs,XtNumber(percentargs));
167
168  scrollargs[5].value = (XtArgVal) percent;
169  scrollargs[6].value = (XtArgVal) jumpcallbacks;
170  scrollargs[7].value = (XtArgVal) scrollcallbacks;
171
172  slider = XtCreateManagedWidget("Slider",scrollbarWidgetClass,w,
173				 scrollargs,XtNumber(scrollargs));
174
175  XtAppAddActions(appcontext,actiontable,XtNumber(actiontable));
176  XtOverrideTranslations(slider,XtParseTranslationTable(translationtable));
177
178  /* Start the thumb out at 100% */
179
180  XawScrollbarSetThumb(slider, 1.0 - SLIDER_LENGTH, SLIDER_LENGTH);
181}
182
183void
184update_slider(int newpercent)
185{
186  fraction = (float) newpercent / 100.0;
187  XawScrollbarSetThumb(slider, fraction / (1.0-SLIDER_LENGTH), SLIDER_LENGTH);
188}
189