# HG changeset patch # User John Tsiombikas # Date 1293753293 -7200 # Node ID 3d661dd17af3d7afc83a80f36d8dbdeef8dd1d22 # Parent dfbd12d1f566f90578780e0b8a348eb9e1ca1b6a - initial textbox implementation added - made the test program slightly more interesting diff -r dfbd12d1f566 -r 3d661dd17af3 src/imtk.c --- a/src/imtk.c Thu Dec 30 15:10:25 2010 +0200 +++ b/src/imtk.c Fri Dec 31 01:54:53 2010 +0200 @@ -1,5 +1,6 @@ -#include +#include #include +#include #include #ifndef __APPLE__ #include @@ -9,12 +10,31 @@ #include "imtk.h" #define CHECKBOX_SIZE 14 +#define TEXTBOX_SIZE 100 enum { FRAME_OUTSET, FRAME_INSET }; +struct key_node { + int key; + struct key_node *next; +}; + +static void set_active(int id); +static int set_hot(int id); +static int hit_test(int x, int y, int w, int h); + +static void draw_button(int id, const char *label, int x, int y); +static void calc_button_size(const char *label, int *wret, int *hret); +static void draw_checkbox(int id, const char *label, int x, int y, int state); +static void draw_textbox(int id, const char *text, int x, int y); +static void draw_string(int x, int y, const char *str); +static int string_size(const char *str); +static void draw_frame(int x, int y, int w, int h, int style); + + /* default colors, can be changed with imtk_set_color */ static float colors[][4] = { {0.0, 0.0, 0.0}, /* text color */ @@ -26,18 +46,10 @@ static int scr_width = 1, scr_height = 1; static int mousex, mousey, mouse_bnmask; -static int active = -1, hot = -1; +static int active = -1, hot = -1, input = -1; -static void set_active(int id); -static int set_hot(int id); -static int hit_test(int x, int y, int w, int h); +static struct key_node *key_list, *key_tail; -static void draw_button(int id, const char *label, int x, int y); -static void calc_button_size(const char *label, int *wret, int *hret); -static void draw_checkbox(int id, const char *label, int x, int y, int state); -static void draw_string(int x, int y, const char *str); -static int string_size(const char *str); -static void draw_frame(int x, int y, int w, int h, int style); void imtk_set_color(int col, float r, float g, float b) { @@ -50,6 +62,23 @@ void imtk_inp_key(int key, int state) { + if(state == IMTK_DOWN) { + struct key_node *node; + + if(!(node = malloc(sizeof *node))) { + return; + } + node->key = key; + node->next = 0; + + if(key_list) { + key_tail->next = node; + key_tail = node; + } else { + key_list = key_tail = node; + } + } + glutPostRedisplay(); } @@ -84,12 +113,25 @@ glLoadIdentity(); glTranslatef(-1, 1, 0); glScalef(2.0 / scr_width, -2.0 / scr_height, 1.0); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); } void imtk_end(void) { + glPopAttrib(); + glMatrixMode(GL_PROJECTION); glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } int imtk_button(int id, const char *label, int x, int y) @@ -152,6 +194,61 @@ return state; } +void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y) +{ + int len, over = 0; + + assert(id >= 0); + + if(hit_test(x, y, TEXTBOX_SIZE, 20)) { + set_hot(id); + over = 1; + } + + if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) { + if(over) { + set_active(id); + } + } else { + if(active == id) { + set_active(-1); + if(hot == id && over) { + input = id; + } + } + } + + if(input == id) { + len = strlen(textbuf); + while(key_list) { + struct key_node *node = key_list; + key_list = key_list->next; + + if(isprint(node->key)) { + if(len < buf_sz) { + textbuf[len++] = (char)node->key; + } + } else { + switch(node->key) { + case '\b': + if(len > 0) { + textbuf[--len] = 0; + } + break; + + default: + break; + } + } + + free(node); + } + key_list = key_tail = 0; + } + + draw_textbox(id, textbuf, x, y); +} + static void set_active(int id) { active = id; @@ -240,6 +337,37 @@ draw_string(x + sz + 5, y + sz - 2, label); } +static void draw_textbox(int id, const char *text, int x, int y) +{ + int strsz = string_size(text); + + if(hit_test(x, y, TEXTBOX_SIZE, 20)) { + glColor3fv(colors[IMTK_FOCUS_COLOR]); + } else { + glColor3fv(colors[IMTK_BASE_COLOR]); + } + + glBegin(GL_QUADS); + glVertex2f(x, y); + glVertex2f(x + TEXTBOX_SIZE, y); + glVertex2f(x + TEXTBOX_SIZE, y + 20); + glVertex2f(x, y + 20); + glEnd(); + + glColor3fv(colors[IMTK_TEXT_COLOR]); + + if(input == id) { + glBegin(GL_LINES); + glVertex2f(x + strsz + 2, y + 2); + glVertex2f(x + strsz + 2, y + 18); + glEnd(); + } + + draw_string(x + 2, y + 15, text); + + draw_frame(x, y, TEXTBOX_SIZE, 20, FRAME_INSET); +} + static void draw_string(int x, int y, const char *str) { glRasterPos2i(x, y); diff -r dfbd12d1f566 -r 3d661dd17af3 src/imtk.h --- a/src/imtk.h Thu Dec 30 15:10:25 2010 +0200 +++ b/src/imtk.h Fri Dec 31 01:54:53 2010 +0200 @@ -33,7 +33,9 @@ void imtk_begin(void); void imtk_end(void); +void imtk_window(int id, const char *title, int x, int y, int width, int height); int imtk_button(int id, const char *label, int x, int y); int imtk_checkbox(int id, const char *label, int x, int y, int state); +void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y); #endif /* IMTK_H_ */ diff -r dfbd12d1f566 -r 3d661dd17af3 test.c --- a/test.c Thu Dec 30 15:10:25 2010 +0200 +++ b/test.c Fri Dec 31 01:54:53 2010 +0200 @@ -1,5 +1,6 @@ #include #include +#include #ifndef __APPLE__ #include #else @@ -17,9 +18,14 @@ void mouse(int bn, int state, int x, int y); void motion(int x, int y); +int xsz, ysz; int main(int argc, char **argv) { + float lpos[] = {-1, 1, 1, 0}; + float white[] = {1, 1, 1, 1}; + float color[] = {0.9, 0.8, 0.73, 1}; + glutInitWindowSize(800, 600); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); @@ -35,54 +41,100 @@ glutMotionFunc(motion); glutPassiveMotionFunc(motion); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lpos); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0); + glutMainLoop(); return 0; } void disp(void) { - glClearColor(0.6, 0.6, 0.6, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glViewport(200, 0, xsz - 200, ysz); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, (float)(xsz - 200) / (float)ysz, 1.0, 1000.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -8); + glRotatef(25, 1, 0, 0); + + glFrontFace(GL_CW); + glutSolidTeapot(1.0); + glFrontFace(GL_CCW); + + + glViewport(0, 0, 200, ysz); + imtk_inp_reshape(200, ysz); + gui(); glutSwapBuffers(); + assert(glGetError() == GL_NO_ERROR); } void gui(void) { static int bnshow; + static char textbuf[256]; + static char textbuf2[256]; imtk_begin(); - if(imtk_button(IMUID, "foobar", 100, 100)) { - printf("clicked button 0\n"); + glBegin(GL_QUADS); + glColor3f(0.6, 0.6, 0.6); + glVertex2f(0, 0); + glVertex2f(200, 0); + glVertex2f(200, glutGet(GLUT_WINDOW_HEIGHT)); + glVertex2f(0, glutGet(GLUT_WINDOW_HEIGHT)); + glEnd(); + + if(imtk_button(IMUID, "red", 30, 50)) { + float color[] = {1, 0.4, 0.3, 1}; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); + glutPostRedisplay(); } - if(imtk_button(IMUID, "xyzzy", 100, 200)) { - printf("clicked button 1\n"); - } - if(imtk_button(IMUID, "Quit", 100, 500)) { - exit(0); + if(imtk_button(IMUID, "blue", 30, 100)) { + float color[] = {0.3, 0.4, 1, 1}; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); + glutPostRedisplay(); } - if((bnshow = imtk_checkbox(IMUID, "show hidden button", 100, 260, bnshow))) { - if(imtk_button(IMUID, "I was hidden!", 130, 300)) { - printf("you clicked the hidden button!\n"); + imtk_textbox(IMUID, textbuf, sizeof textbuf, 30, 200); + imtk_textbox(IMUID, textbuf2, sizeof textbuf2, 30, 250); + + if((bnshow = imtk_checkbox(IMUID, "show hidden button", 30, 300, bnshow))) { + if(imtk_button(IMUID, "yellow", 50, 340)) { + float color[] = {0.8, 0.75, 0.3, 1}; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); + glutPostRedisplay(); } } + if(imtk_button(IMUID, "Quit", 30, 500)) { + exit(0); + } + imtk_end(); } void reshape(int x, int y) { + xsz = x; + ysz = y; + glViewport(0, 0, x, y); - imtk_inp_reshape(x, y); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glTranslatef(-1, -1, 0); - glScalef(2.0 / x, 2.0 / y, 1.0); } void keyb(unsigned char key, int x, int y)