1588 lines
36 KiB
C
1588 lines
36 KiB
C
#include <cdk.h>
|
|
|
|
/*
|
|
* $Author: garbled $
|
|
* $Date: 2001/01/09 18:41:53 $
|
|
* $Revision: 1.3 $
|
|
*/
|
|
|
|
/*
|
|
* Declare file local prototypes.
|
|
*/
|
|
static void highlightCDKMatrixCell (CDKMATRIX *matrix);
|
|
static void CDKMatrixCallBack (CDKMATRIX *matrix, chtype input);
|
|
static void drawCDKMatrixCell (CDKMATRIX *matrix,
|
|
int srow, int scol,
|
|
int vrow, int vcol,
|
|
chtype attr, boolean Box);
|
|
static void redrawTitles (CDKMATRIX *matrix, int row, int col);
|
|
|
|
/*
|
|
* Declare file local variables.
|
|
*/
|
|
extern char *GPasteBuffer;
|
|
|
|
DeclareCDKObjects(my_funcs,Matrix);
|
|
|
|
/*
|
|
* This function creates the matrix widget.
|
|
*/
|
|
CDKMATRIX *newCDKMatrix (CDKSCREEN *cdkscreen, int xplace, int yplace, int rows, int cols, int vrows, int vcols, char *title, char **rowtitles, char **coltitles, int *colwidths, int *colvalues, int rspace, int cspace, chtype filler, int dominant, boolean
|
|
|
|
|
|
Box, boolean boxCell, boolean shadow)
|
|
{
|
|
/* Declare local variables. */
|
|
CDKMATRIX *matrix = newCDKObject(CDKMATRIX, &my_funcs);
|
|
int parentWidth = getmaxx(cdkscreen->window);
|
|
int parentHeight = getmaxy(cdkscreen->window);
|
|
chtype *junk = 0;
|
|
int boxHeight = 0;
|
|
int boxWidth = 0;
|
|
int xpos = xplace;
|
|
int ypos = yplace;
|
|
int maxWidth = INT_MIN;
|
|
int maxRowTitleWidth = 0;
|
|
int rowSpace = MAXIMUM (0, rspace);
|
|
int colSpace = MAXIMUM (0, cspace);
|
|
int begx = 0;
|
|
int begy = 0;
|
|
int cellWidth = 0;
|
|
char **temp = 0;
|
|
int x, y, z, len, junk2;
|
|
|
|
/* Make sure that the number of rows/cols/vrows/vcols is not zero. */
|
|
if (rows == 0 || cols == 0 || vrows == 0 || vcols == 0)
|
|
{
|
|
/* Free up any used memory. */
|
|
free (matrix);
|
|
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Make sure the number of virtual cells is not larger than
|
|
* the physical size.
|
|
*/
|
|
vrows = (vrows > rows ? rows : vrows);
|
|
vcols = (vcols > cols ? cols : vcols);
|
|
|
|
/* We need to determine the width of the matrix box. */
|
|
if (title != 0)
|
|
{
|
|
temp = CDKsplitString (title, '\n');
|
|
matrix->titleLines = CDKcountStrings (temp);
|
|
|
|
for (x=0; x < matrix->titleLines; x++)
|
|
{
|
|
junk = char2Chtype (temp[x], &len, &junk2);
|
|
maxWidth = MAXIMUM (maxWidth, len);
|
|
freeChtype (junk);
|
|
}
|
|
|
|
CDKfreeStrings(temp);
|
|
}
|
|
else
|
|
{
|
|
/* No title? Set the required variables. */
|
|
matrix->titleLines = 0;
|
|
}
|
|
boxWidth = maxWidth;
|
|
|
|
/* Determine the height of the box. */
|
|
if (vrows == 1)
|
|
{
|
|
boxHeight = 6 + matrix->titleLines;
|
|
}
|
|
else
|
|
{
|
|
if (rowSpace == 0)
|
|
{
|
|
boxHeight = 6 + matrix->titleLines + ((vrows - 1) * 2);
|
|
}
|
|
else
|
|
{
|
|
boxHeight = 3 + matrix->titleLines + (vrows * 3) + ((vrows-1) * (rowSpace-1));
|
|
}
|
|
}
|
|
|
|
/* Determine the maximum row title width */
|
|
for (x=1; x <= rows; x++)
|
|
{
|
|
matrix->rowtitle[x] = char2Chtype (rowtitles[x], &matrix->rowtitleLen[x], &matrix->rowtitlePos[x]);
|
|
maxRowTitleWidth = MAXIMUM (maxRowTitleWidth, matrix->rowtitleLen[x]);
|
|
}
|
|
matrix->maxrt = maxRowTitleWidth + 2;
|
|
|
|
/* We need to rejustify the row title cell info. */
|
|
for (x=1; x <= rows; x++)
|
|
{
|
|
matrix->rowtitlePos[x] = justifyString (matrix->maxrt, matrix->rowtitleLen[x], matrix->rowtitlePos[x]);
|
|
}
|
|
|
|
/* Determine the width of the matrix. */
|
|
maxWidth = 2 + matrix->maxrt;
|
|
for (x=1; x <= vcols; x++)
|
|
{
|
|
maxWidth += colwidths[x] + 2 + colSpace;
|
|
}
|
|
maxWidth -= (colSpace-1);
|
|
boxWidth = MAXIMUM (maxWidth, boxWidth);
|
|
|
|
/* Translate the char * items to chtype * */
|
|
if (title != 0)
|
|
{
|
|
temp = CDKsplitString (title, '\n');
|
|
matrix->titleLines = CDKcountStrings (temp);
|
|
|
|
/* For each line in the title, convert from char * to chtype * */
|
|
for (x=0; x < matrix->titleLines; x++)
|
|
{
|
|
matrix->title[x] = char2Chtype (temp[x], &matrix->titleLen[x], &matrix->titlePos[x]);
|
|
matrix->titlePos[x] = justifyString (boxWidth, matrix->titleLen[x], matrix->titlePos[x]);
|
|
}
|
|
|
|
CDKfreeStrings(temp);
|
|
}
|
|
|
|
/*
|
|
* Make sure the dimensions of the window didn't
|
|
* extend beyond the dimensions of the parent window.
|
|
*/
|
|
boxWidth = MINIMUM (boxWidth, parentWidth);
|
|
boxHeight = MINIMUM (boxHeight, parentHeight);
|
|
|
|
/* Rejustify the x and y positions if we need to. */
|
|
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
|
|
|
|
/* Make the pop-up window. */
|
|
matrix->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
|
|
|
|
if (matrix->win == 0)
|
|
{
|
|
/* Free up any used memory. */
|
|
for (z=1; z <= rows; z++)
|
|
{
|
|
freeChtype (matrix->rowtitle[z]);
|
|
}
|
|
free (matrix);
|
|
|
|
return (0);
|
|
}
|
|
|
|
/* Make the subwindows in the pop-up. */
|
|
begx = xpos;
|
|
begy = ypos + 1 + matrix->titleLines;
|
|
|
|
/* Make the 'empty' 0x0 cell. */
|
|
matrix->cell[0][0] = subwin (matrix->win, 3, matrix->maxrt, begy, begx);
|
|
begx += matrix->maxrt + 1;
|
|
|
|
/* Make the column titles. */
|
|
for (x=1; x <= vcols; x++)
|
|
{
|
|
cellWidth = colwidths[x] + 3;
|
|
matrix->cell[0][x] = subwin (matrix->win, 1, cellWidth, begy, begx);
|
|
|
|
if (matrix->cell[0][x] == 0)
|
|
{
|
|
goto death;
|
|
}
|
|
|
|
begx += cellWidth + colSpace - 1;
|
|
}
|
|
begy++;
|
|
|
|
/* Make the main cell body */
|
|
for (x=1; x <= vrows; x++)
|
|
{
|
|
/* Make the row titles */
|
|
matrix->cell[x][0] = subwin (matrix->win, 3, matrix->maxrt, begy, xpos+1);
|
|
|
|
if (matrix->cell[x][0] == 0)
|
|
{
|
|
goto death;
|
|
}
|
|
|
|
/* Set the start of the x position. */
|
|
begx = xpos + matrix->maxrt + 1;
|
|
|
|
/* Make the cells */
|
|
for (y=1; y <= vcols; y++)
|
|
{
|
|
cellWidth = colwidths[y] + 3;
|
|
|
|
matrix->cell[x][y] = subwin (matrix->win, 3, cellWidth, begy, begx);
|
|
if (matrix->cell[x][y] == 0)
|
|
{
|
|
goto death;
|
|
}
|
|
|
|
begx += cellWidth + colSpace - 1;
|
|
keypad (matrix->cell[x][y], TRUE);
|
|
}
|
|
begy += rowSpace + 2;
|
|
}
|
|
keypad (matrix->win, TRUE);
|
|
|
|
/* Copy the titles into the structure. */
|
|
for (x=1; x <= cols; x++)
|
|
{
|
|
matrix->coltitle[x] = char2Chtype (coltitles[x], &matrix->coltitleLen[x], &matrix->coltitlePos[x]);
|
|
matrix->coltitlePos[x] = justifyString (colwidths[x], matrix->coltitleLen[x], matrix->coltitlePos[x]);
|
|
matrix->colwidths[x] = colwidths[x];
|
|
}
|
|
|
|
/* Make room for the cell information. */
|
|
for (x=1; x <= rows; x++)
|
|
{
|
|
for (y=1; y <= cols; y++)
|
|
{
|
|
matrix->info[x][y] = (char *)malloc (sizeof (char) * 256);
|
|
matrix->colvalues[y] = colvalues[y];
|
|
matrix->colwidths[y] = colwidths[y];
|
|
cleanChar (matrix->info[x][y], colwidths[y]+1, '\0');
|
|
}
|
|
}
|
|
|
|
/* Keep the rest of the info. */
|
|
ScreenOf(matrix) = cdkscreen;
|
|
ObjOf(matrix)->box = Box;
|
|
matrix->parent = cdkscreen->window;
|
|
matrix->rows = rows;
|
|
matrix->cols = cols;
|
|
matrix->vrows = vrows;
|
|
matrix->vcols = vcols;
|
|
matrix->boxWidth = boxWidth;
|
|
matrix->boxHeight = boxHeight;
|
|
matrix->rowSpace = rowSpace;
|
|
matrix->colSpace = colSpace;
|
|
matrix->filler = filler;
|
|
matrix->dominant = dominant;
|
|
matrix->row = 1;
|
|
matrix->col = 1;
|
|
matrix->crow = 1;
|
|
matrix->ccol = 1;
|
|
matrix->trow = 1;
|
|
matrix->lcol = 1;
|
|
matrix->oldcrow = 1;
|
|
matrix->oldccol = 1;
|
|
matrix->oldvrow = 1;
|
|
matrix->oldvcol = 1;
|
|
matrix->exitType = vNEVER_ACTIVATED;
|
|
matrix->boxCell = boxCell;
|
|
matrix->shadow = shadow;
|
|
matrix->highlight = A_REVERSE;
|
|
matrix->ULChar = ACS_ULCORNER;
|
|
matrix->URChar = ACS_URCORNER;
|
|
matrix->LLChar = ACS_LLCORNER;
|
|
matrix->LRChar = ACS_LRCORNER;
|
|
matrix->HChar = ACS_HLINE;
|
|
matrix->VChar = ACS_VLINE;
|
|
matrix->BoxAttrib = A_NORMAL;
|
|
matrix->callbackfn = (void *)&CDKMatrixCallBack;
|
|
matrix->preProcessFunction = 0;
|
|
matrix->preProcessData = 0;
|
|
matrix->postProcessFunction = 0;
|
|
matrix->postProcessData = 0;
|
|
|
|
/* Clean the key bindings. */
|
|
cleanCDKObjectBindings (vMATRIX, matrix);
|
|
|
|
/* Register this baby. */
|
|
registerCDKObject (cdkscreen, vMATRIX, matrix);
|
|
|
|
/* Return the matrix pointer */
|
|
return (matrix);
|
|
|
|
death:
|
|
/* Free up any used memory. */
|
|
for (y=1; y <= rows; y++)
|
|
{
|
|
freeChtype (matrix->rowtitle[y]);
|
|
}
|
|
|
|
/* We have to delete any windows created so far. */
|
|
deleteCursesWindow (matrix->win);
|
|
free (matrix);
|
|
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* This activates the matrix.
|
|
*/
|
|
int activateCDKMatrix (CDKMATRIX *matrix, chtype *actions)
|
|
{
|
|
/* Declare local variables. */
|
|
int ret;
|
|
|
|
/* Draw the matrix */
|
|
drawCDKMatrix (matrix, ObjOf(matrix)->box);
|
|
|
|
if (actions == 0)
|
|
{
|
|
chtype input = 0;
|
|
for (;;)
|
|
{
|
|
/* Get the input. */
|
|
wrefresh (matrix->cell[matrix->crow][matrix->ccol]);
|
|
input = wgetch (matrix->cell[matrix->crow][matrix->ccol]);
|
|
|
|
/* Inject the character into the widget. */
|
|
ret = injectCDKMatrix (matrix, input);
|
|
if (matrix->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 = injectCDKMatrix (matrix, actions[x]);
|
|
if (matrix->exitType != vEARLY_EXIT)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Set the exit type and exit. */
|
|
matrix->exitType = vEARLY_EXIT;
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* This injects a single character into the matrix widget.
|
|
*/
|
|
int injectCDKMatrix (CDKMATRIX *matrix, chtype input)
|
|
{
|
|
/* Declare local variables. */
|
|
int refreshCells = FALSE;
|
|
int movedCell = FALSE;
|
|
int charcount = (int)strlen (matrix->info[matrix->row][matrix->col]);
|
|
int ppReturn = 1;
|
|
int x, y, diff;
|
|
|
|
/* Set the exit type. */
|
|
matrix->exitType = vEARLY_EXIT;
|
|
|
|
/* Put the focus on the current cell */
|
|
highlightCDKMatrixCell (matrix);
|
|
|
|
/* Check if there is a pre-process function to be called. */
|
|
if (matrix->preProcessFunction != 0)
|
|
{
|
|
/* Call the pre-process function. */
|
|
ppReturn = ((PROCESSFN)(matrix->preProcessFunction)) (vMATRIX, matrix, matrix->preProcessData, input);
|
|
}
|
|
|
|
/* Should we continue? */
|
|
if (ppReturn != 0)
|
|
{
|
|
/* Check the key bindings. */
|
|
if (checkCDKObjectBind (vMATRIX, matrix, input) != 0)
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
switch (input)
|
|
{
|
|
case CDK_TRANSPOSE :
|
|
break;
|
|
|
|
case CDK_BEGOFLINE :
|
|
break;
|
|
|
|
case CDK_ENDOFLINE :
|
|
break;
|
|
|
|
case KEY_BACKSPACE :
|
|
case DELETE :
|
|
case CONTROL('H') :
|
|
case KEY_DC :
|
|
if (matrix->colvalues[matrix->col] == vVIEWONLY)
|
|
{
|
|
Beep();
|
|
}
|
|
else
|
|
{
|
|
if (charcount > 0)
|
|
{
|
|
charcount--;
|
|
mvwdelch (matrix->cell[matrix->crow][matrix->ccol], 1, charcount+1);
|
|
mvwinsch (matrix->cell[matrix->crow][matrix->ccol], 1, charcount+1, matrix->filler);
|
|
wnoutrefresh (matrix->cell[matrix->crow][matrix->ccol]);
|
|
matrix->info[matrix->row][matrix->col][charcount] = '\0';
|
|
}
|
|
else
|
|
{
|
|
Beep();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_RIGHT :
|
|
case KEY_TAB :
|
|
if (matrix->ccol != matrix->vcols)
|
|
{
|
|
/* We are moving to the right... */
|
|
matrix->col++;
|
|
matrix->ccol++;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* We have to shift the columns to the right. */
|
|
if (matrix->col != matrix->cols)
|
|
{
|
|
matrix->lcol++;
|
|
matrix->col++;
|
|
redrawTitles (matrix, FALSE, TRUE);
|
|
refreshCells = TRUE;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* We are at the far right column, we need */
|
|
/* shift down one row, if we can. */
|
|
if (matrix->row == matrix->rows)
|
|
{
|
|
Beep();
|
|
}
|
|
else
|
|
{
|
|
/* Set up the columns info. */
|
|
matrix->col = 1;
|
|
matrix->lcol = 1;
|
|
matrix->ccol = 1;
|
|
|
|
/* Shift the rows... */
|
|
if (matrix->crow != matrix->vrows)
|
|
{
|
|
matrix->row++;
|
|
matrix->crow++;
|
|
}
|
|
else
|
|
{
|
|
matrix->row++;
|
|
matrix->trow++;
|
|
redrawTitles (matrix, TRUE, TRUE);
|
|
refreshCells = TRUE;
|
|
}
|
|
movedCell = TRUE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_LEFT :
|
|
if (matrix->ccol != 1)
|
|
{
|
|
/* We are moving to the left... */
|
|
matrix->col--;
|
|
matrix->ccol--;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* Are we at the far left??? */
|
|
if (matrix->lcol != 1)
|
|
{
|
|
matrix->lcol--;
|
|
matrix->col--;
|
|
redrawTitles (matrix, FALSE, TRUE);
|
|
refreshCells = TRUE;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* Shift up one line if we can... */
|
|
if (matrix->row == 1)
|
|
{
|
|
Beep();
|
|
}
|
|
else
|
|
{
|
|
/* Set up the columns info. */
|
|
matrix->col = matrix->cols;
|
|
matrix->lcol = matrix->cols - matrix->vcols + 1;
|
|
matrix->ccol = matrix->vcols;
|
|
|
|
/* Shift the rows... */
|
|
if (matrix->crow != 1)
|
|
{
|
|
matrix->row--;
|
|
matrix->crow--;
|
|
}
|
|
else
|
|
{
|
|
matrix->row--;
|
|
matrix->trow--;
|
|
redrawTitles (matrix, TRUE, TRUE);
|
|
refreshCells = TRUE;
|
|
}
|
|
movedCell = TRUE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_UP :
|
|
if (matrix->crow != 1)
|
|
{
|
|
matrix->row--;
|
|
matrix->crow--;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
diff = matrix->trow - 1;
|
|
if (diff > 0)
|
|
{
|
|
matrix->trow--;
|
|
matrix->row--;
|
|
redrawTitles (matrix, TRUE, FALSE);
|
|
refreshCells = TRUE;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
Beep();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_DOWN :
|
|
if (matrix->crow != matrix->vrows)
|
|
{
|
|
matrix->row++;
|
|
matrix->crow++;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
diff = matrix->rows - (matrix->trow + matrix->vrows - 1);
|
|
if (diff > 0)
|
|
{
|
|
matrix->trow++;
|
|
matrix->row++;
|
|
redrawTitles (matrix, TRUE, FALSE);
|
|
refreshCells = TRUE;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
Beep();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_NPAGE :
|
|
case CONTROL('F') :
|
|
if (matrix->row < matrix->rows)
|
|
{
|
|
diff = matrix->rows - (matrix->trow + matrix->vrows - 1);
|
|
if (diff > 0)
|
|
{
|
|
matrix->trow += MINIMUM (diff, matrix->vrows - 1);
|
|
redrawTitles (matrix, TRUE, FALSE);
|
|
refreshCells = TRUE;
|
|
}
|
|
matrix->row = MINIMUM (matrix->row + matrix->vrows - 1,
|
|
matrix->rows);
|
|
matrix->crow = matrix->row - matrix->trow + 1;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
Beep();
|
|
}
|
|
break;
|
|
|
|
case KEY_PPAGE :
|
|
case CONTROL('B') :
|
|
if (matrix->row > 1)
|
|
{
|
|
diff = matrix->trow - 1;
|
|
if (diff > 0)
|
|
{
|
|
matrix->trow -= MINIMUM (diff, matrix->vrows - 1);
|
|
redrawTitles (matrix, TRUE, FALSE);
|
|
refreshCells = TRUE;
|
|
}
|
|
matrix->row = MAXIMUM (matrix->row - matrix->vrows + 1,
|
|
1);
|
|
matrix->crow = matrix->row - matrix->trow + 1;
|
|
movedCell = TRUE;
|
|
}
|
|
else
|
|
{
|
|
Beep();
|
|
}
|
|
break;
|
|
|
|
case CONTROL('G') :
|
|
jumpToCell (matrix, -1, -1);
|
|
drawCDKMatrix (matrix, ObjOf(matrix)->box);
|
|
break;
|
|
|
|
case CDK_PASTE :
|
|
if (GPasteBuffer == 0 || (int)strlen (GPasteBuffer) > matrix->colwidths[matrix->ccol])
|
|
{
|
|
Beep();
|
|
}
|
|
else
|
|
{
|
|
strcpy (matrix->info[matrix->trow+matrix->crow-1][matrix->lcol+matrix->ccol-1], GPasteBuffer);
|
|
drawCDKMatrixCell (matrix, matrix->crow, matrix->ccol, matrix->row, matrix->col, A_NORMAL, matrix->boxCell);
|
|
}
|
|
break;
|
|
|
|
case CDK_COPY :
|
|
freeChar (GPasteBuffer);
|
|
GPasteBuffer = copyChar (matrix->info[matrix->trow+matrix->crow-1][matrix->lcol+matrix->ccol-1]);
|
|
break;
|
|
|
|
case CDK_CUT :
|
|
freeChar (GPasteBuffer);
|
|
GPasteBuffer = copyChar (matrix->info[matrix->trow+matrix->crow-1][matrix->lcol+matrix->ccol-1]);
|
|
cleanChar (matrix->info[matrix->trow+matrix->crow-1][matrix->lcol+matrix->ccol-1], matrix->colwidths[matrix->lcol+matrix->ccol-1], '\0');
|
|
drawCDKMatrixCell (matrix, matrix->crow, matrix->ccol, matrix->row, matrix->col, A_NORMAL, matrix->boxCell);
|
|
break;
|
|
|
|
case CDK_ERASE :
|
|
cleanChar (matrix->info[matrix->trow+matrix->crow-1][matrix->lcol+matrix->ccol-1], matrix->colwidths[matrix->lcol+matrix->ccol-1], '\0');
|
|
drawCDKMatrixCell (matrix, matrix->crow, matrix->ccol, matrix->row, matrix->col, A_NORMAL, matrix->boxCell);
|
|
break;
|
|
|
|
case KEY_RETURN :
|
|
case KEY_ENTER :
|
|
case KEY_CR :
|
|
drawCDKMatrixCell (matrix,
|
|
matrix->oldcrow,
|
|
matrix->oldccol,
|
|
matrix->oldvrow,
|
|
matrix->oldvcol,
|
|
A_NORMAL,
|
|
matrix->boxCell);
|
|
wrefresh (matrix->cell[matrix->crow][matrix->ccol]);
|
|
matrix->exitType = vNORMAL;
|
|
return 0;
|
|
|
|
case KEY_ESC :
|
|
drawCDKMatrixCell (matrix,
|
|
matrix->oldcrow,
|
|
matrix->oldccol,
|
|
matrix->oldvrow,
|
|
matrix->oldvcol,
|
|
A_NORMAL,
|
|
matrix->boxCell);
|
|
wrefresh (matrix->cell[matrix->crow][matrix->ccol]);
|
|
matrix->exitType = vESCAPE_HIT;
|
|
return -1;
|
|
|
|
case CDK_REFRESH :
|
|
eraseCDKScreen (ScreenOf(matrix));
|
|
refreshCDKScreen (ScreenOf(matrix));
|
|
break;
|
|
|
|
default :
|
|
((MATRIXCB)matrix->callbackfn)(matrix, input);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Did we change cells? */
|
|
if (movedCell && !refreshCells)
|
|
{
|
|
/* un-highlight the old box */
|
|
drawCDKMatrixCell (matrix,
|
|
matrix->oldcrow,
|
|
matrix->oldccol,
|
|
matrix->oldvrow,
|
|
matrix->oldvcol,
|
|
0,
|
|
matrix->boxCell);
|
|
}
|
|
|
|
/* Redraw each cell. */
|
|
if (refreshCells)
|
|
{
|
|
/* Fill in the cells. */
|
|
for (x=0; x < matrix->vrows; x++)
|
|
{
|
|
for (y=0; y < matrix->vcols; y++)
|
|
{
|
|
drawCDKMatrixCell (matrix, x+1, y+1,
|
|
matrix->trow + x,
|
|
matrix->lcol + y,
|
|
A_NORMAL,
|
|
matrix->boxCell);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Move to the correct position in the cell. */
|
|
if (refreshCells || movedCell)
|
|
{
|
|
/* Highlight the new cell. */
|
|
highlightCDKMatrixCell (matrix);
|
|
}
|
|
|
|
wnoutrefresh (matrix->win);
|
|
|
|
/* Should we call a post-process? */
|
|
if (matrix->postProcessFunction != 0)
|
|
{
|
|
((PROCESSFN)(matrix->postProcessFunction)) (vMATRIX, matrix, matrix->postProcessData, input);
|
|
}
|
|
}
|
|
|
|
/* Set the variables we need. */
|
|
matrix->oldcrow = matrix->crow;
|
|
matrix->oldccol = matrix->ccol;
|
|
matrix->oldvrow = matrix->row;
|
|
matrix->oldvcol = matrix->col;
|
|
|
|
/* Set the exit type and exit. */
|
|
matrix->exitType = vEARLY_EXIT;
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* This allows the programmer to define their own key mappings.
|
|
*/
|
|
static void CDKMatrixCallBack (CDKMATRIX *matrix, chtype input)
|
|
{
|
|
/* Declare local variables. */
|
|
EDisplayType disptype = (EDisplayType)matrix->colvalues[matrix->col];
|
|
int charcount = (int)strlen (matrix->info[matrix->row][matrix->col]);
|
|
chtype newchar = 0;
|
|
|
|
/* Check the types */
|
|
if (disptype == vINT && !isdigit((int)input))
|
|
{
|
|
Beep();
|
|
}
|
|
else if ((disptype == vCHAR || disptype == vUCHAR ||
|
|
disptype == vLCHAR || disptype == vUHCHAR ||
|
|
disptype == vLHCHAR) && isdigit((int)input))
|
|
{
|
|
Beep();
|
|
}
|
|
else if (disptype == vVIEWONLY)
|
|
{
|
|
Beep();
|
|
}
|
|
else
|
|
{
|
|
/* Check the width of the string. */
|
|
if (charcount == matrix->colwidths[matrix->col])
|
|
{
|
|
Beep();
|
|
}
|
|
else
|
|
{
|
|
/* We will make any needed adjustments to the case of the character. */
|
|
newchar = input;
|
|
if ((disptype == vUCHAR || disptype == vUCHAR ||
|
|
disptype == vUMIXED || disptype == vUHMIXED)
|
|
&& !isdigit((int)input))
|
|
{
|
|
newchar = toupper(input);
|
|
}
|
|
else if ((disptype == vUCHAR || disptype == vUCHAR ||
|
|
disptype == vUMIXED || disptype == vUHMIXED) &&
|
|
!isdigit((int)input))
|
|
{
|
|
newchar = tolower(input);
|
|
}
|
|
|
|
/* Update the screen. */
|
|
wmove (matrix->cell[matrix->crow][matrix->ccol], 1, (int)strlen (matrix->info[matrix->row][matrix->col])+1);
|
|
waddch (matrix->cell[matrix->crow][matrix->ccol], newchar);
|
|
wrefresh (matrix->cell[matrix->crow][matrix->ccol]);
|
|
|
|
/* Update the character pointer. */
|
|
matrix->info[matrix->row][matrix->col][charcount++] = newchar;
|
|
matrix->info[matrix->row][matrix->col][charcount] = '\0';
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Highlight the new field.
|
|
*/
|
|
static void highlightCDKMatrixCell (CDKMATRIX *matrix)
|
|
{
|
|
WINDOW *cell;
|
|
|
|
drawCDKMatrixCell (matrix, matrix->crow, matrix->ccol, matrix->row,
|
|
matrix->col, A_BOLD, TRUE);
|
|
|
|
/* Move the cursor to the correct position within the cell. */
|
|
cell = matrix->cell[matrix->crow][matrix->ccol];
|
|
if (matrix->colwidths[matrix->ccol] == 1)
|
|
{
|
|
wmove (cell, 1, 1);
|
|
}
|
|
else
|
|
{
|
|
wmove (cell, 1, (int)strlen (matrix->info[matrix->row][matrix->col])+1);
|
|
}
|
|
wnoutrefresh (cell);
|
|
}
|
|
|
|
/*
|
|
* This moves the matrix field to the given location.
|
|
*/
|
|
static void _moveCDKMatrix (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
|
|
{
|
|
CDKMATRIX *matrix = (CDKMATRIX *)object;
|
|
|
|
/*
|
|
* If this is a relative move, then we will adjust where we want
|
|
* to move to.
|
|
*/
|
|
if (relative)
|
|
{
|
|
xplace += getbegx(matrix->win);
|
|
yplace += getbegy(matrix->win);
|
|
}
|
|
|
|
/* Adjust the window if we need to. */
|
|
alignxy (WindowOf(matrix), &xplace, &yplace, matrix->boxWidth, matrix->boxHeight);
|
|
|
|
/* Move the window to the new location. */
|
|
moveCursesWindow(matrix->win, xplace, yplace);
|
|
|
|
/* Redraw the window, if they asked for it. */
|
|
if (refresh_flag)
|
|
{
|
|
drawCDKMatrix (matrix, ObjOf(matrix)->box);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This draws a cell within a matrix.
|
|
*/
|
|
static void drawCDKMatrixCell (CDKMATRIX *matrix, int row, int col, int vrow, int vcol, chtype attr, boolean Box)
|
|
{
|
|
/* Declare local variables. */
|
|
WINDOW *cell = matrix->cell[row][col];
|
|
chtype highlight;
|
|
int rows = matrix->vrows;
|
|
int cols = matrix->vcols;
|
|
int infolen = (int)strlen (matrix->info[vrow][vcol]);
|
|
|
|
/*
|
|
* Given the dominance of the colors/attributes, we need to set the
|
|
* current cell attribute.
|
|
*/
|
|
if (matrix->dominant == ROW)
|
|
{
|
|
highlight = matrix->rowtitle[row][0] & A_ATTRIBUTES;
|
|
}
|
|
else if (matrix->dominant == COL)
|
|
{
|
|
highlight = matrix->coltitle[col][0] & A_ATTRIBUTES;
|
|
}
|
|
else if (vrow == matrix->row && vcol == matrix->col)
|
|
{
|
|
highlight = matrix->highlight;
|
|
}
|
|
else
|
|
{
|
|
highlight = matrix->filler & A_ATTRIBUTES;
|
|
}
|
|
|
|
/* Draw in the cell info. */
|
|
mvwhline (cell, 1, 1,
|
|
matrix->filler | highlight, matrix->colwidths[col]);
|
|
writeCharAttrib (cell, 1, 1,
|
|
matrix->info[vrow][vcol], highlight, HORIZONTAL,
|
|
0, MINIMUM (matrix->colwidths[col], infolen));
|
|
wmove (cell, 1, infolen + 1);
|
|
|
|
/* Always box the current cell. */
|
|
if (vrow == matrix->row && vcol == matrix->col)
|
|
{
|
|
boxWindow (cell, A_BOLD);
|
|
}
|
|
/* If there is no box, draw blanks around the cell. */
|
|
else if (!Box)
|
|
{
|
|
attrbox (cell, ' ', ' ', ' ', ' ', ' ', ' ', A_NORMAL, FALSE);
|
|
}
|
|
/*
|
|
* If the value of the column spacing is greater than 0 then these
|
|
* are independent boxes.
|
|
*/
|
|
else if (matrix->colSpace != 0 && matrix->rowSpace != 0)
|
|
{
|
|
boxWindow (cell, attr);
|
|
}
|
|
else if (matrix->colSpace != 0 && matrix->rowSpace == 0)
|
|
{
|
|
if (row == 1)
|
|
{
|
|
attrbox (cell, ACS_ULCORNER, ACS_URCORNER,
|
|
ACS_LTEE, ACS_RTEE,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (row > 1 && row < rows)
|
|
{
|
|
attrbox (cell, ACS_LTEE, ACS_RTEE,
|
|
ACS_LTEE, ACS_RTEE,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (row == rows)
|
|
{
|
|
attrbox (cell, ACS_LTEE, ACS_RTEE,
|
|
ACS_LLCORNER, ACS_LRCORNER,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
}
|
|
else if (matrix->colSpace == 0 && matrix->rowSpace != 0)
|
|
{
|
|
if (col == 1)
|
|
{
|
|
attrbox (cell, ACS_ULCORNER, ACS_TTEE,
|
|
ACS_LLCORNER, ACS_BTEE,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (col > 1 && col < cols)
|
|
{
|
|
attrbox (cell, ACS_TTEE, ACS_TTEE,
|
|
ACS_BTEE, ACS_BTEE,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (col == cols)
|
|
{
|
|
attrbox (cell, ACS_TTEE, ACS_URCORNER,
|
|
ACS_BTEE, ACS_LRCORNER,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
}
|
|
/* Start drawing the matrix. */
|
|
else if (row == 1)
|
|
{
|
|
if (col == 1)
|
|
{
|
|
/* Draw the top left corner */
|
|
attrbox (cell, ACS_ULCORNER, ACS_TTEE,
|
|
ACS_LTEE, ACS_PLUS,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (col > 1 && col < cols)
|
|
{
|
|
/* Draw the top middle box */
|
|
attrbox (cell, ACS_TTEE, ACS_TTEE,
|
|
ACS_PLUS, ACS_PLUS,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (col == cols)
|
|
{
|
|
/* Draw the top right corner */
|
|
attrbox (cell, ACS_TTEE, ACS_URCORNER,
|
|
ACS_PLUS, ACS_RTEE,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
}
|
|
else if (row > 1 && row < rows)
|
|
{
|
|
if (col == 1)
|
|
{
|
|
/* Draw the middle left box */
|
|
attrbox (cell, ACS_LTEE, ACS_PLUS,
|
|
ACS_LTEE, ACS_PLUS,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (col > 1 && col < cols)
|
|
{
|
|
/* Draw the middle box */
|
|
attrbox (cell, ACS_PLUS, ACS_PLUS,
|
|
ACS_PLUS, ACS_PLUS,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (col == cols)
|
|
{
|
|
/* Draw the middle right box */
|
|
attrbox (cell, ACS_PLUS, ACS_RTEE,
|
|
ACS_PLUS, ACS_RTEE,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
}
|
|
else if (row == rows)
|
|
{
|
|
if (col == 1)
|
|
{
|
|
/* Draw the bottom left corner */
|
|
attrbox (cell, ACS_LTEE, ACS_PLUS,
|
|
ACS_LLCORNER, ACS_BTEE,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (col > 1 && col < cols)
|
|
{
|
|
/* Draw the bottom middle box */
|
|
attrbox (cell, ACS_PLUS, ACS_PLUS,
|
|
ACS_BTEE, ACS_BTEE,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
else if (col == cols)
|
|
{
|
|
/* Draw the bottom right corner */
|
|
attrbox (cell, ACS_PLUS, ACS_RTEE,
|
|
ACS_BTEE, ACS_LRCORNER,
|
|
ACS_HLINE, ACS_VLINE,
|
|
attr, FALSE);
|
|
}
|
|
}
|
|
|
|
wnoutrefresh (cell);
|
|
}
|
|
|
|
/*
|
|
* This function draws the matrix widget.
|
|
*/
|
|
static void _drawCDKMatrix (CDKOBJS *object, boolean Box)
|
|
{
|
|
CDKMATRIX *matrix = (CDKMATRIX *)object;
|
|
int x, y;
|
|
|
|
/* Should we box the matrix??? */
|
|
if (Box)
|
|
{
|
|
attrbox (matrix->win,
|
|
matrix->ULChar, matrix->URChar,
|
|
matrix->LLChar, matrix->LRChar,
|
|
matrix->HChar, matrix->VChar,
|
|
matrix->BoxAttrib,
|
|
matrix->shadow);
|
|
}
|
|
|
|
/* Draw in the title. */
|
|
for (x=0; x < matrix->titleLines; x++)
|
|
{
|
|
writeChtype (matrix->win,
|
|
matrix->titlePos[x],
|
|
x + 1,
|
|
matrix->title[x],
|
|
HORIZONTAL, 0,
|
|
matrix->titleLen[x]);
|
|
}
|
|
|
|
redrawTitles (matrix, TRUE, TRUE);
|
|
|
|
/* Draw in the cells.. */
|
|
for (x=0; x < matrix->vrows; x++)
|
|
{
|
|
for (y=0; y < matrix->vcols; y++)
|
|
{
|
|
drawCDKMatrixCell (matrix, x+1, y+1,
|
|
matrix->trow + x,
|
|
matrix->lcol + y,
|
|
A_NORMAL,
|
|
matrix->boxCell);
|
|
}
|
|
}
|
|
|
|
/* Highlight the new cell. */
|
|
highlightCDKMatrixCell (matrix);
|
|
|
|
/* Redraw the window. */
|
|
wnoutrefresh (matrix->win);
|
|
}
|
|
|
|
/*
|
|
* This function destroys the matrix widget.
|
|
*/
|
|
void destroyCDKMatrix (CDKMATRIX *matrix)
|
|
{
|
|
/* Declare local variables. */
|
|
int x = 0;
|
|
int y = 0;
|
|
|
|
/* Erase the object. */
|
|
eraseCDKMatrix (matrix);
|
|
|
|
/* Clear out the title. */
|
|
for (x=0; x < matrix->titleLines; x++)
|
|
{
|
|
freeChtype (matrix->title[x]);
|
|
}
|
|
|
|
/* Clear out the col titles. */
|
|
for (x=1; x <= matrix->cols; x++)
|
|
{
|
|
freeChtype (matrix->coltitle[x]);
|
|
}
|
|
|
|
/* Clear out the row titles. */
|
|
for (x=1; x <= matrix->rows; x++)
|
|
{
|
|
freeChtype (matrix->rowtitle[x]);
|
|
}
|
|
|
|
/* Clear out the matrix cells. */
|
|
for (x=1; x <= matrix->rows; x++)
|
|
{
|
|
for (y=1; y <= matrix->cols; y++)
|
|
{
|
|
freeChar (matrix->info[x][y]);
|
|
}
|
|
}
|
|
|
|
/* Clear the matrix windows. */
|
|
deleteCursesWindow (matrix->win);
|
|
|
|
/* Unregister this object. */
|
|
unregisterCDKObject (vMATRIX, matrix);
|
|
|
|
/* Finish cleaning up. */
|
|
free (matrix);
|
|
}
|
|
|
|
/*
|
|
* This function erases the matrix widget from the screen.
|
|
*/
|
|
static void _eraseCDKMatrix (CDKOBJS *object)
|
|
{
|
|
CDKMATRIX *matrix = (CDKMATRIX *)object;
|
|
|
|
eraseCursesWindow (matrix->win);
|
|
}
|
|
|
|
/*
|
|
* This function sets the values of the matrix widget.
|
|
*/
|
|
void setCDKMatrix (CDKMATRIX *matrix, char *info[MAX_MATRIX_ROWS][MAX_MATRIX_COLS], int rows, int *subSize)
|
|
{
|
|
/* Declare local variables. */
|
|
int x = 0;
|
|
int y = 0;
|
|
|
|
/* Clear out all the cells. */
|
|
for (x=1; x <= matrix->rows; x++)
|
|
{
|
|
for (y=1; y <= matrix->cols; y++)
|
|
{
|
|
/* Clean the old info, and copy in the new. */
|
|
if (matrix->info[x][y] != 0)
|
|
{
|
|
/* Clean the cell information. */
|
|
cleanChar (matrix->info[x][y], matrix->colwidths[y], '\0');
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Copy in the new info. */
|
|
for (x=1; x <= rows; x++)
|
|
{
|
|
for (y=1; y <= subSize[x]; y++)
|
|
{
|
|
/* Copy in the new information. */
|
|
if (info[x][y] != 0)
|
|
{
|
|
strncpy (matrix->info[x][y], info[x][y], matrix->colwidths[y]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This cleans out the information cells in the matrix widget.
|
|
*/
|
|
void cleanCDKMatrix (CDKMATRIX *matrix)
|
|
{
|
|
/* Declare local variables. */
|
|
int x = 0;
|
|
int y = 0;
|
|
|
|
for (x=1; x <= matrix->rows; x++)
|
|
{
|
|
for (y=1; y <= matrix->cols; y++)
|
|
{
|
|
cleanChar (matrix->info[x][y], matrix->colwidths[y], '\0');
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This allows us to hyper-warp to a cell.
|
|
*/
|
|
int jumpToCell (CDKMATRIX *matrix, int row, int col)
|
|
{
|
|
/* Declare local variables. */
|
|
CDKSCALE *scale = 0;
|
|
int newRow = row;
|
|
int newCol = col;
|
|
|
|
/*
|
|
* Only create the row scale if needed.
|
|
*/
|
|
if ((row == -1) || (row > matrix->rows))
|
|
{
|
|
/* Create the row scale widget. */
|
|
scale = newCDKScale (ScreenOf(matrix),
|
|
CENTER, CENTER,
|
|
"<C>Jump to which row.",
|
|
"</5/B>Row: ", A_NORMAL, 5,
|
|
1, 1, matrix->rows, 1, 1, TRUE, FALSE);
|
|
|
|
/* Activate the scale and get the row. */
|
|
newRow = activateCDKScale (scale, 0);
|
|
destroyCDKScale (scale);
|
|
}
|
|
|
|
/*
|
|
* Only create the column scale if needed.
|
|
*/
|
|
if ((col == -1) || (col > matrix->cols))
|
|
{
|
|
/* Create the column scale widget. */
|
|
scale = newCDKScale (ScreenOf(matrix),
|
|
CENTER, CENTER,
|
|
"<C>Jump to which column",
|
|
"</5/B>Col: ", A_NORMAL, 5,
|
|
1, 1, matrix->cols, 1, 1, TRUE, FALSE);
|
|
|
|
/* Activate the scale and get the column. */
|
|
newCol = activateCDKScale (scale, 0);
|
|
destroyCDKScale (scale);
|
|
}
|
|
|
|
/* Hyper-warp.... */
|
|
if (newRow != matrix->row || newCol != matrix->col)
|
|
{
|
|
return (moveToCDKMatrixCell (matrix, newRow, newCol));
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This allows us to move to a given cell.
|
|
*/
|
|
int moveToCDKMatrixCell (CDKMATRIX *matrix, int newrow, int newcol)
|
|
{
|
|
/* Declare local variables. */
|
|
int rowShift = newrow - matrix->row;
|
|
int colShift = newcol - matrix->col;
|
|
|
|
/* Make sure we arent asking to move out of the matrix. */
|
|
if (newrow > matrix->rows || newcol > matrix->cols || newrow <= 0 || newcol <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* Did we move up/down???? */
|
|
if (rowShift > 0)
|
|
{
|
|
/* We are moving down. */
|
|
if (matrix->vrows == matrix->cols)
|
|
{
|
|
matrix->trow = 1;
|
|
matrix->crow = newrow;
|
|
matrix->row = newrow;
|
|
}
|
|
else
|
|
{
|
|
if ((rowShift + matrix->vrows) < matrix->rows)
|
|
{
|
|
/* Just shift down by rowShift... */
|
|
matrix->trow += rowShift;
|
|
matrix->crow = 1;
|
|
matrix->row += rowShift;
|
|
}
|
|
else
|
|
{
|
|
/* We need to munge with the values... */
|
|
matrix->trow = matrix->rows - matrix->vrows + 1;
|
|
matrix->crow = ((rowShift + matrix->vrows) - matrix->rows) + 1;
|
|
matrix->row = newrow;
|
|
}
|
|
}
|
|
}
|
|
else if (rowShift < 0)
|
|
{
|
|
/* We are moving up. */
|
|
if (matrix->vrows == matrix->rows)
|
|
{
|
|
matrix->trow = 1;
|
|
matrix->row = newrow;
|
|
matrix->crow = newrow;
|
|
}
|
|
else
|
|
{
|
|
if ((rowShift + matrix->vrows) > 1)
|
|
{
|
|
/* Just shift up by rowShift... */
|
|
matrix->trow += rowShift;
|
|
matrix->row += rowShift;
|
|
matrix->crow = 1;
|
|
}
|
|
else
|
|
{
|
|
/* We need to munge with the values... */
|
|
matrix->trow = 1;
|
|
matrix->crow = 1;
|
|
matrix->row = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Did we move left/right ???? */
|
|
if (colShift > 0)
|
|
{
|
|
/* We are moving right. */
|
|
if (matrix->vcols == matrix->cols)
|
|
{
|
|
matrix->lcol = 1;
|
|
matrix->ccol = newcol;
|
|
matrix->col = newcol;
|
|
}
|
|
else
|
|
{
|
|
if ((colShift + matrix->vcols) < matrix->cols)
|
|
{
|
|
matrix->lcol += colShift;
|
|
matrix->ccol = 1;
|
|
matrix->col += colShift;
|
|
}
|
|
else
|
|
{
|
|
/* We need to munge with the values... */
|
|
matrix->lcol = matrix->cols - matrix->vcols + 1;
|
|
matrix->ccol = ((colShift + matrix->vcols) - matrix->cols) + 1;
|
|
matrix->col = newcol;
|
|
}
|
|
}
|
|
}
|
|
else if (colShift < 0)
|
|
{
|
|
/* We are moving left. */
|
|
if (matrix->vcols == matrix->cols)
|
|
{
|
|
matrix->lcol = 1;
|
|
matrix->col = newcol;
|
|
matrix->ccol = newcol;
|
|
}
|
|
else
|
|
{
|
|
if ((colShift + matrix->vcols) > 1)
|
|
{
|
|
/* Just shift left by colShift... */
|
|
matrix->lcol += colShift;
|
|
matrix->col += colShift;
|
|
matrix->ccol = 1;
|
|
}
|
|
else
|
|
{
|
|
matrix->lcol = 1;
|
|
matrix->col = 1;
|
|
matrix->ccol = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Keep the 'old' values around for redrawing sake. */
|
|
matrix->oldcrow = matrix->crow;
|
|
matrix->oldccol = matrix->ccol;
|
|
matrix->oldvrow = matrix->row;
|
|
matrix->oldvcol = matrix->col;
|
|
|
|
/* Lets ... */
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* This redraws the titles indicated...
|
|
*/
|
|
static void redrawTitles (CDKMATRIX *matrix, int rowTitles, int colTitles)
|
|
{
|
|
/* Declare local variables. */
|
|
int x;
|
|
WINDOW *cell;
|
|
|
|
/* Redraw the row titles. */
|
|
if (rowTitles)
|
|
{
|
|
for (x=0; x < matrix->vrows; x++)
|
|
{
|
|
cell = matrix->cell[x+1][0];
|
|
werase (cell);
|
|
writeChtype (cell,
|
|
matrix->rowtitlePos[matrix->trow + x], 1,
|
|
matrix->rowtitle[matrix->trow + x],
|
|
HORIZONTAL,
|
|
0, matrix->rowtitleLen[matrix->trow + x]);
|
|
wnoutrefresh (cell);
|
|
}
|
|
}
|
|
|
|
/* Redraw the column titles. */
|
|
if (colTitles)
|
|
{
|
|
for (x=0; x < matrix->vcols; x++)
|
|
{
|
|
cell = matrix->cell[0][x+1];
|
|
werase (cell);
|
|
writeChtype (cell,
|
|
matrix->coltitlePos[matrix->lcol + x], 0,
|
|
matrix->coltitle[matrix->lcol + x],
|
|
HORIZONTAL,
|
|
0, matrix->coltitleLen[matrix->lcol + x]);
|
|
wnoutrefresh (cell);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This sets the value of a matrix cell.
|
|
*/
|
|
int setCDKMatrixCell (CDKMATRIX *matrix, int row, int col, char *value)
|
|
{
|
|
/* Make sure the row/col combination is within the matrix. */
|
|
if (row > matrix->rows || col > matrix->cols || row <= 0 || col <= 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
/* Clean out the old value. */
|
|
cleanChar (matrix->info[row][col], matrix->colwidths[col]+1, '\0');
|
|
|
|
/* Copy the new version in and return. */
|
|
strncpy (matrix->info[row][col], value, matrix->colwidths[col]);
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* This gets the value of a matrix cell.
|
|
*/
|
|
char *getCDKMatrixCell (CDKMATRIX *matrix, int row, int col)
|
|
{
|
|
/* Make sure the row/col combination is within the matrix. */
|
|
if (row > matrix->rows || col > matrix->cols || row <= 0 || col <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
return matrix->info[row][col];
|
|
}
|
|
|
|
/*
|
|
* This returns the current row/col cell.
|
|
*/
|
|
int getCDKMatrixCol (CDKMATRIX *matrix)
|
|
{
|
|
return matrix->col;
|
|
}
|
|
int getCDKMatrixRow (CDKMATRIX *matrix)
|
|
{
|
|
return matrix->row;
|
|
}
|
|
|
|
/*
|
|
* These functions set the drawing characters of the widget.
|
|
*/
|
|
void setCDKMatrixULChar (CDKMATRIX *matrix, chtype character)
|
|
{
|
|
matrix->ULChar = character;
|
|
}
|
|
void setCDKMatrixURChar (CDKMATRIX *matrix, chtype character)
|
|
{
|
|
matrix->URChar = character;
|
|
}
|
|
void setCDKMatrixLLChar (CDKMATRIX *matrix, chtype character)
|
|
{
|
|
matrix->LLChar = character;
|
|
}
|
|
void setCDKMatrixLRChar (CDKMATRIX *matrix, chtype character)
|
|
{
|
|
matrix->LRChar = character;
|
|
}
|
|
void setCDKMatrixVerticalChar (CDKMATRIX *matrix, chtype character)
|
|
{
|
|
matrix->VChar = character;
|
|
}
|
|
void setCDKMatrixHorizontalChar (CDKMATRIX *matrix, chtype character)
|
|
{
|
|
matrix->HChar = character;
|
|
}
|
|
void setCDKMatrixBoxAttribute (CDKMATRIX *matrix, chtype character)
|
|
{
|
|
matrix->BoxAttrib = character;
|
|
}
|
|
|
|
/*
|
|
* This sets the background color of the widget.
|
|
*/
|
|
void setCDKMatrixBackgroundColor (CDKMATRIX *matrix, char *color)
|
|
{
|
|
chtype *holder = 0;
|
|
int x, y, junk1, junk2;
|
|
|
|
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 (matrix->win, holder[0]);
|
|
for (x=0; x <= matrix->vrows; x++)
|
|
{
|
|
for (y=0; y <= matrix->vcols; y++)
|
|
{
|
|
wbkgd (matrix->cell[x][y], holder[0]);
|
|
}
|
|
}
|
|
|
|
/* Clean up. */
|
|
freeChtype (holder);
|
|
}
|
|
|
|
/*
|
|
* This function sets the pre-process function.
|
|
*/
|
|
void setCDKMatrixPreProcess (CDKMATRIX *matrix, PROCESSFN callback, void *data)
|
|
{
|
|
matrix->preProcessFunction = callback;
|
|
matrix->preProcessData = data;
|
|
}
|
|
|
|
/*
|
|
* This function sets the post-process function.
|
|
*/
|
|
void setCDKMatrixPostProcess (CDKMATRIX *matrix, PROCESSFN callback, void *data)
|
|
{
|
|
matrix->postProcessFunction = callback;
|
|
matrix->postProcessData = data;
|
|
}
|