imtk

annotate src/listbox.c @ 19:11da537aeba6

blah
author John Tsiombikas <nuclear@siggraph.org>
date Tue, 26 Apr 2011 22:53:21 +0300
parents 737e9047d9c9
children c7a7ddbe7714
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 }