1 /* $Id: cdkslider.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
2 
3 #include <cdk_test.h>
4 
5 #ifdef XCURSES
6 char *XCursesProgramName = "cdkslider";
7 #endif
8 
9 /*
10  * Declare file local prototypes.
11  */
12 static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
13 
14 /*
15  * Define file local variables.
16  */
17 static const char *FPUsage = "-f Field Width -l Low Value -h High Value [-s Initial Value]] [-i Increment Value] [-a Accelerated Increment Value] [-F Field Character] [-T Title] [-L Label] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-N] [-S]";
18 
19 /*
20  *
21  */
main(int argc,char ** argv)22 int main (int argc, char **argv)
23 {
24    /* *INDENT-EQLS* */
25    CDKSCREEN *cdkScreen         = 0;
26    CDKSLIDER *widget            = 0;
27    CDKBUTTONBOX *buttonWidget   = 0;
28    char *CDK_WIDGET_COLOR       = 0;
29    char *temp                   = 0;
30    chtype *holder               = 0;
31    chtype fieldAttr             = A_REVERSE | ' ';
32    int answer                   = 0;
33    int buttonCount              = 0;
34    int selection                = 0;
35    int shadowHeight             = 0;
36    FILE *fp                     = stderr;
37    char **buttonList            = 0;
38    int j1, j2, tmp;
39 
40    CDK_PARAMS params;
41    boolean boxWidget;
42    boolean shadowWidget;
43    char *barAttribute;
44    char *buttons;
45    char *label;
46    char *outputFile;
47    char *title;
48    int fieldWidth;
49    int incrementStep;
50    int acceleratedStep;
51    int initValue;
52    int lowValue;
53    int highValue;
54    int xpos;
55    int ypos;
56 
57    CDKparseParams (argc, argv, &params, "a:f:h:i:l:s:B:F:L:O:T:" CDK_MIN_PARAMS);
58 
59    /* *INDENT-EQLS* */
60    xpos            = CDKparamValue (&params, 'X', CENTER);
61    ypos            = CDKparamValue (&params, 'Y', CENTER);
62    boxWidget       = CDKparamValue (&params, 'N', TRUE);
63    shadowWidget    = CDKparamValue (&params, 'S', FALSE);
64    acceleratedStep = CDKparamValue (&params, 'a', -1);
65    fieldWidth      = CDKparamValue (&params, 'f', 0);
66    highValue       = CDKparamValue (&params, 'h', INT_MIN);
67    incrementStep   = CDKparamValue (&params, 'i', 1);
68    lowValue        = CDKparamValue (&params, 'l', INT_MAX);
69    initValue       = CDKparamValue (&params, 's', INT_MIN);
70    buttons         = CDKparamString (&params, 'B');
71    barAttribute    = CDKparamString (&params, 'F');
72    label           = CDKparamString (&params, 'L');
73    outputFile      = CDKparamString (&params, 'O');
74    title           = CDKparamString (&params, 'T');
75    incrementStep   = abs (incrementStep);
76 
77    /* Make sure all the command line parameters were provided. */
78    if (fieldWidth <= 0)
79    {
80       fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
81       ExitProgram (CLI_ERROR);
82    }
83 
84    /* Make sure the user supplied the low/high values. */
85    if ((lowValue == INT_MAX) || (highValue == INT_MIN))
86    {
87       fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
88       ExitProgram (CLI_ERROR);
89    }
90 
91    /* If the user asked for an output file, try to open it. */
92    if (outputFile != 0)
93    {
94       if ((fp = fopen (outputFile, "w")) == 0)
95       {
96 	 fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
97 	 ExitProgram (CLI_ERROR);
98       }
99    }
100 
101    /* Make sure the low is lower than the high (and vice versa). */
102    if (lowValue > highValue)
103    {
104       tmp = lowValue;
105       lowValue = highValue;
106       highValue = tmp;
107    }
108 
109    /* Make sure the starting value is in range. */
110    if (initValue < lowValue)
111    {
112       initValue = lowValue;
113    }
114    else if (initValue > highValue)
115    {
116       initValue = highValue;
117    }
118 
119    /* Check if the accelerated incremnt value was set. */
120    if (acceleratedStep <= 0)
121    {
122       acceleratedStep = (int)((highValue - lowValue) / 10);
123       acceleratedStep = MAXIMUM (1, acceleratedStep);
124    }
125 
126    cdkScreen = initCDKScreen (NULL);
127 
128    /* Start color. */
129    initCDKColor ();
130 
131    /* Check if the user wants to set the background of the main screen. */
132    if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
133    {
134       holder = char2Chtype (temp, &j1, &j2);
135       wbkgd (cdkScreen->window, holder[0]);
136       wrefresh (cdkScreen->window);
137       freeChtype (holder);
138    }
139 
140    /* Get the widget color background color. */
141    if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
142    {
143       CDK_WIDGET_COLOR = 0;
144    }
145 
146    /* Did the user ask to change the bar attribute? */
147    if (barAttribute != 0)
148    {
149       holder = char2Chtype (barAttribute, &j1, &j2);
150       fieldAttr = holder[0];
151       freeChtype (holder);
152    }
153 
154    /* Create the entry widget. */
155    widget = newCDKSlider (cdkScreen, xpos, ypos,
156 			  title, label,
157 			  fieldAttr, fieldWidth,
158 			  initValue, lowValue, highValue,
159 			  incrementStep, acceleratedStep,
160 			  boxWidget, shadowWidget);
161 
162    /* Check to make sure we created the dialog box. */
163    if (widget == 0)
164    {
165       /* Shut down curses and CDK. */
166       destroyCDKScreen (cdkScreen);
167       endCDK ();
168 
169       fprintf (stderr,
170 	       "Error: Could not create the numeric slider field. "
171 	       "Is the window too small?\n");
172 
173       ExitProgram (CLI_ERROR);
174    }
175 
176    /* Split the buttons if they supplied some. */
177    if (buttons != 0)
178    {
179       /* Split the button list up. */
180       buttonList = CDKsplitString (buttons, '\n');
181       buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
182 
183       /* We need to create a buttonbox widget. */
184       buttonWidget = newCDKButtonbox (cdkScreen,
185 				      getbegx (widget->win),
186 				      (getbegy (widget->win)
187 				       + widget->boxHeight - 1),
188 				      1, widget->boxWidth - 1,
189 				      0, 1, buttonCount,
190 				      (CDK_CSTRING2) buttonList, buttonCount,
191 				      A_REVERSE, boxWidget, FALSE);
192       CDKfreeStrings (buttonList);
193 
194       setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
195       setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
196 
197       /*
198        * We need to set the lower left and right
199        * characters of the widget.
200        */
201       setCDKSliderLLChar (widget, ACS_LTEE);
202       setCDKSliderLRChar (widget, ACS_RTEE);
203 
204       /*
205        * Bind the Tab key in the widget to send a
206        * Tab key to the button box widget.
207        */
208       bindCDKObject (vSLIDER, widget, KEY_TAB, widgetCB, buttonWidget);
209       bindCDKObject (vSLIDER, widget, CDK_NEXT, widgetCB, buttonWidget);
210       bindCDKObject (vSLIDER, widget, CDK_PREV, widgetCB, buttonWidget);
211 
212       /* Check if the user wants to set the background of the widget. */
213       setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
214 
215       /* Draw the button widget. */
216       drawCDKButtonbox (buttonWidget, boxWidget);
217    }
218 
219    /*
220     * If the user asked for a shadow, we need to create one.  Do this instead
221     * of using the shadow parameter because the button widget is not part of
222     * the main widget and if the user asks for both buttons and a shadow, we
223     * need to create a shadow big enough for both widgets.  Create the shadow
224     * window using the widgets shadowWin element, so screen refreshes will draw
225     * them as well.
226     */
227    if (shadowWidget == TRUE)
228    {
229       /* Determine the height of the shadow window. */
230       shadowHeight = (buttonWidget == 0 ?
231 		      widget->boxHeight :
232 		      widget->boxHeight + buttonWidget->boxHeight - 1);
233 
234       /* Create the shadow window. */
235       widget->shadowWin = newwin (shadowHeight,
236 				  widget->boxWidth,
237 				  getbegy (widget->win) + 1,
238 				  getbegx (widget->win) + 1);
239 
240       /* Make sure we could have created the shadow window. */
241       if (widget->shadowWin != 0)
242       {
243 	 widget->shadow = TRUE;
244 
245 	 /*
246 	  * We force the widget and buttonWidget to be drawn so the
247 	  * buttonbox widget will be drawn when the widget is activated.
248 	  * Otherwise the shadow window will draw over the button widget.
249 	  */
250 	 drawCDKSlider (widget, ObjOf (widget)->box);
251 	 eraseCDKButtonbox (buttonWidget);
252 	 drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
253       }
254    }
255 
256    /* Check if the user wants to set the background of the widget. */
257    setCDKSliderBackgroundColor (widget, CDK_WIDGET_COLOR);
258 
259    /* Activate the widget. */
260    answer = activateCDKSlider (widget, 0);
261 
262    /* If there were buttons, get the button selected. */
263    if (buttonWidget != 0)
264    {
265       selection = buttonWidget->currentButton;
266       destroyCDKButtonbox (buttonWidget);
267    }
268 
269    /* End CDK. */
270    destroyCDKSlider (widget);
271    destroyCDKScreen (cdkScreen);
272    endCDK ();
273 
274    /* Print the value from the widget. */
275    fprintf (fp, "%d\n", answer);
276    fclose (fp);
277 
278    /* Exit with the button selected. */
279    ExitProgram (selection);
280 }
281 
widgetCB(EObjectType cdktype GCC_UNUSED,void * object GCC_UNUSED,void * clientData,chtype key)282 static int widgetCB (EObjectType cdktype GCC_UNUSED,
283 		     void *object GCC_UNUSED,
284 		     void *clientData,
285 		     chtype key)
286 {
287    CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
288    (void) injectCDKButtonbox (buttonbox, key);
289    return (TRUE);
290 }
291