UI: finishes callback processing in main_window, key input callbacks and draw bottom bar

This commit is contained in:
2026-04-20 15:23:12 +03:00
parent 173bd3000d
commit ee2bccc5c8
15 changed files with 115 additions and 62 deletions
+2 -2
View File
@@ -26,7 +26,7 @@ void connect_to_server(w_app_t *app) {
w_app_destroy(app, 2); w_app_destroy(app, 2);
} }
app->params->is_connected = TRUE; app->params->is_connected = TRUE;
w_app_print_bars(app); w_app_draw_bars(app);
} }
void init_params(params_t *params) { void init_params(params_t *params) {
@@ -59,7 +59,7 @@ void get_ip_port(params_t *params, char *ip, char *port) {
void close_session(int sd) { close(sd); } void close_session(int sd) { close(sd); }
int init_client() { int init_client(void) {
int res; int res;
int cs = socket(AF_INET, SOCK_STREAM, 0); int cs = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in client; struct sockaddr_in client;
+1
View File
@@ -95,6 +95,7 @@ typedef struct main_window {
int32_t (*cb_b_press) (void *app, void *args); /* callback on button press */ int32_t (*cb_b_press) (void *app, void *args); /* callback on button press */
void (*cb_refresh) (void *app); /* refresh callback */ void (*cb_refresh) (void *app); /* refresh callback */
struct action_key *b_keys; struct action_key *b_keys;
int32_t b_keys_len;
} main_window_t; } main_window_t;
typedef struct query_args { typedef struct query_args {
+5 -4
View File
@@ -1,5 +1,6 @@
#include "main_window.h" #include "main_window.h"
#include "fs_file_list.h" #include "fs_file_list.h"
#include "server.h"
void main_window_set(w_app_t *app, enum main_window_type type) { void main_window_set(w_app_t *app, enum main_window_type type) {
if (app->main_ui.ui != NULL) { if (app->main_ui.ui != NULL) {
@@ -8,12 +9,11 @@ void main_window_set(w_app_t *app, enum main_window_type type) {
app->main_ui.type = type; app->main_ui.type = type;
switch (type) { switch (type) {
case mw_fl_server: case mw_fl_server:
app->main_ui.ui = w_fl_init(app); w_fl_init(app);
app->active_callback = w_fl_cb; app->query_args->state = S_FILE_LIST;
break; break;
case mw_fl_local: case mw_fl_local:
app->main_ui.ui = w_lfl_init_win(app); w_lfl_init_win(app);
app->active_callback = w_lfl_cb;
break; break;
case mw_f_desc: case mw_f_desc:
break; break;
@@ -33,6 +33,7 @@ void main_window_draw(w_app_t *app) {
case mw_f_desc: case mw_f_desc:
break; break;
} }
w_app_draw_bbar(app);
} }
void main_window_destroy(w_app_t *app) { void main_window_destroy(w_app_t *app) {
+1 -1
View File
@@ -35,7 +35,7 @@ void init_login_credentials_modal_cb(w_cb_args_t *args) {
server_send_string(app->query_args, app->params->uname); server_send_string(app->query_args, app->params->uname);
app->query_args->state = S_WAIT_SERVER; app->query_args->state = S_WAIT_SERVER;
d->needs_destroy = true; d->needs_destroy = true;
w_app_print_bars(app); w_app_draw_bars(app);
break; break;
case 2: case 2:
app->query_args->state = S_ASK_LOGIN_TYPE; app->query_args->state = S_ASK_LOGIN_TYPE;
+1 -1
View File
@@ -29,7 +29,7 @@ void login_modal_option_cb(w_cb_args_t *args) {
strcpy(app->params->uname, "anonymous"); strcpy(app->params->uname, "anonymous");
server_send_string(app->query_args, app->params->uname); server_send_string(app->query_args, app->params->uname);
app->query_args->state = S_WAIT_SERVER; app->query_args->state = S_WAIT_SERVER;
w_app_print_bars(app); w_app_draw_bars(app);
break; break;
case 2: case 2:
d->needs_destroy = true; d->needs_destroy = true;
+13 -6
View File
@@ -39,9 +39,9 @@ int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args);
#define EXIT_APP(message, app, exit_code) \ #define EXIT_APP(message, app, exit_code) \
{ \ { \
w_alert(message); \ w_alert(message); \
close_session(app->params->sd); \ close_session(app->params->sd); \
w_app_destroy(app, exit_code); \ w_app_destroy(app, exit_code); \
} }
void query_loop(w_app_t *app) { void query_loop(w_app_t *app) {
@@ -112,8 +112,14 @@ void query_loop(w_app_t *app) {
} }
if (FD_ISSET(STDIN_FILENO, &readfds)) { if (FD_ISSET(STDIN_FILENO, &readfds)) {
if (ERR == process_user_input(app, &d_args)) { if (app->main_ui.cb_b_press != NULL) {
EXIT_APP("*** error while processing user input ***", app, 4) if (ERR == app->main_ui.cb_b_press(app, &d_args)) {
EXIT_APP("*** error while processing user input ***", app, 4)
}
} else {
if (ERR == process_user_input(app, &d_args)) {
EXIT_APP("*** error while processing user input ***", app, 4)
}
} }
} }
} }
@@ -131,8 +137,9 @@ void wait_register(query_args_t *q_args) {
int upload_confirm_cb(w_app_t *app, char *query, int q_len) { int upload_confirm_cb(w_app_t *app, char *query, int q_len) {
if (!strncmp("finished\n", query, sizeof("finished\n") - 1)) { if (!strncmp("finished\n", query, sizeof("finished\n") - 1)) {
w_ui_file_list_t *fui = (w_ui_file_list_t *)app->query_args->main_ui->ui; w_ui_file_list_t *fui = (w_ui_file_list_t *)app->query_args->main_ui->ui;
w_notification("File upload", dc_normal, "File %s is uploaded to the server!", w_notification("File upload", dc_normal,
app->query_args->file->name); "File %s is uploaded to the server!",
app->query_args->file->name);
clear_file_in_query(app->query_args); clear_file_in_query(app->query_args);
app->query_args->state = S_FILE_LIST; app->query_args->state = S_FILE_LIST;
app->modal.needs_destroy = true; app->modal.needs_destroy = true;
+1 -1
View File
@@ -47,7 +47,7 @@ int server_wait_reg_confirm_cb(w_app_t *app, char *line, int l_len) {
"Welcome, %s!", "Welcome, %s!",
app->params->uname); app->params->uname);
w_notification("Registration", dc_normal, query); w_notification("Registration", dc_normal, query);
w_app_print_bars(app); w_app_draw_bars(app);
return 0; return 0;
} else { } else {
q_args->state = S_ASK_REGISTER; q_args->state = S_ASK_REGISTER;
+30 -24
View File
@@ -33,11 +33,9 @@ w_app_t *w_app_init() {
_app->modal.win = NULL; _app->modal.win = NULL;
_app->modal.is_initiated = 0; _app->modal.is_initiated = 0;
/* default callback */ /* print top and bottom bars */
_app->active_callback = w_fl_cb; _app->main_ui.b_keys_len = 0;
w_app_draw_bars(_app);
/* print decorative bars */
w_app_print_bars(_app);
/* here goes box borders */ /* here goes box borders */
w_app_draw_borders(_app); w_app_draw_borders(_app);
@@ -96,7 +94,9 @@ int64_t print_bottom_menu_option(WINDOW *win, char *key, char *title, int64_t y,
return key_len + title_len; return key_len + title_len;
} }
void w_app_print_bars(w_app_t *app) { void w_app_draw_bbar(w_app_t *app);
void w_app_draw_bars(w_app_t *app) {
char top_text[64] = "Hello!"; char top_text[64] = "Hello!";
wattrset(app->win, A_REVERSE); wattrset(app->win, A_REVERSE);
@@ -116,32 +116,38 @@ void w_app_print_bars(w_app_t *app) {
ip_addr[1], ip_addr[2], ip_addr[3], app->params->uname); ip_addr[1], ip_addr[2], ip_addr[3], app->params->uname);
} }
mvwprintw(app->win, 1, 2, "%s", top_text); mvwprintw(app->win, 1, 2, "%s", top_text);
wattroff(app->win, A_REVERSE);
/* add content to the bottom bar */ /* add content to the bottom bar */
if (app->main_ui.b_keys_len > 0) {
w_app_draw_bbar(app);
}
}
struct action_key action_keys[] = { void w_app_draw_bbar(w_app_t *app) {
{.key = "F1", .title = "Help"}, wattrset(app->win, A_REVERSE);
{.key = "U", .title = "Upload"}, int t_margin = 0; /* tab margin */
{.key = "S", .title = "Search"}, int c_size =
{.key = "F9", .title = "Quit"}, app->coordinates.max_x / app->main_ui.b_keys_len; /* column size */
};
int t_margin = 0; /* tab margin */
int c_size = app->coordinates.max_x / 4; /* column size */
int incr_last = app->coordinates.max_x % int incr_last = app->coordinates.max_x %
4; /* increment size fo the last element (fill empty space) */ app->main_ui.b_keys_len; /* increment size fo the last element
(fill empty space) */
for (int i = 0; i < 3; i++) { struct action_key *k = NULL;
struct action_key *k = &action_keys[i]; if (app->main_ui.b_keys_len > 1) {
t_margin += for (int i = 0; i < app->main_ui.b_keys_len - 1; i++) {
print_bottom_menu_option(app->win, k->key, k->title, k = &(app->main_ui.b_keys)[i];
app->coordinates.cur_y - 2, t_margin, c_size); t_margin += print_bottom_menu_option(app->win, k->key, k->title,
app->coordinates.cur_y - 2, t_margin,
c_size);
}
} }
t_margin += print_bottom_menu_option( k = &(app->main_ui.b_keys)[app->main_ui.b_keys_len - 1];
app->win, action_keys[3].key, action_keys[3].title,
app->coordinates.cur_y - 2, t_margin, c_size + incr_last);
t_margin += print_bottom_menu_option(app->win, k->key, k->title,
app->coordinates.cur_y - 2, t_margin,
c_size + incr_last);
wattroff(app->win, A_REVERSE); wattroff(app->win, A_REVERSE);
} }
+2 -1
View File
@@ -31,8 +31,9 @@ w_app_t *w_app_init(void);
void w_app_init_nc(void); void w_app_init_nc(void);
void w_app_destroy(w_app_t *app, int32_t exit_code); void w_app_destroy(w_app_t *app, int32_t exit_code);
void w_app_draw_borders(w_app_t *app); void w_app_draw_borders(w_app_t *app);
void w_app_print_bars(w_app_t *app); void w_app_draw_bars(w_app_t *app);
void w_app_refresh(w_app_t *app); void w_app_refresh(w_app_t *app);
void w_app_draw_modal(w_app_t *app); void w_app_draw_modal(w_app_t *app);
void w_app_draw_bbar(w_app_t *app);
#endif // N_APP_H #endif // N_APP_H
+1 -1
View File
@@ -319,7 +319,7 @@ void w_dialogue_destroy(w_dialogue_t *d, void *_app) {
d->win = NULL; d->win = NULL;
d->is_initiated = 0; d->is_initiated = 0;
d->needs_destroy = false; d->needs_destroy = false;
app->active_callback = w_fl_cb; app->active_callback = (w_cb_t) app->main_ui.cb_b_press;
app->query_args->active_dialogue = NULL; app->query_args->active_dialogue = NULL;
u_d_arr_ptr_free(&(d->id_map)); u_d_arr_ptr_free(&(d->id_map));
w_app_refresh(app); w_app_refresh(app);
+7 -6
View File
@@ -19,7 +19,7 @@
void w_fl_reset(w_ui_file_list_t *fl_ui); void w_fl_reset(w_ui_file_list_t *fl_ui);
void w_fl_cb(w_cb_args_t *args) { static void w_fl_cb(w_cb_args_t *args) {
w_app_t *app = args->app; w_app_t *app = args->app;
w_ui_file_list_t *fui = app->query_args->main_ui->ui; w_ui_file_list_t *fui = app->query_args->main_ui->ui;
int32_t key = *((int32_t *)args->data); int32_t key = *((int32_t *)args->data);
@@ -133,7 +133,7 @@ static struct action_key action_keys[] = {
{.key = "F9", .title = "Quit", .code = KEY_F(9)}, {.key = "F9", .title = "Quit", .code = KEY_F(9)},
}; };
int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args) { static int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args) {
int32_t c; int32_t c;
w_ui_file_list_t *fui = (w_ui_file_list_t *)app->query_args->main_ui->ui; w_ui_file_list_t *fui = (w_ui_file_list_t *)app->query_args->main_ui->ui;
c = wgetch(app->win); c = wgetch(app->win);
@@ -143,8 +143,7 @@ int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args) {
return OK; return OK;
case 'U': case 'U':
case 'u': case 'u':
if (!app->modal.is_initiated && !fui->active_search && if (!app->modal.is_initiated && !fui->active_search) {
app->main_ui.type != mw_fl_local) {
/* app->query_args->state = S_UPLOAD_FILE_SELECT; */ /* app->query_args->state = S_UPLOAD_FILE_SELECT; */
main_window_set(app, mw_fl_local); main_window_set(app, mw_fl_local);
main_window_draw(app); main_window_draw(app);
@@ -166,13 +165,15 @@ int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args) {
return OK; return OK;
} }
w_ui_file_list_t *w_fl_init(w_app_t *app) { void *w_fl_init(w_app_t *app) {
w_ui_file_list_t *fui = malloc(sizeof(w_ui_file_list_t)); w_ui_file_list_t *fui = malloc(sizeof(w_ui_file_list_t));
app->main_ui.ui = fui; app->main_ui.ui = fui;
app->main_ui.type = mw_fl_server; app->main_ui.type = mw_fl_server;
app->main_ui.cb_refresh = w_fl_cb_refresh; app->main_ui.cb_refresh = w_fl_cb_refresh;
app->main_ui.b_keys = action_keys; app->main_ui.b_keys = action_keys;
app->main_ui.cb_b_press = process_user_input; app->main_ui.b_keys_len = 4;
app->main_ui.cb_b_press = (w_cb_press_t) process_user_input;
app->active_callback = w_fl_cb;
w_init(&(fui->w), NULL, &(app->win), ""); w_init(&(fui->w), NULL, &(app->win), "");
WINDOW *win_parent = app->win; WINDOW *win_parent = app->win;
fui->current_idx = 0; fui->current_idx = 0;
+1 -2
View File
@@ -27,8 +27,7 @@ typedef struct {
} w_ui_file_list_t; } w_ui_file_list_t;
void w_fl_draw(w_ui_file_list_t *fl_ui); void w_fl_draw(w_ui_file_list_t *fl_ui);
w_ui_file_list_t *w_fl_init(w_app_t *app); void *w_fl_init(w_app_t *app);
void w_fl_cb(w_cb_args_t *args);
void w_fl_reset(w_ui_file_list_t *fl_ui); void w_fl_reset(w_ui_file_list_t *fl_ui);
void w_fl_destroy(w_ui_file_list_t **fui); void w_fl_destroy(w_ui_file_list_t **fui);
+48 -11
View File
@@ -14,12 +14,13 @@
#include <unistd.h> #include <unistd.h>
#include <utils.h> #include <utils.h>
#include "../main_window.h"
#include "../server.h"
#include "alert.h" #include "alert.h"
#include "fs_file_list.h" #include "fs_file_list.h"
#include "widget_core.h" #include "widget_core.h"
void w_fl_reset(w_lfl_ui_t *fl_ui); // void w_fl_reset(w_lfl_ui_t *fl_ui);
struct fl_args { struct fl_args {
char *name; char *name;
@@ -186,7 +187,7 @@ void open_selected_item(w_lfl_ui_t *fui, w_cbrp_data *resp_data) {
/* next page */ /* next page */
void page_next(w_lfl_ui_t *fui) { void page_next(w_lfl_ui_t *fui) {
int count = fui->rows_num; int count = fui->max_lines;
w_lfl_item_t *n_page_item = fui->page_start; w_lfl_item_t *n_page_item = fui->page_start;
if (fui->cur_page < fui->pages_num) { if (fui->cur_page < fui->pages_num) {
for (; count; count--) { for (; count; count--) {
@@ -202,7 +203,7 @@ void page_next(w_lfl_ui_t *fui) {
/* previous page */ /* previous page */
void page_previous(w_lfl_ui_t *fui) { void page_previous(w_lfl_ui_t *fui) {
int count = fui->rows_num; int count = fui->max_lines;
w_lfl_item_t *n_page_item = fui->page_start; w_lfl_item_t *n_page_item = fui->page_start;
if (fui->cur_page > 1) { if (fui->cur_page > 1) {
for (; count; count--) { for (; count; count--) {
@@ -216,13 +217,13 @@ void page_previous(w_lfl_ui_t *fui) {
w_lfl_draw(fui); w_lfl_draw(fui);
} }
void w_lfl_cb(w_cb_args_t *args) { static void w_lfl_cb(w_cb_args_t *args) {
w_lfl_ui_t *fui = args->element; w_lfl_ui_t *fui = args->element;
int32_t key = *((int32_t *)args->data); int32_t key = *((int32_t *)args->data);
switch (key) { switch (key) {
case KEY_DOWN: case KEY_DOWN:
if (fui->current->next != NULL) { if (fui->current->next != NULL) {
if (fui->current_idx < fui->rows_num - 1) { if (fui->current_idx < fui->max_lines - 1) {
fui->current = fui->current->next; fui->current = fui->current->next;
fui->current_idx++; fui->current_idx++;
} else { } else {
@@ -269,7 +270,7 @@ w_lfl_ui_t *w_lfl_init(WINDOW **win, w_t *w_parent) {
fl_ui->w.callback = w_lfl_cb; fl_ui->w.callback = w_lfl_cb;
fl_ui->w.sz.x = getmaxx(win_par) / 10 * 8; fl_ui->w.sz.x = getmaxx(win_par) / 10 * 8;
fl_ui->w.sz.y = getmaxy(win_par) / 10 * 8; fl_ui->w.sz.y = getmaxy(win_par) / 10 * 8;
fl_ui->rows_num = 0; /* detects on the first draw */ fl_ui->max_lines = 0; /* detects on the first draw */
fl_ui->cur_page = 1; fl_ui->cur_page = 1;
return fl_ui; return fl_ui;
} }
@@ -284,11 +285,47 @@ static void w_lfl_cb_refresh(void *data) {
wnoutrefresh(fui->win_info); wnoutrefresh(fui->win_info);
} }
static struct action_key action_keys[] = {
{.key = "Esc", .title = "Back", .code = '\33'},
{.key = "F9", .title = "Quit", .code = KEY_F(9)},
};
static int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args) {
int32_t c;
w_lfl_ui_t *fui = (w_lfl_ui_t *)app->query_args->main_ui->ui;
c = wgetch(app->win);
switch (c) {
case KEY_F(9):
w_app_destroy(app, 0);
return OK;
case 'D':
case 'd':
case '\33': /* ESC key */
if (!app->modal.is_initiated) {
main_window_set(app, mw_fl_server);
main_window_draw(app);
server_send_string(app->query_args, "file list %u %u\n", fui->max_lines,
1);
d_args->element = app->main_ui.ui;
break;
}
default:
d_args->data = (void *)&c;
app->active_callback(d_args);
break;
}
return OK;
}
w_lfl_ui_t *w_lfl_init_win(w_app_t *app) { w_lfl_ui_t *w_lfl_init_win(w_app_t *app) {
w_lfl_ui_t *fui = malloc(sizeof(w_lfl_ui_t)); w_lfl_ui_t *fui = malloc(sizeof(w_lfl_ui_t));
app->main_ui.ui = fui; app->main_ui.ui = fui;
app->main_ui.type = mw_fl_local; app->main_ui.type = mw_fl_local;
app->main_ui.cb_refresh = w_lfl_cb_refresh; app->main_ui.cb_refresh = w_lfl_cb_refresh;
app->main_ui.b_keys = action_keys;
app->main_ui.b_keys_len = 2;
app->main_ui.cb_b_press = (w_cb_press_t)process_user_input;
app->active_callback = w_lfl_cb;
w_init(&(fui->w), NULL, &(app->win), ""); w_init(&(fui->w), NULL, &(app->win), "");
fui->current_idx = 0; fui->current_idx = 0;
fui->win_info = NULL; fui->win_info = NULL;
@@ -299,7 +336,7 @@ w_lfl_ui_t *w_lfl_init_win(w_app_t *app) {
fui->w.callback = w_lfl_cb; fui->w.callback = w_lfl_cb;
fui->w.sz.x = getmaxx(app->win); fui->w.sz.x = getmaxx(app->win);
fui->w.sz.y = getmaxy(app->win); fui->w.sz.y = getmaxy(app->win);
fui->rows_num = 0; /* detects on the first draw */ fui->max_lines = 0; /* detects on the first draw */
fui->cur_page = 1; fui->cur_page = 1;
fui->w.parent_win = &(app->win); fui->w.parent_win = &(app->win);
/* * INIT UI * */ /* * INIT UI * */
@@ -326,9 +363,9 @@ void w_lfl_draw(w_lfl_ui_t *fui) {
getmaxyx(win, sz_y, sz_x); getmaxyx(win, sz_y, sz_x);
int32_t sz_y_f = sz_y - 2; // actual size (without box) int32_t sz_y_f = sz_y - 2; // actual size (without box)
int32_t sz_x_f = sz_x - 2; // actual size (without box) int32_t sz_x_f = sz_x - 2; // actual size (without box)
fui->rows_num = sz_y_f; fui->max_lines = sz_y_f;
fui->pages_num = fui->files_num / fui->rows_num + fui->pages_num = fui->files_num / fui->max_lines +
(fui->files_num % fui->rows_num > 0 ? 1 : 0); (fui->files_num % fui->max_lines > 0 ? 1 : 0);
p_y = 1; p_y = 1;
p_x = 1; p_x = 1;
w_lfl_item_t *el = fui->page_start; w_lfl_item_t *el = fui->page_start;
+1 -2
View File
@@ -24,7 +24,7 @@ typedef struct {
w_lfl_item_t *start; w_lfl_item_t *start;
w_lfl_item_t *page_start; w_lfl_item_t *page_start;
int32_t current_idx; int32_t current_idx;
int32_t rows_num; int32_t max_lines;
int32_t cur_page; int32_t cur_page;
int32_t pages_num; int32_t pages_num;
size_t files_num; size_t files_num;
@@ -35,7 +35,6 @@ typedef struct {
void w_lfl_draw(w_lfl_ui_t *fl_ui); void w_lfl_draw(w_lfl_ui_t *fl_ui);
void w_lfl_destroy(w_lfl_ui_t *fl_ui); 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); 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(WINDOW **win, w_t *w_parent);
w_lfl_ui_t *w_lfl_init_win(w_app_t *app); w_lfl_ui_t *w_lfl_init_win(w_app_t *app);
+1
View File
@@ -73,6 +73,7 @@ typedef struct {
} w_cb_args_t; } w_cb_args_t;
typedef void (*w_cb_t)(w_cb_args_t *args); typedef void (*w_cb_t)(w_cb_args_t *args);
typedef int32_t (*w_cb_press_t)(void *app, void *data);
typedef struct w_t { typedef struct w_t {
int64_t id; int64_t id;