1
2 /* Terminality - a portable terminal handling library
3 * Copyright (C) 1998-2002, Emil Mikulic.
4 * This is LGPL - look at COPYING.LIB
5 */
6
7 /* Project: Terminality/GUI
8 * File: checkbox.cpp
9 * Author: Michal Safranek
10 * Description: Implements the checkbox class
11 */
12
13 #include <gui.h>
14
15 const char checkbox_rcsid[] =
16 "$Id: checkbox.cpp,v 1.9 2002/07/26 01:39:40 darkmoon Exp $";
17
18
19
20 /* Checkbox elements */
element(const checkbox_element el)21 void checkbox::element(const checkbox_element el)
22 {
23 if (has_color()) {
24 /* Pretty colors */
25 switch (el) {
26 case CB_left:
27 if (focus)
28 setcolor(SELECTED_BOX,SELECTED_BOX_BG);
29 else
30 setcolor(BOX,BOX_BG);
31 printw("%c", LBOX_CHR);
32 break;
33
34 case CB_check:
35 if (focus)
36 setcolor(SELECTED_CHECK,
37 SELECTED_CHECK_BG);
38 else
39 setcolor(CHECK,CHECK_BG);
40 if (selected)
41 printw("%c", CHECK_CHECKED_CHR);
42 else
43 printw("%c", CHECK_UNCHECKED_CHR);
44 break;
45
46 case CB_label:
47 if (focus)
48 setcolor(SELECTED_LABEL,
49 SELECTED_LABEL_BG);
50 else
51 setcolor(LABEL,LABEL_BG);
52 break;
53
54 case CB_right:
55 if (focus)
56 setcolor(SELECTED_BOX,SELECTED_BOX_BG);
57 else
58 setcolor(BOX,BOX_BG);
59 printw("%c", RBOX_CHR);
60 break;
61 }
62 } else {
63 /* Plain */
64 switch (el) {
65 case CB_left:
66 if (focus)
67 highvideo();
68 else
69 normvideo();
70 printw("%c", LBOX_CHR);
71 break;
72
73 case CB_check:
74 if (focus)
75 normvideo();
76 else
77 highvideo();
78 if (selected)
79 printw("%c", CHECK_CHECKED_CHR);
80 else
81 printw("%c", CHECK_UNCHECKED_CHR);
82 break;
83
84 case CB_label:
85 if (focus)
86 normvideo();
87 else
88 lowvideo();
89 break;
90
91 case CB_right:
92 if (focus)
93 highvideo();
94 else
95 normvideo();
96 printw("%c",RBOX_CHR);
97 break;
98 }
99 }
100 }
101
102
103
104 #define CB_SETUP() BACKGROUND = COLOR_CHECKBOX_BG; \
105 LABEL_BG = COLOR_CHECKBOX_LABELBG; \
106 CHECK_BG = COLOR_CHECKBOX_CHECKBG; \
107 BOX_BG = COLOR_CHECKBOX_BOXBG; \
108 LABEL = COLOR_CHECKBOX_LABEL; \
109 SELECTED_LABEL_BG = COLOR_CHECKBOX_SLABELBG; \
110 SELECTED_CHECK_BG = COLOR_CHECKBOX_SCHECKBG; \
111 SELECTED_BOX_BG = COLOR_CHECKBOX_SBOXBG; \
112 SELECTED_LABEL = COLOR_CHECKBOX_SLABEL; \
113 BOX = COLOR_CHECKBOX_BOX; \
114 SELECTED_CHECK = COLOR_CHECKBOX_SCHECK; \
115 SELECTED_BOX = COLOR_CHECKBOX_SBOX; \
116 CHECK = COLOR_CHECKBOX_CHECK; \
117 LBOX_CHR = '['; RBOX_CHR = ']'; \
118 CHECK_CHECKED_CHR = 'x'; \
119 CHECK_UNCHECKED_CHR = ' ';
120
121
122
123 // Construct checkbox at <x,y>
checkbox(const int xx,const int yy,bool sel)124 checkbox::checkbox(const int xx, const int yy, bool sel)
125 {
126 x = xx;
127 y = yy;
128 width = 4;
129 focus = false;
130 selected = sel;
131 label = NULL;
132 type_id = Checkbox;
133 visible = true;
134 fixed_colors = false;
135 spc_handle = NULL;
136 CB_SETUP();
137 }
138
139
140
141 // Construct checkbox at <x,y> using <s> for a buffer
checkbox(const int xx,const int yy,bool sel,const char * s)142 checkbox::checkbox(const int xx, const int yy, bool sel, const char *s)
143 {
144 x = xx;
145 y = yy;
146 focus = false;
147 selected = sel;
148 width = 4 + strlen(s);
149 label = (char*)xmalloc(strlen(s)+1);
150 strcpy(label, s);
151 type_id = Checkbox;
152 visible = true;
153 fixed_colors = false;
154 spc_handle = NULL;
155 CB_SETUP();
156 }
157
158
159
160 // Construct checkbox at <x,y> using <s> for a buffer, label's width <w>
checkbox(const int xx,const int yy,bool sel,const char * s,const int w)161 checkbox::checkbox(const int xx, const int yy, bool sel,
162 const char *s, const int w)
163 {
164 x = xx;
165 y = yy;
166 focus = false;
167 selected = sel;
168 width = 4 + w;
169 label = (char*)xmalloc(w+1);
170 strncpy(label, s, w);
171 label[w] = 0;
172 type_id = Checkbox;
173 visible = true;
174 fixed_colors = false;
175 spc_handle = NULL;
176 CB_SETUP();
177 }
178
179
180
181 // Destroy checkbox
~checkbox()182 checkbox::~checkbox()
183 {
184 // Deallocate buffer!
185 xfree(label);
186 }
187
188
189
190 // Draw checkbox
draw(void)191 void checkbox::draw(void)
192 {
193 char *temp;
194
195 if(!visible) return;
196
197 // Draw empty box
198 bgcolor(BACKGROUND);
199 gotoxy(x,y);
200 for(int i=0; i<width; i++)
201 printw(" ");
202
203 // Go to beginning of box
204 gotoxy(x,y);
205 element(CB_left);
206 element(CB_check);
207 element(CB_right);
208 element(CB_label);
209
210 // Write out label
211 temp = (char*) xmalloc((width-4)+1+1); // label size+space+null
212 temp[0]=' ';
213 memcpy(temp+1, label, width-4);
214 temp[(width-4)+1] = 0;
215 printw(temp);
216 xfree(temp);
217 gotoxy(x+1,y);
218 }
219
220
221
222 /* Non-blocking get function
223 * Returns:
224 * 0 - enter, 27 - ESC, -1 - up, 1 - down
225 */
getnb(void)226 int checkbox::getnb(void)
227 {
228 key c;
229 int result = 101;
230 cursor cs = get_cursor();
231 bool old_vis = visible;
232
233 visible = true;
234 set_cursor(none); // cursor
235 focus = true; // highlighting
236 draw(); // draw textbox
237
238 /* Get the input */
239 do
240 {
241 /* Update screen */
242 update();
243
244 /* Get letter */
245 c = readkey();
246 c = keyhandler(c, Checkbox);
247 c = handle_key(c, Checkbox, this);
248
249 /* Handle input */
250 switch (c)
251 {
252 // filter
253 case KEY_ENTER: result = 0; break;
254 case KEY_ESC: result = 27; break;
255 case KEY_UP: result = -1; break;
256 case KEY_DOWN:
257 case KEY_TAB: result = 1; break;
258 case ' ':
259 if (selected)
260 selected = false;
261 else
262 selected = true;
263 if(spc_handle)
264 spc_handle(selected);
265 draw();
266 if(onchange)
267 onchange(Checkbox, this);
268 break;
269
270 case KEY_NOTHING:
271 break;
272
273 default:
274 beep();
275 }
276 }
277 while (result == 101);
278
279 visible = old_vis;
280
281 focus = false; // Kill highlighting
282 set_cursor(cs);
283
284 return result;
285 }
286
287
288
289 // Blocking get (cannot be aborted)
get(void)290 bool checkbox::get(void)
291 {
292 while (1)
293 {
294 switch(getnb())
295 {
296 case 27: return 0;
297 case 0: return selected;
298 }
299 }
300 }
301
302
303
304 // Change color scheme
change_scheme(void)305 void checkbox::change_scheme(void)
306 {
307 if (fixed_colors) return;
308 BACKGROUND = COLOR_CHECKBOX_BG; LABEL_BG = COLOR_CHECKBOX_LABELBG;
309 CHECK_BG = COLOR_CHECKBOX_CHECKBG; BOX_BG = COLOR_CHECKBOX_BOXBG;
310 LABEL = COLOR_CHECKBOX_LABEL;
311 SELECTED_LABEL_BG = COLOR_CHECKBOX_SLABELBG;
312 BOX = COLOR_CHECKBOX_BOX; SELECTED_CHECK = COLOR_CHECKBOX_SCHECK;
313 SELECTED_BOX = COLOR_CHECKBOX_SBOX; CHECK = COLOR_CHECKBOX_CHECK;
314 SELECTED_CHECK_BG = COLOR_CHECKBOX_SCHECKBG;
315 SELECTED_BOX_BG = COLOR_CHECKBOX_SBOXBG;
316 SELECTED_LABEL = COLOR_CHECKBOX_SLABEL;
317 }
318
319