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