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