imtk

view src/listbox.c @ 18:737e9047d9c9

added radio group
author John Tsiombikas <nuclear@siggraph.org>
date Mon, 25 Apr 2011 08:54:05 +0300
parents ac2a8d8fca9a
children 11da537aeba6
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 int list_radio(int id, const char *list, int sel, int x, int y, void (*draw)());
12 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over);
13 static void draw_radio(int id, const char *list, int sel, int x, int y, int width, int nitems, int over);
15 int imtk_listbox(int id, const char *list, int sel, int x, int y)
16 {
17 return list_radio(id, list, sel, x, y, draw_listbox);
18 }
20 int imtk_radiogroup(int id, const char *list, int sel, int x, int y)
21 {
22 return list_radio(id, list, sel, x, y, draw_radio);
23 }
25 static int list_radio(int id, const char *list, int sel, int x, int y, void (*draw)())
26 {
27 int i, max_width, nitems, over;
28 const char *ptr;
30 assert(id >= 0);
32 max_width = 0;
33 over = 0;
35 ptr = list;
36 for(i=0; *ptr; i++) {
37 int strsz = imtk_string_size(ptr) + 2 * PAD;
38 if(strsz > max_width) {
39 max_width = strsz;
40 }
41 ptr += strlen(ptr) + 1;
43 if(imtk_hit_test(x, y + i * ITEM_HEIGHT, max_width, ITEM_HEIGHT)) {
44 imtk_set_hot(id);
45 over = i + 1;
46 }
47 }
48 nitems = i;
50 if(imtk_button_state(IMTK_LEFT_BUTTON)) {
51 if(over) {
52 imtk_set_active(id);
53 }
54 } else {
55 if(imtk_is_active(id)) {
56 imtk_set_active(-1);
57 if(imtk_is_hot(id) && over) {
58 sel = over - 1;
59 }
60 }
61 }
63 draw(id, list, sel, x, y, max_width, nitems, over);
64 return sel;
65 }
67 char *imtk_create_list(const char *first, ...)
68 {
69 int sz;
70 char *buf, *item;
71 va_list ap;
73 if(!first) {
74 return 0;
75 }
77 sz = strlen(first) + 2;
78 if(!(buf = malloc(sz))) {
79 return 0;
80 }
81 memcpy(buf, first, sz - 2);
82 buf[sz - 1] = buf[sz - 2] = 0;
84 va_start(ap, first);
85 while((item = va_arg(ap, char*))) {
86 int len = strlen(item);
87 char *tmp = realloc(buf, sz + len + 1);
88 if(!tmp) {
89 free(buf);
90 return 0;
91 }
92 buf = tmp;
94 memcpy(buf + sz - 1, item, len);
95 sz += len + 1;
96 buf[sz - 1] = buf[sz - 2] = 0;
97 }
98 va_end(ap);
100 return buf;
101 }
103 void imtk_free_list(char *list)
104 {
105 free(list);
106 }
108 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over)
109 {
110 int i;
111 const char *item = list;
113 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
115 for(i=0; i<nitems; i++) {
116 int item_y = i * ITEM_HEIGHT + y;
117 unsigned int attr = 0;
118 float tcol[4], bcol[4];
120 if(over - 1 == i) {
121 attr |= IMTK_FOCUS_BIT;
122 }
124 if(sel == i) {
125 attr |= IMTK_SEL_BIT;
126 memcpy(tcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof tcol);
127 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
128 } else {
129 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
130 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
131 }
133 imtk_draw_rect(x, item_y, width, ITEM_HEIGHT, tcol, bcol);
135 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
136 imtk_draw_string(x + 3, item_y + ITEM_HEIGHT - 5, item);
137 item += strlen(item) + 1;
138 }
140 imtk_draw_frame(x, y, width, ITEM_HEIGHT * nitems, FRAME_INSET);
141 }
143 static void draw_radio(int id, const char *list, int sel, int x, int y, int width, int nitems, int over)
144 {
145 int i;
146 const char *item = list;
147 float rad = ITEM_HEIGHT * 0.5;
149 for(i=0; i<nitems; i++) {
150 int item_y = i * ITEM_HEIGHT + y;
151 unsigned int attr = 0;
152 float tcol[4], bcol[4];
154 if(over - 1 == i) {
155 attr |= IMTK_FOCUS_BIT;
156 }
158 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
159 memcpy(bcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof bcol);
161 imtk_draw_disc(x + rad, item_y + rad, rad * 0.8, 5, tcol, bcol);
163 if(i == sel) {
164 attr |= IMTK_SEL_BIT;
165 memcpy(tcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof tcol);
166 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
167 imtk_draw_disc(x + rad, item_y + ITEM_HEIGHT / 2, rad * 0.6, 5, tcol, bcol);
168 }
170 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
171 imtk_draw_string(x + rad * 2.0 + 3, item_y + ITEM_HEIGHT - 5, item);
172 item += strlen(item) + 1;
173 }
174 }