1 #include <cdk_int.h>
2 #include <scroller.h>
3 
4 /*
5  * $Author: tom $
6  * $Date: 2019/02/20 13:45:52 $
7  * $Revision: 1.147 $
8  */
9 
10 /*
11  * Declare file local prototypes.
12  */
13 static int createList (CDKRADIO *radio, CDK_CSTRING2 list, int listSize, int width);
14 static void drawCDKRadioList (CDKRADIO *radio, boolean Box);
15 static void setViewSize (CDKRADIO *scrollp, int listSize);
16 static int maxViewSize (CDKRADIO *scrollp);
17 
18 /* Determine how many characters we can shift to the right */
19 /* before all the items have been scrolled off the screen. */
20 #define AvailableWidth(w)  ((w)->boxWidth - 2*BorderOf(w) - 3)
21 #define updateViewWidth(w, widest) \
22 	(w)->maxLeftChar = (((w)->boxWidth > widest) \
23 			      ? 0 \
24 			      : (widest - AvailableWidth(w)))
25 #define WidestItem(w)      ((w)->maxLeftChar + AvailableWidth(w))
26 
27 #define SCREENPOS(w,n) (w)->itemPos[n] - (w)->leftChar + scrollbarAdj + BorderOf(w)
28 
29 DeclareCDKObjects (RADIO, Radio, setCdk, Int);
30 
31 /*
32  * This function creates the radio widget.
33  */
newCDKRadio(CDKSCREEN * cdkscreen,int xplace,int yplace,int splace,int height,int width,const char * title,CDK_CSTRING2 list,int listSize,chtype choiceChar,int defItem,chtype highlight,boolean Box,boolean shadow)34 CDKRADIO *newCDKRadio (CDKSCREEN *cdkscreen,
35 		       int xplace,
36 		       int yplace,
37 		       int splace,
38 		       int height,
39 		       int width,
40 		       const char *title,
41 		       CDK_CSTRING2 list,
42 		       int listSize,
43 		       chtype choiceChar,
44 		       int defItem,
45 		       chtype highlight,
46 		       boolean Box,
47 		       boolean shadow)
48 {
49    /* *INDENT-EQLS* */
50    CDKRADIO *radio      = 0;
51    int parentWidth      = getmaxx (cdkscreen->window);
52    int parentHeight     = getmaxy (cdkscreen->window);
53    int boxWidth;
54    int boxHeight;
55    int xpos             = xplace;
56    int ypos             = yplace;
57    int widestItem       = 0;
58    int j;
59    /* *INDENT-OFF* */
60    static const struct { int from; int to; } bindings[] = {
61 		{ CDK_BACKCHAR,	KEY_PPAGE },
62 		{ CDK_FORCHAR,	KEY_NPAGE },
63 		{ 'g',		KEY_HOME },
64 		{ '1',		KEY_HOME },
65 		{ 'G',		KEY_END },
66 		{ '<',		KEY_HOME },
67 		{ '>',		KEY_END },
68    };
69    /* *INDENT-ON* */
70 
71    if ((radio = newCDKObject (CDKRADIO, &my_funcs)) == 0)
72    {
73       return (0);
74    }
75 
76    setCDKRadioBox (radio, Box);
77 
78    /*
79     * If the height is a negative value, the height will
80     * be ROWS-height, otherwise, the height will be the
81     * given height.
82     */
83    boxHeight = setWidgetDimension (parentHeight, height, 0);
84 
85    /*
86     * If the width is a negative value, the width will
87     * be COLS-width, otherwise, the width will be the
88     * given width.
89     */
90    boxWidth = setWidgetDimension (parentWidth, width, 5);
91 
92    boxWidth = setCdkTitle (ObjOf (radio), title, boxWidth);
93 
94    /* Set the box height. */
95    if (TitleLinesOf (radio) > boxHeight)
96    {
97       boxHeight = TitleLinesOf (radio)
98 	 + MINIMUM (listSize, 8)
99 	 + 2 * BorderOf (radio);
100    }
101 
102    /* Adjust the box width if there is a scroll bar. */
103    if (splace == LEFT || splace == RIGHT)
104    {
105       boxWidth++;
106       radio->scrollbar = TRUE;
107    }
108    else
109    {
110       radio->scrollbar = FALSE;
111    }
112 
113    /*
114     * Make sure we didn't extend beyond the dimensions of the window.
115     */
116    radio->boxWidth = MINIMUM (boxWidth, parentWidth);
117    radio->boxHeight = MINIMUM (boxHeight, parentHeight);
118 
119    setViewSize (radio, listSize);
120 
121    /* Each item in the needs to be converted to chtype * */
122    widestItem = createList (radio, list, listSize, radio->boxWidth);
123    if (widestItem > 0)
124    {
125       updateViewWidth (radio, widestItem);
126    }
127    else if (listSize)
128    {
129       destroyCDKObject (radio);
130       return (0);
131    }
132 
133    /* Rejustify the x and y positions if we need to. */
134    alignxy (cdkscreen->window, &xpos, &ypos, radio->boxWidth, radio->boxHeight);
135 
136    /* Make the radio window */
137    radio->win = newwin (radio->boxHeight, radio->boxWidth, ypos, xpos);
138 
139    /* Is the window null??? */
140    if (radio->win == 0)
141    {
142       destroyCDKObject (radio);
143       return (0);
144    }
145 
146    /* Turn on the keypad. */
147    keypad (radio->win, TRUE);
148 
149    /* Create the scrollbar window. */
150    if (splace == RIGHT)
151    {
152       radio->scrollbarWin = subwin (radio->win,
153 				    maxViewSize (radio), 1,
154 				    SCREEN_YPOS (radio, ypos),
155 				    (xpos
156 				     + radio->boxWidth
157 				     - BorderOf (radio)
158 				     - 1));
159    }
160    else if (splace == LEFT)
161    {
162       radio->scrollbarWin = subwin (radio->win,
163 				    maxViewSize (radio), 1,
164 				    SCREEN_YPOS (radio, ypos),
165 				    SCREEN_XPOS (radio, xpos));
166    }
167    else
168    {
169       radio->scrollbarWin = 0;
170    }
171 
172    /* *INDENT-EQLS* Set the rest of the variables */
173    ScreenOf (radio)             = cdkscreen;
174    radio->parent                = cdkscreen->window;
175    radio->scrollbarPlacement    = splace;
176    radio->widestItem            = widestItem;
177    radio->leftChar              = 0;
178    radio->selectedItem          = 0;
179    radio->highlight             = highlight;
180    radio->choiceChar            = choiceChar;
181    radio->leftBoxChar           = (chtype)'[';
182    radio->rightBoxChar          = (chtype)']';
183    radio->defItem               = defItem;
184    initExitType (radio);
185    ObjOf (radio)->inputWindow   = radio->win;
186    ObjOf (radio)->acceptsFocus  = TRUE;
187    radio->shadow                = shadow;
188 
189    setCDKRadioCurrentItem (radio, 0);
190 
191    /* Do we need to create the shadow??? */
192    if (shadow)
193    {
194       radio->shadowWin = newwin (boxHeight, boxWidth + 1, ypos + 1, xpos + 1);
195    }
196 
197    /* Setup the key bindings. */
198    for (j = 0; j < (int)SIZEOF (bindings); ++j)
199       bindCDKObject (vRADIO,
200 		     radio,
201 		     (chtype)bindings[j].from,
202 		     getcCDKBind,
203 		     (void *)(long)bindings[j].to);
204 
205    /* Register this baby. */
206    registerCDKObject (cdkscreen, vRADIO, radio);
207 
208    /* Return the radio list */
209    return (radio);
210 }
211 
212 /*
213  * Put the cursor on the currently-selected item.
214  */
fixCursorPosition(CDKRADIO * widget)215 static void fixCursorPosition (CDKRADIO *widget)
216 {
217    scroller_FixCursorPosition ((CDKSCROLLER *)widget);
218 }
219 
220 /*
221  * This actually manages the radio widget.
222  */
activateCDKRadio(CDKRADIO * radio,chtype * actions)223 int activateCDKRadio (CDKRADIO *radio, chtype *actions)
224 {
225    /* Draw the radio list. */
226    drawCDKRadio (radio, ObjOf (radio)->box);
227 
228    if (actions == 0)
229    {
230       chtype input;
231       boolean functionKey;
232 
233       for (;;)
234       {
235 	 int ret;
236 
237 	 fixCursorPosition (radio);
238 	 input = (chtype)getchCDKObject (ObjOf (radio), &functionKey);
239 
240 	 /* Inject the character into the widget. */
241 	 ret = injectCDKRadio (radio, input);
242 	 if (radio->exitType != vEARLY_EXIT)
243 	 {
244 	    return ret;
245 	 }
246       }
247    }
248    else
249    {
250       int length = chlen (actions);
251       int j;
252 
253       /* Inject each character one at a time. */
254       for (j = 0; j < length; j++)
255       {
256 	 int ret = injectCDKRadio (radio, actions[j]);
257 	 if (radio->exitType != vEARLY_EXIT)
258 	 {
259 	    return ret;
260 	 }
261       }
262    }
263 
264    /* Set the exit type and return. */
265    setExitType (radio, 0);
266    return -1;
267 }
268 
269 /*
270  * This injects a single character into the widget.
271  */
_injectCDKRadio(CDKOBJS * object,chtype input)272 static int _injectCDKRadio (CDKOBJS *object, chtype input)
273 {
274    CDKRADIO *radio = (CDKRADIO *)object;
275    CDKSCROLLER *widget = (CDKSCROLLER *)object;
276    int ppReturn = 1;
277    int ret = unknownInt;
278    bool complete = FALSE;
279 
280    /* Set the exit type. */
281    setExitType (widget, 0);
282 
283    /* Draw the widget list */
284    drawCDKRadioList (radio, ObjOf (widget)->box);
285 
286    /* Check if there is a pre-process function to be called. */
287    if (PreProcessFuncOf (widget) != 0)
288    {
289       /* Call the pre-process function. */
290       ppReturn = PreProcessFuncOf (widget) (vRADIO,
291 					    widget,
292 					    PreProcessDataOf (widget),
293 					    input);
294    }
295 
296    /* Should we continue? */
297    if (ppReturn != 0)
298    {
299       /* Check for a predefined key binding. */
300       if (checkCDKObjectBind (vRADIO, widget, input) != 0)
301       {
302 	 checkEarlyExit (widget);
303 	 complete = TRUE;
304       }
305       else
306       {
307 	 switch (input)
308 	 {
309 	 case KEY_UP:
310 	    scroller_KEY_UP (widget);
311 	    break;
312 
313 	 case KEY_DOWN:
314 	    scroller_KEY_DOWN (widget);
315 	    break;
316 
317 	 case KEY_RIGHT:
318 	    scroller_KEY_RIGHT (widget);
319 	    break;
320 
321 	 case KEY_LEFT:
322 	    scroller_KEY_LEFT (widget);
323 	    break;
324 
325 	 case KEY_PPAGE:
326 	    scroller_KEY_PPAGE (widget);
327 	    break;
328 
329 	 case KEY_NPAGE:
330 	    scroller_KEY_NPAGE (widget);
331 	    break;
332 
333 	 case KEY_HOME:
334 	    scroller_KEY_HOME (widget);
335 	    break;
336 
337 	 case KEY_END:
338 	    scroller_KEY_END (widget);
339 	    break;
340 
341 	 case '$':
342 	    widget->leftChar = widget->maxLeftChar;
343 	    break;
344 
345 	 case '|':
346 	    widget->leftChar = 0;
347 	    break;
348 
349 	 case SPACE:
350 	    radio->selectedItem = widget->currentItem;
351 	    break;
352 
353 	 case KEY_ESC:
354 	    setExitType (widget, input);
355 	    ret = -1;
356 	    complete = TRUE;
357 	    break;
358 
359 	 case KEY_ERROR:
360 	    setExitType (widget, input);
361 	    complete = TRUE;
362 	    break;
363 
364 	 case KEY_TAB:
365 	 case KEY_ENTER:
366 	    setExitType (widget, input);
367 	    ret = radio->selectedItem;
368 	    complete = TRUE;
369 	    break;
370 
371 	 case CDK_REFRESH:
372 	    eraseCDKScreen (ScreenOf (widget));
373 	    refreshCDKScreen (ScreenOf (widget));
374 	    break;
375 
376 	 default:
377 	    break;
378 	 }
379       }
380 
381       /* Should we call a post-process? */
382       if (!complete && (PostProcessFuncOf (widget) != 0))
383       {
384 	 PostProcessFuncOf (widget) (vRADIO,
385 				     widget,
386 				     PostProcessDataOf (widget),
387 				     input);
388       }
389    }
390 
391    if (!complete)
392    {
393       drawCDKRadioList (radio, ObjOf (widget)->box);
394       setExitType (widget, 0);
395    }
396 
397    fixCursorPosition (radio);
398    ResultOf (widget).valueInt = ret;
399    return (ret != unknownInt);
400 }
401 
402 /*
403  * This moves the radio field to the given location.
404  */
_moveCDKRadio(CDKOBJS * object,int xplace,int yplace,boolean relative,boolean refresh_flag)405 static void _moveCDKRadio (CDKOBJS *object,
406 			   int xplace,
407 			   int yplace,
408 			   boolean relative,
409 			   boolean refresh_flag)
410 {
411    CDKRADIO *radio = (CDKRADIO *)object;
412    /* *INDENT-EQLS* */
413    int currentX = getbegx (radio->win);
414    int currentY = getbegy (radio->win);
415    int xpos     = xplace;
416    int ypos     = yplace;
417    int xdiff    = 0;
418    int ydiff    = 0;
419 
420    /*
421     * If this is a relative move, then we will adjust where we want
422     * to move to.
423     */
424    if (relative)
425    {
426       xpos = getbegx (radio->win) + xplace;
427       ypos = getbegy (radio->win) + yplace;
428    }
429 
430    /* Adjust the window if we need to. */
431    alignxy (WindowOf (radio), &xpos, &ypos, radio->boxWidth, radio->boxHeight);
432 
433    /* Get the difference. */
434    xdiff = currentX - xpos;
435    ydiff = currentY - ypos;
436 
437    /* Move the window to the new location. */
438    moveCursesWindow (radio->win, -xdiff, -ydiff);
439    moveCursesWindow (radio->scrollbarWin, -xdiff, -ydiff);
440    moveCursesWindow (radio->shadowWin, -xdiff, -ydiff);
441 
442    /* Touch the windows so they 'move'. */
443    refreshCDKWindow (WindowOf (radio));
444 
445    /* Redraw the window, if they asked for it. */
446    if (refresh_flag)
447    {
448       drawCDKRadio (radio, ObjOf (radio)->box);
449    }
450 }
451 
maxViewSize(CDKRADIO * widget)452 static int maxViewSize (CDKRADIO *widget)
453 {
454    return scroller_MaxViewSize ((CDKSCROLLER *)widget);
455 }
456 
457 /*
458  * Set variables that depend upon the list-size.
459  */
setViewSize(CDKRADIO * widget,int listSize)460 static void setViewSize (CDKRADIO *widget, int listSize)
461 {
462    scroller_SetViewSize ((CDKSCROLLER *)widget, listSize);
463 }
464 
465 /*
466  * This function draws the radio widget.
467  */
_drawCDKRadio(CDKOBJS * object,boolean Box GCC_UNUSED)468 static void _drawCDKRadio (CDKOBJS *object, boolean Box GCC_UNUSED)
469 {
470    CDKRADIO *radio = (CDKRADIO *)object;
471 
472    /* Do we need to draw in the shadow??? */
473    if (radio->shadowWin != 0)
474    {
475       drawShadow (radio->shadowWin);
476    }
477 
478    drawCdkTitle (radio->win, object);
479 
480    /* Draw in the radio list. */
481    drawCDKRadioList (radio, ObjOf (radio)->box);
482 }
483 
484 /*
485  * This redraws the radio list.
486  */
drawCDKRadioList(CDKRADIO * radio,boolean Box)487 static void drawCDKRadioList (CDKRADIO *radio, boolean Box)
488 {
489    int scrollbarAdj = (radio->scrollbarPlacement == LEFT) ? 1 : 0;
490    int j, k;
491 
492    /* draw the list */
493    for (j = 0; j < radio->viewSize; j++)
494    {
495       int xpos = SCREEN_XPOS (radio, 0);
496       int ypos = SCREEN_YPOS (radio, j);
497 
498       /* Draw the empty string. */
499       writeBlanks (radio->win, xpos, ypos,
500 		   HORIZONTAL, 0, radio->boxWidth - BorderOf (radio));
501 
502       k = j + radio->currentTop;
503 
504       /* Draw the element in the radio list. */
505       if (k < radio->listSize)
506       {
507 	 int screenPos = SCREENPOS (radio, k);
508 
509 	 /* Draw the line. */
510 	 writeChtype (radio->win,
511 		      (screenPos >= 0) ? screenPos : 1,
512 		      ypos,
513 		      radio->item[k],
514 		      HORIZONTAL,
515 		      (screenPos >= 0) ? 0 : (1 - screenPos),
516 		      radio->itemLen[k]);
517 
518 	 /* Draw the selected choice... */
519 	 xpos += scrollbarAdj;
520 	 (void)mvwaddch (radio->win, ypos, xpos++, radio->leftBoxChar);
521 	 (void)mvwaddch (radio->win, ypos, xpos++, ((k == radio->selectedItem)
522 						    ? radio->choiceChar
523 						    : ' '));
524 	 (void)mvwaddch (radio->win, ypos, xpos++, radio->rightBoxChar);
525       }
526    }
527 
528    /* Highlight the current item. */
529    if (ObjPtr (radio)->hasFocus)
530    {
531       k = radio->currentItem;
532       if (k < radio->listSize)
533       {
534 	 int screenPos = SCREENPOS (radio, k);
535 	 int ypos = SCREEN_YPOS (radio, radio->currentHigh);
536 
537 	 writeChtypeAttrib (radio->win,
538 			    (screenPos >= 0) ? screenPos : (1 + scrollbarAdj),
539 			    ypos,
540 			    radio->item[k],
541 			    radio->highlight,
542 			    HORIZONTAL,
543 			    (screenPos >= 0) ? 0 : (1 - screenPos),
544 			    radio->itemLen[k]);
545       }
546    }
547 
548    if (radio->scrollbar)
549    {
550       radio->togglePos = floorCDK (radio->currentItem * (double)radio->step);
551       radio->togglePos = MINIMUM (radio->togglePos,
552 				  getmaxy (radio->scrollbarWin) - 1);
553 
554       (void)mvwvline (radio->scrollbarWin, 0, 0,
555 		      ACS_CKBOARD, getmaxy (radio->scrollbarWin));
556       (void)mvwvline (radio->scrollbarWin, radio->togglePos, 0,
557 		      ' ' | A_REVERSE, radio->toggleSize);
558    }
559 
560    /* Box it if needed. */
561    if (Box)
562    {
563       drawObjBox (radio->win, ObjOf (radio));
564    }
565    else
566    {
567       touchwin (radio->win);
568    }
569 
570    fixCursorPosition (radio);
571 }
572 
573 /*
574  * This sets the background attribute of the widget.
575  */
_setBKattrRadio(CDKOBJS * object,chtype attrib)576 static void _setBKattrRadio (CDKOBJS *object, chtype attrib)
577 {
578    if (object != 0)
579    {
580       CDKRADIO *widget = (CDKRADIO *)object;
581 
582       wbkgd (widget->win, attrib);
583       if (widget->scrollbarWin != 0)
584       {
585 	 wbkgd (widget->scrollbarWin, attrib);
586       }
587    }
588 }
589 
destroyInfo(CDKRADIO * widget)590 static void destroyInfo (CDKRADIO *widget)
591 {
592    CDKfreeChtypes (widget->item);
593    widget->item = 0;
594 
595    freeAndNull (widget->itemLen);
596    freeAndNull (widget->itemPos);
597 }
598 
599 /*
600  * This function destroys the radio widget.
601  */
_destroyCDKRadio(CDKOBJS * object)602 static void _destroyCDKRadio (CDKOBJS *object)
603 {
604    if (object != 0)
605    {
606       CDKRADIO *radio = (CDKRADIO *)object;
607 
608       cleanCdkTitle (object);
609       destroyInfo (radio);
610 
611       /* Clean up the windows. */
612       deleteCursesWindow (radio->scrollbarWin);
613       deleteCursesWindow (radio->shadowWin);
614       deleteCursesWindow (radio->win);
615 
616       /* Clean the key bindings. */
617       cleanCDKObjectBindings (vRADIO, radio);
618 
619       /* Unregister this object. */
620       unregisterCDKObject (vRADIO, radio);
621    }
622 }
623 
624 /*
625  * This function erases the radio widget.
626  */
_eraseCDKRadio(CDKOBJS * object)627 static void _eraseCDKRadio (CDKOBJS *object)
628 {
629    if (validCDKObject (object))
630    {
631       CDKRADIO *radio = (CDKRADIO *)object;
632 
633       eraseCursesWindow (radio->win);
634       eraseCursesWindow (radio->shadowWin);
635    }
636 }
637 
638 /*
639  * This set various attributes of the radio list.
640  */
setCDKRadio(CDKRADIO * radio,chtype highlight,chtype choiceChar,int Box)641 void setCDKRadio (CDKRADIO *radio, chtype highlight, chtype choiceChar, int Box)
642 {
643    setCDKRadioHighlight (radio, highlight);
644    setCDKRadioChoiceCharacter (radio, choiceChar);
645    setCDKRadioBox (radio, Box);
646 }
647 
648 /*
649  * This sets the radio list items.
650  */
setCDKRadioItems(CDKRADIO * radio,CDK_CSTRING2 list,int listSize)651 void setCDKRadioItems (CDKRADIO *radio, CDK_CSTRING2 list, int listSize)
652 {
653    int widestItem;
654    int j = 0;
655 
656    widestItem = createList (radio, list, listSize, radio->boxWidth);
657    if (widestItem <= 0)
658       return;
659 
660    /* Clean up the display. */
661    for (j = 0; j < radio->viewSize; j++)
662    {
663       writeBlanks (radio->win,
664 		   SCREEN_XPOS (radio, 0),
665 		   SCREEN_YPOS (radio, j),
666 		   HORIZONTAL,
667 		   0,
668 		   radio->boxWidth - BorderOf (radio));
669    }
670 
671    setViewSize (radio, listSize);
672 
673    setCDKRadioCurrentItem (radio, 0);
674    radio->leftChar = 0;
675    radio->selectedItem = 0;
676 
677    updateViewWidth (radio, widestItem);
678 }
getCDKRadioItems(CDKRADIO * radio,char ** list)679 int getCDKRadioItems (CDKRADIO *radio, char **list)
680 {
681    if (list != 0)
682    {
683       int j;
684 
685       for (j = 0; j < radio->listSize; j++)
686       {
687 	 list[j] = chtype2Char (radio->item[j]);
688       }
689    }
690    return radio->listSize;
691 }
692 
693 /*
694  * This sets the highlight bar of the radio list.
695  */
setCDKRadioHighlight(CDKRADIO * radio,chtype highlight)696 void setCDKRadioHighlight (CDKRADIO *radio, chtype highlight)
697 {
698    radio->highlight = highlight;
699 }
getCDKRadioHighlight(CDKRADIO * radio)700 chtype getCDKRadioHighlight (CDKRADIO *radio)
701 {
702    return radio->highlight;
703 }
704 
705 /*
706  * This sets the character to use when selecting an item in the list.
707  */
setCDKRadioChoiceCharacter(CDKRADIO * radio,chtype character)708 void setCDKRadioChoiceCharacter (CDKRADIO *radio, chtype character)
709 {
710    radio->choiceChar = character;
711 }
getCDKRadioChoiceCharacter(CDKRADIO * radio)712 chtype getCDKRadioChoiceCharacter (CDKRADIO *radio)
713 {
714    return radio->choiceChar;
715 }
716 
717 /*
718  * This sets the character to use to draw the left side of the
719  * choice box on the list.
720  */
setCDKRadioLeftBrace(CDKRADIO * radio,chtype character)721 void setCDKRadioLeftBrace (CDKRADIO *radio, chtype character)
722 {
723    radio->leftBoxChar = character;
724 }
getCDKRadioLeftBrace(CDKRADIO * radio)725 chtype getCDKRadioLeftBrace (CDKRADIO *radio)
726 {
727    return radio->leftBoxChar;
728 }
729 
730 /*
731  * This sets the character to use to draw the right side of the
732  * choice box on the list.
733  */
setCDKRadioRightBrace(CDKRADIO * radio,chtype character)734 void setCDKRadioRightBrace (CDKRADIO *radio, chtype character)
735 {
736    radio->rightBoxChar = character;
737 }
getCDKRadioRightBrace(CDKRADIO * radio)738 chtype getCDKRadioRightBrace (CDKRADIO *radio)
739 {
740    return radio->rightBoxChar;
741 }
742 
743 /*
744  * This sets the box attribute of the widget.
745  */
setCDKRadioBox(CDKRADIO * radio,boolean Box)746 void setCDKRadioBox (CDKRADIO *radio, boolean Box)
747 {
748    ObjOf (radio)->box = Box;
749    ObjOf (radio)->borderSize = Box ? 1 : 0;
750 }
getCDKRadioBox(CDKRADIO * radio)751 boolean getCDKRadioBox (CDKRADIO *radio)
752 {
753    return ObjOf (radio)->box;
754 }
755 
756 /*
757  * This sets the current high lighted item of the widget
758  */
setCDKRadioCurrentItem(CDKRADIO * radio,int item)759 void setCDKRadioCurrentItem (CDKRADIO *radio, int item)
760 {
761    scroller_SetPosition ((CDKSCROLLER *)radio, item);
762    radio->selectedItem = item;
763 }
getCDKRadioCurrentItem(CDKRADIO * radio)764 int getCDKRadioCurrentItem (CDKRADIO *radio)
765 {
766    return radio->currentItem;
767 }
768 
769 /*
770  * This sets the selected item of the widget
771  */
setCDKRadioSelectedItem(CDKRADIO * radio,int item)772 void setCDKRadioSelectedItem (CDKRADIO *radio, int item)
773 {
774    radio->selectedItem = item;
775 }
getCDKRadioSelectedItem(CDKRADIO * radio)776 int getCDKRadioSelectedItem (CDKRADIO *radio)
777 {
778    return radio->selectedItem;
779 }
780 
_focusCDKRadio(CDKOBJS * object)781 static void _focusCDKRadio (CDKOBJS *object)
782 {
783    CDKRADIO *radio = (CDKRADIO *)object;
784 
785    drawCDKRadioList (radio, ObjOf (radio)->box);
786 }
787 
_unfocusCDKRadio(CDKOBJS * object)788 static void _unfocusCDKRadio (CDKOBJS *object)
789 {
790    CDKRADIO *radio = (CDKRADIO *)object;
791 
792    drawCDKRadioList (radio, ObjOf (radio)->box);
793 }
794 
createList(CDKRADIO * radio,CDK_CSTRING2 list,int listSize,int boxWidth)795 static int createList (CDKRADIO *radio, CDK_CSTRING2 list, int listSize, int boxWidth)
796 {
797    int status = 0;
798    int widestItem = 0;
799 
800    if (radio->listSize > 0)
801    {
802       CDKfreeChtypes (radio->item);
803       radio->item = 0;
804       freeAndNull (radio->itemLen);
805       freeAndNull (radio->itemPos);
806    }
807 
808    if (listSize >= 0)
809    {
810       /* *INDENT-EQLS* */
811       chtype **newList = typeCallocN (chtype *, listSize + 1);
812       int *newLen      = typeCallocN (int, listSize + 1);
813       int *newPos      = typeCallocN (int, listSize + 1);
814 
815       if (newList != 0
816 	  && newLen != 0
817 	  && newPos != 0)
818       {
819 	 int j;
820 
821 	 /* Each item in the needs to be converted to chtype * */
822 	 status = 1;
823 	 boxWidth -= (2 + BorderOf (radio));
824 	 for (j = 0; j < listSize; j++)
825 	 {
826 	    newList[j] = char2Chtype (list[j], &newLen[j], &newPos[j]);
827 	    if (newList[j] == 0)
828 	    {
829 	       status = 0;
830 	       break;
831 	    }
832 	    newPos[j] = justifyString (boxWidth, newLen[j], newPos[j]) + 3;
833 	    widestItem = MAXIMUM (widestItem, newLen[j]);
834 	 }
835 	 if (status)
836 	 {
837 	    destroyInfo (radio);
838 
839 	    /* *INDENT-EQLS* */
840 	    radio->listSize = listSize;
841 	    radio->item     = newList;
842 	    radio->itemLen  = newLen;
843 	    radio->itemPos  = newPos;
844 	 }
845 	 else
846 	 {
847 	    CDKfreeChtypes (newList);
848 	    freeChecked (newLen);
849 	    freeChecked (newPos);
850 	 }
851       }
852       else
853       {
854 	 CDKfreeChtypes (newList);
855 	 freeChecked (newLen);
856 	 freeChecked (newPos);
857       }
858    }
859    else
860    {
861       destroyInfo (radio);
862    }
863 
864    return status ? widestItem : 0;
865 }
866 
867 dummyRefreshData (Radio)
868 
869 dummySaveData (Radio)
870