changeset 151:b19d076856d2

ui: cleanup theme module, closes #2498
author David Demelier <markand@malikania.fr>
date Thu, 15 Oct 2020 14:01:24 +0200
parents 9733d379be89
children 1008a796a9e7
files examples/CMakeLists.txt examples/example-ui.c libui/ui/button.c libui/ui/button.h libui/ui/checkbox.c libui/ui/checkbox.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
diffstat 12 files changed, 334 insertions(+), 142 deletions(-) [+]
line wrap: on
line diff
--- a/examples/CMakeLists.txt	Thu Oct 15 13:13:38 2020 +0200
+++ b/examples/CMakeLists.txt	Thu Oct 15 14:01:24 2020 +0200
@@ -32,6 +32,7 @@
 	TARGET example-font
 	SOURCES example-font.c
 	LIBRARIES libui
+	FOLDER examples
 )
 
 molko_define_executable(
@@ -49,6 +50,7 @@
 	TARGET example-label
 	SOURCES example-label.c
 	LIBRARIES libui
+	FOLDER examples
 )
 
 molko_define_executable(
@@ -82,3 +84,10 @@
 	FOLDER examples
 	LIBRARIES libui libadventure
 )
+
+molko_define_executable(
+	TARGET example-ui
+	SOURCES example-ui.c
+	FOLDER examples
+	LIBRARIES libui
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-ui.c	Thu Oct 15 14:01:24 2020 +0200
@@ -0,0 +1,157 @@
+/*
+ * example-action.c -- example on how to use automatic actions
+ *
+ * Copyright (c) 2020 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <core/clock.h>
+#include <core/event.h>
+#include <core/panic.h>
+#include <core/painter.h>
+#include <core/sys.h>
+#include <core/util.h>
+#include <core/window.h>
+
+#include <ui/button.h>
+#include <ui/checkbox.h>
+#include <ui/frame.h>
+#include <ui/label.h>
+#include <ui/theme.h>
+
+#define W       (1280)
+#define H       (720)
+
+static struct frame frame = {
+	.x = 10,
+	.y = 10,
+	.w = 400,
+	.h = 200
+};
+
+static struct label title = {
+	.text = "Preferences",
+	.x = 10,
+	.y = 10,
+	.w = 400,
+	.h = 200,
+	.flags = LABEL_FLAGS_SHADOW,
+	.align = ALIGN_TOP_LEFT
+};
+
+static struct {
+	struct checkbox cb;
+	struct label label;
+} autosave = {
+	.cb = {
+		.x = 20,
+		.y = 60,
+		.w = 20,
+		.h = 20
+	},
+	.label = {
+		.text = "Auto save game",
+		.x = 20 + 20,
+		.y = 60,
+		.w = 200,
+		.h = 20,
+		.align = ALIGN_LEFT,
+		.flags = LABEL_FLAGS_SHADOW
+	}
+};
+
+static struct button btquit = {
+	.text = "Quit",
+	.w = 50,
+	.h = 20
+};
+
+static void
+init(void)
+{
+	if (!sys_init() ||
+	    !window_init("Example - UI", W, H) ||
+	    !theme_init())
+		panic();
+}
+
+static void
+run(void)
+{
+	struct clock clock = {0};
+
+	clock_start(&clock);
+
+	for (;;) {
+		unsigned int elapsed = clock_elapsed(&clock);
+
+		clock_start(&clock);
+
+		for (union event ev; event_poll(&ev); ) {
+			switch (ev.type) {
+			case EVENT_QUIT:
+				return;
+			default:
+				checkbox_handle(&autosave.cb, &ev);
+				button_handle(&btquit, &ev);
+
+				if (btquit.state == BUTTON_STATE_ACTIVATED)
+					return;
+
+				break;
+			}
+		}
+
+		/* Compute button position at runtime. */
+		align(ALIGN_BOTTOM_RIGHT, &btquit.x, &btquit.y, btquit.w, btquit.h,
+		    frame.x, frame.y, frame.w, frame.h);
+
+		btquit.x -= theme_default()->padding;
+		btquit.y -= theme_default()->padding;
+
+		painter_set_color(0xffffffff);
+		painter_clear();
+		frame_draw(&frame);
+		label_draw(&title);
+		checkbox_draw(&autosave.cb);
+		label_draw(&autosave.label);
+		button_draw(&btquit);
+		painter_present();
+
+		if ((elapsed = clock_elapsed(&clock)) < 20)
+			delay(20 - elapsed);
+	}
+}
+
+static void
+quit(void)
+{
+	theme_finish();
+	window_finish();
+	sys_finish();
+}
+
+int
+main(int argc, char **argv)
+{
+	(void)argc;
+	(void)argv;
+
+	init();
+	run();
+	quit();
+
+	return 0;
+}
+
--- a/libui/ui/button.c	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/button.c	Thu Oct 15 14:01:24 2020 +0200
@@ -20,8 +20,10 @@
 
 #include <core/event.h>
 #include <core/maths.h>
+#include <core/painter.h>
 
 #include "button.h"
+#include "label.h"
 #include "theme.h"
 
 static bool
@@ -36,6 +38,29 @@
 }
 
 void
+button_draw_default(struct theme *t, const struct button *button)
+{
+	assert(t);
+	assert(button);
+
+	(void)t;
+
+	const struct label label = {
+		.text = button->text,
+		.x = button->x,
+		.y = button->y,
+		.w = button->w,
+		.h = button->h,
+		.align = ALIGN_CENTER
+	};
+
+	painter_set_color(0x577277ff);
+	painter_draw_rectangle(button->x, button->y, button->w, button->h);
+
+	label_draw(&label);
+}
+
+void
 button_handle(struct button *button, const union event *ev)
 {
 	assert(button);
--- a/libui/ui/button.h	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/button.h	Thu Oct 15 14:01:24 2020 +0200
@@ -74,6 +74,17 @@
 button_reset(struct button *button);
 
 /**
+ * Default drawing function.
+ *
+ * \pre t != NULL
+ * \pre frame != NULL
+ * \param t the theme
+ * \param button the button
+ */
+void
+button_draw_default(struct theme *t, const struct button *button);
+
+/**
  * Draw the button.
  *
  * \pre button != NULL
--- a/libui/ui/checkbox.c	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/checkbox.c	Thu Oct 15 14:01:24 2020 +0200
@@ -20,7 +20,9 @@
 
 #include <core/event.h>
 #include <core/maths.h>
+#include <core/painter.h>
 
+#include "label.h"
 #include "checkbox.h"
 #include "theme.h"
 
@@ -34,6 +36,23 @@
 }
 
 void
+checkbox_draw_default(struct theme *t, const struct checkbox *cb)
+{
+	assert(t);
+	assert(cb);
+
+	painter_set_color(0x151d28ff);
+	painter_draw_rectangle(cb->x, cb->y, cb->w, cb->h);
+	painter_set_color(0xd7b594ff);
+	painter_draw_rectangle(cb->x + 1, cb->y + 1, cb->w - 2, cb->h - 2);
+
+	if (cb->checked) {
+		painter_set_color(0x341c27ff);
+		painter_draw_rectangle(cb->x + 5, cb->y + 5, cb->w - 10, cb->h - 10);
+	}
+}
+
+void
 checkbox_handle(struct checkbox *cb, const union event *ev)
 {
 	assert(cb);
--- a/libui/ui/checkbox.h	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/checkbox.h	Thu Oct 15 14:01:24 2020 +0200
@@ -36,12 +36,22 @@
 	int y;                  /*!< (+) Position in y. */
 	unsigned int w;         /*!< (+) Width. */
 	unsigned int h;         /*!< (+) Height. */
-	const char *label;      /*!< (+&) Text to show. */
 	bool checked;           /*!< (+) Is activated? */
 	struct theme *theme;    /*!< (+&?) Theme to use. */
 };
 
 /**
+ * Default drawing function.
+ *
+ * \pre t != NULL
+ * \pre cb != NULL
+ * \param t the theme
+ * \param cb the checkbox
+ */
+void
+checkbox_draw_default(struct theme *t, const struct checkbox *cb);
+
+/**
  * Draw the checkbox.
  *
  * \pre cb != NULL
--- a/libui/ui/frame.c	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/frame.c	Thu Oct 15 14:01:24 2020 +0200
@@ -18,10 +18,28 @@
 
 #include <assert.h>
 
+#include <core/painter.h>
+
 #include "frame.h"
 #include "theme.h"
 
 void
+frame_draw_default(struct theme *t, const struct frame *frame)
+{
+	assert(t);
+	assert(frame);
+
+	(void)t;
+
+	if (frame->style == FRAME_STYLE_BOX)
+		painter_set_color(0x7a4841ff);
+	else
+		painter_set_color(0xad7757ff);
+
+	painter_draw_rectangle(frame->x, frame->y, frame->w, frame->h);
+}
+
+void
 frame_draw(const struct frame *frame)
 {
 	assert(frame);
--- a/libui/ui/frame.h	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/frame.h	Thu Oct 15 14:01:24 2020 +0200
@@ -47,6 +47,17 @@
 };
 
 /**
+ * Default drawing function.
+ *
+ * \pre t != NULL
+ * \pre frame != NULL
+ * \param t the theme
+ * \param frame the frame
+ */
+void
+frame_draw_default(struct theme *t, const struct frame *frame);
+
+/**
  * Draw the frame.
  *
  * \pre frame != NULL
--- a/libui/ui/label.c	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/label.c	Thu Oct 15 14:01:24 2020 +0200
@@ -18,12 +18,66 @@
 
 #include <assert.h>
 
+#include <core/font.h>
+#include <core/panic.h>
 #include <core/trace.h>
+#include <core/texture.h>
 
 #include "label.h"
 #include "theme.h"
 
 void
+label_draw_default(struct theme *t, const struct label *label)
+{
+	assert(t);
+	assert(label);
+
+	struct font *font;
+	struct texture tex;
+	int x, y, bx, by;
+	unsigned int tw, th, bw, bh;
+
+	/* Compute real box size according to padding. */
+	bx = label->x + t->padding;
+	by = label->y + t->padding;
+	bw = label->w - (t->padding * 2);
+	bh = label->h - (t->padding * 2);
+
+	/* Make a shallow copy of the interface font. */
+	font = t->fonts[THEME_FONT_INTERFACE];
+
+	/* Compute text size. */
+	if (!font_box(font, label->text, &tw, &th))
+		panic();
+
+	/* Align if needed. */
+	x = label->x;
+	y = label->y;
+
+	align(label->align, &x, &y, tw, th, bx, by, bw, bh);
+
+	/* 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))
+			panic();
+
+		texture_draw(&tex, x + 1, y + 1);
+		texture_finish(&tex);
+	}
+
+	/* Normal text. */
+	font->color = t->colors[THEME_COLOR_NORMAL];
+
+	if (!font_render(font, &tex, label->text))
+		panic();
+
+	texture_draw(&tex, x, y);
+	texture_finish(&tex);
+}
+
+void
 label_draw(const struct label *label)
 {
 	assert(label);
--- a/libui/ui/label.h	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/label.h	Thu Oct 15 14:01:24 2020 +0200
@@ -55,6 +55,17 @@
 };
 
 /**
+ * Default drawing function.
+ *
+ * \pre t != NULL
+ * \pre label != NULL
+ * \param t the theme
+ * \param label the label
+ */
+void
+label_draw_default(struct theme *t, const struct label *label);
+
+/**
  * Draw the label.
  *
  * \pre label != NULL
--- a/libui/ui/theme.c	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/theme.c	Thu Oct 15 14:01:24 2020 +0200
@@ -39,129 +39,9 @@
 
 #define THEME(t) (t ? t : &default_theme)
 
-#define CHECKBOX_W 16
-#define CHECKBOX_H 16
-#define CHECKBOX_RAD 6
-
-static void
-box(int x, int y, unsigned int w, unsigned int h)
-{
-	/* Some basic outlines. */
-	painter_set_color(0x4d3533ff);
-
-	painter_draw_line(x, y, x + w, y);
-	painter_draw_line(x, y + h, x + w, y + h);
-	painter_draw_line(x, y, x, y + h);
-	painter_draw_line(x + w, y, x + w, y + h);
-}
-
-static void
-draw_frame(struct theme *t, const struct frame *frame)
-{
-	(void)t;
-
-	if (frame->style == FRAME_STYLE_BOX)
-		painter_set_color(0x6e4c30ff);
-	else
-		painter_set_color(0xce9248ff);
-
-	painter_draw_rectangle(frame->x, frame->y, frame->w, frame->h);
-	box(frame->x, frame->y, frame->w, frame->h);
-}
-
-static void
-draw_label(struct theme *t, const struct label *label)
-{
-	struct font *font;
-	struct texture tex;
-	int x, y, bx, by;
-	unsigned int tw, th, bw, bh;
-
-	/* Compute real box size according to padding. */
-	bx = label->x + t->padding;
-	by = label->y + t->padding;
-	bw = label->w - (t->padding * 2);
-	bh = label->h - (t->padding * 2);
-
-	/* Make a shallow copy of the interface font. */
-	font = t->fonts[THEME_FONT_INTERFACE];
-
-	/* Compute text size. */
-	if (!font_box(font, label->text, &tw, &th))
-		panic();
-
-	/* Align if needed. */
-	x = label->x;
-	y = label->y;
-
-	align(label->align, &x, &y, tw, th, bx, by, bw, bh);
-
-	/* 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))
-			panic();
-
-		texture_draw(&tex, x + 1, y + 1);
-		texture_finish(&tex);
-	}
-
-	/* Normal text. */
-	font->color = t->colors[THEME_COLOR_NORMAL];
-
-	if (!font_render(font, &tex, label->text))
-		panic();
-
-	texture_draw(&tex, x, y);
-	texture_finish(&tex);
-}
-
-static void
-draw_button(struct theme *t, const struct button *button)
-{
-	(void)t;
-
-	struct label label = {
-		.text = button->text,
-		.x = button->x,
-		.y = button->y,
-		.w = button->w,
-		.h = button->h
-	};
-
-	painter_set_color(0xabcdefff);
-	painter_draw_rectangle(button->x, button->y, button->w, button->h);
-
-	label_draw(&label);
-
-	box(button->x, button->y, button->w, button->h);
-}
-
-static void
-draw_checkbox(struct theme *t, const struct checkbox *cb)
-{
-	box(cb->x, cb->y, CHECKBOX_W, CHECKBOX_H);
-
-	if (cb->checked)
-		painter_draw_rectangle(cb->x + 5, cb->y + 5, CHECKBOX_W - 9, CHECKBOX_H - 9);
-
-	if (cb->label) {
-		const unsigned int w = cb->w - (t->padding * 2) - CHECKBOX_W;
-		const int x = cb->x + (t->padding * 2) + CHECKBOX_W;
-
-		struct label label = {
-			.text = cb->label,
-			.align = ALIGN_LEFT,
-			.x = x,
-			.y = cb->y,
-			.w = w,
-			.h = cb->h
-		};
-
-		draw_label(t, &label);
-	}
-}
+/* Default font catalog. */
+#define FONT(bin, size, index)                                          \
+	{ bin, sizeof (bin), size, &default_theme.fonts[index], {0} }
 
 /* Default theme. */
 static struct theme default_theme = {
@@ -171,16 +51,12 @@
 		[THEME_COLOR_SHADOW]    = 0x000000ff
 	},
 	.padding = 10,
-	.draw_frame = draw_frame,
-	.draw_label = draw_label,
-	.draw_button = draw_button,
-	.draw_checkbox = draw_checkbox
+	.draw_frame = frame_draw_default,
+	.draw_label = label_draw_default,
+	.draw_button = button_draw_default,
+	.draw_checkbox = checkbox_draw_default
 };
 
-/* Default font catalog. */
-#define FONT(bin, size, index)                                          \
-	{ bin, sizeof (bin), size, &default_theme.fonts[index], {0} }
-
 static struct font_catalog {
 	const unsigned char *data;
 	const size_t datasz;
@@ -189,7 +65,7 @@
 	struct font font;
 } default_fonts[] = {
 	FONT(fonts_f25_bank_printer, 10, THEME_FONT_DEBUG),
-	FONT(fonts_comic_neue, 20, THEME_FONT_INTERFACE)
+	FONT(fonts_comic_neue, 18, THEME_FONT_INTERFACE)
 };
 
 bool
--- a/libui/ui/theme.h	Thu Oct 15 13:13:38 2020 +0200
+++ b/libui/ui/theme.h	Thu Oct 15 14:01:24 2020 +0200
@@ -138,15 +138,6 @@
 theme_shallow(struct theme *dst, const struct theme *src);
 
 /**
- * Get the desired padding between GUI elements.
- *
- * \param t the theme to use (may be NULL)
- * \return the padding in pixels
- */
-unsigned int
-theme_padding(const struct theme *t);
-
-/**
  * Draw a frame.
  *
  * \pre frame != NULL