From eee2bc0ccb847c7c3f9d9fadfd924a48b87e9b52 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Wed, 3 Dec 2025 14:40:53 +0200 Subject: [PATCH] initial callback support --- src/deps.mk | 6 +++--- src/main.c | 39 ++++++++++++--------------------------- src/ui/modals/login.c | 7 ++----- src/ui/widget.c | 1 + src/ui/widget.h | 2 +- src/ui/widget/button.c | 16 ++++------------ src/ui/widget/button.h | 5 +---- src/ui/widget/dialogue.c | 20 +++++++++++++++++++- src/ui/widget/dialogue.h | 1 + src/ui/widget/group.c | 27 +++++++++++++++++---------- src/ui/widget/group.h | 2 ++ 11 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/deps.mk b/src/deps.mk index 386a9ca..76352f4 100644 --- a/src/deps.mk +++ b/src/deps.mk @@ -6,9 +6,9 @@ file_processor.o: src/file_processor.c src/client.h src/main.h \ main.o: src/main.c src/ui/app.h src/ui/widget/dialogue.h \ src/ui/widget/../widget.h src/ui/widget/../../main.h \ src/ui/widget/../../types.h src/ui/widget/button.h \ - src/ui/widget/../../main.h src/ui/widget/group.h \ - src/ui/widget/dialogue.h src/ui/modals/login.h \ - src/ui/modals/../widget/dialogue.h src/ui/modals/../app.h + src/ui/widget/../../main.h src/ui/widget/group.h src/ui/modals/login.h \ + src/ui/modals/../widget/dialogue.h src/ui/modals/../app.h \ + src/ui/widget/dialogue.h modal.o: src/modal.c src/ui/app.h src/ui/widget/dialogue.h \ src/ui/widget/../widget.h src/ui/widget/../../main.h \ src/ui/widget/../../types.h src/ui/widget/button.h \ diff --git a/src/main.c b/src/main.c index f4eee3a..7e51e9a 100644 --- a/src/main.c +++ b/src/main.c @@ -1,17 +1,17 @@ +#include +#include +#include #include #include -#include #include #include -#include #include #include #include -#include #include "ui/app.h" -#include "ui/widget/dialogue.h" #include "ui/modals/login.h" +#include "ui/widget/dialogue.h" uint32_t m_id = 0; @@ -30,7 +30,7 @@ int main(int argc, char **argv) { // temporal app->modal.active = login; - + init_login_modal(app); draw_dialogue(app, &(app->modal.dialogue)); @@ -47,35 +47,17 @@ void event_loop(app_t *app) { for (;;) { c = wgetch(app->win); - - // if (app->modal.active != none_active) { - // modal_event_loop(c, app); - // continue; - // } - switch (c) { // 113 is q key. This exits the program case 113: return; case KEY_F(9): return; - case 'e': - // ac_edit(app); - break; - // 27 is ESC key. Usage of ESC is not recommended, but for now this clears - // the menus - case 27: - // app->menu_bar->selected_menu = -1; - break; - // 9 or \t is horizontal tab - case 9: - // if (app->active == N_MENU) { - // app->active = N_ACTION; - // } else { - // app->active = N_MENU; - // } - break; default: + if (app->modal.active != none_active) { + app->modal.dialogue.w.callback(app->modal.dialogue.win, + &(app->modal.dialogue), (void *)&c); + } break; } @@ -84,6 +66,9 @@ void event_loop(app_t *app) { wnoutrefresh(app->win); wnoutrefresh(app->menu_win); wnoutrefresh(app->action_win); + if (app->modal.active != none_active) { + wnoutrefresh(app->modal.dialogue.win); + } doupdate(); }; } diff --git a/src/ui/modals/login.c b/src/ui/modals/login.c index b4f05fd..b1e9fb8 100644 --- a/src/ui/modals/login.c +++ b/src/ui/modals/login.c @@ -20,16 +20,13 @@ dialogue_t *init_login_modal(app_t *app) { {.type = w_button, .label = "Register"}, {.type = w_end}}; - dialogue_t *d = init_dialogue("Login", - "Select your login " - "option"); + dialogue_t *d = init_dialogue("Login", "Select your login " + "option"); memcpy(&(app->modal.dialogue), d, sizeof(dialogue_t)); free(d); app->modal.dialogue.ch_group = init_group(&(app->modal.dialogue.win), &(d->w), children, horizontal); - group_bt_t *ch_btns = (group_bt_t *)app->modal.dialogue.ch_group->elements; - ch_btns[0].element->is_hovered = 1; return NULL; } \ No newline at end of file diff --git a/src/ui/widget.c b/src/ui/widget.c index f8df5d2..492aba1 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c @@ -14,6 +14,7 @@ void init_widget(widget_t *w, widget_t *w_parent, WINDOW **win, char *title) { w->m_y = 0; w->parent_win = win; w->w_parent = w_parent; + w->callback = NULL; strcpy(w->title, title); } diff --git a/src/ui/widget.h b/src/ui/widget.h index fbef381..b88bb78 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -21,6 +21,7 @@ typedef struct widget_t { uint32_t m_y; WINDOW *const* parent_win; struct widget_t *w_parent; + void (*callback) (WINDOW *win, void *widget, void *data); } widget_t; enum pmt_attrs { @@ -34,5 +35,4 @@ uint32_t 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); -typedef void (*callback_t) (widget_t*, void*); #endif \ No newline at end of file diff --git a/src/ui/widget/button.c b/src/ui/widget/button.c index 0ef5218..31b6117 100644 --- a/src/ui/widget/button.c +++ b/src/ui/widget/button.c @@ -11,30 +11,22 @@ 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); btn->is_disabled = 0; - btn->is_focused = 0; - btn->is_hovered = 0; - btn->callback = NULL; - btn->w.x = strlen(btn->w.title) + 4; // + "[ ]" + btn->w.x = strlen(btn->w.title) + 6; // + "[ ]" btn->w.y = 1; // TODO: detect new line - if (btn->is_focused) btn->w.x += 2; // + "<>" return btn; } -int32_t draw_button(button_t *btn) { +int32_t draw_button(button_t *btn, uint32_t active_id) { char title[DIALOGUE_TITLE + 6]; WINDOW *win = *(btn->w.parent_win); uint32_t margin_y = btn->w.m_y + btn->w.w_parent->m_y; uint32_t margin_x = btn->w.m_x + btn->w.w_parent->m_x; - if (btn->is_focused) { + if (btn->w.id == active_id) { sprintf(title, "[< %s >]", btn->w.title); - } else { - sprintf(title, "[ %s ]", btn->w.title); - } - - if (btn->is_hovered) { wattrset(win, COLOR_PAIR(MODAL_COLOR_PAIR) | A_BOLD | A_REVERSE); } else { + sprintf(title, "[ %s ]", btn->w.title); wattrset(win, COLOR_PAIR(0) | A_REVERSE); } diff --git a/src/ui/widget/button.h b/src/ui/widget/button.h index 492fbe8..ce44c57 100644 --- a/src/ui/widget/button.h +++ b/src/ui/widget/button.h @@ -8,13 +8,10 @@ typedef struct { widget_t w; char hotkey; - uint32_t is_focused : 1; uint32_t is_disabled : 1; - uint32_t is_hovered : 1; - callback_t *callback; } button_t; button_t *init_button(WINDOW **win, widget_t *w_parent, char *label); -int32_t draw_button(button_t *btn); +int32_t draw_button(button_t *btn, uint32_t active_id); void destroy_button(button_t *btn); #endif \ No newline at end of file diff --git a/src/ui/widget/dialogue.c b/src/ui/widget/dialogue.c index 763a318..17075ad 100644 --- a/src/ui/widget/dialogue.c +++ b/src/ui/widget/dialogue.c @@ -8,12 +8,28 @@ #include "dialogue.h" #include "group.h" +void default_callback(WINDOW *win, void *widget, void *data) { + dialogue_t *d = (void *)widget; + char key = *((char *)data); + switch (key) { + case '\t': + if (d->ch_group->w_active_id != d->ch_group->last_id) { + d->ch_group->w_active_id = d->ch_group->w_active_id + 1; + } else { + d->ch_group->w_active_id = d->ch_group->first_id; + } + draw_group(win, d->ch_group); + break; + } +} + dialogue_t *init_dialogue(const char title[], const char text[]) { dialogue_t *dialogue = malloc(sizeof(dialogue_t)); dialogue->win = 0; dialogue->ch_group = NULL; dialogue->w.x = 0; dialogue->w.y = 0; + dialogue->w.callback = default_callback; strcpy(dialogue->w.title, title); strcpy(dialogue->text, text); return dialogue; @@ -52,7 +68,9 @@ int32_t draw_dialogue(void *_app, dialogue_t *d) { d->w.m_y = (app->cur_y - y) / 2; /* render window */ - d->win = newwin(y, x, d->w.m_y, d->w.m_x); + if (d->win == NULL) { + d->win = newwin(y, x, d->w.m_y, d->w.m_x); + } wattrset(d->win, COLOR_PAIR(0) | A_BOLD | A_REVERSE); /* background */ diff --git a/src/ui/widget/dialogue.h b/src/ui/widget/dialogue.h index 37ce0a5..f2f5273 100644 --- a/src/ui/widget/dialogue.h +++ b/src/ui/widget/dialogue.h @@ -16,5 +16,6 @@ typedef struct { dialogue_t *init_dialogue(const char title[], const char text[]); int32_t draw_dialogue(void *app, dialogue_t *d); void destroy_active_dialogue(dialogue_t *d); +void default_callback(WINDOW *win, void *widget, void *data); #endif \ No newline at end of file diff --git a/src/ui/widget/group.c b/src/ui/widget/group.c index d600e86..6bdfd9c 100644 --- a/src/ui/widget/group.c +++ b/src/ui/widget/group.c @@ -9,23 +9,25 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, group_t *group = malloc(sizeof(group_t)); /* count elements */ - uint32_t count = 0; - for (; children[count].type != w_end; count++) + group->count = 0; + for (; children[group->count].type != w_end; group->count++) ; - group->elements = calloc(count, sizeof(group_el_t)); + group->elements = calloc(group->count, sizeof(group_el_t)); group->w.w_parent = w_parent; group_el_t *elements = group->elements; - for (int i = 0; i < count; i++) { + for (int i = 0; i < group->count; i++) { elements[i].type = children[i].type; } /* init child elements */ - for (int i = 0; elements[i].type != w_end; i++) { + uint32_t el_id = 0; + for (int i = 0; i < group->count; i++) { switch (elements[i].type) { case w_button: elements[i].element = init_button(win, &(group->w), children[i].label); if (direction == horizontal) { button_t *b = (button_t *)elements[i].element; + el_id = b->w.id; b->w.m_x = group->w.x; b->w.m_y = group->w.m_y; group->w.x += b->w.x + 1; @@ -36,21 +38,26 @@ group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children, case w_box: case w_group: case w_end: - group->w.x--; break; } + if (i == 0) { + group->first_id = el_id; + group->w_active_id = el_id; + } else { + group->last_id = el_id; + } } - + return group; } void draw_group(WINDOW *win, group_t *group) { group_el_t *children = group->elements; - for (int i = 0; children[i].type != w_end; i++) { + for (int i = 0; i < group->count; i++) { group_el_t *el = &children[i]; switch (el->type) { case w_button: - draw_button((button_t *)el->element); + draw_button((button_t *)el->element, group->w_active_id); break; case w_box: case w_group: @@ -62,7 +69,7 @@ void draw_group(WINDOW *win, group_t *group) { void destroy_group(group_t *group) { group_el_t *children = group->elements; - for (int i = 0; children[i].type != w_end; i++) { + for (int i = 0; i < group->count; i++) { group_el_t *el = &children[i]; switch (el->type) { case w_button: diff --git a/src/ui/widget/group.h b/src/ui/widget/group.h index 4e32872..f8029b4 100644 --- a/src/ui/widget/group.h +++ b/src/ui/widget/group.h @@ -23,6 +23,8 @@ typedef struct { widget_t w; uint32_t w_active_id; enum g_direction direction; + uint32_t count; + uint32_t first_id, last_id; } group_t; group_t *init_group(WINDOW **win, widget_t *w_parent, group_el_init_t *children,