changeset 174:6992085d47fd

ui: major theme overhaul, closes #2509 @1h - The font does not contain a color anymore, - Add a new color argument to font_render, - Theme are stored `const` in UI elements to promise no modifications, - Also make all <ui>_draw function to take a const widget too.
author David Demelier <markand@malikania.fr>
date Thu, 22 Oct 2020 15:16:43 +0200
parents cd69c8791dac
children ce789473567e
files examples/example-font.c examples/example-message.c libadventure/adventure/state/mainmenu.c libadventure/adventure/state/panic.c libadventure/adventure/state/splashscreen.c libcore/core/font.c libcore/core/font.h librpg/rpg/message.c librpg/rpg/message.h libui/ui/button.c libui/ui/button.h libui/ui/checkbox.c libui/ui/checkbox.h libui/ui/debug.c libui/ui/debug.h libui/ui/frame.c libui/ui/frame.h libui/ui/label.c libui/ui/label.h libui/ui/theme.c libui/ui/theme.h libui/ui/ui.h
diffstat 22 files changed, 135 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/examples/example-font.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/examples/example-font.c	Thu Oct 22 15:16:43 2020 +0200
@@ -102,10 +102,9 @@
 		painter_set_color(0xffffffff);
 		painter_clear();
 
-		font->color = colors[ci];
 		font->style = style;
 
-		if (!font_render(font, &tex, "Example of text. Use <Left>/<Right> to change color and <Space> to toggle antialiasing."))
+		if (!font_render(font, &tex, "Example of text. Use <Left>/<Right> to change color and <Space> to toggle antialiasing.", colors[ci]))
 			panic();
 
 		texture_draw(&tex, 10, 10);
--- a/examples/example-message.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/examples/example-message.c	Thu Oct 22 15:16:43 2020 +0200
@@ -97,7 +97,7 @@
 }
 
 static void
-my_draw_frame(struct theme *th, const struct frame *f)
+my_draw_frame(const struct theme *th, const struct frame *f)
 {
 	(void)th;
 
--- a/libadventure/adventure/state/mainmenu.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libadventure/adventure/state/mainmenu.c	Thu Oct 22 15:16:43 2020 +0200
@@ -84,7 +84,7 @@
 static void
 init_title(struct mainmenu *main, struct font *font)
 {
-	if (!font_render(font, &main->texts[3].tex, "Molko's Adventure"))
+	if (!font_render(font, &main->texts[3].tex, "Molko's Adventure", 0x000000ff))
 		panic();
 	
 	/* Align header. */
@@ -97,9 +97,9 @@
 static void
 init_items(struct mainmenu *main, struct font *font)
 {
-	if (!font_render(font, &main->texts[0].tex, "New") ||
-	    !font_render(font, &main->texts[1].tex, "Continue") ||
-	    !font_render(font, &main->texts[2].tex, "Quit"))
+	if (!font_render(font, &main->texts[0].tex, "New", 0x000000ff) ||
+	    !font_render(font, &main->texts[1].tex, "Continue", 0x000000ff) ||
+	    !font_render(font, &main->texts[2].tex, "Quit", 0x000000ff))
 		panic();
 
 	main->texts[0].x = (window.w / 2) - (main->texts[0].tex.w / 2);
@@ -125,7 +125,6 @@
 	    !font_openmem(&fonts[1], fonts_pirata_one, sizeof (fonts_pirata_one), 30))
 		panic();
 
-	fonts[0].color = fonts[1].color = 0x000000ff;
 	fonts[0].style = fonts[1].style = FONT_STYLE_ANTIALIASED;
 
 	init_title(main, &fonts[0]);
--- a/libadventure/adventure/state/panic.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libadventure/adventure/state/panic.c	Thu Oct 22 15:16:43 2020 +0200
@@ -94,20 +94,16 @@
 {
 	struct theme *theme;
 	struct view *view;
-	struct font font;
+	struct font *font;
 
 	theme = theme_default();
+	font = theme->fonts[THEME_FONT_INTERFACE];
 	view = ecalloc(1, sizeof (*view));
 
-	/* Generate the texts. */
-	font_shallow(&font, theme->fonts[THEME_FONT_INTERFACE]);
-	font.style = FONT_STYLE_ANTIALIASED,
-	font.color = FOREGROUND;
-
-	if (!font_render(&font, &view->texts[0].tex, "An unrecoverable error occured and the game cannot continue.") ||
-	    !font_render(&font, &view->texts[1].tex, "Please report the detailed error as provided below.") ||
-	    !font_render(&font, &view->texts[2].tex, "Press <s> to save information and generate a core dump.") ||
-	    !font_render(&font, &view->texts[3].tex, "Press <q> to quit without saving information."))
+	if (!font_render(font, &view->texts[0].tex, "An unrecoverable error occured and the game cannot continue.", FOREGROUND) ||
+	    !font_render(font, &view->texts[1].tex, "Please report the detailed error as provided below.", FOREGROUND) ||
+	    !font_render(font, &view->texts[2].tex, "Press <s> to save information and generate a core dump.", FOREGROUND) ||
+	    !font_render(font, &view->texts[3].tex, "Press <q> to quit without saving information.", FOREGROUND))
 		die("%s", error());
 
 	/* All align x the same. */
@@ -173,7 +169,7 @@
 	struct theme *theme = theme_default();
 	struct view *view = state->data;
 	struct texture tex;
-	struct font font;
+	struct font *font;
 	int x, y;
 
 	painter_set_color(BACKGROUND);
@@ -183,11 +179,9 @@
 		texture_draw(&view->texts[i].tex, view->texts[i].x, view->texts[i].y);
 
 	/* The error is only available here. */
-	font_shallow(&font, theme->fonts[THEME_FONT_INTERFACE]);
-	font.color = FOREGROUND;
-	font.style = FONT_STYLE_ANTIALIASED;
+	font = theme->fonts[THEME_FONT_INTERFACE];
 
-	if (!font_render(&font, &tex, error()))
+	if (!font_render(font, &tex, error(), FOREGROUND))
 		die("%s\n", error());
 
 	align(ALIGN_LEFT, &x, &y, tex.w, tex.h, 0, 0, window.w, window.h);
--- a/libadventure/adventure/state/splashscreen.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libadventure/adventure/state/splashscreen.c	Thu Oct 22 15:16:43 2020 +0200
@@ -60,10 +60,9 @@
 	if (!font_openmem(&font, fonts_cubic, sizeof (fonts_cubic), 80))
 		panic();
 
-	font.color = 0x19332dff;
 	font.style = FONT_STYLE_ANTIALIASED;
 
-	if (!font_render(&font, &splash->tex, "malikania"))
+	if (!font_render(&font, &splash->tex, "malikania", 0x19332dff))
 		panic();
 
 	align(ALIGN_CENTER, &splash->x, &splash->y, splash->tex.w, splash->tex.h,
--- a/libcore/core/font.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libcore/core/font.c	Thu Oct 22 15:16:43 2020 +0200
@@ -66,22 +66,20 @@
 bool
 font_ok(const struct font *font)
 {
-	assert(font);
-
-	return font->handle;
+	return font && font->handle;
 }
 
 bool
-font_render(struct font *font, struct texture *tex, const char *text)
+font_render(struct font *font, struct texture *tex, const char *text, unsigned int color)
 {
 	assert(font_ok(font));
 	assert(text);
 
 	SDL_Color fg = {
-		.r = COLOR_R(font->color),
-		.g = COLOR_G(font->color),
-		.b = COLOR_B(font->color),
-		.a = COLOR_A(font->color)
+		.r = COLOR_R(color),
+		.g = COLOR_G(color),
+		.b = COLOR_B(color),
+		.a = COLOR_A(color)
 	};
 	SDL_Surface *surface;
 	SDL_Surface *(*func)(TTF_Font *, const char *, SDL_Color);
--- a/libcore/core/font.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/libcore/core/font.h	Thu Oct 22 15:16:43 2020 +0200
@@ -28,6 +28,8 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#include <core/plat.h>
+
 struct texture;
 
 /**
@@ -43,7 +45,6 @@
  */
 struct font {
 	enum font_style style;          /*!< (+) Style for rendering. */
-	unsigned long color;            /*!< (+) Color for rendering. */
 	void *handle;                   /*!< (*) Native handle. */
 };
 
@@ -58,7 +59,7 @@
  * \return False on errors.
  */
 bool
-font_open(struct font *font, const char *path, unsigned int size);
+font_open(struct font *font, const char *path, unsigned int size) PLAT_NODISCARD;
 
 /**
  * Open font from memory buffer.
@@ -73,7 +74,7 @@
  * \return False on errors.
  */
 bool
-font_openmem(struct font *font, const void *buffer, size_t buflen, unsigned int size);
+font_openmem(struct font *font, const void *buffer, size_t buflen, unsigned int size) PLAT_NODISCARD;
 
 /**
  * Convenient shortcut to shallow copy src into dst.
@@ -95,8 +96,7 @@
 /**
  * Tells if the font was properly opened.
  *
- * \pre font != NULL
- * \param font the font to check
+ * \param font the font to check (may be NULL)
  * \return True if the native handle was opened.
  */
 bool
@@ -113,10 +113,11 @@
  * \param font the font to use
  * \param tex the texture to generate
  * \param text the UTF-8 text
+ * \param color the foreground color
  * \return False on errors.
  */
 bool
-font_render(struct font *font, struct texture *tex, const char *text);
+font_render(struct font *font, struct texture *tex, const char *text, unsigned int color) PLAT_NODISCARD;
 
 /**
  * Get the maximum height for all glyphs.
@@ -140,7 +141,7 @@
  * \return False in case of error and pointers to w and h are left unmodified.
  */
 bool
-font_query(const struct font *font, const char *text, unsigned int *w, unsigned int *h);
+font_query(const struct font *font, const char *text, unsigned int *w, unsigned int *h) PLAT_NODISCARD;
 
 /**
  * Close the font.
--- a/librpg/rpg/message.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/librpg/rpg/message.c	Thu Oct 22 15:16:43 2020 +0200
@@ -115,8 +115,11 @@
 	struct label label;
 	unsigned int lw, lh;
 
-	/* Shallow copy theme to modify colors. */
-	theme_shallow(&theme, msg->theme);
+	/*
+	 * We need a copy of the current theme because we will alter the label
+	 * color depending on the selection.
+	 */
+	theme_shallow(&theme, THEME(msg));
 
 	for (int i = 0; i < MESSAGE_LINES_MAX; ++i) {
 		if (!msg->text[i])
@@ -261,7 +264,7 @@
 }
 
 void
-message_draw(struct message *msg)
+message_draw(const struct message *msg)
 {
 	assert(msg);
 
--- a/librpg/rpg/message.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/librpg/rpg/message.h	Thu Oct 22 15:16:43 2020 +0200
@@ -134,7 +134,7 @@
 	unsigned int index;                     /*!< (+) Line selected */
 	enum message_flags flags;               /*!< (+) Message flags */
 	enum message_state state;               /*!< (-) Current state */
-	struct theme *theme;                    /*!< (+&?) Theme to use. */
+	const struct theme *theme;              /*!< (+&?) Theme to use. */
 	unsigned int elapsed;                   /*!< (-) Time elapsed. */
 	double scale;                           /*!< (-) Current scale [0-1]. */
 };
@@ -194,7 +194,7 @@
  * \param msg the message
  */
 void
-message_draw(struct message *msg);
+message_draw(const struct message *msg);
 
 /**
  * Start hiding the message.
--- a/libui/ui/button.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/button.c	Thu Oct 22 15:16:43 2020 +0200
@@ -54,7 +54,7 @@
 }
 
 void
-button_draw_default(struct theme *t, const struct button *button)
+button_draw_default(const struct theme *t, const struct button *button)
 {
 	assert(t);
 	assert(button);
@@ -118,7 +118,7 @@
 }
 
 void
-button_draw(struct button *button)
+button_draw(const struct button *button)
 {
 	assert(button);
 
--- a/libui/ui/button.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/button.h	Thu Oct 22 15:16:43 2020 +0200
@@ -49,7 +49,7 @@
 	unsigned int h;                 /*!< (+) Height. */
 	const char *text;               /*!< (+&) Text to draw. */
 	enum button_state state;        /*!< (+) Button state. */
-	struct theme *theme;            /*!< (+&?) Theme to use. */
+	const struct theme *theme;      /*!< (+&?) Theme to use. */
 };
 
 /**
@@ -84,7 +84,7 @@
  * \param button the button
  */
 void
-button_draw_default(struct theme *t, const struct button *button);
+button_draw_default(const struct theme *t, const struct button *button);
 
 /**
  * Draw the button.
@@ -93,7 +93,7 @@
  * \param button the button
  */
 void
-button_draw(struct button *button);
+button_draw(const struct button *button);
 
 /**
  * Convert the button into an action.
--- a/libui/ui/checkbox.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/checkbox.c	Thu Oct 22 15:16:43 2020 +0200
@@ -50,7 +50,7 @@
 }
 
 void
-checkbox_draw_default(struct theme *t, const struct checkbox *cb)
+checkbox_draw_default(const struct theme *t, const struct checkbox *cb)
 {
 	assert(t);
 	assert(cb);
--- a/libui/ui/checkbox.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/checkbox.h	Thu Oct 22 15:16:43 2020 +0200
@@ -36,12 +36,12 @@
  * \brief GUI checkbox.
  */
 struct checkbox {
-	int x;                  /*!< (+) Position in x. */
-	int y;                  /*!< (+) Position in y. */
-	unsigned int w;         /*!< (+) Width. */
-	unsigned int h;         /*!< (+) Height. */
-	bool checked;           /*!< (+) Is activated? */
-	struct theme *theme;    /*!< (+&?) Theme to use. */
+	int x;                          /*!< (+) Position in x. */
+	int y;                          /*!< (+) Position in y. */
+	unsigned int w;                 /*!< (+) Width. */
+	unsigned int h;                 /*!< (+) Height. */
+	bool checked;                   /*!< (+) Is activated? */
+	const struct theme *theme;      /*!< (+&?) Theme to use. */
 };
 
 /**
@@ -53,7 +53,7 @@
  * \param cb the checkbox
  */
 void
-checkbox_draw_default(struct theme *t, const struct checkbox *cb);
+checkbox_draw_default(const struct theme *t, const struct checkbox *cb);
 
 /**
  * Draw the checkbox.
--- a/libui/ui/debug.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/debug.c	Thu Oct 22 15:16:43 2020 +0200
@@ -56,22 +56,17 @@
 		return;
 
 	char line[DEBUG_LINE_MAX];
-	struct theme *theme;
-	struct font font;
+	const struct theme *theme;
+	struct font *font;
 	struct texture tex;
 	int x, y;
 
 	vsnprintf(line, sizeof (line), fmt, ap);
 
-	/* Get the font and modify its style. */
 	theme = report->theme ? report->theme : theme_default();
+	font = theme->fonts[THEME_FONT_DEBUG];
 
-	/* Update font style. */
-	font_shallow(&font, theme->fonts[THEME_FONT_DEBUG]);
-	font.style = FONT_STYLE_ANTIALIASED;
-	font.color = theme->colors[THEME_COLOR_DEBUG];
-
-	if (!font_render(&font, &tex, line))
+	if (!font_render(font, &tex, line, theme->colors[THEME_COLOR_DEBUG]))
 		return;
 
 	x = theme->padding;
--- a/libui/ui/debug.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/debug.h	Thu Oct 22 15:16:43 2020 +0200
@@ -66,7 +66,7 @@
  * Use this structure each time you need to print one or more messages.
  */
 struct debug_report {
-	struct theme *theme;            /*!< (+&?) Theme to use. */
+	const struct theme *theme;      /*!< (+&?) Theme to use. */
 	unsigned int count;             /*!< (-) Number of messages already printed. */
 };
 
--- a/libui/ui/frame.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/frame.c	Thu Oct 22 15:16:43 2020 +0200
@@ -32,7 +32,7 @@
 }
 
 void
-frame_draw_default(struct theme *t, const struct frame *frame)
+frame_draw_default(const struct theme *t, const struct frame *frame)
 {
 	assert(t);
 	assert(frame);
--- a/libui/ui/frame.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/frame.h	Thu Oct 22 15:16:43 2020 +0200
@@ -40,12 +40,12 @@
  * \brief GUI frame.
  */
 struct frame {
-	int x;                  /*!< (+) Position in x. */
-	int y;                  /*!< (+) Position in y. */
-	unsigned int w;         /*!< (+) Width. */
-	unsigned int h;         /*!< (+) Height. */
-	enum frame_style style; /*!< (+) Frame style. */
-	struct theme *theme;    /*!< (+&?) Theme to use. */
+	int x;                          /*!< (+) Position in x. */
+	int y;                          /*!< (+) Position in y. */
+	unsigned int w;                 /*!< (+) Width. */
+	unsigned int h;                 /*!< (+) Height. */
+	enum frame_style style;         /*!< (+) Frame style. */
+	const struct theme *theme;      /*!< (+&?) Theme to use. */
 };
 
 /**
@@ -57,7 +57,7 @@
  * \param frame the frame
  */
 void
-frame_draw_default(struct theme *t, const struct frame *frame);
+frame_draw_default(const struct theme *t, const struct frame *frame);
 
 /**
  * Draw the frame.
--- a/libui/ui/label.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/label.c	Thu Oct 22 15:16:43 2020 +0200
@@ -34,7 +34,7 @@
 }
 
 void
-label_draw_default(struct theme *t, const struct label *label)
+label_draw_default(const struct theme *t, const struct label *label)
 {
 	assert(t);
 	assert(label);
@@ -46,9 +46,7 @@
 
 	/* Shadow text, only if enabled. */
 	if (label->flags & LABEL_FLAGS_SHADOW) {
-		font->color = t->colors[THEME_COLOR_SHADOW];
-
-		if (!font_render(font, &tex, label->text))
+		if (!font_render(font, &tex, label->text, t->colors[THEME_COLOR_SHADOW]))
 			panic();
 
 		texture_draw(&tex, label->x + 1, label->y + 1);
@@ -56,22 +54,26 @@
 	}
 
 	/* Normal text. */
-	font->color = t->colors[THEME_COLOR_NORMAL];
-
-	if (!font_render(font, &tex, label->text))
+	if (!font_render(font, &tex, label->text, t->colors[THEME_COLOR_NORMAL]))
 		panic();
 
 	texture_draw(&tex, label->x, label->y);
 	texture_finish(&tex);
 }
 
+bool
+label_ok(const struct label *label)
+{
+	return label && label->text && strlen(label->text) > 0;
+}
+
 void
-label_query(struct label *label, unsigned int *w, unsigned int *h)
+label_query(const struct label *label, unsigned int *w, unsigned int *h)
 {
 	assert(label);
 	assert(label->text);
 
-	struct theme *t = label->theme ? label->theme : theme_default();
+	const struct theme *t = label->theme ? label->theme : theme_default();
 
 	if (!font_query(t->fonts[THEME_FONT_INTERFACE], label->text, w, h))
 		panic();
--- a/libui/ui/label.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/label.h	Thu Oct 22 15:16:43 2020 +0200
@@ -44,7 +44,7 @@
 	int y;                          /*!< (+) Position in y. */
 	const char *text;               /*!< (+&) Text to show. */
 	enum label_flags flags;         /*!< (+) Optional flags. */
-	struct theme *theme;            /*!< (+&?) Theme to use. */
+	const struct theme *theme;      /*!< (+&?) Theme to use. */
 };
 
 /**
@@ -56,7 +56,16 @@
  * \param label the label
  */
 void
-label_draw_default(struct theme *t, const struct label *label);
+label_draw_default(const struct theme *t, const struct label *label);
+
+/**
+ * Tells if the label is usable.
+ *
+ * \param label the label to check (may be NULL)
+ * \return False if label is null or as empty text.
+ */
+bool
+label_ok(const struct label *label);
 
 /**
  * Update the `w` and `h` fields with the dimensions the text would needs with
@@ -68,7 +77,7 @@
  * \param h the pointer to height (may be NULL)
  */
 void
-label_query(struct label *label, unsigned int *w, unsigned int *h);
+label_query(const struct label *label, unsigned int *w, unsigned int *h);
 
 /**
  * Draw the label.
--- a/libui/ui/theme.c	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/theme.c	Thu Oct 22 15:16:43 2020 +0200
@@ -112,7 +112,7 @@
 }
 
 void
-theme_draw_frame(struct theme *t, const struct frame *frame)
+theme_draw_frame(const struct theme *t, const struct frame *frame)
 {
 	assert(frame);
 
@@ -120,7 +120,7 @@
 }
 
 void
-theme_draw_label(struct theme *t, const struct label *label)
+theme_draw_label(const struct theme *t, const struct label *label)
 {
 	assert(label);
 
@@ -128,7 +128,7 @@
 }
 
 void
-theme_draw_button(struct theme *t, const struct button *button)
+theme_draw_button(const struct theme *t, const struct button *button)
 {
 	assert(button);
 
@@ -136,7 +136,7 @@
 }
 
 void
-theme_draw_checkbox(struct theme *t, const struct checkbox *cb)
+theme_draw_checkbox(const struct theme *t, const struct checkbox *cb)
 {
 	assert(cb);
 
--- a/libui/ui/theme.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/theme.h	Thu Oct 22 15:16:43 2020 +0200
@@ -63,7 +63,7 @@
 	struct font *fonts[THEME_FONT_LAST];
 
 	/**
-	 * (+) Miscellaneous colors.
+	 * (+) User interface colors.
 	 */
 	unsigned long colors[THEME_COLOR_LAST];
 
@@ -80,28 +80,28 @@
 	 *
 	 * \see \ref theme_draw_frame
 	 */
-	void (*draw_frame)(struct theme *, const struct frame *);
+	void (*draw_frame)(const struct theme *, const struct frame *);
 
 	/**
 	 * (+) Draw a label.
 	 *
 	 * \see \ref theme_draw_label
 	 */
-	void (*draw_label)(struct theme *, const struct label *);
+	void (*draw_label)(const struct theme *, const struct label *);
 
 	/**
 	 * (+) Draw a button.
 	 *
 	 * \see \ref theme_draw_button
 	 */
-	void (*draw_button)(struct theme *, const struct button *);
+	void (*draw_button)(const struct theme *, const struct button *);
 
 	/**
 	 * (+) Draw a checkbox.
 	 *
 	 * \see \ref theme_draw_button
 	 */
-	void (*draw_checkbox)(struct theme *t, const struct checkbox *);
+	void (*draw_checkbox)(const struct theme *t, const struct checkbox *);
 };
 
 /**
@@ -118,7 +118,9 @@
 /**
  * Get a reference to the default theme.
  *
- * \return A non-owning pointer to a static storage for the default theme
+ * The returned theme may be modified to modify the whole UI.
+ *
+ * \return A non-owning pointer to a static storage for the default theme.
  */
 struct theme *
 theme_default(void);
@@ -129,13 +131,40 @@
  * Use this function when you want your own local copy of a theme because you
  * want to modify some attributes.
  *
+ * You should not modify underlying objects within the new theme because they
+ * still point to the same region and you may erase the user settings.
+ *
+ * This code is incorrect:
+ *
+ * ```c
+ * struct theme th;
+ *
+ * theme_shallow(&th, theme_default());
+ * th.fonts[THEME_FONT_INTERFACE].style = FONT_STYLE_NONE;
+ *
+ * //
+ * // Since th.fonts contain same pointers to theme_default, you'll erase
+ * // the default theme settings.
+ * //
+ * ```
+ *
+ * Instead, if you really need to modify an underlying object, you have to copy
+ * it too.
+ *
+ * ```c
+ * struct font font;
+ *
+ * font_shallow(&font, theme_default()->fonts[THEME_FONT_INTERFACE];
+ * font.style = FONT_STYLE_NONE;
+ *
+ * // No font_finish needed either, it is only a shallow copy.
+ * ```
+ *
  * This is a shortcut to `memcpy(dst, src, sizeof (*src))`.
  *
  * \pre dst != NULL
  * \param dst the destination theme
  * \param src the source theme (may be NULL)
- * \note Resources are not cloned, internal pointers will adress the same
- *       regions.
  */
 void
 theme_shallow(struct theme *dst, const struct theme *src);
@@ -148,7 +177,7 @@
  * \param frame the frame
  */
 void
-theme_draw_frame(struct theme *t, const struct frame *frame);
+theme_draw_frame(const struct theme *t, const struct frame *frame);
 
 /**
  * Draw a label.
@@ -158,7 +187,7 @@
  * \param label the label
  */
 void
-theme_draw_label(struct theme *t, const struct label *label);
+theme_draw_label(const struct theme *t, const struct label *label);
 
 /**
  * Draw a button.
@@ -168,7 +197,7 @@
  * \param button the button
  */
 void
-theme_draw_button(struct theme *t, const struct button *button);
+theme_draw_button(const struct theme *t, const struct button *button);
 
 /**
  * Draw a checkbox.
@@ -177,7 +206,7 @@
  * \param cb the checkbox
  */
 void
-theme_draw_checkbox(struct theme *t, const struct checkbox *cb);
+theme_draw_checkbox(const struct theme *t, const struct checkbox *cb);
 
 /**
  * This function is automatically called from \ref ui_finish and thus not
--- a/libui/ui/ui.h	Wed Oct 21 12:50:11 2020 +0200
+++ b/libui/ui/ui.h	Thu Oct 22 15:16:43 2020 +0200
@@ -26,13 +26,15 @@
 
 #include <stdbool.h>
 
+#include <core/plat.h>
+
 /**
  * Initialize the ui library.
  *
  * \return False on errors.
  */
 bool
-ui_init(void);
+ui_init(void) PLAT_NODISCARD;
 
 /**
  * Close the ui library.