R: changes name convention on objective elements

This commit is contained in:
2026-04-06 15:02:20 +03:00
parent 707087b8fe
commit 2414abbdcb
59 changed files with 643 additions and 638 deletions
+18 -1
View File
@@ -1,7 +1,7 @@
# Bulletin Board System (Client Side)
This is my sandbox project. I made it test and develop my programming skills. Maybe one day it become a mature and production-ready project.
![File upload](src/contents/img/zbss-client-cli_1.png)
![File upload](contents/img/zbss-client-cli_1.png)
## Setup
1. Create necessary file structure by running `$ ./setup.sh`.
@@ -9,3 +9,20 @@ It will create all necessary file structure in order to run the program correctl
2. Build the binary running `$ make` or `$ make bbs-client`
3. Run it by `$ make run`
## Develop
### Name conventions:
For objective elements like UI, there is a following name convention:
`b_element_action`, where:
* `b` stands for which block does the function belongs to;
* `element` - the element name;
* `action` - an action performed with the element;
There are 3 type of blocks available yet:
* `w`: widget
* `m`: modal
* `u`: utility

Before

Width:  |  Height:  |  Size: 285 KiB

After

Width:  |  Height:  |  Size: 285 KiB

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 208 KiB

+3 -3
View File
@@ -15,7 +15,7 @@
#include <termios.h>
#include <unistd.h>
void connect_to_server(app_t *app) {
void connect_to_server(w_app_t *app) {
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = app->params->addr;
@@ -23,10 +23,10 @@ void connect_to_server(app_t *app) {
if (-1 ==
connect(app->params->sd, (struct sockaddr *)&server, sizeof(server))) {
perror("connect");
destroy_app(app, 2);
w_app_destroy(app, 2);
}
app->params->is_connected = TRUE;
print_bars(app);
w_app_print_bars(app);
}
void init_params(params_t *params) {
+1 -1
View File
@@ -6,7 +6,7 @@
#include "main.h"
#include <widget.h>
void connect_to_server(app_t *params);
void connect_to_server(w_app_t *params);
void init_params(params_t *restrict);
void clear_params(params_t *params);
void get_ip_port(params_t *params, char *ip, char *port);
+13 -13
View File
@@ -5,43 +5,43 @@
#include <widget.h>
#include "main.h"
void app_draw_modal(app_t *app) {
void w_app_draw_modal(w_app_t *app) {
if (app->modal.needs_destroy ||
(app->query_args->state == S_WAIT_SERVER && app->modal.is_initiated)) {
destroy_dialogue(&(app->modal), app);
w_dialogue_destroy(&(app->modal), app);
}
if (!app->modal.is_initiated) {
switch (app->query_args->state) {
case S_ASK_SEVER_IP:
init_asa_modal(app);
m_asa_init(app);
break;
case S_ASK_LOGIN_TYPE:
init_login_option_modal(app);
m_login_option_init(app);
break;
case S_ASK_LOGIN_USER:
init_login_credentials_modal(app);
m_login_credentials_init(app);
break;
case S_PRINT_SERVER_MESSAGE:
init_server_message_modal(app);
m_server_message_init(app);
break;
case S_FILE_DOWNLOAD:
init_dwn_pr_modal(app, false);
m_load_pr_init(app, false);
break;
case S_UPLOAD_FILE:
init_dwn_pr_modal(app, true);
m_load_pr_init(app, true);
break;
case S_UPLOAD_FILE_SELECT:
init_upload_dialogue_modal(app);
m_upload_dialogue_init(app);
break;
case S_ASK_REGISTER:
init_register_modal(app);
m_register_init(app);
break;
case S_UPLOAD_PARAMS:
init_upload_props_dialogue_modal(app);
m_upload_props_dialogue_init(app);
break;
default:
if (app->query_args->notification != NULL) {
init_notification_modal(app);
m_notification_init(app);
} else {
return;
}
@@ -51,5 +51,5 @@ void app_draw_modal(app_t *app) {
app->active_win_type = aw_modal;
app->active_widget = &(app->modal);
}
draw_dialogue(&(app->modal));
w_dialogue_draw(&(app->modal));
}
+10 -9
View File
@@ -24,6 +24,7 @@
#include "file_processor.h"
#include "main.h"
#include "query.h"
static void fl_add(fl_item_t **cur, fl_item_t **start, char *fname);
fl_item_t *fl_select(fl_item_t *start, int num);
void fl_clear(fl_item_t **start, fl_item_t **current);
@@ -33,8 +34,8 @@ 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->main_ui->ui;
dialogue_t *d = (dialogue_t *)q_args->active_dialogue;
w_ui_file_list_t *fui = (w_ui_file_list_t *)q_args->main_ui->ui;
w_dialogue_t *d = (w_dialogue_t *)q_args->active_dialogue;
fui->start = &(f_args->l_start);
fui->current = &(f_args->l_current);
@@ -49,7 +50,7 @@ void file_list(file_args_t *f_args, query_args_t *q_args) {
if (d != NULL && d->is_initiated) {
d->needs_update = true;
}
draw_file_list(fui);
w_fl_draw(fui);
free(query);
q_args->state = WAIT_CLIENT;
break;
@@ -117,9 +118,9 @@ void file_download(file_args_t *f_args, query_args_t *q_args) {
static size_t size_rest = 0;
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->main_ui->ui;
w_pgb_ui_t *pb = (w_pgb_ui_t *)q_args->progress_bar;
w_dialogue_t *d = (w_dialogue_t *)q_args->active_dialogue;
w_ui_file_list_t *fui = (w_ui_file_list_t *)q_args->main_ui->ui;
int32_t a_len = 0;
if (size_rest == 0)
@@ -181,7 +182,7 @@ int32_t file_upload_start(query_args_t *q_args) {
query_extract_from_buf(q_args->buf, &(q_args->buf_used), &query);
if (strcmp(query, "accept")) {
clear_file_in_query(q_args);
notification("Server response", dc_alert, query);
w_notification("Server response", dc_alert, query);
return -1;
}
return 0;
@@ -197,8 +198,8 @@ int32_t file_upload(query_args_t *q_args) {
}
uint32_t progress =
(q_args->file->size - q_args->file->rest) * 100 / q_args->file->size;
ui_progress_bar_t *pb = (ui_progress_bar_t *)q_args->progress_bar;
dialogue_t *d = (dialogue_t *)q_args->active_dialogue;
w_pgb_ui_t *pb = (w_pgb_ui_t *)q_args->progress_bar;
w_dialogue_t *d = (w_dialogue_t *)q_args->active_dialogue;
if (q_args->buf_used > 0) {
int wlen = write(q_args->sd, q_args->buf, q_args->buf_used);
if (q_args->buf_used != wlen) {
+24 -24
View File
@@ -23,27 +23,27 @@
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);
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);
int main(int argc, char **argv) {
app_t *app;
w_app_t *app;
params_t params;
query_args_t *q_args = malloc(sizeof(query_args_t));
app = calloc(1, sizeof(app_t));
app = calloc(1, sizeof(w_app_t));
init_nc();
w_app_init_nc();
app = init_app();
app = w_app_init();
init_params(&params);
app->params = &params;
analyze_args(argc, argv, &params);
/* init alert */
init_alert(app);
w_alert_init(app);
wrefresh(app->left_win);
wrefresh(app->right_win);
@@ -70,18 +70,18 @@ int main(int argc, char **argv) {
query_loop(app);
clear_params(&params);
destroy_app(app, 0);
w_app_destroy(app, 0);
return OK;
}
int32_t process_user_input(app_t *app, callback_args_t *d_args) {
int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args) {
int32_t c;
ui_file_list_t *fui = (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);
switch (c) {
case KEY_F(9):
destroy_app(app, 0);
w_app_destroy(app, 0);
return OK;
case 'U':
case 'u':
@@ -96,7 +96,7 @@ int32_t process_user_input(app_t *app, callback_args_t *d_args) {
case 'S':
if (!app->modal.is_initiated && !fui->active_search) {
fui->active_search = true;
draw_file_list(fui);
w_fl_draw(fui);
return OK;
}
default:
@@ -107,20 +107,20 @@ int32_t process_user_input(app_t *app, callback_args_t *d_args) {
return OK;
}
void main_window_set(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) {
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;
app->main_ui.ui = w_fl_init(&(app->left_win), &(app->right_win));
app->active_callback = w_fl_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;
w_lfl_init_win(&(app->left_win), &(app->right_win));
app->active_callback = w_lfl_cb;
break;
case mw_f_desc:
break;
@@ -129,23 +129,23 @@ void main_window_set(app_t *app, enum main_window_type type) {
}
}
void main_window_draw(app_t *app) {
void main_window_draw(w_app_t *app) {
switch (app->main_ui.type) {
case mw_fl_server:
draw_file_list((ui_file_list_t *)app->main_ui.ui);
w_fl_draw((w_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);
w_lfl_draw((w_lfl_ui_t *)app->main_ui.ui);
break;
case mw_f_desc:
break;
}
}
void main_window_delete(app_t *app) {
void main_window_delete(w_app_t *app) {
switch (app->main_ui.type) {
case mw_fl_server:
delete_file_list((ui_file_list_t **)&(app->main_ui.ui));
w_fl_destroy((w_ui_file_list_t **)&(app->main_ui.ui));
break;
case mw_fl_local:
/* TODO: delete fs_file_list */
+18 -18
View File
@@ -7,20 +7,20 @@
#include "group.h"
typedef struct {
button_t *element;
w_button_t *element;
enum w_type type;
} group_bt_t;
void asa_modal_dialogue_callback(callback_args_t *args) {
callback_args_t d_args;
app_t *app = args->app;
dialogue_t *d = (dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(callback_args_t));
void asa_modal_dialogue_callback(w_cb_args_t *args) {
w_cb_args_t d_args;
w_app_t *app = args->app;
w_dialogue_t *d = (w_dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(w_cb_args_t));
d_args.app = NULL;
d_args.element = app->active_widget;
input_t *in_ip = d->g_content->elements[0].element;
input_t *in_port = d->g_content->elements[1].element;
dialogue_default_callback(&d_args);
w_input_t *in_ip = d->g_content->elements[0].element;
w_input_t *in_port = d->g_content->elements[1].element;
w_dialogue_callback_default(&d_args);
if (d_args.resp_data.code == cbrp_val) {
switch (d_args.resp_data.val.val.num) {
case 1:
@@ -30,33 +30,33 @@ void asa_modal_dialogue_callback(callback_args_t *args) {
app->query_args->state = S_WAIT_SERVER;
break;
case 2:
destroy_app(app, 0);
w_app_destroy(app, 0);
}
}
}
dialogue_t *init_asa_modal(app_t *app) {
w_dialogue_t *m_asa_init(w_app_t *app) {
if (app == NULL)
return NULL;
group_el_init_t content[] = {
w_group_el_init_t content[] = {
{.type = w_input, .label = "Address", .length = 15},
{.type = w_input, .label = "Port", .length = 5},
{.type = w_end}};
group_el_init_t actions[] = {
w_group_el_init_t actions[] = {
{.type = w_button, .label = "Connect", .is_default = true, .val.num = 1},
{.type = w_button, .label = "Cancel", .is_default = false, .val.num = 2},
{.type = w_end}};
init_dialogue(&(app->modal), "Connect to server",
w_dialogue_init(&(app->modal), "Connect to server",
"There is information needed", &(app->coordinates));
dialogue_t *d = &(app->modal);
w_dialogue_t *d = &(app->modal);
d->w.callback = asa_modal_dialogue_callback;
d->g_content = init_group(&(d->win), &(d->w), content,&(d->id_map), horizontal, g_content);
d->g_action = init_group(&(d->win), &(d->w), actions,&(d->id_map), horizontal, g_action);
d->g_content = w_group_init(&(d->win), &(d->w), content,&(d->id_map), horizontal, g_content);
d->g_action = w_group_init(&(d->win), &(d->w), actions,&(d->id_map), horizontal, g_action);
dialogue_init_active_id(d);
w_dialogue_init_active_id(d);
return NULL;
}
+3 -3
View File
@@ -1,8 +1,8 @@
#ifndef ASK_SERVER_ADDR_H
#define ASK_SERVER_ADDR_H
#ifndef M_ASK_SERVER_ADDR_H
#define M_ASK_SERVER_ADDR_H
#include <widget.h>
dialogue_t *init_asa_modal(app_t *app);
w_dialogue_t *m_asa_init(w_app_t *app);
#endif
-8
View File
@@ -1,8 +0,0 @@
#ifndef DOWNLOAD_PR_H
#define DOWNLOAD_PR_H
#include <widget.h>
dialogue_t *init_dwn_pr_modal(app_t *app, bool is_upload);
#endif
@@ -4,36 +4,36 @@
#include <stdint.h>
#include <stdio.h>
void dwn_pr_modal_cb(callback_args_t *args) {
void dwn_pr_modal_cb(w_cb_args_t *args) {
/* TODO: cancel action */
}
dialogue_t *init_dwn_pr_modal(app_t *app, bool is_upload) {
w_dialogue_t *m_load_pr_init(w_app_t *app, bool is_upload) {
if (app == NULL)
return NULL;
group_el_init_t content[] = {
w_group_el_init_t content[] = {
{.type = w_progress, .label = "", .length = 30}, /* length is ignored */
{.type = w_end}};
char text[256];
sprintf(text, "%s file: %s", is_upload ? "Uploading" : "Downloading",
is_upload ? app->query_args->file->name : app->file_args->f_selected.name);
group_el_init_t actions[] = {
w_group_el_init_t actions[] = {
{.type = w_button, .label = "Cancel", .is_default = true, .val.num = 1}, {.type = w_end}};
app->modal.w.parent_win = &app->win;
init_dialogue(&(app->modal), is_upload ? "Upload" : "Download", text,
w_dialogue_init(&(app->modal), is_upload ? "Upload" : "Download", text,
&(app->coordinates));
dialogue_t *d = &(app->modal);
w_dialogue_t *d = &(app->modal);
d->w.callback = dwn_pr_modal_cb;
d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal, g_content);
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action);
d->g_content = w_group_init(&(d->win), &(d->w), content, &(d->id_map), horizontal, g_content);
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action);
app->query_args->progress_bar = d->g_content->elements[0].element;
app->query_args->active_dialogue = d;
dialogue_init_active_id(d);
w_dialogue_init_active_id(d);
return NULL;
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef M_LOAD_PR_H
#define M_LOAD_PR_H
#include <widget.h>
w_dialogue_t *m_load_pr_init(w_app_t *app, bool is_upload);
#endif
+18 -18
View File
@@ -9,20 +9,20 @@
#include "../server.h"
typedef struct {
button_t *element;
w_button_t *element;
enum w_type type;
} group_bt_t;
void init_login_credentials_modal_cb(callback_args_t *args) {
callback_args_t d_args;
app_t *app = args->app;
dialogue_t *d = (dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(callback_args_t));
void init_login_credentials_modal_cb(w_cb_args_t *args) {
w_cb_args_t d_args;
w_app_t *app = args->app;
w_dialogue_t *d = (w_dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(w_cb_args_t));
d_args.app = NULL;
d_args.element = app->active_widget;
input_t *in_name = d->g_content->elements[0].element;
input_t *in_pass = d->g_content->elements[1].element;
dialogue_default_callback(&d_args);
w_input_t *in_name = d->g_content->elements[0].element;
w_input_t *in_pass = d->g_content->elements[1].element;
w_dialogue_callback_default(&d_args);
if (d_args.resp_data.code == cbrp_val) {
switch (d_args.resp_data.val.val.num) {
case 1:
@@ -35,7 +35,7 @@ void init_login_credentials_modal_cb(callback_args_t *args) {
server_send_string(app->query_args, app->params->uname);
app->query_args->state = S_WAIT_SERVER;
d->needs_destroy = true;
print_bars(app);
w_app_print_bars(app);
break;
case 2:
app->query_args->state = S_ASK_LOGIN_TYPE;
@@ -44,10 +44,10 @@ void init_login_credentials_modal_cb(callback_args_t *args) {
}
}
dialogue_t *init_login_credentials_modal(app_t *app) {
w_dialogue_t *m_login_credentials_init(w_app_t *app) {
if (app == NULL)
return NULL;
group_el_init_t content[] = {
w_group_el_init_t content[] = {
{.type = w_input, .label = "Username", .length = 15},
{.type = w_input,
.label = "Password",
@@ -55,20 +55,20 @@ dialogue_t *init_login_credentials_modal(app_t *app) {
.is_hidden_value = true},
{.type = w_end}};
group_el_init_t actions[] = {
w_group_el_init_t actions[] = {
{.type = w_button, .label = "Login", .is_default = true, .val.num = 1},
{.type = w_button, .label = "Cancel", .is_default = false, .val.num = 2},
{.type = w_end}};
init_dialogue(&(app->modal), "Login", "Your login credentials",
w_dialogue_init(&(app->modal), "Login", "Your login credentials",
&(app->coordinates));
dialogue_t *d = &(app->modal);
w_dialogue_t *d = &(app->modal);
d->w.callback = init_login_credentials_modal_cb;
d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), horizontal, g_content);
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action);
d->g_content = w_group_init(&(d->win), &(d->w), content, &(d->id_map), horizontal, g_content);
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action);
dialogue_init_active_id(d);
w_dialogue_init_active_id(d);
return NULL;
}
+3 -3
View File
@@ -1,8 +1,8 @@
#ifndef LOGIN_CREDENTIALS_MODAL_H
#define LOGIN_CREDENTIALS_MODAL_H
#ifndef M_LOGIN_CREDENTIALS_H
#define M_LOGIN_CREDENTIALS_H
#include <widget.h>
dialogue_t *init_login_credentials_modal(app_t *app);
w_dialogue_t *m_login_credentials_init(w_app_t *app);
#endif
+13 -13
View File
@@ -9,18 +9,18 @@
#include "../server.h"
typedef struct {
button_t *element;
w_button_t *element;
enum w_type type;
} group_bt_t;
void login_modal_option_cb(callback_args_t *args) {
callback_args_t d_args;
app_t *app = args->app;
dialogue_t *d = (dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(callback_args_t));
void login_modal_option_cb(w_cb_args_t *args) {
w_cb_args_t d_args;
w_app_t *app = args->app;
w_dialogue_t *d = (w_dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(w_cb_args_t));
d_args.app = NULL;
d_args.element = app->active_widget;
dialogue_default_callback(&d_args);
w_dialogue_callback_default(&d_args);
if (d_args.resp_data.code == cbrp_val) {
switch (d_args.resp_data.val.val.num) {
case 1:
@@ -29,7 +29,7 @@ void login_modal_option_cb(callback_args_t *args) {
strcpy(app->params->uname, "anonymous");
server_send_string(app->query_args, app->params->uname);
app->query_args->state = S_WAIT_SERVER;
print_bars(app);
w_app_print_bars(app);
break;
case 2:
d->needs_destroy = true;
@@ -43,22 +43,22 @@ void login_modal_option_cb(callback_args_t *args) {
}
}
dialogue_t *init_login_option_modal(app_t *app) {
w_dialogue_t *m_login_option_init(w_app_t *app) {
if (app == NULL)
return NULL;
group_el_init_t children[] = {{.type = w_button, .label = "Anonymous", .val.num = 1},
w_group_el_init_t children[] = {{.type = w_button, .label = "Anonymous", .val.num = 1},
{.type = w_button, .label = "User", .val.num = 2},
{.type = w_button, .label = "Register", .val.num = 3},
{.type = w_end}};
init_dialogue(&(app->modal), "Login",
w_dialogue_init(&(app->modal), "Login",
"Select your login "
"option",
&(app->coordinates));
app->modal.g_action = init_group(&(app->modal.win), &(app->modal.w), children,
app->modal.g_action = w_group_init(&(app->modal.win), &(app->modal.w), children,
&(app->modal.id_map), horizontal, g_action);
app->modal.w.callback = login_modal_option_cb;
dialogue_init_active_id(&(app->modal));
w_dialogue_init_active_id(&(app->modal));
return NULL;
}
+3 -3
View File
@@ -1,8 +1,8 @@
#ifndef LOGIN_OPTION_MODAL_H
#define LOGIN_OPTION_MODAL_H
#ifndef M_LOGIN_OPTION_H
#define M_LOGIN_OPTION_H
#include <widget.h>
dialogue_t *init_login_option_modal(app_t *app);
w_dialogue_t *m_login_option_init(w_app_t *app);
#endif
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef MODALS_H
#define MODALS_H
#include "ask_server_addr.h"
#include "download_pr.h"
#include "load_pr.h"
#include "login_credentials.h"
#include "login_option.h"
#include "notification.h"
+13 -13
View File
@@ -7,44 +7,44 @@
#include <widget.h>
typedef struct {
button_t *element;
w_button_t *element;
enum w_type type;
} group_bt_t;
void init_notification_modal_cb(callback_args_t *args) {
callback_args_t d_args;
app_t *app = args->app;
dialogue_t *d = (dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(callback_args_t));
void init_notification_modal_cb(w_cb_args_t *args) {
w_cb_args_t d_args;
w_app_t *app = args->app;
w_dialogue_t *d = (w_dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(w_cb_args_t));
d_args.app = NULL;
d_args.element = app->active_widget;
dialogue_default_callback(&d_args);
w_dialogue_callback_default(&d_args);
app->query_args->state = WAIT_CLIENT;
d->needs_destroy = true;
}
dialogue_t *init_notification_modal(app_t *app) {
w_dialogue_t *m_notification_init(w_app_t *app) {
if (app == NULL)
return NULL;
group_el_init_t actions[] = {
w_group_el_init_t actions[] = {
{.type = w_button, .label = "OK", .is_default = true, .val.num = 1},
{.type = w_end}};
init_dialogue(&(app->modal), "Notification", app->query_args->notification,
w_dialogue_init(&(app->modal), "Notification", app->query_args->notification,
&(app->coordinates));
free(app->query_args->notification);
app->query_args->notification = NULL;
dialogue_t *d = &(app->modal);
w_dialogue_t *d = &(app->modal);
app->query_args->active_dialogue = d;
d->w.callback = init_notification_modal_cb;
d->g_content = NULL;
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map),
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map),
horizontal, g_action);
dialogue_init_active_id(d);
w_dialogue_init_active_id(d);
return NULL;
}
+3 -3
View File
@@ -1,8 +1,8 @@
#ifndef NOTIFICATION_H
#define NOTIFICATION_H
#ifndef M_NOTIFICATION_H
#define M_NOTIFICATION_H
#include <widget.h>
dialogue_t *init_notification_modal(app_t *app);
w_dialogue_t *m_notification_init(w_app_t *app);
#endif
+25 -25
View File
@@ -11,18 +11,18 @@
#include "../server.h"
typedef struct {
button_t *element;
w_button_t *element;
enum w_type type;
} group_bt_t;
void init_register_modal_cb(callback_args_t *args) {
callback_args_t d_args;
app_t *app = args->app;
dialogue_t *d = (dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(callback_args_t));
void init_register_modal_cb(w_cb_args_t *args) {
w_cb_args_t d_args;
w_app_t *app = args->app;
w_dialogue_t *d = (w_dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(w_cb_args_t));
d_args.app = NULL;
d_args.element = app->active_widget;
dialogue_default_callback(&d_args);
w_dialogue_callback_default(&d_args);
if (d_args.resp_data.code == cbrp_val &&
d_args.resp_data.val.type == val_num) {
@@ -32,25 +32,25 @@ void init_register_modal_cb(callback_args_t *args) {
return;
}
input_t *in_name = d->g_content->elements[0].element;
group_t *g_passwords = d->g_content->elements[1].element;
input_t *in_email = d->g_content->elements[2].element;
input_t *in_pass = g_passwords->elements[0].element;
input_t *in_pass_r = g_passwords->elements[1].element;
w_input_t *in_name = d->g_content->elements[0].element;
w_group_t *g_passwords = d->g_content->elements[1].element;
w_input_t *in_email = d->g_content->elements[2].element;
w_input_t *in_pass = g_passwords->elements[0].element;
w_input_t *in_pass_r = g_passwords->elements[1].element;
if (in_name->value_len == 0) {
alert("Name field is empty!");
w_alert("Name field is empty!");
return;
}
if (in_email->value_len == 0) {
alert("Email field is empty!");
w_alert("Email field is empty!");
return;
}
if (!in_pass->value_len || !in_pass->value_len) {
alert("One of password's field is empty!");
w_alert("One of password's field is empty!");
return;
}
if (strcmp(in_pass->value, in_pass_r->value)) {
alert("Your passwords do not match!");
w_alert("Your passwords do not match!");
in_pass->value[0] = '\0';
in_pass->value_len = 0;
in_pass_r->value[0] = '\0';
@@ -70,11 +70,11 @@ void init_register_modal_cb(callback_args_t *args) {
}
}
dialogue_t *init_register_modal(app_t *app) {
w_dialogue_t *m_register_init(w_app_t *app) {
if (app == NULL)
return NULL;
group_el_init_t content_pass[] = {{.type = w_input,
w_group_el_init_t content_pass[] = {{.type = w_input,
.label = "Password",
.length = 18,
.is_hidden_value = true},
@@ -84,28 +84,28 @@ dialogue_t *init_register_modal(app_t *app) {
.is_hidden_value = true},
{.type = w_end}};
group_el_init_t content[] = {
w_group_el_init_t content[] = {
{.type = w_input, .label = "Username", .length = 18},
{.type = w_group, .direction = horizontal, .children = content_pass},
{.type = w_input, .label = "Email", .length = 40},
{.type = w_end}};
group_el_init_t actions[] = {
w_group_el_init_t actions[] = {
{.type = w_button, .label = "Register", .is_default = true, .val.num = 1},
{.type = w_button, .label = "Cancel", .is_default = false, .val.num = 2},
{.type = w_end}};
init_dialogue(&(app->modal), "Credentials", "There is information needed",
w_dialogue_init(&(app->modal), "Credentials", "There is information needed",
&(app->coordinates));
dialogue_t *d = &(app->modal);
w_dialogue_t *d = &(app->modal);
d->w.callback = init_register_modal_cb;
d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), vertical,
d->g_content = w_group_init(&(d->win), &(d->w), content, &(d->id_map), vertical,
g_content);
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map),
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map),
horizontal, g_action);
dialogue_init_active_id(d);
w_dialogue_init_active_id(d);
return NULL;
}
+3 -3
View File
@@ -1,8 +1,8 @@
#ifndef REGISTER_MODAL_H
#define REGISTER_MODAL_H
#ifndef M_REGISTER_H
#define M_REGISTER_H
#include <widget.h>
dialogue_t *init_register_modal(app_t *app);
w_dialogue_t *m_register_init(w_app_t *app);
#endif
+12 -12
View File
@@ -7,18 +7,18 @@
#include <widget.h>
typedef struct {
button_t *element;
w_button_t *element;
enum w_type type;
} group_bt_t;
void server_message_modal_cb(callback_args_t *args) {
callback_args_t d_args;
app_t *app = args->app;
dialogue_t *d = (dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(callback_args_t));
void server_message_modal_cb(w_cb_args_t *args) {
w_cb_args_t d_args;
w_app_t *app = args->app;
w_dialogue_t *d = (w_dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(w_cb_args_t));
d_args.app = NULL;
d_args.element = app->active_widget;
dialogue_default_callback(&d_args);
w_dialogue_callback_default(&d_args);
if (d_args.resp_data.code == cbrp_val) {
switch (d_args.resp_data.val.val.num) {
case 1:
@@ -34,18 +34,18 @@ void server_message_modal_cb(callback_args_t *args) {
}
}
void *init_server_message_modal(app_t *app) {
void *m_server_message_init(w_app_t *app) {
if (app == NULL)
return NULL;
group_el_init_t children[] = {
w_group_el_init_t children[] = {
{.type = w_button, .label = "OK", .is_default = true, .val.num = 1}, {.type = w_end}};
init_dialogue(&(app->modal), "Server response",
w_dialogue_init(&(app->modal), "Server response",
app->query_args->server_message.text, &(app->coordinates));
app->modal.g_action =
init_group(&(app->modal.win), &(app->modal.w), children, &(app->modal.id_map), horizontal, g_action);
w_group_init(&(app->modal.win), &(app->modal.w), children, &(app->modal.id_map), horizontal, g_action);
app->modal.w.callback = server_message_modal_cb;
dialogue_init_active_id(&(app->modal));
w_dialogue_init_active_id(&(app->modal));
return NULL;
}
+3 -3
View File
@@ -1,8 +1,8 @@
#ifndef SERVER_MESSAGE_H
#define SERVER_MESSAGE_H
#ifndef M_SERVER_MESSAGE_H
#define M_SERVER_MESSAGE_H
#include <widget.h>
void *init_server_message_modal(app_t *app);
void *m_server_message_init(w_app_t *app);
#endif
+16 -16
View File
@@ -5,16 +5,16 @@
#include <string.h>
#include <widget.h>
void upload_dialogue_modal_cb(callback_args_t *args) {
callback_args_t d_args;
app_t *app = args->app;
dialogue_t *d = (dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(callback_args_t));
void upload_dialogue_modal_cb(w_cb_args_t *args) {
w_cb_args_t d_args;
w_app_t *app = args->app;
w_dialogue_t *d = (w_dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(w_cb_args_t));
d_args.app = NULL;
d_args.element = app->active_widget;
dialogue_default_callback(&d_args);
ui_fs_file_list_t *fui =
(ui_fs_file_list_t *)d->g_content->elements[0].element;
w_dialogue_callback_default(&d_args);
w_lfl_ui_t *fui =
(w_lfl_ui_t *)d->g_content->elements[0].element;
if (d_args.resp_data.code == cbrp_val) {
switch (d_args.resp_data.val.val.num) {
case 0:
@@ -33,31 +33,31 @@ void upload_dialogue_modal_cb(callback_args_t *args) {
}
}
dialogue_t *init_upload_dialogue_modal(app_t *app) {
w_dialogue_t *m_upload_dialogue_init(w_app_t *app) {
if (app == NULL)
return NULL;
group_el_init_t content[] = {
w_group_el_init_t content[] = {
// {.type = w_input, .label = "File description", .length = 30},
{.type = w_fs_file_list, .label = "File", .length = 30},
{.type = w_end}};
group_el_init_t actions[] = {
w_group_el_init_t actions[] = {
{.type = w_button, .label = "Cancel", .is_default = false, .val.num = 0}, {.type = w_end}};
app->modal.w.parent_win = &app->win;
init_dialogue(&(app->modal), "Upload new file", "Enter essential data",
w_dialogue_init(&(app->modal), "Upload new file", "Enter essential data",
&(app->coordinates));
dialogue_t *d = &(app->modal);
w_dialogue_t *d = &(app->modal);
d->w.callback = upload_dialogue_modal_cb;
d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map),
d->g_content = w_group_init(&(d->win), &(d->w), content, &(d->id_map),
horizontal, g_content);
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map),
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map),
horizontal, g_action);
app->query_args->active_dialogue = d;
dialogue_init_active_id(d);
w_dialogue_init_active_id(d);
return NULL;
}
+3 -3
View File
@@ -1,8 +1,8 @@
#ifndef UPLOAD_DIALOGUE_H
#define UPLOAD_DIALOGUE_H
#ifndef M_UPLOAD_DIALOGUE_H
#define M_UPLOAD_DIALOGUE_H
#include <widget.h>
dialogue_t *init_upload_dialogue_modal(app_t *app);
w_dialogue_t *m_upload_dialogue_init(w_app_t *app);
#endif
+17 -17
View File
@@ -11,19 +11,19 @@
#include "../server.h"
void upload_props_dialogue_modal_cb(callback_args_t *args) {
callback_args_t d_args;
app_t *app = args->app;
dialogue_t *d = (dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(callback_args_t));
void upload_props_dialogue_modal_cb(w_cb_args_t *args) {
w_cb_args_t d_args;
w_app_t *app = args->app;
w_dialogue_t *d = (w_dialogue_t *)app->active_widget;
memcpy(&d_args, args, sizeof(w_cb_args_t));
d_args.app = NULL;
d_args.element = app->active_widget;
dialogue_default_callback(&d_args);
w_dialogue_callback_default(&d_args);
int32_t query_len = 0;
if (d_args.resp_data.code == cbrp_val) {
checkbox_t *reg_cbx = (checkbox_t *)d->g_content->elements[0].element;
checkbox_t *anon_cbx = (checkbox_t *)d->g_content->elements[1].element;
checkbox_t *comp_cbx = (checkbox_t *)d->g_content->elements[2].element;
w_checkbox_t *reg_cbx = (w_checkbox_t *)d->g_content->elements[0].element;
w_checkbox_t *anon_cbx = (w_checkbox_t *)d->g_content->elements[1].element;
w_checkbox_t *comp_cbx = (w_checkbox_t *)d->g_content->elements[2].element;
int32_t privileges = 0;
if (anon_cbx->value == true)
@@ -57,10 +57,10 @@ void upload_props_dialogue_modal_cb(callback_args_t *args) {
}
}
dialogue_t *init_upload_props_dialogue_modal(app_t *app) {
w_dialogue_t *m_upload_props_dialogue_init(w_app_t *app) {
if (app == NULL)
return NULL;
group_el_init_t content[] = {{.type = w_checkbox,
w_group_el_init_t content[] = {{.type = w_checkbox,
.label = "Visible for registered",
.is_default = true},
{.type = w_checkbox,
@@ -71,26 +71,26 @@ dialogue_t *init_upload_props_dialogue_modal(app_t *app) {
.is_default = false},
{.type = w_end}};
group_el_init_t actions[] = {
w_group_el_init_t actions[] = {
{.type = w_button, .label = "Upload", .is_default = false, .val.num = 1},
{.type = w_button, .label = "Cancel", .is_default = false, .val.num = 2},
{.type = w_end},
};
app->modal.w.parent_win = &app->win;
init_dialogue(&(app->modal), "Description for the file",
w_dialogue_init(&(app->modal), "Description for the file",
"Enter essential data", &(app->coordinates));
dialogue_t *d = &(app->modal);
w_dialogue_t *d = &(app->modal);
d->w.callback = upload_props_dialogue_modal_cb;
d->g_content = init_group(&(d->win), &(d->w), content, &(d->id_map), vertical,
d->g_content = w_group_init(&(d->win), &(d->w), content, &(d->id_map), vertical,
g_content);
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map),
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map),
horizontal, g_action);
app->query_args->active_dialogue = d;
dialogue_init_active_id(d);
w_dialogue_init_active_id(d);
return NULL;
}
+1 -1
View File
@@ -3,6 +3,6 @@
#include <widget.h>
dialogue_t *init_upload_props_dialogue_modal(app_t *app);
w_dialogue_t *m_upload_props_dialogue_init(w_app_t *app);
#endif
+15 -15
View File
@@ -32,26 +32,26 @@
#include "server.h"
#include "types.h"
static int process_command(app_t *app, wait_server_cb *cb);
static int process_command(w_app_t *app, wait_server_cb *cb);
void user_request_description(query_args_t *q_args);
int process_query(app_t *app);
int32_t process_user_input(app_t *app, callback_args_t *d_args);
int process_query(w_app_t *app);
int32_t process_user_input(w_app_t *app, w_cb_args_t *d_args);
#define EXIT_APP(message, app, exit_code) \
{ \
alert(message); \
w_alert(message); \
close_session(app->params->sd); \
destroy_app(app, exit_code); \
w_app_destroy(app, exit_code); \
}
void query_loop(app_t *app) {
void query_loop(w_app_t *app) {
query_args_t *query_args = app->query_args;
fd_set readfds;
int32_t sd = app->params->sd;
size_t qlen;
int sr;
static file_args_t file_args;
callback_args_t d_args = {
w_cb_args_t d_args = {
.app = app, .element = NULL, .data = NULL, .resp_data.code = cbrc_none};
init_file_args(&file_args);
@@ -60,8 +60,8 @@ void query_loop(app_t *app) {
for (;;) {
/* update screen */
app_draw_modal(app);
app_refresh(app);
w_app_draw_modal(app);
w_app_refresh(app);
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
@@ -128,22 +128,22 @@ void wait_register(query_args_t *q_args) {
email);
}
int upload_confirm_cb(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)) {
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!",
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!",
app->query_args->file->name);
clear_file_in_query(app->query_args);
app->query_args->state = S_FILE_LIST;
app->modal.needs_destroy = true;
reset_file_list(fui);
w_fl_rest(fui);
server_send_string(app->query_args, "file list %u %u\n", fui->max_lines, 1);
return 0;
}
return 1; /* TODO: Error case */
}
int process_query(app_t *app) {
int process_query(w_app_t *app) {
query_args_t *query_args = app->query_args;
file_args_t *file_args = app->file_args;
query_args->buf[query_args->buf_used] = 0;
@@ -251,7 +251,7 @@ void query_return_to_buf(char *buf, int *buf_used, char *input_line) {
buf[*buf_used] = 0;
}
static int process_command(app_t *app, wait_server_cb *callback) {
static int process_command(w_app_t *app, wait_server_cb *callback) {
query_args_t *q_args = app->query_args;
int qlen;
char *query = NULL;
+3 -3
View File
@@ -8,11 +8,11 @@
#include "main.h"
#include <widget.h>
void query_loop(app_t *);
void query_loop(w_app_t *);
void wait_register(query_args_t *q_args);
int process_query(app_t *app);
int process_query(w_app_t *app);
int query_extract_from_buf(char *buf, int *buf_used, char **output_line);
void init_query_args(query_args_t *q_args, params_t *params);
typedef int wait_server_cb(app_t *app, char *query, int q_len);
typedef int wait_server_cb(w_app_t *app, char *query, int q_len);
void query_return_to_buf(char *buf, int *buf_used, char *input_line);
#endif
+11 -11
View File
@@ -32,31 +32,31 @@ void server_send_string(query_args_t *q, const char *fmt, ...) {
va_end(args);
}
int server_wait_reg_confirm_cb(app_t *app, char *line, int l_len) {
int server_wait_reg_confirm_cb(w_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->main_ui->ui;
w_ui_file_list_t *fui = (w_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,
fui->current_page);
q_args->state = S_FILE_LIST;
destroy_dialogue(&(app->modal), app);
w_dialogue_destroy(&(app->modal), app);
sprintf(query,
"You've been successfully registered.\n"
"Welcome, %s!",
app->params->uname);
notification("Registration", dc_normal, query);
print_bars(app);
w_notification("Registration", dc_normal, query);
w_app_print_bars(app);
return 0;
} else {
q_args->state = S_ASK_REGISTER;
alert(line);
w_alert(line);
return 1;
}
}
int server_print_message_cb(app_t *app, char *line, int l_len) {
int server_print_message_cb(w_app_t *app, char *line, int l_len) {
int64_t new_capacity;
query_args_t *q_args = app->query_args;
if (q_args->server_message.text == NULL) {
@@ -82,7 +82,7 @@ int server_print_message_cb(app_t *app, char *line, int l_len) {
query_return_to_buf(app->query_args->buf, &(app->query_args->buf_used),
end_char + 1);
*end_char = '\0'; /* Don't show this symbol */
notification("Server response", dc_normal, q_args->server_message.text);
w_notification("Server response", dc_normal, q_args->server_message.text);
/* q_args->state = S_PRINT_SERVER_MESSAGE; */
q_args->server_message.size = 0;
q_args->server_message.text[0] = 0;
@@ -92,11 +92,11 @@ int server_print_message_cb(app_t *app, char *line, int l_len) {
return 0;
}
int process_server_command(char *line, int l_len, app_t *app) {
int process_server_command(char *line, int l_len, w_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->main_ui->ui;
w_ui_file_list_t *fui = (w_ui_file_list_t *)q_args->main_ui->ui;
char *cptr = strchr(line, ' ');
if (cptr != NULL && cptr > line)
@@ -123,7 +123,7 @@ int process_server_command(char *line, int l_len, app_t *app) {
/* LOGIN AGAIN */
if (!strncmp(line, "login_again>\n", ws_pos)) {
alert("Incorrect credentials! Try again");
w_alert("Incorrect credentials! Try again");
free(params->uname);
free(params->pass);
params->uname = NULL;
+3 -3
View File
@@ -6,9 +6,9 @@
#include "app.h"
#include "main.h"
int process_server_command(char *line, int l_len, app_t *app);
int process_server_command(char *line, int l_len, w_app_t *app);
void ask_register(params_t *params, char *email);
void server_send_string(query_args_t *q, const char *fmt, ...);
int server_print_message_cb(app_t *app, char *line, int l_len);
int server_wait_reg_confirm_cb(app_t *app, char *line, int l_len);
int server_print_message_cb(w_app_t *app, char *line, int l_len);
int server_wait_reg_confirm_cb(w_app_t *app, char *line, int l_len);
#endif
+3 -3
View File
@@ -4,7 +4,7 @@
#include <stdlib.h>
#include <string.h>
void init_d_arr_ptr(d_array_ptr_t *arr, int64_t init_capacity) {
void u_d_arr_ptr_init(d_array_ptr_t *arr, int64_t init_capacity) {
arr->capacity = init_capacity;
arr->length = 0;
arr->arr = malloc(sizeof(void *) * init_capacity);
@@ -13,7 +13,7 @@ void init_d_arr_ptr(d_array_ptr_t *arr, int64_t init_capacity) {
memset(arr->arr, 0, init_capacity);
}
void add_d_arr_ptr(d_array_ptr_t *arr, void *ptr, int64_t idx) {
void u_d_arr_ptr_add(d_array_ptr_t *arr, void *ptr, int64_t idx) {
int64_t new_capacity = idx * 2;
if (idx > arr->capacity - 1) {
arr->arr = realloc(arr->arr, new_capacity);
@@ -26,7 +26,7 @@ void add_d_arr_ptr(d_array_ptr_t *arr, void *ptr, int64_t idx) {
arr->length = idx+1;
}
void free_d_arr(d_array_ptr_t *arr) {
void u_d_arr_ptr_free(d_array_ptr_t *arr) {
arr->capacity = 0;
arr->length = 0;
free(arr->arr);
+3 -3
View File
@@ -10,8 +10,8 @@ typedef struct d_array_ptr_t {
void *last_el;
} d_array_ptr_t;
void init_d_arr_ptr(d_array_ptr_t *arr, int64_t init_capacity);
void add_d_arr_ptr(d_array_ptr_t *arr, void *ptr, int64_t idx);
void free_d_arr(d_array_ptr_t *arr);
void u_d_arr_ptr_init(d_array_ptr_t *arr, int64_t init_capacity);
void u_d_arr_ptr_add(d_array_ptr_t *arr, void *ptr, int64_t idx);
void u_d_arr_ptr_free(d_array_ptr_t *arr);
#endif
+5 -5
View File
@@ -5,7 +5,7 @@
#include <stdlib.h>
#include <wchar.h>
size_t count_utf8_code_points(const char *s) {
size_t u_utf8_code_points_count(const char *s) {
size_t count = 0;
while (*s) {
count += (*s++ & 0xC0) != 0x80;
@@ -13,11 +13,11 @@ size_t count_utf8_code_points(const char *s) {
return count;
}
int64_t convert_utf8_to_wide(const char *utf8_str, wchar_t **restrict wide_str,
int64_t u_utf8_conver_to_wide(const char *utf8_str, wchar_t **restrict wide_str,
size_t *restrict len) {
// Step 1: Convert UTF-8 (MBCS) to wchar_t (wide)
size_t wide_len =
count_utf8_code_points(utf8_str); // Get required length (-1 on error)
u_utf8_code_points_count(utf8_str); // Get required length (-1 on error)
if (wide_len == (size_t)-1) {
*len = 0;
perror("mbstowcs failed");
@@ -30,10 +30,10 @@ int64_t convert_utf8_to_wide(const char *utf8_str, wchar_t **restrict wide_str,
return 0;
}
int64_t 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) {
wchar_t *wname = NULL;
size_t nsize = 0;
convert_utf8_to_wide(utf8_str, &wname, &nsize);
u_utf8_conver_to_wide(utf8_str, &wname, &nsize);
mvwaddwstr(win, y, x, wname);
free(wname);
return nsize;
+5 -3
View File
@@ -4,8 +4,10 @@
#include <ncursesw/ncurses.h>
#include <stddef.h>
#include <stdint.h>
size_t count_utf8_code_points(const char *s);
int64_t convert_utf8_to_wide(const char *utf8_str, wchar_t **restrict wide_str,
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 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);
#endif
+13 -13
View File
@@ -7,41 +7,41 @@
/* Short notifications. Prefer using this method to simply notify the client */
static app_t *app;
static w_app_t *app;
void alert_cb(callback_args_t *args) {
void alert_cb(w_cb_args_t *args) {
//
}
void init_alert(app_t *_app) { app = _app; }
void w_alert_init(w_app_t *_app) { app = _app; }
void alert(const char *message) { notification("Alert", dc_alert, message); }
void w_alert(const char *message) { w_notification("Alert", dc_alert, message); }
void notification(const char *title, enum dc_color_scheme color,
void w_notification(const char *title, enum w_dialogue_color_scheme color,
const char *f_message, ...) {
if (app == NULL)
return;
void *callback = app->active_callback;
group_el_init_t actions[] = {
w_group_el_init_t actions[] = {
{.type = w_button, .label = "OK", .is_default = true}, {.type = w_end}};
dialogue_t *d = malloc(sizeof(dialogue_t));
w_dialogue_t *d = malloc(sizeof(w_dialogue_t));
va_list args;
va_start(args, f_message);
vinit_dialogue(d, title, &(app->coordinates), f_message, &args);
w_dialogue_vinit(d, title, &(app->coordinates), f_message, &args);
d->w.callback = alert_cb;
d->g_content = NULL;
d->g_action = init_group(&(d->win), &(d->w), actions, &(d->id_map),
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map),
horizontal, g_action);
dialogue_init_active_id(d);
w_dialogue_init_active_id(d);
d->color_scheme = color;
draw_dialogue(d);
w_dialogue_draw(d);
wrefresh(d->win);
int c = 0;
@@ -50,11 +50,11 @@ void notification(const char *title, enum dc_color_scheme color,
break;
}
destroy_group(d->g_action);
w_group_destroy(d->g_action);
delwin(d->win);
free(d);
app->active_callback = callback;
app_refresh(app);
w_app_refresh(app);
if (app->modal.win != NULL) {
app->modal.needs_update = true;
}
+8 -5
View File
@@ -1,9 +1,12 @@
#ifndef ALERT_H
#define ALERT_H
#ifndef W_ALERT_H
#define W_ALERT_H
#include "app.h"
#include <stdarg.h>
void init_alert(app_t *app);
void alert(const char *message);
void notification(const char *title, enum dc_color_scheme color,
void w_alert_init(w_app_t *app);
void w_alert(const char *message);
void w_notification(const char *title, enum w_dialogue_color_scheme color,
const char *f_message, ...);
#endif
+11 -11
View File
@@ -15,13 +15,13 @@
void ac_file(WINDOW *win, int is_action_w);
app_t *init_app() {
w_app_t *w_app_init() {
/* get values from terminal size */
int32_t y_max, x_max;
getmaxyx(stdscr, y_max, x_max);
/* allocate app struct memory */
app_t *_app = calloc(1, sizeof(app_t));
w_app_t *_app = calloc(1, sizeof(w_app_t));
/* associate values for screen size */
_app->coordinates.max_x = _app->coordinates.cur_x = x_max;
@@ -47,13 +47,13 @@ app_t *init_app() {
_app->active_win_type = aw_left;
/* default callback */
_app->active_callback = file_list_cb;
_app->active_callback = w_fl_cb;
/* print decorative bars */
print_bars(_app);
w_app_print_bars(_app);
/* here goes box borders */
draw_borders(_app);
w_app_draw_borders(_app);
/* NULL to main_ui */
_app->main_ui.ui = NULL;
@@ -69,7 +69,7 @@ app_t *init_app() {
return _app;
}
void init_nc() {
void w_app_init_nc() {
initscr();
cbreak();
keypad(stdscr, TRUE);
@@ -89,7 +89,7 @@ void init_nc() {
}
}
void draw_borders(app_t *app) {
void w_app_draw_borders(w_app_t *app) {
if (app->modal.win != NULL && !app->modal.needs_update) {
return;
}
@@ -118,7 +118,7 @@ int64_t print_bottom_menu_option(WINDOW *win, char *key, char *title, int64_t y,
return key_len + title_len;
}
void print_bars(app_t *app) {
void w_app_print_bars(w_app_t *app) {
char top_text[64] = "Hello!";
wattrset(app->win, A_REVERSE);
@@ -166,8 +166,8 @@ void print_bars(app_t *app) {
wattroff(app->win, A_REVERSE);
}
void app_refresh(app_t *app) {
draw_borders(app);
void w_app_refresh(w_app_t *app) {
w_app_draw_borders(app);
wnoutrefresh(app->win);
wnoutrefresh(app->right_win);
@@ -180,7 +180,7 @@ void app_refresh(app_t *app) {
doupdate();
}
void destroy_app(app_t *app, int32_t exit_code) {
void w_app_destroy(w_app_t *app, int32_t exit_code) {
delwin(app->win);
endwin();
app->win = NULL;
+15 -15
View File
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */
#ifndef N_APP_H
#define N_APP_H
#ifndef W_APP_H
#define W_APP_H
#include "../main.h"
#include "../common.h"
@@ -13,36 +13,36 @@
typedef enum {
modal_color_pair = 3,
} color;
} w_app_color;
typedef enum {
aw_left,
aw_right,
aw_modal
} active_win_t;
} w_active_win_t;
typedef struct {
WINDOW *win;
WINDOW *left_win;
WINDOW *right_win;
dialogue_t modal;
w_dialogue_t modal;
params_t *params;
coordinates_t coordinates;
query_args_t *query_args;
file_args_t *file_args;
active_win_t active_win_type;
void (*active_callback)(callback_args_t *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;
} app_t;
} w_app_t;
app_t *init_app(void);
void init_nc(void);
void destroy_app(app_t *app, int32_t exit_code);
void draw_borders(app_t *app);
void print_bars(app_t *app);
void app_refresh(app_t *app);
void app_draw_modal(app_t *app);
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_refresh(w_app_t *app);
void w_app_draw_modal(w_app_t *app);
#endif // N_APP_H
+6 -6
View File
@@ -10,9 +10,9 @@
#include "button.h"
#include "app.h"
button_t *init_button(WINDOW **win, widget_t *w_parent, char *label) {
button_t *btn = malloc(sizeof(button_t));
init_widget(&(btn->w), w_parent, win, label);
w_button_t *init_button(WINDOW **win, w_t *w_parent, char *label) {
w_button_t *btn = malloc(sizeof(w_button_t));
w_init(&(btn->w), w_parent, win, label);
btn->is_disabled = 0;
btn->w.sz.x = strlen(btn->w.title) + 6; // + "[ ]"
btn->w.sz.y = 1; // TODO: detect new line
@@ -21,13 +21,13 @@ button_t *init_button(WINDOW **win, widget_t *w_parent, char *label) {
return btn;
}
int32_t draw_button(button_t *btn, uint32_t active_id) {
int32_t draw_button(w_button_t *btn, uint32_t active_id) {
char title[DIALOGUE_TITLE + 6];
WINDOW *win = *(btn->w.parent_win);
uint32_t margin_y = btn->w.ps.y + btn->w.m.y;
uint32_t margin_x = btn->w.ps.x + btn->w.m.x;
widget_t *w_par = btn->w.w_parent;
w_t *w_par = btn->w.w_parent;
while (w_par->parent_win == btn->w.parent_win) {
margin_y += w_par->ps.y;
@@ -51,4 +51,4 @@ int32_t draw_button(button_t *btn, uint32_t active_id) {
return strlen(title);
}
void destroy_button(button_t *btn) { free(btn); }
void destroy_button(w_button_t *btn) { free(btn); }
+8 -7
View File
@@ -1,19 +1,20 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */
#ifndef BUTTON_H
#define BUTTON_H
#ifndef W_BUTTON_H
#define W_BUTTON_H
#include <widget_core.h>
#include <stdint.h>
typedef struct {
widget_t w;
w_t w;
int32_t hotkey;
uint32_t is_disabled : 1;
} button_t;
} w_button_t;
w_button_t *init_button(WINDOW **win, w_t *w_parent, char *label);
int32_t draw_button(w_button_t *btn, uint32_t active_id);
void destroy_button(w_button_t *btn);
button_t *init_button(WINDOW **win, widget_t *w_parent, char *label);
int32_t draw_button(button_t *btn, uint32_t active_id);
void destroy_button(button_t *btn);
#endif
+9 -9
View File
@@ -10,10 +10,10 @@
#include "checkbox.h"
#include <widget_core.h>
bool checkbox_default_key_action(callback_args_t *args) {
bool w_checkbox_default_key_action(w_cb_args_t *args) {
int32_t key = *((int32_t *)args->data);
group_el_t *g_el = args->active_el;
checkbox_t *cbx = g_el->element;
w_g_el_t *g_el = args->active_el;
w_checkbox_t *cbx = g_el->element;
switch (key) {
case '\40':
cbx->value = !cbx->value;
@@ -24,9 +24,9 @@ bool checkbox_default_key_action(callback_args_t *args) {
return true;
}
checkbox_t *init_checkbox(WINDOW **win, widget_t *w_parent, char *label) {
checkbox_t *cbx = malloc(sizeof(checkbox_t));
init_widget(&(cbx->w), w_parent, win, label);
w_checkbox_t *w_checkbox_init(WINDOW **win, w_t *w_parent, char *label) {
w_checkbox_t *cbx = malloc(sizeof(w_checkbox_t));
w_init(&(cbx->w), w_parent, win, label);
cbx->is_disabled = false;
cbx->value = false;
cbx->w.sz.x = strlen(cbx->w.title) + 4; // + "[ ] "
@@ -36,13 +36,13 @@ checkbox_t *init_checkbox(WINDOW **win, widget_t *w_parent, char *label) {
return cbx;
}
int32_t draw_checkbox(checkbox_t *cbx, uint32_t active_id) {
int32_t w_checkbox_draw(w_checkbox_t *cbx, uint32_t active_id) {
char title[DIALOGUE_TITLE + 6];
WINDOW *win = *(cbx->w.parent_win);
uint32_t margin_y = cbx->w.ps.y + cbx->w.m.y;
uint32_t margin_x = cbx->w.ps.x + cbx->w.m.x;
widget_t *w_par = cbx->w.w_parent;
w_t *w_par = cbx->w.w_parent;
while (w_par->parent_win == cbx->w.parent_win) {
margin_y += w_par->ps.y;
@@ -68,4 +68,4 @@ int32_t draw_checkbox(checkbox_t *cbx, uint32_t active_id) {
return strlen(title);
}
void destroy_checkbox(checkbox_t *btn) { free(btn); }
void w_checkbox_destroy(w_checkbox_t *btn) { free(btn); }
+9 -8
View File
@@ -1,20 +1,21 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */
#ifndef CHECKBOX_H
#define CHECKBOX_H
#ifndef W_CHECKBOX_H
#define W_CHECKBOX_H
#include <widget_core.h>
#include <stdint.h>
typedef struct {
widget_t w;
w_t w;
bool is_disabled;
bool value;
} checkbox_t;
} w_checkbox_t;
bool w_checkbox_default_key_action(w_cb_args_t *args);
w_checkbox_t *w_checkbox_init(WINDOW **win, w_t *w_parent, char *label);
int32_t w_checkbox_draw(w_checkbox_t *cbx, uint32_t active_id);
void w_checkbox_destroy(w_checkbox_t *cbx);
bool checkbox_default_key_action(callback_args_t *args);
checkbox_t *init_checkbox(WINDOW **win, widget_t *w_parent, char *label);
int32_t draw_checkbox(checkbox_t *cbx, uint32_t active_id);
void destroy_checkbox(checkbox_t *cbx);
#endif
+38 -38
View File
@@ -11,8 +11,8 @@
#include "file_list.h"
void incr_active_id(dialogue_t *d) {
group_el_t *active_el = NULL;
void incr_active_id(w_dialogue_t *d) {
w_g_el_t *active_el = NULL;
while (true) {
for (int i = d->active_el->id + 1;
active_el == NULL && d->id_map.length > i; i++) {
@@ -29,8 +29,8 @@ void incr_active_id(dialogue_t *d) {
}
}
void decr_active_id(dialogue_t *d) {
group_el_t *active_el = NULL;
void decr_active_id(w_dialogue_t *d) {
w_g_el_t *active_el = NULL;
while (true) {
for (int i = d->active_el->id - 1; active_el == NULL && i > 0; i--) {
active_el = d->id_map.arr[i];
@@ -59,16 +59,16 @@ void decr_active_id(dialogue_t *d) {
} \
}
void dialogue_default_callback(callback_args_t *args) {
dialogue_t *d = (void *)args->element;
void w_dialogue_callback_default(w_cb_args_t *args) {
w_dialogue_t *d = (void *)args->element;
int32_t key = *((int32_t *)args->data);
callback_args_t new_args;
memcpy(&new_args, args, sizeof(callback_args_t));
w_cb_args_t new_args;
memcpy(&new_args, args, sizeof(w_cb_args_t));
new_args.active_el = d->active_el;
int32_t diff;
d->needs_update = true;
input_t *input;
widget_t *widget;
w_input_t *input;
w_t *widget;
switch (key) {
case '\t':
incr_active_id(d);
@@ -87,16 +87,16 @@ void dialogue_default_callback(callback_args_t *args) {
args->resp_data.code = cbrc_none;
break;
case '\n':
widget = (widget_t *)d->active_el->element;
widget = (w_t *)d->active_el->element;
if (widget->callback != NULL) { /* Existing callback case */
new_args.element = widget;
widget->callback(&new_args);
memcpy(&(args->resp_data), &(new_args.resp_data), sizeof(cb_resp_data));
memcpy(&(args->resp_data), &(new_args.resp_data), sizeof(w_cbrp_data));
break;
} /* Default cases */
if (d->active_el->g_type == g_action) {
new_args.element = d->g_action;
group_default_callback(&new_args);
w_group_cb_default(&new_args);
mempcpy(&(args->resp_data), &(new_args.resp_data),
sizeof(new_args.resp_data));
} else if (d->g_action != NULL) {
@@ -116,7 +116,7 @@ void dialogue_default_callback(callback_args_t *args) {
case KEY_UP:
if (d->active_el->type == w_fs_file_list) {
new_args.element = d->g_content;
group_default_callback(&new_args);
w_group_cb_default(&new_args);
} else if (d->active_el->g_type == g_content &&
d->g_content->direction == vertical) {
decr_active_id(d);
@@ -126,7 +126,7 @@ void dialogue_default_callback(callback_args_t *args) {
case KEY_DOWN:
if (d->active_el->type == w_fs_file_list) {
new_args.element = d->g_content;
group_default_callback(&new_args);
w_group_cb_default(&new_args);
} else if (d->active_el->g_type == g_content &&
d->g_content->direction == vertical) {
incr_active_id(d);
@@ -140,11 +140,11 @@ void dialogue_default_callback(callback_args_t *args) {
} else {
new_args.element = d->g_action;
}
group_default_callback(&new_args);
w_group_cb_default(&new_args);
}
}
void init_dialogue(dialogue_t *dialogue, const char title[], const char text[],
void w_dialogue_init(w_dialogue_t *dialogue, const char title[], const char text[],
coordinates_t *p_coordinates) {
uint32_t t_size = 0;
dialogue->win = 0;
@@ -152,7 +152,7 @@ void init_dialogue(dialogue_t *dialogue, const char title[], const char text[],
dialogue->w.sz.x = 0;
dialogue->w.sz.y = 0;
dialogue->p_coordinates = p_coordinates;
dialogue->w.callback = dialogue_default_callback;
dialogue->w.callback = w_dialogue_callback_default;
dialogue->is_initiated = true;
dialogue->needs_update = true;
dialogue->needs_destroy = false;
@@ -160,21 +160,21 @@ void init_dialogue(dialogue_t *dialogue, const char title[], const char text[],
strcpy(dialogue->w.title, title);
t_size = strlen(text);
strcpy(dialogue->text, text);
init_d_arr_ptr(&(dialogue->id_map), MAX_IDS);
u_d_arr_ptr_init(&(dialogue->id_map), MAX_IDS);
/* trim the last new line symbol */
if (t_size && dialogue->text[t_size - 1] == '\n')
dialogue->text[t_size - 1] = '\0';
}
/* variadic */
void vinit_dialogue(dialogue_t *dialogue, const char title[],
void w_dialogue_vinit(w_dialogue_t *dialogue, const char title[],
coordinates_t *p_coordinates, const char fmt[], va_list *v_args) {
char f_text[DIALOGUE_TEXT];
vsprintf(f_text, fmt, *v_args);
init_dialogue(dialogue, title, f_text, p_coordinates);
w_dialogue_init(dialogue, title, f_text, p_coordinates);
}
int group_init_active_id(group_t *g, dialogue_t *d) {
int group_init_active_id(w_group_t *g, w_dialogue_t *d) {
enum w_type wt;
for (int i = 0; i < g->count; i++) {
@@ -184,14 +184,14 @@ int group_init_active_id(group_t *g, dialogue_t *d) {
d->active_el = g->elements + i;
return 1;
} else if (wt == w_group) {
group_t *child_g = g->elements[i].element;
w_group_t *child_g = g->elements[i].element;
return group_init_active_id(child_g, d);
}
}
return 0;
}
void dialogue_init_active_id(dialogue_t *dialogue) {
void w_dialogue_init_active_id(w_dialogue_t *dialogue) {
if (dialogue->g_content != NULL) {
if (group_init_active_id(dialogue->g_content, dialogue)) {
return;
@@ -216,14 +216,14 @@ void dialogue_init_active_id(dialogue_t *dialogue) {
y += group->w.sz.y; \
}
int32_t draw_dialogue(dialogue_t *d) {
int32_t w_dialogue_draw(w_dialogue_t *d) {
if (!d->is_initiated)
return -1;
else if (!d->needs_update) {
return 0;
}
group_el_t *ae_ptr = NULL; /* active element */
w_g_el_t *ae_ptr = NULL; /* active element */
/* count dimensions */
uint32_t x = 1; /* when uses box */
uint32_t y = 1; /* when uses box */
@@ -231,7 +231,7 @@ int32_t draw_dialogue(dialogue_t *d) {
/* analyze text content */
uint32_t line_count = 0;
uint32_t line_max_len = 0;
line_max_len = get_max_line_len(d->text, &line_count);
line_max_len = w_get_max_line_len(d->text, &line_count);
y += line_count;
y += 2; /* margin for text */
@@ -277,20 +277,20 @@ int32_t draw_dialogue(dialogue_t *d) {
/* text */
wattroff(d->win, A_BOLD);
/* mvwhline(d->win, d->w.sz.y - 3, 1, 0, d->w.sz.x - 2); */
print_multiline_text(d->win, d->text, d->w.sz.x, 2, 1, PMT_ALIGN_CENTER);
w_print_multiline_text(d->win, d->text, d->w.sz.x, 2, 1, PMT_ALIGN_CENTER);
wattroff(d->win, A_REVERSE);
if (d->g_content != NULL) {
draw_group(d->win, d->g_content, d->active_el->id);
w_group_draw(d->win, d->g_content, d->active_el->id);
}
if (d->g_action != NULL) {
draw_group(d->win, d->g_action, d->active_el->id);
w_group_draw(d->win, d->g_action, d->active_el->id);
}
/* move cursor */
if (d->active_el != NULL &&
(d->active_el->type == w_input || d->active_el->type == w_checkbox)) {
widget_t *w = d->active_el->element;
w_t *w = d->active_el->element;
d->w.cur.y = w->cur.y;
d->w.cur.x = w->cur.x;
if (d->w.cur.y || d->w.cur.x) {
@@ -307,13 +307,13 @@ int32_t draw_dialogue(dialogue_t *d) {
return 0;
}
void destroy_dialogue(dialogue_t *d, void *_app) {
app_t *app = (app_t *)_app;
void w_dialogue_destroy(w_dialogue_t *d, void *_app) {
w_app_t *app = (w_app_t *)_app;
if (d->g_content) {
destroy_group(d->g_content);
w_group_destroy(d->g_content);
}
if (d->g_action) {
destroy_group(d->g_action);
w_group_destroy(d->g_action);
}
delwin(d->win);
d->win = NULL;
@@ -321,8 +321,8 @@ void destroy_dialogue(dialogue_t *d, void *_app) {
d->needs_destroy = false;
app->active_win_type = aw_left;
app->active_win = app->left_win;
app->active_callback = file_list_cb;
app->active_callback = w_fl_cb;
app->query_args->active_dialogue = NULL;
free_d_arr(&(d->id_map));
app_refresh(app);
u_d_arr_ptr_free(&(d->id_map));
w_app_refresh(app);
}
+15 -15
View File
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */
#ifndef DIALOGUE_H
#define DIALOGUE_H
#ifndef W_DIALOGUE_H
#define W_DIALOGUE_H
#include "../common.h"
#include "group.h"
@@ -12,31 +12,31 @@
#include <widget_core.h>
#define MAX_IDS 64
enum dc_color_scheme { dc_normal, dc_alert };
enum w_dialogue_color_scheme { dc_normal, dc_alert };
typedef struct {
widget_t w;
w_t w;
WINDOW *win;
group_t *g_content;
group_t *g_action;
group_el_t *active_el;
w_group_t *g_content;
w_group_t *g_action;
w_g_el_t *active_el;
char text[DIALOGUE_TEXT];
bool is_initiated;
bool needs_update;
bool needs_destroy;
coordinates_t *p_coordinates;
enum dc_color_scheme color_scheme;
enum w_dialogue_color_scheme color_scheme;
d_array_ptr_t id_map;
} dialogue_t;
} w_dialogue_t;
void init_dialogue(dialogue_t *d, const char title[], const char text[],
void w_dialogue_init(w_dialogue_t *d, const char title[], const char text[],
coordinates_t *p_coordinates);
void vinit_dialogue(dialogue_t *dialogue, const char title[],
void w_dialogue_vinit(w_dialogue_t *dialogue, const char title[],
coordinates_t *p_coordinates, const char fmt[],
va_list *v_args);
int32_t draw_dialogue(dialogue_t *d);
void destroy_dialogue(dialogue_t *d, void *app);
void dialogue_default_callback(callback_args_t *args);
void dialogue_init_active_id(dialogue_t *dialogue);
int32_t w_dialogue_draw(w_dialogue_t *d);
void w_dialogue_destroy(w_dialogue_t *d, void *app);
void w_dialogue_callback_default(w_cb_args_t *args);
void w_dialogue_init_active_id(w_dialogue_t *dialogue);
#endif
+22 -22
View File
@@ -16,11 +16,11 @@
#include <sys/types.h>
#include <unistd.h>
void reset_file_list(ui_file_list_t *fl_ui);
void w_fl_rest(w_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->main_ui->ui;
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);
char q_prefix[128];
if (fui->search_key->slen > 0) {
@@ -33,7 +33,7 @@ void file_list_cb(callback_args_t *args) {
if (key == KEY_BACKSPACE || key == KEY_DL) {
if (blength(fui->search_key)) {
btrunc(fui->search_key, blength(fui->search_key) - 1);
draw_file_list(fui);
w_fl_draw(fui);
}
} else if (key == '\n' || key == '\33') {
fui->active_search = false;
@@ -45,10 +45,10 @@ void file_list_cb(callback_args_t *args) {
}
server_send_string(app->query_args, "%s %u %u\n", q_prefix,
fui->max_lines, 1);
reset_file_list(fui);
w_fl_rest(fui);
} else {
bconchar(fui->search_key, key);
draw_file_list(fui);
w_fl_draw(fui);
}
return;
}
@@ -57,23 +57,23 @@ void file_list_cb(callback_args_t *args) {
case KEY_DOWN:
if (fui->current_idx < fui->current_count - 1) {
fui->current_idx++;
draw_file_list(fui);
w_fl_draw(fui);
} else if (fui->current_page < fui->pages) {
app->query_args->state = S_FILE_LIST;
server_send_string(app->query_args, "%s %u %u\n", q_prefix,
fui->max_lines, fui->current_page + 1);
reset_file_list(fui);
w_fl_rest(fui);
}
break;
case KEY_UP:
if (fui->current_idx > 0) {
fui->current_idx--;
draw_file_list(fui);
w_fl_draw(fui);
} else if (fui->current_page > 1) {
app->query_args->state = S_FILE_LIST;
server_send_string(app->query_args, "%s %u %u\n", q_prefix,
fui->max_lines, fui->current_page - 1);
reset_file_list(fui);
w_fl_rest(fui);
fui->activate_last = true;
}
break;
@@ -82,7 +82,7 @@ void file_list_cb(callback_args_t *args) {
app->query_args->state = S_FILE_LIST;
server_send_string(app->query_args, "%s %u %u\n", q_prefix,
fui->max_lines, fui->current_page + 1);
reset_file_list(fui);
w_fl_rest(fui);
}
break;
case KEY_PPAGE:
@@ -90,7 +90,7 @@ void file_list_cb(callback_args_t *args) {
app->query_args->state = S_FILE_LIST;
server_send_string(app->query_args, "%s %u %u\n", q_prefix,
fui->max_lines, fui->current_page - 1);
reset_file_list(fui);
w_fl_rest(fui);
fui->activate_last = true;
}
break;
@@ -103,16 +103,16 @@ void file_list_cb(callback_args_t *args) {
app->query_args->state = S_FILE_LIST;
server_send_string(app->query_args, "%s %u %u\n", q_prefix, fui->max_lines,
1);
reset_file_list(fui);
w_fl_rest(fui);
case '\n':
ui_file_select(app->file_args, app->query_args, fui->current_idx + 1);
break;
}
}
ui_file_list_t *init_file_list(WINDOW **win, WINDOW *const *info_win) {
ui_file_list_t *fui = malloc(sizeof(ui_file_list_t));
init_widget(&(fui->w), NULL, win, "");
w_ui_file_list_t *w_fl_init(WINDOW **win, WINDOW *const *info_win) {
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);
fui->current_idx = 0;
fui->current_page = 1;
@@ -129,13 +129,13 @@ ui_file_list_t *init_file_list(WINDOW **win, WINDOW *const *info_win) {
return fui;
}
void delete_file_list(ui_file_list_t **fui) {
void w_fl_destroy(w_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) {
void w_fl_rest(w_ui_file_list_t *fl_ui) {
fl_clear(fl_ui->start, fl_ui->current);
fl_ui->current_idx = 0;
fl_ui->current_page = 0;
@@ -146,7 +146,7 @@ void reset_file_list(ui_file_list_t *fl_ui) {
fl_ui->active_search = false;
}
void draw_file_list(ui_file_list_t *fui) {
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);
@@ -186,7 +186,7 @@ void draw_file_list(ui_file_list_t *fui) {
active_el = el;
}
p_x = 1;
p_x += curs_printw(parent_win, p_y, p_x, el->name);
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, "");
if (cur_el_idx == fui->current_idx) {
wattroff(parent_win, A_BOLD | A_REVERSE);
@@ -234,7 +234,7 @@ void draw_file_list(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: ");
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);
}
}
}
+11 -10
View File
@@ -1,14 +1,15 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */
#ifndef FILE_LIST_H
#define FILE_LIST_H
#ifndef W_FILE_LIST_H
#define W_FILE_LIST_H
#include <bstrlib.h>
#include <stdint.h>
#include <widget_core.h>
typedef struct {
widget_t w;
w_t w;
fl_item_t **current;
fl_item_t **start;
int32_t current_idx;
@@ -21,12 +22,12 @@ typedef struct {
bstring search_key;
bool activate_last;
bool active_search;
} ui_file_list_t;
} 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);
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);
void draw_file_list(ui_file_list_t *fl_ui);
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
+38 -38
View File
@@ -19,7 +19,7 @@
#include "fs_file_list.h"
#include "widget_core.h"
void reset_file_list(ui_fs_file_list_t *fl_ui);
void w_fl_rest(w_lfl_ui_t *fl_ui);
struct fl_args {
char *name;
@@ -27,9 +27,9 @@ struct fl_args {
u_char d_type;
};
static void fl_add(fs_fl_item_t **f_start, fs_fl_item_t **f_current,
static void fl_add(w_lfl_item_t **f_start, w_lfl_item_t **f_current,
struct fl_args *fargs) {
fs_fl_item_t *c_item = malloc(sizeof(fs_fl_item_t));
w_lfl_item_t *c_item = malloc(sizeof(w_lfl_item_t));
c_item->name = malloc(strlen(fargs->name) + 1);
strcpy(c_item->name, fargs->name);
c_item->next = NULL;
@@ -49,10 +49,10 @@ static void fl_add(fs_fl_item_t **f_start, fs_fl_item_t **f_current,
}
}
static void fl_clear(fs_fl_item_t **start, fs_fl_item_t **arg_current) {
static void fl_clear(w_lfl_item_t **start, w_lfl_item_t **arg_current) {
if (*start == NULL)
return;
fs_fl_item_t *next, *current;
w_lfl_item_t *next, *current;
current = *start;
do {
@@ -64,7 +64,7 @@ static void fl_clear(fs_fl_item_t **start, fs_fl_item_t **arg_current) {
*arg_current = NULL;
}
static int get_files_from_fs(ui_fs_file_list_t *fui, char *path) {
static int get_files_from_fs(w_lfl_ui_t *fui, char *path) {
DIR *dir;
struct dirent *dent;
char name[257];
@@ -73,8 +73,8 @@ static int get_files_from_fs(ui_fs_file_list_t *fui, char *path) {
ssize_t r = 0;
fui->files_num = 0;
fs_fl_item_t *d_start = NULL, *d_current = NULL; /* directories */
fs_fl_item_t *f_start = NULL, *f_current = NULL; /* files */
w_lfl_item_t *d_start = NULL, *d_current = NULL; /* directories */
w_lfl_item_t *f_start = NULL, *f_current = NULL; /* files */
dir = opendir(path);
if (!dir)
@@ -89,7 +89,7 @@ static int get_files_from_fs(ui_fs_file_list_t *fui, char *path) {
f_args.path = NULL;
if ((f_args.d_type = dent->d_type) == DT_DIR) {
if (!strcmp(dent->d_name, "..")) {
fs_fl_item_t *t_st = NULL, *t_cur = NULL;
w_lfl_item_t *t_st = NULL, *t_cur = NULL;
sprintf(name, "/%s", dent->d_name);
f_args.name = name;
fl_add(&t_st, &t_cur, &f_args);
@@ -138,7 +138,7 @@ static int get_files_from_fs(ui_fs_file_list_t *fui, char *path) {
return 0;
}
void open_selected_item(ui_fs_file_list_t *fui, cb_resp_data *resp_data) {
void open_selected_item(w_lfl_ui_t *fui, w_cbrp_data *resp_data) {
char *bash_case = NULL;
char *selection = NULL;
size_t dp_current;
@@ -150,7 +150,7 @@ void open_selected_item(ui_fs_file_list_t *fui, cb_resp_data *resp_data) {
if (bash_case != NULL) {
*bash_case = '\0';
if (get_files_from_fs(fui, n_path)) {
alert("Can't open the folder!");
w_alert("Can't open the folder!");
return;
}
}
@@ -159,14 +159,14 @@ void open_selected_item(ui_fs_file_list_t *fui, cb_resp_data *resp_data) {
selection = fui->current->name + 1;
sprintf(n_path, "%s/%s", fui->d_path, selection);
if (get_files_from_fs(fui, n_path)) {
alert("Can't open the folder!");
w_alert("Can't open the folder!");
return;
}
}
fui->current = fui->start;
fui->current_idx = 0;
resp_data->code = cbrc_none;
draw_fs_file_list(fui);
w_lfl_draw(fui);
} else if (fui->current->d_type == DT_REG) {
resp_data->code = cbrp_val;
resp_data->val.type = val_num;
@@ -174,20 +174,20 @@ void open_selected_item(ui_fs_file_list_t *fui, cb_resp_data *resp_data) {
} else if (fui->current->d_type == DT_LNK) {
strcpy(n_path, fui->current->path);
if (get_files_from_fs(fui, n_path)) {
alert("Can't open the link!");
w_alert("Can't open the link!");
return;
}
fui->current = fui->start;
fui->current_idx = 0;
resp_data->code = cbrc_none;
draw_fs_file_list(fui);
w_lfl_draw(fui);
}
}
/* next page */
void page_next(ui_fs_file_list_t *fui) {
void page_next(w_lfl_ui_t *fui) {
int count = fui->rows_num;
fs_fl_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) {
for (; count; count--) {
n_page_item = n_page_item->next;
@@ -197,13 +197,13 @@ void page_next(ui_fs_file_list_t *fui) {
fui->current_idx = 0;
fui->current = n_page_item;
}
draw_fs_file_list(fui);
w_lfl_draw(fui);
}
/* previous page */
void page_previous(ui_fs_file_list_t *fui) {
void page_previous(w_lfl_ui_t *fui) {
int count = fui->rows_num;
fs_fl_item_t *n_page_item = fui->page_start;
w_lfl_item_t *n_page_item = fui->page_start;
if (fui->cur_page > 1) {
for (; count; count--) {
n_page_item = n_page_item->prev;
@@ -213,11 +213,11 @@ void page_previous(ui_fs_file_list_t *fui) {
fui->current_idx = 0;
fui->current = n_page_item;
}
draw_fs_file_list(fui);
w_lfl_draw(fui);
}
void fs_file_list_cb(callback_args_t *args) {
ui_fs_file_list_t *fui = args->element;
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:
@@ -225,7 +225,7 @@ void fs_file_list_cb(callback_args_t *args) {
if (fui->current_idx < fui->rows_num - 1) {
fui->current = fui->current->next;
fui->current_idx++;
draw_fs_file_list(fui);
w_lfl_draw(fui);
} else {
page_next(fui);
}
@@ -236,7 +236,7 @@ void fs_file_list_cb(callback_args_t *args) {
if (fui->current_idx > 0) {
fui->current = fui->current->prev;
fui->current_idx--;
draw_fs_file_list(fui);
w_lfl_draw(fui);
} else {
page_previous(fui);
}
@@ -254,17 +254,17 @@ void fs_file_list_cb(callback_args_t *args) {
}
}
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));
w_lfl_ui_t *w_lfl_init(WINDOW **win, w_t *w_parent) {
w_lfl_ui_t *fl_ui = malloc(sizeof(w_lfl_ui_t));
WINDOW *win_par = *(w_parent->w_parent->parent_win);
init_widget(&(fl_ui->w), w_parent, win, "");
w_init(&(fl_ui->w), w_parent, 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.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 */
@@ -272,16 +272,16 @@ 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, "");
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;
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.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 */
@@ -289,9 +289,9 @@ ui_fs_file_list_t *init_fs_file_list_win(WINDOW **win, WINDOW *const *info_win)
return fl_ui;
}
void reset_fs_file_list(ui_fs_file_list_t *fl_ui) { fl_ui->current_idx = 0; }
void w_lfl_reset(w_lfl_ui_t *fl_ui) { fl_ui->current_idx = 0; }
void draw_fs_file_list(ui_fs_file_list_t *fui) {
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);
@@ -303,7 +303,7 @@ void draw_fs_file_list(ui_fs_file_list_t *fui) {
(fui->files_num % fui->rows_num > 0 ? 1 : 0);
p_y = 1;
p_x = 1;
fs_fl_item_t *el = fui->page_start;
w_lfl_item_t *el = fui->page_start;
if (fui->current_idx + 1 >= sz_y_f) {
p_y -= fui->current_idx - sz_y_f + 2;
@@ -319,7 +319,7 @@ void draw_fs_file_list(ui_fs_file_list_t *fui) {
wattrset(win, COLOR_PAIR(3) | A_BOLD | A_REVERSE);
}
p_x = 1;
p_x += curs_printw(win, p_y, p_x, el->name);
p_x += u_utf8_curs_printw(win, p_y, p_x, el->name);
mvwprintw(win, p_y, p_x, "%*s", sz_x_f - p_x, "");
if (el == fui->current) {
wattroff(win, COLOR_PAIR(3) | A_BOLD);
@@ -338,7 +338,7 @@ void draw_fs_file_list(ui_fs_file_list_t *fui) {
curs_set(false);
}
void destroy_fs_file_list(ui_fs_file_list_t *fui) {
void w_lfl_destroy(w_lfl_ui_t *fui) {
fl_clear(&(fui->start), &(fui->current));
free(fui);
}
+16 -15
View File
@@ -1,8 +1,9 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */
#ifndef FS_FILE_LIST_H
#define FS_FILE_LIST_H
#ifndef W_LFL_H /* LOCAL FILE LIST */
#define W_LFL_H
#include <widget_core.h>
#include <ncursesw/ncurses.h>
#include <stdint.h>
@@ -14,13 +15,13 @@ typedef struct fs_fl_item {
struct fs_fl_item *next;
struct fs_fl_item *prev;
u_char d_type;
} fs_fl_item_t;
} w_lfl_item_t;
typedef struct {
widget_t w;
fs_fl_item_t *current;
fs_fl_item_t *start;
fs_fl_item_t *page_start;
w_t w;
w_lfl_item_t *current;
w_lfl_item_t *start;
w_lfl_item_t *page_start;
int32_t current_idx;
int32_t rows_num;
int32_t cur_page;
@@ -28,13 +29,13 @@ typedef struct {
size_t files_num;
WINDOW *const* info_win;
char *d_path;
} ui_fs_file_list_t;
} w_lfl_ui_t;
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(WINDOW **win, WINDOW *const *info_win);
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);
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
+52 -52
View File
@@ -16,35 +16,35 @@
#include <sys/types.h>
#include <utils.h>
bool group_default_key_action(callback_args_t *args) {
group_el_t *element = args->active_el;
bool w_group_default_key_action(w_cb_args_t *args) {
w_g_el_t *element = args->active_el;
switch (element->type) {
case w_input:
return input_default_key_action(args);
return w_input_default_key_action(args);
case w_checkbox:
return checkbox_default_key_action(args);
return w_checkbox_default_key_action(args);
default:
return false;
}
}
void group_default_callback(callback_args_t *args) {
void w_group_cb_default(w_cb_args_t *args) {
int32_t key = *((int32_t *)args->data);
widget_t *widget;
group_el_t *element_ptr = args->active_el;
callback_args_t new_args;
w_t *widget;
w_g_el_t *element_ptr = args->active_el;
w_cb_args_t new_args;
switch (key) {
case '\n': /* Enter */
args->resp_data.code = cbrp_val;
mempcpy(&(args->resp_data.val), &(element_ptr->val), sizeof(struct val_t));
mempcpy(&(args->resp_data.val), &(element_ptr->val), sizeof(struct w_val_t));
break;
default:
if (!group_default_key_action(args)) {
if (!w_group_default_key_action(args)) {
/* callback case */
widget = (widget_t *)element_ptr->element;
widget = (w_t *)element_ptr->element;
if (widget->callback != NULL) {
memccpy(&new_args, args, 1, sizeof(callback_args_t));
memccpy(&new_args, args, 1, sizeof(w_cb_args_t));
new_args.element = element_ptr->element;
widget->callback(&new_args);
break;
@@ -56,31 +56,31 @@ void group_default_callback(callback_args_t *args) {
}
union current_element {
group_t *group;
w_group_t *group;
enum w_type type;
};
group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
d_array_ptr_t *id_map, enum g_direction direction,
enum g_type g_type) {
group_t *group = malloc(sizeof(group_t));
w_group_t *w_group_init(WINDOW **win, w_t *w_parent, w_group_el_init_t *children,
d_array_ptr_t *id_map, enum w_g_dir direction,
enum w_g_type g_type) {
w_group_t *group = malloc(sizeof(w_group_t));
union current_element current;
group->parent_group = NULL;
current.type = w_end;
init_widget(&(group->w), w_parent, win, "");
w_init(&(group->w), w_parent, win, "");
group->w.m.x = 1; /* margin left */
/* count elements */
group->count = 0;
for (; children[group->count].type != w_end; group->count++)
;
group->w.w_parent = w_parent;
group->w.callback = group_default_callback;
group->w.callback = w_group_cb_default;
group->direction = direction;
if (group->count == 0) {
return group;
}
group->elements = calloc(group->count, sizeof(group_el_t));
group_el_t *elements = group->elements;
group->elements = calloc(group->count, sizeof(w_g_el_t));
w_g_el_t *elements = group->elements;
for (int32_t i = 0; i < group->count; i++) {
elements[i].type = children[i].type;
elements[i].is_default = children[i].is_default;
@@ -91,22 +91,22 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
/* init child elements */
for (int32_t i = 0; i < group->count; i++) {
widget_t *w;
w_t *w;
switch (elements[i].type) {
case w_button:
elements[i].element = init_button(win, &(group->w), children[i].label);
elements[i].val.type = val_num;
elements[i].val.val.num = children[i].val.num;
w = &(((button_t *)elements[i].element)->w);
w = &(((w_button_t *)elements[i].element)->w);
break;
case w_box:
case w_end:
break;
case w_group:
elements[i].element = init_group(win, &(group->w), children[i].children,
elements[i].element = w_group_init(win, &(group->w), children[i].children,
id_map, children[i].direction, g_type);
w = &(((group_t *)elements[i].element)->w);
current.group = (group_t *)elements[i].element;
w = &(((w_group_t *)elements[i].element)->w);
current.group = (w_group_t *)elements[i].element;
current.group->parent_group = group;
if (i == 0) {
group->first_id = current.group->first_id;
@@ -118,21 +118,21 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
break;
case w_input:
elements[i].element =
init_input(win, &(group->w), children[i].label, children[i].length,
w_input_init(win, &(group->w), children[i].label, children[i].length,
children[i].is_hidden_value);
w = &(((input_t *)elements[i].element)->w);
w = &(((w_input_t *)elements[i].element)->w);
break;
case w_progress:
elements[i].element = init_ui_progress_bar(win, &(group->w));
w = &(((ui_progress_bar_t *)elements[i].element)->w);
elements[i].element = w_pgb_ui_init(win, &(group->w));
w = &(((w_pgb_ui_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);
elements[i].element = w_lfl_init(win, &(group->w));
w = &(((w_pgb_ui_t *)elements[i].element)->w);
break;
case w_checkbox:
elements[i].element = init_checkbox(win, &(group->w), children[i].label);
w = &(((checkbox_t *)elements[i].element)->w);
elements[i].element = w_checkbox_init(win, &(group->w), children[i].label);
w = &(((w_checkbox_t *)elements[i].element)->w);
break;
}
if (current.type != w_group) {
@@ -146,7 +146,7 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
/* set dimensions */
/* TODO: revise */
elements[i].id = w->id;
add_d_arr_ptr(id_map, elements + i, w->id);
u_d_arr_ptr_add(id_map, elements + i, w->id);
if (direction == horizontal) {
w->ps.x = group->w.ps.x + group->w.sz.x;
w->ps.y = group->w.ps.y;
@@ -168,61 +168,61 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
return group;
}
void draw_group(WINDOW *win, group_t *group, int32_t active_id) {
group_el_t *children = group->elements;
void w_group_draw(WINDOW *win, w_group_t *group, int32_t active_id) {
w_g_el_t *children = group->elements;
for (int i = 0; i < group->count; i++) {
group_el_t *el = &children[i];
w_g_el_t *el = &children[i];
switch (el->type) {
case w_button:
draw_button((button_t *)el->element, active_id);
draw_button((w_button_t *)el->element, active_id);
break;
case w_group:
draw_group(win, (group_t *)el->element, active_id);
w_group_draw(win, (w_group_t *)el->element, active_id);
break;
case w_box:
case w_end:
break;
case w_input:
draw_input((input_t *)el->element, active_id);
w_input_draw((w_input_t *)el->element, active_id);
break;
case w_progress:
draw_ui_progress_bar((ui_progress_bar_t *)el->element);
w_pgb_ui_draw((w_pgb_ui_t *)el->element);
break;
case w_fs_file_list:
draw_fs_file_list((ui_fs_file_list_t *)el->element);
w_lfl_draw((w_lfl_ui_t *)el->element);
break;
case w_checkbox:
draw_checkbox((checkbox_t *)el->element, active_id);
w_checkbox_draw((w_checkbox_t *)el->element, active_id);
break;
}
}
}
void destroy_group(group_t *group) {
group_el_t *children = group->elements;
void w_group_destroy(w_group_t *group) {
w_g_el_t *children = group->elements;
for (int i = 0; i < group->count; i++) {
group_el_t *el = &children[i];
w_g_el_t *el = &children[i];
switch (el->type) {
case w_button:
destroy_button(el->element);
break;
case w_group:
destroy_group(el->element);
w_group_destroy(el->element);
break;
case w_box:
case w_end:
break;
case w_input:
destroy_input(el->element);
w_input_destroy(el->element);
break;
case w_progress:
destroy_ui_progress_bar(el->element);
w_pgb_ui_destroy(el->element);
break;
case w_fs_file_list:
destroy_fs_file_list(el->element);
w_lfl_destroy(el->element);
break;
case w_checkbox:
destroy_checkbox(el->element);
w_checkbox_destroy(el->element);
break;
}
}
+14 -14
View File
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */
#ifndef GROUP_H
#define GROUP_H
#ifndef W_GROUP_H
#define W_GROUP_H
#include <stdint.h>
#include <utils.h>
@@ -14,27 +14,27 @@ typedef struct group_el_init_t {
bool is_hidden_value;
char label[DIALOGUE_TITLE];
uint32_t length;
enum g_direction direction;
enum w_g_dir direction;
union {
int64_t num;
} val;
struct group_el_init_t *children;
} group_el_init_t;
} w_group_el_init_t;
typedef struct group_t {
widget_t w;
group_el_t *elements;
enum g_direction direction;
w_t w;
w_g_el_t *elements;
enum w_g_dir direction;
uint32_t count;
uint32_t first_id, last_id;
struct group_t *parent_group;
} group_t;
} w_group_t;
group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
d_array_ptr_t *id_map, enum g_direction dir,
enum g_type g_type);
void draw_group(WINDOW *win, group_t *group, int32_t active_id);
void destroy_group(group_t *group);
void group_default_callback(callback_args_t *args);
w_group_t *w_group_init(WINDOW **win, w_t *w_parent, w_group_el_init_t *children,
d_array_ptr_t *id_map, enum w_g_dir dir,
enum w_g_type g_type);
void w_group_draw(WINDOW *win, w_group_t *group, int32_t active_id);
void w_group_destroy(w_group_t *group);
void w_group_cb_default(w_cb_args_t *args);
#endif
+9 -9
View File
@@ -10,10 +10,10 @@
#include "input.h"
#include <widget_core.h>
bool input_default_key_action(callback_args_t *args) {
bool w_input_default_key_action(w_cb_args_t *args) {
int32_t key = *((int32_t *)args->data);
group_el_t *g_el = args->active_el;
input_t *input = g_el->element;
w_g_el_t *g_el = args->active_el;
w_input_t *input = g_el->element;
int64_t start_pos = 0;
switch (key) {
@@ -45,10 +45,10 @@ bool input_default_key_action(callback_args_t *args) {
return true;
}
input_t *init_input(WINDOW **win, widget_t *w_parent, char *label,
w_input_t *w_input_init(WINDOW **win, w_t *w_parent, char *label,
uint32_t length, uint32_t is_hidden_value) {
input_t *input = malloc(sizeof(input_t));
init_widget(&(input->w), w_parent, win, label);
w_input_t *input = malloc(sizeof(w_input_t));
w_init(&(input->w), w_parent, win, label);
input->is_disabled = 0;
input->w.sz.y = 3; // with borders
input->w.sz.x =
@@ -65,14 +65,14 @@ input_t *init_input(WINDOW **win, widget_t *w_parent, char *label,
return input;
}
int32_t draw_input(input_t *input, uint32_t active_id) {
int32_t w_input_draw(w_input_t *input, uint32_t active_id) {
const char stars[] = "*******************";
WINDOW *win = *(input->w.parent_win);
uint32_t pos_y = input->w.ps.y + input->w.m.y;
uint32_t pos_x = input->w.ps.x + input->w.m.x;
/* counts margins of the ancestors of the same window */
widget_t *w_par = input->w.w_parent;
w_t *w_par = input->w.w_parent;
while (w_par->parent_win == input->w.parent_win) {
pos_y += w_par->ps.y;
pos_x += w_par->ps.x;
@@ -123,4 +123,4 @@ int32_t draw_input(input_t *input, uint32_t active_id) {
return 0;
}
void destroy_input(input_t *btn) { free(btn); }
void w_input_destroy(w_input_t *btn) { free(btn); }
+9 -8
View File
@@ -1,26 +1,27 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */
#ifndef INPUT_H
#define INPUT_H
#ifndef W_INPUT_H
#define W_INPUT_H
#include "../main.h"
#include <widget_core.h>
#include <stdint.h>
typedef struct {
widget_t w;
w_t w;
char value[INPUT_TEXT];
int64_t cur_pos; /* is relative to the end of a string */
int64_t value_len;
int64_t max_len;
bool is_disabled;
bool is_hidden;
} input_t;
} w_input_t;
bool input_default_key_action(callback_args_t *args);
input_t *init_input(WINDOW **win, widget_t *w_parent, char *label,
bool w_input_default_key_action(w_cb_args_t *args);
w_input_t *w_input_init(WINDOW **win, w_t *w_parent, char *label,
uint32_t size, uint32_t is_hidden_value);
int32_t draw_input(input_t *input, uint32_t active_id);
void destroy_input(input_t *input);
int32_t w_input_draw(w_input_t *input, uint32_t active_id);
void w_input_destroy(w_input_t *input);
#endif
+6 -6
View File
@@ -7,10 +7,10 @@
#include <stdint.h>
#include <stdlib.h>
ui_progress_bar_t *init_ui_progress_bar(WINDOW **win, widget_t *w_parent) {
w_pgb_ui_t *w_pgb_ui_init(WINDOW **win, w_t *w_parent) {
WINDOW *win_par = *(w_parent->w_parent->parent_win);
ui_progress_bar_t *pb = malloc(sizeof(ui_progress_bar_t));
init_widget(&pb->w, w_parent, win, "");
w_pgb_ui_t *pb = malloc(sizeof(w_pgb_ui_t));
w_init(&pb->w, w_parent, win, "");
pb->procent = 0;
pb->text[0] = '\0';
pb->w.sz.y = 4;
@@ -18,7 +18,7 @@ ui_progress_bar_t *init_ui_progress_bar(WINDOW **win, widget_t *w_parent) {
return pb;
}
void draw_ui_progress_bar(ui_progress_bar_t *pb) {
void w_pgb_ui_draw(w_pgb_ui_t *pb) {
WINDOW *win = *(pb->w.w_parent->parent_win);
uint32_t margin_y = pb->w.ps.y + pb->w.w_parent->ps.y;
uint32_t margin_x = pb->w.ps.x + pb->w.w_parent->ps.x + 1;
@@ -55,7 +55,7 @@ void draw_ui_progress_bar(ui_progress_bar_t *pb) {
mvwvline(win, margin_y + 3, margin_x + pb->w.sz.x - 2, ACS_LRCORNER, 1);
}
void destroy_ui_progress_bar(void *_pb) {
ui_progress_bar_t *pb = (ui_progress_bar_t *)_pb;
void w_pgb_ui_destroy(void *_pb) {
w_pgb_ui_t *pb = (w_pgb_ui_t *)_pb;
free(pb);
}
+9 -5
View File
@@ -3,13 +3,17 @@
#ifndef PROGRESS_BAR_H
#define PROGRESS_BAR_H
#include <widget_core.h>
typedef struct {
widget_t w;
w_t w;
uint32_t procent;
char text[24];
} ui_progress_bar_t;
void destroy_ui_progress_bar(void *_pb);
void draw_ui_progress_bar(ui_progress_bar_t *pb);
ui_progress_bar_t *init_ui_progress_bar(WINDOW **win, widget_t *w_parent);
} w_pgb_ui_t;
w_pgb_ui_t *w_pgb_ui_init(WINDOW **win, w_t *w_parent);
void w_pgb_ui_draw(w_pgb_ui_t *pb);
void w_pgb_ui_destroy(void *_pb);
#endif
+2
View File
@@ -8,6 +8,7 @@
#ifndef WIDGET_H
#define WIDGET_H
#include "app.h"
#include "button.h"
#include "dialogue.h"
@@ -18,4 +19,5 @@
#include "progress_bar.h"
#include "checkbox.h"
#include "alert.h"
#endif
+8 -29
View File
@@ -14,9 +14,8 @@
#include <utils.h>
extern uint32_t m_id;
int32_t rsize_to_value(int32_t size, enum rsize rsize);
void init_widget(widget_t *w, widget_t *w_parent, WINDOW **win, char *title) {
void w_init(w_t *w, w_t *w_parent, WINDOW **win, char *title) {
w->id = m_id++;
w->sz.x = 0;
w->sz.y = 0;
@@ -36,7 +35,7 @@ void init_widget(widget_t *w, widget_t *w_parent, WINDOW **win, char *title) {
strcpy(w->title, title);
}
int32_t get_max_line_len(const char *text, uint32_t *line_count) {
int32_t w_get_max_line_len(const char *text, uint32_t *line_count) {
uint32_t nl_pos = 0; /* new line position */
uint32_t c_len = 0; /* current line length */
uint32_t m_len = 0; /* max length */
@@ -79,17 +78,17 @@ void PRINT_TEXT(WINDOW *win, char *l_buf, char *text, int64_t i,
int64_t utf8len = 0;
strncpy(l_buf, text + i - c_line_len, c_line_len);
l_buf[c_line_len] = '\0';
utf8len = count_utf8_code_points(l_buf);
utf8len = u_utf8_code_points_count(l_buf);
if ((attrs & PMT_ALIGN_CENTER) == PMT_ALIGN_CENTER) {
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);
} else if (attrs & PMT_POS_CENTER) {
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);
} else {
curs_printw(win, line_v_pos, x, l_buf);
u_utf8_curs_printw(win, line_v_pos, x, l_buf);
}
}
uint32_t print_multiline_text(WINDOW *win, const char *_text,
uint32_t w_print_multiline_text(WINDOW *win, const char *_text,
const uint32_t win_width, const uint32_t y,
const uint32_t x, const uint16_t attrs) {
@@ -120,7 +119,7 @@ uint32_t print_multiline_text(WINDOW *win, const char *_text,
}
if (attrs & PMT_POS_CENTER) {
m_line_len = get_max_line_len(text, NULL);
m_line_len = w_get_max_line_len(text, NULL);
}
for (; text[i]; i++, c_line_len++) {
@@ -139,23 +138,3 @@ uint32_t print_multiline_text(WINDOW *win, const char *_text,
return 1;
}
int32_t rsize_to_value(int32_t size, enum rsize rsize) {
switch (rsize) {
case s_1:
return size;
case s_1_2:
return size / 2;
case s_1_3:
return size / 3;
case s_2_3:
return size / 3 * 2;
case s_1_4:
return size / 4;
case s_3_4:
return size / 4 * 3;
case s_auto:
default:
return size;
}
}
+25 -33
View File
@@ -8,9 +8,9 @@
#include <ncursesw/ncurses.h>
#include <stdint.h>
enum g_type { g_content, g_action };
enum w_g_type { g_content, g_action };
enum g_direction {
enum w_g_dir {
horizontal,
vertical,
};
@@ -26,14 +26,14 @@ enum w_type {
w_fs_file_list,
};
enum val_type {
enum w_val_type {
val_num,
val_ptr,
val_nul,
};
struct val_t {
enum val_type type;
struct w_val_t {
enum w_val_type type;
union {
void *ptr;
int64_t num;
@@ -45,42 +45,34 @@ typedef struct {
int64_t idx; /* element index in the group */
void *element;
enum w_type type;
enum g_type g_type;
enum w_g_type g_type;
bool is_default;
struct val_t val;
} group_el_t;
struct w_val_t val;
} w_g_el_t;
enum cbrp_code {
/* widget callback response code */
enum w_cbrp_code {
cbrc_none, /* default */
cbrp_val,
cbrp_g_el, /* element of type group_el_t */
cbrp_err
};
/* widget callback response data */
typedef struct {
enum cbrp_code code;
struct val_t val;
} cb_resp_data;
enum w_cbrp_code code;
struct w_val_t val;
} w_cbrp_data;
typedef struct {
void *app;
void *element;
void *data;
cb_resp_data resp_data;
w_cbrp_data resp_data;
void *active_el;
} callback_args_t;
} w_cb_args_t;
enum rsize {
s_auto,
s_1,
s_1_2,
s_1_3,
s_2_3,
s_1_4,
s_3_4,
};
typedef struct widget_t {
typedef struct w_t {
int64_t id;
char title[DIALOGUE_TITLE];
struct {
@@ -100,20 +92,20 @@ typedef struct widget_t {
int64_t x;
} ps; /* position (relative to the window) */
WINDOW *const *parent_win;
struct widget_t *w_parent;
void (*callback)(callback_args_t *args);
} widget_t;
struct w_t *w_parent;
void (*callback)(w_cb_args_t *args);
} w_t;
typedef void (*callback_t)(callback_args_t *args);
typedef void (*w_cb_t)(w_cb_args_t *args);
enum pmt_attrs {
enum w_pmt_attrs {
PMT_POS_CENTER = 01,
PMT_ALIGN_CENTER = 03,
};
void init_widget(widget_t *w, widget_t *w_parent, WINDOW **win, char *title);
int32_t get_max_line_len(const char *text, uint32_t *line_count);
uint32_t print_multiline_text(WINDOW *win, const char *text,
void w_init(w_t *w, w_t *w_parent, WINDOW **win, char *title);
int32_t w_get_max_line_len(const char *text, uint32_t *line_count);
uint32_t w_print_multiline_text(WINDOW *win, const char *text,
const uint32_t win_width, const uint32_t y,
const uint32_t x, const uint16_t attrs);