914 lines
23 KiB
C
914 lines
23 KiB
C
#include <cdk.h>
|
|
|
|
/*
|
|
* $Author: garbled $
|
|
* $Date: 2001/01/09 18:41:54 $
|
|
* $Revision: 1.3 $
|
|
*/
|
|
|
|
/*
|
|
* Declare file local prototypes.
|
|
*/
|
|
static void CDKTemplateCallBack (CDKTEMPLATE *cdktemplate, chtype input);
|
|
static void drawCDKTemplateField (CDKTEMPLATE *cdktemplate);
|
|
static void adjustCDKTemplateCursor (CDKTEMPLATE *cdktemplate, int direction);
|
|
|
|
#define isPlateChar(c) ((c) != 0 && strchr("#ACcMXxz", c) != 0)
|
|
|
|
/*
|
|
* Declare file local variables.
|
|
*/
|
|
extern char *GPasteBuffer;
|
|
|
|
DeclareCDKObjects(my_funcs,Template);
|
|
|
|
/*
|
|
* This creates a cdktemplate widget.
|
|
*/
|
|
CDKTEMPLATE *newCDKTemplate (CDKSCREEN *cdkscreen, int xplace, int yplace, char *title, char *label, char *plate, char *Overlay, boolean Box, boolean shadow)
|
|
{
|
|
/* Set up some variables */
|
|
CDKTEMPLATE *cdktemplate = newCDKObject(CDKTEMPLATE, &my_funcs);
|
|
chtype *holder = 0;
|
|
int parentWidth = getmaxx(cdkscreen->window);
|
|
int parentHeight = getmaxy(cdkscreen->window);
|
|
int boxWidth = 0;
|
|
int boxHeight = 3;
|
|
int maxWidth = INT_MIN;
|
|
int xpos = xplace;
|
|
int ypos = yplace;
|
|
int horizontalAdjust = 0;
|
|
int fieldWidth = 0;
|
|
int plateLen = 0;
|
|
int junk = 0;
|
|
char **temp = 0;
|
|
int x, len, junk2;
|
|
|
|
/* Make sure the plate is not null. */
|
|
if (plate == 0)
|
|
{
|
|
free (cdktemplate);
|
|
return 0;
|
|
}
|
|
fieldWidth = (int)strlen (plate);
|
|
|
|
/* Set some basic values of the cdktemplate field. */
|
|
cdktemplate->label = 0;
|
|
cdktemplate->labelLen = 0;
|
|
cdktemplate->labelWin = 0;
|
|
cdktemplate->titleLines = 0;
|
|
|
|
/* Translate the char * label to a chtype * */
|
|
if (label != 0)
|
|
{
|
|
cdktemplate->label = char2Chtype (label, &cdktemplate->labelLen, &junk);
|
|
}
|
|
|
|
/* Translate the char * Overlay to a chtype * */
|
|
if (Overlay != 0)
|
|
{
|
|
cdktemplate->overlay = char2Chtype (Overlay, &cdktemplate->overlayLen, &junk);
|
|
cdktemplate->fieldAttr = cdktemplate->overlay[0] & A_ATTRIBUTES;
|
|
}
|
|
else
|
|
{
|
|
cdktemplate->overlay = 0;
|
|
cdktemplate->overlayLen = 0;
|
|
cdktemplate->fieldAttr = A_NORMAL;
|
|
}
|
|
|
|
/* Set the box width. */
|
|
boxWidth = fieldWidth+ cdktemplate->labelLen + 2;
|
|
|
|
/* Translate the char * items to chtype * */
|
|
if (title != 0)
|
|
{
|
|
temp = CDKsplitString (title, '\n');
|
|
cdktemplate->titleLines = CDKcountStrings (temp);
|
|
|
|
/* We need to determine the widest title line. */
|
|
for (x=0; x < cdktemplate->titleLines; x++)
|
|
{
|
|
holder = char2Chtype (temp[x], &len, &junk2);
|
|
maxWidth = MAXIMUM (maxWidth, len);
|
|
freeChtype (holder);
|
|
}
|
|
|
|
/*
|
|
* If one of the title lines is wider than the field and the label,
|
|
* the box width will expand to accomodate.
|
|
*/
|
|
if (maxWidth > boxWidth)
|
|
{
|
|
horizontalAdjust = (int)((maxWidth - boxWidth) / 2) + 1;
|
|
boxWidth = maxWidth + 2;
|
|
}
|
|
|
|
/* For each line in the title, convert from char * to chtype * */
|
|
for (x=0; x < cdktemplate->titleLines; x++)
|
|
{
|
|
cdktemplate->title[x] = char2Chtype (temp[x], &cdktemplate->titleLen[x], &cdktemplate->titlePos[x]);
|
|
cdktemplate->titlePos[x] = justifyString (boxWidth - 2, cdktemplate->titleLen[x], cdktemplate->titlePos[x]);
|
|
}
|
|
|
|
CDKfreeStrings(temp);
|
|
}
|
|
else
|
|
{
|
|
/* No title? Set the required variables. */
|
|
cdktemplate->titleLines = 0;
|
|
}
|
|
boxHeight += cdktemplate->titleLines;
|
|
|
|
/*
|
|
* Make sure we didn't extend beyond the dimensions of the window.
|
|
*/
|
|
boxWidth = MINIMUM (boxWidth, parentWidth);
|
|
boxHeight = MINIMUM (boxHeight, parentHeight);
|
|
fieldWidth = MINIMUM (boxWidth - 2 - cdktemplate->labelLen, fieldWidth);
|
|
|
|
/* Rejustify the x and y positions if we need to. */
|
|
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
|
|
|
|
/* Make the cdktemplate window */
|
|
cdktemplate->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
|
|
|
|
/* Is the cdktemplate window null?? */
|
|
if (cdktemplate->win == 0)
|
|
{
|
|
/* Clean up any used memory. */
|
|
freeChtype (cdktemplate->label);
|
|
freeChtype (cdktemplate->overlay);
|
|
free (cdktemplate);
|
|
|
|
/* Return a null pointer. */
|
|
return (0);
|
|
}
|
|
keypad (cdktemplate->win, TRUE);
|
|
|
|
if (cdktemplate->titleLines > 0)
|
|
{
|
|
/* Make the title window. */
|
|
cdktemplate->titleWin = subwin (cdktemplate->win,
|
|
cdktemplate->titleLines, boxWidth - 2,
|
|
ypos + 1, xpos + 1);
|
|
}
|
|
|
|
/* Make the label window. */
|
|
if (cdktemplate->label != 0)
|
|
{
|
|
cdktemplate->labelWin = subwin (cdktemplate->win,
|
|
1, cdktemplate->labelLen + 2,
|
|
ypos + cdktemplate->titleLines + 1,
|
|
xpos + horizontalAdjust + 1);
|
|
}
|
|
|
|
/* Make the field window. */
|
|
cdktemplate->fieldWin = subwin (cdktemplate->win,
|
|
1, fieldWidth,
|
|
ypos + cdktemplate->titleLines + 1,
|
|
xpos + cdktemplate->labelLen + horizontalAdjust + 1);
|
|
keypad (cdktemplate->fieldWin, TRUE);
|
|
|
|
/* Set up the info field. */
|
|
cdktemplate->plateLen = (int)strlen(plate);
|
|
cdktemplate->info = (char *)malloc (sizeof(char) * (cdktemplate->plateLen + 2));
|
|
memset (cdktemplate->info, '\0', cdktemplate->plateLen + 1);
|
|
|
|
/* Copy the plate to the cdktemplate. */
|
|
plateLen = strlen (plate);
|
|
cdktemplate->plate = (char *)malloc (sizeof (char) * plateLen + 3);
|
|
strncpy (cdktemplate->plate, plate, plateLen + 3);
|
|
|
|
/* Set up the rest of the structure */
|
|
ScreenOf(cdktemplate) = cdkscreen;
|
|
cdktemplate->parent = cdkscreen->window;
|
|
cdktemplate->fieldWidth = fieldWidth;
|
|
cdktemplate->boxHeight = boxHeight;
|
|
cdktemplate->boxWidth = boxWidth;
|
|
cdktemplate->platePos = 0;
|
|
cdktemplate->screenPos = 0;
|
|
cdktemplate->infoPos = 0;
|
|
cdktemplate->exitType = vNEVER_ACTIVATED;
|
|
cdktemplate->min = 0;
|
|
ObjOf(cdktemplate)->box = Box;
|
|
cdktemplate->shadow = shadow;
|
|
cdktemplate->callbackfn = (void *)&CDKTemplateCallBack;
|
|
cdktemplate->preProcessFunction = 0;
|
|
cdktemplate->preProcessData = 0;
|
|
cdktemplate->postProcessFunction = 0;
|
|
cdktemplate->postProcessData = 0;
|
|
cdktemplate->ULChar = ACS_ULCORNER;
|
|
cdktemplate->URChar = ACS_URCORNER;
|
|
cdktemplate->LLChar = ACS_LLCORNER;
|
|
cdktemplate->LRChar = ACS_LRCORNER;
|
|
cdktemplate->HChar = ACS_HLINE;
|
|
cdktemplate->VChar = ACS_VLINE;
|
|
cdktemplate->BoxAttrib = A_NORMAL;
|
|
|
|
/* Clean the key bindings. */
|
|
cleanCDKObjectBindings (vTEMPLATE, cdktemplate);
|
|
|
|
/* Register this baby. */
|
|
registerCDKObject (cdkscreen, vTEMPLATE, cdktemplate);
|
|
|
|
/* Return the pointer to the structure */
|
|
return cdktemplate;
|
|
}
|
|
|
|
/*
|
|
* This actually manages the cdktemplate widget...
|
|
*/
|
|
char *activateCDKTemplate (CDKTEMPLATE *cdktemplate, chtype *actions)
|
|
{
|
|
/* Declare local variables. */
|
|
chtype input = 0;
|
|
char *ret = 0;
|
|
|
|
/* Draw the object. */
|
|
drawCDKTemplate (cdktemplate, ObjOf(cdktemplate)->box);
|
|
|
|
/* Check if actions is null. */
|
|
if (actions == 0)
|
|
{
|
|
for (;;)
|
|
{
|
|
/* Get the input. */
|
|
wrefresh (cdktemplate->fieldWin);
|
|
input = wgetch (cdktemplate->fieldWin);
|
|
|
|
/* Inject the character into the widget. */
|
|
ret = injectCDKTemplate (cdktemplate, input);
|
|
if (cdktemplate->exitType != vEARLY_EXIT)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int length = chlen (actions);
|
|
int x = 0;
|
|
|
|
/* Inject each character one at a time. */
|
|
for (x=0; x < length; x++)
|
|
{
|
|
ret = injectCDKTemplate (cdktemplate, actions[x]);
|
|
if (cdktemplate->exitType != vEARLY_EXIT)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Set the exit type and return. */
|
|
cdktemplate->exitType = vEARLY_EXIT;
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* This injects a character into the widget.
|
|
*/
|
|
char *injectCDKTemplate (CDKTEMPLATE *cdktemplate, chtype input)
|
|
{
|
|
/* Declare some local variables. */
|
|
int ppReturn = 1;
|
|
int length, x;
|
|
|
|
/* Set the exit type and return. */
|
|
cdktemplate->exitType = vEARLY_EXIT;
|
|
|
|
/* Move the cursor. */
|
|
drawCDKTemplateField (cdktemplate);
|
|
|
|
/* Check if there is a pre-process function to be called. */
|
|
if (cdktemplate->preProcessFunction != 0)
|
|
{
|
|
ppReturn = ((PROCESSFN)(cdktemplate->preProcessFunction)) (vTEMPLATE, cdktemplate, cdktemplate->preProcessData, input);
|
|
}
|
|
|
|
/* Should we continue? */
|
|
if (ppReturn != 0)
|
|
{
|
|
/* Check a predefined binding... */
|
|
if (checkCDKObjectBind (vTEMPLATE, cdktemplate, input) != 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
switch (input)
|
|
{
|
|
case KEY_LEFT : case KEY_RIGHT : case KEY_UP : case KEY_DOWN :
|
|
Beep();
|
|
break;
|
|
|
|
case CDK_ERASE :
|
|
if (strlen(cdktemplate->info) != 0)
|
|
{
|
|
cleanChar (cdktemplate->info, cdktemplate->plateLen + 1, '\0');
|
|
cdktemplate->screenPos = 0;
|
|
cdktemplate->infoPos = 0;
|
|
cdktemplate->platePos = 0;
|
|
drawCDKTemplateField (cdktemplate);
|
|
}
|
|
break;
|
|
|
|
case CDK_CUT:
|
|
if ((int)strlen(cdktemplate->info) != 0)
|
|
{
|
|
freeChar (GPasteBuffer);
|
|
GPasteBuffer = copyChar (cdktemplate->info);
|
|
cleanChar (cdktemplate->info, cdktemplate->plateLen + 1, '\0');
|
|
cdktemplate->screenPos = 0;
|
|
cdktemplate->infoPos = 0;
|
|
cdktemplate->platePos = 0;
|
|
drawCDKTemplateField (cdktemplate);
|
|
}
|
|
else
|
|
{
|
|
Beep();
|
|
}
|
|
break;
|
|
|
|
case CDK_COPY:
|
|
if ((int)strlen(cdktemplate->info) != 0)
|
|
{
|
|
freeChar (GPasteBuffer);
|
|
GPasteBuffer = copyChar (cdktemplate->info);
|
|
}
|
|
else
|
|
{
|
|
Beep();
|
|
}
|
|
break;
|
|
|
|
case CDK_PASTE:
|
|
if (GPasteBuffer != 0)
|
|
{
|
|
/* Clean the informatiob from the field. */
|
|
cleanChar (cdktemplate->info, cdktemplate->plateLen + 1, '\0');
|
|
cdktemplate->screenPos = 0;
|
|
cdktemplate->infoPos = 0;
|
|
cdktemplate->platePos = 0;
|
|
|
|
/* Start inserting each character one at a time. */
|
|
length = (int)strlen (GPasteBuffer);
|
|
for (x=0; x < length; x++)
|
|
{
|
|
((TEMPLATECB)cdktemplate->callbackfn)(cdktemplate, GPasteBuffer[x]);
|
|
}
|
|
drawCDKTemplateField (cdktemplate);
|
|
}
|
|
else
|
|
{
|
|
Beep();
|
|
}
|
|
break;
|
|
|
|
case KEY_RETURN : case KEY_TAB : case KEY_ENTER : case KEY_CR :
|
|
if ((int)strlen(cdktemplate->info) < (int)cdktemplate->min)
|
|
{
|
|
Beep();
|
|
}
|
|
else
|
|
{
|
|
cdktemplate->exitType = vNORMAL;
|
|
return cdktemplate->info;
|
|
}
|
|
break;
|
|
|
|
case KEY_ESC :
|
|
cdktemplate->exitType = vESCAPE_HIT;
|
|
return 0;
|
|
|
|
case CDK_REFRESH :
|
|
eraseCDKScreen (ScreenOf(cdktemplate));
|
|
refreshCDKScreen (ScreenOf(cdktemplate));
|
|
break;
|
|
|
|
default :
|
|
((TEMPLATECB)cdktemplate->callbackfn)(cdktemplate, input);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Should we call a post-process? */
|
|
if (cdktemplate->postProcessFunction != 0)
|
|
{
|
|
((PROCESSFN)(cdktemplate->postProcessFunction)) (vTEMPLATE, cdktemplate, cdktemplate->postProcessData, input);
|
|
}
|
|
}
|
|
|
|
/* Set the exit type and return. */
|
|
cdktemplate->exitType = vEARLY_EXIT;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* This is the standard callback proc for the cdktemplate.
|
|
*/
|
|
static void CDKTemplateCallBack (CDKTEMPLATE *cdktemplate, chtype input)
|
|
{
|
|
chtype fieldColor;
|
|
|
|
/* Check the character input. */
|
|
if (input == DELETE || input == KEY_BACKSPACE ||
|
|
input == CONTROL('H') || input == KEY_DC)
|
|
{
|
|
/* Make sure we don't go out of bounds. */
|
|
if (cdktemplate->platePos == 0 || cdktemplate->info[0] == '\0')
|
|
{
|
|
Beep();
|
|
return;
|
|
}
|
|
|
|
/* Remove it and redisplay.... */
|
|
cdktemplate->info[--cdktemplate->infoPos] = '\0';
|
|
cdktemplate->platePos--;
|
|
cdktemplate->screenPos--;
|
|
|
|
/* Move the cursor */
|
|
fieldColor = cdktemplate->overlay[cdktemplate->screenPos] & A_ATTRIBUTES;
|
|
adjustCDKTemplateCursor (cdktemplate, -1);
|
|
mvwaddch (cdktemplate->fieldWin, 0, cdktemplate->screenPos,
|
|
cdktemplate->overlay[cdktemplate->platePos] | fieldColor);
|
|
adjustCDKTemplateCursor (cdktemplate, -1);
|
|
}
|
|
else
|
|
{
|
|
/* To be safe, we should cast the chtype to a char */
|
|
char newchar = (char)input;
|
|
|
|
/* Make sure we don't go out of bounds. */
|
|
if (cdktemplate->platePos >= cdktemplate->fieldWidth)
|
|
{
|
|
Beep();
|
|
return;
|
|
}
|
|
|
|
/* We should check to see if what they typed in matches */
|
|
/* what the plate states. */
|
|
if (isdigit((int)newchar) && (
|
|
cdktemplate->plate[cdktemplate->platePos] == 'A' ||
|
|
cdktemplate->plate[cdktemplate->platePos] == 'C' ||
|
|
cdktemplate->plate[cdktemplate->platePos] == 'c'))
|
|
{
|
|
Beep();
|
|
return;
|
|
}
|
|
if (!isdigit ((int)newchar) &&
|
|
cdktemplate->plate[cdktemplate->platePos] == '#')
|
|
{
|
|
Beep();
|
|
return;
|
|
}
|
|
|
|
/* Do we need to convert the case??? */
|
|
if (cdktemplate->plate[cdktemplate->platePos] == 'C' ||
|
|
cdktemplate->plate[cdktemplate->platePos] == 'X')
|
|
{
|
|
if (isascii ((int)newchar) && islower ((int)newchar))
|
|
{
|
|
newchar = toupper ((int)newchar);
|
|
}
|
|
}
|
|
else if (cdktemplate->plate[cdktemplate->platePos] == 'c' ||
|
|
cdktemplate->plate[cdktemplate->platePos] == 'x')
|
|
{
|
|
if (isascii ((int)newchar) && isupper ((int)newchar))
|
|
{
|
|
newchar = tolower ((int)newchar);
|
|
}
|
|
}
|
|
|
|
/* Add it and redisplay.... */
|
|
fieldColor = cdktemplate->overlay[cdktemplate->screenPos] & A_ATTRIBUTES;
|
|
cdktemplate->info[cdktemplate->infoPos++] = newchar;
|
|
cdktemplate->info[cdktemplate->infoPos] = '\0';
|
|
mvwaddch (cdktemplate->fieldWin, 0, cdktemplate->screenPos,
|
|
newchar | fieldColor);
|
|
cdktemplate->platePos++;
|
|
cdktemplate->screenPos++;
|
|
|
|
/* Move the cursor */
|
|
adjustCDKTemplateCursor (cdktemplate, +1);
|
|
}
|
|
wnoutrefresh (cdktemplate->fieldWin);
|
|
wnoutrefresh (cdktemplate->win);
|
|
}
|
|
|
|
/*
|
|
* This takes the overlay and the info, and mixes the two, for a
|
|
* 'mixed' character string...
|
|
*/
|
|
char *mixCDKTemplate (CDKTEMPLATE *cdktemplate)
|
|
{
|
|
/* Reconstruct the info. */
|
|
char *mixedString = 0;
|
|
int platePos = 0;
|
|
int infoPos = 0;
|
|
|
|
/* Make some room for the mixed string. */
|
|
mixedString = (char *) malloc ((sizeof (char) * cdktemplate->plateLen) + 3);
|
|
cleanChar (mixedString, cdktemplate->plateLen + 3, '\0');
|
|
|
|
/* Start copying from the plate to the destination string. */
|
|
while (platePos < cdktemplate->plateLen)
|
|
{
|
|
if (isPlateChar(cdktemplate->plate[platePos]))
|
|
{
|
|
mixedString[platePos] = cdktemplate->info[infoPos++];
|
|
}
|
|
else
|
|
{
|
|
mixedString[platePos] = cdktemplate->plate[platePos];
|
|
}
|
|
platePos++;
|
|
}
|
|
|
|
/* Return the new string. */
|
|
return mixedString;
|
|
}
|
|
|
|
/*
|
|
* This takes a mixed string and returns a non-mixed string.
|
|
*/
|
|
char *unmixCDKTemplate (CDKTEMPLATE *cdktemplate, char *info)
|
|
{
|
|
/* Reconstruct the info. */
|
|
char *unmixedString = 0;
|
|
int infolen = (int)strlen (info);
|
|
int x = 0;
|
|
int pos = 0;
|
|
|
|
/* Create a char * pointer. */
|
|
unmixedString = (char *)malloc (sizeof(char) * (infolen + 2));
|
|
cleanChar (unmixedString, infolen + 2, '\0');
|
|
|
|
/* Start copying. */
|
|
while (pos < infolen)
|
|
{
|
|
if (isPlateChar(cdktemplate->plate[pos]))
|
|
{
|
|
unmixedString[x++] = info[pos++];
|
|
}
|
|
else
|
|
{
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
/* Return the new string. */
|
|
return unmixedString;
|
|
}
|
|
|
|
/*
|
|
* This moves the cdktemplate field to the given location.
|
|
*/
|
|
static void _moveCDKTemplate (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
|
|
{
|
|
CDKTEMPLATE *cdktemplate = (CDKTEMPLATE *)object;
|
|
|
|
/*
|
|
* If this is a relative move, then we will adjust where we want
|
|
* to move to.
|
|
*/
|
|
if (relative)
|
|
{
|
|
xplace += getbegx(cdktemplate->win);
|
|
yplace += getbegy(cdktemplate->win);
|
|
}
|
|
|
|
/* Adjust the window if we need to. */
|
|
alignxy (WindowOf(cdktemplate), &xplace, &yplace, cdktemplate->boxWidth, cdktemplate->boxHeight);
|
|
|
|
/* Move the window to the new location. */
|
|
moveCursesWindow(cdktemplate->win, xplace, yplace);
|
|
|
|
/* Redraw the window, if they asked for it. */
|
|
if (refresh_flag)
|
|
{
|
|
drawCDKTemplate (cdktemplate, ObjOf(cdktemplate)->box);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This function draws the tmeplate widget.
|
|
*/
|
|
static void _drawCDKTemplate (CDKOBJS *object, boolean Box)
|
|
{
|
|
CDKTEMPLATE *cdktemplate = (CDKTEMPLATE *)object;
|
|
int x;
|
|
|
|
/* Box it if needed */
|
|
if (Box)
|
|
{
|
|
attrbox (cdktemplate->win,
|
|
cdktemplate->ULChar, cdktemplate->URChar,
|
|
cdktemplate->LLChar, cdktemplate->LRChar,
|
|
cdktemplate->HChar, cdktemplate->VChar,
|
|
cdktemplate->BoxAttrib,
|
|
cdktemplate->shadow);
|
|
}
|
|
|
|
if (cdktemplate->titleLines > 0)
|
|
{
|
|
/* Draw in the title if there is one. */
|
|
for (x=0; x < cdktemplate->titleLines; x++)
|
|
{
|
|
writeChtype (cdktemplate->titleWin,
|
|
cdktemplate->titlePos[x], x,
|
|
cdktemplate->title[x],
|
|
HORIZONTAL, 0,
|
|
cdktemplate->titleLen[x]);
|
|
}
|
|
wnoutrefresh (cdktemplate->titleWin);
|
|
}
|
|
|
|
/* Draw the cdktemplate field. */
|
|
drawCDKTemplateField (cdktemplate);
|
|
}
|
|
|
|
/*
|
|
* This draws the cdktemplate field.
|
|
*/
|
|
static void drawCDKTemplateField (CDKTEMPLATE *cdktemplate)
|
|
{
|
|
/* Declare local variables. */
|
|
chtype fieldColor = 0;
|
|
int infolen = (int)strlen (cdktemplate->info);
|
|
int x = 0;
|
|
|
|
/* Draw in the label and the cdktemplate object. */
|
|
if (cdktemplate->label != 0)
|
|
{
|
|
writeChtype (cdktemplate->labelWin,
|
|
0, 0,
|
|
cdktemplate->label,
|
|
HORIZONTAL, 0,
|
|
cdktemplate->labelLen);
|
|
wnoutrefresh (cdktemplate->labelWin);
|
|
}
|
|
|
|
/* Draw in the cdktemplate... */
|
|
if (cdktemplate->overlay != 0)
|
|
{
|
|
writeChtype (cdktemplate->fieldWin,
|
|
0, 0,
|
|
cdktemplate->overlay,
|
|
HORIZONTAL, 0,
|
|
cdktemplate->overlayLen);
|
|
}
|
|
|
|
/* Adjust the cursor. */
|
|
if (infolen != 0)
|
|
{
|
|
int pos = 0;
|
|
for (x=0; x < cdktemplate->fieldWidth; x++)
|
|
{
|
|
if (isPlateChar(cdktemplate->plate[x]) && pos < infolen)
|
|
{
|
|
fieldColor = cdktemplate->overlay[x] & A_ATTRIBUTES;
|
|
mvwaddch (cdktemplate->fieldWin,
|
|
0, x,
|
|
cdktemplate->info[pos++]|fieldColor);
|
|
}
|
|
}
|
|
wmove (cdktemplate->fieldWin, 0, cdktemplate->screenPos);
|
|
}
|
|
else
|
|
{
|
|
adjustCDKTemplateCursor (cdktemplate, +1);
|
|
}
|
|
wnoutrefresh (cdktemplate->fieldWin);
|
|
wnoutrefresh (cdktemplate->win);
|
|
}
|
|
|
|
/*
|
|
* This function adjusts the cursor for the cdktemplate.
|
|
*/
|
|
static void adjustCDKTemplateCursor (CDKTEMPLATE *cdktemplate, int direction)
|
|
{
|
|
while (!isPlateChar(cdktemplate->plate[cdktemplate->platePos])
|
|
&& cdktemplate->platePos < cdktemplate->fieldWidth)
|
|
{
|
|
cdktemplate->platePos += direction;
|
|
cdktemplate->screenPos += direction;
|
|
}
|
|
wmove (cdktemplate->fieldWin, 0, cdktemplate->screenPos);
|
|
}
|
|
|
|
/*
|
|
* These functions set the drawing characters of the widget.
|
|
*/
|
|
void setCDKTemplateULChar (CDKTEMPLATE *cdktemplate, chtype character)
|
|
{
|
|
cdktemplate->ULChar = character;
|
|
}
|
|
void setCDKTemplateURChar (CDKTEMPLATE *cdktemplate, chtype character)
|
|
{
|
|
cdktemplate->URChar = character;
|
|
}
|
|
void setCDKTemplateLLChar (CDKTEMPLATE *cdktemplate, chtype character)
|
|
{
|
|
cdktemplate->LLChar = character;
|
|
}
|
|
void setCDKTemplateLRChar (CDKTEMPLATE *cdktemplate, chtype character)
|
|
{
|
|
cdktemplate->LRChar = character;
|
|
}
|
|
void setCDKTemplateVerticalChar (CDKTEMPLATE *cdktemplate, chtype character)
|
|
{
|
|
cdktemplate->VChar = character;
|
|
}
|
|
void setCDKTemplateHorizontalChar (CDKTEMPLATE *cdktemplate, chtype character)
|
|
{
|
|
cdktemplate->HChar = character;
|
|
}
|
|
void setCDKTemplateBoxAttribute (CDKTEMPLATE *cdktemplate, chtype character)
|
|
{
|
|
cdktemplate->BoxAttrib = character;
|
|
}
|
|
|
|
/*
|
|
* This sets the background color of the widget.
|
|
*/
|
|
void setCDKTemplateBackgroundColor (CDKTEMPLATE *cdktemplate, char *color)
|
|
{
|
|
chtype *holder = 0;
|
|
int junk1, junk2;
|
|
|
|
/* Make sure the color isn't null. */
|
|
if (color == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Convert the value of the environment variable to a chtype. */
|
|
holder = char2Chtype (color, &junk1, &junk2);
|
|
|
|
/* Set the widgets background color. */
|
|
wbkgd (cdktemplate->win, holder[0]);
|
|
wbkgd (cdktemplate->fieldWin, holder[0]);
|
|
if (cdktemplate->labelWin != 0)
|
|
{
|
|
wbkgd (cdktemplate->labelWin, holder[0]);
|
|
}
|
|
|
|
/* Clean up. */
|
|
freeChtype (holder);
|
|
}
|
|
|
|
/*
|
|
* This function destroys this widget.
|
|
*/
|
|
void destroyCDKTemplate (CDKTEMPLATE *cdktemplate)
|
|
{
|
|
int x;
|
|
|
|
/* Erase the object. */
|
|
eraseCDKTemplate (cdktemplate);
|
|
|
|
/* Clear out the character pointers. */
|
|
freeChtype (cdktemplate->label);
|
|
freeChtype (cdktemplate->overlay);
|
|
freeChar (cdktemplate->plate);
|
|
freeChar (cdktemplate->info);
|
|
for (x=0; x < cdktemplate->titleLines; x++)
|
|
{
|
|
freeChtype (cdktemplate->title[x]);
|
|
}
|
|
|
|
/* Delete the windows. */
|
|
deleteCursesWindow (cdktemplate->win);
|
|
|
|
/* Unregister this object. */
|
|
unregisterCDKObject (vTEMPLATE, cdktemplate);
|
|
|
|
/* Finish cleaning up. */
|
|
free (cdktemplate);
|
|
}
|
|
|
|
/*
|
|
* This function erases the widget.
|
|
*/
|
|
static void _eraseCDKTemplate (CDKOBJS *object)
|
|
{
|
|
CDKTEMPLATE *cdktemplate = (CDKTEMPLATE *)object;
|
|
|
|
eraseCursesWindow (cdktemplate->win);
|
|
}
|
|
|
|
/*
|
|
* This function sets the value given to the cdktemplate.
|
|
*/
|
|
void setCDKTemplate (CDKTEMPLATE *cdktemplate, char *newValue, boolean Box)
|
|
{
|
|
setCDKTemplateValue (cdktemplate, newValue);
|
|
setCDKTemplateBox (cdktemplate, Box);
|
|
}
|
|
|
|
/*
|
|
* This function sets the value given to the cdktemplate.
|
|
*/
|
|
void setCDKTemplateValue (CDKTEMPLATE *cdktemplate, char *newValue)
|
|
{
|
|
/* Declare local variables. */
|
|
int len = 0;
|
|
int copychars = 0;
|
|
int x;
|
|
|
|
/* Just to be sure, if let's make sure the new value isn't null. */
|
|
if (newValue == 0)
|
|
{
|
|
/* Then we want to just erase the old value. */
|
|
cleanChar (cdktemplate->info, cdktemplate->fieldWidth, '\0');
|
|
|
|
/* Set the cursor place values. */
|
|
cdktemplate->screenPos = 0;
|
|
cdktemplate->platePos = 0;
|
|
cdktemplate->infoPos = 0;
|
|
return;
|
|
}
|
|
|
|
/* Determine how many characters we need to copy. */
|
|
len = (int)strlen (newValue);
|
|
copychars = MINIMUM (len, cdktemplate->fieldWidth);
|
|
|
|
/* OK, erase the old value, and copy in the new value. */
|
|
cleanChar (cdktemplate->info, cdktemplate->fieldWidth, '\0');
|
|
strncpy (cdktemplate->info, newValue, copychars);
|
|
|
|
/* Use the function which handles the input of the characters. */
|
|
for (x=0; x < len; x++)
|
|
{
|
|
((TEMPLATECB)cdktemplate->callbackfn)(cdktemplate, (chtype)newValue[x]);
|
|
}
|
|
}
|
|
char *getCDKTemplateValue (CDKTEMPLATE *cdktemplate)
|
|
{
|
|
return cdktemplate->info;
|
|
}
|
|
|
|
/*
|
|
* This sets the minimum number of characters to enter into the widget.
|
|
*/
|
|
void setCDKTemplateMin (CDKTEMPLATE *cdktemplate, int min)
|
|
{
|
|
if (min >= 0)
|
|
{
|
|
cdktemplate->min = min;
|
|
}
|
|
}
|
|
int getCDKTemplateMin (CDKTEMPLATE *cdktemplate)
|
|
{
|
|
return cdktemplate->min;
|
|
}
|
|
|
|
/*
|
|
* This sets the box attribute of the cdktemplate widget.
|
|
*/
|
|
void setCDKTemplateBox (CDKTEMPLATE *cdktemplate, boolean Box)
|
|
{
|
|
ObjOf(cdktemplate)->box = Box;
|
|
}
|
|
boolean getCDKTemplateBox (CDKTEMPLATE *cdktemplate)
|
|
{
|
|
return ObjOf(cdktemplate)->box;
|
|
}
|
|
|
|
/*
|
|
* This erases the information in the cdktemplate widget.
|
|
*/
|
|
void cleanCDKTemplate (CDKTEMPLATE *cdktemplate)
|
|
{
|
|
cleanChar (cdktemplate->info, cdktemplate->fieldWidth, '\0');
|
|
}
|
|
|
|
/*
|
|
* This function sets the callback function for the widget.
|
|
*/
|
|
void setCDKTemplateCB (CDKTEMPLATE *cdktemplate, TEMPLATECB callback)
|
|
{
|
|
cdktemplate->callbackfn = (void *)callback;
|
|
}
|
|
|
|
/*
|
|
* This function sets the pre-process function.
|
|
*/
|
|
void setCDKTemplatePreProcess (CDKTEMPLATE *cdktemplate, PROCESSFN callback, void *data)
|
|
{
|
|
cdktemplate->preProcessFunction = callback;
|
|
cdktemplate->preProcessData = data;
|
|
}
|
|
|
|
/*
|
|
* This function sets the post-process function.
|
|
*/
|
|
void setCDKTemplatePostProcess (CDKTEMPLATE *cdktemplate, PROCESSFN callback, void *data)
|
|
{
|
|
cdktemplate->postProcessFunction = callback;
|
|
cdktemplate->postProcessData = data;
|
|
}
|