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