changeset 157:fb306ed990f8

ui: make message more flexible, closes #2501
author David Demelier <markand@malikania.fr>
date Fri, 16 Oct 2020 14:32:22 +0200
parents c3a40062acc2
children e8d2740703df
files examples/example-message.c librpg/rpg/message.c librpg/rpg/message.h
diffstat 3 files changed, 91 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- 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();
 }
--- 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);
 	}
 }
--- 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]. */
 };
 
 /**