- added libdrawtext
[demo_prior] / src / imtk / textbox.c
diff --git a/src/imtk/textbox.c b/src/imtk/textbox.c
new file mode 100644 (file)
index 0000000..8fda2f8
--- /dev/null
@@ -0,0 +1,154 @@
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include "imtk.h"
+#include "state.h"
+#include "draw.h"
+
+#define TEXTBOX_SIZE   100
+#define TEXTBOX_HEIGHT 20
+
+static void draw_textbox(int id, char *text, int cursor, int x, int y, int over);
+
+
+void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y)
+{
+       int key, len, cursor = 0, over = 0;
+
+       assert(id >= 0);
+
+       if(x == IMTK_AUTO || y == IMTK_AUTO) {
+               imtk_layout_get_pos(&x, &y);
+       }
+
+       len = strlen(textbuf);
+
+       /* HACK! using last element of textbuf for saving cursor position */
+       if((cursor = textbuf[buf_sz - 1]) > len || cursor < 0) {
+               cursor = len;
+       }
+
+       if(imtk_hit_test(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT)) {
+               imtk_set_hot(id);
+               over = 1;
+       }
+
+       if(imtk_button_state(IMTK_LEFT_BUTTON)) {
+               if(over) {
+                       imtk_set_active(id);
+               }
+       } else {
+               if(imtk_is_active(id)) {
+                       imtk_set_active(-1);
+                       if(imtk_is_hot(id) && over) {
+                               imtk_set_focus(id);
+                       }
+               }
+       }
+
+       if(imtk_has_focus(id)) {
+               while((key = imtk_get_key()) != -1) {
+                       if(!(key & 0xff00) && isprint(key)) {
+                               if(len < buf_sz - 1) {
+                                       if(cursor == len) {
+                                               textbuf[len++] = (char)key;
+                                               cursor = len;
+                                       } else {
+                                               memmove(textbuf + cursor + 1, textbuf + cursor, len - cursor);
+                                               len++;
+                                               textbuf[cursor++] = (char)key;
+                                       }
+                               }
+                       } else {
+                               key &= 0xff;
+
+                               switch(key) {
+                               case '\b':
+                                       if(cursor > 0) {
+                                               if(cursor == len) {
+                                                       textbuf[--cursor] = 0;
+                                               } else {
+                                                       memmove(textbuf + cursor - 1, textbuf + cursor, len - cursor);
+                                                       textbuf[--len] = 0;
+                                                       cursor--;
+                                               }
+                                       }
+                                       break;
+
+                               case 127:       /* del */
+                                       if(cursor < len) {
+                                               memmove(textbuf + cursor, textbuf + cursor + 1, len - cursor);
+                                               textbuf[--len] = 0;
+                                       }
+                                       break;
+
+                               case GLUT_KEY_LEFT:
+                                       if(cursor > 0) {
+                                               cursor--;
+                                       }
+                                       break;
+
+                               case GLUT_KEY_RIGHT:
+                                       if(cursor < len) {
+                                               cursor++;
+                                       }
+                                       break;
+
+                               case GLUT_KEY_HOME:
+                                       cursor = 0;
+                                       break;
+
+                               case GLUT_KEY_END:
+                                       cursor = len;
+                                       break;
+
+                               default:
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       textbuf[buf_sz - 1] = cursor;
+       draw_textbox(id, textbuf, cursor, x, y, over);
+       imtk_layout_advance(TEXTBOX_SIZE, TEXTBOX_HEIGHT);
+}
+
+
+static void draw_textbox(int id, char *text, int cursor, int x, int y, int over)
+{
+       float tcol[4], bcol[4];
+       unsigned int attr = 0;
+
+       if(over) {
+               attr |= IMTK_FOCUS_BIT;
+       }
+       memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
+       memcpy(bcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof bcol);
+
+       imtk_draw_rect(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, tcol, bcol);
+
+       if(imtk_has_focus(id)) {
+               int strsz;
+               char tmp;
+
+               tmp = text[cursor];
+               text[cursor] = 0;
+               strsz = imtk_string_size(text);
+               text[cursor] = tmp;
+
+               glBegin(GL_QUADS);
+               glColor4fv(imtk_get_color(IMTK_CURSOR_COLOR));
+               glVertex2f(x + strsz + 2, y + 2);
+               glVertex2f(x + strsz + 4, y + 2);
+               glVertex2f(x + strsz + 4, y + 18);
+               glVertex2f(x + strsz + 2, y + 18);
+               glEnd();
+       }
+
+       glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
+       imtk_draw_string(x + 2, y + 15, text);
+
+       imtk_draw_frame(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, FRAME_INSET);
+}
+