Annotation of othersrc/dist/cdk/mentry.c, revision 1.1.1.1
1.1 garbled 1: #include <cdk.h>
2:
3: /*
4: * $Author: tom $
5: * $Date: 2000/02/18 23:20:55 $
6: * $Revision: 1.112 $
7: */
8:
9: /*
10: * Declare file local prototypes.
11: */
12: static void CDKMentryCallBack (CDKMENTRY *mentry, chtype character);
13:
14: /*
15: * Declare file local variables.
16: */
17: extern char *GPasteBuffer;
18:
19: DeclareCDKObjects(my_funcs,Mentry);
20:
21: /*
22: * This creates a pointer to a muliple line entry widget.
23: */
24: CDKMENTRY *newCDKMentry (CDKSCREEN *cdkscreen, int xplace, int yplace, char *title, char *label, chtype fieldAttr, chtype filler, EDisplayType dispType, int fWidth, int fRows, int logicalRows, int min, boolean Box, boolean shadow)
25: {
26: /* Set up some variables */
27: CDKMENTRY *mentry = newCDKObject(CDKMENTRY, &my_funcs);
28: chtype *holder = 0;
29: int parentWidth = getmaxx(cdkscreen->window);
30: int parentHeight = getmaxy(cdkscreen->window);
31: int fieldWidth = fWidth;
32: int fieldRows = fRows;
33: int boxWidth = 0;
34: int boxHeight = 0;
35: int maxWidth = INT_MIN;
36: int horizontalAdjust = 0;
37: int xpos = xplace;
38: int ypos = yplace;
39: char **temp = 0;
40: int x, len, junk, junk2;
41:
42: /*
43: * If the fieldWidth is a negative value, the fieldWidth will
44: * be COLS-fieldWidth, otherwise, the fieldWidth will be the
45: * given width.
46: */
47: fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0);
48:
49: /*
50: * If the fieldRows is a negative value, the fieldRows will
51: * be ROWS-fieldRows, otherwise, the fieldRows will be the
52: * given height.
53: */
54: fieldRows = setWidgetDimension (parentWidth, fieldRows, 0);
55: boxHeight = fieldRows + 2;
56:
57: /* Set some basic values of the mentry field. */
58: mentry->label = 0;
59: mentry->labelLen = 0;
60: mentry->labelWin = 0;
61: mentry->titleLines = 0;
62:
63: /* We need to translate the char * label to a chtype * */
64: if (label != 0)
65: {
66: mentry->label = char2Chtype (label, &mentry->labelLen, &junk);
67: }
68: boxWidth = mentry->labelLen + fieldWidth + 2;
69:
70: /* Translate the char * items to chtype * */
71: if (title != 0)
72: {
73: temp = CDKsplitString (title, '\n');
74: mentry->titleLines = CDKcountStrings (temp);
75:
76: /* We need to determine the widest title line. */
77: for (x=0; x < mentry->titleLines; x++)
78: {
79: holder = char2Chtype (temp[x], &len, &junk2);
80: maxWidth = MAXIMUM (maxWidth, len);
81: freeChtype (holder);
82: }
83:
84: /*
85: * If one of the title lines is wider than the field and the label,
86: * the box width will expand to accomodate.
87: */
88: if (maxWidth > boxWidth)
89: {
90: horizontalAdjust = (int)((maxWidth - boxWidth) / 2) + 1;
91: boxWidth = maxWidth + 2;
92: }
93:
94: /* For each line in the title, convert from char * to chtype * */
95: for (x=0; x < mentry->titleLines; x++)
96: {
97: mentry->title[x] = char2Chtype (temp[x], &mentry->titleLen[x], &mentry->titlePos[x]);
98: mentry->titlePos[x] = justifyString (boxWidth, mentry->titleLen[x], mentry->titlePos[x]);
99: }
100:
101: CDKfreeStrings(temp);
102: }
103: else
104: {
105: /* No title? Set the required variables. */
106: mentry->titleLines = 0;
107: }
108: boxHeight += mentry->titleLines;
109:
110: /*
111: * Make sure we didn't extend beyond the parent window.
112: */
113: boxWidth = MINIMUM (boxWidth, parentWidth);
114: boxHeight = MINIMUM (boxHeight, parentHeight);
115: fieldWidth = (fieldWidth > (boxWidth - mentry->labelLen - 2) ? (boxWidth - mentry->labelLen - 2) : fieldWidth);
116: fieldRows = (fieldRows > (boxHeight - mentry->titleLines - 2) ? (boxHeight - mentry->titleLines - 2) : fieldRows);
117:
118: /* Rejustify the x and y positions if we need to. */
119: alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
120:
121: /* Make the label window. */
122: mentry->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
123:
124: /* Is the window null??? */
125: if (mentry->win == 0)
126: {
127: /* Free up any memory used. */
128: freeChtype (mentry->label);
129: free (mentry);
130:
131: /* Return a null pointer. */
132: return (0);
133: }
134: keypad (mentry->win, TRUE);
135:
136: if (mentry->titleLines > 0)
137: {
138: /* Make the title window. */
139: mentry->titleWin = subwin (mentry->win,
140: mentry->titleLines, boxWidth - 2,
141: ypos + 1, xpos + 1);
142: }
143:
144: /* Create the label window. */
145: if (mentry->label != 0)
146: {
147: mentry->labelWin = subwin (mentry->win, fieldRows, mentry->labelLen,
148: ypos + mentry->titleLines + 1,
149: xpos + horizontalAdjust + 1);
150: }
151:
152: /* Make the field window. */
153: mentry->fieldWin = subwin (mentry->win, fieldRows, fieldWidth,
154: ypos + mentry->titleLines + 1,
155: xpos + mentry->labelLen + horizontalAdjust + 1);
156: keypad (mentry->fieldWin, TRUE);
157:
158: /* Set up the rest of the structure. */
159: mentry->parent = cdkscreen->window;
160: mentry->totalWidth = fieldWidth * logicalRows;
161:
162: /* Create the info char * pointer. */
163: mentry->infoWidth = mentry->totalWidth + 3;
164: mentry->info = (char *)malloc (mentry->infoWidth);
165: cleanChar (mentry->info, mentry->infoWidth, '\0');
166:
167: /* Set up the rest of the widget information. */
168: ScreenOf(mentry) = cdkscreen;
169: mentry->fieldAttr = fieldAttr;
170: mentry->fieldWidth = fieldWidth;
171: mentry->rows = fieldRows;
172: mentry->boxHeight = boxHeight;
173: mentry->boxWidth = boxWidth;
174: mentry->filler = filler;
175: mentry->hidden = filler;
176: ObjOf(mentry)->box = Box;
177: mentry->currentRow = 0;
178: mentry->currentCol = 0;
179: mentry->topRow = 0;
180: mentry->shadow = shadow;
181: mentry->dispType = dispType;
182: mentry->min = min;
183: mentry->logicalRows = logicalRows;
184: mentry->ULChar = ACS_ULCORNER;
185: mentry->URChar = ACS_URCORNER;
186: mentry->LLChar = ACS_LLCORNER;
187: mentry->LRChar = ACS_LRCORNER;
188: mentry->HChar = ACS_HLINE;
189: mentry->VChar = ACS_VLINE;
190: mentry->BoxAttrib = A_NORMAL;
191: mentry->exitType = vNEVER_ACTIVATED;
192: mentry->callbackfn = (void *)&CDKMentryCallBack;
193: mentry->preProcessFunction = 0;
194: mentry->preProcessData = 0;
195: mentry->postProcessFunction = 0;
196: mentry->postProcessData = 0;
197:
198: /* Clean the key bindings. */
199: cleanCDKObjectBindings (vMENTRY, mentry);
200:
201: /* Register this baby. */
202: registerCDKObject (cdkscreen, vMENTRY, mentry);
203:
204: /* Return the pointer to the structure. */
205: return (mentry);
206: }
207:
208: /*
209: * This actually manages the mentry widget...
210: */
211: char *activateCDKMentry (CDKMENTRY *mentry, chtype *actions)
212: {
213: /* Declare local variables. */
214: chtype input = 0;
215: char *ret = 0;
216:
217: /* Draw the mentry widget. */
218: drawCDKMentry (mentry, ObjOf(mentry)->box);
219:
220: /* Check if 'actions' is null. */
221: if (actions == 0)
222: {
223: for (;;)
224: {
225: /* Get the input. */
226: wrefresh (mentry->fieldWin);
227: input = wgetch (mentry->fieldWin);
228:
229: /* Inject this character into the widget. */
230: ret = injectCDKMentry (mentry, input);
231: if (mentry->exitType != vEARLY_EXIT)
232: {
233: return ret;
234: }
235: }
236: }
237: else
238: {
239: int length = chlen (actions);
240: int x;
241:
242: /* Inject each character one at a time. */
243: for (x=0; x < length; x++)
244: {
245: ret = injectCDKMentry (mentry, actions[x]);
246: if (mentry->exitType != vEARLY_EXIT)
247: {
248: return ret;
249: }
250: }
251: }
252:
253: /* Set the exit type and exit. */
254: mentry->exitType = vEARLY_EXIT;
255: return 0;
256: }
257:
258: /*
259: * This injects a character into the widget.
260: */
261: char *injectCDKMentry (CDKMENTRY *mentry, chtype input)
262: {
263: /* Declare local variables. */
264: int cursorPos = ((mentry->currentRow + mentry->topRow) *
265: mentry->fieldWidth) + mentry->currentCol;
266: int ppReturn = 1;
267: int x, infoLength, fieldCharacters;
268: char holder;
269:
270: /* Check if there is a pre-process function to be called. */
271: if (mentry->preProcessFunction != 0)
272: {
273: /* Call the pre-process function. */
274: ppReturn = ((PROCESSFN)(mentry->preProcessFunction)) (vMENTRY, mentry, mentry->preProcessData, input);
275: }
276:
277: /* Should we continue? */
278: if (ppReturn != 0)
279: {
280: /* Check for a key binding... */
281: if (checkCDKObjectBind (vMENTRY, mentry, input) != 0)
282: {
283: mentry->exitType = vESCAPE_HIT;
284: return 0;
285: }
286: else
287: {
288: switch (input)
289: {
290: case CDK_BEGOFLINE :
291: mentry->currentCol = 0;
292: mentry->currentRow = 0;
293: mentry->topRow = 0;
294: break;
295:
296: case CDK_ENDOFLINE :
297: infoLength = (int)strlen(mentry->info);
298: fieldCharacters = mentry->rows * mentry->fieldWidth;
299: if (infoLength < fieldCharacters)
300: {
301: mentry->topRow = 0;
302: mentry->currentRow = infoLength / mentry->fieldWidth;
303: mentry->currentCol = infoLength % mentry->fieldWidth;
304: }
305: else
306: {
307: mentry->topRow = (infoLength / mentry->fieldWidth) - mentry->rows + 1;
308: mentry->currentRow = mentry->rows - 1;
309: mentry->currentCol = infoLength % mentry->fieldWidth;
310: }
311: break;
312:
313: case KEY_LEFT : case CDK_BACKCHAR :
314: if (mentry->currentCol != 0)
315: {
316: mentry->currentCol--;
317: }
318: else
319: {
320: if (mentry->currentRow == 0)
321: {
322: if (mentry->topRow == 0)
323: {
324: Beep();
325: }
326: else
327: {
328: /* Move up one row. */
329: mentry->currentCol = mentry->fieldWidth - 1;
330: mentry->topRow--;
331: }
332: }
333: else
334: {
335: mentry->currentRow--;
336: mentry->currentCol = mentry->fieldWidth - 1;
337: }
338: }
339: break;
340:
341: case KEY_RIGHT : case CDK_FORCHAR :
342: if (mentry->currentCol < (mentry->fieldWidth - 1))
343: {
344: if ((((mentry->topRow + mentry->currentRow) * mentry->fieldWidth) + mentry->currentCol + 1) > (int)strlen (mentry->info)-1)
345: {
346: Beep();
347: }
348: else
349: {
350: mentry->currentCol++;
351: }
352: }
353: else
354: {
355: if (mentry->currentRow == mentry->rows - 1)
356: {
357: if ((mentry->topRow + mentry->currentRow + 1) <= mentry->logicalRows)
358: {
359: mentry->currentCol = 0;
360: mentry->topRow++;
361: }
362: else
363: {
364: Beep();
365: }
366: }
367: else
368: {
369: mentry->currentCol = 0;
370: mentry->currentRow++;
371: }
372: }
373: break;
374:
375: case KEY_DOWN :
376: if (mentry->currentRow != (mentry->rows-1))
377: {
378: if ((((mentry->topRow + mentry->currentRow + 1) * mentry->fieldWidth) + mentry->currentCol) > (int)strlen (mentry->info)-1)
379: {
380: Beep();
381: }
382: else
383: {
384: mentry->currentRow++;
385: }
386: }
387: else
388: {
389: if (mentry->topRow >= mentry->logicalRows - mentry->rows)
390: {
391: Beep();
392: }
393: else
394: {
395: infoLength = (int)strlen(mentry->info);
396: if (((mentry->topRow + mentry->currentRow + 1) * mentry->fieldWidth) > infoLength)
397: {
398: Beep();
399: }
400: else
401: {
402: mentry->topRow++;
403: }
404: }
405: }
406: break;
407:
408: case KEY_UP :
409: if (mentry->currentRow != 0)
410: {
411: mentry->currentRow--;
412: }
413: else
414: {
415: if (mentry->topRow == 0)
416: {
417: Beep();
418: }
419: else
420: {
421: mentry->topRow--;
422: }
423: }
424: break;
425:
426: case DELETE : case KEY_BACKSPACE : case CONTROL('H') : case KEY_DC :
427: if (mentry->dispType == vVIEWONLY)
428: {
429: Beep();
430: }
431: else
432: {
433: infoLength = (int)strlen(mentry->info);
434:
435: /* If there is nothing left to delete, then beep. */
436: if (infoLength == 0)
437: {
438: Beep();
439: }
440: else
441: {
442: /*
443: * Check if the cursor is inside the string or
444: * at the end of the string.
445: */
446: if (cursorPos != infoLength)
447: {
448: /* We are deleting from the middle of the string. */
449: for (x = cursorPos; x < infoLength; x++)
450: {
451: mentry->info[x] = mentry->info[x + 1];
452: }
453: mentry->info[--infoLength] = '\0';
454: }
455: else
456: {
457: /* We are deleting from the end of the string. */
458: mentry->info[--infoLength] = '\0';
459:
460: /* Adjust the currentRow/currentCol vars. */
461: if (mentry->currentCol == 0 &&
462: mentry->currentRow == 0)
463: {
464: if (mentry->topRow == 0)
465: {
466: Beep();
467: }
468: else
469: {
470: /* Bump everything down X lines. */
471: int rows = infoLength / mentry->fieldWidth;
472: int cols = infoLength % mentry->fieldWidth;
473:
474: if (rows < mentry->rows)
475: {
476: mentry->topRow = 0;
477: mentry->currentCol = cols;
478: mentry->currentRow = rows;
479: }
480: else
481: {
482: mentry->topRow -= mentry->rows;
483: mentry->currentRow = mentry->rows-1;
484: mentry->currentCol = cols;
485: }
486: }
487: }
488: else if (mentry->currentCol == 0)
489: {
490: mentry->currentCol = mentry->fieldWidth-1;
491: mentry->currentRow--;
492: }
493: else
494: {
495: mentry->currentCol--;
496: }
497: }
498: }
499: }
500: break;
501:
502: case CDK_TRANSPOSE :
503: infoLength = (int)strlen(mentry->info);
504: if (cursorPos >= infoLength-1)
505: {
506: Beep();
507: }
508: else
509: {
510: holder = mentry->info[cursorPos];
511: mentry->info[cursorPos] = mentry->info[cursorPos + 1];
512: mentry->info[cursorPos + 1] = holder;
513: }
514: break;
515:
516: case CDK_ERASE :
517: infoLength = (int)strlen(mentry->info);
518: if (infoLength != 0)
519: {
520: cleanCDKMentry (mentry);
521: }
522: break;
523:
524: case CDK_CUT:
525: infoLength = (int)strlen(mentry->info);
526: if (infoLength != 0)
527: {
528: freeChar (GPasteBuffer);
529: GPasteBuffer = copyChar (mentry->info);
530: cleanCDKMentry (mentry);
531: }
532: else
533: {
534: Beep();
535: }
536: break;
537:
538: case CDK_COPY:
539: infoLength = (int)strlen(mentry->info);
540: if (infoLength != 0)
541: {
542: freeChar (GPasteBuffer);
543: GPasteBuffer = copyChar (mentry->info);
544: }
545: else
546: {
547: Beep();
548: }
549: break;
550:
551: case CDK_PASTE:
552: if (GPasteBuffer != 0)
553: {
554: setCDKMentryValue (mentry, GPasteBuffer);
555: }
556: else
557: {
558: Beep();
559: }
560: break;
561:
562: case KEY_RETURN : case KEY_TAB : case KEY_ENTER :
563: infoLength = (int)strlen(mentry->info);
564: if (infoLength < mentry->min + 1)
565: {
566: Beep();
567: }
568: else
569: {
570: mentry->exitType = vNORMAL;
571: return (mentry->info);
572: }
573: break;
574:
575: case KEY_ESC :
576: mentry->exitType = vESCAPE_HIT;
577: return 0;
578:
579: case CDK_REFRESH :
580: eraseCDKScreen (ScreenOf(mentry));
581: refreshCDKScreen (ScreenOf(mentry));
582: break;
583:
584: default :
585: ((MENTRYCB)mentry->callbackfn)(mentry, input);
586: break;
587: }
588: }
589:
590: /* Should we do a post-process? */
591: if (mentry->postProcessFunction != 0)
592: {
593: ((PROCESSFN)(mentry->postProcessFunction)) (vMENTRY, mentry, mentry->postProcessData, input);
594: }
595: }
596:
597: /* Refresh the field. */
598: drawCDKMentryField (mentry);
599:
600: /* Set the exit type and return. */
601: mentry->exitType = vEARLY_EXIT;
602: return 0;
603: }
604:
605: /*
606: * This moves the mentry field to the given location.
607: */
608: static void _moveCDKMentry (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
609: {
610: CDKMENTRY *mentry = (CDKMENTRY *)object;
611:
612: /*
613: * If this is a relative move, then we will adjust where we want
614: * to move to.
615: */
616: if (relative)
617: {
618: xplace += getbegx(mentry->win);
619: yplace += getbegy(mentry->win);
620: }
621:
622: /* Adjust the window if we need to. */
623: alignxy (WindowOf(mentry), &xplace, &yplace, mentry->boxWidth, mentry->boxHeight);
624:
625: /* Move the window to the new location. */
626: moveCursesWindow(mentry->win, xplace, yplace);
627:
628: /* Redraw the window, if they asked for it. */
629: if (refresh_flag)
630: {
631: drawCDKMentry (mentry, ObjOf(mentry)->box);
632: }
633: }
634:
635: /*
636: * This function redraws the multiple line entry field.
637: */
638: void drawCDKMentryField (CDKMENTRY *mentry)
639: {
640: /* Declare local variables. */
641: int currchar = (mentry->fieldWidth * mentry->topRow);
642: int length = 0;
643: int lastpos = 0;
644: int x, y;
645:
646: /* Check the value of info. */
647: if (mentry->info == 0)
648: {
649: return;
650: }
651:
652: /* The information isn't null, redraw the field. */
653: length = (int)strlen (mentry->info);
654: lastpos = ((chtype)mentry->info[length] == (chtype)mentry->filler ? length-1 : length);
655:
656: /* Start redrawing the fields. */
657: for (x=0; x < mentry->rows; x++)
658: {
659: for (y=0; y < mentry->fieldWidth ; y++)
660: {
661: if (currchar < lastpos)
662: {
663: if (mentry->dispType == vHCHAR ||
664: mentry->dispType == vHINT ||
665: mentry->dispType == vHMIXED ||
666: mentry->dispType == vUHCHAR ||
667: mentry->dispType == vLHCHAR ||
668: mentry->dispType == vUHMIXED ||
669: mentry->dispType == vLHMIXED)
670: {
671: mvwaddch (mentry->fieldWin, x, y, mentry->filler);
672: }
673: else
674: {
675: mvwaddch (mentry->fieldWin, x, y,
676: (mentry->info[currchar++] & A_CHARTEXT) | mentry->fieldAttr);
677: }
678: }
679: else
680: {
681: mvwaddch (mentry->fieldWin, x, y, mentry->filler);
682: }
683: }
684: }
685:
686: /* Refresh the screen. */
687: wmove (mentry->fieldWin, mentry->currentRow, mentry->currentCol);
688: wnoutrefresh (mentry->fieldWin);
689: wnoutrefresh (mentry->win);
690: }
691:
692: /*
693: * This is a generic character parser for the mentry field. It is used as a
694: * callback function, so any personal modifications can be made by creating
695: * a new function and calling that one the mentry activation.
696: */
697: static void CDKMentryCallBack (CDKMENTRY *mentry, chtype character)
698: {
699: /* Declare local variables. */
700: int cursorPos = ((mentry->currentRow + mentry->topRow) *
701: mentry->fieldWidth) + mentry->currentCol;
702: int infoLength = (int)strlen (mentry->info);
703: char plainchar = (character & A_CHARTEXT);
704: int x;
705:
706: /* Check the type of character we are looking for. */
707: if ((mentry->dispType == vINT ||
708: mentry->dispType == vHINT) &&
709: !isdigit((int)plainchar))
710: {
711: Beep();
712: }
713: else if ((mentry->dispType == vCHAR ||
714: mentry->dispType == vUCHAR ||
715: mentry->dispType == vLCHAR ||
716: mentry->dispType == vUHCHAR ||
717: mentry->dispType == vLHCHAR) &&
718: isdigit((int)plainchar))
719: {
720: Beep();
721: }
722: else if (mentry->dispType == vVIEWONLY)
723: {
724: Beep();
725: }
726: else
727: {
728: if ((int)strlen (mentry->info) == mentry->totalWidth)
729: {
730: Beep();
731: }
732: else
733: {
734: /* We will make any adjustments to the case of the character. */
735: if ((mentry->dispType == vUCHAR ||
736: mentry->dispType == vUHCHAR ||
737: mentry->dispType == vUMIXED ||
738: mentry->dispType == vUHMIXED) &&
739: !isdigit((int)plainchar))
740: {
741: plainchar = toupper (plainchar);
742: }
743: else if ((mentry->dispType == vLCHAR ||
744: mentry->dispType == vLHCHAR ||
745: mentry->dispType == vLMIXED ||
746: mentry->dispType == vLHMIXED) &&
747: !isdigit((int)plainchar))
748: {
749: plainchar = tolower (plainchar);
750: }
751:
752: /*
753: * Check if we are adding onto the end or we are adding
754: * into the middle?
755: */
756: if (cursorPos != infoLength-1)
757: {
758: /* We are adding in the middle of the string. */
759: for (x = infoLength + 1; x > cursorPos; x--)
760: {
761: mentry->info[x] = mentry->info[x-1];
762: }
763: mentry->info[cursorPos] = plainchar;
764: mentry->currentCol++;
765: }
766: else
767: {
768: /* We are adding onto the end of the string. */
769: mentry->info[infoLength-1] = plainchar;
770: mentry->info[infoLength] = mentry->filler;
771:
772: /* Add the character on the screen */
773: if (mentry->dispType == vHCHAR ||
774: mentry->dispType == vHINT ||
775: mentry->dispType == vHMIXED ||
776: mentry->dispType == vUHCHAR ||
777: mentry->dispType == vLHCHAR ||
778: mentry->dispType == vUHMIXED ||
779: mentry->dispType == vLHMIXED)
780: {
781: mvwaddch (mentry->fieldWin,
782: mentry->currentRow,
783: mentry->currentCol++,
784: mentry->filler);
785: }
786: else
787: {
788: mvwaddch (mentry->fieldWin,
789: mentry->currentRow,
790: mentry->currentCol++,
791: plainchar|mentry->fieldAttr);
792: }
793: }
794:
795: /* Have we gone out of bounds. */
796: if (mentry->currentCol == mentry->fieldWidth)
797: {
798: /* Update the row and col values. */
799: mentry->currentCol = 0;
800: mentry->currentRow++;
801:
802: /*
803: * If we have gone outside of the visual boundries, we
804: * need to scroll the window.
805: */
806: if (mentry->currentRow == mentry->rows)
807: {
808: /* We have to redraw the screen. */
809: mentry->currentRow--;
810: mentry->topRow++;
811: drawCDKMentryField (mentry);
812: }
813: }
814: }
815: }
816: }
817:
818: /*
819: * This function draws the multiple line entry field.
820: */
821: static void _drawCDKMentry (CDKOBJS *object, boolean Box)
822: {
823: CDKMENTRY *mentry = (CDKMENTRY *)object;
824: int x;
825:
826: /* Box the widget if asked. */
827: if (Box)
828: {
829: attrbox (mentry->win,
830: mentry->ULChar, mentry->URChar,
831: mentry->LLChar, mentry->LRChar,
832: mentry->HChar, mentry->VChar,
833: mentry->BoxAttrib,
834: mentry->shadow);
835: }
836:
837: if (mentry->titleLines > 0)
838: {
839: /* Draw in the title if there is one. */
840: for (x=0; x < mentry->titleLines; x++)
841: {
842: writeChtype (mentry->titleWin,
843: mentry->titlePos[x], x,
844: mentry->title[x],
845: HORIZONTAL, 0,
846: mentry->titleLen[x]);
847: }
848: wnoutrefresh (mentry->titleWin);
849: }
850:
851: /* Draw in the label to the widget. */
852: if (mentry->label != 0)
853: {
854: writeChtype (mentry->labelWin, 0, 0,
855: mentry->label,
856: HORIZONTAL, 0,
857: mentry->labelLen);
858: wnoutrefresh (mentry->labelWin);
859: }
860:
861: /* Draw the mentry field. */
862: drawCDKMentryField (mentry);
863: }
864:
865: /*
866: * These functions set the drawing characters of the widget.
867: */
868: void setCDKMentryULChar (CDKMENTRY *mentry, chtype character)
869: {
870: mentry->ULChar = character;
871: }
872: void setCDKMentryURChar (CDKMENTRY *mentry, chtype character)
873: {
874: mentry->URChar = character;
875: }
876: void setCDKMentryLLChar (CDKMENTRY *mentry, chtype character)
877: {
878: mentry->LLChar = character;
879: }
880: void setCDKMentryLRChar (CDKMENTRY *mentry, chtype character)
881: {
882: mentry->LRChar = character;
883: }
884: void setCDKMentryVerticalChar (CDKMENTRY *mentry, chtype character)
885: {
886: mentry->VChar = character;
887: }
888: void setCDKMentryHorizontalChar (CDKMENTRY *mentry, chtype character)
889: {
890: mentry->HChar = character;
891: }
892: void setCDKMentryBoxAttribute (CDKMENTRY *mentry, chtype character)
893: {
894: mentry->BoxAttrib = character;
895: }
896:
897: /*
898: * This sets the background color of the widget.
899: */
900: void setCDKMentryBackgroundColor (CDKMENTRY *mentry, char *color)
901: {
902: chtype *holder = 0;
903: int junk1, junk2;
904:
905: /* Make sure the color isn't null. */
906: if (color == 0)
907: {
908: return;
909: }
910:
911: /* Convert the value of the environment variable to a chtype. */
912: holder = char2Chtype (color, &junk1, &junk2);
913:
914: /* Set the widgets background color. */
915: wbkgd (mentry->win, holder[0]);
916: wbkgd (mentry->fieldWin, holder[0]);
917: if (mentry->label != 0)
918: {
919: wbkgd (mentry->labelWin, holder[0]);
920: }
921:
922: /* Clean up. */
923: freeChtype (holder);
924: }
925:
926: /*
927: * This function erases the multiple line entry field from the screen.
928: */
929: static void _eraseCDKMentry (CDKOBJS *object)
930: {
931: CDKMENTRY *mentry = (CDKMENTRY *)object;
932:
933: eraseCursesWindow (mentry->win);
934: }
935:
936: /*
937: * This function destroys a multiple line entry field widget.
938: */
939: void destroyCDKMentry (CDKMENTRY *mentry)
940: {
941: int x;
942:
943: /* Erase the object. */
944: eraseCDKMentry (mentry);
945:
946: /* Clean up the char pointers. */
947: for (x=0; x < mentry->titleLines; x++)
948: {
949: freeChtype (mentry->title[x]);
950: }
951: freeChtype (mentry->label);
952: freeChar (mentry->info);
953:
954: /* Clean up the windows. */
955: deleteCursesWindow (mentry->win);
956:
957: /* Unregister this object. */
958: unregisterCDKObject (vMENTRY, mentry);
959:
960: /* Finish cleaning up. */
961: free (mentry);
962: }
963:
964: /*
965: * This sets multiple attributes of the widget.
966: */
967: void setCDKMentry (CDKMENTRY *mentry, char *value, int min, boolean Box)
968: {
969: setCDKMentryValue (mentry, value);
970: setCDKMentryMin (mentry, min);
971: setCDKMentryBox (mentry, Box);
972: }
973:
974: /*
975: * This removes the old information in the entry field and keeps the
976: * new information given.
977: */
978: void setCDKMentryValue (CDKMENTRY *mentry, char *newValue)
979: {
980: /* Declare local variables. */
981: int fieldCharacters = mentry->rows * mentry->fieldWidth;
982: int len = 0;
983: int rowsUsed;
984:
985: /* Just to be sure, if lets make sure the new value isn't null. */
986: if (newValue == 0)
987: {
988: /* Then we want to just erase the old value. */
989: cleanChar (mentry->info, mentry->infoWidth, '\0');
990: return;
991: }
992:
993: /* Determine how many characters we need to copy. */
994: len = (int)strlen (newValue);
995:
996: /* OK, erase the old value, and copy in the new value. */
997: cleanChar (mentry->info, mentry->infoWidth, '\0');
998: strncpy (mentry->info, newValue, mentry->infoWidth);
999:
1000: /* Set the cursor/row info. */
1001: if (len < fieldCharacters)
1002: {
1003: mentry->topRow = 0;
1004: mentry->currentRow = len / mentry->fieldWidth;
1005: mentry->currentCol = len % mentry->fieldWidth;
1006: }
1007: else
1008: {
1009: rowsUsed = len / mentry->fieldWidth;
1010: mentry->topRow = rowsUsed - mentry->rows + 1;
1011: mentry->currentRow = mentry->rows - 1;
1012: mentry->currentCol = len % mentry->fieldWidth;
1013: }
1014:
1015: /* Redraw the widget. */
1016: drawCDKMentryField (mentry);
1017: }
1018: char *getCDKMentryValue (CDKMENTRY *mentry)
1019: {
1020: return mentry->info;
1021: }
1022:
1023: /*
1024: * This sets the filler character to use when drawing the widget.
1025: */
1026: void setCDKMentryFillerChar (CDKMENTRY *mentry, chtype filler)
1027: {
1028: mentry->filler = filler;
1029: }
1030: chtype getCDKMentryFillerChar (CDKMENTRY *mentry)
1031: {
1032: return mentry->filler;
1033: }
1034:
1035: /*
1036: * This sets the character to use when a hidden character type is used.
1037: */
1038: void setCDKMentryHiddenChar (CDKMENTRY *mentry, chtype character)
1039: {
1040: mentry->hidden = character;
1041: }
1042: chtype getCDKMentryHiddenChar (CDKMENTRY *mentry)
1043: {
1044: return mentry->hidden;
1045: }
1046:
1047: /*
1048: * This sets the minimum length of the widget.
1049: */
1050: void setCDKMentryMin (CDKMENTRY *mentry, int min)
1051: {
1052: mentry->min = min;
1053: }
1054: int getCDKMentryMin (CDKMENTRY *mentry)
1055: {
1056: return mentry->min;
1057: }
1058:
1059: /*
1060: * This sets the widgets box attribute.
1061: */
1062: void setCDKMentryBox (CDKMENTRY *mentry, boolean Box)
1063: {
1064: ObjOf(mentry)->box = Box;
1065: }
1066: boolean getCDKMentryBox (CDKMENTRY *mentry)
1067: {
1068: return ObjOf(mentry)->box;
1069: }
1070:
1071: /*
1072: * This erases the information in the multiple line entry widget.
1073: */
1074: void cleanCDKMentry (CDKMENTRY *mentry)
1075: {
1076: /* Erase the information in the character pointer. */
1077: cleanChar (mentry->info, mentry->infoWidth, '\0');
1078:
1079: mentry->currentRow = 0;
1080: mentry->currentCol = 0;
1081: mentry->topRow = 0;
1082: }
1083:
1084: /*
1085: * This sets the callback function.
1086: */
1087: void setCDKMentryCB (CDKMENTRY *mentry, MENTRYCB callback)
1088: {
1089: mentry->callbackfn = (void *)callback;
1090: }
1091:
1092: /*
1093: * This function sets the pre-process function.
1094: */
1095: void setCDKMentryPreProcess (CDKMENTRY *mentry, PROCESSFN callback, void *data)
1096: {
1097: mentry->preProcessFunction = callback;
1098: mentry->preProcessData = data;
1099: }
1100:
1101: /*
1102: * This function sets the post-process function.
1103: */
1104: void setCDKMentryPostProcess (CDKMENTRY *mentry, PROCESSFN callback, void *data)
1105: {
1106: mentry->postProcessFunction = callback;
1107: mentry->postProcessData = data;
1108: }
CVSweb <webmaster@jp.NetBSD.org>