1 #include <cdk_int.h>
2
3 /*
4 * $Author: tom $
5 * $Date: 2016/12/10 15:18:01 $
6 * $Revision: 1.198 $
7 */
8
9 /*
10 * Declare file local prototypes.
11 */
12 static void highlightCDKMatrixCell (CDKMATRIX *matrix);
13 static void CDKMatrixCallBack (CDKMATRIX *matrix, chtype input);
14 static void drawCDKMatrixCell (CDKMATRIX *matrix,
15 int srow, int scol,
16 int vrow, int vcol,
17 boolean Box);
18 static void drawCurCDKMatrixCell (CDKMATRIX *matrix);
19 static void drawEachCDKMatrixCell (CDKMATRIX *matrix);
20 static void drawEachColTitle (CDKMATRIX *matrix);
21 static void drawEachRowTitle (CDKMATRIX *matrix);
22 static void drawOldCDKMatrixCell (CDKMATRIX *matrix);
23 static void redrawTitles (CDKMATRIX *matrix, int row, int col);
24
25 #define emptyString(s) ((s) == 0 || *(s) == '\0')
26
27 #define CurMatrixCell(matrix) \
28 MATRIX_CELL (matrix, matrix->crow, matrix->ccol)
29
30 #define CurMatrixInfo(matrix) \
31 MATRIX_INFO (matrix, \
32 matrix->trow + matrix->crow - 1, \
33 matrix->lcol + matrix->ccol - 1)
34
35 DeclareCDKObjects (MATRIX, Matrix, setCdk, Int);
36
37 #define WHOLE_BOX ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER
38
39 #define TOP_C_BOX ACS_ULCORNER, ACS_URCORNER, ACS_LTEE, ACS_RTEE
40 #define MID_C_BOX ACS_LTEE, ACS_RTEE, ACS_LTEE, ACS_RTEE
41 #define BOT_C_BOX ACS_LTEE, ACS_RTEE, ACS_LLCORNER, ACS_LRCORNER
42
43 #define LFT_R_BOX ACS_ULCORNER, ACS_TTEE, ACS_LLCORNER, ACS_BTEE
44 #define MID_R_BOX ACS_TTEE, ACS_TTEE, ACS_BTEE, ACS_BTEE
45 #define RGT_R_BOX ACS_TTEE, ACS_URCORNER, ACS_BTEE, ACS_LRCORNER
46
47 #define LFT_T_BOX ACS_ULCORNER, ACS_TTEE, ACS_LTEE, ACS_PLUS
48 #define MID_T_BOX ACS_TTEE, ACS_TTEE, ACS_PLUS, ACS_PLUS
49 #define RGT_T_BOX ACS_TTEE, ACS_URCORNER, ACS_PLUS, ACS_RTEE
50
51 #define LFT_M_BOX ACS_LTEE, ACS_PLUS, ACS_LTEE, ACS_PLUS
52 #define MID_M_BOX ACS_PLUS, ACS_PLUS, ACS_PLUS, ACS_PLUS
53 #define RGT_M_BOX ACS_PLUS, ACS_RTEE, ACS_PLUS, ACS_RTEE
54
55 #define LFT_B_BOX ACS_LTEE, ACS_PLUS, ACS_LLCORNER, ACS_BTEE
56 #define MID_B_BOX ACS_PLUS, ACS_PLUS, ACS_BTEE, ACS_BTEE
57 #define RGT_B_BOX ACS_PLUS, ACS_RTEE, ACS_BTEE, ACS_LRCORNER
58
59 #define MyBox(cell,what,attr) attrbox(cell, what, ACS_HLINE, ACS_VLINE, attr)
60
61 /*
62 * This function creates the matrix widget.
63 */
newCDKMatrix(CDKSCREEN * cdkscreen,int xplace,int yplace,int rows,int cols,int vrows,int vcols,const char * title,CDK_CSTRING2 rowtitles,CDK_CSTRING2 coltitles,int * colwidths,int * colvalues,int rspace,int cspace,chtype filler,int dominant,boolean Box,boolean boxCell,boolean shadow)64 CDKMATRIX *newCDKMatrix (CDKSCREEN *cdkscreen,
65 int xplace,
66 int yplace,
67 int rows,
68 int cols,
69 int vrows,
70 int vcols,
71 const char *title,
72 CDK_CSTRING2 rowtitles,
73 CDK_CSTRING2 coltitles,
74 int *colwidths,
75 int *colvalues,
76 int rspace,
77 int cspace,
78 chtype filler,
79 int dominant,
80 boolean Box,
81 boolean boxCell,
82 boolean shadow)
83 {
84 /* *INDENT-EQLS* */
85 CDKMATRIX *matrix = 0;
86 int parentWidth = getmaxx (cdkscreen->window);
87 int parentHeight = getmaxy (cdkscreen->window);
88 int boxHeight = 0;
89 int boxWidth = 0;
90 int xpos = xplace;
91 int ypos = yplace;
92 int maxWidth;
93 int maxRowTitleWidth = 0;
94 int rowSpace = MAXIMUM (0, rspace);
95 int colSpace = MAXIMUM (0, cspace);
96 int begx = 0;
97 int begy = 0;
98 int cellWidth = 0;
99 char **temp = 0;
100 int x, y;
101 int borderw = 0;
102 bool have_rowtitles = FALSE;
103 bool have_coltitles = FALSE;
104 /* *INDENT-OFF* */
105 static const struct { int from; int to; } bindings[] = {
106 { CDK_FORCHAR, KEY_NPAGE },
107 { CDK_BACKCHAR, KEY_PPAGE },
108 };
109 /* *INDENT-ON* */
110
111 if ((matrix = newCDKObject (CDKMATRIX, &my_funcs)) == 0)
112 {
113 return (0);
114 }
115
116 setCDKMatrixBox (matrix, Box);
117 borderw = (ObjOf (matrix)->box) ? 1 : 0;
118
119 /* Make sure that the number of rows/cols/vrows/vcols is not zero. */
120 if (rows <= 0 || cols <= 0 || vrows <= 0 || vcols <= 0)
121 {
122 destroyCDKObject (matrix);
123 return (0);
124 }
125 #if NEW_CDKMATRIX
126 matrix->cell = typeCallocN (WINDOW *, (rows + 1) * (cols + 1));
127 matrix->info = typeCallocN (char *, (rows + 1) * (cols + 1));
128 #endif
129
130 /*
131 * Make sure the number of virtual cells is not larger than
132 * the physical size.
133 */
134 vrows = (vrows > rows ? rows : vrows);
135 vcols = (vcols > cols ? cols : vcols);
136
137 /* Set these early, since they are used in matrix index computations */
138 /* *INDENT-EQLS* */
139 matrix->rows = rows;
140 matrix->cols = cols;
141 /* columns */
142 matrix->colwidths = typeCallocN (int, cols + 1);
143 matrix->colvalues = typeCallocN (int, cols + 1);
144 matrix->coltitle = typeCallocN (chtype *, cols + 1);
145 matrix->coltitleLen = typeCallocN (int, cols + 1);
146 matrix->coltitlePos = typeCallocN (int, cols + 1);
147 /* titles */
148 matrix->rowtitle = typeCallocN (chtype *, rows + 1);
149 matrix->rowtitleLen = typeCallocN (int, rows + 1);
150 matrix->rowtitlePos = typeCallocN (int, rows + 1);
151
152 /*
153 * Count the number of lines in the title (see setCdkTitle).
154 */
155 temp = CDKsplitString (title, '\n');
156 TitleLinesOf (matrix) = (int)CDKcountStrings ((CDK_CSTRING2)temp);
157 CDKfreeStrings (temp);
158
159 /* Determine the height of the box. */
160 if (vrows == 1)
161 {
162 boxHeight = 6 + TitleLinesOf (matrix);
163 }
164 else
165 {
166 if (rowSpace == 0)
167 {
168 boxHeight = (6 + TitleLinesOf (matrix) +
169 ((vrows - 1) * 2));
170 }
171 else
172 {
173 boxHeight = (3 + TitleLinesOf (matrix) +
174 (vrows * 3) + ((vrows - 1) * (rowSpace - 1)));
175 }
176 }
177
178 /* Determine the maximum row title width */
179 for (x = 1; x <= rows; x++)
180 {
181 if (rowtitles && !emptyString (rowtitles[x])) /*VR */
182 have_rowtitles = TRUE;
183 matrix->rowtitle[x] = char2Chtype (rowtitles ? rowtitles[x] : 0, /*VR */
184 &matrix->rowtitleLen[x],
185 &matrix->rowtitlePos[x]);
186 maxRowTitleWidth = MAXIMUM (maxRowTitleWidth, matrix->rowtitleLen[x]);
187 }
188
189 if (have_rowtitles)
190 {
191 matrix->maxrt = maxRowTitleWidth + 2;
192
193 /* We need to rejustify the row title cell info. */
194 for (x = 1; x <= rows; x++)
195 {
196 matrix->rowtitlePos[x] = justifyString (matrix->maxrt,
197 matrix->rowtitleLen[x],
198 matrix->rowtitlePos[x]);
199 }
200 }
201 else
202 {
203 matrix->maxrt = 0;
204 }
205
206 /* Determine the width of the matrix. */
207 maxWidth = 2 + matrix->maxrt;
208 for (x = 1; x <= vcols; x++)
209 {
210 maxWidth += colwidths[x] + 2 + colSpace;
211 }
212 maxWidth -= (colSpace - 1);
213 boxWidth = MAXIMUM (maxWidth, boxWidth);
214
215 boxWidth = setCdkTitle (ObjOf (matrix), title, boxWidth);
216
217 /*
218 * Make sure the dimensions of the window didn't
219 * extend beyond the dimensions of the parent window.
220 */
221 boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
222 boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
223
224 /* Rejustify the x and y positions if we need to. */
225 alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
226
227 /* Make the pop-up window. */
228 matrix->win = newwin (boxHeight, boxWidth, ypos, xpos);
229
230 if (matrix->win == 0)
231 {
232 destroyCDKObject (matrix);
233 return (0);
234 }
235
236 /* Make the subwindows in the pop-up. */
237 begx = xpos;
238 begy = ypos + borderw + TitleLinesOf (matrix);
239
240 /* Make the 'empty' 0x0 cell. */
241 MATRIX_CELL (matrix, 0, 0) = subwin (matrix->win, 3, matrix->maxrt, begy, begx);
242 begx += matrix->maxrt + 1;
243
244 /* Copy the titles into the structure. */
245 for (x = 1; x <= cols; x++)
246 {
247 if (coltitles && !emptyString (coltitles[x])) /*VR */
248 have_coltitles = TRUE;
249 matrix->coltitle[x] = char2Chtype (coltitles ? coltitles[x] : 0, /*VR */
250 &matrix->coltitleLen[x],
251 &matrix->coltitlePos[x]);
252 matrix->coltitlePos[x] = (BorderOf (matrix) +
253 justifyString (colwidths[x],
254 matrix->coltitleLen[x],
255 matrix->coltitlePos[x]));
256 matrix->colwidths[x] = colwidths[x];
257 }
258
259 if (have_coltitles)
260 {
261 /* Make the column titles. */
262 for (x = 1; x <= vcols; x++)
263 {
264 cellWidth = colwidths[x] + 3;
265 MATRIX_CELL (matrix, 0, x) = subwin (matrix->win,
266 borderw,
267 cellWidth,
268 begy,
269 begx);
270
271 if (MATRIX_CELL (matrix, 0, x) == 0)
272 {
273 destroyCDKObject (matrix);
274 return (0);
275 }
276 begx += cellWidth + colSpace - 1;
277 }
278 begy++;
279 }
280
281 /* Make the main cell body */
282 for (x = 1; x <= vrows; x++)
283 {
284 if (have_rowtitles)
285 {
286 /* Make the row titles */
287 MATRIX_CELL (matrix, x, 0) = subwin (matrix->win,
288 3, matrix->maxrt,
289 begy, xpos + borderw);
290
291 if (MATRIX_CELL (matrix, x, 0) == 0)
292 {
293 destroyCDKObject (matrix);
294 return (0);
295 }
296 }
297
298 /* Set the start of the x position. */
299 begx = xpos + matrix->maxrt + borderw;
300
301 /* Make the cells */
302 for (y = 1; y <= vcols; y++)
303 {
304 cellWidth = colwidths[y] + 3;
305 MATRIX_CELL (matrix, x, y) = subwin (matrix->win,
306 3, cellWidth,
307 begy, begx);
308
309 if (MATRIX_CELL (matrix, x, y) == 0)
310 {
311 destroyCDKObject (matrix);
312 return (0);
313 }
314 begx += cellWidth + colSpace - 1;
315 keypad (MATRIX_CELL (matrix, x, y), TRUE);
316 }
317 begy += rowSpace + 2;
318 }
319 keypad (matrix->win, TRUE);
320
321 /* *INDENT-EQLS* Keep the rest of the info. */
322 ScreenOf (matrix) = cdkscreen;
323 ObjOf (matrix)->acceptsFocus = TRUE;
324 ObjOf (matrix)->inputWindow = matrix->win;
325 matrix->parent = cdkscreen->window;
326 matrix->vrows = vrows;
327 matrix->vcols = vcols;
328 matrix->boxWidth = boxWidth;
329 matrix->boxHeight = boxHeight;
330 matrix->rowSpace = rowSpace;
331 matrix->colSpace = colSpace;
332 matrix->filler = filler;
333 matrix->dominant = dominant;
334 matrix->row = 1;
335 matrix->col = 1;
336 matrix->crow = 1;
337 matrix->ccol = 1;
338 matrix->trow = 1;
339 matrix->lcol = 1;
340 matrix->oldcrow = 1;
341 matrix->oldccol = 1;
342 matrix->oldvrow = 1;
343 matrix->oldvcol = 1;
344 initExitType (matrix);
345 matrix->boxCell = boxCell;
346 matrix->shadow = shadow;
347 matrix->highlight = A_REVERSE;
348 matrix->callbackfn = CDKMatrixCallBack;
349
350 /* Make room for the cell information. */
351 for (x = 1; x <= rows; x++)
352 {
353 for (y = 1; y <= cols; y++)
354 {
355 MATRIX_INFO (matrix, x, y) = typeCallocN (char, (colwidths[y] + 1));
356 matrix->colvalues[y] = colvalues[y];
357 matrix->colwidths[y] = colwidths[y];
358 }
359 }
360
361 /* Do we want a shadow??? */
362 if (shadow)
363 {
364 matrix->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
365 }
366
367 /* Setup the key bindings. */
368 for (x = 0; x < (int)SIZEOF (bindings); ++x)
369 bindCDKObject (vMATRIX, matrix,
370 (chtype)bindings[x].from,
371 getcCDKBind,
372 (void *)(long)bindings[x].to);
373
374 /* Register this baby. */
375 registerCDKObject (cdkscreen, vMATRIX, matrix);
376
377 /* Return the matrix pointer */
378 return (matrix);
379 }
380
381 /*
382 * This activates the matrix.
383 */
activateCDKMatrix(CDKMATRIX * matrix,chtype * actions)384 int activateCDKMatrix (CDKMATRIX *matrix, chtype *actions)
385 {
386 int ret;
387
388 /* Draw the matrix */
389 drawCDKMatrix (matrix, ObjOf (matrix)->box);
390
391 if (actions == 0)
392 {
393 chtype input = 0;
394 boolean functionKey;
395
396 for (;;)
397 {
398 ObjOf (matrix)->inputWindow = CurMatrixCell (matrix);
399 keypad (ObjOf (matrix)->inputWindow, TRUE);
400 input = (chtype)getchCDKObject (ObjOf (matrix), &functionKey);
401
402 /* Inject the character into the widget. */
403 ret = injectCDKMatrix (matrix, input);
404 if (matrix->exitType != vEARLY_EXIT)
405 {
406 return ret;
407 }
408 }
409 }
410 else
411 {
412 int length = chlen (actions);
413 int x = 0;
414
415 /* Inject each character one at a time. */
416 for (x = 0; x < length; x++)
417 {
418 ret = injectCDKMatrix (matrix, actions[x]);
419 if (matrix->exitType != vEARLY_EXIT)
420 {
421 return ret;
422 }
423 }
424 }
425
426 /* Set the exit type and exit. */
427 setExitType (matrix, 0);
428 return -1;
429 }
430
431 /*
432 * This injects a single character into the matrix widget.
433 */
_injectCDKMatrix(CDKOBJS * object,chtype input)434 static int _injectCDKMatrix (CDKOBJS *object, chtype input)
435 {
436 /* *INDENT-EQLS* */
437 CDKMATRIX *widget = (CDKMATRIX *)object;
438 int refreshCells = FALSE;
439 int movedCell = FALSE;
440 int charcount = (int)strlen (MATRIX_INFO (widget, widget->row, widget->col));
441 int ppReturn = 1;
442 int ret = unknownInt;
443 bool complete = FALSE;
444
445 /* Set the exit type. */
446 setExitType (widget, 0);
447
448 /* Move the cursor to the correct position within the cell. */
449 if (widget->colwidths[widget->ccol] == 1)
450 {
451 wmove (CurMatrixCell (widget), 1, 1);
452 }
453 else
454 {
455 wmove (CurMatrixCell (widget),
456 1,
457 (int)strlen (MATRIX_INFO (widget, widget->row, widget->col)) + 1);
458 }
459
460 /* Put the focus on the current cell */
461 MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD);
462 wrefresh (CurMatrixCell (widget));
463 highlightCDKMatrixCell (widget);
464
465 /* Check if there is a pre-process function to be called. */
466 if (PreProcessFuncOf (widget) != 0)
467 {
468 /* Call the pre-process function. */
469 ppReturn = PreProcessFuncOf (widget) (vMATRIX,
470 widget,
471 PreProcessDataOf (widget),
472 input);
473 }
474
475 /* Should we continue? */
476 if (ppReturn != 0)
477 {
478 /* Check the key bindings. */
479 if (checkCDKObjectBind (vMATRIX, widget, input) != 0)
480 {
481 checkEarlyExit (widget);
482 complete = TRUE;
483 }
484 else
485 {
486 switch (input)
487 {
488 case CDK_TRANSPOSE:
489 break;
490
491 case KEY_HOME:
492 break;
493
494 case KEY_END:
495 break;
496
497 case KEY_BACKSPACE:
498 case KEY_DC:
499 if (widget->colvalues[widget->col] == vVIEWONLY || charcount <= 0)
500 {
501 Beep ();
502 }
503 else
504 {
505 charcount--;
506 (void)mvwdelch (CurMatrixCell (widget), 1, charcount + 1);
507 (void)mvwinsch (CurMatrixCell (widget), 1, charcount + 1, widget->filler);
508 wrefresh (CurMatrixCell (widget));
509 MATRIX_INFO (widget, widget->row, widget->col)[charcount] = '\0';
510 }
511 break;
512
513 case KEY_RIGHT:
514 case KEY_TAB:
515 if (widget->ccol != widget->vcols)
516 {
517 /* We are moving to the right... */
518 widget->col++;
519 widget->ccol++;
520 movedCell = TRUE;
521 }
522 else
523 {
524 /* We have to shift the columns to the right. */
525 if (widget->col != widget->cols)
526 {
527 widget->lcol++;
528 widget->col++;
529
530 /* Redraw the column titles. */
531 if (widget->rows > widget->vrows)
532 {
533 redrawTitles (widget, FALSE, TRUE);
534 }
535 refreshCells = TRUE;
536 movedCell = TRUE;
537 }
538 else
539 {
540 /* We are at the far right column, we need */
541 /* shift down one row, if we can. */
542 if (widget->row == widget->rows)
543 {
544 Beep ();
545 }
546 else
547 {
548 /* Set up the columns info. */
549 widget->col = 1;
550 widget->lcol = 1;
551 widget->ccol = 1;
552
553 /* Shift the rows... */
554 if (widget->crow != widget->vrows)
555 {
556 widget->row++;
557 widget->crow++;
558 }
559 else
560 {
561 widget->row++;
562 widget->trow++;
563 }
564 redrawTitles (widget, TRUE, TRUE);
565 refreshCells = TRUE;
566 movedCell = TRUE;
567 }
568 }
569 }
570 break;
571
572 case KEY_LEFT:
573 case KEY_BTAB:
574 if (widget->ccol != 1)
575 {
576 /* We are moving to the left... */
577 widget->col--;
578 widget->ccol--;
579 movedCell = TRUE;
580 }
581 else
582 {
583 /* Are we at the far left??? */
584 if (widget->lcol != 1)
585 {
586 widget->lcol--;
587 widget->col--;
588
589 /* Redraw the column titles. */
590 if (widget->cols > widget->vcols)
591 {
592 redrawTitles (widget, FALSE, TRUE);
593 }
594 refreshCells = TRUE;
595 movedCell = TRUE;
596 }
597 else
598 {
599 /* Shift up one line if we can... */
600 if (widget->row == 1)
601 {
602 Beep ();
603 }
604 else
605 {
606 /* Set up the columns info. */
607 widget->col = widget->cols;
608 widget->lcol = widget->cols - widget->vcols + 1;
609 widget->ccol = widget->vcols;
610
611 /* Shift the rows... */
612 if (widget->crow != 1)
613 {
614 widget->row--;
615 widget->crow--;
616 }
617 else
618 {
619 widget->row--;
620 widget->trow--;
621 }
622 redrawTitles (widget, TRUE, TRUE);
623 refreshCells = TRUE;
624 movedCell = TRUE;
625 }
626 }
627 }
628 break;
629
630 case KEY_UP:
631 if (widget->crow != 1)
632 {
633 widget->row--;
634 widget->crow--;
635 movedCell = TRUE;
636 }
637 else
638 {
639 if (widget->trow != 1)
640 {
641 widget->trow--;
642 widget->row--;
643
644 /* Redraw the row titles. */
645 if (widget->rows > widget->vrows)
646 {
647 redrawTitles (widget, TRUE, FALSE);
648 }
649 refreshCells = TRUE;
650 movedCell = TRUE;
651 }
652 else
653 {
654 Beep ();
655 }
656 }
657 break;
658
659 case KEY_DOWN:
660 if (widget->crow != widget->vrows)
661 {
662 widget->row++;
663 widget->crow++;
664 movedCell = TRUE;
665 }
666 else
667 {
668 if ((widget->trow + widget->vrows - 1) != widget->rows)
669 {
670 widget->trow++;
671 widget->row++;
672
673 /* Redraw the titles. */
674 if (widget->rows > widget->vrows)
675 {
676 redrawTitles (widget, TRUE, FALSE);
677 }
678 refreshCells = TRUE;
679 movedCell = TRUE;
680 }
681 else
682 {
683 Beep ();
684 }
685 }
686 break;
687
688 case KEY_NPAGE:
689 if (widget->rows > widget->vrows)
690 {
691 if ((widget->trow + ((widget->vrows - 1) * 2)) <= widget->rows)
692 {
693 widget->trow += widget->vrows - 1;
694 widget->row += widget->vrows - 1;
695 redrawTitles (widget, TRUE, FALSE);
696 refreshCells = TRUE;
697 movedCell = TRUE;
698 }
699 else
700 {
701 Beep ();
702 }
703 }
704 else
705 {
706 Beep ();
707 }
708 break;
709
710 case KEY_PPAGE:
711 if (widget->rows > widget->vrows)
712 {
713 if ((widget->trow - ((widget->vrows - 1) * 2)) >= 1)
714 {
715 widget->trow -= widget->vrows - 1;
716 widget->row -= widget->vrows - 1;
717 redrawTitles (widget, TRUE, FALSE);
718 refreshCells = TRUE;
719 movedCell = TRUE;
720 }
721 else
722 {
723 Beep ();
724 }
725 }
726 else
727 {
728 Beep ();
729 }
730 break;
731
732 case CTRL ('G'):
733 jumpToCell (widget, -1, -1);
734 drawCDKMatrix (widget, ObjOf (widget)->box);
735 break;
736
737 case CDK_PASTE:
738 if (GPasteBuffer == 0 ||
739 (int)strlen (GPasteBuffer) > widget->colwidths[widget->ccol])
740 {
741 Beep ();
742 }
743 else
744 {
745 strcpy (CurMatrixInfo (widget), GPasteBuffer);
746 drawCurCDKMatrixCell (widget);
747 }
748 break;
749
750 case CDK_COPY:
751 freeChar (GPasteBuffer);
752 GPasteBuffer = copyChar (CurMatrixInfo (widget));
753 break;
754
755 case CDK_CUT:
756 freeChar (GPasteBuffer);
757 GPasteBuffer = copyChar (CurMatrixInfo (widget));
758 cleanCDKMatrixCell (widget,
759 widget->trow + widget->crow - 1,
760 widget->lcol + widget->ccol - 1);
761 drawCurCDKMatrixCell (widget);
762 break;
763
764 case CDK_ERASE:
765 cleanCDKMatrixCell (widget,
766 widget->trow + widget->crow - 1,
767 widget->lcol + widget->ccol - 1);
768 drawCurCDKMatrixCell (widget);
769 break;
770
771 case KEY_ENTER:
772 if (!widget->boxCell)
773 {
774 attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol),
775 ' ', ' ',
776 ' ', ' ',
777 ' ', ' ',
778 A_NORMAL);
779 }
780 else
781 {
782 drawOldCDKMatrixCell (widget);
783 }
784 wrefresh (CurMatrixCell (widget));
785 setExitType (widget, input);
786 ret = 1;
787 complete = TRUE;
788 break;
789
790 case KEY_ERROR:
791 setExitType (widget, input);
792 complete = TRUE;
793 break;
794
795 case KEY_ESC:
796 if (!widget->boxCell)
797 {
798 attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol),
799 ' ', ' ',
800 ' ', ' ',
801 ' ', ' ',
802 A_NORMAL);
803 }
804 else
805 {
806 drawOldCDKMatrixCell (widget);
807 }
808 wrefresh (CurMatrixCell (widget));
809 setExitType (widget, input);
810 complete = TRUE;
811 break;
812
813 case CDK_REFRESH:
814 eraseCDKScreen (ScreenOf (widget));
815 refreshCDKScreen (ScreenOf (widget));
816 break;
817
818 default:
819 (widget->callbackfn) (widget, input);
820 break;
821 }
822 }
823
824 if (!complete)
825 {
826 /* Did we change cells? */
827 if (movedCell)
828 {
829 /* un-highlight the old box */
830 if (!widget->boxCell)
831 {
832 attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol),
833 ' ', ' ',
834 ' ', ' ',
835 ' ', ' ',
836 A_NORMAL);
837 }
838 else
839 {
840 drawOldCDKMatrixCell (widget);
841 }
842 wrefresh (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol));
843
844 /* Highlight the new cell. */
845 MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD);
846 wrefresh (CurMatrixCell (widget));
847 highlightCDKMatrixCell (widget);
848 }
849
850 /* Redraw each cell. */
851 if (refreshCells)
852 {
853 drawEachCDKMatrixCell (widget);
854
855 /* Highlight the current cell. */
856 MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD);
857 wrefresh (CurMatrixCell (widget));
858 highlightCDKMatrixCell (widget);
859 }
860
861 /* Move to the correct position in the cell. */
862 if (refreshCells || movedCell)
863 {
864 if (widget->colwidths[widget->ccol] == 1)
865 {
866 wmove (CurMatrixCell (widget), 1, 1);
867 }
868 else
869 {
870 int infolen = (int)strlen (CurMatrixInfo (widget));
871 wmove (CurMatrixCell (widget), 1, infolen + 1);
872 }
873 wrefresh (CurMatrixCell (widget));
874 }
875
876 /* Should we call a post-process? */
877 if (PostProcessFuncOf (widget) != 0)
878 {
879 PostProcessFuncOf (widget) (vMATRIX,
880 widget,
881 PostProcessDataOf (widget),
882 input);
883 }
884 }
885 }
886
887 if (!complete)
888 {
889 /* Set the variables we need. */
890 widget->oldcrow = widget->crow;
891 widget->oldccol = widget->ccol;
892 widget->oldvrow = widget->row;
893 widget->oldvcol = widget->col;
894
895 /* Set the exit type and exit. */
896 setExitType (widget, 0);
897 }
898
899 ResultOf (widget).valueInt = ret;
900 return (ret != unknownInt);
901 }
902
903 /*
904 * This allows the programmer to define their own key mappings.
905 */
CDKMatrixCallBack(CDKMATRIX * matrix,chtype input)906 static void CDKMatrixCallBack (CDKMATRIX *matrix, chtype input)
907 {
908 EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col];
909 int plainchar = filterByDisplayType (disptype, input);
910 int charcount = (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col));
911
912 if (plainchar == ERR)
913 {
914 Beep ();
915 }
916 else if (charcount == matrix->colwidths[matrix->col])
917 {
918 Beep ();
919 }
920 else
921 {
922 /* Update the screen. */
923 wmove (CurMatrixCell (matrix),
924 1,
925 (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col)) + 1);
926 waddch (CurMatrixCell (matrix),
927 (chtype)((isHiddenDisplayType (disptype))
928 ? (int)matrix->filler
929 : plainchar));
930 wrefresh (CurMatrixCell (matrix));
931
932 /* Update the character pointer. */
933 MATRIX_INFO (matrix, matrix->row, matrix->col)[charcount++] = (char)plainchar;
934 MATRIX_INFO (matrix, matrix->row, matrix->col)[charcount] = '\0';
935 }
936 }
937
938 /*
939 * Highlight the new field.
940 */
highlightCDKMatrixCell(CDKMATRIX * matrix)941 static void highlightCDKMatrixCell (CDKMATRIX *matrix)
942 {
943 /* *INDENT-EQLS* */
944 EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col];
945 chtype highlight = matrix->highlight;
946 int x = 0;
947 int infolen = (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col));
948
949 /*
950 * Given the dominance of the colors/attributes, we need to set the
951 * current cell attribute.
952 */
953 if (matrix->dominant == ROW)
954 {
955 highlight = matrix->rowtitle[matrix->crow][0] & A_ATTRIBUTES;
956 }
957 else if (matrix->dominant == COL)
958 {
959 highlight = matrix->coltitle[matrix->ccol][0] & A_ATTRIBUTES;
960 }
961
962 /* If the column is only one char. */
963 for (x = 1; x <= matrix->colwidths[matrix->ccol]; x++)
964 {
965 chtype ch = (((x <= infolen) && !isHiddenDisplayType (disptype))
966 ? CharOf (MATRIX_INFO (matrix,
967 matrix->row,
968 matrix->col)[x - 1])
969 : matrix->filler);
970
971 (void)mvwaddch (CurMatrixCell (matrix), 1, x, ch | highlight);
972 }
973 wmove (CurMatrixCell (matrix), 1, infolen + 1);
974 wrefresh (CurMatrixCell (matrix));
975 }
976
977 /*
978 * This moves the matrix field to the given location.
979 */
_moveCDKMatrix(CDKOBJS * object,int xplace,int yplace,boolean relative,boolean refresh_flag)980 static void _moveCDKMatrix (CDKOBJS *object,
981 int xplace,
982 int yplace,
983 boolean relative,
984 boolean refresh_flag)
985 {
986 /* *INDENT-EQLS* */
987 CDKMATRIX *matrix = (CDKMATRIX *)object;
988 int currentX = getbegx (matrix->win);
989 int currentY = getbegy (matrix->win);
990 int xpos = xplace;
991 int ypos = yplace;
992 int xdiff = 0;
993 int ydiff = 0;
994 int x, y;
995
996 /*
997 * If this is a relative move, then we will adjust where we want
998 * to move to.
999 */
1000 if (relative)
1001 {
1002 xpos = getbegx (matrix->win) + xplace;
1003 ypos = getbegy (matrix->win) + yplace;
1004 }
1005
1006 /* Adjust the window if we need to. */
1007 alignxy (WindowOf (matrix), &xpos, &ypos, matrix->boxWidth, matrix->boxHeight);
1008
1009 /* Get the difference. */
1010 xdiff = currentX - xpos;
1011 ydiff = currentY - ypos;
1012
1013 /* Move the window to the new location. */
1014 moveCursesWindow (matrix->win, -xdiff, -ydiff);
1015
1016 for (x = 0; x <= matrix->vrows; x++)
1017 {
1018 for (y = 0; y <= matrix->vcols; y++)
1019 {
1020 moveCursesWindow (MATRIX_CELL (matrix, x, y), -xdiff, -ydiff);
1021 }
1022 }
1023
1024 moveCursesWindow (matrix->shadowWin, -xdiff, -ydiff);
1025
1026 /* Touch the windows so they 'move'. */
1027 refreshCDKWindow (WindowOf (matrix));
1028
1029 /* Redraw the window, if they asked for it. */
1030 if (refresh_flag)
1031 {
1032 drawCDKMatrix (matrix, ObjOf (matrix)->box);
1033 }
1034 }
1035
1036 /*
1037 * This draws a cell within a matrix.
1038 */
drawCDKMatrixCell(CDKMATRIX * matrix,int row,int col,int vrow,int vcol,boolean Box)1039 static void drawCDKMatrixCell (CDKMATRIX *matrix,
1040 int row,
1041 int col,
1042 int vrow,
1043 int vcol,
1044 boolean Box)
1045 {
1046 /* *INDENT-EQLS* */
1047 WINDOW *cell = MATRIX_CELL (matrix, row, col);
1048 EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col];
1049 chtype highlight = matrix->filler & A_ATTRIBUTES;
1050 int rows = matrix->vrows;
1051 int cols = matrix->vcols;
1052 int infolen = (int)strlen (MATRIX_INFO (matrix, vrow, vcol));
1053 chtype attr = A_NORMAL;
1054 int x;
1055
1056 /*
1057 * Given the dominance of the colors/attributes, we need to set the
1058 * current cell attribute.
1059 */
1060 if (matrix->dominant == ROW)
1061 {
1062 highlight = matrix->rowtitle[row][0] & A_ATTRIBUTES;
1063 }
1064 else if (matrix->dominant == COL)
1065 {
1066 highlight = matrix->coltitle[col][0] & A_ATTRIBUTES;
1067 }
1068
1069 /* Draw in the cell info. */
1070 for (x = 1; x <= matrix->colwidths[col]; x++)
1071 {
1072 chtype ch = (((x <= infolen) && !isHiddenDisplayType (disptype))
1073 ? (CharOf (MATRIX_INFO (matrix, vrow, vcol)[x - 1]) | highlight)
1074 : matrix->filler);
1075
1076 (void)mvwaddch (cell, 1, x, ch | highlight);
1077 }
1078 wmove (cell, 1, infolen + 1);
1079 wrefresh (cell);
1080
1081 /* Only draw the box iff the user asked for a box. */
1082 if (!Box)
1083 {
1084 return;
1085 }
1086
1087 /*
1088 * If the value of the column spacing is greater than 0 then these
1089 * are independent boxes.
1090 */
1091 if (matrix->colSpace != 0)
1092 {
1093 if (matrix->rowSpace != 0)
1094 {
1095 MyBox (cell, WHOLE_BOX, attr);
1096 }
1097 else
1098 {
1099 if (row == 1)
1100 {
1101 MyBox (cell, TOP_C_BOX, attr);
1102 }
1103 else if (row > 1 && row < rows)
1104 {
1105 MyBox (cell, MID_C_BOX, attr);
1106 }
1107 else if (row == rows)
1108 {
1109 MyBox (cell, BOT_C_BOX, attr);
1110 }
1111 }
1112 }
1113 else if (matrix->rowSpace != 0)
1114 {
1115 if (col == 1)
1116 {
1117 MyBox (cell, LFT_R_BOX, attr);
1118 }
1119 else if (col > 1 && col < cols)
1120 {
1121 MyBox (cell, MID_R_BOX, attr);
1122 }
1123 else if (col == cols)
1124 {
1125 MyBox (cell, RGT_R_BOX, attr);
1126 }
1127 }
1128 else
1129 {
1130 if (row == 1)
1131 {
1132 if (col == 1)
1133 {
1134 MyBox (cell, LFT_T_BOX, attr); /* top left corner */
1135 }
1136 else if (col > 1 && col < cols)
1137 {
1138 MyBox (cell, MID_T_BOX, attr); /* top middle */
1139 }
1140 else if (col == cols)
1141 {
1142 MyBox (cell, RGT_T_BOX, attr); /* top right corner */
1143 }
1144 }
1145 else if (row > 1 && row < rows)
1146 {
1147 if (col == 1)
1148 {
1149 MyBox (cell, LFT_M_BOX, attr); /* middle left */
1150 }
1151 else if (col > 1 && col < cols)
1152 {
1153 MyBox (cell, MID_M_BOX, attr); /* middle */
1154 }
1155 else if (col == cols)
1156 {
1157 MyBox (cell, RGT_M_BOX, attr); /* middle right */
1158 }
1159 }
1160 else if (row == rows)
1161 {
1162 if (col == 1)
1163 {
1164 MyBox (cell, LFT_B_BOX, attr); /* bottom left corner */
1165 }
1166 else if (col > 1 && col < cols)
1167 {
1168 MyBox (cell, MID_B_BOX, attr); /* bottom middle */
1169 }
1170 else if (col == cols)
1171 {
1172 MyBox (cell, RGT_B_BOX, attr); /* bottom right corner */
1173 }
1174 }
1175 }
1176
1177 /* Highlight the current cell. */
1178 MyBox (CurMatrixCell (matrix), WHOLE_BOX, A_BOLD);
1179 wrefresh (CurMatrixCell (matrix));
1180 highlightCDKMatrixCell (matrix);
1181 }
1182
drawEachColTitle(CDKMATRIX * matrix)1183 static void drawEachColTitle (CDKMATRIX *matrix)
1184 {
1185 int x;
1186
1187 for (x = 1; x <= matrix->vcols; x++)
1188 {
1189 if (MATRIX_CELL (matrix, 0, x))
1190 {
1191 werase (MATRIX_CELL (matrix, 0, x)); /*VR */
1192 writeChtype (MATRIX_CELL (matrix, 0, x),
1193 matrix->coltitlePos[matrix->lcol + x - 1], 0,
1194 matrix->coltitle[matrix->lcol + x - 1],
1195 HORIZONTAL,
1196 0, matrix->coltitleLen[matrix->lcol + x - 1]);
1197 wrefresh (MATRIX_CELL (matrix, 0, x));
1198 }
1199 }
1200 }
1201
drawEachRowTitle(CDKMATRIX * matrix)1202 static void drawEachRowTitle (CDKMATRIX *matrix)
1203 {
1204 int x;
1205
1206 for (x = 1; x <= matrix->vrows; x++)
1207 {
1208 if (MATRIX_CELL (matrix, x, 0))
1209 {
1210 werase (MATRIX_CELL (matrix, x, 0));
1211 writeChtype (MATRIX_CELL (matrix, x, 0),
1212 matrix->rowtitlePos[matrix->trow + x - 1], 1,
1213 matrix->rowtitle[matrix->trow + x - 1],
1214 HORIZONTAL,
1215 0, matrix->rowtitleLen[matrix->trow + x - 1]);
1216 wrefresh (MATRIX_CELL (matrix, x, 0));
1217 }
1218 }
1219 }
1220
drawEachCDKMatrixCell(CDKMATRIX * matrix)1221 static void drawEachCDKMatrixCell (CDKMATRIX *matrix)
1222 {
1223 int y, x;
1224
1225 /* Fill in the cells. */
1226 for (x = 1; x <= matrix->vrows; x++)
1227 {
1228 for (y = 1; y <= matrix->vcols; y++)
1229 {
1230 drawCDKMatrixCell (matrix, x, y,
1231 matrix->trow + x - 1,
1232 matrix->lcol + y - 1,
1233 matrix->boxCell);
1234 }
1235 }
1236 }
1237
drawCurCDKMatrixCell(CDKMATRIX * matrix)1238 static void drawCurCDKMatrixCell (CDKMATRIX *matrix)
1239 {
1240 drawCDKMatrixCell (matrix,
1241 matrix->crow,
1242 matrix->ccol,
1243 matrix->row,
1244 matrix->col,
1245 matrix->boxCell);
1246 }
1247
drawOldCDKMatrixCell(CDKMATRIX * matrix)1248 static void drawOldCDKMatrixCell (CDKMATRIX *matrix)
1249 {
1250 drawCDKMatrixCell (matrix,
1251 matrix->oldcrow,
1252 matrix->oldccol,
1253 matrix->oldvrow,
1254 matrix->oldvcol,
1255 matrix->boxCell);
1256 }
1257
1258 /*
1259 * This function draws the matrix widget.
1260 */
_drawCDKMatrix(CDKOBJS * object,boolean Box)1261 static void _drawCDKMatrix (CDKOBJS *object, boolean Box)
1262 {
1263 CDKMATRIX *matrix = (CDKMATRIX *)object;
1264
1265 /* Did we ask for a shadow??? */
1266 if (matrix->shadowWin != 0)
1267 {
1268 drawShadow (matrix->shadowWin);
1269 }
1270
1271 /* Should we box the matrix??? */
1272 if (Box)
1273 {
1274 drawObjBox (matrix->win, ObjOf (matrix));
1275 }
1276
1277 drawCdkTitle (matrix->win, object);
1278
1279 wrefresh (matrix->win);
1280
1281 drawEachColTitle (matrix);
1282 drawEachRowTitle (matrix);
1283 drawEachCDKMatrixCell (matrix);
1284
1285 /* Highlight the current cell. */
1286 MyBox (CurMatrixCell (matrix), WHOLE_BOX, A_BOLD);
1287 wrefresh (CurMatrixCell (matrix));
1288 highlightCDKMatrixCell (matrix);
1289 }
1290
1291 /*
1292 * This function destroys the matrix widget.
1293 */
_destroyCDKMatrix(CDKOBJS * object)1294 static void _destroyCDKMatrix (CDKOBJS *object)
1295 {
1296 if (object != 0)
1297 {
1298 CDKMATRIX *matrix = (CDKMATRIX *)object;
1299 int x = 0;
1300 int y = 0;
1301
1302 cleanCdkTitle (object);
1303
1304 /* Clear out the col titles. */
1305 for (x = 1; x <= matrix->cols; x++)
1306 {
1307 freeChtype (matrix->coltitle[x]);
1308 }
1309
1310 /* Clear out the row titles. */
1311 for (x = 1; x <= matrix->rows; x++)
1312 {
1313 freeChtype (matrix->rowtitle[x]);
1314 }
1315
1316 /* Clear out the matrix cells. */
1317 for (x = 1; x <= matrix->rows; x++)
1318 {
1319 for (y = 1; y <= matrix->cols; y++)
1320 {
1321 freeChar (MATRIX_INFO (matrix, x, y));
1322 }
1323 }
1324
1325 /* Clear the matrix windows. */
1326 deleteCursesWindow (MATRIX_CELL (matrix, 0, 0));
1327 for (x = 1; x <= matrix->vrows; x++)
1328 {
1329 deleteCursesWindow (MATRIX_CELL (matrix, x, 0));
1330 }
1331 for (x = 1; x <= matrix->vcols; x++)
1332 {
1333 deleteCursesWindow (MATRIX_CELL (matrix, 0, x));
1334 }
1335 for (x = 1; x <= matrix->vrows; x++)
1336 {
1337 for (y = 1; y <= matrix->vcols; y++)
1338 {
1339 deleteCursesWindow (MATRIX_CELL (matrix, x, y));
1340 }
1341 }
1342
1343 #if NEW_CDKMATRIX
1344 freeChecked (matrix->cell);
1345 freeChecked (matrix->info);
1346 #endif
1347
1348 freeChecked (matrix->colwidths);
1349 freeChecked (matrix->colvalues);
1350
1351 freeChecked (matrix->coltitle);
1352 freeChecked (matrix->coltitleLen);
1353 freeChecked (matrix->coltitlePos);
1354
1355 freeChecked (matrix->rowtitle);
1356 freeChecked (matrix->rowtitleLen);
1357 freeChecked (matrix->rowtitlePos);
1358
1359 deleteCursesWindow (matrix->shadowWin);
1360 deleteCursesWindow (matrix->win);
1361
1362 /* Clean the key bindings. */
1363 cleanCDKObjectBindings (vMATRIX, matrix);
1364
1365 /* Unregister this object. */
1366 unregisterCDKObject (vMATRIX, matrix);
1367 }
1368 }
1369
1370 /*
1371 * This function erases the matrix widget from the screen.
1372 */
_eraseCDKMatrix(CDKOBJS * object)1373 static void _eraseCDKMatrix (CDKOBJS *object)
1374 {
1375 if (validCDKObject (object))
1376 {
1377 CDKMATRIX *matrix = (CDKMATRIX *)object;
1378 int x = 0;
1379 int y = 0;
1380
1381 /* Clear the matrix cells. */
1382 eraseCursesWindow (MATRIX_CELL (matrix, 0, 0));
1383 for (x = 1; x <= matrix->vrows; x++)
1384 {
1385 eraseCursesWindow (MATRIX_CELL (matrix, x, 0));
1386 }
1387 for (x = 1; x <= matrix->vcols; x++)
1388 {
1389 eraseCursesWindow (MATRIX_CELL (matrix, 0, x));
1390 }
1391 for (x = 1; x <= matrix->vrows; x++)
1392 {
1393 for (y = 1; y <= matrix->vcols; y++)
1394 {
1395 eraseCursesWindow (MATRIX_CELL (matrix, x, y));
1396 }
1397 }
1398 eraseCursesWindow (matrix->shadowWin);
1399 eraseCursesWindow (matrix->win);
1400 }
1401 }
1402
1403 /*
1404 * Set the callback-function.
1405 */
setCDKMatrixCB(CDKMATRIX * widget,MATRIXCB callback)1406 void setCDKMatrixCB (CDKMATRIX *widget, MATRIXCB callback)
1407 {
1408 widget->callbackfn = callback;
1409 }
1410
1411 /*
1412 * This function sets the values of the matrix widget.
1413 */
setCDKMatrixCells(CDKMATRIX * matrix,CDK_CSTRING2 info,int rows,int maxcols,int * subSize)1414 void setCDKMatrixCells (CDKMATRIX *matrix,
1415 CDK_CSTRING2 info,
1416 int rows,
1417 int maxcols,
1418 int *subSize)
1419 {
1420 int x = 0;
1421 int y = 0;
1422
1423 if (rows > matrix->rows)
1424 rows = matrix->rows;
1425
1426 /* Copy in the new info. */
1427 for (x = 1; x <= rows; x++)
1428 {
1429 for (y = 1; y <= matrix->cols; y++)
1430 {
1431 if (x <= rows && y <= subSize[x])
1432 {
1433 const char *source = info[(x * maxcols) + y];
1434
1435 /* Copy in the new information. */
1436 if (source != 0)
1437 {
1438 char *target = MATRIX_INFO (matrix, x, y);
1439
1440 if (target == 0) /* this should not happen... */
1441 {
1442 target = typeCallocN (char, matrix->colwidths[y] + 1);
1443 MATRIX_INFO (matrix, x, y) = target;
1444 }
1445 strncpy (MATRIX_INFO (matrix, x, y),
1446 source,
1447 (size_t) matrix->colwidths[y]);
1448 }
1449 }
1450 else
1451 cleanCDKMatrixCell (matrix, x, y);
1452 }
1453 }
1454 }
1455
1456 /*
1457 * This sets the widget's box attribute.
1458 */
setCDKMatrixBox(CDKMATRIX * matrix,boolean Box)1459 void setCDKMatrixBox (CDKMATRIX *matrix, boolean Box)
1460 {
1461 ObjOf (matrix)->box = Box;
1462 ObjOf (matrix)->borderSize = Box ? 1 : 0;
1463 }
getCDKMatrixBox(CDKMATRIX * matrix)1464 boolean getCDKMatrixBox (CDKMATRIX *matrix)
1465 {
1466 return ObjOf (matrix)->box;
1467 }
1468
1469 /*
1470 * This cleans out the information cells in the matrix widget.
1471 */
cleanCDKMatrix(CDKMATRIX * matrix)1472 void cleanCDKMatrix (CDKMATRIX *matrix)
1473 {
1474 int x = 0;
1475 int y = 0;
1476
1477 for (x = 1; x <= matrix->rows; x++)
1478 {
1479 for (y = 1; y <= matrix->cols; y++)
1480 {
1481 cleanCDKMatrixCell (matrix, x, y);
1482 }
1483 }
1484 }
1485
1486 /*
1487 * This cleans one cell in the matrix widget.
1488 */
cleanCDKMatrixCell(CDKMATRIX * matrix,int row,int col)1489 void cleanCDKMatrixCell (CDKMATRIX *matrix, int row, int col)
1490 {
1491 if (row > 0 && row <= matrix->rows &&
1492 col > 0 && col <= matrix->cols)
1493 cleanChar (MATRIX_INFO (matrix, row, col), matrix->colwidths[col], '\0');
1494 }
1495
1496 /*
1497 * This allows us to hyper-warp to a cell.
1498 */
jumpToCell(CDKMATRIX * matrix,int row,int col)1499 int jumpToCell (CDKMATRIX *matrix, int row, int col)
1500 {
1501 CDKSCALE *scale = 0;
1502 int newRow = row;
1503 int newCol = col;
1504
1505 /*
1506 * Only create the row scale if needed.
1507 */
1508 if ((row == -1) || (row > matrix->rows))
1509 {
1510 /* Create the row scale widget. */
1511 scale = newCDKScale (ScreenOf (matrix),
1512 CENTER, CENTER,
1513 "<C>Jump to which row.",
1514 "</5/B>Row: ", A_NORMAL, 5,
1515 1, 1, matrix->rows, 1, 1, TRUE, FALSE);
1516
1517 /* Activate the scale and get the row. */
1518 newRow = activateCDKScale (scale, 0);
1519 destroyCDKScale (scale);
1520 }
1521
1522 /*
1523 * Only create the column scale if needed.
1524 */
1525 if ((col == -1) || (col > matrix->cols))
1526 {
1527 /* Create the column scale widget. */
1528 scale = newCDKScale (ScreenOf (matrix),
1529 CENTER, CENTER,
1530 "<C>Jump to which column",
1531 "</5/B>Col: ", A_NORMAL, 5,
1532 1, 1, matrix->cols, 1, 1, TRUE, FALSE);
1533
1534 /* Activate the scale and get the column. */
1535 newCol = activateCDKScale (scale, 0);
1536 destroyCDKScale (scale);
1537 }
1538
1539 /* Hyper-warp.... */
1540 if (newRow != matrix->row || newCol != matrix->col)
1541 {
1542 return (moveToCDKMatrixCell (matrix, newRow, newCol));
1543 }
1544 else
1545 {
1546 return 1;
1547 }
1548 }
1549
1550 /*
1551 * This allows us to move to a given cell.
1552 */
moveToCDKMatrixCell(CDKMATRIX * matrix,int newrow,int newcol)1553 int moveToCDKMatrixCell (CDKMATRIX *matrix, int newrow, int newcol)
1554 {
1555 int rowShift = newrow - matrix->row;
1556 int colShift = newcol - matrix->col;
1557
1558 /* Make sure we arent asking to move out of the matrix. */
1559 if (newrow > matrix->rows ||
1560 newcol > matrix->cols ||
1561 newrow <= 0 ||
1562 newcol <= 0)
1563 {
1564 return 0;
1565 }
1566
1567 /* Did we move up/down???? */
1568 if (rowShift > 0)
1569 {
1570 /* We are moving down. */
1571 if (matrix->vrows == matrix->cols)
1572 {
1573 matrix->trow = 1;
1574 matrix->crow = newrow;
1575 matrix->row = newrow;
1576 }
1577 else
1578 {
1579 if ((rowShift + matrix->vrows) < matrix->rows)
1580 {
1581 /* Just shift down by rowShift... */
1582 matrix->trow += rowShift;
1583 matrix->crow = 1;
1584 matrix->row += rowShift;
1585 }
1586 else
1587 {
1588 /* We need to munge with the values... */
1589 matrix->trow = matrix->rows - matrix->vrows + 1;
1590 matrix->crow = ((rowShift + matrix->vrows) - matrix->rows) + 1;
1591 matrix->row = newrow;
1592 }
1593 }
1594 }
1595 else if (rowShift < 0)
1596 {
1597 /* We are moving up. */
1598 if (matrix->vrows == matrix->rows)
1599 {
1600 matrix->trow = 1;
1601 matrix->row = newrow;
1602 matrix->crow = newrow;
1603 }
1604 else
1605 {
1606 if ((rowShift + matrix->vrows) > 1)
1607 {
1608 /* Just shift up by rowShift... */
1609 matrix->trow += rowShift;
1610 matrix->row += rowShift;
1611 matrix->crow = 1;
1612 }
1613 else
1614 {
1615 /* We need to munge with the values... */
1616 matrix->trow = 1;
1617 matrix->crow = 1;
1618 matrix->row = 1;
1619 }
1620 }
1621 }
1622
1623 /* Did we move left/right ???? */
1624 if (colShift > 0)
1625 {
1626 /* We are moving right. */
1627 if (matrix->vcols == matrix->cols)
1628 {
1629 matrix->lcol = 1;
1630 matrix->ccol = newcol;
1631 matrix->col = newcol;
1632 }
1633 else
1634 {
1635 if ((colShift + matrix->vcols) < matrix->cols)
1636 {
1637 matrix->lcol += colShift;
1638 matrix->ccol = 1;
1639 matrix->col += colShift;
1640 }
1641 else
1642 {
1643 /* We need to munge with the values... */
1644 matrix->lcol = matrix->cols - matrix->vcols + 1;
1645 matrix->ccol = ((colShift + matrix->vcols) - matrix->cols) + 1;
1646 matrix->col = newcol;
1647 }
1648 }
1649 }
1650 else if (colShift < 0)
1651 {
1652 /* We are moving left. */
1653 if (matrix->vcols == matrix->cols)
1654 {
1655 matrix->lcol = 1;
1656 matrix->col = newcol;
1657 matrix->ccol = newcol;
1658 }
1659 else
1660 {
1661 if ((colShift + matrix->vcols) > 1)
1662 {
1663 /* Just shift left by colShift... */
1664 matrix->lcol += colShift;
1665 matrix->col += colShift;
1666 matrix->ccol = 1;
1667 }
1668 else
1669 {
1670 matrix->lcol = 1;
1671 matrix->col = 1;
1672 matrix->ccol = 1;
1673 }
1674 }
1675 }
1676
1677 /* Keep the 'old' values around for redrawing sake. */
1678 matrix->oldcrow = matrix->crow;
1679 matrix->oldccol = matrix->ccol;
1680 matrix->oldvrow = matrix->row;
1681 matrix->oldvcol = matrix->col;
1682
1683 /* Lets ... */
1684 return 1;
1685 }
1686
1687 /*
1688 * This redraws the titles indicated...
1689 */
redrawTitles(CDKMATRIX * matrix,int rowTitles,int colTitles)1690 static void redrawTitles (CDKMATRIX *matrix, int rowTitles, int colTitles)
1691 {
1692 /* Redraw the row titles. */
1693 if (rowTitles)
1694 {
1695 drawEachRowTitle (matrix);
1696 }
1697
1698 /* Redraw the column titles. */
1699 if (colTitles)
1700 {
1701 drawEachColTitle (matrix);
1702 }
1703 }
1704
1705 /*
1706 * This sets the value of a matrix cell.
1707 */
setCDKMatrixCell(CDKMATRIX * matrix,int row,int col,const char * value)1708 int setCDKMatrixCell (CDKMATRIX *matrix, int row, int col, const char *value)
1709 {
1710 /* Make sure the row/col combination is within the matrix. */
1711 if (row > matrix->rows || col > matrix->cols || row <= 0 || col <= 0)
1712 {
1713 return -1;
1714 }
1715
1716 cleanCDKMatrixCell (matrix, row, col);
1717 strncpy (MATRIX_INFO (matrix, row, col),
1718 value,
1719 (size_t) matrix->colwidths[col]);
1720 return 1;
1721 }
1722
1723 /*
1724 * This gets the value of a matrix cell.
1725 */
getCDKMatrixCell(CDKMATRIX * matrix,int row,int col)1726 char *getCDKMatrixCell (CDKMATRIX *matrix, int row, int col)
1727 {
1728 /* Make sure the row/col combination is within the matrix. */
1729 if (row > matrix->rows || col > matrix->cols || row <= 0 || col <= 0)
1730 {
1731 return 0;
1732 }
1733 return MATRIX_INFO (matrix, row, col);
1734 }
1735
1736 /*
1737 * This returns the current row/col cell.
1738 */
getCDKMatrixCol(CDKMATRIX * matrix)1739 int getCDKMatrixCol (CDKMATRIX *matrix)
1740 {
1741 return matrix->col;
1742 }
getCDKMatrixRow(CDKMATRIX * matrix)1743 int getCDKMatrixRow (CDKMATRIX *matrix)
1744 {
1745 return matrix->row;
1746 }
1747
1748 /*
1749 * This sets the background attribute of the widget.
1750 */
_setBKattrMatrix(CDKOBJS * object,chtype attrib)1751 static void _setBKattrMatrix (CDKOBJS *object, chtype attrib)
1752 {
1753 if (object != 0)
1754 {
1755 CDKMATRIX *widget = (CDKMATRIX *)object;
1756 int x, y;
1757
1758 wbkgd (widget->win, attrib);
1759 for (x = 0; x <= widget->vrows; x++)
1760 {
1761 for (y = 0; y <= widget->vcols; y++)
1762 {
1763 wbkgd (MATRIX_CELL (widget, x, y), attrib);
1764 }
1765 }
1766 }
1767 }
1768
_focusCDKMatrix(CDKOBJS * object)1769 static void _focusCDKMatrix (CDKOBJS *object)
1770 {
1771 CDKMATRIX *widget = (CDKMATRIX *)object;
1772
1773 drawCDKMatrix (widget, ObjOf (widget)->box);
1774 }
1775
_unfocusCDKMatrix(CDKOBJS * object)1776 static void _unfocusCDKMatrix (CDKOBJS *object)
1777 {
1778 CDKMATRIX *widget = (CDKMATRIX *)object;
1779
1780 drawCDKMatrix (widget, ObjOf (widget)->box);
1781 }
1782
1783 dummyRefreshData (Matrix)
1784
1785 dummySaveData (Matrix)
1786