105 lines
2.9 KiB
C
Executable File
105 lines
2.9 KiB
C
Executable File
#include "tim.h"
|
|
|
|
|
|
void TimEditState_init(TimEditState* e, i32 capacity, cstr initial_content){
|
|
e->length = tim_utf8_len(initial_content);
|
|
e->cursor = tim_utf8_len(initial_content);
|
|
e->capacity = capacity;
|
|
e->s = (char*)malloc(capacity + 1);
|
|
i32 byte_len = strlen(initial_content);
|
|
memcpy(e->s, initial_content, byte_len);
|
|
e->s[byte_len] = 0;
|
|
}
|
|
|
|
void TimEditState_insert(TimEditState* e, cstr s) {
|
|
i32 dst_size = tim_ztrlen(e->s);
|
|
i32 src_size = tim_ztrlen(s);
|
|
if (dst_size + src_size < e->capacity) {
|
|
i32 len = tim_utf8_len(s); // usually 1, except when smashing keys
|
|
i32 cur = tim_utf8_pos(e->s, e->cursor);
|
|
memmove(e->s + cur + src_size, e->s + cur, dst_size - cur);
|
|
memmove(e->s + cur, s, src_size);
|
|
e->s[dst_size + src_size] = 0;
|
|
e->length += len;
|
|
e->cursor += len;
|
|
}
|
|
}
|
|
|
|
void TimEditState_delete(TimEditState* e) {
|
|
i32 size = tim_ztrlen(e->s);
|
|
i32 cur = tim_utf8_pos(e->s, e->cursor);
|
|
i32 len = tim_utf8_pos(e->s + cur, 1);
|
|
if (size - cur > 0) {
|
|
memmove(e->s + cur, e->s + cur + len, size - cur);
|
|
e->length -= 1;
|
|
}
|
|
}
|
|
|
|
/// @return key id or 0
|
|
static TimKey edit_event(TimEditState* e, TimRect r) {
|
|
if (tim_is_mouse_click_over(r)) {
|
|
// take focus
|
|
tim->focus = e;
|
|
return 0;
|
|
}
|
|
|
|
if (tim->focus != e || tim->event.type != TimEvent_Key) {
|
|
// not focused or no key press
|
|
return 0;
|
|
}
|
|
tim->event.type = TimEvent_Void; // consume event
|
|
|
|
switch (tim->event.key) {
|
|
case TimKey_Escape:
|
|
case TimKey_Enter:
|
|
tim->focus = 0; // release focus
|
|
break;
|
|
case TimKey_Delete:
|
|
TimEditState_delete(e);
|
|
break;
|
|
case TimKey_Backspace:
|
|
if (e->cursor > 0) {
|
|
e->cursor -= 1;
|
|
TimEditState_delete(e);
|
|
}
|
|
break;
|
|
case TimKey_Left:
|
|
e->cursor -= (e->cursor > 0);
|
|
break;
|
|
case TimKey_Right:
|
|
e->cursor += (e->cursor < e->length);
|
|
break;
|
|
case TimKey_Home:
|
|
e->cursor = 0;
|
|
break;
|
|
case TimKey_End:
|
|
e->cursor = e->length;
|
|
break;
|
|
default:
|
|
if (tim->event.key >= ' ') {
|
|
TimEditState_insert(e, tim->event.s);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return tim->event.key;
|
|
}
|
|
|
|
TimKey tim_edit(TimEditState* e, i32 x, i32 y, i32 w, u64 color) {
|
|
TimRect r = tim_scope_rect_to_absolute(x, y, w, 3);
|
|
|
|
if (tim->event.type == TimEvent_Draw) {
|
|
tim_draw_box(r.x, r.y, r.w, r.h, color >> 16, color >> 8);
|
|
if (tim->focus == e) {
|
|
char* s = e->s + tim_utf8_pos(e->s, e->cursor - r.w + 4);
|
|
i32 cur = MIN(r.w - 4, e->cursor);
|
|
tim_draw_str(s, r.x + 2, r.y + 1, r.w - 3, color, color >> 8);
|
|
tim_draw_invert(r.x + cur + 2, r.y + 1, 1);
|
|
} else {
|
|
tim_draw_str(e->s, r.x + 2, r.y + 1, r.w - 3, color, color >> 8);
|
|
}
|
|
}
|
|
|
|
return edit_event(e, r);
|
|
}
|