glamtk

annotate src/imtk.c @ 7:a115dff39a54

rounded crappy buttons
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 11 Mar 2011 02:25:49 +0200
parents 00a4ea4ee6dc
children cd00a5775373
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 }