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