Annotation of othersrc/dist/cdk/slider.c, revision 1.2
1.1 garbled 1: #include <cdk.h>
2:
3: /*
1.2 ! garbled 4: * $Author: garbled $
! 5: * $Date: 2001/01/04 19:58:41 $
! 6: * $Revision: 1.1.1.1 $
1.1 garbled 7: */
8:
9: /*
10: * Declare file local prototypes.
11: */
12: static void drawCDKSliderField (CDKSLIDER *slider);
13:
14: DeclareCDKObjects(my_funcs,Slider);
15:
16: /*
17: * This function creates a slider widget.
18: */
19: CDKSLIDER *newCDKSlider (CDKSCREEN *cdkscreen, int xplace, int yplace, char *title, char *label, chtype filler, int fieldWidth, int start, int low, int high, int inc, int fastInc, boolean Box, boolean shadow)
20: {
21: /* Declare local variables. */
22: CDKSLIDER *slider = newCDKObject(CDKSLIDER, &my_funcs);
23: chtype *holder = 0;
24: int parentWidth = getmaxx(cdkscreen->window);
25: int parentHeight = getmaxy(cdkscreen->window);
26: int boxHeight = 3;
27: int boxWidth = 0;
28: int maxWidth = INT_MIN;
29: int horizontalAdjust = 0;
30: int xpos = xplace;
31: int ypos = yplace;
32: int highValueLen = intlen (high);
33: char **temp = 0;
34: int x, len, junk, junk2;
35:
36: /* Set some basic values of the slider field. */
37: slider->label = 0;
38: slider->labelLen = 0;
39: slider->labelWin = 0;
40: slider->titleLines = 0;
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: /* Translate the label char *pointer to a chtype pointer. */
50: boxWidth = fieldWidth + highValueLen + 2;
51: if (label != 0)
52: {
53: slider->label = char2Chtype (label, &slider->labelLen, &junk);
54: boxWidth += slider->labelLen;
55: }
56:
57: /* Translate the char * items to chtype * */
58: if (title != 0)
59: {
60: temp = CDKsplitString (title, '\n');
61: slider->titleLines = CDKcountStrings (temp);
62:
63: /* We need to determine the widest title line. */
64: for (x=0; x < slider->titleLines; x++)
65: {
66: holder = char2Chtype (temp[x], &len, &junk2);
67: maxWidth = MAXIMUM (maxWidth, len);
68: freeChtype (holder);
69: }
70:
71: /*
72: * If one of the title lines is wider than the field and the label,
73: * the box width will expand to accomodate.
74: */
75: if (maxWidth > boxWidth)
76: {
77: horizontalAdjust = (int)((maxWidth - boxWidth) / 2) + 1;
78: boxWidth = maxWidth + 2;
79: }
80:
81: /* For each line in the title, convert from char * to chtype * */
82: for (x=0; x < slider->titleLines; x++)
83: {
84: slider->title[x] = char2Chtype (temp[x], &slider->titleLen[x], &slider->titlePos[x]);
85: slider->titlePos[x] = justifyString (boxWidth - 2, slider->titleLen[x], slider->titlePos[x]);
86: }
87:
88: CDKfreeStrings(temp);
89: }
90: else
91: {
92: /* No title? Set the required variables. */
93: slider->titleLines = 0;
94: }
95: boxHeight += slider->titleLines;
96:
97: /*
98: * Make sure we didn't extend beyond the dimensions of the window.
99: */
100: boxWidth = MINIMUM (boxWidth, parentWidth);
101: boxHeight = MINIMUM (boxHeight, parentHeight);
102: fieldWidth = (fieldWidth > (boxWidth-slider->labelLen-highValueLen-2) ? (boxWidth-slider->labelLen-highValueLen-2) : fieldWidth);
103:
104: /* Rejustify the x and y positions if we need to. */
105: alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
106:
107: /* Make the slider window. */
108: slider->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
109:
110: /* Is the main window null??? */
111: if (slider->win == 0)
112: {
113: freeChtype (slider->label);
114: free (slider);
115:
116: /* Return a null pointer. */
117: return (0);
118: }
119: keypad (slider->win, TRUE);
120: leaveok (slider->win, TRUE);
121:
122: if (slider->titleLines > 0)
123: {
124: /* Make the title window. */
125: slider->titleWin = subwin (slider->win,
126: slider->titleLines, boxWidth - 2,
127: ypos + 1, xpos + 1);
128: }
129:
130: /* Create the slider label window. */
131: if (slider->label != 0)
132: {
133: slider->labelWin = subwin (slider->win, 1,
134: slider->labelLen,
135: ypos + slider->titleLines + 1,
136: xpos + horizontalAdjust + 1);
137: }
138:
139: /* Create the slider field window. */
140: slider->fieldWin = subwin (slider->win, 1, fieldWidth + highValueLen,
141: ypos + slider->titleLines + 1,
142: xpos + slider->labelLen + horizontalAdjust + 1);
143:
144: /* Create the slider field. */
145: ScreenOf(slider) = cdkscreen;
146: slider->parent = cdkscreen->window;
147: slider->boxWidth = boxWidth;
148: slider->boxHeight = boxHeight;
149: slider->fieldWidth = fieldWidth;
150: slider->filler = filler;
151: slider->low = low;
152: slider->high = high;
153: slider->current = start;
154: slider->inc = inc;
155: slider->fastinc = fastInc;
156: slider->exitType = vNEVER_ACTIVATED;
157: ObjOf(slider)->box = Box;
158: slider->shadow = shadow;
159: slider->preProcessFunction = 0;
160: slider->preProcessData = 0;
161: slider->postProcessFunction = 0;
162: slider->postProcessData = 0;
163: slider->ULChar = ACS_ULCORNER;
164: slider->URChar = ACS_URCORNER;
165: slider->LLChar = ACS_LLCORNER;
166: slider->LRChar = ACS_LRCORNER;
167: slider->HChar = ACS_HLINE;
168: slider->VChar = ACS_VLINE;
169: slider->BoxAttrib = A_NORMAL;
170:
171: /* Determine the step value. */
172: slider->step = (float)((float)slider->fieldWidth/(float)(high-low));
173:
174: /* Set the start value. */
175: if (start < low)
176: {
177: slider->current = low;
178: }
179:
180: /* Clean the key bindings. */
181: cleanCDKObjectBindings (vSLIDER, slider);
182:
183: /* Register this baby. */
184: registerCDKObject (cdkscreen, vSLIDER, slider);
185:
186: /* Return the pointer. */
187: return (slider);
188: }
189:
190: /*
191: * This allows the person to use the slider field.
192: */
193: int activateCDKSlider (CDKSLIDER *slider, chtype *actions)
194: {
195: /* Declare local variables. */
196: int ret;
197:
198: /* Draw the slider widget. */
199: drawCDKSlider (slider, ObjOf(slider)->box);
200:
201: /* Check if actions is null. */
202: if (actions == 0)
203: {
204: chtype input = 0;
205: for (;;)
206: {
207: /* Get the input. */
208: wrefresh (slider->win);
209: input = wgetch (slider->win);
210:
211: /* Inject the character into the widget. */
212: ret = injectCDKSlider (slider, input);
213: if (slider->exitType != vEARLY_EXIT)
214: {
215: return ret;
216: }
217: }
218: }
219: else
220: {
221: int length = chlen (actions);
222: int x = 0;
223:
224: /* Inject each character one at a time. */
225: for (x=0; x < length; x++)
226: {
227: ret = injectCDKSlider (slider, actions[x]);
228: if (slider->exitType != vEARLY_EXIT)
229: {
230: return ret;
231: }
232: }
233: }
234:
235: /* Set the exit type and return. */
236: slider->exitType = vEARLY_EXIT;
237: return -1;
238: }
239:
240: /*
241: * This function injects a single character into the widget.
242: */
243: int injectCDKSlider (CDKSLIDER *slider, chtype input)
244: {
245: /* Declare some local variables. */
246: int ppReturn = 1;
247:
248: /* Set the exit type. */
249: slider->exitType = vEARLY_EXIT;
250:
251: /* Draw the field. */
252: drawCDKSliderField (slider);
253:
254: /* Check if there is a pre-process function to be called. */
255: if (slider->preProcessFunction != 0)
256: {
257: /* Call the pre-process function. */
258: ppReturn = ((PROCESSFN)(slider->preProcessFunction)) (vSLIDER, slider, slider->preProcessData, input);
259: }
260:
261: /* Should we continue? */
262: if (ppReturn != 0)
263: {
264: /* Check for a key binding. */
265: if (checkCDKObjectBind(vSLIDER, slider, input) != 0)
266: {
267: slider->exitType = vESCAPE_HIT;
268: return -1;
269: }
270: else
271: {
272: switch (input)
273: {
274: case KEY_LEFT : case 'd' : case '-' : case KEY_DOWN :
275: if (slider->current > slider->low)
276: {
277: slider->current -= slider->inc;
278: }
279: else
280: {
281: Beep();
282: }
283: break;
284:
285: case KEY_RIGHT : case 'u' : case '+' : case KEY_UP :
286: if (slider->current < slider->high)
287: {
288: slider->current += slider->inc;
289: }
290: else
291: {
292: Beep();
293: }
294: break;
295:
296: case KEY_PPAGE : case 'U' : case CONTROL('B') :
297: if ((slider->current + slider->fastinc) <= slider->high)
298: {
299: slider->current += slider->fastinc;
300: }
301: else
302: {
303: Beep();
304: }
305: break;
306:
307: case KEY_NPAGE : case 'D' : case CONTROL('F') :
308: if ((slider->current - slider->fastinc) >= slider->low)
309: {
310: slider->current -= slider->fastinc;
311: }
312: else
313: {
314: Beep();
315: }
316: break;
317:
318: case KEY_HOME : case 'g' : case '0' :
319: slider->current = slider->low;
320: break;
321:
322: case KEY_END : case 'G' : case '$' :
323: slider->current = slider->high;
324: break;
325:
326: case KEY_ESC :
327: slider->exitType = vESCAPE_HIT;
328: return -1;
329:
1.2 ! garbled 330: case KEY_RETURN : case KEY_TAB : case KEY_ENTER : case KEY_CR :
1.1 garbled 331: slider->exitType = vNORMAL;
332: return (slider->current);
333:
334: case CDK_REFRESH :
335: eraseCDKScreen (ScreenOf(slider));
336: refreshCDKScreen (ScreenOf(slider));
337: break;
338:
339: default :
340: Beep();
341: break;
342: }
343: }
344:
345: /* Should we call a post-process? */
346: if (slider->postProcessFunction != 0)
347: {
348: ((PROCESSFN)(slider->postProcessFunction)) (vSLIDER, slider, slider->postProcessData, input);
349: }
350: }
351:
352: /* Draw the field window. */
353: drawCDKSliderField (slider);
354:
355: /* Set the exit type and return. */
356: slider->exitType = vEARLY_EXIT;
357: return -1;
358: }
359:
360: /*
361: * This moves the slider field to the given location.
362: */
363: static void _moveCDKSlider (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
364: {
365: CDKSLIDER *slider = (CDKSLIDER *)object;
366:
367: /*
368: * If this is a relative move, then we will adjust where we want
369: * to move to.
370: */
371: if (relative)
372: {
373: xplace += getbegx(slider->win);
374: yplace += getbegy(slider->win);
375: }
376:
377: /* Adjust the window if we need to. */
378: alignxy (WindowOf(slider), &xplace, &yplace, slider->boxWidth, slider->boxHeight);
379:
380: /* Move the window to the new location. */
381: moveCursesWindow(slider->win, xplace, yplace);
382:
383: /* Redraw the window, if they asked for it. */
384: if (refresh_flag)
385: {
386: drawCDKSlider (slider, ObjOf(slider)->box);
387: }
388: }
389:
390: /*
391: * This function draws the slider widget.
392: */
393: static void _drawCDKSlider (CDKOBJS *object, boolean Box)
394: {
395: CDKSLIDER *slider = (CDKSLIDER *)object;
396: int x;
397:
398: /* Box the widget if asked. */
399: if (Box)
400: {
401: attrbox (slider->win,
402: slider->ULChar, slider->URChar,
403: slider->LLChar, slider->LRChar,
404: slider->HChar, slider->VChar,
405: slider->BoxAttrib,
406: slider->shadow);
407: }
408:
409: if (slider->titleLines > 0)
410: {
411: /* Draw in the title if there is one. */
412: for (x=0; x < slider->titleLines; x++)
413: {
414: writeChtype (slider->titleWin,
415: slider->titlePos[x], x,
416: slider->title[x],
417: HORIZONTAL, 0,
418: slider->titleLen[x]);
419: }
420: }
421:
422: /* Draw the label. */
423: if (slider->label != 0)
424: {
425: writeChtype (slider->labelWin, 0, 0,
426: slider->label,
427: HORIZONTAL, 0,
428: slider->labelLen);
429: wnoutrefresh (slider->labelWin);
430: }
431:
432: /* Draw the field window. */
433: drawCDKSliderField (slider);
434: }
435:
436: /*
437: * This draws the slider widget.
438: */
439: static void drawCDKSliderField (CDKSLIDER *slider)
440: {
441: /* Declare the local variables. */
442: int fillerCharacters, len;
443: char temp[256];
444:
445: /* Determine how many filler characters need to be drawn. */
446: fillerCharacters = (int)((slider->current-slider->low) * slider->step);
447:
448: /* Empty the field. */
449: werase (slider->fieldWin);
450:
451: /* Add the character to the window. */
452: mvwhline (slider->fieldWin, 0, 0, slider->filler, fillerCharacters);
453:
454: /* Draw the value in the field. */
455: sprintf (temp, "%d", slider->current);
456: len = (int)strlen(temp);
457: writeCharAttrib (slider->fieldWin,
458: slider->fieldWidth, 0, temp,
459: A_NORMAL,
460: HORIZONTAL, 0,
461: len);
462:
463: /* Refresh the field window. */
464: wnoutrefresh (slider->fieldWin);
465: wnoutrefresh (slider->win);
466: }
467:
468: /*
469: * These functions set the drawing characters of the widget.
470: */
471: void setCDKSliderULChar (CDKSLIDER *slider, chtype character)
472: {
473: slider->ULChar = character;
474: }
475: void setCDKSliderURChar (CDKSLIDER *slider, chtype character)
476: {
477: slider->URChar = character;
478: }
479: void setCDKSliderLLChar (CDKSLIDER *slider, chtype character)
480: {
481: slider->LLChar = character;
482: }
483: void setCDKSliderLRChar (CDKSLIDER *slider, chtype character)
484: {
485: slider->LRChar = character;
486: }
487: void setCDKSliderVerticalChar (CDKSLIDER *slider, chtype character)
488: {
489: slider->VChar = character;
490: }
491: void setCDKSliderHorizontalChar (CDKSLIDER *slider, chtype character)
492: {
493: slider->HChar = character;
494: }
495: void setCDKSliderBoxAttribute (CDKSLIDER *slider, chtype character)
496: {
497: slider->BoxAttrib = character;
498: }
499:
500: /*
501: * This sets the background color of the widget.
502: */
503: void setCDKSliderBackgroundColor (CDKSLIDER *slider, char *color)
504: {
505: chtype *holder = 0;
506: int junk1, junk2;
507:
508: /* Make sure the color isn't null. */
509: if (color == 0)
510: {
511: return;
512: }
513:
514: /* Convert the value of the environment variable to a chtype. */
515: holder = char2Chtype (color, &junk1, &junk2);
516:
517: /* Set the widgets background color. */
518: wbkgd (slider->win, holder[0]);
519: wbkgd (slider->fieldWin, holder[0]);
520: if (slider->label != 0)
521: {
522: wbkgd (slider->labelWin, holder[0]);
523: }
524:
525: /* Clean up. */
526: freeChtype (holder);
527: }
528:
529: /*
530: * This function destroys the slider widget.
531: */
532: void destroyCDKSlider (CDKSLIDER *slider)
533: {
534: int x;
535:
536: /* Erase the object. */
537: eraseCDKSlider (slider);
538:
539: /* Clean up the char pointers. */
540: freeChtype (slider->label);
541: for (x=0; x < slider->titleLines; x++)
542: {
543: freeChtype (slider->title[x]);
544: }
545:
546: /* Clean up the windows. */
547: deleteCursesWindow (slider->win);
548:
549: /* Unregister this object. */
550: unregisterCDKObject (vSLIDER, slider);
551:
552: /* Finish cleaning up. */
553: free (slider);
554: }
555:
556: /*
557: * This function erases the slider widget from the screen.
558: */
559: static void _eraseCDKSlider (CDKOBJS *object)
560: {
561: CDKSLIDER *slider = (CDKSLIDER *)object;
562:
563: eraseCursesWindow (slider->win);
564: }
565:
566: /*
567: * This function sets the low/high/current values of the slider widget.
568: */
569: void setCDKSlider (CDKSLIDER *slider, int low, int high, int value, boolean Box)
570: {
571: setCDKSliderLowHigh (slider, low, high);
572: setCDKSliderValue (slider, value);
573: setCDKSliderBox (slider, Box);
574: }
575:
576: /*
577: * This function sets the low/high/current value of the widget.
578: */
579: void setCDKSliderValue (CDKSLIDER *slider, int value)
580: {
581: slider->current = value;
582: }
583: int getCDKSliderValue (CDKSLIDER *slider)
584: {
585: return slider->current;
586: }
587:
588: /*
589: * This function sets the low/high values of the widget.
590: */
591: void setCDKSliderLowHigh (CDKSLIDER *slider, int low, int high)
592: {
593: /* Make sure the values aren't out of bounds. */
594: if (low <= high)
595: {
596: slider->low = low;
597: slider->high = high;
598: }
599: else if (low > high)
600: {
601: slider->low = high;
602: slider->high = low;
603: }
604:
605: /* Make sure the user hasn't done something silly. */
606: if (slider->current < low)
607: {
608: slider->current = low;
609: }
610: if (slider->current > high)
611: {
612: slider->current = high;
613: }
614:
615: /* Determine the step value. */
616: slider->step = (float)((float)slider->fieldWidth / (float)(high-low));
617: }
618: int getCDKSliderLowValue (CDKSLIDER *slider)
619: {
620: return slider->low;
621: }
622: int getCDKSliderHighValue (CDKSLIDER *slider)
623: {
624: return slider->high;
625: }
626:
627: /*
628: * This sets the box attribute of the slider widget.
629: */
630: void setCDKSliderBox (CDKSLIDER *slider, boolean Box)
631: {
632: ObjOf(slider)->box = Box;
633: }
634: boolean getCDKSliderBox (CDKSLIDER *slider)
635: {
636: return ObjOf(slider)->box;
637: }
638:
639: /*
640: * This function sets the pre-process function.
641: */
642: void setCDKSliderPreProcess (CDKSLIDER *slider, PROCESSFN callback, void *data)
643: {
644: slider->preProcessFunction = callback;
645: slider->preProcessData = data;
646: }
647:
648: /*
649: * This function sets the post-process function.
650: */
651: void setCDKSliderPostProcess (CDKSLIDER *slider, PROCESSFN callback, void *data)
652: {
653: slider->postProcessFunction = callback;
654: slider->postProcessData = data;
655: }
CVSweb <webmaster@jp.NetBSD.org>