rev |
line source |
nuclear@3
|
1 #include <stdio.h>
|
nuclear@2
|
2 #include <stdlib.h>
|
nuclear@1
|
3 #include <string.h>
|
nuclear@2
|
4 #include <ctype.h>
|
nuclear@4
|
5 #include <stdarg.h>
|
nuclear@0
|
6 #include <assert.h>
|
nuclear@0
|
7 #ifndef __APPLE__
|
nuclear@0
|
8 #include <GL/glut.h>
|
nuclear@0
|
9 #else
|
nuclear@0
|
10 #include <GLUT/glut.h>
|
nuclear@0
|
11 #endif
|
nuclear@0
|
12 #include "imtk.h"
|
nuclear@7
|
13 #include "draw.h"
|
nuclear@0
|
14
|
nuclear@1
|
15 #define CHECKBOX_SIZE 14
|
nuclear@2
|
16 #define TEXTBOX_SIZE 100
|
nuclear@3
|
17 #define SLIDER_SIZE 100
|
nuclear@3
|
18 #define THUMB_WIDTH 10
|
nuclear@3
|
19 #define THUMB_HEIGHT 20
|
nuclear@1
|
20
|
nuclear@1
|
21 enum {
|
nuclear@1
|
22 FRAME_OUTSET,
|
nuclear@1
|
23 FRAME_INSET
|
nuclear@1
|
24 };
|
nuclear@1
|
25
|
nuclear@2
|
26 struct key_node {
|
nuclear@2
|
27 int key;
|
nuclear@2
|
28 struct key_node *next;
|
nuclear@2
|
29 };
|
nuclear@2
|
30
|
nuclear@2
|
31 static void set_active(int id);
|
nuclear@2
|
32 static int set_hot(int id);
|
nuclear@2
|
33 static int hit_test(int x, int y, int w, int h);
|
nuclear@2
|
34
|
nuclear@2
|
35 static void draw_button(int id, const char *label, int x, int y);
|
nuclear@2
|
36 static void calc_button_size(const char *label, int *wret, int *hret);
|
nuclear@2
|
37 static void draw_checkbox(int id, const char *label, int x, int y, int state);
|
nuclear@2
|
38 static void draw_textbox(int id, const char *text, int x, int y);
|
nuclear@3
|
39 static void draw_slider(int id, float pos, float min, float max, int x, int y);
|
nuclear@3
|
40 static void draw_progress(int id, float pos, int x, int y);
|
nuclear@2
|
41 static void draw_string(int x, int y, const char *str);
|
nuclear@2
|
42 static int string_size(const char *str);
|
nuclear@2
|
43 static void draw_frame(int x, int y, int w, int h, int style);
|
nuclear@2
|
44
|
nuclear@2
|
45
|
nuclear@1
|
46 /* default colors, can be changed with imtk_set_color */
|
nuclear@1
|
47 static float colors[][4] = {
|
nuclear@7
|
48 {0.0, 0.0, 0.0, 0.7}, /* text color */
|
nuclear@7
|
49 {0.6, 0.6, 0.6, 0.7}, /* base color */
|
nuclear@7
|
50 {0.7, 0.7, 0.7, 0.7}, /* focus color */
|
nuclear@7
|
51 {1.0, 1.0, 1.0, 1.0}, /* lit bevel */
|
nuclear@7
|
52 {0.3, 0.3, 0.3, 1.0} /* shadowed bevel */
|
nuclear@1
|
53 };
|
nuclear@1
|
54
|
nuclear@0
|
55 static int scr_width = 1, scr_height = 1;
|
nuclear@3
|
56 static int mousex, mousey, prevx, mouse_bnmask;
|
nuclear@4
|
57 static int active = -1, hot = -1, input = -1, prev_active = -1;
|
nuclear@0
|
58
|
nuclear@2
|
59 static struct key_node *key_list, *key_tail;
|
nuclear@0
|
60
|
nuclear@1
|
61
|
nuclear@1
|
62 void imtk_set_color(int col, float r, float g, float b)
|
nuclear@1
|
63 {
|
nuclear@1
|
64 assert(col >= 0 && col < sizeof colors / sizeof *colors);
|
nuclear@1
|
65
|
nuclear@1
|
66 colors[col][0] = r;
|
nuclear@1
|
67 colors[col][1] = g;
|
nuclear@1
|
68 colors[col][2] = b;
|
nuclear@1
|
69 }
|
nuclear@0
|
70
|
nuclear@0
|
71 void imtk_inp_key(int key, int state)
|
nuclear@0
|
72 {
|
nuclear@2
|
73 if(state == IMTK_DOWN) {
|
nuclear@2
|
74 struct key_node *node;
|
nuclear@2
|
75
|
nuclear@2
|
76 if(!(node = malloc(sizeof *node))) {
|
nuclear@2
|
77 return;
|
nuclear@2
|
78 }
|
nuclear@2
|
79 node->key = key;
|
nuclear@2
|
80 node->next = 0;
|
nuclear@2
|
81
|
nuclear@2
|
82 if(key_list) {
|
nuclear@2
|
83 key_tail->next = node;
|
nuclear@2
|
84 key_tail = node;
|
nuclear@2
|
85 } else {
|
nuclear@2
|
86 key_list = key_tail = node;
|
nuclear@2
|
87 }
|
nuclear@2
|
88 }
|
nuclear@2
|
89
|
nuclear@0
|
90 glutPostRedisplay();
|
nuclear@0
|
91 }
|
nuclear@0
|
92
|
nuclear@0
|
93 void imtk_inp_mouse(int bn, int state)
|
nuclear@0
|
94 {
|
nuclear@0
|
95 if(state == IMTK_DOWN) {
|
nuclear@0
|
96 mouse_bnmask |= 1 << bn;
|
nuclear@0
|
97 } else {
|
nuclear@0
|
98 mouse_bnmask &= ~(1 << bn);
|
nuclear@0
|
99 }
|
nuclear@0
|
100 glutPostRedisplay();
|
nuclear@0
|
101 }
|
nuclear@0
|
102
|
nuclear@0
|
103 void imtk_inp_motion(int x, int y)
|
nuclear@0
|
104 {
|
nuclear@0
|
105 mousex = x;
|
nuclear@0
|
106 mousey = y;
|
nuclear@0
|
107
|
nuclear@0
|
108 glutPostRedisplay();
|
nuclear@0
|
109 }
|
nuclear@0
|
110
|
nuclear@0
|
111 void imtk_inp_reshape(int x, int y)
|
nuclear@0
|
112 {
|
nuclear@0
|
113 scr_width = x;
|
nuclear@0
|
114 scr_height = y;
|
nuclear@0
|
115 }
|
nuclear@0
|
116
|
nuclear@0
|
117 void imtk_begin(void)
|
nuclear@0
|
118 {
|
nuclear@0
|
119 glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
120 glPushMatrix();
|
nuclear@0
|
121 glLoadIdentity();
|
nuclear@0
|
122 glTranslatef(-1, 1, 0);
|
nuclear@0
|
123 glScalef(2.0 / scr_width, -2.0 / scr_height, 1.0);
|
nuclear@2
|
124
|
nuclear@2
|
125 glMatrixMode(GL_MODELVIEW);
|
nuclear@2
|
126 glPushMatrix();
|
nuclear@2
|
127 glLoadIdentity();
|
nuclear@2
|
128
|
nuclear@2
|
129 glPushAttrib(GL_ENABLE_BIT);
|
nuclear@2
|
130 glDisable(GL_DEPTH_TEST);
|
nuclear@2
|
131 glDisable(GL_CULL_FACE);
|
nuclear@2
|
132 glDisable(GL_LIGHTING);
|
nuclear@0
|
133 }
|
nuclear@0
|
134
|
nuclear@0
|
135 void imtk_end(void)
|
nuclear@0
|
136 {
|
nuclear@2
|
137 glPopAttrib();
|
nuclear@2
|
138
|
nuclear@0
|
139 glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
140 glPopMatrix();
|
nuclear@2
|
141 glMatrixMode(GL_MODELVIEW);
|
nuclear@2
|
142 glPopMatrix();
|
nuclear@0
|
143 }
|
nuclear@0
|
144
|
nuclear@0
|
145 int imtk_button(int id, const char *label, int x, int y)
|
nuclear@0
|
146 {
|
nuclear@0
|
147 int w, h, res = 0;
|
nuclear@0
|
148 int over = 0;
|
nuclear@0
|
149
|
nuclear@0
|
150 assert(id >= 0);
|
nuclear@0
|
151
|
nuclear@0
|
152 calc_button_size(label, &w, &h);
|
nuclear@0
|
153
|
nuclear@0
|
154 if(hit_test(x, y, w, h)) {
|
nuclear@1
|
155 set_hot(id);
|
nuclear@0
|
156 over = 1;
|
nuclear@0
|
157 }
|
nuclear@0
|
158
|
nuclear@0
|
159 if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) {
|
nuclear@0
|
160 if(over) {
|
nuclear@0
|
161 set_active(id);
|
nuclear@0
|
162 }
|
nuclear@0
|
163 } else { /* mouse button up */
|
nuclear@0
|
164 if(active == id) {
|
nuclear@0
|
165 set_active(-1);
|
nuclear@0
|
166 if(hot == id && over) {
|
nuclear@0
|
167 res = 1;
|
nuclear@0
|
168 }
|
nuclear@0
|
169 }
|
nuclear@0
|
170 }
|
nuclear@0
|
171
|
nuclear@1
|
172 draw_button(id, label, x, y);
|
nuclear@0
|
173 return res;
|
nuclear@0
|
174 }
|
nuclear@0
|
175
|
nuclear@1
|
176 int imtk_checkbox(int id, const char *label, int x, int y, int state)
|
nuclear@1
|
177 {
|
nuclear@1
|
178 int sz = CHECKBOX_SIZE;
|
nuclear@1
|
179 int over = 0;
|
nuclear@1
|
180
|
nuclear@1
|
181 assert(id >= 0);
|
nuclear@1
|
182
|
nuclear@1
|
183 if(hit_test(x, y, sz, sz)) {
|
nuclear@1
|
184 set_hot(id);
|
nuclear@1
|
185 over = 1;
|
nuclear@1
|
186 }
|
nuclear@1
|
187
|
nuclear@1
|
188 if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) {
|
nuclear@1
|
189 if(over) {
|
nuclear@1
|
190 set_active(id);
|
nuclear@1
|
191 }
|
nuclear@1
|
192 } else { /* mouse button up */
|
nuclear@1
|
193 if(active == id) {
|
nuclear@1
|
194 set_active(-1);
|
nuclear@1
|
195 if(hot == id && over) {
|
nuclear@1
|
196 state = !state;
|
nuclear@1
|
197 }
|
nuclear@1
|
198 }
|
nuclear@1
|
199 }
|
nuclear@1
|
200
|
nuclear@1
|
201 draw_checkbox(id, label, x, y, state);
|
nuclear@1
|
202 return state;
|
nuclear@1
|
203 }
|
nuclear@1
|
204
|
nuclear@2
|
205 void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y)
|
nuclear@2
|
206 {
|
nuclear@2
|
207 int len, over = 0;
|
nuclear@2
|
208
|
nuclear@2
|
209 assert(id >= 0);
|
nuclear@2
|
210
|
nuclear@2
|
211 if(hit_test(x, y, TEXTBOX_SIZE, 20)) {
|
nuclear@2
|
212 set_hot(id);
|
nuclear@2
|
213 over = 1;
|
nuclear@2
|
214 }
|
nuclear@2
|
215
|
nuclear@2
|
216 if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) {
|
nuclear@2
|
217 if(over) {
|
nuclear@2
|
218 set_active(id);
|
nuclear@2
|
219 }
|
nuclear@2
|
220 } else {
|
nuclear@2
|
221 if(active == id) {
|
nuclear@2
|
222 set_active(-1);
|
nuclear@2
|
223 if(hot == id && over) {
|
nuclear@2
|
224 input = id;
|
nuclear@2
|
225 }
|
nuclear@2
|
226 }
|
nuclear@2
|
227 }
|
nuclear@2
|
228
|
nuclear@2
|
229 if(input == id) {
|
nuclear@2
|
230 len = strlen(textbuf);
|
nuclear@2
|
231 while(key_list) {
|
nuclear@2
|
232 struct key_node *node = key_list;
|
nuclear@2
|
233 key_list = key_list->next;
|
nuclear@2
|
234
|
nuclear@2
|
235 if(isprint(node->key)) {
|
nuclear@2
|
236 if(len < buf_sz) {
|
nuclear@2
|
237 textbuf[len++] = (char)node->key;
|
nuclear@2
|
238 }
|
nuclear@2
|
239 } else {
|
nuclear@2
|
240 switch(node->key) {
|
nuclear@2
|
241 case '\b':
|
nuclear@2
|
242 if(len > 0) {
|
nuclear@2
|
243 textbuf[--len] = 0;
|
nuclear@2
|
244 }
|
nuclear@2
|
245 break;
|
nuclear@2
|
246
|
nuclear@2
|
247 default:
|
nuclear@2
|
248 break;
|
nuclear@2
|
249 }
|
nuclear@2
|
250 }
|
nuclear@2
|
251
|
nuclear@2
|
252 free(node);
|
nuclear@2
|
253 }
|
nuclear@2
|
254 key_list = key_tail = 0;
|
nuclear@2
|
255 }
|
nuclear@2
|
256
|
nuclear@2
|
257 draw_textbox(id, textbuf, x, y);
|
nuclear@2
|
258 }
|
nuclear@2
|
259
|
nuclear@3
|
260 float imtk_slider(int id, float pos, float min, float max, int x, int y)
|
nuclear@3
|
261 {
|
nuclear@3
|
262 int thumb_x, thumb_y, over = 0;
|
nuclear@3
|
263 float range = max - min;
|
nuclear@3
|
264
|
nuclear@3
|
265 assert(id >= 0);
|
nuclear@3
|
266
|
nuclear@3
|
267 pos = (pos - min) / range;
|
nuclear@3
|
268 if(pos < 0.0) pos = 0.0;
|
nuclear@3
|
269 if(pos > 1.0) pos = 1.0;
|
nuclear@3
|
270
|
nuclear@3
|
271 thumb_x = x + SLIDER_SIZE * pos - THUMB_WIDTH / 2;
|
nuclear@3
|
272 thumb_y = y - THUMB_HEIGHT / 2;
|
nuclear@3
|
273
|
nuclear@3
|
274 if(hit_test(thumb_x, thumb_y, THUMB_WIDTH, THUMB_HEIGHT)) {
|
nuclear@3
|
275 set_hot(id);
|
nuclear@3
|
276 over = 1;
|
nuclear@3
|
277 }
|
nuclear@3
|
278
|
nuclear@3
|
279 if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) {
|
nuclear@3
|
280 if(over && hot == id) {
|
nuclear@3
|
281 if(active != id) {
|
nuclear@3
|
282 prevx = mousex;
|
nuclear@3
|
283 }
|
nuclear@3
|
284 set_active(id);
|
nuclear@3
|
285 }
|
nuclear@3
|
286 } else {
|
nuclear@3
|
287 if(active == id) {
|
nuclear@3
|
288 set_active(-1);
|
nuclear@3
|
289 }
|
nuclear@3
|
290 }
|
nuclear@3
|
291
|
nuclear@3
|
292 if(active == id) {
|
nuclear@3
|
293 float dx = (float)(mousex - prevx) / (float)SLIDER_SIZE;
|
nuclear@3
|
294 pos += dx;
|
nuclear@3
|
295 prevx = mousex;
|
nuclear@3
|
296
|
nuclear@3
|
297 if(pos < 0.0) pos = 0.0;
|
nuclear@3
|
298 if(pos > 1.0) pos = 1.0;
|
nuclear@3
|
299 }
|
nuclear@3
|
300
|
nuclear@3
|
301 draw_slider(id, pos, min, max, x, y);
|
nuclear@3
|
302 return pos * range + min;
|
nuclear@3
|
303 }
|
nuclear@3
|
304
|
nuclear@3
|
305 void imtk_progress(int id, float pos, int x, int y)
|
nuclear@3
|
306 {
|
nuclear@3
|
307 draw_progress(id, pos, x, y);
|
nuclear@3
|
308 }
|
nuclear@3
|
309
|
nuclear@4
|
310 int imtk_listbox(int id, const char *list, int sel, int x, int y)
|
nuclear@4
|
311 {
|
nuclear@4
|
312 int i;
|
nuclear@4
|
313 assert(id >= 0);
|
nuclear@4
|
314
|
nuclear@4
|
315 if(!list) {
|
nuclear@4
|
316 return -1;
|
nuclear@4
|
317 }
|
nuclear@4
|
318
|
nuclear@4
|
319 if(id & 1) {
|
nuclear@4
|
320 id++;
|
nuclear@4
|
321 }
|
nuclear@4
|
322
|
nuclear@4
|
323 for(i=0; *list; i++) {
|
nuclear@4
|
324 if(imtk_button(id + i * 2 + 1, list, x, y + i * 20)) {
|
nuclear@4
|
325 sel = i;
|
nuclear@4
|
326 }
|
nuclear@4
|
327 list += strlen(list) + 1;
|
nuclear@4
|
328 }
|
nuclear@4
|
329 return sel;
|
nuclear@4
|
330 }
|
nuclear@4
|
331
|
nuclear@4
|
332 int imtk_combobox(int id, char *textbuf, size_t buf_sz, const char *list, int sel, int x, int y)
|
nuclear@4
|
333 {
|
nuclear@4
|
334 imtk_textbox(id + 1, textbuf, buf_sz, x, y);
|
nuclear@4
|
335 imtk_button(id + 3, "V", x + TEXTBOX_SIZE, y);
|
nuclear@4
|
336
|
nuclear@4
|
337 if(prev_active == id + 3) {
|
nuclear@4
|
338 sel = imtk_listbox(id + 5, list, sel, x, y + 20);
|
nuclear@4
|
339 }
|
nuclear@4
|
340 return sel;
|
nuclear@4
|
341 }
|
nuclear@4
|
342
|
nuclear@4
|
343 char *imtk_create_list(const char *first, ...)
|
nuclear@4
|
344 {
|
nuclear@4
|
345 int sz;
|
nuclear@4
|
346 char *buf, *item;
|
nuclear@4
|
347 va_list ap;
|
nuclear@4
|
348
|
nuclear@4
|
349 if(!first) {
|
nuclear@4
|
350 return 0;
|
nuclear@4
|
351 }
|
nuclear@4
|
352
|
nuclear@4
|
353 sz = strlen(first) + 2;
|
nuclear@4
|
354 if(!(buf = malloc(sz))) {
|
nuclear@4
|
355 return 0;
|
nuclear@4
|
356 }
|
nuclear@4
|
357 memcpy(buf, first, sz - 2);
|
nuclear@4
|
358 buf[sz - 1] = buf[sz - 2] = 0;
|
nuclear@4
|
359
|
nuclear@4
|
360 va_start(ap, first);
|
nuclear@4
|
361 while((item = va_arg(ap, char*))) {
|
nuclear@4
|
362 int len = strlen(item);
|
nuclear@4
|
363 char *tmp = realloc(buf, sz + len + 1);
|
nuclear@4
|
364 if(!tmp) {
|
nuclear@4
|
365 free(buf);
|
nuclear@4
|
366 return 0;
|
nuclear@4
|
367 }
|
nuclear@4
|
368 buf = tmp;
|
nuclear@4
|
369
|
nuclear@4
|
370 memcpy(buf + sz - 1, item, len);
|
nuclear@4
|
371 sz += len + 1;
|
nuclear@4
|
372 buf[sz - 1] = buf[sz - 2] = 0;
|
nuclear@4
|
373 }
|
nuclear@4
|
374 va_end(ap);
|
nuclear@4
|
375
|
nuclear@4
|
376 return buf;
|
nuclear@4
|
377 }
|
nuclear@4
|
378
|
nuclear@4
|
379 void imtk_free_list(char *list)
|
nuclear@4
|
380 {
|
nuclear@4
|
381 free(list);
|
nuclear@4
|
382 }
|
nuclear@4
|
383
|
nuclear@0
|
384 static void set_active(int id)
|
nuclear@0
|
385 {
|
nuclear@3
|
386 if(id == -1 || hot == id) {
|
nuclear@4
|
387 prev_active = active;
|
nuclear@3
|
388 active = id;
|
nuclear@3
|
389 }
|
nuclear@0
|
390 }
|
nuclear@0
|
391
|
nuclear@0
|
392 static int set_hot(int id)
|
nuclear@0
|
393 {
|
nuclear@0
|
394 if(active == -1) {
|
nuclear@0
|
395 hot = id;
|
nuclear@0
|
396 return 1;
|
nuclear@0
|
397 }
|
nuclear@0
|
398 return 0;
|
nuclear@0
|
399 }
|
nuclear@0
|
400
|
nuclear@0
|
401 static int hit_test(int x, int y, int w, int h)
|
nuclear@0
|
402 {
|
nuclear@0
|
403 return mousex >= x && mousex < (x + w) &&
|
nuclear@0
|
404 mousey >= y && mousey < (y + h);
|
nuclear@0
|
405 }
|
nuclear@0
|
406
|
nuclear@1
|
407 static void draw_button(int id, const char *label, int x, int y)
|
nuclear@0
|
408 {
|
nuclear@0
|
409 int width, height;
|
nuclear@0
|
410
|
nuclear@0
|
411 calc_button_size(label, &width, &height);
|
nuclear@0
|
412
|
nuclear@7
|
413 /*
|
nuclear@0
|
414 glBegin(GL_QUADS);
|
nuclear@1
|
415 if(hit_test(x, y, width, height)) {
|
nuclear@1
|
416 glColor3fv(colors[IMTK_FOCUS_COLOR]);
|
nuclear@0
|
417 } else {
|
nuclear@1
|
418 glColor3fv(colors[IMTK_BASE_COLOR]);
|
nuclear@0
|
419 }
|
nuclear@0
|
420 glVertex2f(x, y);
|
nuclear@0
|
421 glVertex2f(x + width, y);
|
nuclear@0
|
422 glVertex2f(x + width, y + height);
|
nuclear@0
|
423 glVertex2f(x, y + height);
|
nuclear@0
|
424 glEnd();
|
nuclear@0
|
425
|
nuclear@1
|
426 draw_frame(x, y, width, height, active == id ? FRAME_INSET : FRAME_OUTSET);
|
nuclear@7
|
427 */
|
nuclear@7
|
428
|
nuclear@7
|
429 if(hit_test(x, y, width, height)) {
|
nuclear@7
|
430 imtk_draw_backgroundv(colors[IMTK_FOCUS_COLOR]);
|
nuclear@7
|
431 } else {
|
nuclear@7
|
432 imtk_draw_backgroundv(colors[IMTK_BASE_COLOR]);
|
nuclear@7
|
433 }
|
nuclear@7
|
434 imtk_draw_rect(x, y, width, height, 8);
|
nuclear@1
|
435
|
nuclear@1
|
436 glColor3fv(colors[IMTK_TEXT_COLOR]);
|
nuclear@0
|
437 draw_string(x + 20, y + 15, label);
|
nuclear@0
|
438 }
|
nuclear@0
|
439
|
nuclear@0
|
440 static void calc_button_size(const char *label, int *wret, int *hret)
|
nuclear@0
|
441 {
|
nuclear@0
|
442 int strsz = string_size(label);
|
nuclear@0
|
443 if(wret) *wret = strsz + 40;
|
nuclear@0
|
444 if(hret) *hret = 20;
|
nuclear@0
|
445 }
|
nuclear@0
|
446
|
nuclear@1
|
447 static void draw_checkbox(int id, const char *label, int x, int y, int state)
|
nuclear@1
|
448 {
|
nuclear@1
|
449 static const int sz = CHECKBOX_SIZE;
|
nuclear@1
|
450
|
nuclear@1
|
451 if(hit_test(x, y, sz, sz)) {
|
nuclear@1
|
452 glColor3fv(colors[IMTK_FOCUS_COLOR]);
|
nuclear@1
|
453 } else {
|
nuclear@1
|
454 glColor3fv(colors[IMTK_BASE_COLOR]);
|
nuclear@1
|
455 }
|
nuclear@1
|
456
|
nuclear@1
|
457 glBegin(GL_QUADS);
|
nuclear@1
|
458 glVertex2f(x, y);
|
nuclear@1
|
459 glVertex2f(x + sz, y);
|
nuclear@1
|
460 glVertex2f(x + sz, y + sz);
|
nuclear@1
|
461 glVertex2f(x, y + sz);
|
nuclear@1
|
462 glEnd();
|
nuclear@1
|
463
|
nuclear@1
|
464 draw_frame(x, y, sz, sz, FRAME_INSET);
|
nuclear@1
|
465
|
nuclear@1
|
466 glColor3fv(colors[IMTK_TEXT_COLOR]);
|
nuclear@1
|
467 if(state) {
|
nuclear@1
|
468 glPushAttrib(GL_LINE_BIT);
|
nuclear@1
|
469 glLineWidth(2);
|
nuclear@1
|
470
|
nuclear@1
|
471 glBegin(GL_LINES);
|
nuclear@1
|
472 glVertex2f(x + 2, y + 2);
|
nuclear@1
|
473 glVertex2f(x + sz - 2, y + sz - 2);
|
nuclear@1
|
474 glVertex2f(x + sz - 2, y + 2);
|
nuclear@1
|
475 glVertex2f(x + 2, y + sz - 2);
|
nuclear@1
|
476 glEnd();
|
nuclear@1
|
477
|
nuclear@1
|
478 glPopAttrib();
|
nuclear@1
|
479 }
|
nuclear@1
|
480
|
nuclear@1
|
481 draw_string(x + sz + 5, y + sz - 2, label);
|
nuclear@1
|
482 }
|
nuclear@1
|
483
|
nuclear@2
|
484 static void draw_textbox(int id, const char *text, int x, int y)
|
nuclear@2
|
485 {
|
nuclear@2
|
486 int strsz = string_size(text);
|
nuclear@2
|
487
|
nuclear@2
|
488 if(hit_test(x, y, TEXTBOX_SIZE, 20)) {
|
nuclear@2
|
489 glColor3fv(colors[IMTK_FOCUS_COLOR]);
|
nuclear@2
|
490 } else {
|
nuclear@2
|
491 glColor3fv(colors[IMTK_BASE_COLOR]);
|
nuclear@2
|
492 }
|
nuclear@2
|
493
|
nuclear@2
|
494 glBegin(GL_QUADS);
|
nuclear@2
|
495 glVertex2f(x, y);
|
nuclear@2
|
496 glVertex2f(x + TEXTBOX_SIZE, y);
|
nuclear@2
|
497 glVertex2f(x + TEXTBOX_SIZE, y + 20);
|
nuclear@2
|
498 glVertex2f(x, y + 20);
|
nuclear@2
|
499 glEnd();
|
nuclear@2
|
500
|
nuclear@2
|
501 glColor3fv(colors[IMTK_TEXT_COLOR]);
|
nuclear@2
|
502
|
nuclear@2
|
503 if(input == id) {
|
nuclear@2
|
504 glBegin(GL_LINES);
|
nuclear@2
|
505 glVertex2f(x + strsz + 2, y + 2);
|
nuclear@2
|
506 glVertex2f(x + strsz + 2, y + 18);
|
nuclear@2
|
507 glEnd();
|
nuclear@2
|
508 }
|
nuclear@2
|
509
|
nuclear@2
|
510 draw_string(x + 2, y + 15, text);
|
nuclear@2
|
511
|
nuclear@2
|
512 draw_frame(x, y, TEXTBOX_SIZE, 20, FRAME_INSET);
|
nuclear@2
|
513 }
|
nuclear@2
|
514
|
nuclear@3
|
515 static void draw_slider(int id, float pos, float min, float max, int x, int y)
|
nuclear@3
|
516 {
|
nuclear@3
|
517 float range = max - min;
|
nuclear@3
|
518 int thumb_x, thumb_y;
|
nuclear@3
|
519 char buf[32];
|
nuclear@3
|
520
|
nuclear@3
|
521 thumb_x = x + SLIDER_SIZE * pos - THUMB_WIDTH / 2;
|
nuclear@3
|
522 thumb_y = y - THUMB_HEIGHT / 2;
|
nuclear@3
|
523
|
nuclear@3
|
524 /* draw trough */
|
nuclear@3
|
525 glBegin(GL_QUADS);
|
nuclear@3
|
526 glColor3fv(colors[IMTK_BASE_COLOR]);
|
nuclear@3
|
527 glVertex2f(x, y - 2);
|
nuclear@3
|
528 glVertex2f(x + SLIDER_SIZE, y - 2);
|
nuclear@3
|
529 glVertex2f(x + SLIDER_SIZE, y + 2);
|
nuclear@3
|
530 glVertex2f(x, y + 2);
|
nuclear@3
|
531 glEnd();
|
nuclear@3
|
532 draw_frame(x, y - 2, SLIDER_SIZE, 4, FRAME_INSET);
|
nuclear@3
|
533
|
nuclear@3
|
534 if(hit_test(thumb_x, thumb_y, THUMB_WIDTH, THUMB_HEIGHT)) {
|
nuclear@3
|
535 glColor3fv(colors[IMTK_FOCUS_COLOR]);
|
nuclear@3
|
536 } else {
|
nuclear@3
|
537 glColor3fv(colors[IMTK_BASE_COLOR]);
|
nuclear@3
|
538 }
|
nuclear@3
|
539
|
nuclear@3
|
540 /* draw handle */
|
nuclear@3
|
541 glBegin(GL_QUADS);
|
nuclear@3
|
542 glVertex2f(thumb_x, thumb_y);
|
nuclear@3
|
543 glVertex2f(thumb_x + THUMB_WIDTH, thumb_y);
|
nuclear@3
|
544 glVertex2f(thumb_x + THUMB_WIDTH, thumb_y + THUMB_HEIGHT);
|
nuclear@3
|
545 glVertex2f(thumb_x, thumb_y + THUMB_HEIGHT);
|
nuclear@3
|
546 glEnd();
|
nuclear@3
|
547 draw_frame(thumb_x, thumb_y, THUMB_WIDTH, THUMB_HEIGHT, FRAME_OUTSET);
|
nuclear@3
|
548
|
nuclear@3
|
549 /* draw display */
|
nuclear@3
|
550 sprintf(buf, "%.3f", pos * range + min);
|
nuclear@3
|
551 glColor3fv(colors[IMTK_TEXT_COLOR]);
|
nuclear@3
|
552 draw_string(x + SLIDER_SIZE + THUMB_WIDTH / 2 + 2, y + 4, buf);
|
nuclear@3
|
553 }
|
nuclear@3
|
554
|
nuclear@3
|
555 static void draw_progress(int id, float pos, int x, int y)
|
nuclear@3
|
556 {
|
nuclear@3
|
557 int bar_size = SLIDER_SIZE * pos;
|
nuclear@3
|
558
|
nuclear@3
|
559 if(pos < 0.0) pos = 0.0;
|
nuclear@3
|
560 if(pos > 1.0) pos = 1.0;
|
nuclear@3
|
561
|
nuclear@3
|
562 /* through */
|
nuclear@3
|
563 glBegin(GL_QUADS);
|
nuclear@3
|
564 glColor3fv(colors[IMTK_BASE_COLOR]);
|
nuclear@3
|
565 glVertex2f(x - 1, y - 1);
|
nuclear@3
|
566 glVertex2f(x + SLIDER_SIZE + 1, y - 1);
|
nuclear@3
|
567 glVertex2f(x + SLIDER_SIZE + 1, y + 17);
|
nuclear@3
|
568 glVertex2f(x - 1, y + 17);
|
nuclear@3
|
569 glEnd();
|
nuclear@3
|
570 draw_frame(x - 1, y - 1, SLIDER_SIZE + 2, 17, FRAME_INSET);
|
nuclear@3
|
571
|
nuclear@3
|
572 if(pos > 0.0) {
|
nuclear@3
|
573 /* bar */
|
nuclear@3
|
574 glBegin(GL_QUADS);
|
nuclear@3
|
575 glColor3fv(colors[IMTK_BASE_COLOR]);
|
nuclear@3
|
576 glVertex2f(x, y);
|
nuclear@3
|
577 glVertex2f(x + bar_size, y);
|
nuclear@3
|
578 glVertex2f(x + bar_size, y + 15);
|
nuclear@3
|
579 glVertex2f(x, y + 15);
|
nuclear@3
|
580 glEnd();
|
nuclear@3
|
581 draw_frame(x, y, bar_size, 15, FRAME_OUTSET);
|
nuclear@3
|
582 }
|
nuclear@3
|
583 }
|
nuclear@3
|
584
|
nuclear@0
|
585 static void draw_string(int x, int y, const char *str)
|
nuclear@0
|
586 {
|
nuclear@0
|
587 glRasterPos2i(x, y);
|
nuclear@0
|
588 while(*str) {
|
nuclear@1
|
589 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *str++);
|
nuclear@0
|
590 }
|
nuclear@0
|
591 }
|
nuclear@0
|
592
|
nuclear@0
|
593 static int string_size(const char *str)
|
nuclear@0
|
594 {
|
nuclear@1
|
595 return glutBitmapLength(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)str);
|
nuclear@0
|
596 }
|
nuclear@1
|
597
|
nuclear@1
|
598 static void draw_frame(int x, int y, int w, int h, int style)
|
nuclear@1
|
599 {
|
nuclear@1
|
600 float tcol[3], bcol[3];
|
nuclear@1
|
601
|
nuclear@1
|
602 switch(style) {
|
nuclear@1
|
603 case FRAME_INSET:
|
nuclear@1
|
604 memcpy(tcol, colors[IMTK_BEVEL_SHAD_COLOR], sizeof tcol);
|
nuclear@1
|
605 memcpy(bcol, colors[IMTK_BEVEL_LIT_COLOR], sizeof bcol);
|
nuclear@1
|
606 break;
|
nuclear@1
|
607
|
nuclear@1
|
608 case FRAME_OUTSET:
|
nuclear@1
|
609 default:
|
nuclear@1
|
610 memcpy(tcol, colors[IMTK_BEVEL_LIT_COLOR], sizeof tcol);
|
nuclear@1
|
611 memcpy(bcol, colors[IMTK_BEVEL_SHAD_COLOR], sizeof bcol);
|
nuclear@1
|
612 }
|
nuclear@1
|
613
|
nuclear@1
|
614 glBegin(GL_LINES);
|
nuclear@1
|
615 glColor3fv(tcol);
|
nuclear@1
|
616 glVertex2f(x, y + h);
|
nuclear@1
|
617 glVertex2f(x, y);
|
nuclear@1
|
618 glVertex2f(x, y);
|
nuclear@1
|
619 glVertex2f(x + w, y);
|
nuclear@1
|
620 glColor3fv(bcol);
|
nuclear@1
|
621 glVertex2f(x + w, y);
|
nuclear@1
|
622 glVertex2f(x + w, y + h);
|
nuclear@1
|
623 glVertex2f(x + w, y + h);
|
nuclear@1
|
624 glVertex2f(x, y + h);
|
nuclear@1
|
625 glEnd();
|
nuclear@1
|
626 }
|