glamtk
changeset 2:3d661dd17af3
- initial textbox implementation added
- made the test program slightly more interesting
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 31 Dec 2010 01:54:53 +0200 |
parents | dfbd12d1f566 |
children | 038e5577d527 |
files | src/imtk.c src/imtk.h test.c |
diffstat | 3 files changed, 210 insertions(+), 28 deletions(-) [+] |
line diff
1.1 --- a/src/imtk.c Thu Dec 30 15:10:25 2010 +0200 1.2 +++ b/src/imtk.c Fri Dec 31 01:54:53 2010 +0200 1.3 @@ -1,5 +1,6 @@ 1.4 -#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 #include <string.h> 1.7 +#include <ctype.h> 1.8 #include <assert.h> 1.9 #ifndef __APPLE__ 1.10 #include <GL/glut.h> 1.11 @@ -9,12 +10,31 @@ 1.12 #include "imtk.h" 1.13 1.14 #define CHECKBOX_SIZE 14 1.15 +#define TEXTBOX_SIZE 100 1.16 1.17 enum { 1.18 FRAME_OUTSET, 1.19 FRAME_INSET 1.20 }; 1.21 1.22 +struct key_node { 1.23 + int key; 1.24 + struct key_node *next; 1.25 +}; 1.26 + 1.27 +static void set_active(int id); 1.28 +static int set_hot(int id); 1.29 +static int hit_test(int x, int y, int w, int h); 1.30 + 1.31 +static void draw_button(int id, const char *label, int x, int y); 1.32 +static void calc_button_size(const char *label, int *wret, int *hret); 1.33 +static void draw_checkbox(int id, const char *label, int x, int y, int state); 1.34 +static void draw_textbox(int id, const char *text, int x, int y); 1.35 +static void draw_string(int x, int y, const char *str); 1.36 +static int string_size(const char *str); 1.37 +static void draw_frame(int x, int y, int w, int h, int style); 1.38 + 1.39 + 1.40 /* default colors, can be changed with imtk_set_color */ 1.41 static float colors[][4] = { 1.42 {0.0, 0.0, 0.0}, /* text color */ 1.43 @@ -26,18 +46,10 @@ 1.44 1.45 static int scr_width = 1, scr_height = 1; 1.46 static int mousex, mousey, mouse_bnmask; 1.47 -static int active = -1, hot = -1; 1.48 +static int active = -1, hot = -1, input = -1; 1.49 1.50 -static void set_active(int id); 1.51 -static int set_hot(int id); 1.52 -static int hit_test(int x, int y, int w, int h); 1.53 +static struct key_node *key_list, *key_tail; 1.54 1.55 -static void draw_button(int id, const char *label, int x, int y); 1.56 -static void calc_button_size(const char *label, int *wret, int *hret); 1.57 -static void draw_checkbox(int id, const char *label, int x, int y, int state); 1.58 -static void draw_string(int x, int y, const char *str); 1.59 -static int string_size(const char *str); 1.60 -static void draw_frame(int x, int y, int w, int h, int style); 1.61 1.62 void imtk_set_color(int col, float r, float g, float b) 1.63 { 1.64 @@ -50,6 +62,23 @@ 1.65 1.66 void imtk_inp_key(int key, int state) 1.67 { 1.68 + if(state == IMTK_DOWN) { 1.69 + struct key_node *node; 1.70 + 1.71 + if(!(node = malloc(sizeof *node))) { 1.72 + return; 1.73 + } 1.74 + node->key = key; 1.75 + node->next = 0; 1.76 + 1.77 + if(key_list) { 1.78 + key_tail->next = node; 1.79 + key_tail = node; 1.80 + } else { 1.81 + key_list = key_tail = node; 1.82 + } 1.83 + } 1.84 + 1.85 glutPostRedisplay(); 1.86 } 1.87 1.88 @@ -84,12 +113,25 @@ 1.89 glLoadIdentity(); 1.90 glTranslatef(-1, 1, 0); 1.91 glScalef(2.0 / scr_width, -2.0 / scr_height, 1.0); 1.92 + 1.93 + glMatrixMode(GL_MODELVIEW); 1.94 + glPushMatrix(); 1.95 + glLoadIdentity(); 1.96 + 1.97 + glPushAttrib(GL_ENABLE_BIT); 1.98 + glDisable(GL_DEPTH_TEST); 1.99 + glDisable(GL_CULL_FACE); 1.100 + glDisable(GL_LIGHTING); 1.101 } 1.102 1.103 void imtk_end(void) 1.104 { 1.105 + glPopAttrib(); 1.106 + 1.107 glMatrixMode(GL_PROJECTION); 1.108 glPopMatrix(); 1.109 + glMatrixMode(GL_MODELVIEW); 1.110 + glPopMatrix(); 1.111 } 1.112 1.113 int imtk_button(int id, const char *label, int x, int y) 1.114 @@ -152,6 +194,61 @@ 1.115 return state; 1.116 } 1.117 1.118 +void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y) 1.119 +{ 1.120 + int len, over = 0; 1.121 + 1.122 + assert(id >= 0); 1.123 + 1.124 + if(hit_test(x, y, TEXTBOX_SIZE, 20)) { 1.125 + set_hot(id); 1.126 + over = 1; 1.127 + } 1.128 + 1.129 + if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) { 1.130 + if(over) { 1.131 + set_active(id); 1.132 + } 1.133 + } else { 1.134 + if(active == id) { 1.135 + set_active(-1); 1.136 + if(hot == id && over) { 1.137 + input = id; 1.138 + } 1.139 + } 1.140 + } 1.141 + 1.142 + if(input == id) { 1.143 + len = strlen(textbuf); 1.144 + while(key_list) { 1.145 + struct key_node *node = key_list; 1.146 + key_list = key_list->next; 1.147 + 1.148 + if(isprint(node->key)) { 1.149 + if(len < buf_sz) { 1.150 + textbuf[len++] = (char)node->key; 1.151 + } 1.152 + } else { 1.153 + switch(node->key) { 1.154 + case '\b': 1.155 + if(len > 0) { 1.156 + textbuf[--len] = 0; 1.157 + } 1.158 + break; 1.159 + 1.160 + default: 1.161 + break; 1.162 + } 1.163 + } 1.164 + 1.165 + free(node); 1.166 + } 1.167 + key_list = key_tail = 0; 1.168 + } 1.169 + 1.170 + draw_textbox(id, textbuf, x, y); 1.171 +} 1.172 + 1.173 static void set_active(int id) 1.174 { 1.175 active = id; 1.176 @@ -240,6 +337,37 @@ 1.177 draw_string(x + sz + 5, y + sz - 2, label); 1.178 } 1.179 1.180 +static void draw_textbox(int id, const char *text, int x, int y) 1.181 +{ 1.182 + int strsz = string_size(text); 1.183 + 1.184 + if(hit_test(x, y, TEXTBOX_SIZE, 20)) { 1.185 + glColor3fv(colors[IMTK_FOCUS_COLOR]); 1.186 + } else { 1.187 + glColor3fv(colors[IMTK_BASE_COLOR]); 1.188 + } 1.189 + 1.190 + glBegin(GL_QUADS); 1.191 + glVertex2f(x, y); 1.192 + glVertex2f(x + TEXTBOX_SIZE, y); 1.193 + glVertex2f(x + TEXTBOX_SIZE, y + 20); 1.194 + glVertex2f(x, y + 20); 1.195 + glEnd(); 1.196 + 1.197 + glColor3fv(colors[IMTK_TEXT_COLOR]); 1.198 + 1.199 + if(input == id) { 1.200 + glBegin(GL_LINES); 1.201 + glVertex2f(x + strsz + 2, y + 2); 1.202 + glVertex2f(x + strsz + 2, y + 18); 1.203 + glEnd(); 1.204 + } 1.205 + 1.206 + draw_string(x + 2, y + 15, text); 1.207 + 1.208 + draw_frame(x, y, TEXTBOX_SIZE, 20, FRAME_INSET); 1.209 +} 1.210 + 1.211 static void draw_string(int x, int y, const char *str) 1.212 { 1.213 glRasterPos2i(x, y);
2.1 --- a/src/imtk.h Thu Dec 30 15:10:25 2010 +0200 2.2 +++ b/src/imtk.h Fri Dec 31 01:54:53 2010 +0200 2.3 @@ -33,7 +33,9 @@ 2.4 void imtk_begin(void); 2.5 void imtk_end(void); 2.6 2.7 +void imtk_window(int id, const char *title, int x, int y, int width, int height); 2.8 int imtk_button(int id, const char *label, int x, int y); 2.9 int imtk_checkbox(int id, const char *label, int x, int y, int state); 2.10 +void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y); 2.11 2.12 #endif /* IMTK_H_ */
3.1 --- a/test.c Thu Dec 30 15:10:25 2010 +0200 3.2 +++ b/test.c Fri Dec 31 01:54:53 2010 +0200 3.3 @@ -1,5 +1,6 @@ 3.4 #include <stdio.h> 3.5 #include <stdlib.h> 3.6 +#include <assert.h> 3.7 #ifndef __APPLE__ 3.8 #include <GL/glut.h> 3.9 #else 3.10 @@ -17,9 +18,14 @@ 3.11 void mouse(int bn, int state, int x, int y); 3.12 void motion(int x, int y); 3.13 3.14 +int xsz, ysz; 3.15 3.16 int main(int argc, char **argv) 3.17 { 3.18 + float lpos[] = {-1, 1, 1, 0}; 3.19 + float white[] = {1, 1, 1, 1}; 3.20 + float color[] = {0.9, 0.8, 0.73, 1}; 3.21 + 3.22 glutInitWindowSize(800, 600); 3.23 glutInit(&argc, argv); 3.24 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 3.25 @@ -35,54 +41,100 @@ 3.26 glutMotionFunc(motion); 3.27 glutPassiveMotionFunc(motion); 3.28 3.29 + glEnable(GL_DEPTH_TEST); 3.30 + glEnable(GL_CULL_FACE); 3.31 + glEnable(GL_LIGHTING); 3.32 + glEnable(GL_LIGHT0); 3.33 + glLightfv(GL_LIGHT0, GL_POSITION, lpos); 3.34 + 3.35 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 3.36 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); 3.37 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0); 3.38 + 3.39 glutMainLoop(); 3.40 return 0; 3.41 } 3.42 3.43 void disp(void) 3.44 { 3.45 - glClearColor(0.6, 0.6, 0.6, 0.0); 3.46 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 3.47 3.48 + glViewport(200, 0, xsz - 200, ysz); 3.49 + 3.50 + glMatrixMode(GL_PROJECTION); 3.51 + glLoadIdentity(); 3.52 + gluPerspective(45.0, (float)(xsz - 200) / (float)ysz, 1.0, 1000.0); 3.53 + 3.54 + glMatrixMode(GL_MODELVIEW); 3.55 + glLoadIdentity(); 3.56 + glTranslatef(0, 0, -8); 3.57 + glRotatef(25, 1, 0, 0); 3.58 + 3.59 + glFrontFace(GL_CW); 3.60 + glutSolidTeapot(1.0); 3.61 + glFrontFace(GL_CCW); 3.62 + 3.63 + 3.64 + glViewport(0, 0, 200, ysz); 3.65 + imtk_inp_reshape(200, ysz); 3.66 + 3.67 gui(); 3.68 3.69 glutSwapBuffers(); 3.70 + assert(glGetError() == GL_NO_ERROR); 3.71 } 3.72 3.73 void gui(void) 3.74 { 3.75 static int bnshow; 3.76 + static char textbuf[256]; 3.77 + static char textbuf2[256]; 3.78 3.79 imtk_begin(); 3.80 3.81 - if(imtk_button(IMUID, "foobar", 100, 100)) { 3.82 - printf("clicked button 0\n"); 3.83 + glBegin(GL_QUADS); 3.84 + glColor3f(0.6, 0.6, 0.6); 3.85 + glVertex2f(0, 0); 3.86 + glVertex2f(200, 0); 3.87 + glVertex2f(200, glutGet(GLUT_WINDOW_HEIGHT)); 3.88 + glVertex2f(0, glutGet(GLUT_WINDOW_HEIGHT)); 3.89 + glEnd(); 3.90 + 3.91 + if(imtk_button(IMUID, "red", 30, 50)) { 3.92 + float color[] = {1, 0.4, 0.3, 1}; 3.93 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 3.94 + glutPostRedisplay(); 3.95 } 3.96 - if(imtk_button(IMUID, "xyzzy", 100, 200)) { 3.97 - printf("clicked button 1\n"); 3.98 - } 3.99 - if(imtk_button(IMUID, "Quit", 100, 500)) { 3.100 - exit(0); 3.101 + if(imtk_button(IMUID, "blue", 30, 100)) { 3.102 + float color[] = {0.3, 0.4, 1, 1}; 3.103 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 3.104 + glutPostRedisplay(); 3.105 } 3.106 3.107 - if((bnshow = imtk_checkbox(IMUID, "show hidden button", 100, 260, bnshow))) { 3.108 - if(imtk_button(IMUID, "I was hidden!", 130, 300)) { 3.109 - printf("you clicked the hidden button!\n"); 3.110 + imtk_textbox(IMUID, textbuf, sizeof textbuf, 30, 200); 3.111 + imtk_textbox(IMUID, textbuf2, sizeof textbuf2, 30, 250); 3.112 + 3.113 + if((bnshow = imtk_checkbox(IMUID, "show hidden button", 30, 300, bnshow))) { 3.114 + if(imtk_button(IMUID, "yellow", 50, 340)) { 3.115 + float color[] = {0.8, 0.75, 0.3, 1}; 3.116 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 3.117 + glutPostRedisplay(); 3.118 } 3.119 } 3.120 3.121 + if(imtk_button(IMUID, "Quit", 30, 500)) { 3.122 + exit(0); 3.123 + } 3.124 + 3.125 imtk_end(); 3.126 } 3.127 3.128 void reshape(int x, int y) 3.129 { 3.130 + xsz = x; 3.131 + ysz = y; 3.132 + 3.133 glViewport(0, 0, x, y); 3.134 - imtk_inp_reshape(x, y); 3.135 - 3.136 - glMatrixMode(GL_PROJECTION); 3.137 - glLoadIdentity(); 3.138 - glTranslatef(-1, -1, 0); 3.139 - glScalef(2.0 / x, 2.0 / y, 1.0); 3.140 } 3.141 3.142 void keyb(unsigned char key, int x, int y)