nuclear@17: #include nuclear@17: #include nuclear@17: #include nuclear@17: #include "imtk.h" nuclear@17: #include "state.h" nuclear@17: #include "draw.h" nuclear@17: nuclear@17: #define ITEM_HEIGHT 18 nuclear@17: #define PAD 3 nuclear@17: nuclear@18: static int list_radio(int id, const char *list, int sel, int x, int y, void (*draw)()); nuclear@17: static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over); nuclear@18: static void draw_radio(int id, const char *list, int sel, int x, int y, int width, int nitems, int over); nuclear@17: nuclear@17: int imtk_listbox(int id, const char *list, int sel, int x, int y) nuclear@17: { nuclear@18: return list_radio(id, list, sel, x, y, draw_listbox); nuclear@18: } nuclear@18: nuclear@18: int imtk_radiogroup(int id, const char *list, int sel, int x, int y) nuclear@18: { nuclear@18: return list_radio(id, list, sel, x, y, draw_radio); nuclear@18: } nuclear@18: nuclear@18: static int list_radio(int id, const char *list, int sel, int x, int y, void (*draw)()) nuclear@18: { nuclear@17: int i, max_width, nitems, over; nuclear@17: const char *ptr; nuclear@17: nuclear@17: assert(id >= 0); nuclear@17: nuclear@17: max_width = 0; nuclear@17: over = 0; nuclear@17: nuclear@17: ptr = list; nuclear@17: for(i=0; *ptr; i++) { nuclear@17: int strsz = imtk_string_size(ptr) + 2 * PAD; nuclear@17: if(strsz > max_width) { nuclear@17: max_width = strsz; nuclear@17: } nuclear@17: ptr += strlen(ptr) + 1; nuclear@17: nuclear@17: if(imtk_hit_test(x, y + i * ITEM_HEIGHT, max_width, ITEM_HEIGHT)) { nuclear@17: imtk_set_hot(id); nuclear@17: over = i + 1; nuclear@17: } nuclear@17: } nuclear@17: nitems = i; nuclear@17: nuclear@17: if(imtk_button_state(IMTK_LEFT_BUTTON)) { nuclear@17: if(over) { nuclear@17: imtk_set_active(id); nuclear@17: } nuclear@17: } else { nuclear@17: if(imtk_is_active(id)) { nuclear@17: imtk_set_active(-1); nuclear@17: if(imtk_is_hot(id) && over) { nuclear@17: sel = over - 1; nuclear@17: } nuclear@17: } nuclear@17: } nuclear@17: nuclear@18: draw(id, list, sel, x, y, max_width, nitems, over); nuclear@17: return sel; nuclear@17: } nuclear@17: nuclear@17: char *imtk_create_list(const char *first, ...) nuclear@17: { nuclear@17: int sz; nuclear@17: char *buf, *item; nuclear@17: va_list ap; nuclear@17: nuclear@17: if(!first) { nuclear@17: return 0; nuclear@17: } nuclear@17: nuclear@17: sz = strlen(first) + 2; nuclear@17: if(!(buf = malloc(sz))) { nuclear@17: return 0; nuclear@17: } nuclear@17: memcpy(buf, first, sz - 2); nuclear@17: buf[sz - 1] = buf[sz - 2] = 0; nuclear@17: nuclear@17: va_start(ap, first); nuclear@17: while((item = va_arg(ap, char*))) { nuclear@17: int len = strlen(item); nuclear@17: char *tmp = realloc(buf, sz + len + 1); nuclear@17: if(!tmp) { nuclear@17: free(buf); nuclear@17: return 0; nuclear@17: } nuclear@17: buf = tmp; nuclear@17: nuclear@17: memcpy(buf + sz - 1, item, len); nuclear@17: sz += len + 1; nuclear@17: buf[sz - 1] = buf[sz - 2] = 0; nuclear@17: } nuclear@17: va_end(ap); nuclear@17: nuclear@17: return buf; nuclear@17: } nuclear@17: nuclear@17: void imtk_free_list(char *list) nuclear@17: { nuclear@17: free(list); nuclear@17: } nuclear@17: nuclear@17: static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over) nuclear@17: { nuclear@17: int i; nuclear@17: const char *item = list; nuclear@17: nuclear@17: glColor4fv(imtk_get_color(IMTK_TEXT_COLOR)); nuclear@17: nuclear@17: for(i=0; i