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