basic implementation of main_window component and file list fixes

This commit is contained in:
2026-04-07 17:06:29 +03:00
parent 2414abbdcb
commit 9dabb06d99
14 changed files with 151 additions and 109 deletions
-1
View File
@@ -1,7 +1,6 @@
# 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)
-2
View File
@@ -47,8 +47,6 @@ void w_app_draw_modal(w_app_t *app) {
}
}
app->active_callback = app->modal.w.callback;
app->active_win = app->modal.win;
app->active_win_type = aw_modal;
app->active_widget = &(app->modal);
}
w_dialogue_draw(&(app->modal));
+8 -10
View File
@@ -26,7 +26,7 @@ uint32_t m_id = 0;
int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args);
void main_window_set(w_app_t *app, enum main_window_type type);
void main_window_draw(w_app_t *app);
void main_window_delete(w_app_t *app);
void main_window_destroy(w_app_t *app);
int main(int argc, char **argv) {
w_app_t *app;
@@ -45,9 +45,6 @@ int main(int argc, char **argv) {
/* init alert */
w_alert_init(app);
wrefresh(app->left_win);
wrefresh(app->right_win);
init_query_args(q_args, app->params);
q_args->buf = malloc(INBUFSIZE);
app->query_args = q_args;
@@ -85,7 +82,8 @@ int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args) {
return OK;
case 'U':
case 'u':
if (!app->modal.is_initiated && !fui->active_search && app->main_ui.type != mw_fl_local) {
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);
@@ -109,17 +107,16 @@ int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args) {
void main_window_set(w_app_t *app, enum main_window_type type) {
if (app->main_ui.ui != NULL) {
main_window_delete(app);
main_window_destroy(app);
}
app->main_ui.type = type;
switch (type) {
case mw_fl_server:
app->main_ui.ui = w_fl_init(&(app->left_win), &(app->right_win));
app->main_ui.ui = w_fl_init(app);
app->active_callback = w_fl_cb;
break;
case mw_fl_local:
app->main_ui.ui =
w_lfl_init_win(&(app->left_win), &(app->right_win));
app->main_ui.ui = w_lfl_init_win(app);
app->active_callback = w_lfl_cb;
break;
case mw_f_desc:
@@ -142,10 +139,11 @@ void main_window_draw(w_app_t *app) {
}
}
void main_window_delete(w_app_t *app) {
void main_window_destroy(w_app_t *app) {
switch (app->main_ui.type) {
case mw_fl_server:
w_fl_destroy((w_ui_file_list_t **)&(app->main_ui.ui));
app->main_ui.cb_refresh = NULL;
break;
case mw_fl_local:
/* TODO: delete fs_file_list */
+2 -1
View File
@@ -90,7 +90,8 @@ enum main_window_type {
typedef struct main_window {
enum main_window_type type;
void *ui; /* structure that describes window UI */
void *ui; /* structure which describes window UI */
void (*cb_refresh) (void *app); /* refresh callback */
} main_window_t;
typedef struct query_args {
+4 -2
View File
@@ -30,11 +30,13 @@ int64_t u_utf8_conver_to_wide(const char *utf8_str, wchar_t **restrict wide_str,
return 0;
}
int64_t u_utf8_curs_printw(WINDOW *win, int64_t y, int64_t x, char *const utf8_str) {
int64_t u_utf8_curs_printw(WINDOW *win, int64_t y, int64_t x, char *const utf8_str, int max_len) {
wchar_t *wname = NULL;
size_t nsize = 0;
u_utf8_conver_to_wide(utf8_str, &wname, &nsize);
mvwaddwstr(win, y, x, wname);
/* mvwaddwstr(win, y, x, wname); */
wmove(win,(y),(x));
waddnwstr(win, wname, max_len);
free(wname);
return nsize;
}
+1 -1
View File
@@ -8,6 +8,6 @@
size_t u_utf8_code_points_count(const char *s);
int64_t u_utf8_convert_to_wide(const char *utf8_str, wchar_t **restrict wide_str,
size_t *restrict len);
int64_t u_utf8_curs_printw(WINDOW *win, int64_t y, int64_t x, char *const utf8_str);
int64_t u_utf8_curs_printw(WINDOW *win, int64_t y, int64_t x, char *const utf8_str, int max_len);
#endif
+6 -21
View File
@@ -29,23 +29,10 @@ w_app_t *w_app_init() {
_app->win = newwin(_app->coordinates.cur_y, _app->coordinates.cur_x, 0, 0);
/* define the width for each sub window */
int32_t left_w_x = x_max / 10 * 4;
int32_t right_w_x = x_max - left_w_x - 2;
/* create the menu window */
_app->left_win = newwin(y_max - 4, left_w_x, 2, 1);
/* create the action window */
_app->right_win = newwin(y_max - 4, right_w_x, 2, left_w_x + 1);
/* dialogue */
_app->modal.win = NULL;
_app->modal.is_initiated = 0;
/* default win */
_app->active_win_type = aw_left;
/* default callback */
_app->active_callback = w_fl_cb;
@@ -57,13 +44,12 @@ w_app_t *w_app_init() {
/* NULL to main_ui */
_app->main_ui.ui = NULL;
_app->main_ui.cb_refresh = NULL;
keypad(_app->win, TRUE);
/* refresh the windows */
wnoutrefresh(_app->win);
wnoutrefresh(_app->left_win);
wnoutrefresh(_app->right_win);
doupdate();
return _app;
@@ -95,8 +81,6 @@ void w_app_draw_borders(w_app_t *app) {
}
clear();
box(app->win, 0, 0);
box(app->left_win, 0, 0);
box(app->right_win, 0, 0);
}
struct action_key {
@@ -150,7 +134,8 @@ void w_app_print_bars(w_app_t *app) {
int t_margin = 0; /* tab margin */
int c_size = app->coordinates.max_x / 4; /* column size */
int incr_last = app->coordinates.max_x % 4; /* increment size fo the last element (fill empty space) */
int incr_last = app->coordinates.max_x %
4; /* increment size fo the last element (fill empty space) */
for (int i = 0; i < 3; i++) {
struct action_key *k = &action_keys[i];
@@ -168,15 +153,15 @@ void w_app_print_bars(w_app_t *app) {
void w_app_refresh(w_app_t *app) {
w_app_draw_borders(app);
wnoutrefresh(app->win);
wnoutrefresh(app->right_win);
wnoutrefresh(app->left_win);
if (app->modal.win != NULL) {
if (app->modal.is_initiated != 0) {
wnoutrefresh(app->modal.win);
}
}
if (app->main_ui.cb_refresh != NULL) {
app->main_ui.cb_refresh(app);
}
doupdate();
}
-10
View File
@@ -15,24 +15,14 @@ typedef enum {
modal_color_pair = 3,
} w_app_color;
typedef enum {
aw_left,
aw_right,
aw_modal
} w_active_win_t;
typedef struct {
WINDOW *win;
WINDOW *left_win;
WINDOW *right_win;
w_dialogue_t modal;
params_t *params;
coordinates_t coordinates;
query_args_t *query_args;
file_args_t *file_args;
w_active_win_t active_win_type;
void (*active_callback)(w_cb_args_t *args);
WINDOW *active_win;
void *active_widget;
main_window_t main_ui;
} w_app_t;
-2
View File
@@ -319,8 +319,6 @@ void w_dialogue_destroy(w_dialogue_t *d, void *_app) {
d->win = NULL;
d->is_initiated = 0;
d->needs_destroy = false;
app->active_win_type = aw_left;
app->active_win = app->left_win;
app->active_callback = w_fl_cb;
app->query_args->active_dialogue = NULL;
u_d_arr_ptr_free(&(d->id_map));
+64 -26
View File
@@ -110,22 +110,49 @@ void w_fl_cb(w_cb_args_t *args) {
}
}
w_ui_file_list_t *w_fl_init(WINDOW **win, WINDOW *const *info_win) {
static void w_fl_cb_refresh(void *data) {
w_app_t *app = (w_app_t *)data;
if (app->main_ui.type != mw_fl_server) {
return;
}
w_ui_file_list_t *fui = app->main_ui.ui;
wnoutrefresh(fui->win_list);
wnoutrefresh(fui->win_info);
}
w_ui_file_list_t *w_fl_init(w_app_t *app) {
w_ui_file_list_t *fui = malloc(sizeof(w_ui_file_list_t));
w_init(&(fui->w), NULL, win, "");
WINDOW *parent_win = *(fui->w.parent_win);
app->main_ui.ui = fui;
app->main_ui.type = mw_fl_server;
app->main_ui.cb_refresh = w_fl_cb_refresh;
w_init(&(fui->w), NULL, &(app->win), "");
WINDOW *parent_win = app->win;
fui->current_idx = 0;
fui->current_page = 1;
fui->pages = 1;
fui->current_count = 0;
fui->full_count = 0;
fui->activate_last = false;
fui->info_win = info_win;
fui->max_lines = getmaxy(parent_win) - 3; /* 2+1 (bottom info line) */
fui->active_search = false;
fui->search_key = bfromcstrrangealloc(12, 64, "");
fui->start = NULL;
fui->current = NULL;
fui->w.sz.x = getmaxx(app->win);
fui->w.sz.y = getmaxy(app->win);
/* * INIT UI * */
/* define the width for each sub window */
int64_t left_w_x = app->coordinates.max_x / 10 * 5;
int64_t right_w_x = app->coordinates.max_x - left_w_x - 2;
/* create the list window */
fui->win_list = newwin(app->coordinates.max_y - 4, left_w_x, 2, 1);
/* create the action window */
fui->win_info =
newwin(app->coordinates.max_y - 4, right_w_x, 2, left_w_x + 1);
return fui;
}
@@ -149,9 +176,11 @@ void w_fl_rest(w_ui_file_list_t *fl_ui) {
void w_fl_draw(w_ui_file_list_t *fui) {
int32_t sz_y, sz_x;
int32_t p_y, p_x;
WINDOW *parent_win = *(fui->w.parent_win);
getmaxyx(parent_win, sz_y, sz_x);
WINDOW *win = fui->win_list;
getmaxyx(win, sz_y, sz_x);
int32_t sz_y_f = sz_y - 2; /* TODO: можно заменить на поле max_lines */
sz_x -= 1; /* do not count the borders */
p_y = 1;
p_x = 1;
fl_item_t *el = NULL;
@@ -159,6 +188,9 @@ void w_fl_draw(w_ui_file_list_t *fui) {
int32_t cur_el_idx = 0;
curs_set(false);
box(fui->win_list, 0, 0);
box(fui->win_info, 0, 0);
if (fui->start != NULL) {
el = *(fui->start);
active_el = el;
@@ -182,14 +214,17 @@ void w_fl_draw(w_ui_file_list_t *fui) {
continue;
}
if (cur_el_idx == fui->current_idx) {
wattrset(parent_win, A_BOLD | A_REVERSE);
wattrset(win, A_BOLD | A_REVERSE);
active_el = el;
}
p_x = 1;
p_x += u_utf8_curs_printw(parent_win, p_y, p_x, el->name);
mvwprintw(parent_win, p_y, p_x, "%*s", sz_x - p_x, "");
p_x += u_utf8_curs_printw(win, p_y, p_x, el->name, sz_x-1);
int pad = sz_x - p_x;
if (pad >= 0) {
mvwprintw(win, p_y, p_x, "%*s", pad, "");
}
if (cur_el_idx == fui->current_idx) {
wattroff(parent_win, A_BOLD | A_REVERSE);
wattroff(win, A_BOLD | A_REVERSE);
}
p_y++;
cur_el_idx++;
@@ -202,17 +237,16 @@ void w_fl_draw(w_ui_file_list_t *fui) {
*(fui->start) == NULL) {
bstring text = bfromStatic("[No data to show]");
for (; p_y < (sz_y_f / 2); p_y++) {
mvwprintw(parent_win, p_y, p_x, "%*s", sz_x - 1, "");
mvwprintw(win, p_y, p_x, "%*s", sz_x - 1, "");
}
p_len = (sz_x - text->slen) / 2;
mvwprintw(parent_win, p_y++, p_x, "%*s%s%*s", p_len, "", text->data, p_len,
"");
mvwprintw(win, p_y++, p_x, "%*s%s%*s", p_len, "", text->data, p_len, "");
for (; p_y < sz_y_f; p_y++) {
mvwprintw(parent_win, p_y, p_x, "%*s", sz_x - 1, "");
mvwprintw(win, p_y, p_x, "%*s", sz_x - 1, "");
}
} else {
for (; p_y < sz_y_f; p_y++) {
mvwprintw(parent_win, p_y, p_x, "%*s", sz_x - 1, "");
mvwprintw(win, p_y, p_x, "%*s", sz_x - 1, "");
}
}
@@ -222,7 +256,7 @@ void w_fl_draw(w_ui_file_list_t *fui) {
{
uint32_t p_y = 1;
p_x = 1;
WINDOW *i_win = *fui->info_win;
WINDOW *i_win = fui->win_info;
wclear(i_win);
/* Write to the right side the information about the file */
@@ -234,36 +268,40 @@ void w_fl_draw(w_ui_file_list_t *fui) {
mvwprintw(i_win, p_y++, p_x, "Owner: %s", active_el->owner);
if (active_el->description != NULL) {
mvwprintw(i_win, p_y++, p_x, "Description: ");
w_print_multiline_text(i_win, active_el->description, sz_x, p_y, p_x, 0);
w_print_multiline_text(i_win, active_el->description, sz_x, p_y, p_x,
0);
}
}
}
/* Search bar */
p_x = 1;
wattrset(parent_win, A_BOLD);
wattrset(win, A_BOLD);
if (fui->active_search) {
sprintf(p_info, "[search]: %s%n", fui->search_key->data, &p_len);
mvwprintw(parent_win, p_y, p_x, "%-*s", sz_x, p_info);
mvwprintw(win, p_y, p_x, "%-*s", sz_x, p_info);
curs_set(true);
wmove(parent_win, p_y, p_x + p_len);
wmove(win, p_y, p_x + p_len);
} else {
uint32_t l_pad = 0;
sprintf(p_info, "P: %u/%u F: %u L: %u%n", fui->current_page, fui->pages,
fui->current_count, fui->full_count, &p_len);
if (fui->search_key->slen > 0) {
wattrset(parent_win, A_REVERSE);
mvwprintw(parent_win, p_y, p_x, "[%s]", fui->search_key->data);
wattroff(parent_win, A_REVERSE);
wattrset(win, A_REVERSE);
mvwprintw(win, p_y, p_x, "[%s]", fui->search_key->data);
wattroff(win, A_REVERSE);
l_pad = fui->search_key->slen + 2;
mvwprintw(parent_win, p_y, p_x + l_pad, " %.*s", sz_x - l_pad, p_info);
mvwprintw(win, p_y, p_x + l_pad, " %.*s", sz_x - l_pad, p_info);
} else {
sprintf(p_info, "page: %u/%u files: %u left: %u%n", fui->current_page,
fui->pages, fui->current_count, fui->full_count, &p_len);
l_pad = (sz_x - p_len) / 2;
mvwprintw(parent_win, p_y, p_x, "%*s%s%*s", l_pad, "", p_info, l_pad, "");
if (!(l_pad % 2)) {
l_pad--;
}
mvwprintw(win, p_y, p_x, "%*s%s%*s", l_pad, "", p_info, l_pad, "");
}
}
wattroff(parent_win, A_BOLD);
wattroff(win, A_BOLD);
}
+4 -2
View File
@@ -4,6 +4,7 @@
#ifndef W_FILE_LIST_H
#define W_FILE_LIST_H
#include "app.h"
#include <bstrlib.h>
#include <stdint.h>
#include <widget_core.h>
@@ -18,14 +19,15 @@ typedef struct {
uint32_t pages;
uint32_t current_page;
uint32_t max_lines;
WINDOW *const *info_win;
WINDOW *win_info;
WINDOW *win_list;
bstring search_key;
bool activate_last;
bool active_search;
} w_ui_file_list_t;
void w_fl_draw(w_ui_file_list_t *fl_ui);
w_ui_file_list_t *w_fl_init(WINDOW **win, WINDOW *const *info_win);
w_ui_file_list_t *w_fl_init(w_app_t *app);
void w_fl_cb(w_cb_args_t *args);
void w_fl_rest(w_ui_file_list_t *fl_ui);
void w_fl_destroy(w_ui_file_list_t **fui);
+46 -17
View File
@@ -259,7 +259,7 @@ w_lfl_ui_t *w_lfl_init(WINDOW **win, w_t *w_parent) {
WINDOW *win_par = *(w_parent->w_parent->parent_win);
w_init(&(fl_ui->w), w_parent, win, "");
fl_ui->current_idx = 0;
fl_ui->info_win = NULL;
fl_ui->win_info = NULL;
fl_ui->d_path = NULL;
char *path = get_current_dir_name();
get_files_from_fs(fl_ui, path);
@@ -272,21 +272,47 @@ w_lfl_ui_t *w_lfl_init(WINDOW **win, w_t *w_parent) {
return fl_ui;
}
w_lfl_ui_t *w_lfl_init_win(WINDOW **win, WINDOW *const *info_win) {
w_lfl_ui_t *fl_ui = malloc(sizeof(w_lfl_ui_t));
w_init(&(fl_ui->w), NULL, win, "");
fl_ui->current_idx = 0;
fl_ui->info_win = NULL;
fl_ui->d_path = NULL;
static void w_lfl_cb_refresh(void *data) {
w_app_t *app = (w_app_t *)data;
if (app->main_ui.type != mw_fl_local) {
return;
}
w_lfl_ui_t *fui = app->main_ui.ui;
wnoutrefresh(fui->win_list);
wnoutrefresh(fui->win_info);
}
w_lfl_ui_t *w_lfl_init_win(w_app_t *app) {
w_lfl_ui_t *fui = malloc(sizeof(w_lfl_ui_t));
app->main_ui.ui = fui;
app->main_ui.type = mw_fl_local;
app->main_ui.cb_refresh = w_lfl_cb_refresh;
w_init(&(fui->w), NULL, &(app->win), "");
fui->current_idx = 0;
fui->win_info = NULL;
fui->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 = w_lfl_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;
get_files_from_fs(fui, path);
fui->current = fui->start;
fui->w.callback = w_lfl_cb;
fui->w.sz.x = getmaxx(app->win);
fui->w.sz.y = getmaxy(app->win);
fui->rows_num = 0; /* detects on the first draw */
fui->cur_page = 1;
fui->w.parent_win = &(app->win);
/* * INIT UI * */
/* define the width for each sub window */
int32_t left_w_x = app->coordinates.max_x / 10 * 4;
int32_t right_w_x = app->coordinates.max_x - left_w_x - 2;
/* create the list window */
fui->win_list = newwin(app->coordinates.max_y - 4, left_w_x, 2, 1);
/* create the action window */
fui->win_info =
newwin(app->coordinates.max_y - 4, right_w_x, 2, left_w_x + 1);
return fui;
}
void w_lfl_reset(w_lfl_ui_t *fl_ui) { fl_ui->current_idx = 0; }
@@ -294,7 +320,7 @@ void w_lfl_reset(w_lfl_ui_t *fl_ui) { fl_ui->current_idx = 0; }
void w_lfl_draw(w_lfl_ui_t *fui) {
int32_t sz_y, sz_x;
int32_t p_y, p_x;
WINDOW *win = *(fui->w.parent_win);
WINDOW *win = fui->win_list;
getmaxyx(win, sz_y, sz_x);
int32_t sz_y_f = sz_y - 2; // actual size (without box)
int32_t sz_x_f = sz_x - 2; // actual size (without box)
@@ -309,6 +335,9 @@ void w_lfl_draw(w_lfl_ui_t *fui) {
p_y -= fui->current_idx - sz_y_f + 2;
}
box(fui->win_list, 0, 0);
box(fui->win_info, 0, 0);
wattrset(win, A_REVERSE); /* Match with modal background */
do {
if (p_y < 1) {
@@ -319,7 +348,7 @@ void w_lfl_draw(w_lfl_ui_t *fui) {
wattrset(win, COLOR_PAIR(3) | A_BOLD | A_REVERSE);
}
p_x = 1;
p_x += u_utf8_curs_printw(win, p_y, p_x, el->name);
p_x += u_utf8_curs_printw(win, p_y, p_x, el->name, sz_x);
mvwprintw(win, p_y, p_x, "%*s", sz_x_f - p_x, "");
if (el == fui->current) {
wattroff(win, COLOR_PAIR(3) | A_BOLD);
+4 -2
View File
@@ -4,6 +4,7 @@
#ifndef W_LFL_H /* LOCAL FILE LIST */
#define W_LFL_H
#include "app.h"
#include <widget_core.h>
#include <ncursesw/ncurses.h>
#include <stdint.h>
@@ -27,7 +28,8 @@ typedef struct {
int32_t cur_page;
int32_t pages_num;
size_t files_num;
WINDOW *const* info_win;
WINDOW *win_info;
WINDOW *win_list;
char *d_path;
} w_lfl_ui_t;
@@ -36,6 +38,6 @@ void w_lfl_destroy(w_lfl_ui_t *fl_ui);
void w_lfl_cb(w_cb_args_t *args);
void w_lfl_reset(w_lfl_ui_t *fl_ui);
w_lfl_ui_t *w_lfl_init(WINDOW **win, w_t *w_parent);
w_lfl_ui_t *w_lfl_init_win(WINDOW **win, WINDOW *const *info_win);
w_lfl_ui_t *w_lfl_init_win(w_app_t *app);
#endif
+3 -3
View File
@@ -80,11 +80,11 @@ void PRINT_TEXT(WINDOW *win, char *l_buf, char *text, int64_t i,
l_buf[c_line_len] = '\0';
utf8len = u_utf8_code_points_count(l_buf);
if ((attrs & PMT_ALIGN_CENTER) == PMT_ALIGN_CENTER) {
u_utf8_curs_printw(win, line_v_pos, (win_width - utf8len) / 2, l_buf);
u_utf8_curs_printw(win, line_v_pos, (win_width - utf8len) / 2, l_buf, -1);
} else if (attrs & PMT_POS_CENTER) {
u_utf8_curs_printw(win, line_v_pos, (win_width - max_line_len) / 2, l_buf);
u_utf8_curs_printw(win, line_v_pos, (win_width - max_line_len) / 2, l_buf, -1);
} else {
u_utf8_curs_printw(win, line_v_pos, x, l_buf);
u_utf8_curs_printw(win, line_v_pos, x, l_buf, -1);
}
}