1 #include <cdk_int.h>
2 
3 /*
4  * $Author: tom $
5  * $Date: 2016/11/20 18:32:34 $
6  * $Revision: 1.25 $
7  */
8 
9 /*
10  * Declare file local prototypes.
11  */
12 static void drawCDK<MIXED>Field (CDK<UPPER> * widget);
13 
14 DeclareCDKObjects (<UPPER>, <MIXED>, setCdk, <DTYPE>);
15 
16 /*
17  * This function creates a widget.
18  */
19 CDK<UPPER> *newCDK<MIXED> (CDKSCREEN *cdkscreen,
20 			   int xplace,
21 			   int yplace,
22 			   const char *title,
23 			   const char *label,
24 			   chtype fieldAttr,
25 			   int fieldWidth,
26 			   <CTYPE> start,
27 			   <CTYPE> low,
28 			   <CTYPE> high,
29 			   <CTYPE> inc,
30 			   <CTYPE> fastInc,
31 #if <FLOAT>
32 			   int digits,
33 #endif <FLOAT>
34 			   boolean Box,
35 			   boolean shadow)
36 {
37    /* *INDENT-EQLS* */
38    CDK<UPPER> *widget   = 0;
39    int parentWidth      = getmaxx (cdkscreen->window);
40    int parentHeight     = getmaxy (cdkscreen->window);
41    int boxHeight;
42    int boxWidth;
43    int horizontalAdjust, oldWidth;
44    int xpos             = xplace;
45    int ypos             = yplace;
46    int x, junk;
47    /* *INDENT-OFF* */
48    static const struct { int from; int to; } bindings[] = {
49 		{ 'u',		KEY_UP },
50 		{ 'U',		KEY_PPAGE },
51 		{ CDK_BACKCHAR,	KEY_PPAGE },
52 		{ CDK_FORCHAR,	KEY_NPAGE },
53 		{ 'g',		KEY_HOME },
54 		{ '^',		KEY_HOME },
55 		{ 'G',		KEY_END },
56 		{ '$',		KEY_END },
57    };
58    /* *INDENT-ON* */
59 
60 
61    if ((widget = newCDKObject (CDK<UPPER>, &my_funcs)) == 0)
62       return (0);
63 
64    setCDK<MIXED>Box (widget, Box);
65 
66    boxHeight = (BorderOf (widget) * 2) + 1;
67 
68    /* Set some basic values of the widget's data field. */
69    widget->label = 0;
70    widget->labelLen = 0;
71    widget->labelWin = 0;
72 
73    /*
74     * If the fieldWidth is a negative value, the fieldWidth will
75     * be COLS-fieldWidth, otherwise, the fieldWidth will be the
76     * given width.
77     */
78    fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0);
79    boxWidth = fieldWidth + 2 * BorderOf (widget);
80 
81    /* Translate the label char *pointer to a chtype pointer. */
82    if (label != 0)
83    {
84       widget->label = char2Chtype (label, &widget->labelLen, &junk);
85       boxWidth = widget->labelLen + fieldWidth + 2;
86    }
87 
88    oldWidth = boxWidth;
89    boxWidth = setCdkTitle (ObjOf (widget), title, boxWidth);
90    horizontalAdjust = (boxWidth - oldWidth) / 2;
91 
92    boxHeight += TitleLinesOf (widget);
93 
94    /*
95     * Make sure we didn't extend beyond the dimensions of the window.
96     */
97    boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
98    boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
99    fieldWidth = (fieldWidth > (boxWidth - widget->labelLen - 2 * BorderOf (widget))
100 		 ? (boxWidth - widget->labelLen - 2 * BorderOf (widget))
101 		 : fieldWidth);
102 
103    /* Rejustify the x and y positions if we need to. */
104    alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
105 
106    /* Make the widget's window. */
107    widget->win = newwin (boxHeight, boxWidth, ypos, xpos);
108 
109    /* Is the main window null??? */
110    if (widget->win == 0)
111    {
112       destroyCDKObject (widget);
113       return (0);
114    }
115 
116    /* Create the widget's label window. */
117    if (widget->label != 0)
118    {
119       widget->labelWin = subwin (widget->win,
120 				 1, widget->labelLen,
121 				 ypos + TitleLinesOf (widget) + BorderOf (widget),
122 				 xpos + horizontalAdjust + BorderOf (widget));
123       if (widget->labelWin == 0)
124       {
125 	 destroyCDKObject (widget);
126 	 return (0);
127       }
128    }
129 
130    /* Create the widget's data field window. */
131    widget->fieldWin = subwin (widget->win,
132 			      1, fieldWidth,
133 			      (ypos + TitleLinesOf (widget) + BorderOf (widget)),
134 			      (xpos
135 			       + widget->labelLen
136 			       + horizontalAdjust
137 			       + BorderOf (widget)));
138    if (widget->fieldWin == 0)
139    {
140       destroyCDKObject (widget);
141       return (0);
142    }
143    keypad (widget->fieldWin, TRUE);
144    keypad (widget->win, TRUE);
145 
146    /* *INDENT-EQLS* Create the widget's data field. */
147    ScreenOf (widget)            = cdkscreen;
148    widget->parent               = cdkscreen->window;
149    widget->shadowWin            = 0;
150    widget->boxWidth             = boxWidth;
151    widget->boxHeight            = boxHeight;
152    widget->fieldWidth           = fieldWidth;
153    widget->fieldAttr            = (chtype)fieldAttr;
154    widget->current              = low;
155    widget->low                  = low;
156    widget->high                 = high;
157    widget->current              = start;
158    widget->inc                  = inc;
159    widget->fastinc              = fastInc;
160 #if <FLOAT>
161    widget->digits               = digits;
162 #endif <FLOAT>
163    initExitType (widget);
164    ObjOf (widget)->acceptsFocus = TRUE;
165    ObjOf (widget)->inputWindow  = widget->win;
166    widget->shadow               = shadow;
167 
168    /* Do we want a shadow??? */
169    if (shadow)
170    {
171       widget->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
172       if (widget->shadowWin == 0)
173       {
174 	 destroyCDKObject (widget);
175 	 return (0);
176       }
177    }
178 
179    /* Setup the key bindings. */
180    for (x = 0; x < (int)SIZEOF (bindings); ++x)
181       bindCDKObject (v<UPPER>,
182 		     widget,
183 		     (chtype) bindings[x].from,
184 		     getcCDKBind,
185 		     (void *)(long)bindings[x].to);
186 
187    registerCDKObject (cdkscreen, v<UPPER>, widget);
188 
189    return (widget);
190 }
191 
192 /*
193  * This allows the person to use the widget's data field.
194  */
195 <CTYPE> activateCDK<MIXED> (CDK<UPPER> * widget, chtype *actions)
196 {
197    <CTYPE> ret;
198 
199    /* Draw the widget. */
200    drawCDK<MIXED> (widget, ObjOf (widget)->box);
201 
202    if (actions == 0)
203    {
204       chtype input = 0;
205       boolean functionKey;
206 
207       for (;;)
208       {
209 	 input = (chtype) getchCDKObject (ObjOf (widget), &functionKey);
210 
211 	 /* Inject the character into the widget. */
212 	 ret = (<CTYPE>) injectCDK<MIXED> (widget, input);
213 	 if (widget->exitType != vEARLY_EXIT)
214 	 {
215 	    return ret;
216 	 }
217       }
218    }
219    else
220    {
221       int length = chlen (actions);
222       int x = 0;
223 
224       /* Inject each character one at a time. */
225       for (x = 0; x < length; x++)
226       {
227 	 ret = (<CTYPE>) injectCDK<MIXED> (widget, actions[x]);
228 	 if (widget->exitType != vEARLY_EXIT)
229 	 {
230 	    return ret;
231 	 }
232       }
233    }
234 
235    /* Set the exit type and return. */
236    setExitType (widget, 0);
237    return unknown<DTYPE>;
238 }
239 
240 /*
241  * Check if the value lies outside the low/high range.  If so, force it in.
242  */
limitCurrentValue(CDK<UPPER> * widget)243 static void limitCurrentValue (CDK<UPPER> * widget)
244 {
245    if (widget->current < widget->low)
246    {
247       widget->current = widget->low;
248       Beep ();
249    }
250    else if (widget->current > widget->high)
251    {
252       widget->current = widget->high;
253       Beep ();
254    }
255 }
256 
257 /*
258  * Move the cursor to the given edit-position.
259  */
moveToEditPosition(CDK<UPPER> * widget,int newPosition)260 static int moveToEditPosition (CDK<UPPER> * widget, int newPosition)
261 {
262    return wmove (widget->fieldWin, 0, widget->fieldWidth - newPosition - 1);
263 }
264 
265 /*
266  * Check if the cursor is on a valid edit-position.  This must be one of
267  * the non-blank cells in the field.
268  */
validEditPosition(CDK<UPPER> * widget,int newPosition)269 static int validEditPosition (CDK<UPPER> * widget, int newPosition)
270 {
271    chtype ch;
272    if (newPosition <= 0 || newPosition >= widget->fieldWidth)
273       return FALSE;
274    if (moveToEditPosition (widget, newPosition) == ERR)
275       return FALSE;
276    ch = winch (widget->fieldWin);
277    if (CharOf (ch) != ' ')
278       return TRUE;
279    if (newPosition > 1)
280    {
281       /* don't use recursion - only one level is wanted */
282       if (moveToEditPosition (widget, newPosition - 1) == ERR)
283 	 return FALSE;
284       ch = winch (widget->fieldWin);
285       return CharOf (ch) != ' ';
286    }
287    return FALSE;
288 }
289 
290 /*
291  * Set the edit position.  Normally the cursor is one cell to the right of
292  * the editable field.  Moving it left, over the field allows the user to
293  * modify cells by typing in replacement characters for the field's value.
294  */
setEditPosition(CDK<UPPER> * widget,int newPosition)295 static void setEditPosition (CDK<UPPER> * widget, int newPosition)
296 {
297    if (newPosition < 0)
298    {
299       Beep ();
300    }
301    else if (newPosition == 0)
302    {
303       widget->fieldEdit = newPosition;
304    }
305    else if (validEditPosition (widget, newPosition))
306    {
307       widget->fieldEdit = newPosition;
308    }
309    else
310    {
311       Beep ();
312    }
313 }
314 
315 /*
316  * Remove the character from the string at the given column, if it is blank.
317  * Returns true if a change was made.
318  */
removeChar(char * string,int col)319 static bool removeChar (char *string, int col)
320 {
321    bool result = FALSE;
322 
323    if ((col >= 0) && (string[col] != ' '))
324    {
325       while (string[col] != '\0')
326       {
327 	 string[col] = string[col + 1];
328 	 ++col;
329       }
330       result = TRUE;
331    }
332    return result;
333 }
334 
335 /*
336  * Perform an editing function for the field.
337  */
performEdit(CDK<UPPER> * widget,chtype input)338 static bool performEdit (CDK<UPPER> * widget, chtype input)
339 {
340    bool result = FALSE;
341    bool modify = TRUE;
342    int need = widget->fieldWidth;
343    char *temp = (char *)malloc ((size_t) need + 2);
344    char test;
345    int col = need - widget->fieldEdit - 1;
346 #if <FLOAT>
347    double value;
348 #define SCANF_FMT "%lg%c"
349 #endif <FLOAT>
350 #if <INT>
351    <CTYPE> value;
352 #define SCANF_FMT "%<PRINT>%c"
353 #endif <INT>
354 
355    if (temp != 0)
356    {
357       int base = 0;
358 
359       wmove (widget->fieldWin, 0, base);
360       winnstr (widget->fieldWin, temp, need);
361       strcpy (temp + need, " ");
362       if (isChar (input))	/* replace the char at the cursor */
363       {
364 	 temp[col] = (char) (input);
365       }
366       else if (input == KEY_BACKSPACE)	/* delete the char before the cursor */
367       {
368 	 modify = removeChar (temp, col - 1);
369       }
370       else if (input == KEY_DC)	/* delete the char at the cursor */
371       {
372 	 modify = removeChar (temp, col);
373       }
374       else
375       {
376 	 modify = FALSE;
377       }
378       if (modify
379 	  && sscanf (temp, SCANF_FMT, &value, &test) == 2
380 	  && test == ' '
381 	  && value >= widget->low
382 	  && value <= widget->high)
383       {
384 	 setCDK<MIXED>Value (widget, (<CTYPE>) value);
385 	 result = TRUE;
386       }
387       free (temp);
388    }
389    return result;
390 }
391 
392 #define Decrement(value,by) if (value - by < value) value -= by
393 #define Increment(value,by) if (value + by > value) value += by
394 
395 /*
396  * This function injects a single character into the widget.
397  */
398 static int _injectCDK<MIXED> (CDKOBJS *object, chtype input)
399 {
400    CDK<UPPER> *widget = (CDK<UPPER> *) object;
401    int ppReturn = 1;
402    <CTYPE> ret = unknown<DTYPE>;
403    bool complete = FALSE;
404 
405    /* Set the exit type. */
406    setExitType (widget, 0);
407 
408    /* Draw the field. */
409    drawCDK<MIXED>Field (widget);
410 
411    /* Check if there is a pre-process function to be called. */
412    if (PreProcessFuncOf (widget) != 0)
413    {
414       /* Call the pre-process function. */
415       ppReturn = PreProcessFuncOf (widget) (v<UPPER>,
416 					    widget,
417 					    PreProcessDataOf (widget),
418 					    input);
419    }
420 
421    /* Should we continue? */
422    if (ppReturn != 0)
423    {
424       /* Check for a key binding. */
425       if (checkCDKObjectBind (v<UPPER>, widget, input) != 0)
426       {
427 	 checkEarlyExit (widget);
428 	 complete = TRUE;
429       }
430       else
431       {
432 	 switch (input)
433 	 {
434 	 case KEY_LEFT:
435 	    setEditPosition (widget, widget->fieldEdit + 1);
436 	    break;
437 
438 	 case KEY_RIGHT:
439 	    setEditPosition (widget, widget->fieldEdit - 1);
440 	    break;
441 
442 	 case KEY_DOWN:
443 	    Decrement (widget->current, widget->inc);
444 	    break;
445 
446 	 case KEY_UP:
447 	    Increment (widget->current, widget->inc);
448 	    break;
449 
450 	 case KEY_PPAGE:
451 	    Increment (widget->current, widget->fastinc);
452 	    break;
453 
454 	 case KEY_NPAGE:
455 	    Decrement (widget->current, widget->fastinc);
456 	    break;
457 
458 	 case KEY_HOME:
459 	    widget->current = widget->low;
460 	    break;
461 
462 	 case KEY_END:
463 	    widget->current = widget->high;
464 	    break;
465 
466 	 case KEY_TAB:
467 	 case KEY_ENTER:
468 	    setExitType (widget, input);
469 	    ret = (widget->current);
470 	    complete = TRUE;
471 	    break;
472 
473 	 case KEY_ESC:
474 	    setExitType (widget, input);
475 	    complete = TRUE;
476 	    break;
477 
478 	 case KEY_ERROR:
479 	    setExitType (widget, input);
480 	    complete = TRUE;
481 	    break;
482 
483 	 case CDK_REFRESH:
484 	    eraseCDKScreen (ScreenOf (widget));
485 	    refreshCDKScreen (ScreenOf (widget));
486 	    break;
487 
488 	 default:
489 	    if (widget->fieldEdit)
490 	    {
491 	       if (!performEdit (widget, input))
492 		  Beep ();
493 	    }
494 	    else
495 	    {
496 	       /*
497 	        * The cursor is not within the editable text.  Interpret
498 	        * input as commands.
499 	        */
500 	       switch (input)
501 	       {
502 	       case 'd':
503 	       case '-':
504 		  return _injectCDK<MIXED> (object, KEY_DOWN);
505 	       case '+':
506 		  return _injectCDK<MIXED> (object, KEY_UP);
507 	       case 'D':
508 		  return _injectCDK<MIXED> (object, KEY_NPAGE);
509 	       case '0':
510 		  return _injectCDK<MIXED> (object, KEY_HOME);
511 	       default:
512 		  Beep ();
513 		  break;
514 	       }
515 	    }
516 	    break;
517 	 }
518       }
519       limitCurrentValue (widget);
520 
521       /* Should we call a post-process? */
522       if (!complete && (PostProcessFuncOf (widget) != 0))
523       {
524 	 PostProcessFuncOf (widget) (v<UPPER>,
525 				     widget,
526 				     PostProcessDataOf (widget),
527 				     input);
528       }
529    }
530 
531    if (!complete)
532    {
533       drawCDK<MIXED>Field (widget);
534       setExitType (widget, 0);
535    }
536 
537    ResultOf (widget).value<DTYPE> = ret;
538    return (ret != unknown<DTYPE>);
539 }
540 
541 /*
542  * This moves the widget's data field to the given location.
543  */
544 static void _moveCDK<MIXED> (CDKOBJS *object,
545 			     int xplace,
546 			     int yplace,
547 			     boolean relative,
548 			     boolean refresh_flag)
549 {
550    CDK<UPPER> *widget = (CDK<UPPER> *) object;
551    int currentX = getbegx (widget->win);
552    int currentY = getbegy (widget->win);
553    int xpos = xplace;
554    int ypos = yplace;
555    int xdiff = 0;
556    int ydiff = 0;
557 
558    /*
559     * If this is a relative move, then we will adjust where we want
560     * to move to.
561     */
562    if (relative)
563    {
564       xpos = getbegx (widget->win) + xplace;
565       ypos = getbegy (widget->win) + yplace;
566    }
567 
568    /* Adjust the window if we need to. */
569    alignxy (WindowOf (widget), &xpos, &ypos, widget->boxWidth, widget->boxHeight);
570 
571    /* Get the difference. */
572    xdiff = currentX - xpos;
573    ydiff = currentY - ypos;
574 
575    /* Move the window to the new location. */
576    moveCursesWindow (widget->win, -xdiff, -ydiff);
577    moveCursesWindow (widget->labelWin, -xdiff, -ydiff);
578    moveCursesWindow (widget->fieldWin, -xdiff, -ydiff);
579    moveCursesWindow (widget->shadowWin, -xdiff, -ydiff);
580 
581    /* Touch the windows so they 'move'. */
582    refreshCDKWindow (WindowOf (widget));
583 
584    /* Redraw the window, if they asked for it. */
585    if (refresh_flag)
586    {
587       drawCDK<MIXED> (widget, ObjOf (widget)->box);
588    }
589 }
590 
591 /*
592  * This function draws the widget.
593  */
594 static void _drawCDK<MIXED> (CDKOBJS *object, boolean Box)
595 {
596    CDK<UPPER> *widget = (CDK<UPPER> *) object;
597 
598    /* Draw the shadow. */
599    if (widget->shadowWin != 0)
600    {
601       drawShadow (widget->shadowWin);
602    }
603 
604    /* Box the widget if asked. */
605    if (Box)
606    {
607       drawObjBox (widget->win, ObjOf (widget));
608    }
609 
610    drawCdkTitle (widget->win, object);
611 
612    /* Draw the label. */
613    if (widget->labelWin != 0)
614    {
615       writeChtype (widget->labelWin, 0, 0,
616 		   widget->label,
617 		   HORIZONTAL, 0,
618 		   widget->labelLen);
619       wrefresh (widget->labelWin);
620    }
621    wrefresh (widget->win);
622 
623    /* Draw the field window. */
624    drawCDK<MIXED>Field (widget);
625 }
626 
627 /*
628  * This draws the widget.
629  */
Field(CDK<UPPER> * widget)630 static void drawCDK<MIXED>Field (CDK<UPPER> * widget)
631 {
632    char temp[256];
633 
634    werase (widget->fieldWin);
635 
636    /* Draw the value in the field. */
637 #if <FLOAT>
638    {
639       char format[256];
640       int digits = MINIMUM (widget->digits, 30);
641       sprintf (format, "%%.%i<PRINT>", digits);
642       sprintf (temp, format, widget->current);
643    }
644 #endif <FLOAT>
645 #if <INT>
646    sprintf (temp, "%<PRINT>", widget->current);
647 #endif <INT>
648    writeCharAttrib (widget->fieldWin,
649 		    widget->fieldWidth - (int)strlen (temp) - 1,
650 		    0,
651 		    temp,
652 		    widget->fieldAttr,
653 		    HORIZONTAL,
654 		    0,
655 		    (int)strlen (temp));
656 
657    moveToEditPosition (widget, widget->fieldEdit);
658    wrefresh (widget->fieldWin);
659 }
660 
661 /*
662  * This sets the background attribute of the widget.
663  */
664 static void _setBKattr<MIXED> (CDKOBJS *object, chtype attrib)
665 {
666    if (object != 0)
667    {
668       CDK<UPPER> *widget = (CDK<UPPER> *) object;
669 
670       wbkgd (widget->win, attrib);
671       wbkgd (widget->fieldWin, attrib);
672       if (widget->labelWin != 0)
673       {
674 	 wbkgd (widget->labelWin, attrib);
675       }
676    }
677 }
678 
679 /*
680  * This function destroys the widget.
681  */
682 static void _destroyCDK<MIXED> (CDKOBJS *object)
683 {
684    if (object != 0)
685    {
686       CDK<UPPER> *widget = (CDK<UPPER> *) object;
687 
688       cleanCdkTitle (object);
689       freeChtype (widget->label);
690 
691       /* Clean up the windows. */
692       deleteCursesWindow (widget->fieldWin);
693       deleteCursesWindow (widget->labelWin);
694       deleteCursesWindow (widget->shadowWin);
695       deleteCursesWindow (widget->win);
696 
697       /* Clean the key bindings. */
698       cleanCDKObjectBindings (v<UPPER>, widget);
699 
700       /* Unregister this object. */
701       unregisterCDKObject (v<UPPER>, widget);
702    }
703 }
704 
705 /*
706  * This function erases the widget from the screen.
707  */
708 static void _eraseCDK<MIXED> (CDKOBJS *object)
709 {
710    if (validCDKObject (object))
711    {
712       CDK<UPPER> *widget = (CDK<UPPER> *) object;
713 
714       eraseCursesWindow (widget->labelWin);
715       eraseCursesWindow (widget->fieldWin);
716       eraseCursesWindow (widget->win);
717       eraseCursesWindow (widget->shadowWin);
718    }
719 }
720 
721 /*
722  * This function sets the low/high/current values of the widget.
723  */
724 void setCDK<MIXED> (CDK<UPPER> * widget, <CTYPE> low, <CTYPE> high, <CTYPE> value, boolean Box)
725 {
726    setCDK<MIXED>LowHigh (widget, low, high);
727    setCDK<MIXED>Value (widget, value);
728    setCDK<MIXED>Box (widget, Box);
729 }
730 
731 /*
732  * This sets the digits.
733  */
734 #if <FLOAT>
Digits(CDK<UPPER> * widget,int digits)735 void setCDK<MIXED>Digits (CDK<UPPER> * widget, int digits)
736 {
737    widget->digits = MAXIMUM (0, digits);
738 }
739 
Digits(CDK<UPPER> * widget)740 int getCDK<MIXED>Digits (CDK<UPPER> * widget)
741 {
742    return widget->digits;
743 }
744 #endif <FLOAT>
745 
746 /*
747  * This sets the widget's value.
748  */
749 void setCDK<MIXED>Value (CDK<UPPER> * widget, <CTYPE> value)
750 {
751    widget->current = value;
752    limitCurrentValue (widget);
753 }
Value(CDK<UPPER> * widget)754 <CTYPE> getCDK<MIXED>Value (CDK<UPPER> * widget)
755 {
756    return widget->current;
757 }
758 
759 /*
760  * This function sets the low/high values of the widget.
761  */
762 void setCDK<MIXED>LowHigh (CDK<UPPER> * widget, <CTYPE> low, <CTYPE> high)
763 {
764    /* Make sure the values aren't out of bounds. */
765    if (low <= high)
766    {
767       widget->low = low;
768       widget->high = high;
769    }
770    else
771    {
772       widget->low = high;
773       widget->high = low;
774    }
775 
776    /* Make sure the user hasn't done something silly. */
777    limitCurrentValue (widget);
778 }
LowValue(CDK<UPPER> * widget)779 <CTYPE> getCDK<MIXED>LowValue (CDK<UPPER> * widget)
780 {
781    return widget->low;
782 }
HighValue(CDK<UPPER> * widget)783 <CTYPE> getCDK<MIXED>HighValue (CDK<UPPER> * widget)
784 {
785    return widget->high;
786 }
787 
788 /*
789  * This sets the widget's box attribute.
790  */
Box(CDK<UPPER> * widget,boolean Box)791 void setCDK<MIXED>Box (CDK<UPPER> * widget, boolean Box)
792 {
793    ObjOf (widget)->box = Box;
794    ObjOf (widget)->borderSize = Box ? 1 : 0;
795 }
Box(CDK<UPPER> * widget)796 boolean getCDK<MIXED>Box (CDK<UPPER> * widget)
797 {
798    return ObjOf (widget)->box;
799 }
800 
801 static void _focusCDK<MIXED> (CDKOBJS *object)
802 {
803    CDK<UPPER> *widget = (CDK<UPPER> *) object;
804 
805    drawCDK<MIXED> (widget, ObjOf (widget)->box);
806 }
807 
808 static void _unfocusCDK<MIXED> (CDKOBJS *object)
809 {
810    CDK<UPPER> *widget = (CDK<UPPER> *) object;
811 
812    drawCDK<MIXED> (widget, ObjOf (widget)->box);
813 }
814 
815 dummyRefreshData (<MIXED>)
816 
817 dummySaveData (<MIXED>)
818