860 lines
19 KiB
C
860 lines
19 KiB
C
|
#include <cdk_int.h>
|
||
|
#include <scroller.h>
|
||
|
|
||
|
/*
|
||
|
* $Author: tom $
|
||
|
* $Date: 2016/11/20 20:14:41 $
|
||
|
* $Revision: 1.146 $
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Declare file local prototypes.
|
||
|
*/
|
||
|
static int createList (CDKRADIO *radio, CDK_CSTRING2 list, int listSize, int width);
|
||
|
static void drawCDKRadioList (CDKRADIO *radio, boolean Box);
|
||
|
static void setViewSize (CDKRADIO *scrollp, int listSize);
|
||
|
static int maxViewSize (CDKRADIO *scrollp);
|
||
|
|
||
|
/* Determine how many characters we can shift to the right */
|
||
|
/* before all the items have been scrolled off the screen. */
|
||
|
#define AvailableWidth(w) ((w)->boxWidth - 2*BorderOf(w) - 3)
|
||
|
#define updateViewWidth(w, widest) \
|
||
|
(w)->maxLeftChar = (((w)->boxWidth > widest) \
|
||
|
? 0 \
|
||
|
: (widest - AvailableWidth(w)))
|
||
|
#define WidestItem(w) ((w)->maxLeftChar + AvailableWidth(w))
|
||
|
|
||
|
#define SCREENPOS(w,n) (w)->itemPos[n] - (w)->leftChar + scrollbarAdj + BorderOf(w)
|
||
|
|
||
|
DeclareCDKObjects (RADIO, Radio, setCdk, Int);
|
||
|
|
||
|
/*
|
||
|
* This function creates the radio widget.
|
||
|
*/
|
||
|
CDKRADIO *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)
|
||
|
{
|
||
|
/* *INDENT-EQLS* */
|
||
|
CDKRADIO *radio = 0;
|
||
|
int parentWidth = getmaxx (cdkscreen->window);
|
||
|
int parentHeight = getmaxy (cdkscreen->window);
|
||
|
int boxWidth;
|
||
|
int boxHeight;
|
||
|
int xpos = xplace;
|
||
|
int ypos = yplace;
|
||
|
int widestItem = 0;
|
||
|
int j;
|
||
|
/* *INDENT-OFF* */
|
||
|
static const struct { int from; int to; } bindings[] = {
|
||
|
{ CDK_BACKCHAR, KEY_PPAGE },
|
||
|
{ CDK_FORCHAR, KEY_NPAGE },
|
||
|
{ 'g', KEY_HOME },
|
||
|
{ '1', KEY_HOME },
|
||
|
{ 'G', KEY_END },
|
||
|
{ '<', KEY_HOME },
|
||
|
{ '>', KEY_END },
|
||
|
};
|
||
|
/* *INDENT-ON* */
|
||
|
|
||
|
if ((radio = newCDKObject (CDKRADIO, &my_funcs)) == 0)
|
||
|
{
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
setCDKRadioBox (radio, Box);
|
||
|
|
||
|
/*
|
||
|
* If the height is a negative value, the height will
|
||
|
* be ROWS-height, otherwise, the height will be the
|
||
|
* given height.
|
||
|
*/
|
||
|
boxHeight = setWidgetDimension (parentHeight, height, 0);
|
||
|
|
||
|
/*
|
||
|
* If the width is a negative value, the width will
|
||
|
* be COLS-width, otherwise, the width will be the
|
||
|
* given width.
|
||
|
*/
|
||
|
boxWidth = setWidgetDimension (parentWidth, width, 5);
|
||
|
|
||
|
boxWidth = setCdkTitle (ObjOf (radio), title, boxWidth);
|
||
|
|
||
|
/* Set the box height. */
|
||
|
if (TitleLinesOf (radio) > boxHeight)
|
||
|
{
|
||
|
boxHeight = TitleLinesOf (radio)
|
||
|
+ MINIMUM (listSize, 8)
|
||
|
+ 2 * BorderOf (radio);
|
||
|
}
|
||
|
|
||
|
/* Adjust the box width if there is a scroll bar. */
|
||
|
if (splace == LEFT || splace == RIGHT)
|
||
|
{
|
||
|
boxWidth++;
|
||
|
radio->scrollbar = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
radio->scrollbar = FALSE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Make sure we didn't extend beyond the dimensions of the window.
|
||
|
*/
|
||
|
radio->boxWidth = MINIMUM (boxWidth, parentWidth);
|
||
|
radio->boxHeight = MINIMUM (boxHeight, parentHeight);
|
||
|
|
||
|
setViewSize (radio, listSize);
|
||
|
|
||
|
/* Each item in the needs to be converted to chtype * */
|
||
|
widestItem = createList (radio, list, listSize, radio->boxWidth);
|
||
|
if (widestItem > 0)
|
||
|
{
|
||
|
updateViewWidth (radio, widestItem);
|
||
|
}
|
||
|
else if (listSize)
|
||
|
{
|
||
|
destroyCDKObject (radio);
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
/* Rejustify the x and y positions if we need to. */
|
||
|
alignxy (cdkscreen->window, &xpos, &ypos, radio->boxWidth, radio->boxHeight);
|
||
|
|
||
|
/* Make the radio window */
|
||
|
radio->win = newwin (radio->boxHeight, radio->boxWidth, ypos, xpos);
|
||
|
|
||
|
/* Is the window null??? */
|
||
|
if (radio->win == 0)
|
||
|
{
|
||
|
destroyCDKObject (radio);
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
/* Turn on the keypad. */
|
||
|
keypad (radio->win, TRUE);
|
||
|
|
||
|
/* Create the scrollbar window. */
|
||
|
if (splace == RIGHT)
|
||
|
{
|
||
|
radio->scrollbarWin = subwin (radio->win,
|
||
|
maxViewSize (radio), 1,
|
||
|
SCREEN_YPOS (radio, ypos),
|
||
|
(xpos
|
||
|
+ radio->boxWidth
|
||
|
- BorderOf (radio)
|
||
|
- 1));
|
||
|
}
|
||
|
else if (splace == LEFT)
|
||
|
{
|
||
|
radio->scrollbarWin = subwin (radio->win,
|
||
|
maxViewSize (radio), 1,
|
||
|
SCREEN_YPOS (radio, ypos),
|
||
|
SCREEN_XPOS (radio, xpos));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
radio->scrollbarWin = 0;
|
||
|
}
|
||
|
|
||
|
/* *INDENT-EQLS* Set the rest of the variables */
|
||
|
ScreenOf (radio) = cdkscreen;
|
||
|
radio->parent = cdkscreen->window;
|
||
|
radio->scrollbarPlacement = splace;
|
||
|
radio->widestItem = widestItem;
|
||
|
radio->leftChar = 0;
|
||
|
radio->selectedItem = 0;
|
||
|
radio->highlight = highlight;
|
||
|
radio->choiceChar = choiceChar;
|
||
|
radio->leftBoxChar = (chtype)'[';
|
||
|
radio->rightBoxChar = (chtype)']';
|
||
|
radio->defItem = defItem;
|
||
|
initExitType (radio);
|
||
|
ObjOf (radio)->inputWindow = radio->win;
|
||
|
ObjOf (radio)->acceptsFocus = TRUE;
|
||
|
radio->shadow = shadow;
|
||
|
|
||
|
setCDKRadioCurrentItem (radio, 0);
|
||
|
|
||
|
/* Do we need to create the shadow??? */
|
||
|
if (shadow)
|
||
|
{
|
||
|
radio->shadowWin = newwin (boxHeight, boxWidth + 1, ypos + 1, xpos + 1);
|
||
|
}
|
||
|
|
||
|
/* Setup the key bindings. */
|
||
|
for (j = 0; j < (int)SIZEOF (bindings); ++j)
|
||
|
bindCDKObject (vRADIO,
|
||
|
radio,
|
||
|
(chtype)bindings[j].from,
|
||
|
getcCDKBind,
|
||
|
(void *)(long)bindings[j].to);
|
||
|
|
||
|
/* Register this baby. */
|
||
|
registerCDKObject (cdkscreen, vRADIO, radio);
|
||
|
|
||
|
/* Return the radio list */
|
||
|
return (radio);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Put the cursor on the currently-selected item.
|
||
|
*/
|
||
|
static void fixCursorPosition (CDKRADIO *widget)
|
||
|
{
|
||
|
scroller_FixCursorPosition ((CDKSCROLLER *)widget);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This actually manages the radio widget.
|
||
|
*/
|
||
|
int activateCDKRadio (CDKRADIO *radio, chtype *actions)
|
||
|
{
|
||
|
/* Draw the radio list. */
|
||
|
drawCDKRadio (radio, ObjOf (radio)->box);
|
||
|
|
||
|
if (actions == 0)
|
||
|
{
|
||
|
chtype input;
|
||
|
boolean functionKey;
|
||
|
|
||
|
for (;;)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
fixCursorPosition (radio);
|
||
|
input = (chtype)getchCDKObject (ObjOf (radio), &functionKey);
|
||
|
|
||
|
/* Inject the character into the widget. */
|
||
|
ret = injectCDKRadio (radio, input);
|
||
|
if (radio->exitType != vEARLY_EXIT)
|
||
|
{
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int length = chlen (actions);
|
||
|
int j;
|
||
|
|
||
|
/* Inject each character one at a time. */
|
||
|
for (j = 0; j < length; j++)
|
||
|
{
|
||
|
int ret = injectCDKRadio (radio, actions[j]);
|
||
|
if (radio->exitType != vEARLY_EXIT)
|
||
|
{
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Set the exit type and return. */
|
||
|
setExitType (radio, 0);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This injects a single character into the widget.
|
||
|
*/
|
||
|
static int _injectCDKRadio (CDKOBJS *object, chtype input)
|
||
|
{
|
||
|
CDKRADIO *radio = (CDKRADIO *)object;
|
||
|
CDKSCROLLER *widget = (CDKSCROLLER *)object;
|
||
|
int ppReturn = 1;
|
||
|
int ret = unknownInt;
|
||
|
bool complete = FALSE;
|
||
|
|
||
|
/* Set the exit type. */
|
||
|
setExitType (widget, 0);
|
||
|
|
||
|
/* Draw the widget list */
|
||
|
drawCDKRadioList (radio, ObjOf (widget)->box);
|
||
|
|
||
|
/* Check if there is a pre-process function to be called. */
|
||
|
if (PreProcessFuncOf (widget) != 0)
|
||
|
{
|
||
|
/* Call the pre-process function. */
|
||
|
ppReturn = PreProcessFuncOf (widget) (vRADIO,
|
||
|
widget,
|
||
|
PreProcessDataOf (widget),
|
||
|
input);
|
||
|
}
|
||
|
|
||
|
/* Should we continue? */
|
||
|
if (ppReturn != 0)
|
||
|
{
|
||
|
/* Check for a predefined key binding. */
|
||
|
if (checkCDKObjectBind (vRADIO, widget, input) != 0)
|
||
|
{
|
||
|
checkEarlyExit (widget);
|
||
|
complete = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch (input)
|
||
|
{
|
||
|
case KEY_UP:
|
||
|
scroller_KEY_UP (widget);
|
||
|
break;
|
||
|
|
||
|
case KEY_DOWN:
|
||
|
scroller_KEY_DOWN (widget);
|
||
|
break;
|
||
|
|
||
|
case KEY_RIGHT:
|
||
|
scroller_KEY_RIGHT (widget);
|
||
|
break;
|
||
|
|
||
|
case KEY_LEFT:
|
||
|
scroller_KEY_LEFT (widget);
|
||
|
break;
|
||
|
|
||
|
case KEY_PPAGE:
|
||
|
scroller_KEY_PPAGE (widget);
|
||
|
break;
|
||
|
|
||
|
case KEY_NPAGE:
|
||
|
scroller_KEY_NPAGE (widget);
|
||
|
break;
|
||
|
|
||
|
case KEY_HOME:
|
||
|
scroller_KEY_HOME (widget);
|
||
|
break;
|
||
|
|
||
|
case KEY_END:
|
||
|
scroller_KEY_END (widget);
|
||
|
break;
|
||
|
|
||
|
case '$':
|
||
|
widget->leftChar = widget->maxLeftChar;
|
||
|
break;
|
||
|
|
||
|
case '|':
|
||
|
widget->leftChar = 0;
|
||
|
break;
|
||
|
|
||
|
case SPACE:
|
||
|
radio->selectedItem = widget->currentItem;
|
||
|
break;
|
||
|
|
||
|
case KEY_ESC:
|
||
|
setExitType (widget, input);
|
||
|
ret = -1;
|
||
|
complete = TRUE;
|
||
|
break;
|
||
|
|
||
|
case KEY_ERROR:
|
||
|
setExitType (widget, input);
|
||
|
complete = TRUE;
|
||
|
break;
|
||
|
|
||
|
case KEY_TAB:
|
||
|
case KEY_ENTER:
|
||
|
setExitType (widget, input);
|
||
|
ret = radio->selectedItem;
|
||
|
complete = TRUE;
|
||
|
break;
|
||
|
|
||
|
case CDK_REFRESH:
|
||
|
eraseCDKScreen (ScreenOf (widget));
|
||
|
refreshCDKScreen (ScreenOf (widget));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Should we call a post-process? */
|
||
|
if (!complete && (PostProcessFuncOf (widget) != 0))
|
||
|
{
|
||
|
PostProcessFuncOf (widget) (vRADIO,
|
||
|
widget,
|
||
|
PostProcessDataOf (widget),
|
||
|
input);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!complete)
|
||
|
{
|
||
|
drawCDKRadioList (radio, ObjOf (widget)->box);
|
||
|
setExitType (widget, 0);
|
||
|
}
|
||
|
|
||
|
fixCursorPosition (radio);
|
||
|
ResultOf (widget).valueInt = ret;
|
||
|
return (ret != unknownInt);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This moves the radio field to the given location.
|
||
|
*/
|
||
|
static void _moveCDKRadio (CDKOBJS *object,
|
||
|
int xplace,
|
||
|
int yplace,
|
||
|
boolean relative,
|
||
|
boolean refresh_flag)
|
||
|
{
|
||
|
CDKRADIO *radio = (CDKRADIO *)object;
|
||
|
/* *INDENT-EQLS* */
|
||
|
int currentX = getbegx (radio->win);
|
||
|
int currentY = getbegy (radio->win);
|
||
|
int xpos = xplace;
|
||
|
int ypos = yplace;
|
||
|
int xdiff = 0;
|
||
|
int ydiff = 0;
|
||
|
|
||
|
/*
|
||
|
* If this is a relative move, then we will adjust where we want
|
||
|
* to move to.
|
||
|
*/
|
||
|
if (relative)
|
||
|
{
|
||
|
xpos = getbegx (radio->win) + xplace;
|
||
|
ypos = getbegy (radio->win) + yplace;
|
||
|
}
|
||
|
|
||
|
/* Adjust the window if we need to. */
|
||
|
alignxy (WindowOf (radio), &xpos, &ypos, radio->boxWidth, radio->boxHeight);
|
||
|
|
||
|
/* Get the difference. */
|
||
|
xdiff = currentX - xpos;
|
||
|
ydiff = currentY - ypos;
|
||
|
|
||
|
/* Move the window to the new location. */
|
||
|
moveCursesWindow (radio->win, -xdiff, -ydiff);
|
||
|
moveCursesWindow (radio->scrollbarWin, -xdiff, -ydiff);
|
||
|
moveCursesWindow (radio->shadowWin, -xdiff, -ydiff);
|
||
|
|
||
|
/* Touch the windows so they 'move'. */
|
||
|
refreshCDKWindow (WindowOf (radio));
|
||
|
|
||
|
/* Redraw the window, if they asked for it. */
|
||
|
if (refresh_flag)
|
||
|
{
|
||
|
drawCDKRadio (radio, ObjOf (radio)->box);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int maxViewSize (CDKRADIO *widget)
|
||
|
{
|
||
|
return scroller_MaxViewSize ((CDKSCROLLER *)widget);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Set variables that depend upon the list-size.
|
||
|
*/
|
||
|
static void setViewSize (CDKRADIO *widget, int listSize)
|
||
|
{
|
||
|
scroller_SetViewSize ((CDKSCROLLER *)widget, listSize);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This function draws the radio widget.
|
||
|
*/
|
||
|
static void _drawCDKRadio (CDKOBJS *object, boolean Box GCC_UNUSED)
|
||
|
{
|
||
|
CDKRADIO *radio = (CDKRADIO *)object;
|
||
|
|
||
|
/* Do we need to draw in the shadow??? */
|
||
|
if (radio->shadowWin != 0)
|
||
|
{
|
||
|
drawShadow (radio->shadowWin);
|
||
|
}
|
||
|
|
||
|
drawCdkTitle (radio->win, object);
|
||
|
|
||
|
/* Draw in the radio list. */
|
||
|
drawCDKRadioList (radio, ObjOf (radio)->box);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This redraws the radio list.
|
||
|
*/
|
||
|
static void drawCDKRadioList (CDKRADIO *radio, boolean Box)
|
||
|
{
|
||
|
int scrollbarAdj = (radio->scrollbarPlacement == LEFT) ? 1 : 0;
|
||
|
int j, k;
|
||
|
|
||
|
/* draw the list */
|
||
|
for (j = 0; j < radio->viewSize; j++)
|
||
|
{
|
||
|
int xpos = SCREEN_XPOS (radio, 0);
|
||
|
int ypos = SCREEN_YPOS (radio, j);
|
||
|
|
||
|
/* Draw the empty string. */
|
||
|
writeBlanks (radio->win, xpos, ypos,
|
||
|
HORIZONTAL, 0, radio->boxWidth - BorderOf (radio));
|
||
|
|
||
|
k = j + radio->currentTop;
|
||
|
|
||
|
/* Draw the element in the radio list. */
|
||
|
if (k < radio->listSize)
|
||
|
{
|
||
|
int screenPos = SCREENPOS (radio, k);
|
||
|
|
||
|
/* Draw the line. */
|
||
|
writeChtype (radio->win,
|
||
|
(screenPos >= 0) ? screenPos : 1,
|
||
|
ypos,
|
||
|
radio->item[k],
|
||
|
HORIZONTAL,
|
||
|
(screenPos >= 0) ? 0 : (1 - screenPos),
|
||
|
radio->itemLen[k]);
|
||
|
|
||
|
/* Draw the selected choice... */
|
||
|
xpos += scrollbarAdj;
|
||
|
(void)mvwaddch (radio->win, ypos, xpos++, radio->leftBoxChar);
|
||
|
(void)mvwaddch (radio->win, ypos, xpos++, ((k == radio->selectedItem)
|
||
|
? radio->choiceChar
|
||
|
: ' '));
|
||
|
(void)mvwaddch (radio->win, ypos, xpos++, radio->rightBoxChar);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Highlight the current item. */
|
||
|
if (ObjPtr (radio)->hasFocus)
|
||
|
{
|
||
|
k = radio->currentItem;
|
||
|
if (k < radio->listSize)
|
||
|
{
|
||
|
int screenPos = SCREENPOS (radio, k);
|
||
|
int ypos = SCREEN_YPOS (radio, radio->currentHigh);
|
||
|
|
||
|
writeChtypeAttrib (radio->win,
|
||
|
(screenPos >= 0) ? screenPos : (1 + scrollbarAdj),
|
||
|
ypos,
|
||
|
radio->item[k],
|
||
|
radio->highlight,
|
||
|
HORIZONTAL,
|
||
|
(screenPos >= 0) ? 0 : (1 - screenPos),
|
||
|
radio->itemLen[k]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (radio->scrollbar)
|
||
|
{
|
||
|
radio->togglePos = floorCDK (radio->currentItem * (double)radio->step);
|
||
|
radio->togglePos = MINIMUM (radio->togglePos,
|
||
|
getmaxy (radio->scrollbarWin) - 1);
|
||
|
|
||
|
(void)mvwvline (radio->scrollbarWin, 0, 0,
|
||
|
ACS_CKBOARD, getmaxy (radio->scrollbarWin));
|
||
|
(void)mvwvline (radio->scrollbarWin, radio->togglePos, 0,
|
||
|
' ' | A_REVERSE, radio->toggleSize);
|
||
|
}
|
||
|
|
||
|
/* Box it if needed. */
|
||
|
if (Box)
|
||
|
{
|
||
|
drawObjBox (radio->win, ObjOf (radio));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
touchwin (radio->win);
|
||
|
}
|
||
|
|
||
|
fixCursorPosition (radio);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the background attribute of the widget.
|
||
|
*/
|
||
|
static void _setBKattrRadio (CDKOBJS *object, chtype attrib)
|
||
|
{
|
||
|
if (object != 0)
|
||
|
{
|
||
|
CDKRADIO *widget = (CDKRADIO *)object;
|
||
|
|
||
|
wbkgd (widget->win, attrib);
|
||
|
if (widget->scrollbarWin != 0)
|
||
|
{
|
||
|
wbkgd (widget->scrollbarWin, attrib);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void destroyInfo (CDKRADIO *widget)
|
||
|
{
|
||
|
CDKfreeChtypes (widget->item);
|
||
|
widget->item = 0;
|
||
|
|
||
|
freeAndNull (widget->itemLen);
|
||
|
freeAndNull (widget->itemPos);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This function destroys the radio widget.
|
||
|
*/
|
||
|
static void _destroyCDKRadio (CDKOBJS *object)
|
||
|
{
|
||
|
if (object != 0)
|
||
|
{
|
||
|
CDKRADIO *radio = (CDKRADIO *)object;
|
||
|
|
||
|
cleanCdkTitle (object);
|
||
|
destroyInfo (radio);
|
||
|
|
||
|
/* Clean up the windows. */
|
||
|
deleteCursesWindow (radio->scrollbarWin);
|
||
|
deleteCursesWindow (radio->shadowWin);
|
||
|
deleteCursesWindow (radio->win);
|
||
|
|
||
|
/* Clean the key bindings. */
|
||
|
cleanCDKObjectBindings (vRADIO, radio);
|
||
|
|
||
|
/* Unregister this object. */
|
||
|
unregisterCDKObject (vRADIO, radio);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This function erases the radio widget.
|
||
|
*/
|
||
|
static void _eraseCDKRadio (CDKOBJS *object)
|
||
|
{
|
||
|
if (validCDKObject (object))
|
||
|
{
|
||
|
CDKRADIO *radio = (CDKRADIO *)object;
|
||
|
|
||
|
eraseCursesWindow (radio->win);
|
||
|
eraseCursesWindow (radio->shadowWin);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This set various attributes of the radio list.
|
||
|
*/
|
||
|
void setCDKRadio (CDKRADIO *radio, chtype highlight, chtype choiceChar, int Box)
|
||
|
{
|
||
|
setCDKRadioHighlight (radio, highlight);
|
||
|
setCDKRadioChoiceCharacter (radio, choiceChar);
|
||
|
setCDKRadioBox (radio, Box);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the radio list items.
|
||
|
*/
|
||
|
void setCDKRadioItems (CDKRADIO *radio, CDK_CSTRING2 list, int listSize)
|
||
|
{
|
||
|
int widestItem;
|
||
|
int j = 0;
|
||
|
|
||
|
widestItem = createList (radio, list, listSize, radio->boxWidth);
|
||
|
if (widestItem <= 0)
|
||
|
return;
|
||
|
|
||
|
/* Clean up the display. */
|
||
|
for (j = 0; j < radio->viewSize; j++)
|
||
|
{
|
||
|
writeBlanks (radio->win,
|
||
|
SCREEN_XPOS (radio, 0),
|
||
|
SCREEN_YPOS (radio, j),
|
||
|
HORIZONTAL,
|
||
|
0,
|
||
|
radio->boxWidth - BorderOf (radio));
|
||
|
}
|
||
|
|
||
|
setViewSize (radio, listSize);
|
||
|
|
||
|
setCDKRadioCurrentItem (radio, 0);
|
||
|
radio->leftChar = 0;
|
||
|
radio->selectedItem = 0;
|
||
|
|
||
|
updateViewWidth (radio, widestItem);
|
||
|
}
|
||
|
int getCDKRadioItems (CDKRADIO *radio, char **list)
|
||
|
{
|
||
|
if (list != 0)
|
||
|
{
|
||
|
int j;
|
||
|
|
||
|
for (j = 0; j < radio->listSize; j++)
|
||
|
{
|
||
|
list[j] = chtype2Char (radio->item[j]);
|
||
|
}
|
||
|
}
|
||
|
return radio->listSize;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the highlight bar of the radio list.
|
||
|
*/
|
||
|
void setCDKRadioHighlight (CDKRADIO *radio, chtype highlight)
|
||
|
{
|
||
|
radio->highlight = highlight;
|
||
|
}
|
||
|
chtype getCDKRadioHighlight (CDKRADIO *radio)
|
||
|
{
|
||
|
return radio->highlight;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the character to use when selecting an item in the list.
|
||
|
*/
|
||
|
void setCDKRadioChoiceCharacter (CDKRADIO *radio, chtype character)
|
||
|
{
|
||
|
radio->choiceChar = character;
|
||
|
}
|
||
|
chtype getCDKRadioChoiceCharacter (CDKRADIO *radio)
|
||
|
{
|
||
|
return radio->choiceChar;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the character to use to draw the left side of the
|
||
|
* choice box on the list.
|
||
|
*/
|
||
|
void setCDKRadioLeftBrace (CDKRADIO *radio, chtype character)
|
||
|
{
|
||
|
radio->leftBoxChar = character;
|
||
|
}
|
||
|
chtype getCDKRadioLeftBrace (CDKRADIO *radio)
|
||
|
{
|
||
|
return radio->leftBoxChar;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the character to use to draw the right side of the
|
||
|
* choice box on the list.
|
||
|
*/
|
||
|
void setCDKRadioRightBrace (CDKRADIO *radio, chtype character)
|
||
|
{
|
||
|
radio->rightBoxChar = character;
|
||
|
}
|
||
|
chtype getCDKRadioRightBrace (CDKRADIO *radio)
|
||
|
{
|
||
|
return radio->rightBoxChar;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the box attribute of the widget.
|
||
|
*/
|
||
|
void setCDKRadioBox (CDKRADIO *radio, boolean Box)
|
||
|
{
|
||
|
ObjOf (radio)->box = Box;
|
||
|
ObjOf (radio)->borderSize = Box ? 1 : 0;
|
||
|
}
|
||
|
boolean getCDKRadioBox (CDKRADIO *radio)
|
||
|
{
|
||
|
return ObjOf (radio)->box;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the current high lighted item of the widget
|
||
|
*/
|
||
|
void setCDKRadioCurrentItem (CDKRADIO *radio, int item)
|
||
|
{
|
||
|
scroller_SetPosition ((CDKSCROLLER *)radio, item);
|
||
|
radio->selectedItem = item;
|
||
|
}
|
||
|
int getCDKRadioCurrentItem (CDKRADIO *radio)
|
||
|
{
|
||
|
return radio->currentItem;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This sets the selected item of the widget
|
||
|
*/
|
||
|
void setCDKRadioSelectedItem (CDKRADIO *radio, int item)
|
||
|
{
|
||
|
radio->selectedItem = item;
|
||
|
}
|
||
|
int getCDKRadioSelectedItem (CDKRADIO *radio)
|
||
|
{
|
||
|
return radio->selectedItem;
|
||
|
}
|
||
|
|
||
|
static void _focusCDKRadio (CDKOBJS *object)
|
||
|
{
|
||
|
CDKRADIO *radio = (CDKRADIO *)object;
|
||
|
|
||
|
drawCDKRadioList (radio, ObjOf (radio)->box);
|
||
|
}
|
||
|
|
||
|
static void _unfocusCDKRadio (CDKOBJS *object)
|
||
|
{
|
||
|
CDKRADIO *radio = (CDKRADIO *)object;
|
||
|
|
||
|
drawCDKRadioList (radio, ObjOf (radio)->box);
|
||
|
}
|
||
|
|
||
|
static int createList (CDKRADIO *radio, CDK_CSTRING2 list, int listSize, int boxWidth)
|
||
|
{
|
||
|
int status = 0;
|
||
|
int widestItem = 0;
|
||
|
|
||
|
if (listSize >= 0)
|
||
|
{
|
||
|
/* *INDENT-EQLS* */
|
||
|
chtype **newList = typeCallocN (chtype *, listSize + 1);
|
||
|
int *newLen = typeCallocN (int, listSize + 1);
|
||
|
int *newPos = typeCallocN (int, listSize + 1);
|
||
|
|
||
|
if (newList != 0
|
||
|
&& newLen != 0
|
||
|
&& newPos != 0)
|
||
|
{
|
||
|
int j;
|
||
|
|
||
|
/* Each item in the needs to be converted to chtype * */
|
||
|
status = 1;
|
||
|
boxWidth -= (2 + BorderOf (radio));
|
||
|
for (j = 0; j < listSize; j++)
|
||
|
{
|
||
|
newList[j] = char2Chtype (list[j], &newLen[j], &newPos[j]);
|
||
|
if (newList[j] == 0)
|
||
|
{
|
||
|
status = 0;
|
||
|
break;
|
||
|
}
|
||
|
newPos[j] = justifyString (boxWidth, newLen[j], newPos[j]) + 3;
|
||
|
widestItem = MAXIMUM (widestItem, newLen[j]);
|
||
|
}
|
||
|
if (status)
|
||
|
{
|
||
|
destroyInfo (radio);
|
||
|
|
||
|
radio->item = newList;
|
||
|
radio->itemLen = newLen;
|
||
|
radio->itemPos = newPos;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CDKfreeChtypes (newList);
|
||
|
freeChecked (newLen);
|
||
|
freeChecked (newPos);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CDKfreeChtypes (newList);
|
||
|
freeChecked (newLen);
|
||
|
freeChecked (newPos);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
destroyInfo (radio);
|
||
|
}
|
||
|
|
||
|
return status ? widestItem : 0;
|
||
|
}
|
||
|
|
||
|
dummyRefreshData (Radio)
|
||
|
|
||
|
dummySaveData (Radio)
|