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