# HG changeset patch # User John Tsiombikas # Date 1293714625 -7200 # Node ID dfbd12d1f566f90578780e0b8a348eb9e1ca1b6a # Parent b04d49e4599c4ddb0ec3ec10fa564d4502b57460 finished the checkbox control, did some reorg as well. diff -r b04d49e4599c -r dfbd12d1f566 src/imtk.c --- a/src/imtk.c Thu Dec 30 05:22:14 2010 +0200 +++ b/src/imtk.c Thu Dec 30 15:10:25 2010 +0200 @@ -1,4 +1,5 @@ #include +#include #include #ifndef __APPLE__ #include @@ -7,6 +8,22 @@ #endif #include "imtk.h" +#define CHECKBOX_SIZE 14 + +enum { + FRAME_OUTSET, + FRAME_INSET +}; + +/* default colors, can be changed with imtk_set_color */ +static float colors[][4] = { + {0.0, 0.0, 0.0}, /* text color */ + {0.7, 0.7, 0.7}, /* base color */ + {0.85, 0.85, 0.85}, /* focus color */ + {1.0, 1.0, 1.0}, /* lit bevel */ + {0.3, 0.3, 0.3} /* shadowed bevel */ +}; + static int scr_width = 1, scr_height = 1; static int mousex, mousey, mouse_bnmask; static int active = -1, hot = -1; @@ -15,10 +32,21 @@ static int set_hot(int id); static int hit_test(int x, int y, int w, int h); -static void draw_button(int id, int x, int y, const char *label, int focused); +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) +{ + assert(col >= 0 && col < sizeof colors / sizeof *colors); + + colors[col][0] = r; + colors[col][1] = g; + colors[col][2] = b; +} void imtk_inp_key(int key, int state) { @@ -74,13 +102,10 @@ calc_button_size(label, &w, &h); if(hit_test(x, y, w, h)) { - if(set_hot(id)) { - glutPostRedisplay(); - } + set_hot(id); over = 1; } - if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) { if(over) { set_active(id); @@ -94,10 +119,39 @@ } } - draw_button(id, x, y, label, over); + draw_button(id, label, x, y); return res; } +int imtk_checkbox(int id, const char *label, int x, int y, int state) +{ + int sz = CHECKBOX_SIZE; + int over = 0; + + assert(id >= 0); + + if(hit_test(x, y, sz, sz)) { + set_hot(id); + over = 1; + } + + if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) { + if(over) { + set_active(id); + } + } else { /* mouse button up */ + if(active == id) { + set_active(-1); + if(hot == id && over) { + state = !state; + } + } + } + + draw_checkbox(id, label, x, y, state); + return state; +} + static void set_active(int id) { active = id; @@ -118,17 +172,17 @@ mousey >= y && mousey < (y + h); } -static void draw_button(int id, int x, int y, const char *label, int focused) +static void draw_button(int id, const char *label, int x, int y) { int width, height; calc_button_size(label, &width, &height); glBegin(GL_QUADS); - if(focused) { - glColor3f(0.85, 0.85, 0.85); + if(hit_test(x, y, width, height)) { + glColor3fv(colors[IMTK_FOCUS_COLOR]); } else { - glColor3f(0.7, 0.7, 0.7); + glColor3fv(colors[IMTK_BASE_COLOR]); } glVertex2f(x, y); glVertex2f(x + width, y); @@ -136,7 +190,9 @@ glVertex2f(x, y + height); glEnd(); - glColor3f(0, 0, 0); + draw_frame(x, y, width, height, active == id ? FRAME_INSET : FRAME_OUTSET); + + glColor3fv(colors[IMTK_TEXT_COLOR]); draw_string(x + 20, y + 15, label); } @@ -147,15 +203,82 @@ if(hret) *hret = 20; } +static void draw_checkbox(int id, const char *label, int x, int y, int state) +{ + static const int sz = CHECKBOX_SIZE; + + if(hit_test(x, y, sz, sz)) { + glColor3fv(colors[IMTK_FOCUS_COLOR]); + } else { + glColor3fv(colors[IMTK_BASE_COLOR]); + } + + glBegin(GL_QUADS); + glVertex2f(x, y); + glVertex2f(x + sz, y); + glVertex2f(x + sz, y + sz); + glVertex2f(x, y + sz); + glEnd(); + + draw_frame(x, y, sz, sz, FRAME_INSET); + + glColor3fv(colors[IMTK_TEXT_COLOR]); + if(state) { + glPushAttrib(GL_LINE_BIT); + glLineWidth(2); + + glBegin(GL_LINES); + glVertex2f(x + 2, y + 2); + glVertex2f(x + sz - 2, y + sz - 2); + glVertex2f(x + sz - 2, y + 2); + glVertex2f(x + 2, y + sz - 2); + glEnd(); + + glPopAttrib(); + } + + draw_string(x + sz + 5, y + sz - 2, label); +} + static void draw_string(int x, int y, const char *str) { glRasterPos2i(x, y); while(*str) { - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *str++); + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *str++); } } static int string_size(const char *str) { - return glutBitmapLength(GLUT_BITMAP_HELVETICA_10, str); + return glutBitmapLength(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)str); } + +static void draw_frame(int x, int y, int w, int h, int style) +{ + float tcol[3], bcol[3]; + + switch(style) { + case FRAME_INSET: + memcpy(tcol, colors[IMTK_BEVEL_SHAD_COLOR], sizeof tcol); + memcpy(bcol, colors[IMTK_BEVEL_LIT_COLOR], sizeof bcol); + break; + + case FRAME_OUTSET: + default: + memcpy(tcol, colors[IMTK_BEVEL_LIT_COLOR], sizeof tcol); + memcpy(bcol, colors[IMTK_BEVEL_SHAD_COLOR], sizeof bcol); + } + + glBegin(GL_LINES); + glColor3fv(tcol); + glVertex2f(x, y + h); + glVertex2f(x, y); + glVertex2f(x, y); + glVertex2f(x + w, y); + glColor3fv(bcol); + glVertex2f(x + w, y); + glVertex2f(x + w, y + h); + glVertex2f(x + w, y + h); + glVertex2f(x, y + h); + glEnd(); +} diff -r b04d49e4599c -r dfbd12d1f566 src/imtk.h --- a/src/imtk.h Thu Dec 30 05:22:14 2010 +0200 +++ b/src/imtk.h Thu Dec 30 15:10:25 2010 +0200 @@ -1,6 +1,16 @@ #ifndef IMTK_H_ #define IMTK_H_ +#define IMUID (65536 + __LINE__) + +enum { + IMTK_TEXT_COLOR, + IMTK_BASE_COLOR, + IMTK_FOCUS_COLOR, + IMTK_BEVEL_LIT_COLOR, + IMTK_BEVEL_SHAD_COLOR +}; + /* key/button state enum */ enum { IMTK_UP, @@ -13,6 +23,8 @@ IMTK_RIGHT_BUTTON }; +void imtk_set_color(int col, float r, float g, float b); + void imtk_inp_key(int key, int state); void imtk_inp_mouse(int bn, int state); void imtk_inp_motion(int x, int y); @@ -22,5 +34,6 @@ void imtk_end(void); 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); #endif /* IMTK_H_ */ diff -r b04d49e4599c -r dfbd12d1f566 test.c --- a/test.c Thu Dec 30 05:22:14 2010 +0200 +++ b/test.c Thu Dec 30 15:10:25 2010 +0200 @@ -8,6 +8,7 @@ #include "imtk.h" void disp(void); +void gui(void); void reshape(int x, int y); void keyb(unsigned char key, int x, int y); void keyb_up(unsigned char key, int x, int y); @@ -40,20 +41,37 @@ void disp(void) { + glClearColor(0.6, 0.6, 0.6, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + gui(); + + glutSwapBuffers(); +} + +void gui(void) +{ + static int bnshow; + imtk_begin(); - if(imtk_button(0, "foobar", 100, 100)) { + if(imtk_button(IMUID, "foobar", 100, 100)) { printf("clicked button 0\n"); } - if(imtk_button(1, "xyzzy", 100, 200)) { + if(imtk_button(IMUID, "xyzzy", 100, 200)) { printf("clicked button 1\n"); } + if(imtk_button(IMUID, "Quit", 100, 500)) { + exit(0); + } + + 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_end(); - - glutSwapBuffers(); } void reshape(int x, int y)