imtk

changeset 16:1cf212375db3

textbox cursor handling
author John Tsiombikas <nuclear@siggraph.org>
date Tue, 19 Apr 2011 08:24:39 +0300
parents 6893b4dca5a3
children ac2a8d8fca9a
files src/textbox.c test.c
diffstat 2 files changed, 71 insertions(+), 19 deletions(-) [+]
line diff
     1.1 --- a/src/textbox.c	Tue Apr 19 05:10:09 2011 +0300
     1.2 +++ b/src/textbox.c	Tue Apr 19 08:24:39 2011 +0300
     1.3 @@ -7,15 +7,22 @@
     1.4  
     1.5  #define TEXTBOX_SIZE	100
     1.6  
     1.7 -static void draw_textbox(int id, const char *text, int x, int y, int over);
     1.8 +static void draw_textbox(int id, char *text, int cursor, int x, int y, int over);
     1.9  
    1.10  
    1.11  void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y)
    1.12  {
    1.13 -	int len, over = 0;
    1.14 +	int key, len, cursor = 0, over = 0;
    1.15  
    1.16  	assert(id >= 0);
    1.17  
    1.18 +	len = strlen(textbuf);
    1.19 +
    1.20 +	/* HACK! using last element of textbuf for saving cursor position */
    1.21 +	if((cursor = textbuf[buf_sz - 1]) > len || cursor < 0) {
    1.22 +		cursor = len;
    1.23 +	}
    1.24 +
    1.25  	if(imtk_hit_test(x, y, TEXTBOX_SIZE, 20)) {
    1.26  		imtk_set_hot(id);
    1.27  		over = 1;
    1.28 @@ -35,22 +42,61 @@
    1.29  	}
    1.30  
    1.31  	if(imtk_has_focus(id)) {
    1.32 -		int key;
    1.33 -		len = strlen(textbuf);
    1.34 -
    1.35  		while((key = imtk_get_key()) != -1) {
    1.36 -			if(isprint(key)) {
    1.37 -				if(len < buf_sz) {
    1.38 -					textbuf[len++] = (char)key;
    1.39 +			if(!(key & 0xff00) && isprint(key)) {
    1.40 +				if(len < buf_sz - 1) {
    1.41 +					if(cursor == len) {
    1.42 +						textbuf[len++] = (char)key;
    1.43 +						cursor = len;
    1.44 +					} else {
    1.45 +						memmove(textbuf + cursor + 1, textbuf + cursor, len - cursor);
    1.46 +						len++;
    1.47 +						textbuf[cursor++] = (char)key;
    1.48 +					}
    1.49  				}
    1.50  			} else {
    1.51 +				key &= 0xff;
    1.52 +
    1.53  				switch(key) {
    1.54  				case '\b':
    1.55 -					if(len > 0) {
    1.56 +					if(cursor > 0) {
    1.57 +						if(cursor == len) {
    1.58 +							textbuf[--cursor] = 0;
    1.59 +						} else {
    1.60 +							memmove(textbuf + cursor - 1, textbuf + cursor, len - cursor);
    1.61 +							textbuf[--len] = 0;
    1.62 +							cursor--;
    1.63 +						}
    1.64 +					}
    1.65 +					break;
    1.66 +
    1.67 +				case 127:	/* del */
    1.68 +					if(cursor < len) {
    1.69 +						memmove(textbuf + cursor, textbuf + cursor + 1, len - cursor);
    1.70  						textbuf[--len] = 0;
    1.71  					}
    1.72  					break;
    1.73  
    1.74 +				case GLUT_KEY_LEFT:
    1.75 +					if(cursor > 0) {
    1.76 +						cursor--;
    1.77 +					}
    1.78 +					break;
    1.79 +
    1.80 +				case GLUT_KEY_RIGHT:
    1.81 +					if(cursor < len) {
    1.82 +						cursor++;
    1.83 +					}
    1.84 +					break;
    1.85 +
    1.86 +				case GLUT_KEY_HOME:
    1.87 +					cursor = 0;
    1.88 +					break;
    1.89 +
    1.90 +				case GLUT_KEY_END:
    1.91 +					cursor = len;
    1.92 +					break;
    1.93 +
    1.94  				default:
    1.95  					break;
    1.96  				}
    1.97 @@ -58,13 +104,13 @@
    1.98  		}
    1.99  	}
   1.100  
   1.101 -	draw_textbox(id, textbuf, x, y, over);
   1.102 +	textbuf[buf_sz - 1] = cursor;
   1.103 +	draw_textbox(id, textbuf, cursor, x, y, over);
   1.104  }
   1.105  
   1.106  
   1.107 -static void draw_textbox(int id, const char *text, int x, int y, int over)
   1.108 +static void draw_textbox(int id, char *text, int cursor, int x, int y, int over)
   1.109  {
   1.110 -	int strsz = imtk_string_size(text);
   1.111  	float tcol[4], bcol[4];
   1.112  	unsigned int attr = 0;
   1.113  
   1.114 @@ -77,12 +123,20 @@
   1.115  	imtk_draw_rect(x, y, TEXTBOX_SIZE, 20, tcol, bcol);
   1.116  
   1.117  	if(imtk_has_focus(id)) {
   1.118 -		glBegin(GL_LINES);
   1.119 +		int strsz;
   1.120 +		char tmp;
   1.121 +
   1.122 +		tmp = text[cursor];
   1.123 +		text[cursor] = 0;
   1.124 +		strsz = imtk_string_size(text);
   1.125 +		text[cursor] = tmp;
   1.126 +
   1.127 +		glBegin(GL_QUADS);
   1.128  		glColor4fv(imtk_get_color(IMTK_CURSOR_COLOR));
   1.129 -		glVertex2f(x + strsz + 3, y + 2);
   1.130 -		glVertex2f(x + strsz + 3, y + 18);
   1.131 +		glVertex2f(x + strsz + 2, y + 2);
   1.132  		glVertex2f(x + strsz + 4, y + 2);
   1.133  		glVertex2f(x + strsz + 4, y + 18);
   1.134 +		glVertex2f(x + strsz + 2, y + 18);
   1.135  		glEnd();
   1.136  	}
   1.137  
     2.1 --- a/test.c	Tue Apr 19 05:10:09 2011 +0300
     2.2 +++ b/test.c	Tue Apr 19 08:24:39 2011 +0300
     2.3 @@ -53,8 +53,6 @@
     2.4  	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
     2.5  	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0);
     2.6  
     2.7 -	imtk_set_bevel_width(1);
     2.8 -
     2.9  	glutMainLoop();
    2.10  	return 0;
    2.11  }
    2.12 @@ -216,12 +214,12 @@
    2.13  
    2.14  void skeyb(int key, int x, int y)
    2.15  {
    2.16 -	imtk_inp_key(key, IMTK_DOWN);
    2.17 +	imtk_inp_key(key | 0x100, IMTK_DOWN);
    2.18  }
    2.19  
    2.20  void skeyb_up(int key, int x, int y)
    2.21  {
    2.22 -	imtk_inp_key(key, IMTK_UP);
    2.23 +	imtk_inp_key(key | 0x100, IMTK_UP);
    2.24  }
    2.25  
    2.26  void mouse(int bn, int state, int x, int y)