glamtk

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);