From 707087b8fe0c329886520cc621af24bf6f56ebf9 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Fri, 3 Apr 2026 15:37:10 +0300 Subject: [PATCH] Inits main menu controling struct; moves file list to the main window (not finished) --- TODO.md | 3 +- src/file_processor.c | 4 +-- src/main.c | 69 +++++++++++++++++++++++++++++++++++---- src/main.h | 15 +++++++-- src/query.c | 2 +- src/server.c | 4 +-- src/widget/app.c | 3 ++ src/widget/app.h | 1 + src/widget/file_list.c | 8 ++++- src/widget/file_list.h | 1 + src/widget/fs_file_list.c | 28 +++++++++++++--- src/widget/fs_file_list.h | 1 + 12 files changed, 120 insertions(+), 19 deletions(-) diff --git a/TODO.md b/TODO.md index 3b11ac8..045df12 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,7 @@ # TODO: ## Current: +- [ ] Variable naming convention - [ ] Sorting in file list - [ ] File upload multiline description (window) - [ ] More intuitive navigation between nested groups (by pressing left and right buttons) @@ -10,7 +11,7 @@ - [x] Upload menu disappears after alert (when opening link to non-existing directory for example). ## Bugs: -- [ ] Sometimes segfaults while navigating through modal menu (try use controlling byte) +- [ ] Sometimes segfaults while navigating through modal menu ## Features: - [x] Search files diff --git a/src/file_processor.c b/src/file_processor.c index 5f006f4..a8cab06 100644 --- a/src/file_processor.c +++ b/src/file_processor.c @@ -33,7 +33,7 @@ void file_list(file_args_t *f_args, query_args_t *q_args) { char *query = NULL; static char qbuf[INBUFSIZE * 2]; static uint32_t qbuf_used = 0; - ui_file_list_t *fui = (ui_file_list_t *)q_args->file_list_ui; + ui_file_list_t *fui = (ui_file_list_t *)q_args->main_ui->ui; dialogue_t *d = (dialogue_t *)q_args->active_dialogue; fui->start = &(f_args->l_start); fui->current = &(f_args->l_current); @@ -119,7 +119,7 @@ void file_download(file_args_t *f_args, query_args_t *q_args) { uint32_t progress = (f_selected->size - size_rest) * 100 / f_selected->size; ui_progress_bar_t *pb = (ui_progress_bar_t *)q_args->progress_bar; dialogue_t *d = (dialogue_t *)q_args->active_dialogue; - ui_file_list_t *fui = (ui_file_list_t *)q_args->file_list_ui; + ui_file_list_t *fui = (ui_file_list_t *)q_args->main_ui->ui; int32_t a_len = 0; if (size_rest == 0) diff --git a/src/main.c b/src/main.c index f39c4a4..c278126 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ /* Copyright (c) 2026 Oleksandr Zhylin */ #include +#include #include #include #include @@ -12,16 +13,20 @@ #include #include #include -#include +#include "app.h" #include "connection.h" #include "file_list.h" +#include "fs_file_list.h" #include "main.h" #include "query.h" uint32_t m_id = 0; int32_t process_user_input(app_t *app, callback_args_t *d_args); +void main_window_set(app_t *app, enum main_window_type type); +void main_window_draw(app_t *app); +void main_window_delete(app_t *app); int main(int argc, char **argv) { app_t *app; @@ -46,8 +51,9 @@ int main(int argc, char **argv) { init_query_args(q_args, app->params); q_args->buf = malloc(INBUFSIZE); app->query_args = q_args; - q_args->file_list_ui = init_file_list(&(app->left_win), &(app->right_win)); - draw_file_list(q_args->file_list_ui); + + main_window_set(app, mw_fl_server); + main_window_draw(app); /* init client to connect to the server */ app->params->sd = init_client(); @@ -60,6 +66,7 @@ int main(int argc, char **argv) { } app->query_args->sd = app->params->sd; + app->query_args->main_ui = &(app->main_ui); query_loop(app); clear_params(¶ms); @@ -70,7 +77,7 @@ int main(int argc, char **argv) { int32_t process_user_input(app_t *app, callback_args_t *d_args) { int32_t c; - ui_file_list_t *fui = (ui_file_list_t *)app->query_args->file_list_ui; + ui_file_list_t *fui = (ui_file_list_t *)app->query_args->main_ui->ui; c = wgetch(app->win); switch (c) { case KEY_F(9): @@ -78,8 +85,11 @@ int32_t process_user_input(app_t *app, callback_args_t *d_args) { return OK; case 'U': case 'u': - if (!app->modal.is_initiated && !fui->active_search) { - app->query_args->state = S_UPLOAD_FILE_SELECT; + if (!app->modal.is_initiated && !fui->active_search && app->main_ui.type != mw_fl_local) { + /* app->query_args->state = S_UPLOAD_FILE_SELECT; */ + main_window_set(app, mw_fl_local); + main_window_draw(app); + d_args->element = app->main_ui.ui; break; } case 's': @@ -95,4 +105,51 @@ int32_t process_user_input(app_t *app, callback_args_t *d_args) { break; } return OK; +} + +void main_window_set(app_t *app, enum main_window_type type) { + if (app->main_ui.ui != NULL) { + main_window_delete(app); + } + app->main_ui.type = type; + switch (type) { + case mw_fl_server: + app->main_ui.ui = init_file_list(&(app->left_win), &(app->right_win)); + app->active_callback = file_list_cb; + break; + case mw_fl_local: + app->main_ui.ui = + init_fs_file_list_win(&(app->left_win), &(app->right_win)); + app->active_callback = fs_file_list_cb; + break; + case mw_f_desc: + break; + default: + break; + } +} + +void main_window_draw(app_t *app) { + switch (app->main_ui.type) { + case mw_fl_server: + draw_file_list((ui_file_list_t *)app->main_ui.ui); + break; + case mw_fl_local: + draw_fs_file_list((ui_fs_file_list_t *)app->main_ui.ui); + break; + case mw_f_desc: + break; + } +} + +void main_window_delete(app_t *app) { + switch (app->main_ui.type) { + case mw_fl_server: + delete_file_list((ui_file_list_t **)&(app->main_ui.ui)); + break; + case mw_fl_local: + /* TODO: delete fs_file_list */ + case mw_f_desc: + break; + } } \ No newline at end of file diff --git a/src/main.h b/src/main.h index 0a2d0ed..8607490 100644 --- a/src/main.h +++ b/src/main.h @@ -82,6 +82,17 @@ typedef struct file_args { fl_item_t *l_current; } file_args_t; +enum main_window_type { + mw_fl_server, /* file list on the server */ + mw_fl_local, /* local file list */ + mw_f_desc, /* file description */ +}; + +typedef struct main_window { + enum main_window_type type; + void *ui; /* structure that describes window UI */ +} main_window_t; + typedef struct query_args { int32_t sd; int32_t buf_used; @@ -95,10 +106,10 @@ typedef struct query_args { uint64_t capacity; uint64_t size; } server_message; - void *file_list_ui; /* TODO: find solution to insert actual type without void pointers */ + main_window_t *main_ui; void *progress_bar; void *active_dialogue; - char *notification; + void *notification; } query_args_t; #endif \ No newline at end of file diff --git a/src/query.c b/src/query.c index 430e31d..af09cac 100644 --- a/src/query.c +++ b/src/query.c @@ -130,7 +130,7 @@ void wait_register(query_args_t *q_args) { int upload_confirm_cb(app_t *app, char *query, int q_len) { if (!strncmp("finished\n", query, sizeof("finished\n") - 1)) { - ui_file_list_t *fui = (ui_file_list_t *)app->query_args->file_list_ui; + ui_file_list_t *fui = (ui_file_list_t *)app->query_args->main_ui->ui; notification("File upload", dc_normal, "File %s is uploaded to the server!", app->query_args->file->name); clear_file_in_query(app->query_args); diff --git a/src/server.c b/src/server.c index 5619d3b..0b0a7be 100644 --- a/src/server.c +++ b/src/server.c @@ -35,7 +35,7 @@ void server_send_string(query_args_t *q, const char *fmt, ...) { int server_wait_reg_confirm_cb(app_t *app, char *line, int l_len) { query_args_t *q_args = app->query_args; char query[INBUFSIZE]; - ui_file_list_t *fui = (ui_file_list_t *)q_args->file_list_ui; + ui_file_list_t *fui = (ui_file_list_t *)q_args->main_ui->ui; if (!strcmp(line, "ok\n")) { server_send_string(q_args, "file list %u %u\n", fui->max_lines, @@ -96,7 +96,7 @@ int process_server_command(char *line, int l_len, app_t *app) { int ws_pos = l_len; query_args_t *q_args = app->query_args; params_t *params = q_args->params; - ui_file_list_t *fui = (ui_file_list_t *)q_args->file_list_ui; + ui_file_list_t *fui = (ui_file_list_t *)q_args->main_ui->ui; char *cptr = strchr(line, ' '); if (cptr != NULL && cptr > line) diff --git a/src/widget/app.c b/src/widget/app.c index ab93920..5f6b76a 100644 --- a/src/widget/app.c +++ b/src/widget/app.c @@ -55,6 +55,9 @@ app_t *init_app() { /* here goes box borders */ draw_borders(_app); + /* NULL to main_ui */ + _app->main_ui.ui = NULL; + keypad(_app->win, TRUE); /* refresh the windows */ diff --git a/src/widget/app.h b/src/widget/app.h index f2635cb..a1d06cc 100644 --- a/src/widget/app.h +++ b/src/widget/app.h @@ -34,6 +34,7 @@ typedef struct { void (*active_callback)(callback_args_t *args); WINDOW *active_win; void *active_widget; + main_window_t main_ui; } app_t; app_t *init_app(void); diff --git a/src/widget/file_list.c b/src/widget/file_list.c index 0998c5d..20fb885 100644 --- a/src/widget/file_list.c +++ b/src/widget/file_list.c @@ -20,7 +20,7 @@ void reset_file_list(ui_file_list_t *fl_ui); void file_list_cb(callback_args_t *args) { app_t *app = args->app; - ui_file_list_t *fui = app->query_args->file_list_ui; + ui_file_list_t *fui = app->query_args->main_ui->ui; int32_t key = *((int32_t *)args->data); char q_prefix[128]; if (fui->search_key->slen > 0) { @@ -129,6 +129,12 @@ ui_file_list_t *init_file_list(WINDOW **win, WINDOW *const *info_win) { return fui; } +void delete_file_list(ui_file_list_t **fui) { + fl_clear((*fui)->start, (*fui)->current); + free(*fui); + *fui = NULL; +} + void reset_file_list(ui_file_list_t *fl_ui) { fl_clear(fl_ui->start, fl_ui->current); fl_ui->current_idx = 0; diff --git a/src/widget/file_list.h b/src/widget/file_list.h index 5014a65..848b7ef 100644 --- a/src/widget/file_list.h +++ b/src/widget/file_list.h @@ -28,4 +28,5 @@ void redraw_file_list(ui_file_list_t *fl_ui); ui_file_list_t *init_file_list(WINDOW **win, WINDOW *const *info_win); void file_list_cb(callback_args_t *args); void reset_file_list(ui_file_list_t *fl_ui); +void delete_file_list(ui_file_list_t **fui); #endif \ No newline at end of file diff --git a/src/widget/fs_file_list.c b/src/widget/fs_file_list.c index 1d1c8a4..32aac0b 100644 --- a/src/widget/fs_file_list.c +++ b/src/widget/fs_file_list.c @@ -77,11 +77,14 @@ static int get_files_from_fs(ui_fs_file_list_t *fui, char *path) { fs_fl_item_t *f_start = NULL, *f_current = NULL; /* files */ dir = opendir(path); - if (!dir) return 1; - free(fui->d_path); - fui->d_path = malloc(strlen(path)+1); + if (!dir) + return 1; + if (fui->d_path != NULL) { + free(fui->d_path); + fl_clear(&(fui->start), &(fui->current)); + } + fui->d_path = malloc(strlen(path) + 1); strcpy(fui->d_path, path); - fl_clear(&(fui->start), &(fui->current)); while ((dent = readdir(dir)) != NULL) { f_args.path = NULL; if ((f_args.d_type = dent->d_type) == DT_DIR) { @@ -269,6 +272,23 @@ ui_fs_file_list_t *init_fs_file_list(WINDOW **win, widget_t *w_parent) { return fl_ui; } +ui_fs_file_list_t *init_fs_file_list_win(WINDOW **win, WINDOW *const *info_win) { + ui_fs_file_list_t *fl_ui = malloc(sizeof(ui_fs_file_list_t)); + init_widget(&(fl_ui->w), NULL, win, ""); + fl_ui->current_idx = 0; + fl_ui->info_win = NULL; + fl_ui->d_path = NULL; + char *path = get_current_dir_name(); + get_files_from_fs(fl_ui, path); + fl_ui->current = fl_ui->start; + fl_ui->w.callback = fs_file_list_cb; + fl_ui->w.sz.x = getmaxx(*win) / 10 * 8; + fl_ui->w.sz.y = getmaxy(*win) / 10 * 8; + fl_ui->rows_num = 0; /* detects on the first draw */ + fl_ui->cur_page = 1; + return fl_ui; +} + void reset_fs_file_list(ui_fs_file_list_t *fl_ui) { fl_ui->current_idx = 0; } void draw_fs_file_list(ui_fs_file_list_t *fui) { diff --git a/src/widget/fs_file_list.h b/src/widget/fs_file_list.h index cbf4ca8..7335c02 100644 --- a/src/widget/fs_file_list.h +++ b/src/widget/fs_file_list.h @@ -36,4 +36,5 @@ void destroy_fs_file_list(ui_fs_file_list_t *fl_ui); void fs_file_list_cb(callback_args_t *args); void reset_fs_file_list(ui_fs_file_list_t *fl_ui); ui_fs_file_list_t *init_fs_file_list(WINDOW **win, widget_t *w_parent); +ui_fs_file_list_t *init_fs_file_list_win(WINDOW **win, WINDOW *const *info_win); #endif \ No newline at end of file