imtk

view src/textbox.c @ 27:48e708baa7be

added predicate imtk_layout_contains(x, y)
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 12 Dec 2020 17:20:00 +0200
parents 1cf212375db3
children
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
9 #define TEXTBOX_HEIGHT 20
11 static void draw_textbox(int id, char *text, int cursor, int x, int y, int over);
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;
18 assert(id >= 0);
20 if(x == IMTK_AUTO || y == IMTK_AUTO) {
21 imtk_layout_get_pos(&x, &y);
22 }
24 len = strlen(textbuf);
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 }
31 if(imtk_hit_test(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT)) {
32 imtk_set_hot(id);
33 over = 1;
34 }
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 }
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;
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;
78 case 127: /* del */
79 if(cursor < len) {
80 memmove(textbuf + cursor, textbuf + cursor + 1, len - cursor);
81 textbuf[--len] = 0;
82 }
83 break;
85 case GLUT_KEY_LEFT:
86 if(cursor > 0) {
87 cursor--;
88 }
89 break;
91 case GLUT_KEY_RIGHT:
92 if(cursor < len) {
93 cursor++;
94 }
95 break;
97 case GLUT_KEY_HOME:
98 cursor = 0;
99 break;
101 case GLUT_KEY_END:
102 cursor = len;
103 break;
105 default:
106 break;
107 }
108 }
109 }
110 }
112 textbuf[buf_sz - 1] = cursor;
113 draw_textbox(id, textbuf, cursor, x, y, over);
114 imtk_layout_advance(TEXTBOX_SIZE, TEXTBOX_HEIGHT);
115 }
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;
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);
129 imtk_draw_rect(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, tcol, bcol);
131 if(imtk_has_focus(id)) {
132 int strsz;
133 char tmp;
135 tmp = text[cursor];
136 text[cursor] = 0;
137 strsz = imtk_string_size(text);
138 text[cursor] = tmp;
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 }
149 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
150 imtk_draw_string(x + 2, y + 15, text);
152 imtk_draw_frame(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, FRAME_INSET);
153 }