diff --git a/TODO.md b/TODO.md index 341ab40..ce6f03e 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,5 @@ TODO: - [x] More universal Makefile -- [ ] Check and fix registration and login \ No newline at end of file +- [ ] Check and fix registration and login +- [x] UI: destroy child elements everywhere +- [ ] use parent widgets pointers to count the margins correctly \ No newline at end of file diff --git a/src/deps.mk b/src/deps.mk index 22899d9..386a9ca 100644 --- a/src/deps.mk +++ b/src/deps.mk @@ -8,7 +8,7 @@ main.o: src/main.c src/ui/app.h src/ui/widget/dialogue.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/../widget/dialogue.h src/ui/modals/../app.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 7848d12..69ee61f 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -12,6 +13,7 @@ #include "ui/widget/dialogue.h" #include "ui/modals/login.h" +uint32_t m_id = 0; void event_loop(app_t *app); @@ -29,8 +31,8 @@ int main(int argc, char **argv) { // temporal app->modal.active = login; - dialogue_t *dialogue = init_login_modal(); - draw_dialogue(dialogue, app->cur_x, app->cur_y); + init_login_modal(app); + draw_dialogue(app, &(app->modal.dialogue), app->cur_x, app->cur_y); event_loop(app); diff --git a/src/main.h b/src/main.h index 715e7c2..9aed41c 100644 --- a/src/main.h +++ b/src/main.h @@ -2,6 +2,7 @@ #define MAIN_H #include +#include #include "types.h" #define LOCAL_PORT 1999 diff --git a/src/ui/modals/login.c b/src/ui/modals/login.c index 9ea4adf..112dff2 100644 --- a/src/ui/modals/login.c +++ b/src/ui/modals/login.c @@ -1,5 +1,7 @@ +#include "../app.h" #include "../widget/dialogue.h" #include "../widget/group.h" +#include #include typedef struct { @@ -9,20 +11,25 @@ typedef struct { /* TODO: improve init process (make it more readable) */ -dialogue_t *init_login_modal() { - group_el_t children[] = {{.type = w_button}, - {.type = w_button}, - {.type = w_button}, - {.type = w_end}}; +dialogue_t *init_login_modal(app_t *app) { + if (app == NULL) + return NULL; + group_el_init_t children[] = {{.type = w_button, .label = "Anonymous"}, + {.type = w_button, .label = "User"}, + {.type = w_button, .label = "Register"}, + {.type = w_end}}; dialogue_t *d = init_dialogue("Login", "Select your login " "option", 50, 20); - d->ch_group = init_group(children); - group_bt_t *ch_btns = (group_bt_t *)d->ch_group->elements; - strcpy(ch_btns[0].element->w.title, "Anonymous"); - strcpy(ch_btns[1].element->w.title, "User"); - strcpy(ch_btns[2].element->w.title, "Register"); - return d; + + memcpy(&(app->modal.dialogue), d, sizeof(dialogue_t)); + free(d); + app->modal.dialogue.ch_group = + init_group(&(app->modal.dialogue.win), d->w.id, 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/modals/login.h b/src/ui/modals/login.h index 54cefcd..a6d92e3 100644 --- a/src/ui/modals/login.h +++ b/src/ui/modals/login.h @@ -2,6 +2,8 @@ #define LOGIN_MODAL_H #include "../widget/dialogue.h" -dialogue_t *init_login_modal(); +#include "../app.h" + +dialogue_t *init_login_modal(app_t *app); #endif \ No newline at end of file diff --git a/src/ui/widget.c b/src/ui/widget.c index 61c22fa..582376f 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c @@ -4,6 +4,19 @@ #include #include +extern uint32_t m_id; + +void init_widget(widget_t *w, WINDOW **win, char *title, uint32_t parent_id) { + w->id = m_id++; + w->x = 0; + w->y = 0; + w->m_x = 0; + w->m_y = 0; + w->parent_win = win; + w->parent_id = parent_id; + strcpy(w->title, title); +} + int32_t get_max_line_len(const char *text) { uint32_t nl_pos = 0; // new line position uint32_t c_start = 0; // current line start position diff --git a/src/ui/widget.h b/src/ui/widget.h index 3fb6539..41334d3 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -6,10 +6,10 @@ #include enum w_type { + w_end, w_button, w_box, w_group, - w_end, }; typedef struct { @@ -19,6 +19,8 @@ typedef struct { uint32_t y; uint32_t m_x; uint32_t m_y; + WINDOW **parent_win; + uint32_t parent_id; } widget_t; enum pmt_attrs { @@ -26,6 +28,7 @@ enum pmt_attrs { PMT_ALIGN_CENTER = 03, }; +void init_widget(widget_t *w, WINDOW **win, char *title, uint32_t parent_id); int32_t get_max_line_len(const char *text); uint32_t print_multiline_text(WINDOW *win, const char *text, const uint32_t win_width, const uint32_t y, diff --git a/src/ui/widget/button.c b/src/ui/widget/button.c index 2328d43..e590c35 100644 --- a/src/ui/widget/button.c +++ b/src/ui/widget/button.c @@ -1,19 +1,30 @@ -#include "button.h" #include +#include #include #include -button_t *init_button() { +#include "../app.h" +#include "../widget.h" +#include "button.h" + +button_t *init_button(WINDOW **win, uint32_t parent_id, char *label) { button_t *btn = malloc(sizeof(button_t)); + init_widget(&(btn->w), win, label, parent_id); 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.y = 1; // TODO: detect new line + if (btn->is_focused) btn->w.x += 2; // + "<>" return btn; } -int32_t draw_button(WINDOW *win, button_t *btn, uint32_t cur_x, uint32_t cur_y) { +int32_t draw_button(button_t *btn) { char title[DIALOGUE_TITLE + 6]; + WINDOW *win = *(btn->w.parent_win); + uint32_t cur_y = btn->w.m_y; + uint32_t cur_x = btn->w.m_x; if (btn->is_focused) { sprintf(title, "[< %s >]", btn->w.title); @@ -22,17 +33,15 @@ int32_t draw_button(WINDOW *win, button_t *btn, uint32_t cur_x, uint32_t cur_y) } if (btn->is_hovered) { - wattrset(win, COLOR_PAIR(1) | A_BOLD | A_REVERSE); + wattrset(win, COLOR_PAIR(MODAL_COLOR_PAIR) | A_BOLD | A_REVERSE); } else { - wattrset(win, COLOR_PAIR(1) | A_BOLD); + wattrset(win, COLOR_PAIR(0) | A_REVERSE); } mvwprintw(win, cur_y, cur_x, "%s", title); - wattroff(win, A_REVERSE | A_BOLD); + wattroff(win, A_BOLD | A_REVERSE); return strlen(title); } -void destroy_button(button_t *btn) { - free(btn); -} \ No newline at end of file +void destroy_button(button_t *btn) { free(btn); } \ No newline at end of file diff --git a/src/ui/widget/button.h b/src/ui/widget/button.h index 398c637..84a270e 100644 --- a/src/ui/widget/button.h +++ b/src/ui/widget/button.h @@ -14,7 +14,7 @@ typedef struct { callback_t *callback; } button_t; -button_t *init_button(); -int32_t draw_button(WINDOW *win, button_t *btn, uint32_t cur_x, uint32_t cur_y); +button_t *init_button(WINDOW **win, uint32_t parent_id, char *label); +int32_t draw_button(button_t *btn); 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 413aa6a..b8a12b8 100644 --- a/src/ui/widget/dialogue.c +++ b/src/ui/widget/dialogue.c @@ -18,13 +18,14 @@ dialogue_t *init_dialogue(const char title[], const char text[], return dialogue; } -int32_t draw_dialogue(dialogue_t *d, uint32_t cur_x, uint32_t cur_y) { +int32_t draw_dialogue(void *app, dialogue_t *d, uint32_t cur_x, uint32_t cur_y) { + app_t *_app = (app_t *) app; d->w.m_x = (cur_x - d->w.x) / 2; d->w.m_y = (cur_y - d->w.y) / 2; d->win = newwin(d->w.y, d->w.x, d->w.m_y, d->w.m_x); - wattrset(d->win, COLOR_PAIR(MODAL_COLOR_PAIR) | A_BOLD | A_REVERSE); + wattrset(d->win, COLOR_PAIR(0) | A_BOLD | A_REVERSE); /* background */ for (int xp = 1; xp < d->w.x; xp++) { @@ -43,14 +44,18 @@ int32_t draw_dialogue(dialogue_t *d, uint32_t cur_x, uint32_t cur_y) { /* text */ print_multiline_text(d->win, d->text, d->w.x, 1, 1, PMT_ALIGN_CENTER); wattroff(d->win, A_REVERSE); - // temp!!! - draw_group(d->win, d->ch_group, 1, 4); + d->ch_group->w.m_x = (d->w.x - d->ch_group->w.x) / 2; + d->ch_group->w.m_y = 4; + draw_group(d->win, d->ch_group); wrefresh(d->win); return 0; }; void destroy_active_dialogue(dialogue_t *d) { + if (d->ch_group) { + destroy_group(d->ch_group); + } delwin(d->win); free(d->win); d->win = NULL; diff --git a/src/ui/widget/dialogue.h b/src/ui/widget/dialogue.h index 242b147..babf27f 100644 --- a/src/ui/widget/dialogue.h +++ b/src/ui/widget/dialogue.h @@ -14,7 +14,7 @@ typedef struct { } dialogue_t; dialogue_t *init_dialogue(const char title[], const char text[], const uint32_t w, const uint32_t h); -int32_t draw_dialogue(dialogue_t *d, const uint32_t cur_x, const uint32_t cur_y); +int32_t draw_dialogue(void *app, dialogue_t *d, const uint32_t cur_x, const uint32_t cur_y); void destroy_active_dialogue(dialogue_t *d); #endif \ No newline at end of file diff --git a/src/ui/widget/group.c b/src/ui/widget/group.c index 3a24288..0ca9bb8 100644 --- a/src/ui/widget/group.c +++ b/src/ui/widget/group.c @@ -2,45 +2,55 @@ #include "button.h" #include #include -#include #include -group_t *init_group(group_el_t *children) { +group_t *init_group(WINDOW **win, uint32_t par_id, group_el_init_t *children, + enum g_direction direction) { group_t *group = malloc(sizeof(group_t)); /* count elements */ uint32_t count = 0; - for (count = 0; children[count].type != w_end; count++) + for (; children[count].type != w_end; count++) ; count++; /* TODO: improve counting */ - group->elements = malloc(sizeof(group_el_t) * count); - memcpy(group->elements, children, sizeof(group_el_t) * count); + group->elements = calloc(count, sizeof(group_el_t)); + group_el_t *elements = group->elements; + for (int i = 0; i < count; i++) { + elements[i].type = children[i].type; + } /* init child elements */ - for (int i = 0; group->elements[i].type != w_end; i++) { - group_el_t *el = &(group->elements)[i]; - switch (el->type) { + for (int i = 0; elements[i].type != w_end; i++) { + switch (elements[i].type) { case w_button: - el->element = init_button(); + elements[i].element = init_button(win, par_id, children[i].label); + if (direction == horizontal) { + button_t *b = (button_t *)elements[i].element; + b->w.m_x = group->w.x; + b->w.m_y = group->w.m_y; + group->w.x += b->w.x + 1; + if (group->w.y < b->w.y) + group->w.y = b->w.y; + } break; case w_box: case w_group: case w_end: + group->w.x--; break; } } - group->direction = horizontal; /* horizontal by default */ + return group; } -void draw_group(WINDOW *win, group_t *group, uint32_t cur_x, uint32_t cur_y) { +void draw_group(WINDOW *win, group_t *group) { group_el_t *children = group->elements; - int32_t x_used = 0; /* used space */ for (int i = 0; children[i].type != w_end; i++) { group_el_t *el = &children[i]; switch (el->type) { case w_button: - x_used += draw_button(win, (button_t *)el->element, cur_x + x_used + 1 * i, cur_y); + draw_button((button_t *)el->element); break; case w_box: case w_group: diff --git a/src/ui/widget/group.h b/src/ui/widget/group.h index 93a6291..44f05f5 100644 --- a/src/ui/widget/group.h +++ b/src/ui/widget/group.h @@ -13,6 +13,11 @@ typedef struct { enum w_type type; } group_el_t; +typedef struct { + enum w_type type; + char label[DIALOGUE_TITLE]; +} group_el_init_t; + typedef struct { group_el_t *elements; widget_t w; @@ -20,8 +25,9 @@ typedef struct { enum g_direction direction; } group_t; -group_t *init_group(group_el_t *children); -void draw_group(WINDOW *win, group_t *group, uint32_t cur_x, uint32_t cur_y); +group_t *init_group(WINDOW **win, uint32_t par_id, group_el_init_t *children, + enum g_direction dir); +void draw_group(WINDOW *win, group_t *group); void destroy_group(group_t *group); #endif \ No newline at end of file