rayfract

diff src/imtk/textbox.c @ 10:1496aae2e7d4

- simplified build by including dependences in the source tree - added make dep tracking - added mingw cross-build rules - added readme & licence
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 31 Jul 2023 18:58:56 +0300
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/imtk/textbox.c	Mon Jul 31 18:58:56 2023 +0300
     1.3 @@ -0,0 +1,154 @@
     1.4 +#include <string.h>
     1.5 +#include <ctype.h>
     1.6 +#include <assert.h>
     1.7 +#include "imtk.h"
     1.8 +#include "state.h"
     1.9 +#include "draw.h"
    1.10 +
    1.11 +#define TEXTBOX_SIZE	100
    1.12 +#define TEXTBOX_HEIGHT	20
    1.13 +
    1.14 +static void draw_textbox(int id, char *text, int cursor, int x, int y, int over);
    1.15 +
    1.16 +
    1.17 +void imtk_textbox(int id, char *textbuf, size_t buf_sz, int x, int y)
    1.18 +{
    1.19 +	int key, len, cursor = 0, over = 0;
    1.20 +
    1.21 +	assert(id >= 0);
    1.22 +
    1.23 +	if(x == IMTK_AUTO || y == IMTK_AUTO) {
    1.24 +		imtk_layout_get_pos(&x, &y);
    1.25 +	}
    1.26 +
    1.27 +	len = strlen(textbuf);
    1.28 +
    1.29 +	/* HACK! using last element of textbuf for saving cursor position */
    1.30 +	if((cursor = textbuf[buf_sz - 1]) > len || cursor < 0) {
    1.31 +		cursor = len;
    1.32 +	}
    1.33 +
    1.34 +	if(imtk_hit_test(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT)) {
    1.35 +		imtk_set_hot(id);
    1.36 +		over = 1;
    1.37 +	}
    1.38 +
    1.39 +	if(imtk_button_state(IMTK_LEFT_BUTTON)) {
    1.40 +		if(over) {
    1.41 +			imtk_set_active(id);
    1.42 +		}
    1.43 +	} else {
    1.44 +		if(imtk_is_active(id)) {
    1.45 +			imtk_set_active(-1);
    1.46 +			if(imtk_is_hot(id) && over) {
    1.47 +				imtk_set_focus(id);
    1.48 +			}
    1.49 +		}
    1.50 +	}
    1.51 +
    1.52 +	if(imtk_has_focus(id)) {
    1.53 +		while((key = imtk_get_key()) != -1) {
    1.54 +			if(!(key & 0xff00) && isprint(key)) {
    1.55 +				if(len < buf_sz - 1) {
    1.56 +					if(cursor == len) {
    1.57 +						textbuf[len++] = (char)key;
    1.58 +						cursor = len;
    1.59 +					} else {
    1.60 +						memmove(textbuf + cursor + 1, textbuf + cursor, len - cursor);
    1.61 +						len++;
    1.62 +						textbuf[cursor++] = (char)key;
    1.63 +					}
    1.64 +				}
    1.65 +			} else {
    1.66 +				key &= 0xff;
    1.67 +
    1.68 +				switch(key) {
    1.69 +				case '\b':
    1.70 +					if(cursor > 0) {
    1.71 +						if(cursor == len) {
    1.72 +							textbuf[--cursor] = 0;
    1.73 +						} else {
    1.74 +							memmove(textbuf + cursor - 1, textbuf + cursor, len - cursor);
    1.75 +							textbuf[--len] = 0;
    1.76 +							cursor--;
    1.77 +						}
    1.78 +					}
    1.79 +					break;
    1.80 +
    1.81 +				case 127:	/* del */
    1.82 +					if(cursor < len) {
    1.83 +						memmove(textbuf + cursor, textbuf + cursor + 1, len - cursor);
    1.84 +						textbuf[--len] = 0;
    1.85 +					}
    1.86 +					break;
    1.87 +
    1.88 +				case GLUT_KEY_LEFT:
    1.89 +					if(cursor > 0) {
    1.90 +						cursor--;
    1.91 +					}
    1.92 +					break;
    1.93 +
    1.94 +				case GLUT_KEY_RIGHT:
    1.95 +					if(cursor < len) {
    1.96 +						cursor++;
    1.97 +					}
    1.98 +					break;
    1.99 +
   1.100 +				case GLUT_KEY_HOME:
   1.101 +					cursor = 0;
   1.102 +					break;
   1.103 +
   1.104 +				case GLUT_KEY_END:
   1.105 +					cursor = len;
   1.106 +					break;
   1.107 +
   1.108 +				default:
   1.109 +					break;
   1.110 +				}
   1.111 +			}
   1.112 +		}
   1.113 +	}
   1.114 +
   1.115 +	textbuf[buf_sz - 1] = cursor;
   1.116 +	draw_textbox(id, textbuf, cursor, x, y, over);
   1.117 +	imtk_layout_advance(TEXTBOX_SIZE, TEXTBOX_HEIGHT);
   1.118 +}
   1.119 +
   1.120 +
   1.121 +static void draw_textbox(int id, char *text, int cursor, int x, int y, int over)
   1.122 +{
   1.123 +	float tcol[4], bcol[4];
   1.124 +	unsigned int attr = 0;
   1.125 +
   1.126 +	if(over) {
   1.127 +		attr |= IMTK_FOCUS_BIT;
   1.128 +	}
   1.129 +	memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
   1.130 +	memcpy(bcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof bcol);
   1.131 +
   1.132 +	imtk_draw_rect(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, tcol, bcol);
   1.133 +
   1.134 +	if(imtk_has_focus(id)) {
   1.135 +		int strsz;
   1.136 +		char tmp;
   1.137 +
   1.138 +		tmp = text[cursor];
   1.139 +		text[cursor] = 0;
   1.140 +		strsz = imtk_string_size(text);
   1.141 +		text[cursor] = tmp;
   1.142 +
   1.143 +		glBegin(GL_QUADS);
   1.144 +		glColor4fv(imtk_get_color(IMTK_CURSOR_COLOR));
   1.145 +		glVertex2f(x + strsz + 2, y + 2);
   1.146 +		glVertex2f(x + strsz + 4, y + 2);
   1.147 +		glVertex2f(x + strsz + 4, y + 18);
   1.148 +		glVertex2f(x + strsz + 2, y + 18);
   1.149 +		glEnd();
   1.150 +	}
   1.151 +
   1.152 +	glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
   1.153 +	imtk_draw_string(x + 2, y + 15, text);
   1.154 +
   1.155 +	imtk_draw_frame(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, FRAME_INSET);
   1.156 +}
   1.157 +