From b9d378a3a6718be5e6f6deb5d6971ba61d9e0c7e Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Fri, 28 Nov 2025 13:59:55 +0200 Subject: [PATCH] dialogue color improvement, implementation of print_multiline_text function. --- src/deps.mk | 2 +- src/main.c | 5 ++- src/main.h | 1 + src/ui/app.h | 1 + src/ui/widget.c | 66 ++++++++++++++++++++++++++++++++++++++++ src/ui/widget.h | 10 ++++++ src/ui/widget/dialogue.c | 26 ++++++++++------ src/ui/widget/dialogue.h | 5 +-- 8 files changed, 102 insertions(+), 14 deletions(-) diff --git a/src/deps.mk b/src/deps.mk index 27694cd..7a21821 100644 --- a/src/deps.mk +++ b/src/deps.mk @@ -3,7 +3,7 @@ client.o: src/client.c src/file_processor.h src/main.h src/types.h \ connection.o: src/connection.c src/main.h src/types.h file_processor.o: src/file_processor.c src/client.h src/main.h \ src/types.h src/query.h -main.o: src/main.c src/main.h src/types.h src/modal.h src/ui/app.h \ +main.o: src/main.c src/main.h src/types.h src/ui/app.h \ src/ui/widget/dialogue.h src/ui/widget/../widget.h \ src/ui/widget/../../main.h src/ui/widget/button.h \ src/ui/widget/../../main.h src/ui/widget/dialogue.h diff --git a/src/main.c b/src/main.c index 7cf8086..697875e 100644 --- a/src/main.c +++ b/src/main.c @@ -27,7 +27,10 @@ int main(int argc, char **argv) { // temporal app->modal.active = login; - dialogue_t *dialogue = init_dialogue("Login"); + dialogue_t *dialogue = init_dialogue("Login", + "Select your login " + "option", + 50, 20); draw_dialogue(dialogue, app->cur_x, app->cur_y); event_loop(app); diff --git a/src/main.h b/src/main.h index 3f66ab6..715e7c2 100644 --- a/src/main.h +++ b/src/main.h @@ -10,6 +10,7 @@ #define INBUFSIZE 1024 #define DOWNLOADS_DIR "./Downloads" #define DIALOGUE_TITLE 64 +#define DIALOGUE_TEXT 128 typedef struct params { unsigned short port; diff --git a/src/ui/app.h b/src/ui/app.h index 71af5a5..af9a141 100644 --- a/src/ui/app.h +++ b/src/ui/app.h @@ -6,6 +6,7 @@ typedef enum { MODAL_COLOR_PAIR = 3, + MODAL_BORDER_COLOR_PAIR = 4, } color; typedef enum { diff --git a/src/ui/widget.c b/src/ui/widget.c index e69de29..61c22fa 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c @@ -0,0 +1,66 @@ +#include "widget.h" +#include "../main.h" +#include +#include +#include + +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 + uint32_t c_len = 0; // current line length + uint32_t m_len = 0; // max length + for (int i = 0; text[i] != '\0'; i++, c_len++) { + if (text[i] == '\n') { + if (i - nl_pos > c_len || !m_len) { + m_len = c_len; + } + nl_pos = i; + c_start = i + 1; + c_len = 0; + } + } + if (c_len > m_len) { + return c_len; + } else { + return m_len; + } +} + +#define PRINT_TEXT(win, l_buf, text, i, c_line_len, win_width, line_v_pos, \ + attrs) \ + strncpy(l_buf, text + i - c_line_len, c_line_len); \ + l_buf[c_line_len] = '\0'; \ + if ((attrs & PMT_ALIGN_CENTER) == PMT_ALIGN_CENTER) { \ + mvwprintw(win, line_v_pos, (win_width - c_line_len) / 2, "%s", l_buf); \ + } else if (attrs & PMT_POS_CENTER) { \ + mvwprintw(win, line_v_pos, (win_width - m_line_len) / 2, "%s", l_buf); \ + } else { \ + mvwprintw(win, line_v_pos, x, "%s", l_buf); \ + } + +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) { + + uint16_t line_v_pos = y; + int32_t c_line_len = 0; + uint32_t m_line_len = 0; + uint32_t i = 0; + char l_buf[DIALOGUE_TEXT]; + + if (attrs & PMT_POS_CENTER) { + m_line_len = get_max_line_len(text); + } + + for (; text[i]; i++, c_line_len++) { + if (text[i] == '\n') { + PRINT_TEXT(win, l_buf, text, i, c_line_len, win_width, line_v_pos, attrs) + c_line_len = -1; + line_v_pos++; + } + } + + PRINT_TEXT(win, l_buf, text, i, c_line_len, win_width, line_v_pos, attrs) + + return 1; +} \ No newline at end of file diff --git a/src/ui/widget.h b/src/ui/widget.h index 726e473..110b48e 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -2,6 +2,7 @@ #define WIDGET_H #include "../main.h" +#include #include typedef struct { @@ -13,4 +14,13 @@ typedef struct { char color_pair; } widget_t; +enum pmt_attrs { + PMT_POS_CENTER = 01, + PMT_ALIGN_CENTER = 03, +}; + +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, + const uint32_t x, const uint16_t attrs); #endif \ No newline at end of file diff --git a/src/ui/widget/dialogue.c b/src/ui/widget/dialogue.c index 414e6cd..c9b5a3e 100644 --- a/src/ui/widget/dialogue.c +++ b/src/ui/widget/dialogue.c @@ -5,37 +5,43 @@ #include #include -dialogue_t *init_dialogue(char title[]) { +dialogue_t *init_dialogue(const char title[], const char text[], + const uint32_t width, const uint32_t height) { dialogue_t *dialogue = malloc(sizeof(dialogue_t)); dialogue->win = 0; dialogue->buttons = NULL; + dialogue->w.x = width; + dialogue->w.y = height; strcpy(dialogue->w.title, title); + strcpy(dialogue->text, text); return dialogue; } int32_t draw_dialogue(dialogue_t *d, uint32_t cur_x, uint32_t cur_y) { - d->w.x = 50; - d->w.y = 20; 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); - - wcolor_set(d->win, MODAL_COLOR_PAIR, NULL); - wattrset(d->win, A_REVERSE); + color_set(MODAL_COLOR_PAIR, NULL); + wattrset(d->win, COLOR_PAIR(MODAL_COLOR_PAIR) | A_BOLD | A_REVERSE); + + /* background */ for (int xp = 1; xp < d->w.x; xp++) { for (int yp = 1; yp < d->w.y - 1; yp++) { mvwprintw(d->win, yp, xp, " "); } } - uint32_t title_mx_pos = (d->w.x - strlen(d->w.title)) / 2; - + /* title */ + const uint32_t title_mx_pos = (d->w.x - strlen(d->w.title)) / 2; box(d->win, 0, 0); - mvwprintw(d->win, 0, title_mx_pos-1, " "); - mvwprintw(d->win, 0, title_mx_pos, d->w.title); + mvwprintw(d->win, 0, title_mx_pos - 1, " "); + mvwprintw(d->win, 0, title_mx_pos, "%s", d->w.title); mvwprintw(d->win, 0, title_mx_pos + strlen(d->w.title), " "); + + /* text */ + print_multiline_text(d->win, d->text, d->w.x, 1, 1, PMT_ALIGN_CENTER); wattroff(d->win, A_REVERSE); wrefresh(d->win); diff --git a/src/ui/widget/dialogue.h b/src/ui/widget/dialogue.h index 9e2cd4e..7c0a20e 100644 --- a/src/ui/widget/dialogue.h +++ b/src/ui/widget/dialogue.h @@ -9,10 +9,11 @@ typedef struct { WINDOW *win; widget_t w; button_t *buttons; // ! should be NULL-terminated + char text[DIALOGUE_TEXT]; } dialogue_t; -dialogue_t *init_dialogue(char title[]); -int32_t draw_dialogue(dialogue_t *d, uint32_t cur_x, uint32_t cur_y); +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); void destroy_active_dialogue(dialogue_t *d); #endif \ No newline at end of file