From 57b858f98f66f9fe64356772e4d3579ea36e1db4 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Mon, 23 Feb 2026 16:32:02 +0200 Subject: [PATCH] ui: dialogue: +id_map --- src/CMakeLists.txt | 2 ++ src/modals/CMakeLists.txt | 11 +++++++++-- src/modals/alert.c | 2 +- src/modals/ask_server_addr.c | 4 ++-- src/modals/download_pr.c | 4 ++-- src/modals/login_credentials.c | 4 ++-- src/modals/login_option.c | 7 +++---- src/modals/notification.c | 2 +- src/modals/register.c | 6 ++++-- src/modals/server_message.c | 2 +- src/modals/upload_dialogue.c | 4 ++-- src/modals/upload_props_dialogue.c | 4 ++-- src/utils/CMakeLists.txt | 15 +++++++++++++++ src/utils/d_array.c | 26 ++++++++++++++++++++++++++ src/utils/d_array.h | 15 +++++++++++++++ src/utils/utils.h | 4 ++++ src/widget/CMakeLists.txt | 4 +++- src/widget/dialogue.c | 1 + src/widget/dialogue.h | 4 +++- src/widget/group.c | 7 +++++-- src/widget/group.h | 5 +++-- src/widget/widget.h | 1 - 22 files changed, 106 insertions(+), 28 deletions(-) create mode 100644 src/utils/CMakeLists.txt create mode 100644 src/utils/d_array.c create mode 100644 src/utils/d_array.h create mode 100644 src/utils/utils.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 073fdc7..5ff0c89 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,6 +44,7 @@ add_subdirectory(widget_core) add_subdirectory(widget) add_subdirectory(modals) add_subdirectory(lib) +add_subdirectory(utils) target_link_libraries(zbbs-client-tui PRIVATE @@ -51,5 +52,6 @@ target_link_libraries(zbbs-client-tui widget modals bstring + utils ${CURSES_LIBRARIES} ) \ No newline at end of file diff --git a/src/modals/CMakeLists.txt b/src/modals/CMakeLists.txt index 5634ebe..f1d75a5 100644 --- a/src/modals/CMakeLists.txt +++ b/src/modals/CMakeLists.txt @@ -3,7 +3,13 @@ add_library(modals STATIC) file(GLOB M_HEADERS "*.h") file(GLOB M_SOURCES "*.c") -target_link_libraries(modals PRIVATE widget widget_core bstring) +target_link_libraries(modals + PRIVATE + widget + widget_core + bstring + utils +) target_sources(modals PRIVATE @@ -16,4 +22,5 @@ target_sources(modals target_include_directories(modals PRIVATE "../widget") target_include_directories(modals PRIVATE "../widget_core") -target_include_directories(modals PRIVATE "../lib/") \ No newline at end of file +target_include_directories(modals PRIVATE "../lib/") +target_include_directories(widget PRIVATE "../utils/") \ No newline at end of file diff --git a/src/modals/alert.c b/src/modals/alert.c index 7863d4f..fa5b7fd 100644 --- a/src/modals/alert.c +++ b/src/modals/alert.c @@ -33,7 +33,7 @@ void notification(const char *title, const char *message, d->w.callback = alert_cb; d->g_content = NULL; - d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + d->g_action = init_group(&(d->win), &(d->w), actions,&(d->id_map), horizontal); dialogue_init_active_id(d); d->color_scheme = color; diff --git a/src/modals/ask_server_addr.c b/src/modals/ask_server_addr.c index c9d5100..87d6416 100644 --- a/src/modals/ask_server_addr.c +++ b/src/modals/ask_server_addr.c @@ -60,8 +60,8 @@ dialogue_t *init_asa_modal(app_t *app) { dialogue_t *d = &(app->modal); d->w.callback = asa_modal_dialogue_callback; - d->g_content = init_group(&(d->win), &(d->w), content, horizontal); - d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + d->g_content = init_group(&(d->win), &(d->w), content,&(d->id_map), horizontal); + d->g_action = init_group(&(d->win), &(d->w), actions,&(d->id_map), horizontal); dialogue_init_active_id(d); diff --git a/src/modals/download_pr.c b/src/modals/download_pr.c index 214eed9..13cc980 100644 --- a/src/modals/download_pr.c +++ b/src/modals/download_pr.c @@ -24,8 +24,8 @@ dialogue_t *init_dwn_pr_modal(app_t *app, bool is_upload) { dialogue_t *d = &(app->modal); d->w.callback = dwn_pr_modal_cb; - d->g_content = init_group(&(d->win), &(d->w), content, horizontal); - d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal); + d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal); app->query_args->progress_bar = d->g_content->elements[0].element; app->query_args->active_dialogue = d; diff --git a/src/modals/login_credentials.c b/src/modals/login_credentials.c index e844040..c139b0d 100644 --- a/src/modals/login_credentials.c +++ b/src/modals/login_credentials.c @@ -65,8 +65,8 @@ dialogue_t *init_login_credentials_modal(app_t *app) { dialogue_t *d = &(app->modal); d->w.callback = init_login_credentials_modal_cb; - d->g_content = init_group(&(d->win), &(d->w), content, horizontal); - d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal); + d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal); dialogue_init_active_id(d); diff --git a/src/modals/login_option.c b/src/modals/login_option.c index 439b807..eca5975 100644 --- a/src/modals/login_option.c +++ b/src/modals/login_option.c @@ -27,7 +27,7 @@ void login_modal_option_cb(callback_args_t *args) { d->needs_destroy = true; app->params->uname = malloc(sizeof "anonymous"); strcpy(app->params->uname, "anonymous"); - write(app->params->sd, app->params->uname, sizeof "anonymous"-1); + write(app->params->sd, app->params->uname, sizeof "anonymous" - 1); app->query_args->state = S_WAIT_SERVER; print_bars(app); break; @@ -55,9 +55,8 @@ dialogue_t *init_login_option_modal(app_t *app) { "Select your login " "option", &(app->coordinates)); - app->modal.g_action = - init_group(&(app->modal.win), &(app->modal.w), children, - horizontal); + app->modal.g_action = init_group(&(app->modal.win), &(app->modal.w), children, + &(app->modal.id_map), horizontal); app->modal.w.callback = login_modal_option_cb; dialogue_init_active_id(&(app->modal)); diff --git a/src/modals/notification.c b/src/modals/notification.c index f0cdd05..aed98f1 100644 --- a/src/modals/notification.c +++ b/src/modals/notification.c @@ -43,7 +43,7 @@ dialogue_t *init_notification_modal(app_t *app) { d->w.callback = init_notification_modal_cb; d->g_content = NULL; - d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal); dialogue_init_active_id(d); diff --git a/src/modals/register.c b/src/modals/register.c index bf6704f..894cda8 100644 --- a/src/modals/register.c +++ b/src/modals/register.c @@ -93,8 +93,10 @@ dialogue_t *init_register_modal(app_t *app) { dialogue_t *d = &(app->modal); d->w.callback = init_register_modal_cb; - d->g_content = init_group(&(d->win), &(d->w), content, horizontal); - d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + d->g_content = + init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal); + d->g_action = + init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal); dialogue_init_active_id(d); diff --git a/src/modals/server_message.c b/src/modals/server_message.c index 9c312b4..fd98b49 100644 --- a/src/modals/server_message.c +++ b/src/modals/server_message.c @@ -44,7 +44,7 @@ void *init_server_message_modal(app_t *app) { init_dialogue(&(app->modal), "Server response", app->query_args->server_message.text, &(app->coordinates)); app->modal.g_action = - init_group(&(app->modal.win), &(app->modal.w), children, horizontal); + init_group(&(app->modal.win), &(app->modal.w), children, &(app->modal.id_map), horizontal); app->modal.w.callback = server_message_modal_cb; dialogue_init_active_id(&(app->modal)); diff --git a/src/modals/upload_dialogue.c b/src/modals/upload_dialogue.c index ea9fbd3..475b8a3 100644 --- a/src/modals/upload_dialogue.c +++ b/src/modals/upload_dialogue.c @@ -49,8 +49,8 @@ dialogue_t *init_upload_dialogue_modal(app_t *app) { dialogue_t *d = &(app->modal); d->w.callback = upload_dialogue_modal_cb; - d->g_content = init_group(&(d->win), &(d->w), content, horizontal); - d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal); + d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal); app->query_args->active_dialogue = d; diff --git a/src/modals/upload_props_dialogue.c b/src/modals/upload_props_dialogue.c index dc7be6d..b7eb3c4 100644 --- a/src/modals/upload_props_dialogue.c +++ b/src/modals/upload_props_dialogue.c @@ -64,8 +64,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, horizontal); - d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); + d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal); + d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal); app->query_args->active_dialogue = d; diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt new file mode 100644 index 0000000..7c04195 --- /dev/null +++ b/src/utils/CMakeLists.txt @@ -0,0 +1,15 @@ +add_library(utils STATIC) + +file(GLOB M_HEADERS "*.h") +file(GLOB M_SOURCES "*.c") + +list(REMOVE_ITEM M_HEADERS "utils.h") + +target_sources(utils + PRIVATE + ${M_SOURCES} + PUBLIC + FILE_SET HEADERS + FILES + ${M_HEADERS} +) diff --git a/src/utils/d_array.c b/src/utils/d_array.c new file mode 100644 index 0000000..8347f4c --- /dev/null +++ b/src/utils/d_array.c @@ -0,0 +1,26 @@ + +#include "d_array.h" +#include +#include + +void init_d_arr_ptr(d_array_ptr_t *arr, int64_t init_capacity) { + arr->capacity = init_capacity; + arr->length = 0; + arr->arr = malloc(sizeof(void *) * init_capacity); +} + +void add_d_arr_ptr(d_array_ptr_t *arr, void *ptr, int64_t idx) { + if (idx > arr->capacity - 1) { + arr->capacity = idx * 2; + arr->arr = realloc(arr->arr, arr->capacity); + } + arr->arr[idx] = ptr; + arr->length = idx+1; +} + +void free_d_arr(d_array_ptr_t *arr) { + arr->capacity = 0; + arr->length = 0; + free(arr->arr); + arr->arr = NULL; +} \ No newline at end of file diff --git a/src/utils/d_array.h b/src/utils/d_array.h new file mode 100644 index 0000000..b0fc803 --- /dev/null +++ b/src/utils/d_array.h @@ -0,0 +1,15 @@ +#ifndef D_ARRAY_H +#define D_ARRAY_H +/* Dynamic array of numbers */ +#include +typedef struct d_array_ptr_t { + int64_t capacity; + int64_t length; + void **arr; +} d_array_ptr_t; + +void init_d_arr_ptr(d_array_ptr_t *arr, int64_t init_capacity); +void add_d_arr_ptr(d_array_ptr_t *arr, void *ptr, int64_t idx); +void free_d_arr(d_array_ptr_t *arr); + +#endif \ No newline at end of file diff --git a/src/utils/utils.h b/src/utils/utils.h new file mode 100644 index 0000000..be68e58 --- /dev/null +++ b/src/utils/utils.h @@ -0,0 +1,4 @@ +#ifndef D_UTILS_H +#define D_UTILS_H +#include "d_array.h" +#endif \ No newline at end of file diff --git a/src/widget/CMakeLists.txt b/src/widget/CMakeLists.txt index 978176e..fcaa36f 100644 --- a/src/widget/CMakeLists.txt +++ b/src/widget/CMakeLists.txt @@ -18,7 +18,9 @@ target_link_libraries(widget PRIVATE bstring widget_core + utils ) target_include_directories(widget PRIVATE "../widget_core") -target_include_directories(widget PRIVATE "../lib/") \ No newline at end of file +target_include_directories(widget PRIVATE "../lib/") +target_include_directories(widget PRIVATE "../utils/") \ No newline at end of file diff --git a/src/widget/dialogue.c b/src/widget/dialogue.c index 31228ec..ebc9038 100644 --- a/src/widget/dialogue.c +++ b/src/widget/dialogue.c @@ -178,6 +178,7 @@ void init_dialogue(dialogue_t *dialogue, const char title[], const char text[], strcpy(dialogue->w.title, title); t_size = strlen(text); strcpy(dialogue->text, text); + init_d_arr_ptr(&(dialogue->id_map), MAX_IDS); /* trim the last new line symbol */ if (t_size && dialogue->text[t_size - 1] == '\n') dialogue->text[t_size - 1] = '\0'; diff --git a/src/widget/dialogue.h b/src/widget/dialogue.h index f8b92c5..acb7504 100644 --- a/src/widget/dialogue.h +++ b/src/widget/dialogue.h @@ -6,7 +6,8 @@ #include #include #include - +#include +#define MAX_IDS 64 enum g_type { g_content, g_action }; enum d_color_scheme { dc_normal, dc_alert }; @@ -25,6 +26,7 @@ typedef struct { bool needs_destroy; coordinates_t *p_coordinates; enum d_color_scheme color_scheme; + d_array_ptr_t id_map; } dialogue_t; void init_dialogue(dialogue_t *d, const char title[], const char text[], diff --git a/src/widget/group.c b/src/widget/group.c index 71820d1..d8159dc 100644 --- a/src/widget/group.c +++ b/src/widget/group.c @@ -1,5 +1,6 @@ #include "group.h" #include "button.h" +#include "d_array.h" #include "fs_file_list.h" #include "input.h" #include "progress_bar.h" @@ -9,6 +10,7 @@ #include #include #include +#include /* make response -1 */ #define MAKE_RESPONSE_M1(args, resp_data, response) \ @@ -83,7 +85,7 @@ union current_element { }; group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, - enum g_direction direction) { + d_array_ptr_t *id_map, enum g_direction direction) { group_t *group = malloc(sizeof(group_t)); union current_element current; group->parent_group = NULL; @@ -118,7 +120,7 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, break; case w_group: elements[i].element = init_group(win, &(group->w), children[i].children, - children[i].direction); + id_map, children[i].direction); w = &(((group_t *)elements[i].element)->w); current.group = (group_t *)elements[i].element; current.group->parent_group = group; @@ -155,6 +157,7 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, } /* set dimensions */ elements[i].id = w->id; + add_d_arr_ptr(id_map, &(elements[i]), w->id); if (direction == horizontal) { w->m_x = group->w.m_x + 1 + group->w.x; w->m_y = group->w.m_y; diff --git a/src/widget/group.h b/src/widget/group.h index 6f3deb5..c776b1c 100644 --- a/src/widget/group.h +++ b/src/widget/group.h @@ -3,6 +3,7 @@ #include #include +#include enum g_direction { horizontal, @@ -26,7 +27,7 @@ typedef struct group_el_init_t { struct group_el_init_t *children; } group_el_init_t; -typedef struct group_t{ +typedef struct group_t { widget_t w; group_el_t *elements; enum g_direction direction; @@ -40,7 +41,7 @@ typedef struct group_t{ element_ptr = &(g->elements[element_idx]); group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, - enum g_direction dir); + d_array_ptr_t *id_map, enum g_direction dir); void draw_group(WINDOW *win, group_t *group, int32_t active_id); void destroy_group(group_t *group); void group_default_callback(callback_args_t *args); diff --git a/src/widget/widget.h b/src/widget/widget.h index 2582210..2d7bb7a 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -8,5 +8,4 @@ #include "group.h" #include "input.h" #include "progress_bar.h" - #endif \ No newline at end of file