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);
}
app->params->is_connected = TRUE;
w_app_print_bars(app);
w_app_draw_bars(app);
}
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); }
int init_client() {
int init_client(void) {
int res;
int cs = socket(AF_INET, SOCK_STREAM, 0);
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 */
void (*cb_refresh) (void *app); /* refresh callback */
struct action_key *b_keys;
int32_t b_keys_len;
} main_window_t;
typedef struct query_args {
+5 -4
View File
@@ -1,5 +1,6 @@
#include "main_window.h"
#include "fs_file_list.h"
#include "server.h"
void main_window_set(w_app_t *app, enum main_window_type type) {
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;
switch (type) {
case mw_fl_server:
app->main_ui.ui = w_fl_init(app);
app->active_callback = w_fl_cb;
w_fl_init(app);
app->query_args->state = S_FILE_LIST;
break;
case mw_fl_local:
app->main_ui.ui = w_lfl_init_win(app);
app->active_callback = w_lfl_cb;
w_lfl_init_win(app);
break;
case mw_f_desc:
break;
@@ -33,6 +33,7 @@ void main_window_draw(w_app_t *app) {
case mw_f_desc:
break;
}
w_app_draw_bbar(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);
app->query_args->state = S_WAIT_SERVER;
d->needs_destroy = true;
w_app_print_bars(app);
w_app_draw_bars(app);
break;
case 2:
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");
server_send_string(app->query_args, app->params->uname);
app->query_args->state = S_WAIT_SERVER;
w_app_print_bars(app);
w_app_draw_bars(app);
break;
case 2:
d->needs_destroy = true;
+8 -1
View File
@@ -112,11 +112,17 @@ void query_loop(w_app_t *app) {
}
if (FD_ISSET(STDIN_FILENO, &readfds)) {
if (app->main_ui.cb_b_press != NULL) {
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)
}
}
}
}
}
void wait_register(query_args_t *q_args) {
@@ -131,7 +137,8 @@ void wait_register(query_args_t *q_args) {
int upload_confirm_cb(w_app_t *app, char *query, int q_len) {
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_notification("File upload", dc_normal, "File %s is uploaded to the server!",
w_notification("File upload", dc_normal,
"File %s is uploaded to the server!",
app->query_args->file->name);
clear_file_in_query(app->query_args);
app->query_args->state = S_FILE_LIST;
+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!",
app->params->uname);
w_notification("Registration", dc_normal, query);
w_app_print_bars(app);
w_app_draw_bars(app);
return 0;
} else {
q_args->state = S_ASK_REGISTER;
+29 -23
View File
@@ -33,11 +33,9 @@ w_app_t *w_app_init() {
_app->modal.win = NULL;
_app->modal.is_initiated = 0;
/* default callback */
_app->active_callback = w_fl_cb;
/* print decorative bars */
w_app_print_bars(_app);
/* print top and bottom bars */
_app->main_ui.b_keys_len = 0;
w_app_draw_bars(_app);
/* here goes box borders */
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;
}
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!";
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);
}
mvwprintw(app->win, 1, 2, "%s", top_text);
wattroff(app->win, A_REVERSE);
/* add content to the bottom bar */
if (app->main_ui.b_keys_len > 0) {
w_app_draw_bbar(app);
}
}
struct action_key action_keys[] = {
{.key = "F1", .title = "Help"},
{.key = "U", .title = "Upload"},
{.key = "S", .title = "Search"},
{.key = "F9", .title = "Quit"},
};
void w_app_draw_bbar(w_app_t *app) {
wattrset(app->win, A_REVERSE);
int t_margin = 0; /* tab margin */
int c_size = app->coordinates.max_x / 4; /* column size */
int c_size =
app->coordinates.max_x / app->main_ui.b_keys_len; /* column size */
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 = &action_keys[i];
t_margin +=
print_bottom_menu_option(app->win, k->key, k->title,
app->coordinates.cur_y - 2, t_margin, c_size);
struct action_key *k = NULL;
if (app->main_ui.b_keys_len > 1) {
for (int i = 0; i < app->main_ui.b_keys_len - 1; i++) {
k = &(app->main_ui.b_keys)[i];
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(
app->win, action_keys[3].key, action_keys[3].title,
app->coordinates.cur_y - 2, t_margin, c_size + incr_last);
k = &(app->main_ui.b_keys)[app->main_ui.b_keys_len - 1];
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);
}
+2 -1
View File
@@ -31,8 +31,9 @@ w_app_t *w_app_init(void);
void w_app_init_nc(void);
void w_app_destroy(w_app_t *app, int32_t exit_code);
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_draw_modal(w_app_t *app);
void w_app_draw_bbar(w_app_t *app);
#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->is_initiated = 0;
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;
u_d_arr_ptr_free(&(d->id_map));
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_cb(w_cb_args_t *args) {
static void w_fl_cb(w_cb_args_t *args) {
w_app_t *app = args->app;
w_ui_file_list_t *fui = app->query_args->main_ui->ui;
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)},
};
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;
w_ui_file_list_t *fui = (w_ui_file_list_t *)app->query_args->main_ui->ui;
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;
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->query_args->state = S_UPLOAD_FILE_SELECT; */
main_window_set(app, mw_fl_local);
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;
}
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));
app->main_ui.ui = fui;
app->main_ui.type = mw_fl_server;
app->main_ui.cb_refresh = w_fl_cb_refresh;
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), "");
WINDOW *win_parent = app->win;
fui->current_idx = 0;
+1 -2
View File
@@ -27,8 +27,7 @@ typedef struct {
} w_ui_file_list_t;
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_cb(w_cb_args_t *args);
void *w_fl_init(w_app_t *app);
void w_fl_reset(w_ui_file_list_t *fl_ui);
void w_fl_destroy(w_ui_file_list_t **fui);
+48 -11
View File
@@ -14,12 +14,13 @@
#include <unistd.h>
#include <utils.h>
#include "../main_window.h"
#include "../server.h"
#include "alert.h"
#include "fs_file_list.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 {
char *name;
@@ -186,7 +187,7 @@ void open_selected_item(w_lfl_ui_t *fui, w_cbrp_data *resp_data) {
/* next page */
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;
if (fui->cur_page < fui->pages_num) {
for (; count; count--) {
@@ -202,7 +203,7 @@ void page_next(w_lfl_ui_t *fui) {
/* previous page */
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;
if (fui->cur_page > 1) {
for (; count; count--) {
@@ -216,13 +217,13 @@ void page_previous(w_lfl_ui_t *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;
int32_t key = *((int32_t *)args->data);
switch (key) {
case KEY_DOWN:
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_idx++;
} 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.sz.x = getmaxx(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;
return fl_ui;
}
@@ -284,11 +285,47 @@ static void w_lfl_cb_refresh(void *data) {
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 *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;
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), "");
fui->current_idx = 0;
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.sz.x = getmaxx(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->w.parent_win = &(app->win);
/* * INIT UI * */
@@ -326,9 +363,9 @@ void w_lfl_draw(w_lfl_ui_t *fui) {
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)
fui->rows_num = sz_y_f;
fui->pages_num = fui->files_num / fui->rows_num +
(fui->files_num % fui->rows_num > 0 ? 1 : 0);
fui->max_lines = sz_y_f;
fui->pages_num = fui->files_num / fui->max_lines +
(fui->files_num % fui->max_lines > 0 ? 1 : 0);
p_y = 1;
p_x = 1;
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 *page_start;
int32_t current_idx;
int32_t rows_num;
int32_t max_lines;
int32_t cur_page;
int32_t pages_num;
size_t files_num;
@@ -35,7 +35,6 @@ typedef struct {
void w_lfl_draw(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);
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);
+1
View File
@@ -73,6 +73,7 @@ typedef struct {
} w_cb_args_t;
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 {
int64_t id;