X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=demo_prior;a=blobdiff_plain;f=src%2Fimtk%2Ftextbox.c;fp=src%2Fimtk%2Ftextbox.c;h=8fda2f89bf158c790ffd1615f23c77460df977a2;hp=0000000000000000000000000000000000000000;hb=2f14a35e7d557da12f24056267b911f24774aa18;hpb=5eefe7b94c8d6c6caa2c10e3835ab0831a3c42a1 diff --git a/src/imtk/textbox.c b/src/imtk/textbox.c new file mode 100644 index 0000000..8fda2f8 --- /dev/null +++ b/src/imtk/textbox.c @@ -0,0 +1,154 @@ +#include +#include +#include +#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); +} +