From cb79978cdf972cdf2f588123243c66d60f2e52cd Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Tue, 6 Jan 2026 14:49:37 +0200 Subject: [PATCH] ui: fs file list (not finished) --- src/deps.mk | 1 + src/file_processor.h | 1 - src/fs.c | 39 ++++++++ src/fs.h | 8 ++ src/ui/modals/upload_dialogue.c | 2 +- src/ui/widget.h | 1 + src/ui/widget/file_list.c | 38 +------- src/ui/widget/fs_file_list.c | 160 ++++++++++++++++++++++++++++++++ src/ui/widget/fs_file_list.h | 23 +++++ src/ui/widget/group.c | 12 +++ 10 files changed, 250 insertions(+), 35 deletions(-) create mode 100644 src/fs.c create mode 100644 src/fs.h create mode 100644 src/ui/widget/fs_file_list.c create mode 100644 src/ui/widget/fs_file_list.h diff --git a/src/deps.mk b/src/deps.mk index 94ec06b..a154278 100644 --- a/src/deps.mk +++ b/src/deps.mk @@ -13,6 +13,7 @@ file_processor.o: src/file_processor.c src/client.h src/main.h \ src/ui/widget/../../main.h src/ui/widget/group.h \ src/ui/widget/dialogue.h src/ui/widget/file_list.h \ src/ui/widget/progress_bar.h +fs.o: src/fs.c main.o: src/main.c src/connection.h src/main.h src/types.h src/ui/app.h \ src/ui/../common.h src/ui/widget.h src/ui/../main.h \ src/ui/widget/dialogue.h src/ui/widget/../widget.h \ diff --git a/src/file_processor.h b/src/file_processor.h index 0c98c71..0a3c050 100644 --- a/src/file_processor.h +++ b/src/file_processor.h @@ -12,5 +12,4 @@ int file_upload_start(query_args_t *q_args); int file_upload(query_args_t *q_args); void fl_clear(fl_item_t **start, fl_item_t **arg_current); int32_t ui_file_select(file_args_t *f_args, query_args_t *q_args, int32_t idx); - #endif \ No newline at end of file diff --git a/src/fs.c b/src/fs.c new file mode 100644 index 0000000..74a36ec --- /dev/null +++ b/src/fs.c @@ -0,0 +1,39 @@ +#include +#include +#include + +#define BYTES_IN_GB 1073741824 +#define BYTES_IN_MB 1048576 +#define BYTES_IN_KB 1024 + +#define PRINT_SIZE(text, f_arg, s_arg, unit) \ + s_arg /= 100; \ + if (s_arg > 0) { \ + sprintf(text, "%zu,%zu%s", f_arg, s_arg, unit); \ + } else { \ + sprintf(text, "%zu%s", f_arg, unit); \ + } + +void size_to_text(size_t size, char *text) { + size_t kb = 0; + size_t mb = 0; + size_t gb = 0; + + gb = size / BYTES_IN_GB; + mb = size / BYTES_IN_MB; + kb = size / BYTES_IN_KB; + if (gb > 0) { + size = size % BYTES_IN_GB; + mb = size / BYTES_IN_MB; + PRINT_SIZE(text, gb, mb, "GB"); + } else if (mb > 0) { + size = size % BYTES_IN_MB; + kb = size / BYTES_IN_KB; + PRINT_SIZE(text, mb, kb, "MB"); + } else if (kb > 0) { + size = size % BYTES_IN_KB; + PRINT_SIZE(text, kb, size, "KB"); + } else { + sprintf(text, "%zu B", size); + } +} \ No newline at end of file diff --git a/src/fs.h b/src/fs.h new file mode 100644 index 0000000..58b0b19 --- /dev/null +++ b/src/fs.h @@ -0,0 +1,8 @@ +#ifndef LOC_FS_H +#define LOC_FS_H + +#include + +void size_to_text(size_t size, char *text); + +#endif \ No newline at end of file diff --git a/src/ui/modals/upload_dialogue.c b/src/ui/modals/upload_dialogue.c index 79dfed7..154f1af 100644 --- a/src/ui/modals/upload_dialogue.c +++ b/src/ui/modals/upload_dialogue.c @@ -31,7 +31,7 @@ dialogue_t *init_upload_dialogue_modal(app_t *app) { return NULL; group_el_init_t content[] = { {.type = w_input, .label = "File description", .length = 30}, - {.type = w_input, .label = "File path", .length = 30}, + {.type = w_fs_file_list, .label = "File", .length = 30}, {.type = w_end}}; group_el_init_t actions[] = { diff --git a/src/ui/widget.h b/src/ui/widget.h index aafebca..57ed7b3 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -12,6 +12,7 @@ enum w_type { w_group, w_input, w_progress, + w_fs_file_list, }; typedef struct { diff --git a/src/ui/widget/file_list.c b/src/ui/widget/file_list.c index 62d97fa..63497f6 100644 --- a/src/ui/widget/file_list.c +++ b/src/ui/widget/file_list.c @@ -1,6 +1,7 @@ #include "file_list.h" #include "../../file_processor.h" #include "../app.h" +#include "../../fs.h" #include "progress_bar.h" #include #include @@ -12,7 +13,6 @@ #include void reset_file_list(ui_file_list_t *fl_ui); -void size_to_text(size_t size, char *text); void file_list_cb(callback_args_t *args) { app_t *app = args->app; @@ -79,14 +79,14 @@ void reset_file_list(ui_file_list_t *fl_ui) { void draw_file_list(ui_file_list_t *fl_ui) { int32_t sz_y, sz_x; int32_t p_y, p_x; - getmaxyx(*(fl_ui->w.parent_win), sz_y, sz_x); - int32_t sz_y_f = sz_y - 2; // factual size (without box) + WINDOW *win = *(fl_ui->w.parent_win); + getmaxyx(win, sz_y, sz_x); + int32_t sz_y_f = sz_y - 2; // actual size (without box) p_y = 1; p_x = 1; fl_item_t *el = *(fl_ui->start); fl_item_t *active_el = *(fl_ui->start); int32_t cur_el_idx = 0; - WINDOW *win = *(fl_ui->w.parent_win); curs_set(0); if (fl_ui->activate_last) { @@ -144,37 +144,9 @@ void draw_file_list(ui_file_list_t *fl_ui) { char size_text[64]; size_to_text(active_el->size, size_text); - + mvwprintw(i_win, p_y++, p_x, "Size: %s", size_text); mvwprintw(i_win, p_y++, p_x, "Owner: %s", active_el->owner); mvwprintw(i_win, p_y++, p_x, "Description: "); print_multiline_text(i_win, active_el->description, sz_x, p_y, p_x, 0); -} - -#define BYTES_IN_GB 1073741824 -#define BYTES_IN_MB 1048576 -#define BYTES_IN_KB 1024 - -void size_to_text(size_t size, char *text) { - size_t kb = 0; - size_t mb = 0; - size_t gb = 0; - - gb = size / BYTES_IN_GB; - mb = size / BYTES_IN_MB; - kb = size / BYTES_IN_KB; - if (gb > 0) { - size = size % BYTES_IN_GB; - mb = size / BYTES_IN_MB; - sprintf(text, "%zu,%zu GB", gb, mb); - } else if (mb > 0) { - size = size % BYTES_IN_MB; - kb = size / BYTES_IN_KB; - sprintf(text, "%zu,%zu MB", mb, kb); - } else if (kb > 0) { - size = size % BYTES_IN_KB; - sprintf(text, "%zu,%zu KB", kb, size); - } else { - sprintf(text, "%zu B", size); - } } \ No newline at end of file diff --git a/src/ui/widget/fs_file_list.c b/src/ui/widget/fs_file_list.c new file mode 100644 index 0000000..b1186ad --- /dev/null +++ b/src/ui/widget/fs_file_list.c @@ -0,0 +1,160 @@ +#include "../../file_processor.h" +#include "../app.h" +#include "fs_file_list.h" +#include "progress_bar.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void reset_file_list(ui_fs_file_list_t *fl_ui); + +static void fl_add(fl_item_t **f_start, fl_item_t **f_current, + struct dirent *dent) { + fl_item_t *c_item = malloc(sizeof(fl_item_t)); + c_item->name = dent->d_name; + c_item->description = NULL; + c_item->owner = NULL; + c_item->size = 0; + c_item->next = NULL; + if (*f_start == NULL) { + *f_start = c_item; + *f_current = c_item; + } else { + (*f_current)->next = c_item; + } +} + +fl_item_t *get_files_from_fs(char *path) { + DIR *dir; + struct dirent *dent; + + fl_item_t *l_start = NULL, *l_current = NULL; + + dir = opendir(path); + if (!dir) { + return NULL; + errno = 1; + } + while ((dent = readdir(dir)) != NULL) { + fl_add(&l_start, &l_current, dent); + } + return l_start; +} + +void fs_file_list_cb(callback_args_t *args) { + app_t *app = args->app; + ui_fs_file_list_t *fui = app->query_args->file_list_ui; + int32_t key = *((int32_t *)args->data); + int32_t q_len = 0; + fl_item_t *f_item; + ui_progress_bar_t *pb; + switch (key) { + case KEY_DOWN: + if (fui->current_idx < fui->current_count - 1) { + fui->current_idx++; + draw_fs_file_list(fui); + } else { + fl_clear(fui->start, fui->current); + reset_file_list(fui); + } + break; + case KEY_UP: + if (fui->current_idx > 0) { + fui->current_idx--; + draw_fs_file_list(fui); + } else { + fl_clear(fui->start, fui->current); + reset_fs_file_list(fui); + fui->activate_last = true; + } + break; + case '\n': + /* here goes file select */ + break; + } +} + +ui_fs_file_list_t *init_fs_file_list(WINDOW **win, widget_t *w_parent) { + ui_fs_file_list_t *fl_ui = malloc(sizeof(ui_fs_file_list_t)); + init_widget(&(fl_ui->w), w_parent, win, ""); + fl_ui->current_idx = 0; + fl_ui->current_count = 0; + fl_ui->activate_last = false; + fl_ui->info_win = NULL; + return fl_ui; +} + +void reset_fs_file_list(ui_fs_file_list_t *fl_ui) { + fl_ui->current_idx = 0; + fl_ui->current_count = 0; + fl_ui->activate_last = false; +} + +void draw_fs_file_list(ui_fs_file_list_t *fl_ui) { + int32_t sz_y, sz_x; + int32_t p_y, p_x; + WINDOW *win = *(fl_ui->w.parent_win); + getmaxyx(win, sz_y, sz_x); + int32_t sz_y_f = sz_y - 2; // actual size (without box) + p_y = 1; + p_x = 1; + fl_item_t *el = *(fl_ui->start); + fl_item_t *active_el = *(fl_ui->start); + int32_t cur_el_idx = 0; + curs_set(0); + + if (fl_ui->activate_last) { + fl_ui->current_idx = fl_ui->current_count - 1; + fl_ui->activate_last = false; + } + + if (fl_ui->current_idx + 1 >= sz_y_f) { + p_y -= fl_ui->current_idx - sz_y_f + 2; + } + + do { + if (p_y < 1) { + p_y++; + cur_el_idx++; + continue; + } + if (cur_el_idx == fl_ui->current_idx) { + wattrset(win, A_BOLD | A_REVERSE); + active_el = el; + } + p_x = 1; + mvwprintw(win, p_y, p_x, "%s%n", el->name, &p_x); + mvwprintw(win, p_y, p_x + 1, "%*s", sz_x - p_x, ""); + if (cur_el_idx == fl_ui->current_idx) { + wattroff(win, A_BOLD | A_REVERSE); + } + p_y++; + cur_el_idx++; + } while ((el = el->next) != NULL && p_y < sz_y_f); + + p_x = 1; + + for (; p_y < sz_y_f; p_y++) { + mvwprintw(win, p_y, p_x, "%*s", sz_x - 1, ""); + } + char p_info[24]; + uint32_t p_len; + p_x = 1; + + uint32_t l_pad = (sz_x - p_len) / 2; + + wattrset(win, A_BOLD); + mvwprintw(win, p_y, p_x, "%*s%s%*s", l_pad, "", p_info, l_pad, ""); + wattroff(win, A_BOLD); +} + +void destroy_fs_file_list(ui_fs_file_list_t *fui) { + fl_clear(fui->start, fui->current); + free(fui); +} \ No newline at end of file diff --git a/src/ui/widget/fs_file_list.h b/src/ui/widget/fs_file_list.h new file mode 100644 index 0000000..0413116 --- /dev/null +++ b/src/ui/widget/fs_file_list.h @@ -0,0 +1,23 @@ +#ifndef FS_FILE_LIST_H +#define FS_FILE_LIST_H +#include "../widget.h" +#include +#include + +typedef struct { + widget_t w; + fl_item_t **current; + fl_item_t **start; + int32_t current_idx; + uint32_t current_count; + uint32_t activate_last : 1; + WINDOW *const* info_win; +} ui_fs_file_list_t; + +void draw_fs_file_list(ui_fs_file_list_t *fl_ui); +void redraw_fs_file_list(ui_fs_file_list_t *fl_ui); +void destroy_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); +void fs_file_list_cb(callback_args_t *args); +void reset_fs_file_list(ui_fs_file_list_t *fl_ui); +#endif \ No newline at end of file diff --git a/src/ui/widget/group.c b/src/ui/widget/group.c index a4d15dc..ce2d9ea 100644 --- a/src/ui/widget/group.c +++ b/src/ui/widget/group.c @@ -1,5 +1,7 @@ #include "group.h" #include "button.h" +#include "file_list.h" +#include "fs_file_list.h" #include "input.h" #include "progress_bar.h" #include @@ -106,6 +108,10 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, elements[i].element = init_ui_progress_bar(win, &(group->w)); w = &(((ui_progress_bar_t *)elements[i].element)->w); break; + case w_fs_file_list: + elements[i].element = init_fs_file_list(win, &(group->w)); + w = &(((ui_progress_bar_t *)elements[i].element)->w); + break; } /* set dimensions */ elements[i].id = w->id; @@ -147,6 +153,9 @@ void draw_group(WINDOW *win, group_t *group, int32_t active_id, case w_progress: draw_ui_progress_bar((ui_progress_bar_t *)el->element); break; + case w_fs_file_list: + draw_fs_file_list((ui_fs_file_list_t *)el->element); + break; } } } @@ -169,6 +178,9 @@ void destroy_group(group_t *group) { case w_progress: destroy_ui_progress_bar(el->element); break; + case w_fs_file_list: + destroy_fs_file_list(el->element); + break; } } if (group->elements != NULL) {