glamtk

annotate src/imtk.c @ 10:5b86b98ee988

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