glamtk
changeset 4:00a4ea4ee6dc
attempt at slightly more complex widgets
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 05 Mar 2011 09:25:27 +0200 |
parents | 038e5577d527 |
children | 86ba127ac2f2 |
files | src/imtk.c src/imtk.h test.c |
diffstat | 3 files changed, 114 insertions(+), 6 deletions(-) [+] |
line diff
1.1 --- a/src/imtk.c Fri Dec 31 18:10:13 2010 +0200 1.2 +++ b/src/imtk.c Sat Mar 05 09:25:27 2011 +0200 1.3 @@ -2,6 +2,7 @@ 1.4 #include <stdlib.h> 1.5 #include <string.h> 1.6 #include <ctype.h> 1.7 +#include <stdarg.h> 1.8 #include <assert.h> 1.9 #ifndef __APPLE__ 1.10 #include <GL/glut.h> 1.11 @@ -52,7 +53,7 @@ 1.12 1.13 static int scr_width = 1, scr_height = 1; 1.14 static int mousex, mousey, prevx, mouse_bnmask; 1.15 -static int active = -1, hot = -1, input = -1; 1.16 +static int active = -1, hot = -1, input = -1, prev_active = -1; 1.17 1.18 static struct key_node *key_list, *key_tail; 1.19 1.20 @@ -305,9 +306,84 @@ 1.21 draw_progress(id, pos, x, y); 1.22 } 1.23 1.24 +int imtk_listbox(int id, const char *list, int sel, int x, int y) 1.25 +{ 1.26 + int i; 1.27 + assert(id >= 0); 1.28 + 1.29 + if(!list) { 1.30 + return -1; 1.31 + } 1.32 + 1.33 + if(id & 1) { 1.34 + id++; 1.35 + } 1.36 + 1.37 + for(i=0; *list; i++) { 1.38 + if(imtk_button(id + i * 2 + 1, list, x, y + i * 20)) { 1.39 + sel = i; 1.40 + } 1.41 + list += strlen(list) + 1; 1.42 + } 1.43 + return sel; 1.44 +} 1.45 + 1.46 +int imtk_combobox(int id, char *textbuf, size_t buf_sz, const char *list, int sel, int x, int y) 1.47 +{ 1.48 + imtk_textbox(id + 1, textbuf, buf_sz, x, y); 1.49 + imtk_button(id + 3, "V", x + TEXTBOX_SIZE, y); 1.50 + 1.51 + if(prev_active == id + 3) { 1.52 + sel = imtk_listbox(id + 5, list, sel, x, y + 20); 1.53 + } 1.54 + return sel; 1.55 +} 1.56 + 1.57 +char *imtk_create_list(const char *first, ...) 1.58 +{ 1.59 + int sz; 1.60 + char *buf, *item; 1.61 + va_list ap; 1.62 + 1.63 + if(!first) { 1.64 + return 0; 1.65 + } 1.66 + 1.67 + sz = strlen(first) + 2; 1.68 + if(!(buf = malloc(sz))) { 1.69 + return 0; 1.70 + } 1.71 + memcpy(buf, first, sz - 2); 1.72 + buf[sz - 1] = buf[sz - 2] = 0; 1.73 + 1.74 + va_start(ap, first); 1.75 + while((item = va_arg(ap, char*))) { 1.76 + int len = strlen(item); 1.77 + char *tmp = realloc(buf, sz + len + 1); 1.78 + if(!tmp) { 1.79 + free(buf); 1.80 + return 0; 1.81 + } 1.82 + buf = tmp; 1.83 + 1.84 + memcpy(buf + sz - 1, item, len); 1.85 + sz += len + 1; 1.86 + buf[sz - 1] = buf[sz - 2] = 0; 1.87 + } 1.88 + va_end(ap); 1.89 + 1.90 + return buf; 1.91 +} 1.92 + 1.93 +void imtk_free_list(char *list) 1.94 +{ 1.95 + free(list); 1.96 +} 1.97 + 1.98 static void set_active(int id) 1.99 { 1.100 if(id == -1 || hot == id) { 1.101 + prev_active = active; 1.102 active = id; 1.103 } 1.104 }
2.1 --- a/src/imtk.h Fri Dec 31 18:10:13 2010 +0200 2.2 +++ b/src/imtk.h Sat Mar 05 09:25:27 2011 +0200 2.3 @@ -1,7 +1,8 @@ 2.4 #ifndef IMTK_H_ 2.5 #define IMTK_H_ 2.6 2.7 -#define IMUID (65536 + __LINE__) 2.8 +#define IMUID (__LINE__ << 10) 2.9 +#define IMUID_IDX(i) ((__LINE__ << 10) + ((i) << 1)) 2.10 2.11 enum { 2.12 IMTK_TEXT_COLOR, 2.13 @@ -38,5 +39,11 @@ 2.14 void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y); 2.15 float imtk_slider(int id, float pos, float min, float max, int x, int y); 2.16 void imtk_progress(int id, float pos, int x, int y); 2.17 +int imtk_listbox(int id, const char *list, int sel, int x, int y); 2.18 +int imtk_combobox(int id, char *textbuf, size_t buf_sz, const char *list, int sel, int x, int y); 2.19 + 2.20 +/* helper functions to create and destroy item lists for listboxes and comboboxes */ 2.21 +char *imtk_create_list(const char *first, ...); 2.22 +void imtk_free_list(char *list); 2.23 2.24 #endif /* IMTK_H_ */
3.1 --- a/test.c Fri Dec 31 18:10:13 2010 +0200 3.2 +++ b/test.c Sat Mar 05 09:25:27 2011 +0200 3.3 @@ -20,6 +20,7 @@ 3.4 3.5 int xsz, ysz; 3.6 float angle; 3.7 +int objsel; 3.8 3.9 int main(int argc, char **argv) 3.10 { 3.11 @@ -72,9 +73,24 @@ 3.12 glRotatef(25, 1, 0, 0); 3.13 glRotatef(angle, 0, 1, 0); 3.14 3.15 - glFrontFace(GL_CW); 3.16 - glutSolidTeapot(1.0); 3.17 - glFrontFace(GL_CCW); 3.18 + switch(objsel) { 3.19 + case 0: 3.20 + glFrontFace(GL_CW); 3.21 + glutSolidTeapot(1.0); 3.22 + glFrontFace(GL_CCW); 3.23 + break; 3.24 + 3.25 + case 1: 3.26 + glutSolidTorus(0.5, 1, 12, 24); 3.27 + break; 3.28 + 3.29 + case 2: 3.30 + glutSolidSphere(1.0, 24, 12); 3.31 + break; 3.32 + 3.33 + default: 3.34 + break; 3.35 + } 3.36 3.37 3.38 glViewport(0, 0, 200, ysz); 3.39 @@ -92,6 +108,8 @@ 3.40 static char textbuf[256]; 3.41 static char textbuf2[256]; 3.42 static float val; 3.43 + static int prev_sel; 3.44 + char *itemlist; 3.45 3.46 imtk_begin(); 3.47 3.48 @@ -108,12 +126,19 @@ 3.49 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 3.50 glutPostRedisplay(); 3.51 } 3.52 - if(imtk_button(IMUID, "blue", 30, 100)) { 3.53 + if(imtk_button(IMUID, "blue", 30, 80)) { 3.54 float color[] = {0.3, 0.4, 1, 1}; 3.55 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 3.56 glutPostRedisplay(); 3.57 } 3.58 3.59 + itemlist = imtk_create_list("teapot", "torus", "sphere", NULL); 3.60 + if((objsel = imtk_listbox(IMUID, itemlist, prev_sel, 30, 120)) != prev_sel) { 3.61 + prev_sel = objsel; 3.62 + glutPostRedisplay(); 3.63 + } 3.64 + imtk_free_list(itemlist); 3.65 + 3.66 imtk_textbox(IMUID, textbuf, sizeof textbuf, 30, 200); 3.67 imtk_textbox(IMUID, textbuf2, sizeof textbuf2, 30, 250); 3.68