ui: file list modal (not finished)

This commit is contained in:
2026-01-15 15:04:36 +02:00
parent cb79978cdf
commit 4661a36acf
9 changed files with 64 additions and 45 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ void init_nc() {
cbreak(); cbreak();
keypad(stdscr, TRUE); keypad(stdscr, TRUE);
noecho(); noecho();
curs_set(0); curs_set(false);
if (!has_colors()) { if (!has_colors()) {
printf("Your terminal does not support color\n"); printf("Your terminal does not support color\n");
+1 -1
View File
@@ -20,7 +20,7 @@ void server_message_modal_cb(callback_args_t *args) {
memcpy(&d_args, args, sizeof(callback_args_t)); memcpy(&d_args, args, sizeof(callback_args_t));
d_args.app = NULL; d_args.app = NULL;
d_args.resp_data = &response; d_args.resp_data = &response;
d_args.widget = app->active_widget; d_args.element = app->active_widget;
dialogue_default_callback(&d_args); dialogue_default_callback(&d_args);
if (response > -1) { if (response > -1) {
switch (response) { switch (response) {
+2 -4
View File
@@ -13,7 +13,7 @@ void upload_dialogue_modal_cb(callback_args_t *args) {
memcpy(&d_args, args, sizeof(callback_args_t)); memcpy(&d_args, args, sizeof(callback_args_t));
d_args.app = NULL; d_args.app = NULL;
d_args.resp_data = &response; d_args.resp_data = &response;
d_args.widget = app->active_widget; d_args.element = app->active_widget;
dialogue_default_callback(&d_args); dialogue_default_callback(&d_args);
if (response > -1) { if (response > -1) {
switch (response) { switch (response) {
@@ -30,12 +30,11 @@ dialogue_t *init_upload_dialogue_modal(app_t *app) {
if (app == NULL) if (app == NULL)
return NULL; return NULL;
group_el_init_t content[] = { group_el_init_t content[] = {
{.type = w_input, .label = "File description", .length = 30}, // {.type = w_input, .label = "File description", .length = 30},
{.type = w_fs_file_list, .label = "File", .length = 30}, {.type = w_fs_file_list, .label = "File", .length = 30},
{.type = w_end}}; {.type = w_end}};
group_el_init_t actions[] = { group_el_init_t actions[] = {
{.type = w_button, .label = "Upload", .is_default = 1},
{.type = w_button, .label = "Cancel", .is_default = 0}, {.type = w_button, .label = "Cancel", .is_default = 0},
{.type = w_end}}; {.type = w_end}};
@@ -48,7 +47,6 @@ dialogue_t *init_upload_dialogue_modal(app_t *app) {
d->g_content = init_group(&(d->win), &(d->w), content, horizontal); d->g_content = init_group(&(d->win), &(d->w), content, horizontal);
d->g_action = init_group(&(d->win), &(d->w), actions, horizontal); d->g_action = init_group(&(d->win), &(d->w), actions, horizontal);
app->query_args->progress_bar = d->g_content->elements[0].element;
app->query_args->active_dialogue = d; app->query_args->active_dialogue = d;
dialogue_init_active_id(d); dialogue_init_active_id(d);
+1 -1
View File
@@ -17,7 +17,7 @@ enum w_type {
typedef struct { typedef struct {
void *app; void *app;
void *widget; void *element;
void *data; void *data;
void *resp_data; void *resp_data;
uint32_t active_id; uint32_t active_id;
+25 -11
View File
@@ -43,7 +43,7 @@
} }
void dialogue_default_callback(callback_args_t *args) { void dialogue_default_callback(callback_args_t *args) {
dialogue_t *d = (void *)args->widget; dialogue_t *d = (void *)args->element;
int32_t key = *((int32_t *)args->data); int32_t key = *((int32_t *)args->data);
app_t *app = (app_t *)args->app; app_t *app = (app_t *)args->app;
callback_args_t new_args; callback_args_t new_args;
@@ -54,7 +54,7 @@ void dialogue_default_callback(callback_args_t *args) {
int32_t diff; int32_t diff;
d->needs_update = true; d->needs_update = true;
input_t *input; input_t *input;
switch (key) { switch (key) {
case '\t': case '\t':
if (d->active.type == g_content) { if (d->active.type == g_content) {
INCR_ACTIVE_ID(d, g_content, g_action); INCR_ACTIVE_ID(d, g_content, g_action);
@@ -99,7 +99,7 @@ void dialogue_default_callback(callback_args_t *args) {
break; break;
case '\n': case '\n':
if (d->active.type == g_action) { if (d->active.type == g_action) {
new_args.widget = new_args.widget = d->g_action; new_args.element = new_args.element = d->g_action;
group_default_callback(&new_args); group_default_callback(&new_args);
} else if (d->g_action != NULL) { } else if (d->g_action != NULL) {
for (int i = 0; i < d->g_action->count; i++) { for (int i = 0; i < d->g_action->count; i++) {
@@ -115,17 +115,29 @@ void dialogue_default_callback(callback_args_t *args) {
} }
break; break;
case KEY_UP: case KEY_UP:
CH_GROUP(d, g_action, g_content); if (d->g_content->elements[d->active.id - d->g_content->first_id].type ==
w_fs_file_list) {
new_args.element = d->g_content;
group_default_callback(&new_args);
} else {
CH_GROUP(d, g_action, g_content);
}
break; break;
case KEY_DOWN: case KEY_DOWN:
CH_GROUP(d, g_content, g_action); if (d->g_content->elements[d->active.id - d->g_content->first_id].type ==
w_fs_file_list) {
new_args.element = d->g_content;
group_default_callback(&new_args);
} else {
CH_GROUP(d, g_content, g_action);
}
break; break;
default: default:
/* run callback function */ /* run callback function */
if (d->active.type == g_content) { if (d->active.type == g_content) {
new_args.widget = new_args.widget = d->g_content; new_args.element = new_args.element = d->g_content;
} else { } else {
new_args.widget = new_args.widget = d->g_action; new_args.element = new_args.element = d->g_action;
} }
group_default_callback(&new_args); group_default_callback(&new_args);
} }
@@ -152,7 +164,8 @@ void dialogue_init_active_id(dialogue_t *dialogue) {
if (dialogue->g_content != NULL) { if (dialogue->g_content != NULL) {
for (int i = 0; i < dialogue->g_content->count; i++) { for (int i = 0; i < dialogue->g_content->count; i++) {
widget_type = dialogue->g_content->elements[i].type; widget_type = dialogue->g_content->elements[i].type;
if (widget_type == w_button || widget_type == w_input) { if (widget_type == w_button || widget_type == w_input ||
widget_type == w_fs_file_list) { /* Add here new types */
dialogue->active.type = g_content; dialogue->active.type = g_content;
widget_t *w = (widget_t *)dialogue->g_content->elements[i].element; widget_t *w = (widget_t *)dialogue->g_content->elements[i].element;
dialogue->active.id = w->id; dialogue->active.id = w->id;
@@ -162,7 +175,8 @@ void dialogue_init_active_id(dialogue_t *dialogue) {
} else if (dialogue->g_action != NULL) { } else if (dialogue->g_action != NULL) {
for (int i = 0; i < dialogue->g_action->count; i++) { for (int i = 0; i < dialogue->g_action->count; i++) {
widget_type = dialogue->g_action->elements[i].type; widget_type = dialogue->g_action->elements[i].type;
if (widget_type == w_button || widget_type == w_input) { if (widget_type == w_button || widget_type == w_input ||
widget_type == w_fs_file_list) {
dialogue->active.type = g_action; dialogue->active.type = g_action;
widget_t *w = (widget_t *)dialogue->g_action->elements[i].element; widget_t *w = (widget_t *)dialogue->g_action->elements[i].element;
dialogue->active.id = w->id; dialogue->active.id = w->id;
@@ -264,10 +278,10 @@ int32_t draw_dialogue(dialogue_t *d) {
d->w.cur.x -= input->cur_pos; d->w.cur.x -= input->cur_pos;
if (d->w.cur.y || d->w.cur.x) { if (d->w.cur.y || d->w.cur.x) {
wmove(d->win, d->w.cur.y, d->w.cur.x); wmove(d->win, d->w.cur.y, d->w.cur.x);
curs_set(1); curs_set(true);
} }
} else { } else {
curs_set(0); curs_set(false);
} }
} }
+1 -1
View File
@@ -87,7 +87,7 @@ void draw_file_list(ui_file_list_t *fl_ui) {
fl_item_t *el = *(fl_ui->start); fl_item_t *el = *(fl_ui->start);
fl_item_t *active_el = *(fl_ui->start); fl_item_t *active_el = *(fl_ui->start);
int32_t cur_el_idx = 0; int32_t cur_el_idx = 0;
curs_set(0); curs_set(false);
if (fl_ui->activate_last) { if (fl_ui->activate_last) {
fl_ui->current_idx = fl_ui->current_count - 1; fl_ui->current_idx = fl_ui->current_count - 1;
+17 -16
View File
@@ -1,6 +1,6 @@
#include "fs_file_list.h"
#include "../../file_processor.h" #include "../../file_processor.h"
#include "../app.h" #include "../app.h"
#include "fs_file_list.h"
#include "progress_bar.h" #include "progress_bar.h"
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
@@ -27,6 +27,7 @@ static void fl_add(fl_item_t **f_start, fl_item_t **f_current,
*f_current = c_item; *f_current = c_item;
} else { } else {
(*f_current)->next = c_item; (*f_current)->next = c_item;
*f_current = c_item;
} }
} }
@@ -48,8 +49,7 @@ fl_item_t *get_files_from_fs(char *path) {
} }
void fs_file_list_cb(callback_args_t *args) { void fs_file_list_cb(callback_args_t *args) {
app_t *app = args->app; ui_fs_file_list_t *fui = args->element;
ui_fs_file_list_t *fui = app->query_args->file_list_ui;
int32_t key = *((int32_t *)args->data); int32_t key = *((int32_t *)args->data);
int32_t q_len = 0; int32_t q_len = 0;
fl_item_t *f_item; fl_item_t *f_item;
@@ -87,6 +87,9 @@ ui_fs_file_list_t *init_fs_file_list(WINDOW **win, widget_t *w_parent) {
fl_ui->current_count = 0; fl_ui->current_count = 0;
fl_ui->activate_last = false; fl_ui->activate_last = false;
fl_ui->info_win = NULL; fl_ui->info_win = NULL;
fl_ui->start = malloc(sizeof(fl_item_t *)); /* For compatibility reasons */
*(fl_ui->start) = get_files_from_fs("./");
fl_ui->w.callback = fs_file_list_cb;
return fl_ui; return fl_ui;
} }
@@ -102,12 +105,12 @@ void draw_fs_file_list(ui_fs_file_list_t *fl_ui) {
WINDOW *win = *(fl_ui->w.parent_win); WINDOW *win = *(fl_ui->w.parent_win);
getmaxyx(win, sz_y, sz_x); getmaxyx(win, sz_y, sz_x);
int32_t sz_y_f = sz_y - 2; // actual size (without box) int32_t sz_y_f = sz_y - 2; // actual size (without box)
int32_t sz_x_f = sz_x - 2; // actual size (without box)
p_y = 1; p_y = 1;
p_x = 1; p_x = 1;
fl_item_t *el = *(fl_ui->start); fl_item_t *el = *(fl_ui->start);
fl_item_t *active_el = *(fl_ui->start); fl_item_t *active_el = *(fl_ui->start);
int32_t cur_el_idx = 0; int32_t cur_el_idx = 0;
curs_set(0);
if (fl_ui->activate_last) { if (fl_ui->activate_last) {
fl_ui->current_idx = fl_ui->current_count - 1; fl_ui->current_idx = fl_ui->current_count - 1;
@@ -118,6 +121,8 @@ void draw_fs_file_list(ui_fs_file_list_t *fl_ui) {
p_y -= fl_ui->current_idx - sz_y_f + 2; p_y -= fl_ui->current_idx - sz_y_f + 2;
} }
wattrset(win, A_REVERSE); /* Match with window background */
do { do {
if (p_y < 1) { if (p_y < 1) {
p_y++; p_y++;
@@ -125,14 +130,14 @@ void draw_fs_file_list(ui_fs_file_list_t *fl_ui) {
continue; continue;
} }
if (cur_el_idx == fl_ui->current_idx) { if (cur_el_idx == fl_ui->current_idx) {
wattrset(win, A_BOLD | A_REVERSE); wattrset(win, COLOR_PAIR(3) | A_BOLD | A_REVERSE);
active_el = el; active_el = el;
} }
p_x = 1; p_x = 1;
mvwprintw(win, p_y, p_x, "%s%n", el->name, &p_x); mvwprintw(win, p_y, p_x, "%s%n", el->name, &p_x);
mvwprintw(win, p_y, p_x + 1, "%*s", sz_x - p_x, ""); mvwprintw(win, p_y, p_x + 1, "%*s", sz_x_f - p_x, "");
if (cur_el_idx == fl_ui->current_idx) { if (cur_el_idx == fl_ui->current_idx) {
wattroff(win, A_BOLD | A_REVERSE); wattroff(win, COLOR_PAIR(3) | A_BOLD);
} }
p_y++; p_y++;
cur_el_idx++; cur_el_idx++;
@@ -141,20 +146,16 @@ void draw_fs_file_list(ui_fs_file_list_t *fl_ui) {
p_x = 1; p_x = 1;
for (; p_y < sz_y_f; p_y++) { for (; p_y < sz_y_f; p_y++) {
mvwprintw(win, p_y, p_x, "%*s", sz_x - 1, ""); mvwprintw(win, p_y, p_x, "%*s", sz_x_f - 1, "");
} }
char p_info[24];
uint32_t p_len;
p_x = 1;
uint32_t l_pad = (sz_x - p_len) / 2; wattroff(win, A_BOLD | A_REVERSE);
wattrset(win, COLOR_PAIR(0));
wattrset(win, A_BOLD); curs_set(false);
mvwprintw(win, p_y, p_x, "%*s%s%*s", l_pad, "", p_info, l_pad, "");
wattroff(win, A_BOLD);
} }
void destroy_fs_file_list(ui_fs_file_list_t *fui) { void destroy_fs_file_list(ui_fs_file_list_t *fui) {
fl_clear(fui->start, fui->current); fl_clear(fui->start, fui->current);
free(fui->start);
free(fui); free(fui);
} }
+11 -1
View File
@@ -16,13 +16,15 @@
} }
void group_default_callback(callback_args_t *args) { void group_default_callback(callback_args_t *args) {
group_t *g = (group_t *)args->widget; group_t *g = (group_t *)args->element;
int32_t key = *((int32_t *)args->data); int32_t key = *((int32_t *)args->data);
int32_t *response = (int32_t *)args->resp_data; int32_t *response = (int32_t *)args->resp_data;
input_t *input; input_t *input;
widget_t *widget;
group_el_t *element_ptr; group_el_t *element_ptr;
int32_t element_idx = -1; int32_t element_idx = -1;
u_int32_t start_pos = 0; u_int32_t start_pos = 0;
callback_args_t new_args;
switch (key) { switch (key) {
case '\n': /* Enter */ case '\n': /* Enter */
FIND_ACTIVE_ELEMENT(g, args->active_id, element_ptr, element_idx); FIND_ACTIVE_ELEMENT(g, args->active_id, element_ptr, element_idx);
@@ -60,6 +62,13 @@ void group_default_callback(callback_args_t *args) {
input->value[input->value_len] = '\0'; input->value[input->value_len] = '\0';
} }
} }
} else {
widget = (widget_t *) element_ptr->element;
if (widget->callback != NULL) {
memccpy(&new_args, args, 1, sizeof(callback_args_t *));
new_args.element = element_ptr->element;
widget->callback(&new_args);
}
} }
MAKE_RESPONSE_M1(args, resp_data, response); MAKE_RESPONSE_M1(args, resp_data, response);
break; break;
@@ -124,6 +133,7 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
} }
if (i == 0) { if (i == 0) {
group->first_id = w->id; group->first_id = w->id;
group->last_id = w->id;
} else { } else {
group->last_id = w->id; group->last_id = w->id;
} }
+5 -9
View File
@@ -32,18 +32,14 @@ typedef struct {
uint32_t first_id, last_id; uint32_t first_id, last_id;
} group_t; } group_t;
#define FIND_ACTIVE_ELEMENT(g, active_id, element_ptr, element_idx) \ #define FIND_ACTIVE_ELEMENT(g, active_id, element_ptr, element_idx) \
for (int i = 0; i < g->count; i++) { \ element_idx = active_id - g->first_id; \
if (g->elements[i].id == active_id) { \ element_ptr = &(g->elements[element_idx]);
element_ptr = &(g->elements[i]); \
element_idx = i; \
break; \
} \
}
group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,
enum g_direction dir); enum g_direction dir);
void draw_group(WINDOW *win, group_t *group, int32_t active_id, widget_t *dialog_w); void draw_group(WINDOW *win, group_t *group, int32_t active_id,
widget_t *dialog_w);
void destroy_group(group_t *group); void destroy_group(group_t *group);
void group_default_callback(callback_args_t *args); void group_default_callback(callback_args_t *args);