# HG changeset patch # User John Tsiombikas # Date 1299309927 -7200 # Node ID 00a4ea4ee6dc68c357b799f8ae1ffdcf4166ab55 # Parent 038e5577d527e21aab84432abe27ceda9da34ca7 attempt at slightly more complex widgets diff -r 038e5577d527 -r 00a4ea4ee6dc src/imtk.c --- a/src/imtk.c Fri Dec 31 18:10:13 2010 +0200 +++ b/src/imtk.c Sat Mar 05 09:25:27 2011 +0200 @@ -2,6 +2,7 @@ #include #include #include +#include #include #ifndef __APPLE__ #include @@ -52,7 +53,7 @@ static int scr_width = 1, scr_height = 1; static int mousex, mousey, prevx, mouse_bnmask; -static int active = -1, hot = -1, input = -1; +static int active = -1, hot = -1, input = -1, prev_active = -1; static struct key_node *key_list, *key_tail; @@ -305,9 +306,84 @@ draw_progress(id, pos, x, y); } +int imtk_listbox(int id, const char *list, int sel, int x, int y) +{ + int i; + assert(id >= 0); + + if(!list) { + return -1; + } + + if(id & 1) { + id++; + } + + for(i=0; *list; i++) { + if(imtk_button(id + i * 2 + 1, list, x, y + i * 20)) { + sel = i; + } + list += strlen(list) + 1; + } + return sel; +} + +int imtk_combobox(int id, char *textbuf, size_t buf_sz, const char *list, int sel, int x, int y) +{ + imtk_textbox(id + 1, textbuf, buf_sz, x, y); + imtk_button(id + 3, "V", x + TEXTBOX_SIZE, y); + + if(prev_active == id + 3) { + sel = imtk_listbox(id + 5, list, sel, x, y + 20); + } + return sel; +} + +char *imtk_create_list(const char *first, ...) +{ + int sz; + char *buf, *item; + va_list ap; + + if(!first) { + return 0; + } + + sz = strlen(first) + 2; + if(!(buf = malloc(sz))) { + return 0; + } + memcpy(buf, first, sz - 2); + buf[sz - 1] = buf[sz - 2] = 0; + + va_start(ap, first); + while((item = va_arg(ap, char*))) { + int len = strlen(item); + char *tmp = realloc(buf, sz + len + 1); + if(!tmp) { + free(buf); + return 0; + } + buf = tmp; + + memcpy(buf + sz - 1, item, len); + sz += len + 1; + buf[sz - 1] = buf[sz - 2] = 0; + } + va_end(ap); + + return buf; +} + +void imtk_free_list(char *list) +{ + free(list); +} + static void set_active(int id) { if(id == -1 || hot == id) { + prev_active = active; active = id; } } diff -r 038e5577d527 -r 00a4ea4ee6dc src/imtk.h --- a/src/imtk.h Fri Dec 31 18:10:13 2010 +0200 +++ b/src/imtk.h Sat Mar 05 09:25:27 2011 +0200 @@ -1,7 +1,8 @@ #ifndef IMTK_H_ #define IMTK_H_ -#define IMUID (65536 + __LINE__) +#define IMUID (__LINE__ << 10) +#define IMUID_IDX(i) ((__LINE__ << 10) + ((i) << 1)) enum { IMTK_TEXT_COLOR, @@ -38,5 +39,11 @@ void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y); float imtk_slider(int id, float pos, float min, float max, int x, int y); void imtk_progress(int id, float pos, int x, int y); +int imtk_listbox(int id, const char *list, int sel, int x, int y); +int imtk_combobox(int id, char *textbuf, size_t buf_sz, const char *list, int sel, int x, int y); + +/* helper functions to create and destroy item lists for listboxes and comboboxes */ +char *imtk_create_list(const char *first, ...); +void imtk_free_list(char *list); #endif /* IMTK_H_ */ diff -r 038e5577d527 -r 00a4ea4ee6dc test.c --- a/test.c Fri Dec 31 18:10:13 2010 +0200 +++ b/test.c Sat Mar 05 09:25:27 2011 +0200 @@ -20,6 +20,7 @@ int xsz, ysz; float angle; +int objsel; int main(int argc, char **argv) { @@ -72,9 +73,24 @@ glRotatef(25, 1, 0, 0); glRotatef(angle, 0, 1, 0); - glFrontFace(GL_CW); - glutSolidTeapot(1.0); - glFrontFace(GL_CCW); + switch(objsel) { + case 0: + glFrontFace(GL_CW); + glutSolidTeapot(1.0); + glFrontFace(GL_CCW); + break; + + case 1: + glutSolidTorus(0.5, 1, 12, 24); + break; + + case 2: + glutSolidSphere(1.0, 24, 12); + break; + + default: + break; + } glViewport(0, 0, 200, ysz); @@ -92,6 +108,8 @@ static char textbuf[256]; static char textbuf2[256]; static float val; + static int prev_sel; + char *itemlist; imtk_begin(); @@ -108,12 +126,19 @@ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glutPostRedisplay(); } - if(imtk_button(IMUID, "blue", 30, 100)) { + if(imtk_button(IMUID, "blue", 30, 80)) { float color[] = {0.3, 0.4, 1, 1}; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glutPostRedisplay(); } + itemlist = imtk_create_list("teapot", "torus", "sphere", NULL); + if((objsel = imtk_listbox(IMUID, itemlist, prev_sel, 30, 120)) != prev_sel) { + prev_sel = objsel; + glutPostRedisplay(); + } + imtk_free_list(itemlist); + imtk_textbox(IMUID, textbuf, sizeof textbuf, 30, 200); imtk_textbox(IMUID, textbuf2, sizeof textbuf2, 30, 250);