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@17
|
11 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over);
|
nuclear@17
|
12
|
nuclear@17
|
13 int imtk_listbox(int id, const char *list, int sel, int x, int y)
|
nuclear@17
|
14 {
|
nuclear@17
|
15 int i, max_width, nitems, over;
|
nuclear@17
|
16 const char *ptr;
|
nuclear@17
|
17
|
nuclear@17
|
18 assert(id >= 0);
|
nuclear@17
|
19
|
nuclear@17
|
20 max_width = 0;
|
nuclear@17
|
21 over = 0;
|
nuclear@17
|
22
|
nuclear@17
|
23 ptr = list;
|
nuclear@17
|
24 for(i=0; *ptr; i++) {
|
nuclear@17
|
25 int strsz = imtk_string_size(ptr) + 2 * PAD;
|
nuclear@17
|
26 if(strsz > max_width) {
|
nuclear@17
|
27 max_width = strsz;
|
nuclear@17
|
28 }
|
nuclear@17
|
29 ptr += strlen(ptr) + 1;
|
nuclear@17
|
30
|
nuclear@17
|
31 if(imtk_hit_test(x, y + i * ITEM_HEIGHT, max_width, ITEM_HEIGHT)) {
|
nuclear@17
|
32 imtk_set_hot(id);
|
nuclear@17
|
33 over = i + 1;
|
nuclear@17
|
34 }
|
nuclear@17
|
35 }
|
nuclear@17
|
36 nitems = i;
|
nuclear@17
|
37
|
nuclear@17
|
38 if(imtk_button_state(IMTK_LEFT_BUTTON)) {
|
nuclear@17
|
39 if(over) {
|
nuclear@17
|
40 imtk_set_active(id);
|
nuclear@17
|
41 }
|
nuclear@17
|
42 } else {
|
nuclear@17
|
43 if(imtk_is_active(id)) {
|
nuclear@17
|
44 imtk_set_active(-1);
|
nuclear@17
|
45 if(imtk_is_hot(id) && over) {
|
nuclear@17
|
46 sel = over - 1;
|
nuclear@17
|
47 }
|
nuclear@17
|
48 }
|
nuclear@17
|
49 }
|
nuclear@17
|
50
|
nuclear@17
|
51 draw_listbox(id, list, sel, x, y, max_width, nitems, over);
|
nuclear@17
|
52 return sel;
|
nuclear@17
|
53 }
|
nuclear@17
|
54
|
nuclear@17
|
55 char *imtk_create_list(const char *first, ...)
|
nuclear@17
|
56 {
|
nuclear@17
|
57 int sz;
|
nuclear@17
|
58 char *buf, *item;
|
nuclear@17
|
59 va_list ap;
|
nuclear@17
|
60
|
nuclear@17
|
61 if(!first) {
|
nuclear@17
|
62 return 0;
|
nuclear@17
|
63 }
|
nuclear@17
|
64
|
nuclear@17
|
65 sz = strlen(first) + 2;
|
nuclear@17
|
66 if(!(buf = malloc(sz))) {
|
nuclear@17
|
67 return 0;
|
nuclear@17
|
68 }
|
nuclear@17
|
69 memcpy(buf, first, sz - 2);
|
nuclear@17
|
70 buf[sz - 1] = buf[sz - 2] = 0;
|
nuclear@17
|
71
|
nuclear@17
|
72 va_start(ap, first);
|
nuclear@17
|
73 while((item = va_arg(ap, char*))) {
|
nuclear@17
|
74 int len = strlen(item);
|
nuclear@17
|
75 char *tmp = realloc(buf, sz + len + 1);
|
nuclear@17
|
76 if(!tmp) {
|
nuclear@17
|
77 free(buf);
|
nuclear@17
|
78 return 0;
|
nuclear@17
|
79 }
|
nuclear@17
|
80 buf = tmp;
|
nuclear@17
|
81
|
nuclear@17
|
82 memcpy(buf + sz - 1, item, len);
|
nuclear@17
|
83 sz += len + 1;
|
nuclear@17
|
84 buf[sz - 1] = buf[sz - 2] = 0;
|
nuclear@17
|
85 }
|
nuclear@17
|
86 va_end(ap);
|
nuclear@17
|
87
|
nuclear@17
|
88 return buf;
|
nuclear@17
|
89 }
|
nuclear@17
|
90
|
nuclear@17
|
91 void imtk_free_list(char *list)
|
nuclear@17
|
92 {
|
nuclear@17
|
93 free(list);
|
nuclear@17
|
94 }
|
nuclear@17
|
95
|
nuclear@17
|
96 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over)
|
nuclear@17
|
97 {
|
nuclear@17
|
98 int i;
|
nuclear@17
|
99 const char *item = list;
|
nuclear@17
|
100
|
nuclear@17
|
101 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
|
nuclear@17
|
102
|
nuclear@17
|
103 for(i=0; i<nitems; i++) {
|
nuclear@17
|
104 int item_y = i * ITEM_HEIGHT + y;
|
nuclear@17
|
105 unsigned int attr = 0;
|
nuclear@17
|
106 float tcol[4], bcol[4];
|
nuclear@17
|
107
|
nuclear@17
|
108 if(over - 1 == i) {
|
nuclear@17
|
109 attr |= IMTK_FOCUS_BIT;
|
nuclear@17
|
110 }
|
nuclear@17
|
111
|
nuclear@17
|
112 if(sel == i) {
|
nuclear@17
|
113 attr |= IMTK_SEL_BIT;
|
nuclear@17
|
114 memcpy(tcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof tcol);
|
nuclear@17
|
115 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
|
nuclear@17
|
116 } else {
|
nuclear@17
|
117 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
|
nuclear@17
|
118 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
|
nuclear@17
|
119 }
|
nuclear@17
|
120
|
nuclear@17
|
121 imtk_draw_rect(x, item_y, width, ITEM_HEIGHT, tcol, bcol);
|
nuclear@17
|
122
|
nuclear@17
|
123 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
|
nuclear@17
|
124 imtk_draw_string(x + 3, item_y + ITEM_HEIGHT - 5, item);
|
nuclear@17
|
125 item += strlen(item) + 1;
|
nuclear@17
|
126 }
|
nuclear@17
|
127
|
nuclear@17
|
128 imtk_draw_frame(x, y, width, ITEM_HEIGHT * nitems, FRAME_INSET);
|
nuclear@17
|
129 }
|