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