1 /*
2 
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 //#include <fcntl.h>
20 //#include <io.h>
21 #include <ctype.h>
22 #include <math.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 
27 #include "tngapp.h"
28 #include "tngqbox.h"
29 //#include <_ui.h>
30 #include "tngslidr.h"
31 #include "tngtextg.h"
32 
33 // Externs
34 extern int _tt_do_event(long tt_event);
35 
36 // #include <mprintf.h>
37 
38 TNG *current_tng;
39 int num_slots;
40 
41 // Protoytpes
42 errtype tng_increm_slot(TNG *ptng, int quan);
43 errtype tng_decrem_slot(TNG *ptng, int quan);
44 uchar tng_quickbox_scroll_changed(void *ui_data, intptr_t user_data);
45 uchar quickbox_fix_text_changed(QuickboxSlot *qbs);
46 uchar quickbox_uint_text_changed(QuickboxSlot *qbs);
47 uchar tng_quickbox_text_changed(void *ui_data, intptr_t user_data);
48 errtype tng_draw_qb_int_slot(TNG *ptng, QuickboxSlot *curp, LGRect r);
49 errtype tng_draw_qb_text_slot(TNG *ptng, QuickboxSlot *curp, LGRect r);
50 errtype tng_draw_qb_bool_slot(TNG *ptng, QuickboxSlot *curp, LGRect r);
51 errtype tng_draw_qb_pb_slot(TNG *ptng, QuickboxSlot *curp, LGRect r);
52 errtype gad_qbox_display_slot(QuickboxSlot *qbs, uchar recurse);
53 errtype _draw_text(TNG *ptng, char *txt, int x_coord, int y_coord);
54 int _text_width(TNG *ptng, char *t);
55 int _label_extent(TNG *ptng);
56 int _total_extent(TNG *ptng);
57 errtype _slot_rectangle(TNG *qb, int slot_num, LGRect *slot_rect);
58 
tng_increm_slot(TNG * ptng,int quan)59 errtype tng_increm_slot(TNG *ptng, int quan)
60 {
61    QuickboxSlot *pqs;
62    int *val_i;
63    uint *val_ui;
64    short *val_s;
65    uchar *val_b;
66    ubyte *val_by;
67 
68    pqs = QB_CURRENT(ptng);
69    if (pqs->vartype == QB_INT_SLOT)
70    {
71       val_i = (int *)(pqs->var);
72       *val_i = *val_i + quan;
73       if ((pqs->options & QB_BOUNDED) && (*val_i > (int)pqs->p2))
74          *val_i = (int)pqs->p2;
75       if ((pqs->options & QB_CYCLE) && (*val_i > (int)pqs->p2))
76          *val_i = (int)pqs->p1;
77       if ((pqs->options & QB_STRINGSET) && (*val_i > (int)pqs->p2))
78          *val_i = (int)0;
79    }
80    if (pqs->vartype == QB_UINT_SLOT)
81    {
82       val_ui = (uint *)(pqs->var);
83       *val_ui = *val_ui + quan;
84       if ((pqs->options & QB_BOUNDED) && (*val_ui > (uint)pqs->p2))
85          *val_ui = (uint)pqs->p2;
86       if ((pqs->options & QB_CYCLE) && (*val_ui > (uint)pqs->p2))
87          *val_ui = (uint)pqs->p1;
88       if ((pqs->options & QB_STRINGSET) && (*val_ui > (uint)pqs->p2))
89          *val_ui = (uint)0;
90    }
91    if (pqs->vartype == QB_SHORT_SLOT)
92    {
93       val_s = (short *)(pqs->var);
94       *val_s = *val_s + (short)quan;
95       if ((pqs->options & QB_BOUNDED) && (*val_s > (int)pqs->p2))
96          *val_s = (short)pqs->p2;
97       if ((pqs->options & QB_CYCLE) && (*val_s > (int)pqs->p2))
98          *val_s = (short)pqs->p1;
99       if ((pqs->options & QB_STRINGSET) && (*val_s > (int)pqs->p2))
100          *val_s = (short)0;
101    }
102    if (pqs->vartype == QB_BYTE_SLOT)
103    {
104       val_by = (ubyte *)(pqs->var);
105       *val_by = *val_by + (ubyte)quan;
106       if ((pqs->options & QB_BOUNDED) && (*val_by > (int)pqs->p2))
107          *val_by = (ubyte)pqs->p2;
108       if ((pqs->options & QB_CYCLE) && (*val_by > (int)pqs->p2))
109          *val_by = (ubyte)pqs->p1;
110       if ((pqs->options & QB_STRINGSET) && (*val_by > (int)pqs->p2))
111          *val_by = (ubyte)0;
112    }
113    if (pqs->vartype == QB_BOOL_SLOT)
114    {
115       val_b = (uchar *)(pqs->var);
116       if (*val_b)
117          *val_b = FALSE;
118       else
119          *val_b = TRUE;
120    }
121    pqs->tng->signal(pqs->tng,TNG_SIGNAL_CHANGED);
122    gad_qbox_display_slot(pqs, TRUE);
123    return(OK);
124 }
125 
tng_decrem_slot(TNG * ptng,int quan)126 errtype tng_decrem_slot(TNG *ptng, int quan)
127 {
128    QuickboxSlot *pqs;
129    int *val_i;
130    uint *val_ui;
131    short *val_s;
132    uchar *val_b;
133    ubyte *val_by;
134 
135    pqs = QB_CURRENT(ptng);
136    if (pqs->vartype == QB_INT_SLOT)
137    {
138       val_i = (int *)(pqs->var);
139       *val_i = *val_i - quan;
140       if ((pqs->options & QB_BOUNDED) && (*val_i < (int)pqs->p1))
141          *val_i = (int)pqs->p1;
142       if ((pqs->options & QB_CYCLE) && (*val_i < (int)pqs->p1))
143          *val_i = (int)pqs->p2;
144       if ((pqs->options & QB_STRINGSET) && (*val_i < 0))
145          *val_i = (int)pqs->p2;
146    }
147    if (pqs->vartype == QB_UINT_SLOT)
148    {
149       uint *orig = (uint *)(pqs->var);
150       val_ui = (uint *)(pqs->var);
151       *val_ui = *val_ui - quan;
152       if ((pqs->options & QB_BOUNDED) && (*val_ui < (uint)pqs->p1))
153          *val_ui = (uint)pqs->p1;
154       if ((pqs->options & QB_CYCLE) && (*val_ui < (uint)pqs->p1))
155          *val_ui = (uint)pqs->p2;
156       if ((pqs->options & QB_STRINGSET) && (*val_ui > *orig))
157          *val_ui = (uint)pqs->p2;
158    }
159    if (pqs->vartype == QB_SHORT_SLOT)
160    {
161       val_s = (short *)(pqs->var);
162       *val_s = (*val_s) - (short)quan;
163       if ((pqs->options & QB_BOUNDED) && (*val_s < (int)pqs->p1))
164          *val_s = (short)pqs->p1;
165       if ((pqs->options & QB_CYCLE) && (*val_s < (int)pqs->p1))
166          *val_s = (short)pqs->p2;
167       if ((pqs->options & QB_STRINGSET) && (*val_s < 0))
168          *val_s = (short)pqs->p2;
169    }
170    if (pqs->vartype == QB_BYTE_SLOT)
171    {
172       val_by = (ubyte *)(pqs->var);
173       if ((pqs->options & QB_BOUNDED) && (*val_by < (int)pqs->p1 + (ubyte)quan))
174          *val_by = (ubyte)pqs->p1;
175       else if ((pqs->options & QB_CYCLE) && (*val_by < (int)pqs->p1 + (ubyte)quan))
176          *val_by = (ubyte)pqs->p2;
177       else if ((pqs->options & QB_STRINGSET) && (*val_by < (ubyte)quan))
178          *val_by = (ubyte)pqs->p2;
179       else
180          *val_by = *val_by - (ubyte)quan;
181    }
182    if (pqs->vartype == QB_BOOL_SLOT)
183    {
184       val_b = (uchar *)(pqs->var);
185       if (*val_b)
186          *val_b = FALSE;
187       else
188          *val_b = TRUE;
189    }
190    pqs->tng->signal(pqs->tng,TNG_SIGNAL_CHANGED);
191    gad_qbox_display_slot(pqs, TRUE);
192    return(OK);
193 }
194 
tng_quickbox_scroll_changed(void * ui_data,intptr_t user_data)195 uchar tng_quickbox_scroll_changed(void *ui_data, intptr_t user_data)
196 {
197    QuickboxSlot *qbs;
198    TNG *ptng;
199 #ifndef NO_DUMMIES
200    void *dummy; dummy = ui_data;
201 #endif
202 
203    qbs = (QuickboxSlot *)user_data;
204    ptng = qbs->tng;
205 //   Spew(DSRC_UI_Quickbox, ("Hey, scrollbar changed...\n"));
206    if (qbs->vartype == QB_INT_SLOT)
207       *((int *)(qbs->var)) = TNG_SL(qbs->aux_tng)->value;
208    if (qbs->vartype == QB_UINT_SLOT)
209       *((uint *)(qbs->var)) = TNG_SL(qbs->aux_tng)->value;
210    else if (qbs->vartype == QB_SHORT_SLOT)
211       *((short *)(qbs->var)) = (short)TNG_SL(qbs->aux_tng)->value;
212    else if (qbs->vartype == QB_BYTE_SLOT)
213       *((ubyte *)(qbs->var)) = (ubyte)TNG_SL(qbs->aux_tng)->value;
214    ptng->signal(ptng,TNG_SIGNAL_CHANGED);
215    gad_qbox_display_slot(qbs, TRUE);
216    return(FALSE);
217 }
218 
quickbox_fix_text_changed(QuickboxSlot * qbs)219 uchar quickbox_fix_text_changed(QuickboxSlot *qbs)
220 {
221    char* stringval = TNG_TX_GETLINE(qbs->aux_tng,0);
222    *((fix *)(qbs->var)) = fix_from_float(atof(stringval));
223    return TRUE;
224 }
225 
quickbox_uint_text_changed(QuickboxSlot * qbs)226 uchar quickbox_uint_text_changed(QuickboxSlot *qbs)
227 {
228    char *convstring;
229    uint atoival, newval;
230    short base,i,cap;
231    uchar okay;
232 
233    base = 10;
234    //Spew(DSRC_UI_Quickbox, ("Hey, at top of parsing algorithm!\n"));
235    if (qbs->options & QB_HEX) {  base = 16; cap = 10; }
236    if (qbs->options & QB_OCTAL) {  base = 8; cap = 8; }
237    if (qbs->options & QB_BINARY) {   base = 2; cap = 2; }
238    convstring = TNG_TX_GETLINE(qbs->aux_tng, 0);
239    atoival = 0;
240    okay = TRUE;
241    for (i=0; i<strlen(convstring); i++)
242    {
243       convstring[i] = toupper(convstring[i]);
244       switch(base)
245       {
246          case 16:
247             if ((convstring[i] < '0') || ((convstring[i] > '9') && (convstring[i] < 'A')) || (convstring[i] > 'F'))
248                okay = FALSE;
249             break;
250          case 8:
251             if ((convstring[i] < '0') || (convstring[i] > '7'))
252                okay = FALSE;
253             break;
254          case 2:
255             if ((convstring[i] < '0') || (convstring [i] > '1'))
256                okay = FALSE;
257             break;
258       }
259    }
260    if (okay)
261    {
262       //Spew(DSRC_UI_Quickbox, ("convstring = %s base = %d\n", convstring,base));
263       for (i=0; i<strlen(convstring); i++)
264       {
265          //Spew(DSRC_UI_Quickbox, ("i = %d  convstring[i] = %c(%d)\n",i,convstring[i],convstring[i]));
266          if ((convstring[i] - '0') < cap)
267          {
268             newval = pow(base,strlen(convstring)-1-i) * (convstring[i] - '0');
269             atoival += newval;
270             //Spew(DSRC_UI_Quickbox, ("%d^%d * (%d) = %d * %d = %d\n",
271             //   base,strlen(convstring)-1-i,convstring[i]-'0',pow(base,strlen(convstring) - 1 - i),convstring[i]-'0',newval));
272          }
273          else if ((base == 16) && (convstring[i] >= 'A'))
274          {
275             newval = pow(16,strlen(convstring)-1-i) * (convstring[i] - 'A' + 10);
276             atoival += newval;
277             //Spew(DSRC_UI_Quickbox, ("hex: 16^%d * (%d) = %d * %d = %d\n",
278             //   strlen(convstring)-1-i,convstring[i]-'A'+10,pow(16,strlen(convstring)-1-i),convstring[i]-'A'+10,newval));
279          }
280       }
281    }
282    else
283       atoival = 0;
284    *((uint *)(qbs->var)) = atoival;
285 
286    return TRUE;
287 }
288 
tng_quickbox_text_changed(void * ui_data,intptr_t user_data)289 uchar tng_quickbox_text_changed(void *ui_data, intptr_t user_data)
290 {
291    QuickboxSlot *qbs;
292    TNG *ptng;
293    int atoival, base, i, cap,newval;
294    char *convstring;
295    uchar okay;
296 
297 #ifndef NO_DUMMIES
298    void *dummy; dummy = ui_data;
299 #endif
300 
301    qbs = (QuickboxSlot *)user_data;
302    ptng = qbs->tng;
303    //Spew(DSRC_UI_Quickbox, ("Hey, text changed to: %s\n",TNG_TX_GETLINE(qbs->aux_tng,0)));
304    if (qbs->vartype == QB_TEXT_SLOT)
305    {
306       if (!(qbs->options & QB_RD_ONLY))
307          strcpy(((char *)(qbs->var)), TNG_TX_GETLINE(qbs->aux_tng, 0));
308    }
309    if (qbs->vartype == QB_FIX_SLOT)
310       quickbox_fix_text_changed(qbs);
311    else if (qbs->vartype == QB_UINT_SLOT)
312       quickbox_uint_text_changed(qbs);
313    else if ((qbs->vartype == QB_INT_SLOT) || (qbs->vartype == QB_BYTE_SLOT) || (qbs->vartype == QB_SHORT_SLOT))
314    {
315       base = 10;
316       //Spew(DSRC_UI_Quickbox, ("Hey, at top of parsing algorithm!\n"));
317       if (qbs->options & QB_HEX) {  base = 16; cap = 10; }
318       if (qbs->options & QB_OCTAL) {  base = 8; cap = 8; }
319       if (qbs->options & QB_BINARY) {   base = 2; cap = 2; }
320       convstring = TNG_TX_GETLINE(qbs->aux_tng, 0);
321       if (base == 10)
322       {
323          atoival = atoi(convstring);
324       }
325       else
326       {
327          atoival = 0;
328          okay = TRUE;
329          for (i=0; i<strlen(convstring); i++)
330          {
331             convstring[i] = toupper(convstring[i]);
332             switch(base)
333             {
334                case 16:
335                   if ((convstring[i] < '0') || ((convstring[i] > '9') && (convstring[i] < 'A')) || (convstring[i] > 'F'))
336                      okay = FALSE;
337                   break;
338                case 8:
339                   if ((convstring[i] < '0') || (convstring[i] > '7'))
340                      okay = FALSE;
341                   break;
342                case 2:
343                   if ((convstring[i] < '0') || (convstring [i] > '1'))
344                      okay = FALSE;
345                   break;
346             }
347          }
348          if (okay)
349          {
350             //Spew(DSRC_UI_Quickbox, ("convstring = %s base = %d\n", convstring,base));
351             for (i=0; i<strlen(convstring); i++)
352             {
353                //Spew(DSRC_UI_Quickbox, ("i = %d  convstring[i] = %c(%d)\n",i,convstring[i],convstring[i]));
354                if ((convstring[i] - '0') < cap)
355                {
356                   newval = pow(base,strlen(convstring)-1-i) * (convstring[i] - '0');
357                   atoival += newval;
358                   //Spew(DSRC_UI_Quickbox, ("%d^%d * (%d) = %d * %d = %d\n",
359                   //   base,strlen(convstring)-1-i,convstring[i]-'0',pow(base,strlen(convstring) - 1 - i),convstring[i]-'0',newval));
360                }
361                else if ((base == 16) && (convstring[i] >= 'A'))
362                {
363                   newval = pow(16,strlen(convstring)-1-i) * (convstring[i] - 'A' + 10);
364                   atoival += newval;
365                   //Spew(DSRC_UI_Quickbox, ("hex: 16^%d * (%d) = %d * %d = %d\n",
366                   //   strlen(convstring)-1-i,convstring[i]-'A'+10,pow(16,strlen(convstring)-1-i),convstring[i]-'A'+10,newval));
367                }
368             }
369          }
370          else
371             atoival = 0;
372       }
373       if ((qbs->options & QB_BOUNDED) || (qbs->options & QB_CYCLE))
374       {
375          if (atoival < (int)qbs->p1)
376             atoival = (int)qbs->p1;
377          if (atoival > (int)qbs->p2)
378             atoival = (int)qbs->p2;
379       }
380       //Spew(DSRC_UI_Quickbox, ("**** atoival = %d(%u) vs %d(%u)\n",atoival,atoival,(ubyte)atoival, (ubyte)atoival));
381       switch (qbs->vartype)
382       {
383          case QB_INT_SLOT:  *((int *)(qbs->var)) = (int)atoival; break;
384          case QB_UINT_SLOT:  *((uint *)(qbs->var)) = (uint)atoival; break;
385          case QB_SHORT_SLOT:  *((short *)(qbs->var)) = (short)atoival; break;
386          case QB_BYTE_SLOT:  *((ubyte *)(qbs->var)) = (ubyte)atoival; break;
387       }
388       //Spew(DSRC_UI_Quickbox, ("2:atoival = %d(%u)\n",*((ubyte *)(qbs->var)), *((ubyte *)(qbs->var))));
389    }
390    ptng->signal(ptng,TNG_SIGNAL_CHANGED);
391    gad_qbox_display_slot(qbs, TRUE);
392    return(FALSE);
393 }
394 
395 // Initializes the TNG
tng_quickbox_init(void * ui_data,TNG * ptng,TNGStyle * sty,ushort options,LGPoint slot_size,LGPoint spacing,LGPoint border,Ref left_id,Ref right_id)396 errtype tng_quickbox_init(void *ui_data, TNG *ptng, TNGStyle *sty, ushort options, LGPoint slot_size, LGPoint spacing, LGPoint border,
397    Ref left_id, Ref right_id)
398 {
399    TNG_quickbox *pqbtng;
400 
401    pqbtng = (TNG_quickbox *)GUI_MALLOC(ptng->ui_data, sizeof(TNG_quickbox));
402    //Spew(DSRC_UI_Quickbox, ("Starting quickbox init...\n"));
403 
404    TNGInit(ptng,sty,ui_data);
405    ptng->flags = TNG_BEVEL;
406    ptng->type_data = pqbtng;
407    ptng->draw_func = &tng_quickbox_2d_draw;
408    ptng->mousebutt = &tng_quickbox_mousebutt;
409    ptng->keycooked = &tng_quickbox_keycooked;
410    ptng->signal = &tng_quickbox_signal;
411 
412    pqbtng->tng_data = ptng;
413    pqbtng->size = tngZeroPt;
414    pqbtng->slot_size = slot_size;
415    pqbtng->spacing = spacing;
416    pqbtng->border = border;
417    pqbtng->options = options;
418    pqbtng->internal_margin = -1;
419    pqbtng->aux_size = TNG_QB_DEFAULT_SLIDER_SIZE;
420    pqbtng->slots = NULL;
421    pqbtng->current_slot = NULL;
422    pqbtng->size.x = slot_size.x + (2 * border.x);
423    pqbtng->size.y = 2 * border.y;
424    pqbtng->left_id = left_id;
425    pqbtng->right_id = right_id;
426    current_tng = ptng;
427    return(OK);
428 }
429 
430 // Deallocate all memory used by the TNG
tng_quickbox_destroy(TNG * ptng)431 errtype tng_quickbox_destroy(TNG *ptng)
432 {
433    GUI_DEALLOC(ptng->ui_data, ptng->type_data);
434    return(OK);
435 }
436 
437 // Draw the specified parts (may be all) of the TNG at screen coordinates loc
tng_draw_qb_int_slot(TNG * ptng,QuickboxSlot * curp,LGRect r)438 errtype tng_draw_qb_int_slot(TNG *ptng, QuickboxSlot *curp, LGRect r)
439 {
440    int *argp;
441    short *argsp;
442    ubyte *argbyp;
443    uint *argup;
444    LGRect argrect;     // Where the actual variable should go
445    short base;
446    LGPoint p1,p2,p3,p4;
447    char temp[100];
448 
449    // Set some variables, compute some stuff
450    if (curp->vartype == QB_INT_SLOT)
451       argp = (int *)curp->var;
452    if (curp->vartype == QB_UINT_SLOT)
453       argup = (uint *)curp->var;
454    if (curp->vartype == QB_SHORT_SLOT)
455       argsp = (short *)curp->var;
456    if (curp->vartype == QB_BYTE_SLOT)
457       argbyp = (ubyte *)curp->var;
458    r.ul.x += TNG_QB(ptng)->border.x;
459    r.ul.y += TNG_QB(ptng)->spacing.y;
460    argrect = r;
461    if (TNG_QB(ptng)->options & QB_ALIGNMENT)
462       argrect.ul.x = r.ul.x + TNG_QB(ptng)->internal_margin + (2 * TNG_QB(ptng)->spacing.x);
463    else
464       argrect.ul.x = r.ul.x + _text_width(ptng, curp->label) + (2 * TNG_QB(ptng)->spacing.x);
465    if (curp->options & QB_ARROWS)
466    {
467       // Goofy arrows
468       if (TNG_QB(ptng)->left_id != 0)
469          argrect.ul.x += resource_bm_width(TNG_QB(ptng)->left_id);
470       else
471          argrect.ul.x += ptng->style->frobsize.x;
472       if (TNG_QB(ptng)->right_id != 0)
473          argrect.lr.x -= resource_bm_width(TNG_QB(ptng)->right_id);
474       else
475          argrect.lr.x -= ptng->style->frobsize.x;
476    }
477 
478    // Draw that label
479    gr_set_fcolor(ptng->style->textColor);
480    _draw_text(ptng, curp->label, r.ul.x, r.ul.y+1);
481 
482    // Draw in the actual value of the variable
483    if (curp->vartype == QB_INT_SLOT)
484    {
485       if (curp->options & QB_HEX)
486          sprintf(temp, "hex %x", *argp);
487       else if (curp->options & QB_BINARY)
488 //       itoa(*argp, temp, 2);
489          sprintf(temp, "%d", *argp);
490       else if (curp->options & QB_OCTAL)
491          sprintf(temp, "oct %o", *argp);
492       else if (curp->options & QB_STRINGSET)
493          strcpy(temp, *(((char **)curp->p1) + *argp));
494       else
495          sprintf(temp, "%d", *argp);
496    }
497    else if (curp->vartype == QB_UINT_SLOT)
498    {
499       if (curp->options & QB_HEX)
500          sprintf(temp, "hex %x", *argup);
501       else if (curp->options & QB_BINARY)
502 //       itoa(*argup, temp, 2);
503          sprintf(temp, "%d", *argup);
504       else if (curp->options & QB_OCTAL)
505          sprintf(temp, "oct %o", *argup);
506       else if (curp->options & QB_STRINGSET)
507          strcpy(temp, *(((char **)curp->p1) + *argup));
508       else
509          sprintf(temp, "%d", *argup);
510    }
511    else if (curp->vartype == QB_SHORT_SLOT)
512    {
513       if (curp->options & QB_HEX)            // the h modifier in sprintf - is for short
514          sprintf(temp, "hex %hx", *argsp);
515       else if (curp->options & QB_BINARY)
516 //       itoa((int)*argsp, temp, 2);
517          sprintf(temp, "%d", *argsp);
518       else if (curp->options & QB_OCTAL)
519          sprintf(temp, "oct %ho", *argsp);
520       else if (curp->options & QB_STRINGSET)
521          strcpy(temp, *(((char **)curp->p1) + *argsp));
522       else
523          sprintf(temp, "%hd", *argsp);
524    }
525    else if (curp->vartype == QB_BYTE_SLOT)
526    {
527       if (curp->options & QB_HEX)
528          sprintf(temp, "hex %x", (uint)*argbyp);
529       else if (curp->options & QB_BINARY)
530 //       itoa((int)*argbyp, temp, 2);
531          sprintf(temp, "%d", (uint)*argbyp);
532       else if (curp->options & QB_OCTAL)
533          sprintf(temp, "oct %o", (uint)*argbyp);
534       else if (curp->options & QB_STRINGSET)
535          strcpy(temp, *(((char **)curp->p1) + *argbyp));
536       else
537          sprintf(temp, "%u", (uint)*argbyp);
538    }
539    else if (curp->vartype == QB_FIX_SLOT)
540    {
541       sprintf(temp,"%f",fix_float(*(fix*)curp->var));
542    }
543    _draw_text(ptng, temp, argrect.ul.x, argrect.ul.y+1);
544 
545    // Draw in goofy arrows, if they are necessary
546    if (curp->options & QB_ARROWS)
547    {
548       if (TNG_QB(ptng)->left_id != 0)
549       {
550          if (TNG_QB(ptng)->options & QB_ALIGNMENT)
551             draw_resource_bm(TNG_QB(ptng)->left_id, r.ul.x + TNG_QB(ptng)->internal_margin + TNG_QB(ptng)->spacing.x, r.ul.y);
552          else
553             draw_resource_bm(TNG_QB(ptng)->left_id, r.ul.x + _text_width(ptng, curp->label) + TNG_QB(ptng)->spacing.x, r.ul.y);
554       }
555       else
556       {
557          // Draw goofy left arrow
558          if (TNG_QB(ptng)->options & QB_ALIGNMENT)
559             base = r.ul.x + TNG_QB(ptng)->internal_margin + TNG_QB(ptng)->spacing.x;
560          else
561             base = r.ul.x + _text_width(ptng, curp->label) + TNG_QB(ptng)->spacing.x;
562          p1.x = base + (ptng->style->frobsize.x / 2);
563          p1.y = r.ul.y;
564          p2.x = base + ptng->style->frobsize.x;
565          p2.y = r.ul.y + (ptng->style->frobsize.y / 2);
566          p3.x = p1.x;
567          p3.y = r.ul.y + ptng->style->frobsize.y;
568          p4.x = base;
569          p4.y = p2.y;
570 
571          if (TNG_QB(ptng)->options & QB_ALIGNMENT)
572             p4.x = r.ul.x + TNG_QB(ptng)->internal_margin + TNG_QB(ptng)->spacing.x;
573          else
574             p4.x = r.ul.x + _text_width(ptng, curp->label) + TNG_QB(ptng)->spacing.x;
575          //Spew(DSRC_UI_Quickbox, ("p1 = (%d,%d) p2 = (%d,%d) p3 = (%d,%d) p4 = (%d,%d)\n",
576          //   p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,p4.x,p4.y));
577          gr_set_fcolor(ptng->style->textColor);
578          gr_int_line(p1.x, p1.y, p4.x, p4.y);
579          gr_int_line(p2.x, p2.y, p4.x, p4.y);
580          gr_int_line(p3.x, p3.y, p4.x, p4.y);
581       }
582       if (TNG_QB(ptng)->right_id != 0)
583          draw_resource_bm(TNG_QB(ptng)->right_id, r.lr.x - resource_bm_width(TNG_QB(ptng)->right_id), r.ul.y);
584       else
585       {
586          // Draw goofy right arrow
587          p1.x = r.lr.x - (ptng->style->frobsize.x / 2) - 2;
588          p1.y = r.ul.y;
589          p2.x = r.lr.x - ptng->style->frobsize.x - 2;
590          p2.y = r.ul.y + (ptng->style->frobsize.y / 2);
591          p3.x = p1.x;
592          p3.y = r.ul.y + ptng->style->frobsize.y;
593          p4.x = r.lr.x - 2;
594          p4.y = p2.y;
595          //Spew(DSRC_UI_Quickbox, ("p1 = (%d,%d) p2 = (%d,%d) p3 = (%d,%d) p4 = (%d,%d)\n",
596          //   p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,p4.x,p4.y));
597          gr_set_fcolor(ptng->style->textColor);
598          gr_int_line(p1.x, p1.y, p4.x, p4.y);
599          gr_int_line(p2.x, p2.y, p4.x, p4.y);
600          gr_int_line(p3.x, p3.y, p4.x, p4.y);
601       }
602    }
603    return(OK);
604 }
605 
tng_draw_qb_text_slot(TNG * ptng,QuickboxSlot * curp,LGRect r)606 errtype tng_draw_qb_text_slot(TNG *ptng, QuickboxSlot *curp, LGRect r)
607 {
608    // Should do something goofy here with text frobs...
609    // If this is auto-handled by having a one-line text TNG as a child of the
610    // quickbox TNG, that would be highly spiffy.
611 
612    char *argp;
613    LGRect argrect;     // Where the actual variable should go
614 
615    // Set some variables, compute some stuff
616    argp = (char *)curp->var;
617    r.ul.x += TNG_QB(ptng)->border.x;
618    r.ul.y += TNG_QB(ptng)->spacing.y;
619    argrect = r;
620    if (TNG_QB(ptng)->options & QB_ALIGNMENT)
621       argrect.ul.x = r.ul.x + TNG_QB(ptng)->internal_margin + TNG_QB(ptng)->spacing.x;
622    else
623       argrect.ul.x = r.ul.x + _text_width(ptng, curp->label) + TNG_QB(ptng)->spacing.x;
624 
625    // Draw that label
626    gr_set_fcolor(ptng->style->textColor);
627    _draw_text(ptng, curp->label, r.ul.x, r.ul.y+1);
628 
629    if (curp->options & QB_RD_ONLY)
630    {
631       _draw_text(ptng, (char *)(curp->var),argrect.ul.x, argrect.ul.y+1);
632    }
633    else if (strcmp((char *)curp->var, TNG_TX_GETLINE(curp->aux_tng,0)) != 0)
634    {
635       // If we are out of synch, rectify the problem
636       TNG_TX_CLEARLINE(curp->aux_tng,0);
637       TNG_TX_ADDSTRING(curp->aux_tng, (char *)curp->var);
638    }
639 
640 //   if (curp->aux_tng != NULL)
641 //      Spew(DSRC_UI_Quickbox, ("TX_GETLINE(curp->aux_tng,0) = %s\n",TNG_TX_GETLINE(curp->aux_tng,0)));
642 //   Spew(DSRC_UI_Quickbox, ("argp = <%s>\n",argp));
643 
644    return(OK);
645 }
646 
tng_draw_qb_bool_slot(TNG * ptng,QuickboxSlot * curp,LGRect r)647 errtype tng_draw_qb_bool_slot(TNG *ptng, QuickboxSlot *curp, LGRect r)
648 {
649    uchar *argp;
650    LGRect argrect;     // Where the actual variable should go
651    LGPoint p1,p2,p3,p4;
652    char temp[100];
653    short base;
654 
655    // Set some variables, compute some stuff
656    argp = (uchar *)curp->var;
657    r.ul.x += TNG_QB(ptng)->border.x;
658    r.ul.y += TNG_QB(ptng)->spacing.y;
659    argrect = r;
660    if (TNG_QB(ptng)->options & QB_ALIGNMENT)
661       argrect.ul.x = r.ul.x + TNG_QB(ptng)->internal_margin + (2 * TNG_QB(ptng)->spacing.x);
662    else
663       argrect.ul.x = r.ul.x + _text_width(ptng, curp->label) + (2 * TNG_QB(ptng)->spacing.x);
664    if (curp->options & QB_ARROWS)
665    {
666       // Goofy arrows
667       if (TNG_QB(ptng)->left_id != 0)
668          argrect.ul.x += resource_bm_width(TNG_QB(ptng)->left_id);
669       else
670          argrect.ul.x += ptng->style->frobsize.x;
671       if (TNG_QB(ptng)->right_id != 0)
672          argrect.lr.x -= resource_bm_width(TNG_QB(ptng)->right_id);
673       else
674          argrect.lr.x -= ptng->style->frobsize.x;
675    }
676 
677    // Draw that label
678    gr_set_fcolor(ptng->style->textColor);
679    _draw_text(ptng, curp->label, r.ul.x, r.ul.y+1);
680 
681    // Draw in the actual value of the variable
682    if (*argp)
683       strcpy(temp, "True");
684    else
685       strcpy(temp, "False");
686    _draw_text(ptng, temp, argrect.ul.x, argrect.ul.y+1);
687 
688    // Draw in goofy arrows, if they are necessary
689    if (curp->options & QB_ARROWS)
690    {
691       if (TNG_QB(ptng)->left_id != 0)
692       {
693          if (TNG_QB(ptng)->options & QB_ALIGNMENT)
694             draw_resource_bm(TNG_QB(ptng)->left_id, r.ul.x + TNG_QB(ptng)->internal_margin + TNG_QB(ptng)->spacing.x, r.ul.y);
695          else
696             draw_resource_bm(TNG_QB(ptng)->left_id, r.ul.x + _text_width(ptng, curp->label) + TNG_QB(ptng)->spacing.x, r.ul.y);
697       }
698       else
699       {
700          // Draw goofy left arrow
701          if (TNG_QB(ptng)->options & QB_ALIGNMENT)
702             base = r.ul.x + TNG_QB(ptng)->internal_margin + TNG_QB(ptng)->spacing.x;
703          else
704             base = r.ul.x + _text_width(ptng, curp->label) + TNG_QB(ptng)->spacing.x;
705          p1.x = base + (ptng->style->frobsize.x / 2);
706          p1.y = r.ul.y;
707          p2.x = base + ptng->style->frobsize.x;
708          p2.y = r.ul.y + (ptng->style->frobsize.y / 2);
709          p3.x = p1.x;
710          p3.y = r.ul.y + ptng->style->frobsize.y;
711          p4.x = base;
712          p4.y = p2.y;
713 
714          if (TNG_QB(ptng)->options & QB_ALIGNMENT)
715             p4.x = r.ul.x + TNG_QB(ptng)->internal_margin + TNG_QB(ptng)->spacing.x;
716          else
717             p4.x = r.ul.x + _text_width(ptng, curp->label) + TNG_QB(ptng)->spacing.x;
718          //Spew(DSRC_UI_Quickbox, ("p1 = (%d,%d) p2 = (%d,%d) p3 = (%d,%d) p4 = (%d,%d)\n",
719          //   p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,p4.x,p4.y));
720          gr_set_fcolor(ptng->style->textColor);
721          gr_int_line(p1.x, p1.y, p4.x, p4.y);
722          gr_int_line(p2.x, p2.y, p4.x, p4.y);
723          gr_int_line(p3.x, p3.y, p4.x, p4.y);
724       }
725       if (TNG_QB(ptng)->right_id != 0)
726          draw_resource_bm(TNG_QB(ptng)->right_id, r.lr.x - resource_bm_width(TNG_QB(ptng)->right_id), r.ul.y);
727       else
728       {
729          // Draw goofy right arrow
730          p1.x = r.lr.x - (ptng->style->frobsize.x / 2) - 2;
731          p1.y = r.ul.y;
732          p2.x = r.lr.x - ptng->style->frobsize.x - 2;
733          p2.y = r.ul.y + (ptng->style->frobsize.y / 2);
734          p3.x = p1.x;
735          p3.y = r.ul.y + ptng->style->frobsize.y;
736          p4.x = r.lr.x - 2;
737          p4.y = p2.y;
738          //Spew(DSRC_UI_Quickbox, ("p1 = (%d,%d) p2 = (%d,%d) p3 = (%d,%d) p4 = (%d,%d)\n",
739          //   p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,p4.x,p4.y));
740          gr_set_fcolor(ptng->style->textColor);
741          gr_int_line(p1.x, p1.y, p4.x, p4.y);
742          gr_int_line(p2.x, p2.y, p4.x, p4.y);
743          gr_int_line(p3.x, p3.y, p4.x, p4.y);
744       }
745    }
746    return(OK);
747 }
748 
tng_draw_qb_pb_slot(TNG * ptng,QuickboxSlot * curp,LGRect r)749 errtype tng_draw_qb_pb_slot(TNG *ptng, QuickboxSlot *curp, LGRect r)
750 {
751    r.ul.x += TNG_QB(ptng)->border.x;
752    r.ul.y += TNG_QB(ptng)->spacing.y;
753    // Draw that label, if necessary
754    if (curp->p2 != 0)
755    {
756       gr_set_fcolor(ptng->style->textColor);
757       _draw_text(ptng, curp->label, r.ul.x, r.ul.y+1);
758    }
759 
760    return(OK);
761 }
762 
763 // assumes all appropriate setup has already been done!
tng_quickbox_2d_draw(TNG * ptng,ushort us,LGPoint loc)764 errtype tng_quickbox_2d_draw(TNG *ptng, ushort us, LGPoint loc)
765 {
766    TNG_quickbox *pqbtng;
767    QuickboxSlot *curp;
768    LGRect r;
769 
770    //Spew(DSRC_UI_Quickbox, ("TNG quickbox 2d Draw at (%d, %d) -- partmask = %x\n",loc.x,loc.y,partmask));
771    TNG_IF_OBSCURED(ptng)
772    {
773       return(OK);
774    }
775    ptng->signal(ptng, TNG_SIGNAL_EXPOSE);
776    pqbtng = TNG_QB(ptng);
777    if ((pqbtng->options & QB_ALIGNMENT) && (pqbtng->internal_margin == -1))
778       return(OK);
779    TNGDrawBase(ptng, loc, pqbtng->size);
780    r.ul.x = loc.x + pqbtng->border.x;
781    r.ul.y = loc.y + pqbtng->border.y;
782    r.lr.x = r.ul.x + pqbtng->size.x - pqbtng->border.x - 1;
783    r.lr.y = r.ul.y + pqbtng->size.y;
784 
785    // Let us iterate through the slots, shall we?
786    curp = QB_SLOTS(ptng);
787    while (curp != NULL)
788    {
789       gad_qbox_display_slot(curp, FALSE);
790       curp = curp->next;
791    }
792 
793    return(OK);
794 }
795 
796 // Fill in ppt with the size...
tng_quickbox_size(TNG * ptng,LGPoint * ppt)797 errtype tng_quickbox_size(TNG *ptng, LGPoint *ppt)
798 {
799    *ppt = TNG_QB(ptng)->size;
800    return(OK);
801 }
802 
803 // Returns the current "value" of the TNG
tng_quickbox_getvalue(TNG * ptng)804 int tng_quickbox_getvalue(TNG *ptng)
805 {
806    int i = 0;
807    QuickboxSlot *pqs, *curr;
808 
809    curr = TNG_QB(ptng)->current_slot;
810    pqs = TNG_QB(ptng)->slots;
811    while ((pqs != curr) && (pqs != NULL))
812    {
813       i++;
814       pqs = pqs->next;
815    }
816    if (pqs == NULL)
817       i = -1;
818    return(i);
819 }
820 
821 // React appropriately for receiving the specified cooked key
tng_quickbox_keycooked(TNG * ptng,ushort key)822 uchar tng_quickbox_keycooked(TNG *ptng, ushort key)
823 {
824    int code = key & 0xff;
825    uchar retval =FALSE;
826    QuickboxSlot *qbs, *prevp, *curp;
827 
828    qbs = QB_CURRENT(ptng);
829 //   Spew(DSRC_UI_Quickbox, ("keyboard CB: %x\n", code));
830    if (qbs->aux_tng != NULL)
831       IF_SET_RV(qbs->aux_tng->keycooked(qbs->aux_tng, key));
832    if (qbs->options & QB_ARROWS)
833    {
834       if (code == QB_LEFT_KEY)
835          IF_SET_RV(ptng->signal(ptng, TNG_SIGNAL_DECREMENT));
836       if (code == QB_RIGHT_KEY)
837          IF_SET_RV(ptng->signal(ptng, TNG_SIGNAL_INCREMENT));
838    }
839    if (code == QB_DOWN_KEY)
840    {
841       if (qbs->next != NULL)
842       {
843          QB_CURRENT(ptng) = qbs->next;
844       }
845       else
846       {
847          QB_CURRENT(ptng) = QB_SLOTS(ptng);
848       }
849       gad_qbox_display_slot(qbs, TRUE);
850       gad_qbox_display_slot(QB_CURRENT(ptng), TRUE);
851    }
852    if (code == QB_UP_KEY)
853    {
854       prevp = NULL;
855       curp = QB_SLOTS(ptng);
856       while ((curp != qbs) && (curp != NULL))
857       {
858          prevp = curp;
859          curp = curp->next;
860       }
861       if (prevp == NULL)
862       {
863          curp = QB_SLOTS(ptng);
864          while ((curp != NULL) && (curp->next != NULL))
865             curp = curp->next;
866          QB_CURRENT(ptng) = curp;
867       }
868       else
869       {
870          QB_CURRENT(ptng) = prevp;
871       }
872       gad_qbox_display_slot(qbs, TRUE);
873       gad_qbox_display_slot(QB_CURRENT(ptng),TRUE);
874    }
875    IF_SET_RV(tng_cb_keycooked(ptng, key));
876    if ((code == QB_UP_KEY) || (code == QB_DOWN_KEY) || (code == QB_LEFT_KEY) || (code == QB_RIGHT_KEY))
877       retval = TRUE;
878    return(retval);
879 }
880 
881 // React appropriately for receiving the specified mouse button event
tng_quickbox_mousebutt(TNG * ptng,uchar type,LGPoint loc)882 uchar tng_quickbox_mousebutt(TNG *ptng, uchar type, LGPoint loc)
883 {
884    int localy, tw;
885    int slotcount = 0;
886    TNG_quickbox *pqbtng;
887    QuickboxSlot *oldcur, *curp;
888    uchar retval = FALSE;
889 
890    if ((type == TNG_MOUSE_LDOWN) || (type == TNG_MOUSE_RDOWN))
891    {
892       pqbtng = TNG_QB(ptng);
893       localy = loc.y - pqbtng->border.y;
894       curp = QB_SLOTS(ptng);
895       while ((curp != NULL) && (localy > (pqbtng->spacing.y + pqbtng->slot_size.y)))
896       {
897          localy -= pqbtng->spacing.y + pqbtng->slot_size.y;
898          slotcount++;
899          curp = curp->next;
900       }
901       if (curp != NULL)
902       {
903          if (localy <= pqbtng->slot_size.y)
904          {
905             oldcur = QB_CURRENT(ptng);
906             QB_CURRENT(ptng) = curp;
907             gad_qbox_display_slot(oldcur, TRUE);
908             gad_qbox_display_slot(curp, TRUE);
909          }
910          if (curp->options & QB_ARROWS)
911          {
912             if (curp->vartype == QB_BOOL_SLOT)
913             {
914                ptng->signal(ptng, TNG_SIGNAL_INCREMENT);
915             }
916             else
917             {
918                if (TNG_QB(ptng)->options & QB_ALIGNMENT)
919                   tw = TNG_QB(ptng)->internal_margin;
920                else
921                   tw = _text_width(ptng, curp->label);
922                if ((pqbtng->left_id != 0) &&
923                   (loc.x < resource_bm_width(pqbtng->left_id) + tw + pqbtng->border.x + (2 * pqbtng->spacing.x)))
924                {
925                   if (type == TNG_MOUSE_LDOWN)
926                      ptng->signal(ptng, TNG_SIGNAL_DECREMENT);
927                   else
928                      tng_decrem_slot(ptng, 10);
929                }
930                else if (loc.x < tw + pqbtng->border.x + ptng->style->frobsize.x + (2 * pqbtng->spacing.x))
931                {
932                   if (type == TNG_MOUSE_LDOWN)
933                      ptng->signal(ptng, TNG_SIGNAL_DECREMENT);
934                   else
935                      tng_decrem_slot(ptng, 10);
936                }
937                if ((pqbtng->right_id != 0) &&
938                   (loc.x > pqbtng->size.x - pqbtng->border.x - resource_bm_width(pqbtng->right_id) - 2 ))
939                {
940                   if (type == TNG_MOUSE_LDOWN)
941                      ptng->signal(ptng, TNG_SIGNAL_INCREMENT);
942                   else
943                      tng_increm_slot(ptng, 10);
944                }
945                else if (loc.x > pqbtng->size.x - pqbtng->border.x - ptng->style->frobsize.x - 2)
946                {
947                   if (type == TNG_MOUSE_LDOWN)
948                      ptng->signal(ptng, TNG_SIGNAL_INCREMENT);
949                   else
950                      tng_increm_slot(ptng, 10);
951                }
952             }
953          }
954       }
955    }
956    IF_SET_RV(tng_cb_mousebutt(ptng,type,loc));
957 //   retval = TRUE;
958    return(retval);
959 }
960 
961 // Handle incoming signals
tng_quickbox_signal(TNG * ptng,ushort signal)962 uchar tng_quickbox_signal(TNG *ptng, ushort signal)
963 {
964    uchar retval = FALSE;
965    if (signal & TNG_SIGNAL_INCREMENT)
966       tng_increm_slot(ptng, 1);
967    if (signal & TNG_SIGNAL_DECREMENT)
968       tng_decrem_slot(ptng, 1);
969 //   if (signal & TNG_SIGNAL_CHANGED)
970 //      TNG_DRAW(ptng);
971    IF_SET_RV(tng_cb_signal(ptng,signal));
972    retval = TRUE;
973    return(retval);
974 }
975 
976 // Add a line to a quickbox.  slot_type describes the type of slot, var is a pointer to the variable to be
977 // displaying, and slot_options describes any additional modifiers to the qbox.  Note that some bizarre-o
978 // combinations of options and types might not be implemented.
tng_quickbox_add(char * label,int slot_type,void * var,ulong slot_options)979 errtype tng_quickbox_add(char *label, int slot_type, void *var, ulong slot_options)
980 {
981    return(tng_quickbox_add_parm(label,slot_type,var,slot_options,0,0));
982 }
983 
984 // Just like gad_qbox_add but allows two parameters to be set for the slot.  Certain slot options require
985 // this form of accessing.
tng_quickbox_add_parm(char * label,int slot_type,void * var,ulong slot_options,intptr_t parm1,intptr_t parm2)986 errtype tng_quickbox_add_parm(char *label, int slot_type, void *var, ulong slot_options, intptr_t parm1, intptr_t parm2)
987 {
988    QuickboxSlot *newslot, *curp;
989 
990    newslot = (QuickboxSlot *)malloc(sizeof(QuickboxSlot));
991 
992    // Fill out newslot
993    num_slots++;
994    newslot->options = slot_options;
995    newslot->vartype = slot_type;
996    newslot->var = var;
997    newslot->p1 = parm1;
998    newslot->p2 = parm2;
999    newslot->tng = current_tng;
1000    newslot->next = NULL;
1001    newslot->aux_tng = NULL;
1002    newslot->aux_size = tngZeroPt;
1003    newslot->label = (char *)malloc(sizeof(char) * 100);
1004    strcpy(newslot->label, label);
1005 
1006    // Update size of overall box
1007    if (num_slots != 1)
1008       TNG_QB(current_tng)->size.y += TNG_QB(current_tng)->spacing.y;
1009    TNG_QB(current_tng)->size.y += TNG_QB(current_tng)->slot_size.y;
1010 
1011    // Add at end of current box's list of slots
1012    if (QB_CURRENT(current_tng) == NULL)
1013       QB_CURRENT(current_tng) = newslot;
1014    curp = QB_SLOTS(current_tng);
1015    while ((curp != NULL) && (curp->next != NULL))
1016       curp = curp->next;
1017 
1018    if (curp == NULL)
1019       QB_SLOTS(current_tng) = newslot;
1020    else
1021       curp->next = newslot;
1022 
1023    return (OK);
1024 }
1025 
1026 // This represents that the quickbox is done being created and is ready for display, input, etc.
tng_quickbox_end()1027 errtype tng_quickbox_end()
1028 {
1029    int cid, slotcount = 0;
1030    int max, min;
1031    QuickboxSlot *curp;
1032    ulong text_options;
1033    LGRect *sdim;
1034    LGPoint aux_size;
1035    TNG_quickbox *pqbtng;
1036 /*
1037    Spew(DSRC_UI_Quickbox, ("Beginning of the qbox_end\n"));
1038    if (current_tng != NULL)
1039       Spew(DSRC_UI_Quickbox, ("current_tng not null\n"));
1040    else
1041       Spew(DSRC_UI_Quickbox, ("current_tng IS NULL!!!! AIAIAIIAGHGGGGHHHHH!\n"));
1042 */
1043    pqbtng = TNG_QB(current_tng);
1044 
1045    // compute options-type stuff...
1046    if (pqbtng->options & QB_ALIGNMENT)
1047    {
1048      pqbtng->internal_margin = _label_extent(current_tng);
1049      //Spew(DSRC_UI_Quickbox, ("Yay alignment  margin = %d!!\n",pqbtng->internal_margin));
1050    }
1051 //   else
1052 //   {
1053 //     Spew(DSRC_UI_Quickbox, ("There is NOOOOO alignment!!\n"));
1054 //   }
1055 
1056    if (pqbtng->options & QB_AUTOSIZE)
1057    {
1058       //Spew(DSRC_UI_Quickbox, ("Autosizing...\n"));
1059       pqbtng->slot_size.x = _total_extent(current_tng);
1060    }
1061 
1062   // Make children TNGs, if necessary
1063    curp = QB_SLOTS(current_tng);
1064    while (curp != NULL)
1065    {
1066       if (curp->options & QB_STRINGSET)
1067       {
1068          curp->options |= QB_ARROWS;
1069          curp->p2--;
1070       }
1071       if ((curp->options & QB_SLIDER) ||
1072           (curp->vartype == QB_PUSHBUTTON_SLOT) ||
1073           (curp->vartype == QB_TEXT_SLOT) ||
1074           (curp->vartype == QB_FIX_SLOT) ||
1075           ( ((curp->vartype == QB_SHORT_SLOT) || (curp->vartype == QB_BYTE_SLOT) || (curp->vartype == QB_INT_SLOT) || (curp->vartype == QB_UINT_SLOT))
1076             && !(curp->options & QB_RD_ONLY)))
1077       {
1078          sdim = (LGRect *)malloc(sizeof(LGRect));
1079          if ((curp->options & QB_SLIDER) ||
1080             (((curp->vartype == QB_SHORT_SLOT) || (curp->vartype == QB_INT_SLOT) || (curp->vartype == QB_BYTE_SLOT) || (curp->vartype == QB_UINT_SLOT)
1081                || (curp->vartype == QB_FIX_SLOT))
1082 
1083                && !(curp->options & QB_RD_ONLY) && !(curp->options & QB_ARROWS)))
1084             sdim->ul.x = pqbtng->size.x - pqbtng->aux_size - pqbtng->border.x;
1085          else if (curp->vartype == QB_PUSHBUTTON_SLOT)
1086          {
1087             if (curp->p2 == 0)
1088                sdim->ul.x = pqbtng->border.x;
1089             else
1090                sdim->ul.x = pqbtng->size.x - resource_bm_width(*((Ref *)curp->p2));
1091          }
1092          else if ((curp->vartype == QB_TEXT_SLOT) && (!(curp->options & QB_RD_ONLY)))
1093          {
1094             if (pqbtng->options & QB_ALIGNMENT)
1095                sdim->ul.x = pqbtng->internal_margin + pqbtng->border.x + pqbtng->spacing.x;
1096             else
1097                sdim->ul.x = _text_width(current_tng, curp->label) + pqbtng->border.x + pqbtng->spacing.x;
1098          }
1099          sdim->lr.x = pqbtng->size.x - pqbtng->border.x;
1100          sdim->ul.y = (slotcount * (pqbtng->slot_size.y + pqbtng->spacing.y)) + pqbtng->border.y;
1101          sdim->lr.y = sdim->ul.y + pqbtng->slot_size.y;
1102          aux_size.x = RectWidth(sdim) - 1;
1103          aux_size.y = RectHeight(sdim) - 1;
1104          curp->aux_size = aux_size;
1105          //Spew(DSRC_UI_Quickbox, ("aux_size = (%d,%d)  sdim = (%d,%d)(%d,%d)\n",aux_size.x, aux_size.y,
1106          //   RECT_EXPAND_ARGS(sdim)));
1107          if (curp->options & QB_SLIDER)
1108          {
1109             min = (int)curp->p1;
1110             max = (int)curp->p2;
1111             //Spew(DSRC_UI_Quickbox, ("About to create slider, sdim = (%d, %d) (%d, %d), max = %d, min = %d\n",
1112             //   RECT_EXPAND_ARGS(sdim), max, min));
1113             TNG_CREATE_SLIDER(current_tng->ui_data, sdim->ul, &(curp->aux_tng), current_tng->style, TNG_SL_HORIZONTAL,
1114                min, max, *((int *)(curp->var)), 1, aux_size);
1115 //            TNG_DRAW(curp->aux_tng);
1116             tng_install_callback(curp->aux_tng, TNG_EVENT_SIGNAL, TNG_SIGNAL_CHANGED, &tng_quickbox_scroll_changed, (intptr_t)curp, &cid);
1117          }
1118          if (curp->vartype == QB_PUSHBUTTON_SLOT)
1119          {
1120             if (curp->p2 == 0)
1121                TNG_CREATE_PUSHBUTTON(current_tng->ui_data, sdim->ul,&(curp->aux_tng), current_tng->style, TEXT_TYPE, (void *)curp->label, aux_size);
1122             else
1123                TNG_CREATE_PUSHBUTTON(current_tng->ui_data, sdim->ul, &(curp->aux_tng), current_tng->style, RESOURCE_TYPE, (void *)curp->p2, aux_size);
1124             tng_install_callback(curp->aux_tng, TNG_EVENT_SIGNAL, TNG_SIGNAL_SELECT, (TNGCallback)curp->var, curp->p1, &cid);
1125          }
1126          if (((curp->vartype == QB_SHORT_SLOT) || (curp->vartype == QB_INT_SLOT) || (curp->vartype == QB_UINT_SLOT)
1127             || (curp->vartype == QB_BYTE_SLOT) || (curp->vartype == QB_FIX_SLOT))
1128             && !(curp->options & QB_RD_ONLY) && !(curp->options & QB_SLIDER)
1129             && !(curp->options & QB_ARROWS))
1130          {
1131             text_options = TNG_TG_SINGLE_LINE;
1132             TNG_CREATE_TEXT(current_tng->ui_data, sdim->ul, &(curp->aux_tng), current_tng->style, text_options, aux_size);
1133 #ifdef STARTING_VALUE_STRINGS
1134             if (curp->vartype == QB_INT_SLOT)
1135                sprintf (temp, "%d", *((int *)(curp->var)));
1136             else if (curp->vartype == QB_UINT_SLOT)
1137                sprintf (temp, "%d", *((uint *)(curp->var)));
1138             else if (curp->vartype == QB_SHORT_SLOT)
1139                sprintf (temp, "%d", *((short *)(curp->var)));
1140             else if (curp->vartype == QB_BYTE_SLOT)
1141                sprintf (temp, "%d", *((ubyte *)(curp->var)));
1142             else if (curp->vartype == QB_FIX_SLOT)
1143                sprintf (temp, "%f", fix_float(*((fix *)(curp->var))));
1144             TNG_TX_ADDSTRING(curp->aux_tng, "");
1145 #endif
1146             tng_install_callback(curp->aux_tng, TNG_EVENT_SIGNAL, TNG_SIGNAL_SELECT, tng_quickbox_text_changed, (intptr_t)curp, &cid);
1147          }
1148          if ((curp->vartype == QB_TEXT_SLOT) && (!(curp->options & QB_RD_ONLY)))
1149          {
1150             text_options = TNG_TG_SINGLE_LINE;
1151             //Spew(DSRC_UI_Quickbox, ("About to make textgadg, slotcount = %d, sdim = (%d,%d)(%d,%d)\n",slotcount,RECT_EXPAND_ARGS(sdim)));
1152             TNG_CREATE_TEXT(current_tng->ui_data, sdim->ul, &(curp->aux_tng), current_tng->style, text_options, aux_size);
1153             TNG_TX_ADDSTRING(curp->aux_tng, (char *)curp->var);
1154             tng_install_callback(curp->aux_tng, TNG_EVENT_SIGNAL, TNG_SIGNAL_SELECT, tng_quickbox_text_changed, (intptr_t)curp, &cid);
1155          }
1156       }
1157       curp = curp->next;
1158       slotcount++;
1159    }
1160    TNG_DRAW(current_tng);
1161    return(OK);
1162 }
1163 
_draw_text(TNG * ptng,char * txt,int x_coord,int y_coord)1164 errtype _draw_text(TNG *ptng, char *txt, int x_coord, int y_coord)
1165 {
1166    return(TNGDrawText(ptng->style->font, txt, x_coord, y_coord));
1167 }
1168 
1169 // Returns width of text, in pixels
_text_width(TNG * ptng,char * t)1170 int _text_width(TNG *ptng, char *t)
1171 {
1172    int retval;
1173    gr_set_font(FontLock(ptng->style->font));
1174    retval = gr_string_width(t);
1175    ResUnlock(ptng->style->font);
1176    return(retval);
1177 }
1178 
gad_qbox_display_slot(QuickboxSlot * qbs,uchar recurse)1179 errtype gad_qbox_display_slot(QuickboxSlot *qbs, uchar recurse)
1180 {
1181    LGRect srect;
1182    TNG *ptng;
1183    QuickboxSlot *curp;
1184    int slotcount = 0;
1185 
1186    ptng = qbs->tng;
1187    curp = QB_SLOTS(ptng);
1188    while ((curp != NULL) && (curp != qbs))
1189    {
1190       slotcount++;
1191       curp = curp->next;
1192    }
1193       _slot_rectangle(ptng, slotcount, &srect);
1194       uiHideMouse(&srect);
1195       gr_set_fcolor(ptng->style->backColor);
1196       gr_rect(srect.ul.x, srect.ul.y, srect.lr.x, srect.lr.y);
1197       if (curp == QB_CURRENT(ptng))
1198       {
1199          gr_set_fcolor(ptng->style->altTextColor);
1200          gr_box(srect.ul.x, srect.ul.y, srect.lr.x, srect.lr.y);
1201       }
1202       switch (curp->vartype)
1203       {
1204          case QB_BYTE_SLOT:
1205          case QB_SHORT_SLOT:
1206          case QB_INT_SLOT:
1207          case QB_UINT_SLOT:
1208          case QB_FIX_SLOT:
1209             tng_draw_qb_int_slot(ptng, curp, srect);
1210             break;
1211          case QB_TEXT_SLOT:
1212             tng_draw_qb_text_slot(ptng, curp, srect);
1213             break;
1214          case QB_BOOL_SLOT:
1215             tng_draw_qb_bool_slot(ptng, curp, srect);
1216             break;
1217          case QB_PUSHBUTTON_SLOT:
1218             tng_draw_qb_pb_slot(ptng, curp, srect);
1219             break;
1220       }
1221       if (recurse && (qbs->aux_tng != NULL))
1222          TNG_DRAW(qbs->aux_tng);
1223       uiShowMouse(&srect);
1224    return(OK);
1225 }
1226 
tng_quickbox_rename_slot(TNG * qb,int slot_num,char * new_name)1227 errtype tng_quickbox_rename_slot(TNG *qb, int slot_num, char *new_name)
1228 {
1229    QuickboxSlot *psl;
1230    int count = 0;
1231 
1232    psl = QB_SLOTS(qb);
1233    while (count < slot_num)
1234    {
1235       psl = psl->next;
1236       count++;
1237    }
1238    strcpy(psl->label, new_name);
1239    return(OK);
1240 }
1241 
_slot_rectangle(TNG * qb,int slot_num,LGRect * slot_rect)1242 errtype _slot_rectangle(TNG *qb, int slot_num, LGRect *slot_rect)
1243 {
1244    slot_rect->ul = TNG_ABSLOC(qb);
1245    slot_rect->ul.y += (slot_num * (TNG_QB(qb)->slot_size.y + TNG_QB(qb)->spacing.y)) + 1;
1246    slot_rect->ul.x += TNG_QB(qb)->border.x;
1247    slot_rect->lr.x = slot_rect->ul.x + TNG_QB(qb)->size.x - (2 * TNG_QB(qb)->border.x);
1248    slot_rect->lr.y = slot_rect->ul.y + TNG_QB(qb)->slot_size.y + TNG_QB(qb)->spacing.y - 1;
1249 //   mprintf ("spacing = (%d,%d)\n",TNG_QB(qb)->spacing.x, TNG_QB(qb)->spacing.y);
1250 //   mprintf ("slot_rectangle, slot %d = (%d, %d)(%d, %d)\n",slot_num, RECT_EXPAND_ARGS(slot_rect));
1251    return(OK);
1252 }
1253 
_label_extent(TNG * ptng)1254 int _label_extent(TNG *ptng)
1255 {
1256    QuickboxSlot *qbs;
1257    int retval = 0, v;
1258 
1259    qbs = QB_SLOTS(ptng);
1260    while (qbs != NULL)
1261    {
1262       if (((qbs->vartype == QB_PUSHBUTTON_SLOT) && (qbs->p2 == 0)) ||
1263          ((qbs->vartype == QB_TEXT_SLOT) && (qbs->options & QB_RD_ONLY)))
1264          v = 0;
1265       else
1266          v = _text_width(ptng, qbs->label);
1267       if (v > retval)
1268          retval = v;
1269       qbs = qbs->next;
1270    }
1271    //Spew(DSRC_UI_Quickbox, ("label extent = %d\n",retval));
1272    return(retval);
1273 }
1274 
_total_extent(TNG * ptng)1275 int _total_extent(TNG *ptng)
1276 {
1277    QuickboxSlot *qbs;
1278    int v, retval;
1279    char temp[40];
1280    retval = 0;
1281 
1282    qbs = QB_SLOTS(ptng);
1283    while (qbs != NULL)
1284    {
1285       if (TNG_QB(ptng)->options & QB_ALIGNMENT)
1286          v = TNG_QB(ptng)->internal_margin;
1287       else
1288          v = _text_width(ptng, qbs->label);
1289       v += TNG_QB(ptng)->spacing.x + (2 * TNG_QB(ptng)->border.x);
1290       switch(qbs->vartype)
1291       {
1292          case QB_SHORT_SLOT:
1293          case QB_BYTE_SLOT:
1294          case QB_INT_SLOT:
1295          case QB_UINT_SLOT:
1296          case QB_FIX_SLOT:
1297             if (qbs->options & QB_SLIDER)
1298                v += TNG_QB(ptng)->aux_size;
1299             if (qbs->options & QB_RD_ONLY)
1300             {
1301                if (qbs->vartype == QB_INT_SLOT)
1302                   sprintf(temp, "%d", *((int *)(qbs->var)));
1303                else if (qbs->vartype == QB_UINT_SLOT)
1304                   sprintf(temp, "%d", *((uint *)(qbs->var)));
1305                else if (qbs->vartype == QB_SHORT_SLOT)
1306                   sprintf(temp, "%d", *((short *)(qbs->var)));
1307                else if (qbs->vartype == QB_BYTE_SLOT)
1308                   sprintf(temp, "%d", *((ubyte *)(qbs->var)));
1309                else if (qbs->vartype == QB_FIX_SLOT)
1310                   sprintf (temp, "%f", fix_float(*((fix *)(qbs->var))));
1311                v += _text_width(ptng, temp);
1312             }
1313             else
1314             {
1315                v += TNG_QB(ptng)->aux_size;
1316             }
1317             if (qbs->options & QB_ARROWS)
1318             {
1319                if (TNG_QB(ptng)->left_id == 0)
1320                   v += ptng->style->frobsize.x;
1321                else
1322                   v += resource_bm_width(TNG_QB(ptng)->left_id);
1323                if (TNG_QB(ptng)->right_id == 0)
1324                   v += ptng->style->frobsize.x;
1325                else
1326                   v += resource_bm_width(TNG_QB(ptng)->right_id);
1327             }
1328             break;
1329          case QB_BOOL_SLOT:
1330             if (qbs->options & QB_SLIDER)
1331                v += TNG_QB(ptng)->aux_size;
1332             if (qbs->options & QB_RD_ONLY)
1333             {
1334                if (*((uchar *)(qbs->var)))
1335                   sprintf(temp, "TRUE");
1336                else
1337                   sprintf(temp, "FALSE");
1338                v += _text_width(ptng, temp);
1339             }
1340             else
1341             {
1342                v += TNG_QB(ptng)->aux_size;
1343             }
1344             if (qbs->options & QB_ARROWS)
1345             {
1346                if (TNG_QB(ptng)->left_id == 0)
1347                   v += ptng->style->frobsize.x;
1348                else
1349                   v += resource_bm_width(TNG_QB(ptng)->left_id);
1350                if (TNG_QB(ptng)->right_id == 0)
1351                   v += ptng->style->frobsize.x;
1352                else
1353                   v += resource_bm_width(TNG_QB(ptng)->right_id);
1354             }
1355             break;
1356          case QB_TEXT_SLOT:
1357             if (!(qbs->options & QB_RD_ONLY))
1358                v += TNG_QB(ptng)->aux_size;
1359             break;
1360          case QB_PUSHBUTTON_SLOT:
1361             if (qbs->p2 != 0)
1362                v += resource_bm_width(*((Ref *)(qbs->p2)));
1363             break;
1364       }
1365       if (v > retval)
1366          retval = v;
1367       qbs = qbs->next;
1368    }
1369 
1370    return(retval);
1371 }
1372 
1373 
1374 
1375 
1376 
1377 
1378 
1379 
1380 
1381 
1382 
1383 
1384 
1385 
1386 
1387 
1388 
1389 
1390 
1391 
1392 
1393 
1394 
1395 
1396