diff libcore/core/theme.c @ 145:7f1af54bb35a

core: rework label alignment, closes #2494 @1h Now labels can be positioned on a bounding box with much more convenient possibilities.
author David Demelier <markand@malikania.fr>
date Wed, 14 Oct 2020 18:11:38 +0200
parents eadfed7674ac
children 7d7ea7a9cf50
line wrap: on
line diff
--- a/libcore/core/theme.c	Wed Oct 14 16:40:34 2020 +0200
+++ b/libcore/core/theme.c	Wed Oct 14 18:11:38 2020 +0200
@@ -69,40 +69,81 @@
 static void
 draw_label(struct theme *t, const struct label *label)
 {
+	struct font *font;
 	struct texture tex;
-	int x = label->x, y = label->y;
-	int *px = &x, *py = &y;
+	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();
 
-	if (label->flags & LABEL_NO_HCENTER)
-		px = NULL;
-	if (label->flags & LABEL_NO_VCENTER)
-		py = NULL;
+	/* Compute position according to alignment and box. */
+	switch (label->align) {
+	case LABEL_ALIGN_CENTER:
+		maths_centerize(&x, &y, tw, th, bx, by, bw, bh);
+		break;
+	case LABEL_ALIGN_TOP_LEFT:
+		x = bx;
+		y = by;
+		break;
+	case LABEL_ALIGN_TOP:
+		maths_centerize(&x, NULL, tw, th, bx, by, bw, bh);
+		y = by;
+		break;
+	case LABEL_ALIGN_TOP_RIGHT:
+		x = bx + bw - tw;
+		y = by;
+		break;
+	case LABEL_ALIGN_RIGHT:
+		maths_centerize(NULL, &y, tw, th, bx, by, bw, bh);
+		x = bx + bw - tw;
+		break;
+	case LABEL_ALIGN_BOTTOM_RIGHT:
+		x = bx + bw - tw;
+		y = by + bh - th;
+		break;
+	case LABEL_ALIGN_BOTTOM:
+		maths_centerize(&x, NULL, tw, th, bx, by, bw, bh);
+		y = by + bh - th;
+		break;
+	case LABEL_ALIGN_BOTTOM_LEFT:
+		x = bx;
+		y = by + bh - th;
+		break;
+	case LABEL_ALIGN_LEFT:
+		maths_centerize(NULL, &y, tw, th, bx, by, bw, bh);
+		x = bx;
+	default:
+		break;
+	}
 
 	/* Shadow text, only if enabled. */
-	if (!(label->flags & LABEL_NO_SHADOW)) {
-		t->fonts[THEME_FONT_INTERFACE]->color = t->colors[THEME_COLOR_SHADOW];
+	if (label->flags & LABEL_FLAGS_SHADOW) {
+		font->color = t->colors[THEME_COLOR_SHADOW];
 
-		if (!font_render(t->fonts[THEME_FONT_INTERFACE], &tex, label->text))
+		if (!font_render(font, &tex, label->text))
 			panic();
 
-		maths_centerize(px, py, tex.w, tex.h,
-		    label->x, label->y, label->w, label->h);
-
 		texture_draw(&tex, x + 1, y + 1);
 		texture_finish(&tex);
 	}
 
 	/* Normal text. */
-	t->fonts[THEME_FONT_INTERFACE]->color = label->color
-		? label->color
-		: t->colors[THEME_COLOR_NORMAL];
+	font->color = t->colors[THEME_COLOR_NORMAL];
 
-	if (!font_render(t->fonts[THEME_FONT_INTERFACE], &tex, label->text))
+	if (!font_render(font, &tex, label->text))
 		panic();
 
-	maths_centerize(px, py, tex.w, tex.h,
-	    label->x, label->y, label->w, label->h);
-
 	texture_draw(&tex, x, y);
 	texture_finish(&tex);
 }
@@ -142,7 +183,7 @@
 
 		struct label label = {
 			.text = cb->label,
-			.flags = LABEL_NO_HCENTER,
+			.align = LABEL_ALIGN_LEFT,
 			.x = x,
 			.y = cb->y,
 			.w = w,