# HG changeset patch # User David Demelier # Date 1602851542 -7200 # Node ID fb306ed990f8c1c67ab0ea6297e64cd45f0598ab # Parent c3a40062acc260dbacbe2239001fcf035a3c925f ui: make message more flexible, closes #2501 diff -r c3a40062acc2 -r fb306ed990f8 examples/example-message.c --- a/examples/example-message.c Fri Oct 16 13:54:31 2020 +0200 +++ b/examples/example-message.c Fri Oct 16 14:32:22 2020 +0200 @@ -38,7 +38,7 @@ #define H (720) #define MW (W * 0.75) -#define MH (H * 0.125) +#define MH (H * 0.130) #define MX ((W / 2) - (MW / 2)) #define MY (100) @@ -218,7 +218,7 @@ smallbottom(void) { const unsigned int w = window.w / 4; - const unsigned int h = 50; + const unsigned int h = MH; const int x = (window.w / 2) - (w / 2); const int y = (window.h - h - 10); @@ -238,6 +238,38 @@ } static void +toosmallh(void) +{ + struct message msg = { + .x = MX, + .y = MY, + .w = MW, + .h = 50, + .text = { + "This one is too small in height and will emit a warning.", + }, + }; + + run(&msg); +} + +static void +toosmallw(void) +{ + struct message msg = { + .x = MX, + .y = MY, + .w = 160, + .h = MH, + .text = { + "This one is too small in width." + }, + }; + + run(&msg); +} + +static void custom(void) { struct theme theme; @@ -261,6 +293,23 @@ run(&msg); } +static void +large(void) +{ + struct message msg = { + .x = MX, + .y = MY, + .w = 500, + .h = 500, + .text = { + "And this one is terribly large.", + "But lines are still padded at top." + }, + }; + + run(&msg); +} + int main(int argc, char **argv) { @@ -275,6 +324,9 @@ automatic(); question(); smallbottom(); + toosmallh(); + toosmallw(); custom(); + large(); quit(); } diff -r c3a40062acc2 -r fb306ed990f8 librpg/rpg/message.c --- a/librpg/rpg/message.c Fri Oct 16 13:54:31 2020 +0200 +++ b/librpg/rpg/message.c Fri Oct 16 14:32:22 2020 +0200 @@ -82,20 +82,29 @@ draw_lines(const struct message *msg) { struct theme theme; - unsigned int lineh; + unsigned int lineh, totalh; /* Shallow copy theme to modify colors. */ theme_shallow(&theme, msg->theme); - /* Compute text size for list alignment. */ + /* + * Compute text size for list alignment and full height required to emit + * a warning if the message box is too small. + */ lineh = font_height(theme.fonts[THEME_FONT_INTERFACE]); + totalh = lineh * MESSAGE_LINES_MAX + (MESSAGE_LINES_MAX + 1) * theme.padding; - for (int i = 0; i < 6; ++i) { + /* Check if there is enough room to draw all lines. */ + if (totalh > msg->h) + trace("message height is too small: %u < %u", msg->h, totalh); + + for (int i = 0; i < MESSAGE_LINES_MAX; ++i) { if (!msg->text[i]) continue; struct label label = { - .y = i * lineh, + .x = theme.padding, + .y = theme.padding * (i + 1) + i * lineh, .w = msg->w, .h = msg->h, .theme = &theme, @@ -113,6 +122,11 @@ else theme.colors[THEME_COLOR_NORMAL] = THEME(msg)->colors[THEME_COLOR_NORMAL]; + label_query(&label); + + if (label.w > msg->w) + trace("message width is too small: %u < %u", msg->w, label.w); + label_draw(&label); } } diff -r c3a40062acc2 -r fb306ed990f8 librpg/rpg/message.h --- a/librpg/rpg/message.h Fri Oct 16 13:54:31 2020 +0200 +++ b/librpg/rpg/message.h Fri Oct 16 14:32:22 2020 +0200 @@ -84,6 +84,11 @@ #define MESSAGE_TIMEOUT_DEFAULT (5000) /** + * \brief Maximum number of lines allowed in the message. + */ +#define MESSAGE_LINES_MAX (3) + +/** * \brief Message flags. */ enum message_flags { @@ -110,20 +115,20 @@ * any user properties and therefore must exist while using it. */ struct message { - int x; /*!< (+) Position in x. */ - int y; /*!< (+) Position in y. */ - unsigned int w; /*!< (+) Width. */ - unsigned int h; /*!< (+) Height. */ - unsigned int delay; /*!< (+) Delay for animations. */ - unsigned int timeout; /*!< (+) Timeout in milliseconds. */ - const char *text[6]; /*!< (+) Lines of text to show. */ - struct texture *avatar; /*!< (+&?) Avatar face. */ - unsigned int index; /*!< (+) Line selected */ - enum message_flags flags; /*!< (+) Message flags */ - enum message_state state; /*!< (-) Current state */ - struct theme *theme; /*!< (+&?) Theme to use. */ - unsigned int elapsed; /*!< (-) Time elapsed. */ - double scale; /*!< (-) Current scale [0-1]. */ + int x; /*!< (+) Position in x. */ + int y; /*!< (+) Position in y. */ + unsigned int w; /*!< (+) Width. */ + unsigned int h; /*!< (+) Height. */ + unsigned int delay; /*!< (+) Delay for animations. */ + unsigned int timeout; /*!< (+) Timeout in milliseconds. */ + const char *text[MESSAGE_LINES_MAX]; /*!< (+) Lines of text to show. */ + struct texture *avatar; /*!< (+&?) Avatar face. */ + unsigned int index; /*!< (+) Line selected */ + enum message_flags flags; /*!< (+) Message flags */ + enum message_state state; /*!< (-) Current state */ + struct theme *theme; /*!< (+&?) Theme to use. */ + unsigned int elapsed; /*!< (-) Time elapsed. */ + double scale; /*!< (-) Current scale [0-1]. */ }; /**