imtk
diff src/imtk.c @ 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 |
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);