1 #include <cdk_int.h>
2 
3 /*
4  * $Author: tom $
5  * $Date: 2014/11/06 10:06:46 $
6  * $Revision: 1.91 $
7  */
8 
9 DeclareCDKObjects (LABEL, Label, setCdk, Unknown);
10 
11 /*
12  * This creates a label widget.
13  */
newCDKLabel(CDKSCREEN * cdkscreen,int xplace,int yplace,CDK_CSTRING2 mesg,int rows,boolean Box,boolean shadow)14 CDKLABEL *newCDKLabel (CDKSCREEN *cdkscreen,
15 		       int xplace,
16 		       int yplace,
17 		       CDK_CSTRING2 mesg,
18 		       int rows,
19 		       boolean Box,
20 		       boolean shadow)
21 {
22    /* *INDENT-EQLS* */
23    CDKLABEL *label      = 0;
24    int parentWidth      = getmaxx (cdkscreen->window);
25    int parentHeight     = getmaxy (cdkscreen->window);
26    int boxWidth         = INT_MIN;
27    int boxHeight;
28    int xpos             = xplace;
29    int ypos             = yplace;
30    int x                = 0;
31 
32    if (rows <= 0
33        || (label = newCDKObject (CDKLABEL, &my_funcs)) == 0
34        || (label->info = typeCallocN (chtype *, rows + 1)) == 0
35        || (label->infoLen = typeCallocN (int, rows + 1)) == 0
36        || (label->infoPos = typeCallocN (int, rows + 1)) == 0)
37    {
38       destroyCDKObject (label);
39       return (0);
40    }
41 
42    setCDKLabelBox (label, Box);
43    boxHeight = rows + 2 * BorderOf (label);
44 
45    /* Determine the box width. */
46    for (x = 0; x < rows; x++)
47    {
48       /* Translate the char * to a chtype. */
49       label->info[x] = char2Chtype (mesg[x],
50 				    &label->infoLen[x],
51 				    &label->infoPos[x]);
52       boxWidth = MAXIMUM (boxWidth, label->infoLen[x]);
53    }
54    boxWidth += 2 * BorderOf (label);
55 
56    /* Create the string alignments. */
57    for (x = 0; x < rows; x++)
58    {
59       label->infoPos[x] = justifyString (boxWidth - 2 * BorderOf (label),
60 					 label->infoLen[x],
61 					 label->infoPos[x]);
62    }
63 
64    /*
65     * Make sure we didn't extend beyond the dimensions of the window.
66     */
67    boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
68    boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
69 
70    /* Rejustify the x and y positions if we need to. */
71    alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
72 
73    /* *INDENT-EQLS* Create the label. */
74    ScreenOf (label)     = cdkscreen;
75    label->parent        = cdkscreen->window;
76    label->win           = newwin (boxHeight, boxWidth, ypos, xpos);
77    label->shadowWin     = 0;
78    label->xpos          = xpos;
79    label->ypos          = ypos;
80    label->rows          = rows;
81    label->boxWidth      = boxWidth;
82    label->boxHeight     = boxHeight;
83    ObjOf (label)->inputWindow = label->win;
84    ObjOf (label)->hasFocus = FALSE;
85    label->shadow        = shadow;
86 
87    /* Is the window null? */
88    if (label->win == 0)
89    {
90       destroyCDKObject (label);
91       return (0);
92    }
93    keypad (label->win, TRUE);
94 
95    /* If a shadow was requested, then create the shadow window. */
96    if (shadow)
97    {
98       label->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
99    }
100 
101    /* Register this baby. */
102    registerCDKObject (cdkscreen, vLABEL, label);
103 
104    /* Return the label pointer. */
105    return (label);
106 }
107 
108 /*
109  * This was added for the builder.
110  */
activateCDKLabel(CDKLABEL * label,chtype * actions GCC_UNUSED)111 void activateCDKLabel (CDKLABEL *label, chtype *actions GCC_UNUSED)
112 {
113    drawCDKLabel (label, ObjOf (label)->box);
114 }
115 
116 /*
117  * This sets multiple attributes of the widget.
118  */
setCDKLabel(CDKLABEL * label,CDK_CSTRING2 mesg,int lines,boolean Box)119 void setCDKLabel (CDKLABEL *label, CDK_CSTRING2 mesg, int lines, boolean Box)
120 {
121    setCDKLabelMessage (label, mesg, lines);
122    setCDKLabelBox (label, Box);
123 }
124 
125 /*
126  * This sets the information within the label.
127  */
setCDKLabelMessage(CDKLABEL * label,CDK_CSTRING2 info,int infoSize)128 void setCDKLabelMessage (CDKLABEL *label, CDK_CSTRING2 info, int infoSize)
129 {
130    int x;
131    int limit;
132 
133    /* Clean out the old message. */
134    for (x = 0; x < label->rows; x++)
135    {
136       freeChtype (label->info[x]);
137       label->info[x] = 0;
138       label->infoPos[x] = 0;
139       label->infoLen[x] = 0;
140    }
141 
142    /* update the label's length - but taking into account its window size */
143    limit = label->boxHeight - (2 * BorderOf (label));
144    if (infoSize > limit)
145       infoSize = limit;
146    label->rows = infoSize;
147 
148    /* Copy in the new message. */
149    for (x = 0; x < label->rows; x++)
150    {
151       label->info[x] = char2Chtype (info[x],
152 				    &label->infoLen[x],
153 				    &label->infoPos[x]);
154       label->infoPos[x] = justifyString (label->boxWidth - 2 * BorderOf (label),
155 					 label->infoLen[x],
156 					 label->infoPos[x]);
157    }
158 
159    /* Redraw the label widget. */
160    eraseCDKLabel (label);
161    drawCDKLabel (label, ObjOf (label)->box);
162 }
getCDKLabelMessage(CDKLABEL * label,int * size)163 chtype **getCDKLabelMessage (CDKLABEL *label, int *size)
164 {
165    (*size) = label->rows;
166    return label->info;
167 }
168 
169 /*
170  * This sets the box flag for the label widget.
171  */
setCDKLabelBox(CDKLABEL * label,boolean Box)172 void setCDKLabelBox (CDKLABEL *label, boolean Box)
173 {
174    ObjOf (label)->box = Box;
175    ObjOf (label)->borderSize = Box ? 1 : 0;
176 }
getCDKLabelBox(CDKLABEL * label)177 boolean getCDKLabelBox (CDKLABEL *label)
178 {
179    return ObjOf (label)->box;
180 }
181 
182 /*
183  * This sets the background attribute of the widget.
184  */
_setBKattrLabel(CDKOBJS * object,chtype attrib)185 static void _setBKattrLabel (CDKOBJS *object, chtype attrib)
186 {
187    if (object != 0)
188    {
189       CDKLABEL *widget = (CDKLABEL *)object;
190 
191       wbkgd (widget->win, attrib);
192    }
193 }
194 
195 /*
196  * This draws the label widget.
197  */
_drawCDKLabel(CDKOBJS * object,boolean Box GCC_UNUSED)198 static void _drawCDKLabel (CDKOBJS *object, boolean Box GCC_UNUSED)
199 {
200    CDKLABEL *label = (CDKLABEL *)object;
201    int x = 0;
202 
203    /* Is there a shadow? */
204    if (label->shadowWin != 0)
205    {
206       drawShadow (label->shadowWin);
207    }
208 
209    /* Box the widget if asked. */
210    if (ObjOf (label)->box)
211    {
212       drawObjBox (label->win, ObjOf (label));
213    }
214 
215    /* Draw in the message. */
216    for (x = 0; x < label->rows; x++)
217    {
218       writeChtype (label->win,
219 		   label->infoPos[x] + BorderOf (label),
220 		   x + BorderOf (label),
221 		   label->info[x],
222 		   HORIZONTAL,
223 		   0,
224 		   label->infoLen[x]);
225    }
226 
227    /* Refresh the window. */
228    wrefresh (label->win);
229 }
230 
231 /*
232  * This erases the label widget.
233  */
_eraseCDKLabel(CDKOBJS * object)234 static void _eraseCDKLabel (CDKOBJS *object)
235 {
236    if (validCDKObject (object))
237    {
238       CDKLABEL *label = (CDKLABEL *)object;
239 
240       eraseCursesWindow (label->win);
241       eraseCursesWindow (label->shadowWin);
242    }
243 }
244 
245 /*
246  * This moves the label field to the given location.
247  */
_moveCDKLabel(CDKOBJS * object,int xplace,int yplace,boolean relative,boolean refresh_flag)248 static void _moveCDKLabel (CDKOBJS *object,
249 			   int xplace,
250 			   int yplace,
251 			   boolean relative,
252 			   boolean refresh_flag)
253 {
254    CDKLABEL *label = (CDKLABEL *)object;
255    /* *INDENT-EQLS* */
256    int currentX = getbegx (label->win);
257    int currentY = getbegy (label->win);
258    int xpos     = xplace;
259    int ypos     = yplace;
260    int xdiff    = 0;
261    int ydiff    = 0;
262 
263    /*
264     * If this is a relative move, then we will adjust where we want
265     * to move to.
266     */
267    if (relative)
268    {
269       xpos = getbegx (label->win) + xplace;
270       ypos = getbegy (label->win) + yplace;
271    }
272 
273    /* Adjust the window if we need to. */
274    alignxy (WindowOf (label), &xpos, &ypos, label->boxWidth, label->boxHeight);
275 
276    /* Get the difference. */
277    xdiff = currentX - xpos;
278    ydiff = currentY - ypos;
279 
280    /* Move the window to the new location. */
281    moveCursesWindow (label->win, -xdiff, -ydiff);
282    moveCursesWindow (label->shadowWin, -xdiff, -ydiff);
283 
284    /* Touch the windows so they 'move'. */
285    refreshCDKWindow (WindowOf (label));
286 
287    /* Redraw the window, if they asked for it. */
288    if (refresh_flag)
289    {
290       drawCDKLabel (label, ObjOf (label)->box);
291    }
292 }
293 
294 /*
295  * This destroys the label object pointer.
296  */
_destroyCDKLabel(CDKOBJS * object)297 static void _destroyCDKLabel (CDKOBJS *object)
298 {
299    if (object != 0)
300    {
301       CDKLABEL *label = (CDKLABEL *)object;
302 
303       CDKfreeChtypes (label->info);
304       freeChecked (label->infoLen);
305       freeChecked (label->infoPos);
306 
307       /* Free up the window pointers. */
308       deleteCursesWindow (label->shadowWin);
309       deleteCursesWindow (label->win);
310 
311       /* Clean the key bindings. */
312       cleanCDKObjectBindings (vLABEL, label);
313 
314       /* Unregister the object. */
315       unregisterCDKObject (vLABEL, label);
316    }
317 }
318 
319 /*
320  * This pauses until a user hits a key...
321  */
waitCDKLabel(CDKLABEL * label,char key)322 char waitCDKLabel (CDKLABEL *label, char key)
323 {
324    int code;
325    boolean functionKey;
326 
327    /* If the key is null, we'll accept anything. */
328    if (key == 0)
329    {
330       code = getchCDKObject (ObjOf (label), &functionKey);
331    }
332    else
333    {
334       /* Only exit when a specific key is hit. */
335       for (;;)
336       {
337 	 code = getchCDKObject (ObjOf (label), &functionKey);
338 	 if (code == key)
339 	 {
340 	    break;
341 	 }
342       }
343    }
344    return (char)(code);
345 }
346 
347 dummyInject (Label)
348 
349 dummyFocus (Label)
350 
351 dummyUnfocus (Label)
352 
353 dummyRefreshData (Label)
354 
355 dummySaveData (Label)
356