1 #include <cdk_int.h>
2
3 /*
4 * $Author: tom $
5 * $Date: 2016/11/20 19:12:46 $
6 * $Revision: 1.92 $
7 */
8
9 DeclareCDKObjects (HISTOGRAM, Histogram, setCdk, Unknown);
10
11 /*
12 * Create a histogram widget.
13 */
newCDKHistogram(CDKSCREEN * cdkscreen,int xplace,int yplace,int height,int width,int orient,const char * title,boolean Box,boolean shadow)14 CDKHISTOGRAM *newCDKHistogram (CDKSCREEN *cdkscreen,
15 int xplace,
16 int yplace,
17 int height,
18 int width,
19 int orient,
20 const char *title,
21 boolean Box,
22 boolean shadow)
23 {
24 /* *INDENT-EQLS* */
25 CDKHISTOGRAM *widget = 0;
26 int parentWidth = getmaxx (cdkscreen->window);
27 int parentHeight = getmaxy (cdkscreen->window);
28 int boxWidth;
29 int boxHeight;
30 int xpos = xplace;
31 int ypos = yplace;
32 int oldWidth = 0;
33 int oldHeight = 0;
34
35 if ((widget = newCDKObject (CDKHISTOGRAM, &my_funcs)) == 0)
36 return (0);
37
38 setCDKHistogramBox (widget, Box);
39
40 boxHeight = setWidgetDimension (parentHeight, height, 2);
41 oldHeight = boxHeight;
42
43 boxWidth = setWidgetDimension (parentWidth, width, 0);
44 oldWidth = boxWidth;
45
46 boxWidth = setCdkTitle (ObjOf (widget), title, -(boxWidth + 1));
47
48 /* Increment the height by the number of lines in the title. */
49 boxHeight += TitleLinesOf (widget);
50
51 /*
52 * Make sure we didn't extend beyond the dimensions of the window.
53 */
54 boxWidth = (boxWidth > parentWidth ? oldWidth : boxWidth);
55 boxHeight = (boxHeight > parentHeight ? oldHeight : boxHeight);
56
57 /* Rejustify the x and y positions if we need to. */
58 alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
59
60 /* *INDENT-EQLS* Create the histogram pointer. */
61 ScreenOf (widget) = cdkscreen;
62 widget->parent = cdkscreen->window;
63 widget->win = newwin (boxHeight, boxWidth, ypos, xpos);
64 widget->shadowWin = 0;
65 widget->boxWidth = boxWidth;
66 widget->boxHeight = boxHeight;
67 widget->fieldWidth = boxWidth - 2 * BorderOf (widget);
68 widget->fieldHeight = boxHeight - TitleLinesOf (widget) - 2 * BorderOf (widget);
69 widget->orient = orient;
70 widget->shadow = shadow;
71
72 /* Is the window null. */
73 if (widget->win == 0)
74 {
75 destroyCDKObject (widget);
76 return (0);
77 }
78 keypad (widget->win, TRUE);
79
80 /* *INDENT-EQLS* Set up some default values. */
81 widget->filler = '#' | A_REVERSE;
82 widget->statsAttr = A_NORMAL;
83 widget->statsPos = TOP;
84 widget->viewType = vREAL;
85 widget->high = 0;
86 widget->low = 0;
87 widget->value = 0;
88 widget->lowx = 0;
89 widget->lowy = 0;
90 widget->highx = 0;
91 widget->highy = 0;
92 widget->curx = 0;
93 widget->cury = 0;
94 widget->lowString = 0;
95 widget->highString = 0;
96 widget->curString = 0;
97
98 /* Do we want a shadow? */
99 if (shadow)
100 {
101 widget->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
102 }
103
104 registerCDKObject (cdkscreen, vHISTOGRAM, widget);
105
106 return (widget);
107 }
108
109 /*
110 * This was added for the builder.
111 */
activateCDKHistogram(CDKHISTOGRAM * widget,chtype * actions GCC_UNUSED)112 void activateCDKHistogram (CDKHISTOGRAM *widget, chtype *actions GCC_UNUSED)
113 {
114 drawCDKHistogram (widget, ObjOf (widget)->box);
115 }
116
117 /*
118 * Set various widget attributes.
119 */
setCDKHistogram(CDKHISTOGRAM * widget,EHistogramDisplayType viewType,int statsPos,chtype statsAttr,int low,int high,int value,chtype filler,boolean Box)120 void setCDKHistogram (CDKHISTOGRAM *widget,
121 EHistogramDisplayType viewType,
122 int statsPos,
123 chtype statsAttr,
124 int low,
125 int high,
126 int value,
127 chtype filler,
128 boolean Box)
129 {
130 setCDKHistogramDisplayType (widget, viewType);
131 setCDKHistogramStatsPos (widget, statsPos);
132 setCDKHistogramValue (widget, low, high, value);
133 setCDKHistogramFillerChar (widget, filler);
134 setCDKHistogramStatsAttr (widget, statsAttr);
135 setCDKHistogramBox (widget, Box);
136 }
137
138 /*
139 * Set the values for the widget.
140 */
setCDKHistogramValue(CDKHISTOGRAM * widget,int low,int high,int value)141 void setCDKHistogramValue (CDKHISTOGRAM *widget, int low, int high, int value)
142 {
143 /* *INDENT-EQLS* We should error check the information we have. */
144 widget->low = (low <= high ? low : 0);
145 widget->high = (low <= high ? high : 0);
146 widget->value = (low <= value && value <= high ? value : 0);
147 /* Determine the percentage of the given value. */
148 widget->percent = ((widget->high == 0)
149 ? 0
150 : ((float)widget->value / (float)widget->high));
151
152 /* Determine the size of the histogram bar. */
153 if (widget->orient == VERTICAL)
154 {
155 widget->barSize = (int)(widget->percent * (float)widget->fieldHeight);
156 }
157 else
158 {
159 widget->barSize = (int)(widget->percent * (float)widget->fieldWidth);
160 }
161
162 /*
163 * We have a number of variables which determine the personality of the
164 * histogram. We have to go through each one methodically, and set them
165 * correctly. This section does this.
166 */
167 if (widget->viewType != vNONE)
168 {
169 char string[100];
170 int len;
171
172 if (widget->orient == VERTICAL)
173 {
174 if (widget->statsPos == LEFT || widget->statsPos == BOTTOM)
175 {
176
177 /* Free the space used by the character strings. */
178 freeChar (widget->lowString);
179 freeChar (widget->highString);
180 freeChar (widget->curString);
181
182 /* *INDENT-EQLS* Set the low label attributes. */
183 sprintf (string, "%d", widget->low);
184 len = (int)strlen (string);
185 widget->lowString = copyChar (string);
186 widget->lowx = 1;
187 widget->lowy = widget->boxHeight - len - 1;
188
189 /* *INDENT-EQLS* Set the high label attributes. */
190 sprintf (string, "%d", widget->high);
191 widget->highString = copyChar (string);
192 widget->highx = 1;
193 widget->highy = TitleLinesOf (widget) + 1;
194
195 /* Set the current value attributes. */
196 if (widget->viewType == vPERCENT)
197 {
198 sprintf (string, "%3.1f%%", (float)(widget->percent * 100));
199 }
200 else if (widget->viewType == vFRACTION)
201 {
202 sprintf (string, "%d/%d", widget->value, widget->high);
203 }
204 else
205 {
206 sprintf (string, "%d", widget->value);
207 }
208 len = (int)strlen (string);
209 widget->curString = copyChar (string);
210 widget->curx = 1;
211 widget->cury = (((widget->fieldHeight - len) / 2)
212 + TitleLinesOf (widget) + 1);
213 }
214 else if (widget->statsPos == CENTER)
215 {
216 /* Set the character strings correctly. */
217 freeChar (widget->lowString);
218 freeChar (widget->highString);
219 freeChar (widget->curString);
220
221 /* *INDENT-EQLS* Set the low label attributes. */
222 sprintf (string, "%d", widget->low);
223 len = (int)strlen (string);
224 widget->lowString = copyChar (string);
225 widget->lowx = (widget->fieldWidth / 2) + 1;
226 widget->lowy = widget->boxHeight - len - 1;
227
228 /* *INDENT-EQLS* Set the high label attributes. */
229 sprintf (string, "%d", widget->high);
230 widget->highString = copyChar (string);
231 widget->highx = (widget->fieldWidth / 2) + 1;
232 widget->highy = TitleLinesOf (widget) + 1;
233
234 /* Set the stats label attributes. */
235 if (widget->viewType == vPERCENT)
236 {
237 sprintf (string, "%3.2f%%", (float)(widget->percent * 100));
238 }
239 else if (widget->viewType == vFRACTION)
240 {
241 sprintf (string, "%d/%d", widget->value, widget->high);
242 }
243 else
244 {
245 sprintf (string, "%d", widget->value);
246 }
247 /* *INDENT-EQLS* */
248 len = (int)strlen (string);
249 widget->curString = copyChar (string);
250 widget->curx = (widget->fieldWidth / 2) + 1;
251 widget->cury = (((widget->fieldHeight - len) / 2)
252 + TitleLinesOf (widget)
253 + 1);
254 }
255 else if (widget->statsPos == RIGHT || widget->statsPos == TOP)
256 {
257 /* Set the character strings correctly. */
258 freeChar (widget->lowString);
259 freeChar (widget->highString);
260 freeChar (widget->curString);
261
262 /* *INDENT-EQLS* Set the low label attributes. */
263 sprintf (string, "%d", widget->low);
264 len = (int)strlen (string);
265 widget->lowString = copyChar (string);
266 widget->lowx = widget->fieldWidth;
267 widget->lowy = widget->boxHeight - len - 1;
268
269 /* *INDENT-EQLS* Set the high label attributes. */
270 sprintf (string, "%d", widget->high);
271 widget->highString = copyChar (string);
272 widget->highx = widget->fieldWidth;
273 widget->highy = TitleLinesOf (widget) + 1;
274
275 /* Set the stats label attributes. */
276 if (widget->viewType == vPERCENT)
277 {
278 sprintf (string, "%3.2f%%", (float)(widget->percent * 100));
279 }
280 else if (widget->viewType == vFRACTION)
281 {
282 sprintf (string, "%d/%d", widget->value, widget->high);
283 }
284 else
285 {
286 sprintf (string, "%d", widget->value);
287 }
288 /* *INDENT-EQLS* */
289 len = (int)strlen (string);
290 widget->curString = copyChar (string);
291 widget->curx = widget->fieldWidth;
292 widget->cury = (((widget->fieldHeight - len) / 2)
293 + TitleLinesOf (widget)
294 + 1);
295 }
296 }
297 else
298 {
299 /* Alignment is HORIZONTAL. */
300 if (widget->statsPos == TOP || widget->statsPos == RIGHT)
301 {
302 /* Set the character strings correctly. */
303 freeChar (widget->lowString);
304 freeChar (widget->highString);
305 freeChar (widget->curString);
306
307 /* *INDENT-EQLS* Set the low label attributes. */
308 sprintf (string, "%d", widget->low);
309 widget->lowString = copyChar (string);
310 widget->lowx = 1;
311 widget->lowy = TitleLinesOf (widget) + 1;
312
313 /* *INDENT-EQLS* Set the high label attributes. */
314 sprintf (string, "%d", widget->high);
315 len = (int)strlen (string);
316 widget->highString = copyChar (string);
317 widget->highx = widget->boxWidth - len - 1;
318 widget->highy = TitleLinesOf (widget) + 1;
319
320 /* Set the stats label attributes. */
321 if (widget->viewType == vPERCENT)
322 {
323 sprintf (string, "%3.1f%%", (float)(widget->percent * 100));
324 }
325 else if (widget->viewType == vFRACTION)
326 {
327 sprintf (string, "%d/%d", widget->value, widget->high);
328 }
329 else
330 {
331 sprintf (string, "%d", widget->value);
332 }
333 /* *INDENT-EQLS* */
334 len = (int)strlen (string);
335 widget->curString = copyChar (string);
336 widget->curx = (widget->fieldWidth - len) / 2 + 1;
337 widget->cury = TitleLinesOf (widget) + 1;
338 }
339 else if (widget->statsPos == CENTER)
340 {
341 /* Set the character strings correctly. */
342 freeChar (widget->lowString);
343 freeChar (widget->highString);
344 freeChar (widget->curString);
345
346 /* *INDENT-EQLS* Set the low label attributes. */
347 sprintf (string, "%d", widget->low);
348 widget->lowString = copyChar (string);
349 widget->lowx = 1;
350 widget->lowy = ((widget->fieldHeight / 2)
351 + TitleLinesOf (widget)
352 + 1);
353
354 /* *INDENT-EQLS* Set the high label attributes. */
355 sprintf (string, "%d", widget->high);
356 len = (int)strlen (string);
357 widget->highString = copyChar (string);
358 widget->highx = widget->boxWidth - len - 1;
359 widget->highy = ((widget->fieldHeight / 2)
360 + TitleLinesOf (widget)
361 + 1);
362
363 /* Set the stats label attributes. */
364 if (widget->viewType == vPERCENT)
365 {
366 sprintf (string, "%3.1f%%", (float)(widget->percent * 100));
367 }
368 else if (widget->viewType == vFRACTION)
369 {
370 sprintf (string, "%d/%d", widget->value, widget->high);
371 }
372 else
373 {
374 sprintf (string, "%d", widget->value);
375 }
376 /* *INDENT-EQLS* */
377 len = (int)strlen (string);
378 widget->curString = copyChar (string);
379 widget->curx = (widget->fieldWidth - len) / 2 + 1;
380 widget->cury = ((widget->fieldHeight / 2)
381 + TitleLinesOf (widget)
382 + 1);
383 }
384 else if (widget->statsPos == BOTTOM || widget->statsPos == LEFT)
385 {
386 /* Set the character strings correctly. */
387 freeChar (widget->lowString);
388 freeChar (widget->highString);
389 freeChar (widget->curString);
390
391 /* *INDENT-EQLS* Set the low label attributes. */
392 sprintf (string, "%d", widget->low);
393 widget->lowString = copyChar (string);
394 widget->lowx = 1;
395 widget->lowy = widget->boxHeight - 2 * BorderOf (widget);
396
397 /* *INDENT-EQLS* Set the high label attributes. */
398 sprintf (string, "%d", widget->high);
399 len = (int)strlen (string);
400 widget->highString = copyChar (string);
401 widget->highx = widget->boxWidth - len - 1;
402 widget->highy = widget->boxHeight - 2 * BorderOf (widget);
403
404 /* Set the stats label attributes. */
405 if (widget->viewType == vPERCENT)
406 {
407 sprintf (string, "%3.1f%%", (float)(widget->percent * 100));
408 }
409 else if (widget->viewType == vFRACTION)
410 {
411 sprintf (string, "%d/%d", widget->value, widget->high);
412 }
413 else
414 {
415 sprintf (string, "%d", widget->value);
416 }
417 /* *INDENT-EQLS* */
418 widget->curString = copyChar (string);
419 widget->curx = (widget->fieldWidth - len) / 2 + 1;
420 widget->cury = widget->boxHeight - 2 * BorderOf (widget);
421 }
422 }
423 }
424 }
getCDKHistogramValue(CDKHISTOGRAM * widget)425 int getCDKHistogramValue (CDKHISTOGRAM *widget)
426 {
427 return widget->value;
428 }
getCDKHistogramLowValue(CDKHISTOGRAM * widget)429 int getCDKHistogramLowValue (CDKHISTOGRAM *widget)
430 {
431 return widget->low;
432 }
getCDKHistogramHighValue(CDKHISTOGRAM * widget)433 int getCDKHistogramHighValue (CDKHISTOGRAM *widget)
434 {
435 return widget->high;
436 }
437
438 /*
439 * Set the histogram display type.
440 */
setCDKHistogramDisplayType(CDKHISTOGRAM * widget,EHistogramDisplayType viewType)441 void setCDKHistogramDisplayType (CDKHISTOGRAM *widget, EHistogramDisplayType viewType)
442 {
443 widget->viewType = viewType;
444 }
getCDKHistogramViewType(CDKHISTOGRAM * widget)445 EHistogramDisplayType getCDKHistogramViewType (CDKHISTOGRAM *widget)
446 {
447 return widget->viewType;
448 }
449
450 /*
451 * Set the position of the statistics information.
452 */
setCDKHistogramStatsPos(CDKHISTOGRAM * widget,int statsPos)453 void setCDKHistogramStatsPos (CDKHISTOGRAM *widget, int statsPos)
454 {
455 widget->statsPos = statsPos;
456 }
getCDKHistogramStatsPos(CDKHISTOGRAM * widget)457 int getCDKHistogramStatsPos (CDKHISTOGRAM *widget)
458 {
459 return widget->statsPos;
460 }
461
462 /*
463 * Set the attribute of the statistics.
464 */
setCDKHistogramStatsAttr(CDKHISTOGRAM * widget,chtype statsAttr)465 void setCDKHistogramStatsAttr (CDKHISTOGRAM *widget, chtype statsAttr)
466 {
467 widget->statsAttr = statsAttr;
468 }
getCDKHistogramStatsAttr(CDKHISTOGRAM * widget)469 chtype getCDKHistogramStatsAttr (CDKHISTOGRAM *widget)
470 {
471 return widget->statsAttr;
472 }
473
474 /*
475 * Set the character to use when drawing the widget.
476 */
setCDKHistogramFillerChar(CDKHISTOGRAM * widget,chtype character)477 void setCDKHistogramFillerChar (CDKHISTOGRAM *widget, chtype character)
478 {
479 widget->filler = character;
480 }
getCDKHistogramFillerChar(CDKHISTOGRAM * widget)481 chtype getCDKHistogramFillerChar (CDKHISTOGRAM *widget)
482 {
483 return widget->filler;
484 }
485
486 /*
487 * Set the widget box attribute.
488 */
setCDKHistogramBox(CDKHISTOGRAM * widget,boolean Box)489 void setCDKHistogramBox (CDKHISTOGRAM *widget, boolean Box)
490 {
491 ObjOf (widget)->box = Box;
492 ObjOf (widget)->borderSize = Box ? 1 : 0;
493 }
getCDKHistogramBox(CDKHISTOGRAM * widget)494 boolean getCDKHistogramBox (CDKHISTOGRAM *widget)
495 {
496 return ObjOf (widget)->box;
497 }
498
499 /*
500 * Set the background attribute of the widget.
501 */
_setBKattrHistogram(CDKOBJS * object,chtype attrib)502 static void _setBKattrHistogram (CDKOBJS *object, chtype attrib)
503 {
504 if (object != 0)
505 {
506 CDKHISTOGRAM *widget = (CDKHISTOGRAM *)object;
507 wbkgd (widget->win, attrib);
508 }
509 }
510
511 /*
512 * Move the histogram field to the given location.
513 */
_moveCDKHistogram(CDKOBJS * object,int xplace,int yplace,boolean relative,boolean refresh_flag)514 static void _moveCDKHistogram (CDKOBJS *object,
515 int xplace,
516 int yplace,
517 boolean relative,
518 boolean refresh_flag)
519 {
520 CDKHISTOGRAM *widget = (CDKHISTOGRAM *)object;
521 /* *INDENT-EQLS* */
522 int currentX = getbegx (widget->win);
523 int currentY = getbegy (widget->win);
524 int xpos = xplace;
525 int ypos = yplace;
526 int xdiff = 0;
527 int ydiff = 0;
528
529 /*
530 * If this is a relative move, then we will adjust where we want
531 * to move to.
532 */
533 if (relative)
534 {
535 xpos = getbegx (widget->win) + xplace;
536 ypos = getbegy (widget->win) + yplace;
537 }
538
539 /* Adjust the window if we need to. */
540 alignxy (WindowOf (widget), &xpos, &ypos, widget->boxWidth, widget->boxHeight);
541
542 /* Get the difference. */
543 xdiff = currentX - xpos;
544 ydiff = currentY - ypos;
545
546 /* Move the window to the new location. */
547 moveCursesWindow (widget->win, -xdiff, -ydiff);
548 moveCursesWindow (widget->shadowWin, -xdiff, -ydiff);
549
550 /* Touch the windows so they 'move'. */
551 refreshCDKWindow (WindowOf (widget));
552
553 /* Redraw the window, if they asked for it. */
554 if (refresh_flag)
555 {
556 drawCDKHistogram (widget, ObjOf (widget)->box);
557 }
558 }
559
560 /*
561 * Draw the widget.
562 */
_drawCDKHistogram(CDKOBJS * object,boolean Box)563 static void _drawCDKHistogram (CDKOBJS *object, boolean Box)
564 {
565 CDKHISTOGRAM *widget = (CDKHISTOGRAM *)object;
566 /* *INDENT-EQLS* */
567 chtype battr = 0;
568 chtype bchar = 0;
569 chtype fattr = widget->filler & A_ATTRIBUTES;
570 int histX = TitleLinesOf (widget) + 1;
571 int histY = widget->barSize;
572 int x, y;
573
574 /* Erase the window. */
575 werase (widget->win);
576
577 /* Box the widget if asked. */
578 if (Box)
579 {
580 drawObjBox (widget->win, ObjOf (widget));
581 }
582
583 /* Do we have a shadow to draw? */
584 if (widget->shadowWin != 0)
585 {
586 drawShadow (widget->shadowWin);
587 }
588
589 drawCdkTitle (widget->win, object);
590
591 /* If the user asked for labels, draw them in. */
592 if (widget->viewType != vNONE)
593 {
594 /* Draw in the low label. */
595 if (widget->lowString != 0)
596 {
597 int len = (int)strlen (widget->lowString);
598 writeCharAttrib (widget->win,
599 widget->lowx,
600 widget->lowy,
601 widget->lowString,
602 widget->statsAttr,
603 widget->orient,
604 0, len);
605 }
606
607 /* Draw in the current value label. */
608 if (widget->curString != 0)
609 {
610 int len = (int)strlen (widget->curString);
611 writeCharAttrib (widget->win,
612 widget->curx,
613 widget->cury,
614 widget->curString,
615 widget->statsAttr,
616 widget->orient,
617 0, len);
618 }
619
620 /* Draw in the high label. */
621 if (widget->highString != 0)
622 {
623 int len = (int)strlen (widget->highString);
624 writeCharAttrib (widget->win,
625 widget->highx,
626 widget->highy,
627 widget->highString,
628 widget->statsAttr,
629 widget->orient,
630 0, len);
631 }
632 }
633
634 if (widget->orient == VERTICAL)
635 {
636 histX = widget->boxHeight - widget->barSize - 1;
637 histY = widget->fieldWidth;
638 }
639
640 /* Draw the histogram bar. */
641 for (x = histX; x < widget->boxHeight - 1; x++)
642 {
643 for (y = 1; y <= histY; y++)
644 {
645 battr = mvwinch (widget->win, x, y);
646 bchar = CharOf (battr);
647
648 if (bchar == ' ')
649 {
650 (void)mvwaddch (widget->win, x, y, widget->filler);
651 }
652 else
653 {
654 (void)mvwaddch (widget->win, x, y, battr | fattr);
655 }
656 }
657 }
658
659 /* Refresh the window. */
660 wrefresh (widget->win);
661 }
662
663 /*
664 * Destroy the widget.
665 */
_destroyCDKHistogram(CDKOBJS * object)666 static void _destroyCDKHistogram (CDKOBJS *object)
667 {
668 if (object != 0)
669 {
670 CDKHISTOGRAM *widget = (CDKHISTOGRAM *)object;
671
672 freeChar (widget->curString);
673 freeChar (widget->lowString);
674 freeChar (widget->highString);
675 cleanCdkTitle (object);
676
677 /* Clean up the windows. */
678 deleteCursesWindow (widget->shadowWin);
679 deleteCursesWindow (widget->win);
680
681 /* Clean the key bindings. */
682 cleanCDKObjectBindings (vHISTOGRAM, widget);
683
684 /* Unregister this object. */
685 unregisterCDKObject (vHISTOGRAM, widget);
686 }
687 }
688
689 /*
690 * Erase the widget from the screen.
691 */
_eraseCDKHistogram(CDKOBJS * object)692 static void _eraseCDKHistogram (CDKOBJS *object)
693 {
694 if (validCDKObject (object))
695 {
696 CDKHISTOGRAM *widget = (CDKHISTOGRAM *)object;
697
698 eraseCursesWindow (widget->win);
699 eraseCursesWindow (widget->shadowWin);
700 }
701 }
702
703 dummyInject (Histogram)
704
705 dummyFocus (Histogram)
706
707 dummyUnfocus (Histogram)
708
709 dummyRefreshData (Histogram)
710
711 dummySaveData (Histogram)
712