nuclear@0: #include nuclear@0: #include nuclear@0: #ifndef __APPLE__ nuclear@0: #include nuclear@0: #else nuclear@0: #include nuclear@0: #endif nuclear@0: #include "imtk.h" nuclear@0: nuclear@0: static int scr_width = 1, scr_height = 1; nuclear@0: static int mousex, mousey, mouse_bnmask; nuclear@0: static int active = -1, hot = -1; nuclear@0: nuclear@0: static void set_active(int id); nuclear@0: static int set_hot(int id); nuclear@0: static int hit_test(int x, int y, int w, int h); nuclear@0: nuclear@0: static void draw_button(int id, int x, int y, const char *label, int focused); nuclear@0: static void calc_button_size(const char *label, int *wret, int *hret); nuclear@0: static void draw_string(int x, int y, const char *str); nuclear@0: static int string_size(const char *str); nuclear@0: nuclear@0: void imtk_inp_key(int key, int state) nuclear@0: { nuclear@0: glutPostRedisplay(); nuclear@0: } nuclear@0: nuclear@0: void imtk_inp_mouse(int bn, int state) nuclear@0: { nuclear@0: if(state == IMTK_DOWN) { nuclear@0: mouse_bnmask |= 1 << bn; nuclear@0: } else { nuclear@0: mouse_bnmask &= ~(1 << bn); nuclear@0: } nuclear@0: glutPostRedisplay(); nuclear@0: } nuclear@0: nuclear@0: void imtk_inp_motion(int x, int y) nuclear@0: { nuclear@0: mousex = x; nuclear@0: mousey = y; nuclear@0: nuclear@0: glutPostRedisplay(); nuclear@0: } nuclear@0: nuclear@0: void imtk_inp_reshape(int x, int y) nuclear@0: { nuclear@0: scr_width = x; nuclear@0: scr_height = y; nuclear@0: } nuclear@0: nuclear@0: void imtk_begin(void) nuclear@0: { nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glPushMatrix(); nuclear@0: glLoadIdentity(); nuclear@0: glTranslatef(-1, 1, 0); nuclear@0: glScalef(2.0 / scr_width, -2.0 / scr_height, 1.0); nuclear@0: } nuclear@0: nuclear@0: void imtk_end(void) nuclear@0: { nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glPopMatrix(); nuclear@0: } nuclear@0: nuclear@0: int imtk_button(int id, const char *label, int x, int y) nuclear@0: { nuclear@0: int w, h, res = 0; nuclear@0: int over = 0; nuclear@0: nuclear@0: assert(id >= 0); nuclear@0: nuclear@0: calc_button_size(label, &w, &h); nuclear@0: nuclear@0: if(hit_test(x, y, w, h)) { nuclear@0: if(set_hot(id)) { nuclear@0: glutPostRedisplay(); nuclear@0: } nuclear@0: over = 1; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) { nuclear@0: if(over) { nuclear@0: set_active(id); nuclear@0: } nuclear@0: } else { /* mouse button up */ nuclear@0: if(active == id) { nuclear@0: set_active(-1); nuclear@0: if(hot == id && over) { nuclear@0: res = 1; nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: draw_button(id, x, y, label, over); nuclear@0: return res; nuclear@0: } nuclear@0: nuclear@0: static void set_active(int id) nuclear@0: { nuclear@0: active = id; nuclear@0: } nuclear@0: nuclear@0: static int set_hot(int id) nuclear@0: { nuclear@0: if(active == -1) { nuclear@0: hot = id; nuclear@0: return 1; nuclear@0: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: static int hit_test(int x, int y, int w, int h) nuclear@0: { nuclear@0: return mousex >= x && mousex < (x + w) && nuclear@0: mousey >= y && mousey < (y + h); nuclear@0: } nuclear@0: nuclear@0: static void draw_button(int id, int x, int y, const char *label, int focused) nuclear@0: { nuclear@0: int width, height; nuclear@0: nuclear@0: calc_button_size(label, &width, &height); nuclear@0: nuclear@0: glBegin(GL_QUADS); nuclear@0: if(focused) { nuclear@0: glColor3f(0.85, 0.85, 0.85); nuclear@0: } else { nuclear@0: glColor3f(0.7, 0.7, 0.7); nuclear@0: } nuclear@0: glVertex2f(x, y); nuclear@0: glVertex2f(x + width, y); nuclear@0: glVertex2f(x + width, y + height); nuclear@0: glVertex2f(x, y + height); nuclear@0: glEnd(); nuclear@0: nuclear@0: glColor3f(0, 0, 0); nuclear@0: draw_string(x + 20, y + 15, label); nuclear@0: } nuclear@0: nuclear@0: static void calc_button_size(const char *label, int *wret, int *hret) nuclear@0: { nuclear@0: int strsz = string_size(label); nuclear@0: if(wret) *wret = strsz + 40; nuclear@0: if(hret) *hret = 20; nuclear@0: } nuclear@0: nuclear@0: static void draw_string(int x, int y, const char *str) nuclear@0: { nuclear@0: glRasterPos2i(x, y); nuclear@0: while(*str) { nuclear@0: glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *str++); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: static int string_size(const char *str) nuclear@0: { nuclear@0: return glutBitmapLength(GLUT_BITMAP_HELVETICA_10, str); nuclear@0: }