imtk

view src/listbox.c @ 17:ac2a8d8fca9a

naturally I forgot to add listbox.c
author John Tsiombikas <nuclear@siggraph.org>
date Tue, 19 Apr 2011 08:36:23 +0300
parents
children 737e9047d9c9
line source
1 #include <string.h>
2 #include <stdarg.h>
3 #include <assert.h>
4 #include "imtk.h"
5 #include "state.h"
6 #include "draw.h"
8 #define ITEM_HEIGHT 18
9 #define PAD 3
11 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over);
13 int imtk_listbox(int id, const char *list, int sel, int x, int y)
14 {
15 int i, max_width, nitems, over;
16 const char *ptr;
18 assert(id >= 0);
20 max_width = 0;
21 over = 0;
23 ptr = list;
24 for(i=0; *ptr; i++) {
25 int strsz = imtk_string_size(ptr) + 2 * PAD;
26 if(strsz > max_width) {
27 max_width = strsz;
28 }
29 ptr += strlen(ptr) + 1;
31 if(imtk_hit_test(x, y + i * ITEM_HEIGHT, max_width, ITEM_HEIGHT)) {
32 imtk_set_hot(id);
33 over = i + 1;
34 }
35 }
36 nitems = i;
38 if(imtk_button_state(IMTK_LEFT_BUTTON)) {
39 if(over) {
40 imtk_set_active(id);
41 }
42 } else {
43 if(imtk_is_active(id)) {
44 imtk_set_active(-1);
45 if(imtk_is_hot(id) && over) {
46 sel = over - 1;
47 }
48 }
49 }
51 draw_listbox(id, list, sel, x, y, max_width, nitems, over);
52 return sel;
53 }
55 char *imtk_create_list(const char *first, ...)
56 {
57 int sz;
58 char *buf, *item;
59 va_list ap;
61 if(!first) {
62 return 0;
63 }
65 sz = strlen(first) + 2;
66 if(!(buf = malloc(sz))) {
67 return 0;
68 }
69 memcpy(buf, first, sz - 2);
70 buf[sz - 1] = buf[sz - 2] = 0;
72 va_start(ap, first);
73 while((item = va_arg(ap, char*))) {
74 int len = strlen(item);
75 char *tmp = realloc(buf, sz + len + 1);
76 if(!tmp) {
77 free(buf);
78 return 0;
79 }
80 buf = tmp;
82 memcpy(buf + sz - 1, item, len);
83 sz += len + 1;
84 buf[sz - 1] = buf[sz - 2] = 0;
85 }
86 va_end(ap);
88 return buf;
89 }
91 void imtk_free_list(char *list)
92 {
93 free(list);
94 }
96 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over)
97 {
98 int i;
99 const char *item = list;
101 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
103 for(i=0; i<nitems; i++) {
104 int item_y = i * ITEM_HEIGHT + y;
105 unsigned int attr = 0;
106 float tcol[4], bcol[4];
108 if(over - 1 == i) {
109 attr |= IMTK_FOCUS_BIT;
110 }
112 if(sel == i) {
113 attr |= IMTK_SEL_BIT;
114 memcpy(tcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof tcol);
115 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
116 } else {
117 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
118 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
119 }
121 imtk_draw_rect(x, item_y, width, ITEM_HEIGHT, tcol, bcol);
123 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
124 imtk_draw_string(x + 3, item_y + ITEM_HEIGHT - 5, item);
125 item += strlen(item) + 1;
126 }
128 imtk_draw_frame(x, y, width, ITEM_HEIGHT * nitems, FRAME_INSET);
129 }