ui: move cursor through the text in input

This commit is contained in:
2026-01-02 12:45:41 +02:00
parent 6a9dad9557
commit 34e58daa42
5 changed files with 56 additions and 22 deletions
+2 -2
View File
@@ -12,6 +12,6 @@ TODO:
- [ ] "Server message" to notification
INPUT:
- [ ] hidden text for passwords
- [ ] move cursor through the text in input
- [x] hidden text for passwords
- [x] move cursor through the text in input
+28 -10
View File
@@ -53,8 +53,8 @@ void dialogue_default_callback(callback_args_t *args) {
new_args.active_id = d->active.id;
int32_t diff;
d->needs_update = true;
input_t *input;
switch (key) {
case KEY_RIGHT:
case '\t':
if (d->active.type == g_content) {
INCR_ACTIVE_ID(d, g_content, g_action);
@@ -62,16 +62,40 @@ void dialogue_default_callback(callback_args_t *args) {
INCR_ACTIVE_ID(d, g_action, g_content);
}
*resp_value = -1;
break;
case KEY_RIGHT:
if (d->active.type == g_content) {
if (d->g_content->elements[d->active.id - d->g_content->first_id].type ==
w_input) {
input = d->g_content->elements[d->active.id - d->g_content->first_id]
.element;
if (input->cur_pos > 0) {
input->cur_pos -= 1;
}
} else {
INCR_ACTIVE_ID(d, g_content, g_action);
}
} else if (d->active.type == g_action) {
INCR_ACTIVE_ID(d, g_action, g_content);
}
*resp_value = -1;
break;
case KEY_LEFT:
if (d->active.type == g_content) {
if (d->g_content->elements[d->active.id - d->g_content->first_id].type ==
w_input) {
input = d->g_content->elements[d->active.id - d->g_content->first_id]
.element;
if (input->value_len > input->cur_pos) {
input->cur_pos += 1;
}
} else {
DECR_ACTIVE_ID(d, g_content, g_action);
}
} else if (d->active.type == g_action) {
DECR_ACTIVE_ID(d, g_action, g_content);
}
*resp_value = -1;
break;
case '\n':
if (d->active.type == g_action) {
@@ -89,15 +113,12 @@ void dialogue_default_callback(callback_args_t *args) {
*resp_value = d->active.id - d->g_content->first_id;
return;
}
break;
case KEY_UP:
CH_GROUP(d, g_action, g_content);
break;
case KEY_DOWN:
CH_GROUP(d, g_content, g_action);
break;
default:
/* run callback function */
@@ -239,11 +260,8 @@ int32_t draw_dialogue(dialogue_t *d) {
if (ae_ptr->type == w_input) {
input_t *input = ae_ptr->element;
d->w.cur.y = input->w.cur.y;
if (input->max_len == input->value_len) {
d->w.cur.x = input->w.cur.x + input->value_len - 1;
} else {
d->w.cur.x = input->w.cur.x + input->value_len;
}
d->w.cur.x -= input->cur_pos;
if (d->w.cur.y || d->w.cur.x) {
wmove(d->win, d->w.cur.y, d->w.cur.x);
curs_set(1);
+17 -3
View File
@@ -5,10 +5,9 @@
#include <ncurses.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
// TODO: refactor
#define MAKE_RESPONSE_M1(args, resp_data, response) \
if (args->resp_data != NULL) { \
*response = -1; \
@@ -21,6 +20,7 @@ void group_default_callback(callback_args_t *args) {
input_t *input;
group_el_t *element_ptr;
int32_t element_idx = -1;
u_int32_t start_pos = 0;
switch (key) {
case '\n': /* Enter */
FIND_ACTIVE_ELEMENT(g, args->active_id, element_ptr, element_idx);
@@ -32,9 +32,15 @@ void group_default_callback(callback_args_t *args) {
if (element_ptr->type == w_input) {
input = (input_t *)element_ptr->element;
if (input->value_len) {
if (input->cur_pos > 0) {
start_pos = input->value_len-- - input->cur_pos;
memmove(input->value + start_pos - 1, input->value + start_pos,
input->value_len - start_pos + 2);
} else {
input->value[--input->value_len] = '\0';
}
}
}
MAKE_RESPONSE_M1(args, resp_data, response);
break;
default:
@@ -42,10 +48,17 @@ void group_default_callback(callback_args_t *args) {
if (element_ptr->type == w_input) {
input = (input_t *)element_ptr->element;
if (input->max_len > input->value_len) {
if (input->cur_pos > 0) {
start_pos = input->value_len++ - input->cur_pos;
memmove(input->value + start_pos + 1, input->value + start_pos,
input->value_len - start_pos);
input->value[start_pos] = key;
} else {
input->value[input->value_len++] = key;
input->value[input->value_len] = '\0';
}
}
}
MAKE_RESPONSE_M1(args, resp_data, response);
break;
}
@@ -85,7 +98,8 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
break;
case w_input:
elements[i].element =
init_input(win, &(group->w), children[i].label, children[i].length, children[i].is_hidden_value);
init_input(win, &(group->w), children[i].label, children[i].length,
children[i].is_hidden_value);
w = &(((input_t *)elements[i].element)->w);
break;
case w_progress:
+2 -1
View File
@@ -13,7 +13,7 @@ input_t *init_input(WINDOW **win, widget_t *w_parent, char *label,
init_widget(&(input->w), w_parent, win, label);
input->is_disabled = 0;
input->w.y = 3; // with borders
input->w.x = length + 2; // with borders
input->w.x = length + 3; // with borders and extra space for the last element
uint32_t t_len = strlen(input->w.title) + 4; // with borders and space
if (input->w.x < t_len)
input->w.x = t_len;
@@ -22,6 +22,7 @@ input_t *init_input(WINDOW **win, widget_t *w_parent, char *label,
input->value_len = 0;
input->max_len = length;
input->is_hidden = is_hidden_value;
input->cur_pos = 0;
return input;
}
+1
View File
@@ -8,6 +8,7 @@
typedef struct {
widget_t w;
char value[INPUT_TEXT];
uint32_t cur_pos; /* is relative to the end of a string */
uint32_t value_len;
uint32_t max_len;
uint32_t is_disabled : 1;