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 // Source code for Quickbox Gadgets
20 
21 // THINGS STILL NEEDED:
22 // Concept of alignment
23 // menu-oid slots
24 
25 //#include <fcntl.h>
26 //#include <io.h>
27 
28 #include <string.h>
29 
30 #include "region.h"
31 #include "gadgets.h"
32 #include "qboxgadg.h"
33 #include "tngqbox.h"
34 #include "region.h"
35 #include "2d.h"
36 //#include <_ui.h>
37 #include "event.h"
38 #include "mouse.h"
39 #include "kbcook.h"
40 
41 
42 RectCallback disp_fn;
43 GadgetData *qb_gd;
44 int current_z;
45 Gadget *current_box;
46 LGRect box_dim;
47 
48 LGPoint QboxDefaultSpacing = {2, 0};
49 LGPoint QboxDefaultBorder = {1, 1};
50 
51 // Prototypes
52 int gad_qb_destroy(Gadget *g, void *user_data);
53 uchar gad_qbox_close_func(void *vg, void *ud);
54 
55 
gad_qb_destroy(Gadget * g,void * user_data)56 int gad_qb_destroy(Gadget *g, void *user_data)
57 {
58 #ifndef NO_DUMMIES
59    void *dummy;
60    dummy = (void *)g;
61    dummy = user_data;
62 #endif
63 
64    if (TNG_QB(g->tng_data)->options & QB_GRABFOCUS)
65       uiReleaseFocus(g->rep, UI_EVENT_KBD_COOKED);
66    return(0);
67 }
68 
gad_qbox_start_full(Gadget * parent,LGPoint coord,int z,TNGStyle * sty,ushort options,char * name,LGPoint ss,LGPoint spacing,LGPoint border,Ref left_id,Ref right_id)69 Gadget *gad_qbox_start_full(Gadget *parent, LGPoint coord, int z, TNGStyle *sty, ushort options, char *name, LGPoint ss, LGPoint spacing,
70    LGPoint border, Ref left_id, Ref right_id)
71 {
72    Gadget *retgad;
73    TNG *qb_tng;
74 
75    if (parent == NULL)
76    {
77       //Spew(DSRC_UI_Bounds, ("Attempted to create child of null gadget!\n"));
78       return(NULL);
79    }
80 
81    retgad = (Gadget *)malloc(sizeof(Gadget));
82    qb_gd = (GadgetData *)malloc(sizeof(GadgetData));
83    qb_tng = (TNG *)malloc(sizeof(TNG));
84 
85    switch (parent->rep->device_type)
86    {
87 /*      case DISPLAY_VGA:
88       case DISPLAY_SVGA:
89       case DISPLAY_MODEX:
90          disp_fn = &gadget_tng_vga_expose;
91          break;
92       case DISPLAY_MONO:
93          disp_fn = &gadget_tng_mono_expose;
94          break;  */
95       case DISPLAY_MAC:
96          disp_fn = &gadget_tng_Mac_expose;
97          break;
98    }
99 
100    current_z = z;
101    current_box = retgad;
102    box_dim.ul = coord;
103    tng_quickbox_init(retgad, qb_tng, sty, options, ss, spacing, border, left_id, right_id);
104 
105    // Fill in gadget level data
106    retgad->tng_data = qb_tng;
107    retgad->gclass = CLASS_QUICKBOX;
108    retgad->parent = parent;
109    retgad->device_data = parent->device_data;
110    retgad->conversion = parent->conversion;
111    retgad->handler_id = -1;
112 //   retgad->destroy_func = NULL;
113    retgad->destroy_func = &gad_qb_destroy;
114 
115    // Fill out gadget data
116    qb_gd->name = (char *)malloc((strlen(name) + 1) * sizeof(char));
117    strcpy(qb_gd->name, name);
118    qb_gd->g = retgad;
119 
120    return(retgad);
121 }
122 
123 // Begin a quick box.  Until the qbox is ended, all subsequent qbox calls will use the "current" qbox.
gad_qbox_start(Gadget * parent,LGPoint coord,int z,TNGStyle * sty,ushort options,char * name,LGPoint ss)124 Gadget *gad_qbox_start(Gadget *parent, LGPoint coord, int z, TNGStyle *sty, ushort options, char *name, LGPoint ss)
125 {
126    return(gad_qbox_start_full(parent, coord, z, sty, options, name, ss, QboxDefaultSpacing, QboxDefaultBorder,
127       0, 0));
128 }
129 
130 // Add a line to a quickbox.  slot_type describes the type of slot, var is a pointer to the variable to be
131 // displaying, and slot_options describes any additional modifiers to the qbox.  Note that some bizarre-o
132 // combinations of options and types might not be implemented.
gad_qbox_add(char * label,int slot_type,void * var,ulong slot_options)133 errtype gad_qbox_add(char *label, int slot_type, void *var, ulong slot_options)
134 {
135    return(tng_quickbox_add(label, slot_type, var, slot_options));
136 }
137 
138 // Just like gad_qbox_add but allows two parameters to be set for the slot.  Certain slot options require
139 // this form of accessing.
gad_qbox_add_parm(char * label,int slot_type,void * var,ulong slot_options,intptr_t parm1,intptr_t parm2)140 errtype gad_qbox_add_parm(char *label, int slot_type, void *var, ulong slot_options, intptr_t parm1, intptr_t parm2)
141 {
142    return(tng_quickbox_add_parm(label, slot_type, var, slot_options, parm1, parm2));
143 }
144 
gad_qbox_close_func(void * vg,void * ud)145 uchar gad_qbox_close_func(void *vg, void *ud)
146 {
147 #ifndef NO_DUMMIES
148    void *dummy;
149    dummy = vg;
150 #endif
151 
152    gadget_destroy((Gadget **)ud);
153    return(FALSE);
154 }
155 
156 // This represents that the quickbox is done being created and is ready for display, input, etc.
gad_qbox_end()157 errtype gad_qbox_end()
158 {
159    return(gad_qbox_end_full(NULL));
160 }
161 
gad_qbox_end_full(Gadget ** ptr)162 errtype gad_qbox_end_full(Gadget **ptr)
163 {
164    LGPoint sz;
165    if ((TNG_QB(current_box->tng_data)->options & QB_ADDCLOSE) &&  (ptr != NULL))
166          gad_qbox_add_parm("Close", QB_PUSHBUTTON_SLOT, gad_qbox_close_func, QB_NO_OPTION, (intptr_t)(ptr), 0);
167 
168    tng_quickbox_size(current_box->tng_data, &sz);
169    box_dim.lr.x = box_dim.ul.x + sz.x;
170    box_dim.lr.y = box_dim.ul.y + sz.y;
171 /* Spew(DSRC_UI_Quickbox, ("box_dim = (%d,%d)(%d,%d), current_z = %d\n",RECT_EXPAND_ARGS(&box_dim),current_z));
172    if (current_box->parent == NULL)
173       Spew(DSRC_UI_Quickbox, ("current_box->parent is NULL!\n"));
174    else if (current_box->parent->rep == NULL)
175       Spew(DSRC_UI_Quickbox, ("current_box->parent->rep is NULL!\n"));
176    else
177       Spew(DSRC_UI_Quickbox, ("Current_box seems okay...\n"));
178 */
179    current_box->rep = (LGRegion *)malloc(sizeof(LGRegion));
180    region_create(current_box->parent->rep, current_box->rep, &box_dim, current_z, 1,
181       REG_USER_CONTROLLED | AUTOMANAGE_FLAG | STENCIL_CLIPPING | OBSCURATION_CHECK,
182       disp_fn, NULL, NULL, qb_gd);
183    tng_quickbox_end();
184    uiInstallRegionHandler(current_box->rep, UI_EVENT_MOUSE, &gadget_tng_mouse_handler, (intptr_t)current_box, &(current_box->handler_id));
185    uiInstallRegionHandler(current_box->rep, UI_EVENT_KBD_COOKED, &gadget_tng_keyboard_handler, (intptr_t)current_box, &(current_box->handler_id));
186    uiSetRegionOpacity(current_box->rep,UI_EVENT_KBD_POLL);
187 /*¥¥¥
188    kb_set_state(QB_LEFT_KEY,KBA_REPEAT);
189    kb_set_state(QB_RIGHT_KEY,KBA_REPEAT);
190    kb_set_state(QB_DOWN_KEY,KBA_REPEAT);
191    kb_set_state(QB_UP_KEY,KBA_REPEAT);
192 */
193    if (TNG_QB(current_box->tng_data)->options & QB_GRABFOCUS)
194       uiGrabFocus(current_box->rep, UI_EVENT_KBD_COOKED);
195 
196    return(OK);
197 }
198 
gad_qbox_rename_slot(Gadget * g,int slot_num,char * new_name)199 errtype gad_qbox_rename_slot(Gadget *g, int slot_num, char *new_name)
200 {
201    return(tng_quickbox_rename_slot(g->tng_data, slot_num,new_name));
202 }
203