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