changeset 619:b8fd5c112538

ui: simplify checkbox
author David Demelier <markand@malikania.fr>
date Mon, 21 Aug 2023 21:42:17 +0200
parents 509b395171f2
children 91ef0df9f501
files examples/example-ui/example-ui.c libmlk-ui/mlk/ui/checkbox.c libmlk-ui/mlk/ui/checkbox.h libmlk-ui/mlk/ui/ui.c
diffstat 4 files changed, 102 insertions(+), 155 deletions(-) [+]
line wrap: on
line diff
--- a/examples/example-ui/example-ui.c	Mon Aug 21 21:24:30 2023 +0200
+++ b/examples/example-ui/example-ui.c	Mon Aug 21 21:42:17 2023 +0200
@@ -121,9 +121,7 @@
 	.autosave = {
 		.cb = {
 			.w = ELEMENT_HEIGHT,
-			.h = ELEMENT_HEIGHT,
-			.delegate = &mlk_checkbox_delegate,
-			.style = &mlk_style
+			.h = ELEMENT_HEIGHT
 		},
 		.label = {
 			.text = "Auto save game"
--- a/libmlk-ui/mlk/ui/checkbox.c	Mon Aug 21 21:24:30 2023 +0200
+++ b/libmlk-ui/mlk/ui/checkbox.c	Mon Aug 21 21:42:17 2023 +0200
@@ -18,12 +18,14 @@
 
 #include <assert.h>
 
+#include <mlk/core/color.h>
 #include <mlk/core/event.h>
 #include <mlk/core/maths.h>
 #include <mlk/core/painter.h>
 
 #include "checkbox.h"
 #include "style.h"
+#include "ui_p.h"
 
 static inline int
 is_boxed(const struct mlk_checkbox *cb, const struct mlk_event_click *click)
@@ -33,12 +35,51 @@
 	return mlk_maths_is_boxed(click->x, click->y, cb->x, cb->y, cb->w, cb->h);
 }
 
-static int
-handle(struct mlk_checkbox_delegate *self,
-       struct mlk_checkbox *cb,
-       const union mlk_event *ev)
+static void
+draw(struct mlk_checkbox_style *self, struct mlk_checkbox *cb)
 {
-	(void)self;
+	if (!self->border_size) {
+		mlk_painter_set_color(self->background);
+		mlk_painter_draw_rectangle(cb->x, cb->y, cb->w, cb->h);
+	} else {
+		mlk_painter_set_color(self->border);
+		mlk_painter_draw_rectangle(cb->x, cb->y, cb->w, cb->h);
+		mlk_painter_set_color(self->background);
+		mlk_painter_draw_rectangle(
+			cb->x + self->border_size,
+			cb->y + self->border_size,
+			cb->w - (self->border_size * 2),
+			cb->h - (self->border_size * 2)
+		);
+	}
+
+	if (cb->checked) {
+		mlk_painter_set_color(mlk_color_darken(self->background, 0.9));
+		mlk_painter_draw_rectangle(cb->x + 5, cb->y + 5, cb->w - 10, cb->h - 10);
+	}
+}
+
+struct mlk_checkbox_style mlk_checkbox_style_dark = {
+	.background = 0x222323ff,
+	.border = 0x141414ff,
+	.border_size = 2,
+	.draw = draw
+};
+
+struct mlk_checkbox_style mlk_checkbox_style_light = {
+	.background = 0xf5f7faff,
+	.border = 0xcdd2daff,
+	.border_size = 2,
+	.draw = draw
+};
+
+struct mlk_checkbox_style *mlk_checkbox_style = &mlk_checkbox_style_light;
+
+int
+mlk_checkbox_handle(struct mlk_checkbox *cb, const union mlk_event *ev)
+{
+	assert(cb);
+	assert(ev);
 
 	switch (ev->type) {
 	case MLK_EVENT_CLICKDOWN:
@@ -52,90 +93,18 @@
 	return 0;
 }
 
-static void
-draw(struct mlk_checkbox_delegate *self, const struct mlk_checkbox *cb)
-{
-	(void)self;
-
-	const struct mlk_style_attr *attr = &cb->style->normal;
-
-	if (!attr->geo.border) {
-		mlk_painter_set_color(attr->color.bg);
-		mlk_painter_draw_rectangle(cb->x, cb->y, cb->w, cb->h);
-	} else {
-		mlk_painter_set_color(attr->color.border);
-		mlk_painter_draw_rectangle(cb->x, cb->y, cb->w, cb->h);
-		mlk_painter_set_color(attr->color.bg);
-		mlk_painter_draw_rectangle(
-			cb->x + attr->geo.border,
-			cb->y + attr->geo.border,
-			cb->w - (attr->geo.border * 2),
-			cb->h - (attr->geo.border * 2)
-		);
-	}
-
-	if (cb->checked) {
-		mlk_painter_set_color(attr->color.fg);
-		mlk_painter_draw_rectangle(cb->x + 5, cb->y + 5, cb->w - 10, cb->h - 10);
-	}
-}
-
-struct mlk_checkbox_delegate mlk_checkbox_delegate = {
-	.handle = handle,
-	.draw = draw
-};
-
-void
-mlk_checkbox_init(struct mlk_checkbox *cb,
-                  struct mlk_checkbox_delegate *dt,
-                  struct mlk_style *st)
-{
-	assert(cb);
-
-	cb->x = 0;
-	cb->y = 0;
-	cb->w = 0;
-	cb->h = 0;
-	cb->checked = 0;
-	cb->delegate = dt ? dt : &mlk_checkbox_delegate;
-	cb->style = st ? st : &mlk_style;
-}
-
-int
-mlk_checkbox_handle(struct mlk_checkbox *cb, const union mlk_event *ev)
-{
-	assert(cb);
-	assert(ev);
-
-	if (cb->delegate->handle)
-		return cb->delegate->handle(cb->delegate, cb, ev);
-
-	return 0;
-}
-
 void
 mlk_checkbox_update(struct mlk_checkbox *cb, unsigned int ticks)
 {
 	assert(cb);
 
-	if (cb->delegate->update)
-		cb->delegate->update(cb->delegate, cb, ticks);
+	MLK__STYLE_CALL(cb->style, mlk_checkbox_style, update, cb, ticks);
 }
 
 void
-mlk_checkbox_draw(const struct mlk_checkbox *cb)
+mlk_checkbox_draw(struct mlk_checkbox *cb)
 {
 	assert(cb);
 
-	if (cb->delegate->draw)
-		cb->delegate->draw(cb->delegate, cb);
+	MLK__STYLE_CALL(cb->style, mlk_checkbox_style, draw, cb);
 }
-
-void
-mlk_checkbox_finish(struct mlk_checkbox *cb)
-{
-	assert(cb);
-
-	if (cb->delegate->finish)
-		cb->delegate->finish(cb->delegate, cb);
-}
--- a/libmlk-ui/mlk/ui/checkbox.h	Mon Aug 21 21:24:30 2023 +0200
+++ b/libmlk-ui/mlk/ui/checkbox.h	Mon Aug 21 21:42:17 2023 +0200
@@ -25,8 +25,7 @@
  */
 
 struct mlk_checkbox;
-struct mlk_checkbox_delegate;
-struct mlk_style;
+struct mlk_checkbox_style;
 
 union mlk_event;
 
@@ -71,25 +70,39 @@
 	int checked;
 
 	/**
-	 * (read-write, borrowed)
+	 * (read-write, borrowed, optional)
 	 *
-	 * Checkbox delegate.
+	 * Style to use for drawing this checkbox.
 	 */
-	struct mlk_checkbox_delegate *delegate;
-
-	/**
-	 * (read-write, borrowed)
-	 *
-	 * Checkbox style.
-	 */
-	struct mlk_style *style;
+	struct mlk_checkbox_style *style;
 };
 
 /**
- * \struct mlk_checkbox_delegate
- * \brief Checkbox delegate.
+ * \struct mlk_checkbox_style
+ * \brief Checkbox style.
  */
-struct mlk_checkbox_delegate {
+struct mlk_checkbox_style {
+	/**
+	 * (read-write)
+	 *
+	 * Background color.
+	 */
+	unsigned long background;
+
+	/**
+	 * (read-write)
+	 *
+	 * Border color.
+	 */
+	unsigned long border;
+
+	/**
+	 * (read-write)
+	 *
+	 * Border size.
+	 */
+	unsigned int border_size;
+
 	/*
 	 * (read-write, borrowed, optional)
 	 *
@@ -100,27 +113,13 @@
 	/**
 	 * (read-write, optional)
 	 *
-	 * Handle an event.
-	 *
-	 * \param self this delegate
-	 * \param cb the checkbox
-	 * \param ev the event
-	 * \return the current checkbox status (1 or 0)
-	 */
-	int (*handle)(struct mlk_checkbox_delegate *self,
-	              struct mlk_checkbox *cb,
-	              const union mlk_event *ev);
-
-	/**
-	 * (read-write, optional)
-	 *
 	 * Update the checkbox.
 	 *
-	 * \param self this delegate
+	 * \param self this style
 	 * \param cb the checkbox to update
 	 * \param ticks number of ticks since last frame
 	 */
-	void (*update)(struct mlk_checkbox_delegate *self,
+	void (*update)(struct mlk_checkbox_style *self,
 	               struct mlk_checkbox *cb,
 	               unsigned int ticks);
 
@@ -129,71 +128,49 @@
 	 *
 	 * Draw this checkbox.
 	 *
-	 * \param self this delegate
+	 * \param self this style
 	 * \param cb the checkbox to update
 	 */
-	void (*draw)(struct mlk_checkbox_delegate *self,
-	             const struct mlk_checkbox *cb);
-
-	/**
-	 * (read-write, optional)
-	 *
-	 * Cleanup this delegate associated with the checkbox.
-	 *
-	 * \param self this delegate
-	 * \param cb the underlying checkbox
-	 */
-	void (*finish)(struct mlk_checkbox_delegate *self,
-	               struct mlk_checkbox *cb);
+	void (*draw)(struct mlk_checkbox_style *self,
+	             struct mlk_checkbox *cb);
 };
 
 /**
- * \brief Default stateless delegate for checkbox.
+ * \brief Dark default style for check.
+ */
+extern struct mlk_checkbox_style mlk_checkbox_style_dark;
+
+/**
+ * \brief Light default style for checkbox.
  */
-extern struct mlk_checkbox_delegate mlk_checkbox_delegate;
+extern struct mlk_checkbox_style mlk_checkbox_style_light;
+
+/**
+ * \brief Default style for all checkboxes.
+ */
+extern struct mlk_checkbox_style *mlk_checkbox_style;
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 /**
- * Initialize the checkbox with default values.
- *
- * This is not required if you use designated initializers.
- *
- * \pre cb != NULL
- * \param cb the checkbox to default initialize
- * \param st style to use (or NULL to use a default)
- * \param dt delegate to use (or NULL to use a default)
- */
-void
-mlk_checkbox_init(struct mlk_checkbox *cb,
-                  struct mlk_checkbox_delegate *dt,
-                  struct mlk_style *st);
-
-/**
- * Invoke ::mlk_checkbox_delegate::update.
+ * Invoke ::mlk_checkbox_style::update.
  */
 int
 mlk_checkbox_handle(struct mlk_checkbox *cb, const union mlk_event *ev);
 
 /**
- * Invoke ::mlk_checkbox_delegate::update.
+ * Invoke ::mlk_checkbox_style::update.
  */
 void
 mlk_checkbox_update(struct mlk_checkbox *cb, unsigned int ticks);
 
 /**
- * Invoke ::mlk_checkbox_delegate::draw.
+ * Invoke ::mlk_checkbox_style::draw.
  */
 void
-mlk_checkbox_draw(const struct mlk_checkbox *cb);
-
-/**
- * Invoke ::mlk_checkbox_delegate::finish.
- */
-void
-mlk_checkbox_finish(struct mlk_checkbox *cb);
+mlk_checkbox_draw(struct mlk_checkbox *cb);
 
 #if defined(__cplusplus)
 }
--- a/libmlk-ui/mlk/ui/ui.c	Mon Aug 21 21:24:30 2023 +0200
+++ b/libmlk-ui/mlk/ui/ui.c	Mon Aug 21 21:42:17 2023 +0200
@@ -38,6 +38,7 @@
 
 #include "align.h"
 #include "button.h"
+#include "checkbox.h"
 #include "frame.h"
 #include "label.h"
 #include "ui.h"
@@ -98,10 +99,12 @@
 {
 	if (theme == MLK_WINDOW_THEME_DARK) {
 		mlk_button_style = &mlk_button_style_dark;
+		mlk_checkbox_style = &mlk_checkbox_style_dark;
 		mlk_frame_style = &mlk_frame_style_dark;
 		mlk_label_style = &mlk_label_style_dark;
 	} else {
 		mlk_button_style = &mlk_button_style_light;
+		mlk_checkbox_style = &mlk_checkbox_style_light;
 		mlk_frame_style = &mlk_frame_style_light;
 		mlk_label_style = &mlk_label_style_light;
 	}