rev |
line source |
nuclear@17
|
1 #include <string.h>
|
nuclear@17
|
2 #include <stdarg.h>
|
nuclear@17
|
3 #include <assert.h>
|
nuclear@17
|
4 #include "imtk.h"
|
nuclear@17
|
5 #include "state.h"
|
nuclear@17
|
6 #include "draw.h"
|
nuclear@17
|
7
|
nuclear@17
|
8 #define ITEM_HEIGHT 18
|
nuclear@17
|
9 #define PAD 3
|
nuclear@17
|
10
|
nuclear@18
|
11 static int list_radio(int id, const char *list, int sel, int x, int y, void (*draw)());
|
nuclear@17
|
12 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over);
|
nuclear@18
|
13 static void draw_radio(int id, const char *list, int sel, int x, int y, int width, int nitems, int over);
|
nuclear@17
|
14
|
nuclear@17
|
15 int imtk_listbox(int id, const char *list, int sel, int x, int y)
|
nuclear@17
|
16 {
|
nuclear@18
|
17 return list_radio(id, list, sel, x, y, draw_listbox);
|
nuclear@18
|
18 }
|
nuclear@18
|
19
|
nuclear@18
|
20 int imtk_radiogroup(int id, const char *list, int sel, int x, int y)
|
nuclear@18
|
21 {
|
nuclear@18
|
22 return list_radio(id, list, sel, x, y, draw_radio);
|
nuclear@18
|
23 }
|
nuclear@18
|
24
|
nuclear@18
|
25 static int list_radio(int id, const char *list, int sel, int x, int y, void (*draw)())
|
nuclear@18
|
26 {
|
nuclear@17
|
27 int i, max_width, nitems, over;
|
nuclear@17
|
28 const char *ptr;
|
nuclear@17
|
29
|
nuclear@17
|
30 assert(id >= 0);
|
nuclear@17
|
31
|
nuclear@17
|
32 max_width = 0;
|
nuclear@17
|
33 over = 0;
|
nuclear@17
|
34
|
nuclear@17
|
35 ptr = list;
|
nuclear@17
|
36 for(i=0; *ptr; i++) {
|
nuclear@17
|
37 int strsz = imtk_string_size(ptr) + 2 * PAD;
|
nuclear@17
|
38 if(strsz > max_width) {
|
nuclear@17
|
39 max_width = strsz;
|
nuclear@17
|
40 }
|
nuclear@17
|
41 ptr += strlen(ptr) + 1;
|
nuclear@17
|
42
|
nuclear@17
|
43 if(imtk_hit_test(x, y + i * ITEM_HEIGHT, max_width, ITEM_HEIGHT)) {
|
nuclear@17
|
44 imtk_set_hot(id);
|
nuclear@17
|
45 over = i + 1;
|
nuclear@17
|
46 }
|
nuclear@17
|
47 }
|
nuclear@17
|
48 nitems = i;
|
nuclear@17
|
49
|
nuclear@17
|
50 if(imtk_button_state(IMTK_LEFT_BUTTON)) {
|
nuclear@17
|
51 if(over) {
|
nuclear@17
|
52 imtk_set_active(id);
|
nuclear@17
|
53 }
|
nuclear@17
|
54 } else {
|
nuclear@17
|
55 if(imtk_is_active(id)) {
|
nuclear@17
|
56 imtk_set_active(-1);
|
nuclear@17
|
57 if(imtk_is_hot(id) && over) {
|
nuclear@17
|
58 sel = over - 1;
|
nuclear@17
|
59 }
|
nuclear@17
|
60 }
|
nuclear@17
|
61 }
|
nuclear@17
|
62
|
nuclear@18
|
63 draw(id, list, sel, x, y, max_width, nitems, over);
|
nuclear@17
|
64 return sel;
|
nuclear@17
|
65 }
|
nuclear@17
|
66
|
nuclear@17
|
67 char *imtk_create_list(const char *first, ...)
|
nuclear@17
|
68 {
|
nuclear@17
|
69 int sz;
|
nuclear@17
|
70 char *buf, *item;
|
nuclear@17
|
71 va_list ap;
|
nuclear@17
|
72
|
nuclear@17
|
73 if(!first) {
|
nuclear@17
|
74 return 0;
|
nuclear@17
|
75 }
|
nuclear@17
|
76
|
nuclear@17
|
77 sz = strlen(first) + 2;
|
nuclear@17
|
78 if(!(buf = malloc(sz))) {
|
nuclear@17
|
79 return 0;
|
nuclear@17
|
80 }
|
nuclear@17
|
81 memcpy(buf, first, sz - 2);
|
nuclear@17
|
82 buf[sz - 1] = buf[sz - 2] = 0;
|
nuclear@17
|
83
|
nuclear@17
|
84 va_start(ap, first);
|
nuclear@17
|
85 while((item = va_arg(ap, char*))) {
|
nuclear@17
|
86 int len = strlen(item);
|
nuclear@17
|
87 char *tmp = realloc(buf, sz + len + 1);
|
nuclear@17
|
88 if(!tmp) {
|
nuclear@17
|
89 free(buf);
|
nuclear@17
|
90 return 0;
|
nuclear@17
|
91 }
|
nuclear@17
|
92 buf = tmp;
|
nuclear@17
|
93
|
nuclear@17
|
94 memcpy(buf + sz - 1, item, len);
|
nuclear@17
|
95 sz += len + 1;
|
nuclear@17
|
96 buf[sz - 1] = buf[sz - 2] = 0;
|
nuclear@17
|
97 }
|
nuclear@17
|
98 va_end(ap);
|
nuclear@17
|
99
|
nuclear@17
|
100 return buf;
|
nuclear@17
|
101 }
|
nuclear@17
|
102
|
nuclear@17
|
103 void imtk_free_list(char *list)
|
nuclear@17
|
104 {
|
nuclear@17
|
105 free(list);
|
nuclear@17
|
106 }
|
nuclear@17
|
107
|
nuclear@17
|
108 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over)
|
nuclear@17
|
109 {
|
nuclear@17
|
110 int i;
|
nuclear@17
|
111 const char *item = list;
|
nuclear@17
|
112
|
nuclear@17
|
113 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
|
nuclear@17
|
114
|
nuclear@17
|
115 for(i=0; i<nitems; i++) {
|
nuclear@17
|
116 int item_y = i * ITEM_HEIGHT + y;
|
nuclear@17
|
117 unsigned int attr = 0;
|
nuclear@17
|
118 float tcol[4], bcol[4];
|
nuclear@17
|
119
|
nuclear@17
|
120 if(over - 1 == i) {
|
nuclear@17
|
121 attr |= IMTK_FOCUS_BIT;
|
nuclear@17
|
122 }
|
nuclear@17
|
123
|
nuclear@17
|
124 if(sel == i) {
|
nuclear@17
|
125 attr |= IMTK_SEL_BIT;
|
nuclear@17
|
126 memcpy(tcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof tcol);
|
nuclear@17
|
127 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
|
nuclear@17
|
128 } else {
|
nuclear@17
|
129 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
|
nuclear@17
|
130 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
|
nuclear@17
|
131 }
|
nuclear@17
|
132
|
nuclear@17
|
133 imtk_draw_rect(x, item_y, width, ITEM_HEIGHT, tcol, bcol);
|
nuclear@17
|
134
|
nuclear@17
|
135 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
|
nuclear@17
|
136 imtk_draw_string(x + 3, item_y + ITEM_HEIGHT - 5, item);
|
nuclear@17
|
137 item += strlen(item) + 1;
|
nuclear@17
|
138 }
|
nuclear@17
|
139
|
nuclear@17
|
140 imtk_draw_frame(x, y, width, ITEM_HEIGHT * nitems, FRAME_INSET);
|
nuclear@17
|
141 }
|
nuclear@18
|
142
|
nuclear@18
|
143 static void draw_radio(int id, const char *list, int sel, int x, int y, int width, int nitems, int over)
|
nuclear@18
|
144 {
|
nuclear@18
|
145 int i;
|
nuclear@18
|
146 const char *item = list;
|
nuclear@18
|
147 float rad = ITEM_HEIGHT * 0.5;
|
nuclear@18
|
148
|
nuclear@18
|
149 for(i=0; i<nitems; i++) {
|
nuclear@18
|
150 int item_y = i * ITEM_HEIGHT + y;
|
nuclear@18
|
151 unsigned int attr = 0;
|
nuclear@18
|
152 float tcol[4], bcol[4];
|
nuclear@18
|
153
|
nuclear@18
|
154 if(over - 1 == i) {
|
nuclear@18
|
155 attr |= IMTK_FOCUS_BIT;
|
nuclear@18
|
156 }
|
nuclear@18
|
157
|
nuclear@19
|
158 imtk_draw_disc_frame(x + rad, item_y + rad, rad * 0.9, rad * 0.75, 5, FRAME_INSET);
|
nuclear@19
|
159
|
nuclear@18
|
160 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
|
nuclear@18
|
161 memcpy(bcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof bcol);
|
nuclear@19
|
162 imtk_draw_disc(x + rad, item_y + rad, rad * 0.75, 5, tcol, bcol);
|
nuclear@18
|
163
|
nuclear@18
|
164 if(i == sel) {
|
nuclear@18
|
165 attr |= IMTK_SEL_BIT;
|
nuclear@18
|
166 memcpy(tcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof tcol);
|
nuclear@18
|
167 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
|
nuclear@19
|
168
|
nuclear@18
|
169 imtk_draw_disc(x + rad, item_y + ITEM_HEIGHT / 2, rad * 0.6, 5, tcol, bcol);
|
nuclear@18
|
170 }
|
nuclear@18
|
171
|
nuclear@18
|
172 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
|
nuclear@18
|
173 imtk_draw_string(x + rad * 2.0 + 3, item_y + ITEM_HEIGHT - 5, item);
|
nuclear@18
|
174 item += strlen(item) + 1;
|
nuclear@18
|
175 }
|
nuclear@18
|
176 }
|