imtk

view src/textbox.c @ 16:1cf212375db3

textbox cursor handling
author John Tsiombikas <nuclear@siggraph.org>
date Tue, 19 Apr 2011 08:24:39 +0300
parents df2bc9406561
children c7a7ddbe7714
line source
1 #include <string.h>
2 #include <ctype.h>
3 #include <assert.h>
4 #include "imtk.h"
5 #include "state.h"
6 #include "draw.h"
8 #define TEXTBOX_SIZE 100
10 static void draw_textbox(int id, char *text, int cursor, int x, int y, int over);
13 void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y)
14 {
15 int key, len, cursor = 0, over = 0;
17 assert(id >= 0);
19 len = strlen(textbuf);
21 /* HACK! using last element of textbuf for saving cursor position */
22 if((cursor = textbuf[buf_sz - 1]) > len || cursor < 0) {
23 cursor = len;
24 }
26 if(imtk_hit_test(x, y, TEXTBOX_SIZE, 20)) {
27 imtk_set_hot(id);
28 over = 1;
29 }
31 if(imtk_button_state(IMTK_LEFT_BUTTON)) {
32 if(over) {
33 imtk_set_active(id);
34 }
35 } else {
36 if(imtk_is_active(id)) {
37 imtk_set_active(-1);
38 if(imtk_is_hot(id) && over) {
39 imtk_set_focus(id);
40 }
41 }
42 }
44 if(imtk_has_focus(id)) {
45 while((key = imtk_get_key()) != -1) {
46 if(!(key & 0xff00) && isprint(key)) {
47 if(len < buf_sz - 1) {
48 if(cursor == len) {
49 textbuf[len++] = (char)key;
50 cursor = len;
51 } else {
52 memmove(textbuf + cursor + 1, textbuf + cursor, len - cursor);
53 len++;
54 textbuf[cursor++] = (char)key;
55 }
56 }
57 } else {
58 key &= 0xff;
60 switch(key) {
61 case '\b':
62 if(cursor > 0) {
63 if(cursor == len) {
64 textbuf[--cursor] = 0;
65 } else {
66 memmove(textbuf + cursor - 1, textbuf + cursor, len - cursor);
67 textbuf[--len] = 0;
68 cursor--;
69 }
70 }
71 break;
73 case 127: /* del */
74 if(cursor < len) {
75 memmove(textbuf + cursor, textbuf + cursor + 1, len - cursor);
76 textbuf[--len] = 0;
77 }
78 break;
80 case GLUT_KEY_LEFT:
81 if(cursor > 0) {
82 cursor--;
83 }
84 break;
86 case GLUT_KEY_RIGHT:
87 if(cursor < len) {
88 cursor++;
89 }
90 break;
92 case GLUT_KEY_HOME:
93 cursor = 0;
94 break;
96 case GLUT_KEY_END:
97 cursor = len;
98 break;
100 default:
101 break;
102 }
103 }
104 }
105 }
107 textbuf[buf_sz - 1] = cursor;
108 draw_textbox(id, textbuf, cursor, x, y, over);
109 }
112 static void draw_textbox(int id, char *text, int cursor, int x, int y, int over)
113 {
114 float tcol[4], bcol[4];
115 unsigned int attr = 0;
117 if(over) {
118 attr |= IMTK_FOCUS_BIT;
119 }
120 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
121 memcpy(bcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof bcol);
123 imtk_draw_rect(x, y, TEXTBOX_SIZE, 20, tcol, bcol);
125 if(imtk_has_focus(id)) {
126 int strsz;
127 char tmp;
129 tmp = text[cursor];
130 text[cursor] = 0;
131 strsz = imtk_string_size(text);
132 text[cursor] = tmp;
134 glBegin(GL_QUADS);
135 glColor4fv(imtk_get_color(IMTK_CURSOR_COLOR));
136 glVertex2f(x + strsz + 2, y + 2);
137 glVertex2f(x + strsz + 4, y + 2);
138 glVertex2f(x + strsz + 4, y + 18);
139 glVertex2f(x + strsz + 2, y + 18);
140 glEnd();
141 }
143 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
144 imtk_draw_string(x + 2, y + 15, text);
146 imtk_draw_frame(x, y, TEXTBOX_SIZE, 20, FRAME_INSET);
147 }