# HG changeset patch # User David Demelier # Date 1602863139 -7200 # Node ID e8d2740703df06a1239704bdefe2b8ac30042e89 # Parent fb306ed990f8c1c67ab0ea6297e64cd45f0598ab ui: make message auto-spacing lines diff -r fb306ed990f8 -r e8d2740703df examples/example-message.c --- a/examples/example-message.c Fri Oct 16 14:32:22 2020 +0200 +++ b/examples/example-message.c Fri Oct 16 17:45:39 2020 +0200 @@ -38,7 +38,7 @@ #define H (720) #define MW (W * 0.75) -#define MH (H * 0.130) +#define MH (H * 0.120) #define MX ((W / 2) - (MW / 2)) #define MY (100) @@ -303,7 +303,7 @@ .h = 500, .text = { "And this one is terribly large.", - "But lines are still padded at top." + "So lines will have large spacing." }, }; diff -r fb306ed990f8 -r e8d2740703df librpg/rpg/message.c --- a/librpg/rpg/message.c Fri Oct 16 14:32:22 2020 +0200 +++ b/librpg/rpg/message.c Fri Oct 16 17:45:39 2020 +0200 @@ -78,25 +78,50 @@ frame_draw(&frame); } +static inline unsigned int +spacing(const struct message *msg, const struct theme *t, unsigned int fh) +{ + assert(msg); + assert(t); + + /* No vertical spacing if only one message. */ + if (MESSAGE_LINES_MAX <= 1) + return 0; + + return ((msg->h - t->padding * 2) - (fh * MESSAGE_LINES_MAX)) / (MESSAGE_LINES_MAX - 1); +} + +static inline unsigned int +height(const struct theme *t, unsigned int lvreq) +{ + assert(t); + + return lvreq * MESSAGE_LINES_MAX; +} + static void draw_lines(const struct message *msg) { struct theme theme; - unsigned int lineh, totalh; + unsigned int lvreq, vreq, vspace = 0; /* Shallow copy theme to modify colors. */ theme_shallow(&theme, msg->theme); /* - * Compute text size for list alignment and full height required to emit - * a warning if the message box is too small. + * Compute the maximum line height for the given font. + * + * Then, compute the minimum height required to draw the lines (without + * their vertical spacing). */ - lineh = font_height(theme.fonts[THEME_FONT_INTERFACE]); - totalh = lineh * MESSAGE_LINES_MAX + (MESSAGE_LINES_MAX + 1) * theme.padding; + lvreq = font_height(theme.fonts[THEME_FONT_INTERFACE]); + vreq = height(&theme, lvreq); - /* 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); + /* Now if enough space, compute the spacing between lines. */ + if (vreq > msg->h) + trace("message height is too small: %u < %u", msg->h, vreq); + else + vspace = spacing(msg, &theme, lvreq); for (int i = 0; i < MESSAGE_LINES_MAX; ++i) { if (!msg->text[i]) @@ -104,7 +129,7 @@ struct label label = { .x = theme.padding, - .y = theme.padding * (i + 1) + i * lineh, + .y = theme.padding + (i * (lvreq + vspace)), .w = msg->w, .h = msg->h, .theme = &theme, @@ -118,9 +143,9 @@ * we need to cheat the normal color. */ if (msg->flags & MESSAGE_FLAGS_QUESTION && msg->index == (unsigned int)i) - theme.colors[THEME_COLOR_NORMAL] = THEME(msg)->colors[THEME_COLOR_SELECTED]; + theme.colors[THEME_COLOR_NORMAL] = theme.colors[THEME_COLOR_SELECTED]; else - theme.colors[THEME_COLOR_NORMAL] = THEME(msg)->colors[THEME_COLOR_NORMAL]; + theme.colors[THEME_COLOR_NORMAL] = theme.colors[THEME_COLOR_NORMAL]; label_query(&label);