# HG changeset patch # User David Demelier # Date 1678009885 -3600 # Node ID 88e9bd420a28e486c07151afb1e0667dd42d585a # Parent 79afc6d5cc7e8d8b38302a163c54339ac0fe95d8 rpg: add delegate/style support to mlk_message diff -r 79afc6d5cc7e -r 88e9bd420a28 examples/example-action/dialog.c --- a/examples/example-action/dialog.c Sat Mar 04 20:38:00 2023 +0100 +++ b/examples/example-action/dialog.c Sun Mar 05 10:51:25 2023 +0100 @@ -38,7 +38,7 @@ { struct dialog *dlg = act->data; - message_handle(&dlg->msg, ev); + mlk_message_handle(&dlg->msg, ev); } static int @@ -46,7 +46,7 @@ { struct dialog *dlg = act->data; - return message_update(&dlg->msg, ticks); + return mlk_message_update(&dlg->msg, ticks); } static void @@ -54,7 +54,7 @@ { struct dialog *dlg = act->data; - message_draw(&dlg->msg); + mlk_message_draw(&dlg->msg); } static void @@ -62,7 +62,7 @@ { struct dialog *dlg = act->data; - if ((dlg->msg.flags & MESSAGE_FLAGS_QUESTION) && dlg->response) + if ((dlg->msg.flags & MLK_MESSAGE_FLAGS_QUESTION) && dlg->response) dlg->response(dlg, dlg->msg.index); } @@ -77,8 +77,8 @@ dlg->msg.delay = QMD; dlg->msg.spacing = QMS; - message_start(&dlg->msg); - message_query(&dlg->msg, NULL, &dlg->msg.h); + mlk_message_start(&dlg->msg); + mlk_message_query(&dlg->msg, NULL, &dlg->msg.h); dlg->action.data = dlg; dlg->action.handle = handle; diff -r 79afc6d5cc7e -r 88e9bd420a28 examples/example-action/dialog.h --- a/examples/example-action/dialog.h Sat Mar 04 20:38:00 2023 +0100 +++ b/examples/example-action/dialog.h Sun Mar 05 10:51:25 2023 +0100 @@ -27,7 +27,7 @@ /* public */ void *data; void (*response)(struct dialog *, unsigned int); - struct message msg; + struct mlk_message msg; /* private */ struct mlk_action action; diff -r 79afc6d5cc7e -r 88e9bd420a28 examples/example-action/example-action.c --- a/examples/example-action/example-action.c Sat Mar 04 20:38:00 2023 +0100 +++ b/examples/example-action/example-action.c Sun Mar 05 10:51:25 2023 +0100 @@ -79,7 +79,7 @@ static struct dialog script_left[] = { { .msg = { - .flags = MESSAGE_FLAGS_FADEIN, + .flags = MLK_MESSAGE_FLAGS_FADEIN, .linesz = 1, .lines = (const char *[]) { "Welcome to this game." @@ -99,7 +99,7 @@ { .response = script_left_response, .msg = { - .flags = MESSAGE_FLAGS_QUESTION, + .flags = MLK_MESSAGE_FLAGS_QUESTION, .linesz = 2, .lines = (const char *[]) { "Of course I am", @@ -112,7 +112,7 @@ static struct dialog script_left_responses[] = { { .msg = { - .flags = MESSAGE_FLAGS_FADEOUT, + .flags = MLK_MESSAGE_FLAGS_FADEOUT, .linesz = 1, .lines = (const char *[]) { "Don't be so confident" @@ -121,7 +121,7 @@ }, { .msg = { - .flags = MESSAGE_FLAGS_FADEOUT, + .flags = MLK_MESSAGE_FLAGS_FADEOUT, .linesz = 1, .lines = (const char *[]) { "Nevermind, I'll do it myself" @@ -137,7 +137,7 @@ static struct dialog script_right[] = { { .msg = { - .flags = MESSAGE_FLAGS_FADEIN, + .flags = MLK_MESSAGE_FLAGS_FADEIN, .linesz = 1, .lines = (const char *[]) { "Why did you select this chest?" @@ -147,7 +147,7 @@ { .response = script_right_response, .msg = { - .flags = MESSAGE_FLAGS_QUESTION, + .flags = MLK_MESSAGE_FLAGS_QUESTION, .linesz = 2, .lines = (const char *[]) { "Because I think there was some gold", @@ -160,7 +160,7 @@ static struct dialog script_right_responses[] = { { .msg = { - .flags = MESSAGE_FLAGS_FADEOUT, + .flags = MLK_MESSAGE_FLAGS_FADEOUT, .linesz = 1, .lines = (const char *[]) { "Go away!" @@ -169,7 +169,7 @@ }, { .msg = { - .flags = MESSAGE_FLAGS_FADEOUT, + .flags = MLK_MESSAGE_FLAGS_FADEOUT, .linesz = 1, .lines = (const char *[]) { "Install OpenBSD then" diff -r 79afc6d5cc7e -r 88e9bd420a28 examples/example-message/example-message.c --- a/examples/example-message/example-message.c Sat Mar 04 20:38:00 2023 +0100 +++ b/examples/example-message/example-message.c Sun Mar 05 10:51:25 2023 +0100 @@ -58,7 +58,7 @@ mlk_game_quit(); break; default: - message_handle(st->data, ev); + mlk_message_handle(st->data, ev); break; } } @@ -66,7 +66,7 @@ static void update(struct mlk_state *st, unsigned int ticks) { - if (message_update(st->data, ticks)) + if (mlk_message_update(st->data, ticks)) mlk_game_quit(); } @@ -75,12 +75,12 @@ { mlk_painter_set_color(MLK_EXAMPLE_BG); mlk_painter_clear(); - message_draw(st->data); + mlk_message_draw(st->data); mlk_painter_present(); } static void -run(struct message *msg) +run(struct mlk_message *msg) { struct mlk_state state = { .data = msg, @@ -89,7 +89,7 @@ .draw = draw }; - message_start(msg); + mlk_message_start(msg); mlk_game_init(); mlk_game_push(&state); @@ -115,16 +115,15 @@ "Vertical spacing is automatically computed.", "You need to press to close it.", }; - struct message msg = { + struct mlk_message msg = { .x = MX, .y = MY, .w = MW, - .spacing = 12, .lines = text, .linesz = 3 }; - message_query(&msg, NULL, &msg.h); + mlk_message_query(&msg, NULL, &msg.h); run(&msg); } @@ -136,17 +135,16 @@ "It will disappear in a few seconds.", "You can still press to close it quicker." }; - struct message msg = { + struct mlk_message msg = { .x = MX, .y = MY, .w = MW, - .timeout = MESSAGE_TIMEOUT_DEFAULT, .lines = text, .linesz = 3, - .flags = MESSAGE_FLAGS_AUTOMATIC + .flags = MLK_MESSAGE_FLAGS_AUTOMATIC }; - message_query(&msg, NULL, &msg.h); + mlk_message_query(&msg, NULL, &msg.h); run(&msg); } @@ -156,17 +154,16 @@ const char * const text[] = { "This message will fade in." }; - struct message msg = { + struct mlk_message msg = { .x = MX, .y = MY, .w = MW, - .delay = MESSAGE_DELAY_DEFAULT, .lines = text, .linesz = 1, - .flags = MESSAGE_FLAGS_FADEIN + .flags = MLK_MESSAGE_FLAGS_FADEIN }; - message_query(&msg, NULL, &msg.h); + mlk_message_query(&msg, NULL, &msg.h); run(&msg); } @@ -176,17 +173,16 @@ const char * const text[] = { "This message will fade out." }; - struct message msg = { + struct mlk_message msg = { .x = MX, .y = MY, .w = MW, - .delay = MESSAGE_DELAY_DEFAULT, .lines = text, .linesz = 1, - .flags = MESSAGE_FLAGS_FADEOUT + .flags = MLK_MESSAGE_FLAGS_FADEOUT }; - message_query(&msg, NULL, &msg.h); + mlk_message_query(&msg, NULL, &msg.h); run(&msg); } @@ -196,17 +192,16 @@ const char * const text[] = { "This message will fade in and out." }; - struct message msg = { + struct mlk_message msg = { .x = MX, .y = MY, .w = MW, - .delay = MESSAGE_DELAY_DEFAULT, .lines = text, .linesz = 1, - .flags = MESSAGE_FLAGS_FADEIN | MESSAGE_FLAGS_FADEOUT + .flags = MLK_MESSAGE_FLAGS_FADEIN | MLK_MESSAGE_FLAGS_FADEOUT }; - message_query(&msg, NULL, &msg.h); + mlk_message_query(&msg, NULL, &msg.h); run(&msg); } @@ -217,16 +212,16 @@ "Okay, I've understood.", "Nevermind, I'll do it again." }; - struct message msg = { + struct mlk_message msg = { .x = MX, .y = MY, .w = MW, .lines = text, .linesz = 2, - .flags = MESSAGE_FLAGS_QUESTION + .flags = MLK_MESSAGE_FLAGS_QUESTION }; - message_query(&msg, NULL, &msg.h); + mlk_message_query(&msg, NULL, &msg.h); run(&msg); } @@ -241,13 +236,12 @@ "This one is small here." }; - struct message msg = { + struct mlk_message msg = { .x = x, .y = y, .w = w, .h = h, - .delay = MESSAGE_DELAY_DEFAULT, - .flags = MESSAGE_FLAGS_FADEIN | MESSAGE_FLAGS_FADEOUT, + .flags = MLK_MESSAGE_FLAGS_FADEIN | MLK_MESSAGE_FLAGS_FADEOUT, .lines = text, .linesz = 1 }; @@ -262,7 +256,7 @@ "This one is too small in height and will emit a warning.", "Because this line will be incomplete." }; - struct message msg = { + struct mlk_message msg = { .x = MX, .y = MY, .w = MW, @@ -280,7 +274,7 @@ const char * const text[] = { "This one is too small in width." }; - struct message msg = { + struct mlk_message msg = { .x = MX, .y = MY, .w = 160, @@ -295,28 +289,26 @@ static void custom(void) { -#if 0 const char * const text[] = { "This one will destroy your eyes.", "Because it use a terrible custom theme." }; - struct mlk_theme theme; - struct message msg = { + struct mlk_message_style style = mlk_message_style; + struct mlk_message msg = { .x = MX, .y = MY, .w = MW, - .h = MH, .lines = text, .linesz = 2, - .theme = &theme + .style = &style }; - /* Borrow default theme and change its frame drawing. */ - theme.draw_frame = my_draw_frame; - theme.colors[MLK_THEME_COLOR_NORMAL] = 0x0000ffff; + style.bg_color = 0xf85d80ff; + style.border_color = 0xd94a69ff; + style.text_color = 0xffffffff; + mlk_message_query(&msg, NULL, &msg.h); run(&msg); -#endif } static void diff -r 79afc6d5cc7e -r 88e9bd420a28 libmlk-rpg/mlk/rpg/message.c --- a/libmlk-rpg/mlk/rpg/message.c Sat Mar 04 20:38:00 2023 +0100 +++ b/libmlk-rpg/mlk/rpg/message.c Sun Mar 05 10:51:25 2023 +0100 @@ -30,125 +30,123 @@ #include #include -#include -#include +#include +#include #include "message.h" -static void -draw_frame(const struct message *msg) +static inline struct mlk_font * +style_font(const struct mlk_message *message) +{ + const struct mlk_message_style *style = MLK__STYLE(message, mlk_message_style); + + if (style->text_font) + return style->text_font; + + return mlk_ui_fonts[MLK_UI_FONT_INTERFACE]; +} + +static unsigned int +min_width(const struct mlk_message *msg) { assert(msg); - struct mlk_frame frame = { - .w = msg->w, - .h = msg->h - }; - - mlk_frame_draw(&frame); -} - -static inline unsigned int -min_width(const struct message *msg) -{ -#if 0 - assert(msg); - + const struct mlk_message_style *style = MLK__STYLE(msg, mlk_message_style); + struct mlk_font *font; unsigned int maxw = 0, w = 0; int err; + font = style_font(msg); + for (size_t i = 0; i < msg->linesz; ++i) { if (!msg->lines[i]) continue; - if ((err = mlk_font_query(THEME(msg)->fonts[MLK_THEME_FONT_INTERFACE], msg->lines[i], &w, NULL)) < 0) - mlk_panic(err); + if ((err = mlk_font_query(font, msg->lines[i], &w, NULL)) < 0) + return err; if (w > maxw) maxw = w; } - return (THEME(msg)->padding * 2) + maxw; -#endif - return 0; + return (style->padding * 2) + maxw; } -static inline unsigned int -min_height(const struct message *msg) +static unsigned int +min_height(const struct mlk_message *msg) { assert(msg); -#if 0 - const struct mlk_theme *th = THEME(msg); - const unsigned int lh = mlk_font_height(th->fonts[MLK_THEME_FONT_INTERFACE]); + const struct mlk_message_style *style = MLK__STYLE(msg, mlk_message_style); + struct mlk_font *font; + unsigned int lh; - return (th->padding * 2) + (msg->linesz * lh) + ((msg->linesz - 1) * msg->spacing); -#endif - return 0; + font = style_font(msg); + lh = mlk_font_height(font); + + return (style->padding * 2) + (msg->linesz * lh) + ((msg->linesz - 1) * style->padding); } static void -draw_lines(const struct message *msg) +draw_frame(const struct mlk_message *msg) { -#if 0 - const struct mlk_theme *theme = THEME(msg); - struct mlk_label label; - unsigned int lw, lh; - int err; + const struct mlk_message_style *style = MLK__STYLE(msg, mlk_message_style); + + mlk_painter_set_color(style->border_color); + mlk_painter_draw_rectangle(0, 0, msg->w, msg->h); + mlk_painter_set_color(style->bg_color); + mlk_painter_draw_rectangle( + style->border_size, + style->border_size, + msg->w - (style->border_size * 2), + msg->h - (style->border_size * 2) + ); +} + +static void +draw_lines(const struct mlk_message *msg) +{ + const struct mlk_message_style *style; + struct mlk_font *font; + struct mlk_texture texture; + unsigned long color; + int err, x, y; + + style = MLK__STYLE(msg, mlk_message_style); + font = style_font(msg); for (size_t i = 0; i < msg->linesz; ++i) { if (!msg->lines[i]) continue; - if ((err = mlk_font_query(theme->fonts[MLK_THEME_FONT_INTERFACE], msg->lines[i], &lw, &lh)) < 0) - mlk_panic(err); + + if ((msg->flags & MLK_MESSAGE_FLAGS_QUESTION) && msg->index == (unsigned int)i) + color = style->selected_color; + else + color = style->text_color; - label.x = theme->padding; - label.y = theme->padding + (i * (lh + msg->spacing)); - label.text = msg->lines[i]; - label.flags = MLK_LABEL_FLAGS_SHADOW; + if ((err = mlk_font_render(font, &texture, msg->lines[i], color)) < 0) { + mlk_tracef("%s", mlk_err_string(err)); + continue; + } - if (label.x + lw > msg->w) + x = style->padding; + y = style->padding + (i * (texture.h + style->padding)); + + if (x + texture.w > msg->w) mlk_tracef("message width too small: %u < %u", msg->w, min_width(msg)); - if (label.y + lh > msg->h) + if (y + texture.h > msg->h) mlk_tracef("message height too small: %u < %u", msg->h, min_height(msg)); - /* - * The function label_draw will use THEME_COLOR_NORMAL to draw - * text and THEME_COLOR_SHADOW so if we have selected a line - * we need to cheat the normal color. - */ -#if 0 - if ((msg->flags & MESSAGE_FLAGS_QUESTION) && msg->index == (unsigned int)i) - label.flags |= MLK_LABEL_FLAGS_SELECTED; - else - label.flags &= ~(MLK_LABEL_FLAGS_SELECTED); -#endif - - mlk_label_draw(&label); + mlk_texture_draw(&texture, x, y); + mlk_texture_finish(&texture); } -#endif } -void -message_start(struct message *msg) +static int +delegate_query(struct mlk_message_delegate *self, + const struct mlk_message *msg, + unsigned int *w, + unsigned int *h) { - assert(msg); - - if (msg->flags & (MESSAGE_FLAGS_FADEIN|MESSAGE_FLAGS_FADEOUT)) - assert(msg->delay > 0); - - msg->elapsed = 0; - msg->scale = msg->flags & MESSAGE_FLAGS_FADEIN ? 0.0 : 1.0; - msg->state = msg->flags & MESSAGE_FLAGS_FADEIN - ? MESSAGE_STATE_OPENING - : MESSAGE_STATE_SHOWING; - - if (msg->flags & MESSAGE_FLAGS_AUTOMATIC && msg->timeout == 0) - mlk_tracef("message is automatic but has zero timeout"); -} - -void -message_query(const struct message *msg, unsigned int *w, unsigned int *h) -{ - assert(msg); + (void)self; if (w) *w = min_width(msg); @@ -156,77 +154,47 @@ *h = min_height(msg); } -void -message_handle(struct message *msg, const union mlk_event *ev) +static void +delegate_update(struct mlk_message_delegate *self, + struct mlk_message *msg, + unsigned int ticks) { - assert(msg); - assert(ev); - - /* Skip if the message animation hasn't complete. */ - if (msg->state != MESSAGE_STATE_SHOWING) - return; - - /* Only keyboard event are valid. */ - if (ev->type != MLK_EVENT_KEYDOWN || msg->state == MESSAGE_STATE_NONE) - return; + (void)self; - switch (ev->key.key) { - case MLK_KEY_UP: - if (msg->index > 0) - msg->index--; - break; - case MLK_KEY_DOWN: - if (msg->index + 1 < msg->linesz && msg->lines[msg->index + 1]) - msg->index++; - break; - case MLK_KEY_ENTER: - msg->state = msg->flags & MESSAGE_FLAGS_FADEOUT - ? MESSAGE_STATE_HIDING - : MESSAGE_STATE_NONE; - msg->elapsed = 0; - break; - default: - break; - } -} - -int -message_update(struct message *msg, unsigned int ticks) -{ - assert(msg); + const struct mlk_message_style *style = MLK__STYLE(msg, mlk_message_style); msg->elapsed += ticks; switch (msg->state) { - case MESSAGE_STATE_OPENING: - msg->scale = (double)msg->elapsed / (double)msg->delay; + case MLK_MESSAGE_STATE_OPENING: + msg->scale = (double)msg->elapsed / (double)style->delay; if (msg->scale > 1) msg->scale = 1; - if (msg->elapsed >= msg->delay) { - msg->state = MESSAGE_STATE_SHOWING; + if (msg->elapsed >= style->delay) { + msg->state = MLK_MESSAGE_STATE_SHOWING; msg->elapsed = 0; } break; - case MESSAGE_STATE_SHOWING: + case MLK_MESSAGE_STATE_SHOWING: /* Do automatically switch state if requested by the user. */ - if (msg->flags & MESSAGE_FLAGS_AUTOMATIC && msg->elapsed >= msg->timeout) { - msg->state = msg->flags & MESSAGE_FLAGS_FADEOUT - ? MESSAGE_STATE_HIDING - : MESSAGE_STATE_NONE; + if (msg->flags & MLK_MESSAGE_FLAGS_AUTOMATIC && msg->elapsed >= style->duration) { + msg->state = msg->flags & MLK_MESSAGE_FLAGS_FADEOUT + ? MLK_MESSAGE_STATE_HIDING + : MLK_MESSAGE_STATE_NONE; msg->elapsed = 0; } break; - case MESSAGE_STATE_HIDING: - msg->scale = 1 - (double)msg->elapsed / (double)msg->delay; + case MLK_MESSAGE_STATE_HIDING: + msg->scale = 1 - (double)msg->elapsed / (double)style->delay; if (msg->scale < 0) msg->scale = 0; - if (msg->elapsed >= msg->delay) { - msg->state = MESSAGE_STATE_NONE; + if (msg->elapsed >= style->delay) { + msg->state = MLK_MESSAGE_STATE_NONE; msg->elapsed = 0; } @@ -235,13 +203,12 @@ break; } - return msg->state == MESSAGE_STATE_NONE; } -void -message_draw(const struct message *msg) +static void +delegate_draw(struct mlk_message_delegate *self, const struct mlk_message *msg) { - assert(msg); + (void)self; struct mlk_texture tex; int x, y, err; @@ -272,11 +239,114 @@ mlk_texture_finish(&tex); } +struct mlk_message_style mlk_message_style = { + .padding = MLK_UI_PADDING, + .delay = MLK_MESSAGE_DELAY_DEFAULT, + .duration = MLK_MESSAGE_DURATION_DEFAULT, + .bg_color = MLK_UI_COLOR_BG, + .border_color = MLK_UI_COLOR_BORDER, + .border_size = MLK_UI_BORDER, + .text_color = MLK_UI_COLOR_TEXT, + .selected_color = MLK_UI_COLOR_SELECTED +}; +struct mlk_message_delegate mlk_message_delegate = { + .query = delegate_query, + .update = delegate_update, + .draw = delegate_draw +}; + void -message_hide(struct message *msg) +mlk_message_start(struct mlk_message *msg) +{ + assert(msg); + + const struct mlk_message_style *style = MLK__STYLE(msg, mlk_message_style); + + if ((msg->flags & (MLK_MESSAGE_FLAGS_FADEIN | MLK_MESSAGE_FLAGS_FADEOUT)) && style->delay == 0) + mlk_tracef("message has animation but zero delay"); + + msg->elapsed = 0; + msg->scale = msg->flags & MLK_MESSAGE_FLAGS_FADEIN ? 0.0 : 1.0; + msg->state = msg->flags & MLK_MESSAGE_FLAGS_FADEIN + ? MLK_MESSAGE_STATE_OPENING + : MLK_MESSAGE_STATE_SHOWING; + + if (msg->flags & MLK_MESSAGE_FLAGS_AUTOMATIC && style->duration == 0) + mlk_tracef("message is automatic but has zero duration"); +} + +int +mlk_message_query(const struct mlk_message *msg, unsigned int *w, unsigned int *h) { assert(msg); - msg->state = MESSAGE_STATE_HIDING; + MLK__DELEGATE_INVOKE_RET(msg->delegate, mlk_message_delegate, query, msg, w, h); + + if (w) + *w = 0; + if (h) + *h = 0; + + return MLK_ERR_NO_SUPPORT; +} + +void +mlk_message_handle(struct mlk_message *msg, const union mlk_event *ev) +{ + assert(msg); + assert(ev); + + /* Skip if the message animation hasn't complete. */ + if (msg->state != MLK_MESSAGE_STATE_SHOWING) + return; + + /* Only keyboard event are valid. */ + if (ev->type != MLK_EVENT_KEYDOWN || msg->state == MLK_MESSAGE_STATE_NONE) + return; + + switch (ev->key.key) { + case MLK_KEY_UP: + if (msg->index > 0) + msg->index--; + break; + case MLK_KEY_DOWN: + if (msg->index + 1 < msg->linesz && msg->lines[msg->index + 1]) + msg->index++; + break; + case MLK_KEY_ENTER: + msg->state = msg->flags & MLK_MESSAGE_FLAGS_FADEOUT + ? MLK_MESSAGE_STATE_HIDING + : MLK_MESSAGE_STATE_NONE; + msg->elapsed = 0; + break; + default: + break; + } +} + +int +mlk_message_update(struct mlk_message *msg, unsigned int ticks) +{ + assert(msg); + + MLK__DELEGATE_INVOKE(msg->delegate, mlk_message_delegate, update, msg, ticks); + + return msg->state == MLK_MESSAGE_STATE_NONE; +} + +void +mlk_message_draw(const struct mlk_message *msg) +{ + assert(msg); + + MLK__DELEGATE_INVOKE(msg->delegate, mlk_message_delegate, draw, msg); +} + +void +mlk_message_hide(struct mlk_message *msg) +{ + assert(msg); + + msg->state = MLK_MESSAGE_STATE_HIDING; msg->elapsed = 0; } diff -r 79afc6d5cc7e -r 88e9bd420a28 libmlk-rpg/mlk/rpg/message.h --- a/libmlk-rpg/mlk/rpg/message.h Sat Mar 04 20:38:00 2023 +0100 +++ b/libmlk-rpg/mlk/rpg/message.h Sun Mar 05 10:51:25 2023 +0100 @@ -23,67 +23,94 @@ #include +#define MLK_MESSAGE_DELAY_DEFAULT (150) +#define MLK_MESSAGE_DURATION_DEFAULT (5000) + struct mlk_font; -struct mlk_theme; +struct mlk_message; union mlk_event; -#define MESSAGE_DELAY_DEFAULT (150) -#define MESSAGE_TIMEOUT_DEFAULT (5000) +enum mlk_message_flags { + MLK_MESSAGE_FLAGS_AUTOMATIC = (1 << 0), + MLK_MESSAGE_FLAGS_QUESTION = (1 << 1), + MLK_MESSAGE_FLAGS_FADEIN = (1 << 2), + MLK_MESSAGE_FLAGS_FADEOUT = (1 << 3) +}; -enum message_flags { - MESSAGE_FLAGS_AUTOMATIC = (1 << 0), - MESSAGE_FLAGS_QUESTION = (1 << 1), - MESSAGE_FLAGS_FADEIN = (1 << 2), - MESSAGE_FLAGS_FADEOUT = (1 << 3) +enum mlk_message_state { + MLK_MESSAGE_STATE_NONE, + MLK_MESSAGE_STATE_OPENING, + MLK_MESSAGE_STATE_SHOWING, + MLK_MESSAGE_STATE_HIDING }; -enum message_state { - MESSAGE_STATE_NONE, - MESSAGE_STATE_OPENING, - MESSAGE_STATE_SHOWING, - MESSAGE_STATE_HIDING +struct mlk_message_style { + unsigned int padding; + unsigned int delay; + unsigned int duration; + unsigned long bg_color; + unsigned long border_color; + unsigned long border_size; + unsigned long text_color; + unsigned long selected_color; + struct mlk_font *text_font; }; -struct message { - int x; - int y; - unsigned int w; - unsigned int h; - unsigned int spacing; - unsigned int delay; - unsigned int timeout; +struct mlk_message_delegate { + void *data; + + int (*query)(struct mlk_message_delegate *self, + const struct mlk_message *message, + unsigned int *w, + unsigned int *h); + + void (*update)(struct mlk_message_delegate *self, + struct mlk_message *message, + unsigned int ticks); + + void (*draw)(struct mlk_message_delegate *self, + const struct mlk_message *message); +}; + +struct mlk_message { + int x, y; + unsigned int w, h; const char * const *lines; size_t linesz; unsigned int index; - enum message_flags flags; - enum message_state state; - const struct mlk_theme *theme; + enum mlk_message_flags flags; + enum mlk_message_state state; + struct mlk_message_style *style; + struct mlk_message_delegate *delegate; unsigned int elapsed; double scale; }; +extern struct mlk_message_style mlk_message_style; +extern struct mlk_message_delegate mlk_message_delegate; + #if defined(__cplusplus) extern "C" { #endif void -message_start(struct message *msg); +mlk_message_start(struct mlk_message *msg); -void -message_query(const struct message *msg, unsigned int *w, unsigned int *h); +int +mlk_message_query(const struct mlk_message *msg, unsigned int *w, unsigned int *h); void -message_handle(struct message *msg, const union mlk_event *ev); +mlk_message_handle(struct mlk_message *msg, const union mlk_event *ev); int -message_update(struct message *msg, unsigned int ticks); +mlk_message_update(struct mlk_message *msg, unsigned int ticks); void -message_draw(const struct message *msg); +mlk_message_draw(const struct mlk_message *msg); void -message_hide(struct message *msg); +mlk_message_hide(struct mlk_message *msg); #if defined(__cplusplus) } diff -r 79afc6d5cc7e -r 88e9bd420a28 libmlk-ui/mlk/ui/label.h --- a/libmlk-ui/mlk/ui/label.h Sat Mar 04 20:38:00 2023 +0100 +++ b/libmlk-ui/mlk/ui/label.h Sun Mar 05 10:51:25 2023 +0100 @@ -29,7 +29,7 @@ struct mlk_label_delegate { void *data; - int (*query)(struct mlk_label_delegate *, const struct mlk_label *, unsigned int *, unsigned *); + int (*query)(struct mlk_label_delegate *, const struct mlk_label *, unsigned int *, unsigned int *); void (*update)(struct mlk_label_delegate *, struct mlk_label *, unsigned int); void (*draw)(struct mlk_label_delegate *, const struct mlk_label *); }; diff -r 79afc6d5cc7e -r 88e9bd420a28 libmlk-ui/mlk/ui/ui.h --- a/libmlk-ui/mlk/ui/ui.h Sat Mar 04 20:38:00 2023 +0100 +++ b/libmlk-ui/mlk/ui/ui.h Sun Mar 05 10:51:25 2023 +0100 @@ -23,11 +23,14 @@ /* TODO: make this a global variable to allow modification of default theme. */ /* https://lospec.com/palette-list/duel */ -#define MLK_UI_COLOR_TEXT 0x222323ff -#define MLK_UI_COLOR_SELECTED 0x55b67dff -#define MLK_UI_COLOR_BG 0xf5f7faff -#define MLK_UI_COLOR_BORDER 0xcdd2daff -#define MLK_UI_COLOR_DEBUG 0xe45c5fff +#define MLK_UI_COLOR_TEXT (0x222323ff) +#define MLK_UI_COLOR_SELECTED (0x55b67dff) +#define MLK_UI_COLOR_BG (0xf5f7faff) +#define MLK_UI_COLOR_BORDER (0xcdd2daff) +#define MLK_UI_COLOR_DEBUG (0xe45c5fff) + +#define MLK_UI_PADDING (10) +#define MLK_UI_BORDER (2) enum mlk_align;