From 6eeeb0b797550fd110e512c740c74d8809b786cf Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Thu, 12 Mar 2026 17:05:45 +0200 Subject: [PATCH] I UI: Vertical positioning in groups --- TODO.md | 2 +- src/modals/upload_props_dialogue.c | 41 +++++++++++++++++++----------- src/widget/dialogue.c | 17 +++++++++++-- src/widget/group.c | 1 + 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/TODO.md b/TODO.md index 6550923..6acf75c 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,10 @@ # TODO: ## Current: -- [ ] Login and registration error - [ ] PageUp/PageDown key functionality in lists - [ ] File upload multiline description (window) - [ ] Permission checkboxes for file upload/edit +- [ ] Check file upload - [ ] More intuitive navigation between nested groups (by pressing left and right buttons) ## Features: diff --git a/src/modals/upload_props_dialogue.c b/src/modals/upload_props_dialogue.c index 7b3f8bb..7888d69 100644 --- a/src/modals/upload_props_dialogue.c +++ b/src/modals/upload_props_dialogue.c @@ -1,3 +1,4 @@ +#include "checkbox.h" #include "group.h" #include "widget_core.h" #include @@ -18,17 +19,23 @@ void upload_props_dialogue_modal_cb(callback_args_t *args) { dialogue_default_callback(&d_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) { + checkbox_t *reg_cbx = (checkbox_t *)d->g_content->elements[0].element; + checkbox_t *anon_cbx = (checkbox_t *)d->g_content->elements[1].element; + checkbox_t *comp_cbx = (checkbox_t *)d->g_content->elements[2].element; + int32_t privileges = 0; + if (anon_cbx->value == true) privileges |= 1; + if (reg_cbx->value == true) privileges |= 2; + if (comp_cbx->value == true) privileges |= 4; switch (d_args.resp_data.val.val.num) { case 1: query_len = - sprintf(query, "file upload \"%s\" %zu 1\n", - app->query_args->file->name, app->query_args->file->size); - app->query_args->file->description = - malloc(desc_input->value_len + 9); /* reserve space for \n:END:\n */ - strcpy(app->query_args->file->description, desc_input->value); + sprintf(query, "file upload \"%s\" %zu %d\n", + app->query_args->file->name, app->query_args->file->size, privileges); + /* app->query_args->file->description = + malloc(desc_input->value_len + 9); reserve space for \n:END:\n */ + app->query_args->file->description = malloc(sizeof ("[Empty description]")); + strcpy(app->query_args->file->description, "[Empty description]"); d->needs_destroy = true; app->query_args->state = S_UPLOAD_REQUESTED; write(app->query_args->sd, query, query_len); @@ -49,12 +56,16 @@ void upload_props_dialogue_modal_cb(callback_args_t *args) { dialogue_t *init_upload_props_dialogue_modal(app_t *app) { if (app == NULL) return NULL; - group_el_init_t content[] = { - {.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 content[] = {{.type = w_checkbox, + .label = "Visible for registered", + .is_default = true}, + {.type = w_checkbox, + .label = "Visible for anonymous", + .is_default = false}, + {.type = w_checkbox, + .label = "Visible for my company", + .is_default = false}, + {.type = w_end}}; group_el_init_t actions[] = { {.type = w_button, .label = "Upload", .is_default = false, .val.num = 1}, @@ -68,8 +79,8 @@ 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_content = init_group(&(d->win), &(d->w), content, &(d->id_map), vertical, + g_content); d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action); diff --git a/src/widget/dialogue.c b/src/widget/dialogue.c index 7e5e0ee..cb09025 100644 --- a/src/widget/dialogue.c +++ b/src/widget/dialogue.c @@ -115,10 +115,23 @@ void dialogue_default_callback(callback_args_t *args) { } break; case KEY_UP: + if (d->active_el->type == w_fs_file_list) { + new_args.element = d->g_content; + group_default_callback(&new_args); + } else if (d->active_el->g_type == g_content && + d->g_content->direction == vertical) { + decr_active_id(d); + args->resp_data.code = cbrc_none; + } + break; case KEY_DOWN: if (d->active_el->type == w_fs_file_list) { new_args.element = d->g_content; group_default_callback(&new_args); + } else if (d->active_el->g_type == g_content && + d->g_content->direction == vertical) { + incr_active_id(d); + args->resp_data.code = cbrc_none; } break; default: @@ -159,8 +172,8 @@ int group_init_active_id(group_t *g, dialogue_t *d) { for (int i = 0; i < g->count; i++) { wt = g->elements[i].type; - if (wt == w_button || wt == w_input || - wt == w_fs_file_list) { /* Add here new types */ + if (wt == w_button || wt == w_input || wt == w_fs_file_list || + wt == w_checkbox) { /* Add here new types */ d->active_el = g->elements + i; return 1; } else if (wt == w_group) { diff --git a/src/widget/group.c b/src/widget/group.c index cd70423..b092027 100644 --- a/src/widget/group.c +++ b/src/widget/group.c @@ -72,6 +72,7 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, ; group->w.w_parent = w_parent; group->w.callback = group_default_callback; + group->direction = direction; if (group->count == 0) { return group; }