+ UI: checkboxes
F Login: Fixes scenario when credentials are incorrect R UI: group -> refactors key processing
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
# TODO:
|
||||
|
||||
## Current:
|
||||
- [ ] Login and registration error
|
||||
- [ ] PageUp/PageDown key functionality in lists
|
||||
- [ ] File upload multiline description
|
||||
- [ ] File upload multiline description (window)
|
||||
- [ ] Permission checkboxes for file upload/edit
|
||||
- [ ] More intuitive navigation between nested groups (by pressing left and right buttons)
|
||||
|
||||
|
||||
+1
-13
@@ -36,19 +36,7 @@ void app_draw_modal(app_t *app) {
|
||||
case S_UPLOAD_PARAMS:
|
||||
init_upload_props_dialogue_modal(app);
|
||||
break;
|
||||
case WAIT_SERVER_INIT:
|
||||
case WAIT_SERVER:
|
||||
case WAIT_REGISTER:
|
||||
case WAIT_REGISTER_CONFIRMATION:
|
||||
case WAIT_CLIENT:
|
||||
case S_FILE_LIST:
|
||||
case S_FILE_SELECT:
|
||||
case S_UPLOAD_REQUESTED:
|
||||
case S_ASK_USER_BEFORE_LOGIN:
|
||||
case S_ERR:
|
||||
case S_WAIT_SERVER:
|
||||
case S_N_D:
|
||||
case S_NEXT_ACTION:
|
||||
default:
|
||||
if (app->query_args->notification != NULL) {
|
||||
init_notification_modal(app);
|
||||
} else {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "group.h"
|
||||
#include <widget.h>
|
||||
#include "widget_core.h"
|
||||
#include <ncursesw/ncurses.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <widget.h>
|
||||
|
||||
void upload_props_dialogue_modal_cb(callback_args_t *args) {
|
||||
callback_args_t d_args;
|
||||
@@ -18,9 +19,10 @@ void upload_props_dialogue_modal_cb(callback_args_t *args) {
|
||||
char query[256];
|
||||
int32_t query_len = 0;
|
||||
input_t *desc_input = (input_t *)d->g_content->elements[0].element;
|
||||
/* TODO: permissions */
|
||||
if (d_args.resp_data.code == cbrp_val) {
|
||||
switch (d_args.resp_data.val.val.num) {
|
||||
case 0:
|
||||
case 1:
|
||||
query_len =
|
||||
sprintf(query, "file upload \"%s\" %zu 1\n",
|
||||
app->query_args->file->name, app->query_args->file->size);
|
||||
@@ -31,7 +33,7 @@ void upload_props_dialogue_modal_cb(callback_args_t *args) {
|
||||
app->query_args->state = S_UPLOAD_REQUESTED;
|
||||
write(app->query_args->sd, query, query_len);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if (app->query_args->file->name != NULL)
|
||||
free(app->query_args->file->name);
|
||||
if (app->query_args->file->path != NULL)
|
||||
@@ -48,12 +50,15 @@ dialogue_t *init_upload_props_dialogue_modal(app_t *app) {
|
||||
if (app == NULL)
|
||||
return NULL;
|
||||
group_el_init_t content[] = {
|
||||
{.type = w_input, .label = "File description", .length = 30},
|
||||
{.type = w_checkbox, .label = "Visible for all", .is_default = true},
|
||||
{.type = w_checkbox,
|
||||
.label = "Visible for registered",
|
||||
.is_default = false},
|
||||
{.type = w_end}};
|
||||
|
||||
group_el_init_t actions[] = {
|
||||
{.type = w_button, .label = "Upload", .is_default = true},
|
||||
{.type = w_button, .label = "Cancel", .is_default = false},
|
||||
{.type = w_button, .label = "Upload", .is_default = false, .val.num = 1},
|
||||
{.type = w_button, .label = "Cancel", .is_default = false, .val.num = 2},
|
||||
{.type = w_end},
|
||||
};
|
||||
|
||||
@@ -63,8 +68,10 @@ dialogue_t *init_upload_props_dialogue_modal(app_t *app) {
|
||||
dialogue_t *d = &(app->modal);
|
||||
|
||||
d->w.callback = upload_props_dialogue_modal_cb;
|
||||
d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal, g_content);
|
||||
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action);
|
||||
d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map),
|
||||
horizontal, g_content);
|
||||
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map),
|
||||
horizontal, g_action);
|
||||
|
||||
app->query_args->active_dialogue = d;
|
||||
|
||||
|
||||
+3
-10
@@ -45,10 +45,8 @@ void query_loop(app_t *app) {
|
||||
size_t qlen;
|
||||
int sr;
|
||||
static file_args_t file_args;
|
||||
callback_args_t d_args = {.app = app,
|
||||
.element = NULL,
|
||||
.data = NULL,
|
||||
.resp_data.code = cbrc_none};
|
||||
callback_args_t d_args = {
|
||||
.app = app, .element = NULL, .data = NULL, .resp_data.code = cbrc_none};
|
||||
|
||||
init_file_args(&file_args);
|
||||
query_args->sd = sd;
|
||||
@@ -183,12 +181,7 @@ int process_query(app_t *app) {
|
||||
case WAIT_REGISTER:
|
||||
wait_register(query_args);
|
||||
break;
|
||||
case S_ASK_SEVER_IP:
|
||||
case S_ASK_LOGIN_TYPE:
|
||||
case S_N_D:
|
||||
case S_ASK_LOGIN_USER:
|
||||
case S_PRINT_SERVER_MESSAGE:
|
||||
case S_UPLOAD_FILE_SELECT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
+3
-3
@@ -62,13 +62,13 @@ int process_server_command(char *line, int l_len, app_t *app) {
|
||||
}
|
||||
|
||||
/* LOGIN AGAIN */
|
||||
if (!strncmp(line, "login_again>", ws_pos)) {
|
||||
if (!strncmp(line, "login_again>\n", ws_pos)) {
|
||||
alert("Incorrect credentials! Try again");
|
||||
free(params->uname);
|
||||
free(params->pass);
|
||||
params->uname = NULL;
|
||||
params->pass = NULL;
|
||||
// get_missing_params(params);
|
||||
write(q_args->sd, params->uname, strlen(params->uname));
|
||||
q_args->state = S_ASK_LOGIN_USER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
typedef struct {
|
||||
widget_t w;
|
||||
char hotkey;
|
||||
int32_t hotkey;
|
||||
uint32_t is_disabled : 1;
|
||||
} button_t;
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <ncursesw/ncurses.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "app.h"
|
||||
#include "checkbox.h"
|
||||
#include <widget_core.h>
|
||||
|
||||
bool checkbox_default_key_action(callback_args_t *args) {
|
||||
int32_t key = *((int32_t *)args->data);
|
||||
group_el_t *g_el = args->active_el;
|
||||
checkbox_t *cbx = g_el->element;
|
||||
switch (key) {
|
||||
case '\40':
|
||||
cbx->value = !cbx->value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
checkbox_t *init_checkbox(WINDOW **win, widget_t *w_parent, char *label) {
|
||||
checkbox_t *cbx = malloc(sizeof(checkbox_t));
|
||||
init_widget(&(cbx->w), w_parent, win, label);
|
||||
cbx->is_disabled = false;
|
||||
cbx->value = false;
|
||||
cbx->w.sz.x = strlen(cbx->w.title) + 4; // + "[ ] "
|
||||
cbx->w.sz.y = 1;
|
||||
cbx->w.cur.y = 0;
|
||||
cbx->w.cur.x = 1;
|
||||
return cbx;
|
||||
}
|
||||
|
||||
int32_t draw_checkbox(checkbox_t *cbx, uint32_t active_id) {
|
||||
char title[DIALOGUE_TITLE + 6];
|
||||
WINDOW *win = *(cbx->w.parent_win);
|
||||
uint32_t margin_y = cbx->w.ps.y + cbx->w.m.y;
|
||||
uint32_t margin_x = cbx->w.ps.x + cbx->w.m.x;
|
||||
|
||||
widget_t *w_par = cbx->w.w_parent;
|
||||
|
||||
while (w_par->parent_win == cbx->w.parent_win) {
|
||||
margin_y += w_par->ps.y;
|
||||
margin_x += w_par->ps.x;
|
||||
w_par = w_par->w_parent;
|
||||
}
|
||||
|
||||
char val = cbx->value ? 'x' : ' ';
|
||||
|
||||
if (cbx->w.id == active_id) {
|
||||
sprintf(title, "[%c] %s", val, cbx->w.title);
|
||||
wattrset(win, COLOR_PAIR(modal_color_pair) | A_BOLD | A_REVERSE);
|
||||
} else {
|
||||
sprintf(title, "[%c] %s", val, cbx->w.title);
|
||||
wattrset(win, COLOR_PAIR(0) | A_REVERSE);
|
||||
}
|
||||
|
||||
mvwprintw(win, margin_y, margin_x, "%s", title);
|
||||
cbx->w.cur.y = margin_y;
|
||||
cbx->w.cur.x = margin_x + 1;
|
||||
|
||||
wattroff(win, A_BOLD | A_REVERSE);
|
||||
return strlen(title);
|
||||
}
|
||||
|
||||
void destroy_checkbox(checkbox_t *btn) { free(btn); }
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef CHECKBOX_H
|
||||
#define CHECKBOX_H
|
||||
|
||||
#include <widget_core.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
widget_t w;
|
||||
bool is_disabled;
|
||||
bool value;
|
||||
} checkbox_t;
|
||||
|
||||
bool checkbox_default_key_action(callback_args_t *args);
|
||||
checkbox_t *init_checkbox(WINDOW **win, widget_t *w_parent, char *label);
|
||||
int32_t draw_checkbox(checkbox_t *cbx, uint32_t active_id);
|
||||
void destroy_checkbox(checkbox_t *cbx);
|
||||
#endif
|
||||
+13
-11
@@ -4,6 +4,8 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "app.h"
|
||||
#include "button.h"
|
||||
#include "checkbox.h"
|
||||
#include "dialogue.h"
|
||||
#include "file_list.h"
|
||||
#include "group.h"
|
||||
@@ -193,14 +195,14 @@ void dialogue_init_active_id(dialogue_t *dialogue) {
|
||||
|
||||
#define DETECT_GROUP_SIZE(group, line_max_len, y, x) \
|
||||
if (group) { \
|
||||
group->w.ps.y = y; \
|
||||
if (line_max_len < group->w.sz.x) { \
|
||||
line_max_len = group->w.sz.x; \
|
||||
group->w.ps.x = 0; \
|
||||
group->w.ps.y = y; \
|
||||
if (line_max_len < group->w.sz.x) { \
|
||||
line_max_len = group->w.sz.x; \
|
||||
group->w.ps.x = 0; \
|
||||
} else { \
|
||||
group->w.ps.x = (line_max_len - group->w.sz.x) / 2; \
|
||||
group->w.ps.x = (line_max_len - group->w.sz.x) / 2; \
|
||||
} \
|
||||
y += group->w.sz.y; \
|
||||
y += group->w.sz.y; \
|
||||
}
|
||||
|
||||
int32_t draw_dialogue(dialogue_t *d) {
|
||||
@@ -275,11 +277,11 @@ int32_t draw_dialogue(dialogue_t *d) {
|
||||
}
|
||||
|
||||
/* move cursor */
|
||||
if (d->active_el != NULL && d->active_el->type == w_input) {
|
||||
input_t *input = d->active_el->element;
|
||||
d->w.cur.y = input->w.cur.y;
|
||||
d->w.cur.x = input->w.cur.x + input->value_len;
|
||||
d->w.cur.x -= input->cur_pos;
|
||||
if (d->active_el != NULL &&
|
||||
(d->active_el->type == w_input || d->active_el->type == w_checkbox)) {
|
||||
widget_t *w = d->active_el->element;
|
||||
d->w.cur.y = w->cur.y;
|
||||
d->w.cur.x = w->cur.x;
|
||||
if (d->w.cur.y || d->w.cur.x) {
|
||||
wmove(d->win, d->w.cur.y, d->w.cur.x);
|
||||
curs_set(true);
|
||||
|
||||
+25
-34
@@ -1,5 +1,6 @@
|
||||
#include "group.h"
|
||||
#include "button.h"
|
||||
#include "checkbox.h"
|
||||
#include "d_array.h"
|
||||
#include "fs_file_list.h"
|
||||
#include "input.h"
|
||||
@@ -12,51 +13,31 @@
|
||||
#include <sys/types.h>
|
||||
#include <utils.h>
|
||||
|
||||
bool group_default_key_action(callback_args_t *args) {
|
||||
group_el_t *element = args->active_el;
|
||||
switch (element->type) {
|
||||
case w_input:
|
||||
return input_default_key_action(args);
|
||||
case w_checkbox:
|
||||
return checkbox_default_key_action(args);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void group_default_callback(callback_args_t *args) {
|
||||
group_t *g = (group_t *)args->element;
|
||||
int32_t key = *((int32_t *)args->data);
|
||||
int64_t response = args->resp_data.val.val.num;
|
||||
input_t *input;
|
||||
widget_t *widget;
|
||||
group_el_t *element_ptr = args->active_el;
|
||||
u_int32_t start_pos = 0;
|
||||
callback_args_t new_args;
|
||||
switch (key) {
|
||||
case '\n': /* Enter */
|
||||
args->resp_data.code = cbrp_val;
|
||||
mempcpy(&(args->resp_data.val), &(element_ptr->val), sizeof(struct val_t));
|
||||
break;
|
||||
case KEY_BACKSPACE:
|
||||
case KEY_DL:
|
||||
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';
|
||||
}
|
||||
}
|
||||
}
|
||||
args->resp_data.code = cbrc_none;
|
||||
|
||||
break;
|
||||
default:
|
||||
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';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!group_default_key_action(args)) {
|
||||
/* callback case */
|
||||
widget = (widget_t *)element_ptr->element;
|
||||
if (widget->callback != NULL) {
|
||||
@@ -145,6 +126,10 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
|
||||
elements[i].element = init_fs_file_list(win, &(group->w));
|
||||
w = &(((ui_progress_bar_t *)elements[i].element)->w);
|
||||
break;
|
||||
case w_checkbox:
|
||||
elements[i].element = init_checkbox(win, &(group->w), children[i].label);
|
||||
w = &(((checkbox_t *)elements[i].element)->w);
|
||||
break;
|
||||
}
|
||||
if (current.type != w_group) {
|
||||
if (i == 0) {
|
||||
@@ -202,6 +187,9 @@ void draw_group(WINDOW *win, group_t *group, int32_t active_id) {
|
||||
case w_fs_file_list:
|
||||
draw_fs_file_list((ui_fs_file_list_t *)el->element);
|
||||
break;
|
||||
case w_checkbox:
|
||||
draw_checkbox((checkbox_t *)el->element, active_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,6 +217,9 @@ void destroy_group(group_t *group) {
|
||||
case w_fs_file_list:
|
||||
destroy_fs_file_list(el->element);
|
||||
break;
|
||||
case w_checkbox:
|
||||
destroy_checkbox(el->element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (group->elements != NULL) {
|
||||
|
||||
+41
-5
@@ -7,13 +7,49 @@
|
||||
#include "input.h"
|
||||
#include <widget_core.h>
|
||||
|
||||
bool input_default_key_action(callback_args_t *args) {
|
||||
int32_t key = *((int32_t *)args->data);
|
||||
group_el_t *g_el = args->active_el;
|
||||
input_t *input = g_el->element;
|
||||
int64_t start_pos = 0;
|
||||
|
||||
switch (key) {
|
||||
case KEY_BACKSPACE:
|
||||
case KEY_DL:
|
||||
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';
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
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';
|
||||
}
|
||||
break;
|
||||
}
|
||||
args->resp_data.code = cbrc_none;
|
||||
return true;
|
||||
}
|
||||
|
||||
input_t *init_input(WINDOW **win, widget_t *w_parent, char *label,
|
||||
uint32_t length, uint32_t is_hidden_value) {
|
||||
input_t *input = malloc(sizeof(input_t));
|
||||
init_widget(&(input->w), w_parent, win, label);
|
||||
input->is_disabled = 0;
|
||||
input->w.sz.y = 3; // with borders
|
||||
input->w.sz.x = length + 3; // with borders and extra space for the last element
|
||||
input->w.sz.y = 3; // with borders
|
||||
input->w.sz.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.sz.x < t_len)
|
||||
input->w.sz.x = t_len;
|
||||
@@ -70,15 +106,15 @@ int32_t draw_input(input_t *input, uint32_t active_id) {
|
||||
}
|
||||
|
||||
if (input->is_hidden) {
|
||||
mvwprintw(win, pos_y + 1, pos_x, "%.*s%*s", (int)input->value_len,
|
||||
stars, (int)(input->w.sz.x - input->value_len - 2), "");
|
||||
mvwprintw(win, pos_y + 1, pos_x, "%.*s%*s", (int)input->value_len, stars,
|
||||
(int)(input->w.sz.x - input->value_len - 2), "");
|
||||
} else {
|
||||
mvwprintw(win, pos_y + 1, pos_x, "%s%*s", input->value,
|
||||
(int)(input->w.sz.x - input->value_len - 2), "");
|
||||
}
|
||||
|
||||
input->w.cur.y = pos_y + 1;
|
||||
input->w.cur.x = pos_x;
|
||||
input->w.cur.x = pos_x + input->value_len - input->cur_pos;
|
||||
|
||||
wattroff(win, A_BOLD | A_REVERSE);
|
||||
return 0;
|
||||
|
||||
@@ -15,6 +15,7 @@ typedef struct {
|
||||
bool is_hidden;
|
||||
} input_t;
|
||||
|
||||
bool input_default_key_action(callback_args_t *args);
|
||||
input_t *init_input(WINDOW **win, widget_t *w_parent, char *label,
|
||||
uint32_t size, uint32_t is_hidden_value);
|
||||
int32_t draw_input(input_t *input, uint32_t active_id);
|
||||
|
||||
@@ -8,4 +8,5 @@
|
||||
#include "group.h"
|
||||
#include "input.h"
|
||||
#include "progress_bar.h"
|
||||
#include "checkbox.h"
|
||||
#endif
|
||||
@@ -18,6 +18,7 @@ enum w_type {
|
||||
w_box,
|
||||
w_group,
|
||||
w_input,
|
||||
w_checkbox,
|
||||
w_progress,
|
||||
w_fs_file_list,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user