commits
tags
#include "input_field.h"
#include <string.h>
void input_field_init(InputField *f) {
f->buf[0] = '\0';
f->len = 0;
f->cursor = 0;
}
void input_field_clear(InputField *f) {
input_field_init(f);
}
int input_field_handle_key(InputField *f, int ch) {
if (ch >= 32 && ch < 127) {
if (f->len + 1 < sizeof(f->buf)) {
memmove(f->buf + f->cursor + 1, f->buf + f->cursor, f->len - f->cursor + 1);
f->buf[f->cursor] = (char)ch;
f->cursor++;
f->len++;
}
return 1;
}
switch (ch) {
case KEY_BACKSPACE:
case 127:
case 8:
if (f->cursor > 0) {
memmove(f->buf + f->cursor - 1, f->buf + f->cursor, f->len - f->cursor + 1);
f->cursor--;
f->len--;
}
return 1;
case KEY_DC:
if (f->cursor < f->len) {
memmove(f->buf + f->cursor, f->buf + f->cursor + 1, f->len - f->cursor);
f->len--;
}
return 1;
case KEY_LEFT:
if (f->cursor > 0) f->cursor--;
return 1;
case KEY_RIGHT:
if (f->cursor < f->len) f->cursor++;
return 1;
case KEY_HOME:
case 1: /* Ctrl+A */
f->cursor = 0;
return 1;
case KEY_END:
case 5: /* Ctrl+E */
f->cursor = f->len;
return 1;
case 21: /* Ctrl+U: clear to start */
memmove(f->buf, f->buf + f->cursor, f->len - f->cursor + 1);
f->len -= f->cursor;
f->cursor = 0;
return 1;
case 11: /* Ctrl+K: clear to end */
f->buf[f->cursor] = '\0';
f->len = f->cursor;
return 1;
default:
return 0;
}
}
void input_field_draw(WINDOW *win, int y, int x, int width, const InputField *f, int focused,
const char *placeholder) {
if (width <= 0) return;
wmove(win, y, x);
for (int i = 0; i < width; i++) waddch(win, ' ');
if (f->len == 0 && !focused) {
wattron(win, A_DIM);
mvwaddnstr(win, y, x, placeholder, width);
wattroff(win, A_DIM);
return;
}
size_t start = 0;
if (f->cursor >= (size_t)width) start = f->cursor - width + 1;
size_t visible_len = f->len - start;
if (visible_len > (size_t)width) visible_len = width;
mvwaddnstr(win, y, x, f->buf + start, (int)visible_len);
if (focused) {
wmove(win, y, x + (int)(f->cursor - start));
}
}