- added libdrawtext
[demo_prior] / src / imtk / textbox.c
1 #include <string.h>
2 #include <ctype.h>
3 #include <assert.h>
4 #include "imtk.h"
5 #include "state.h"
6 #include "draw.h"
7
8 #define TEXTBOX_SIZE    100
9 #define TEXTBOX_HEIGHT  20
10
11 static void draw_textbox(int id, char *text, int cursor, int x, int y, int over);
12
13
14 void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y)
15 {
16         int key, len, cursor = 0, over = 0;
17
18         assert(id >= 0);
19
20         if(x == IMTK_AUTO || y == IMTK_AUTO) {
21                 imtk_layout_get_pos(&x, &y);
22         }
23
24         len = strlen(textbuf);
25
26         /* HACK! using last element of textbuf for saving cursor position */
27         if((cursor = textbuf[buf_sz - 1]) > len || cursor < 0) {
28                 cursor = len;
29         }
30
31         if(imtk_hit_test(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT)) {
32                 imtk_set_hot(id);
33                 over = 1;
34         }
35
36         if(imtk_button_state(IMTK_LEFT_BUTTON)) {
37                 if(over) {
38                         imtk_set_active(id);
39                 }
40         } else {
41                 if(imtk_is_active(id)) {
42                         imtk_set_active(-1);
43                         if(imtk_is_hot(id) && over) {
44                                 imtk_set_focus(id);
45                         }
46                 }
47         }
48
49         if(imtk_has_focus(id)) {
50                 while((key = imtk_get_key()) != -1) {
51                         if(!(key & 0xff00) && isprint(key)) {
52                                 if(len < buf_sz - 1) {
53                                         if(cursor == len) {
54                                                 textbuf[len++] = (char)key;
55                                                 cursor = len;
56                                         } else {
57                                                 memmove(textbuf + cursor + 1, textbuf + cursor, len - cursor);
58                                                 len++;
59                                                 textbuf[cursor++] = (char)key;
60                                         }
61                                 }
62                         } else {
63                                 key &= 0xff;
64
65                                 switch(key) {
66                                 case '\b':
67                                         if(cursor > 0) {
68                                                 if(cursor == len) {
69                                                         textbuf[--cursor] = 0;
70                                                 } else {
71                                                         memmove(textbuf + cursor - 1, textbuf + cursor, len - cursor);
72                                                         textbuf[--len] = 0;
73                                                         cursor--;
74                                                 }
75                                         }
76                                         break;
77
78                                 case 127:       /* del */
79                                         if(cursor < len) {
80                                                 memmove(textbuf + cursor, textbuf + cursor + 1, len - cursor);
81                                                 textbuf[--len] = 0;
82                                         }
83                                         break;
84
85                                 case GLUT_KEY_LEFT:
86                                         if(cursor > 0) {
87                                                 cursor--;
88                                         }
89                                         break;
90
91                                 case GLUT_KEY_RIGHT:
92                                         if(cursor < len) {
93                                                 cursor++;
94                                         }
95                                         break;
96
97                                 case GLUT_KEY_HOME:
98                                         cursor = 0;
99                                         break;
100
101                                 case GLUT_KEY_END:
102                                         cursor = len;
103                                         break;
104
105                                 default:
106                                         break;
107                                 }
108                         }
109                 }
110         }
111
112         textbuf[buf_sz - 1] = cursor;
113         draw_textbox(id, textbuf, cursor, x, y, over);
114         imtk_layout_advance(TEXTBOX_SIZE, TEXTBOX_HEIGHT);
115 }
116
117
118 static void draw_textbox(int id, char *text, int cursor, int x, int y, int over)
119 {
120         float tcol[4], bcol[4];
121         unsigned int attr = 0;
122
123         if(over) {
124                 attr |= IMTK_FOCUS_BIT;
125         }
126         memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
127         memcpy(bcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof bcol);
128
129         imtk_draw_rect(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, tcol, bcol);
130
131         if(imtk_has_focus(id)) {
132                 int strsz;
133                 char tmp;
134
135                 tmp = text[cursor];
136                 text[cursor] = 0;
137                 strsz = imtk_string_size(text);
138                 text[cursor] = tmp;
139
140                 glBegin(GL_QUADS);
141                 glColor4fv(imtk_get_color(IMTK_CURSOR_COLOR));
142                 glVertex2f(x + strsz + 2, y + 2);
143                 glVertex2f(x + strsz + 4, y + 2);
144                 glVertex2f(x + strsz + 4, y + 18);
145                 glVertex2f(x + strsz + 2, y + 18);
146                 glEnd();
147         }
148
149         glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
150         imtk_draw_string(x + 2, y + 15, text);
151
152         imtk_draw_frame(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, FRAME_INSET);
153 }
154