Mercurial > molko
changeset 150:9733d379be89
ui: add a standalone align() function
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 15 Oct 2020 13:13:38 +0200 |
parents | a43e79d489ea |
children | b19d076856d2 |
files | examples/example-drawable.c examples/example-label.c examples/example-sound.c libcore/core/maths.c libcore/core/maths.h librpg/rpg/inventory_dialog.c librpg/rpg/message.c libui/CMakeLists.txt libui/ui/align.c libui/ui/align.h libui/ui/label.c libui/ui/label.h libui/ui/theme.c |
diffstat | 13 files changed, 206 insertions(+), 129 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/example-drawable.c Thu Oct 15 10:45:40 2020 +0200 +++ b/examples/example-drawable.c Thu Oct 15 13:13:38 2020 +0200 @@ -46,7 +46,7 @@ .y = 10, .w = W, .h = H, - .align = LABEL_ALIGN_TOP_LEFT, + .align = ALIGN_TOP_LEFT, .flags = LABEL_FLAGS_SHADOW };
--- a/examples/example-label.c Thu Oct 15 10:45:40 2020 +0200 +++ b/examples/example-label.c Thu Oct 15 13:13:38 2020 +0200 @@ -58,7 +58,7 @@ .w = W, .h = H, .text = "Top left", - .align = LABEL_ALIGN_TOP_LEFT + .align = ALIGN_TOP_LEFT }, { .x = 0, @@ -66,7 +66,7 @@ .w = W, .h = H, .text = "Top", - .align = LABEL_ALIGN_TOP + .align = ALIGN_TOP }, { .x = 0, @@ -74,7 +74,7 @@ .w = W, .h = H, .text = "Top right", - .align = LABEL_ALIGN_TOP_RIGHT + .align = ALIGN_TOP_RIGHT }, { .x = 0, @@ -82,7 +82,7 @@ .w = W, .h = H, .text = "Right", - .align = LABEL_ALIGN_RIGHT + .align = ALIGN_RIGHT }, { .x = 0, @@ -90,7 +90,7 @@ .w = W, .h = H, .text = "Bottom right", - .align = LABEL_ALIGN_BOTTOM_RIGHT + .align = ALIGN_BOTTOM_RIGHT }, { .x = 0, @@ -98,7 +98,7 @@ .w = W, .h = H, .text = "Bottom", - .align = LABEL_ALIGN_BOTTOM + .align = ALIGN_BOTTOM }, { .x = 0, @@ -106,7 +106,7 @@ .w = W, .h = H, .text = "Bottom left", - .align = LABEL_ALIGN_BOTTOM_LEFT + .align = ALIGN_BOTTOM_LEFT }, { .x = 0, @@ -114,7 +114,7 @@ .w = W, .h = H, .text = "Left", - .align = LABEL_ALIGN_LEFT + .align = ALIGN_LEFT }, { .x = 0, @@ -123,7 +123,7 @@ .h = H, .text = "The world is Malikania.", .flags = LABEL_FLAGS_SHADOW, - .align = LABEL_ALIGN_CENTER + .align = ALIGN_CENTER }, }; struct label mlabel = {
--- a/examples/example-sound.c Thu Oct 15 10:45:40 2020 +0200 +++ b/examples/example-sound.c Thu Oct 15 13:13:38 2020 +0200 @@ -41,7 +41,7 @@ .y = 10, .w = W, .h = H, - .align = LABEL_ALIGN_TOP_LEFT, + .align = ALIGN_TOP_LEFT, .flags = LABEL_FLAGS_SHADOW };
--- a/libcore/core/maths.c Thu Oct 15 10:45:40 2020 +0200 +++ b/libcore/core/maths.c Thu Oct 15 13:13:38 2020 +0200 @@ -26,19 +26,3 @@ px <= x + (int)w && py <= y + (int)h; } - -void -maths_centerize(int *x, - int *y, - unsigned int w, - unsigned int h, - int px, - int py, - unsigned int pw, - unsigned int ph) -{ - if (x) - *x = px + (pw / 2) - (w / 2); - if (y) - *y = py + (ph / 2) - (h / 2); -}
--- a/libcore/core/maths.h Thu Oct 15 10:45:40 2020 +0200 +++ b/libcore/core/maths.h Thu Oct 15 13:13:38 2020 +0200 @@ -40,29 +40,4 @@ bool maths_is_boxed(int x, int y, unsigned int w, unsigned int h, int px, int py); -/** - * Update x, y to be centered into a parent region. - * - * You can select to ignore horizontal/vertical centering by passing NULL to x - * or y respectively. - * - * \param x the pointer to x coordinate to modify - * \param y the pointer yo y coordinate to modify - * \param w the object width - * \param h the object height - * \param px the parent region start - * \param py the parent region start - * \param pw the parent region width - * \param ph the parent region height - */ -void -maths_centerize(int *x, - int *y, - unsigned int w, - unsigned int h, - int px, - int py, - unsigned int pw, - unsigned int ph); - #endif /* !MOLKO_MATHS_H */
--- a/librpg/rpg/inventory_dialog.c Thu Oct 15 10:45:40 2020 +0200 +++ b/librpg/rpg/inventory_dialog.c Thu Oct 15 13:13:38 2020 +0200 @@ -195,7 +195,7 @@ dlg->fname.x = dlg->lname.x = dlg->x; dlg->fname.y = dlg->lname.y = dlg->y + GRID_HEIGHT; dlg->lname.x += ITEM_PADDING; - dlg->lname.align = LABEL_ALIGN_LEFT; + dlg->lname.align = ALIGN_LEFT; /* Description label. */ dlg->fdesc.w = dlg->ldesc.w = LABEL_WIDTH; @@ -203,7 +203,7 @@ dlg->fdesc.x = dlg->ldesc.x = dlg->y; dlg->fdesc.y = dlg->ldesc.y = dlg->y + GRID_HEIGHT + (LABEL_HEIGHT / 2); dlg->ldesc.x += ITEM_PADDING; - dlg->ldesc.align = LABEL_ALIGN_LEFT; + dlg->ldesc.align = ALIGN_LEFT; /* Button sort. */ dlg->bsort.x = dlg->x;
--- a/librpg/rpg/message.c Thu Oct 15 10:45:40 2020 +0200 +++ b/librpg/rpg/message.c Thu Oct 15 13:13:38 2020 +0200 @@ -30,6 +30,7 @@ #include <core/trace.h> #include <core/util.h> +#include <ui/align.h> #include <ui/frame.h> #include <ui/label.h> #include <ui/theme.h> @@ -99,7 +100,7 @@ .h = msg->h, .theme = &theme, .text = msg->text[i], - .align = LABEL_ALIGN_TOP_LEFT, + .align = ALIGN_TOP_LEFT, .flags = LABEL_FLAGS_SHADOW }; @@ -239,7 +240,7 @@ h = msg->h * msg->scale; /* Centerize within its drawing area. */ - maths_centerize(&x, &y, w, h, msg->x, msg->y, msg->w, msg->h); + align(ALIGN_CENTER, &x, &y, w, h, msg->x, msg->y, msg->w, msg->h); /* Draw and clear. */ texture_scale(&tex, 0, 0, msg->w, msg->h, x, y, w, h, 0);
--- a/libui/CMakeLists.txt Thu Oct 15 10:45:40 2020 +0200 +++ b/libui/CMakeLists.txt Thu Oct 15 13:13:38 2020 +0200 @@ -20,6 +20,8 @@ set( SOURCES + ${libui_SOURCE_DIR}/ui/align.c + ${libui_SOURCE_DIR}/ui/align.h ${libui_SOURCE_DIR}/ui/button.c ${libui_SOURCE_DIR}/ui/button.h ${libui_SOURCE_DIR}/ui/checkbox.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libui/ui/align.c Thu Oct 15 13:13:38 2020 +0200 @@ -0,0 +1,75 @@ +/* + * align.h -- user interface alignment + * + * 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 "align.h" + +#define SET(p, v) if (p) *p = v +#define CENTER(p, c, rs, es) if (p) (*p) = c + (rs / 2) - (es / 2) + +void +align(enum align align, + int *x, + int *y, + unsigned int w, + unsigned int h, + int px, + int py, + unsigned int pw, + unsigned int ph) +{ + switch (align) { + case ALIGN_CENTER: + CENTER(x, px, pw, w); + CENTER(y, py, ph, h); + break; + case ALIGN_TOP_LEFT: + SET(x, px); + SET(y, py); + break; + case ALIGN_TOP: + CENTER(x, px, pw, w); + SET(y, py); + break; + case ALIGN_TOP_RIGHT: + SET(x, px + pw - w); + SET(y, py); + break; + case ALIGN_RIGHT: + SET(x, px + pw - w); + CENTER(y, py, ph, h); + break; + case ALIGN_BOTTOM_RIGHT: + SET(x, px + pw - w); + SET(y, py + ph - h); + break; + case ALIGN_BOTTOM: + CENTER(x, px, pw, w); + SET(y, py + ph - h); + break; + case ALIGN_BOTTOM_LEFT: + SET(x, px); + SET(y, py + ph - h); + break; + case ALIGN_LEFT: + CENTER(y, py, ph, h); + SET(x, px); + break; + default: + break; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libui/ui/align.h Thu Oct 15 13:13:38 2020 +0200 @@ -0,0 +1,102 @@ +/* + * align.h -- user interface alignment + * + * 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. + */ + +#ifndef MOLKO_ALIGN_H +#define MOLKO_ALIGN_H + +/** + * \file align.h + * \brief User interface alignment. + */ + +/** + * \brief Label alignment in bounding box. + * + * The alignment is described as following: + * + * ``` + * +---------------------+ + * | 2 3 4 | + * | | + * | 9 1 5 | + * | | + * | 8 7 6 | + * +---------------------+ + * ``` + * + * The default value of 0 (LABEL_ALIGN_NONE) means the alignment isn't used. + */ +enum align { + ALIGN_NONE, /*!< No alignment. */ + ALIGN_CENTER, /*!< Align to the center. */ + ALIGN_TOP_LEFT, /*!< Top left. */ + ALIGN_TOP, /*!< Top center (aligned horizontally). */ + ALIGN_TOP_RIGHT, /*!< Top right. */ + ALIGN_RIGHT, /*!< Right (aligned vertically). */ + ALIGN_BOTTOM_RIGHT, /*!< Bottom right. */ + ALIGN_BOTTOM, /*!< Bottom (aligned horizontally). */ + ALIGN_BOTTOM_LEFT, /*!< Bottom left. */ + ALIGN_LEFT /*!< Left (aligned vertically). */ +}; + +/** + * Align the given object relative to its parent region. + * + * The arguments are described as following: + * + * ``` + * Example of ALIGN_LEFT (centered vertically but placed on the left.) + * + * px, py + * +----------pw----------+ + * | | + * | x, y | + * | +---w---+ | + * ph h | | + * | +-------+ | + * | | + * | | + * +----------------------+ + * ``` + * + * As a convenience, x and y are left untouched if align is ALIGN_NONE which + * means you can set the coordinates to default values and still call the align + * function without need to check. + * + * \param align the desired alignment + * \param x the pointer to x coordinate to modify (may be NULL) + * \param y the pointer yo y coordinate to modify (may be NULL) + * \param w the object width + * \param h the object height + * \param px the parent region start + * \param py the parent region start + * \param pw the parent region width + * \param ph the parent region height + */ +void +align(enum align align, + int *x, + int *y, + unsigned int w, + unsigned int h, + int px, + int py, + unsigned int pw, + unsigned int ph); + +#endif /* !MOLKO_ALIGN_H */
--- a/libui/ui/label.c Thu Oct 15 10:45:40 2020 +0200 +++ b/libui/ui/label.c Thu Oct 15 13:13:38 2020 +0200 @@ -29,7 +29,7 @@ assert(label); assert(label->text); - if (label->align != LABEL_ALIGN_NONE && (label->w == 0 || label->h == 0)) + if (label->align != ALIGN_NONE && (label->w == 0 || label->h == 0)) trace("label %p has alignment but null dimensions", label); theme_draw_label(label->theme, label);
--- a/libui/ui/label.h Thu Oct 15 10:45:40 2020 +0200 +++ b/libui/ui/label.h Thu Oct 15 13:13:38 2020 +0200 @@ -24,6 +24,8 @@ * \brief GUI label. */ +#include "align.h" + struct theme; /** @@ -35,34 +37,6 @@ }; /** - * \brief Label alignment in bounding box. - * - * The alignment is described as following: - * - * ``` - * +---------------------+ - * | 1 2 3 | - * | | - * | 8 0 4 | - * | | - * | 7 6 5 | - * +---------------------+ - * ``` - */ -enum label_align { - LABEL_ALIGN_NONE, /*!< No alignment. */ - LABEL_ALIGN_CENTER, /*!< Align to the center. */ - LABEL_ALIGN_TOP_LEFT, /*!< Top left. */ - LABEL_ALIGN_TOP, /*!< Top center (aligned horizontally). */ - LABEL_ALIGN_TOP_RIGHT, /*!< Top right. */ - LABEL_ALIGN_RIGHT, /*!< Right (aligned vertically). */ - LABEL_ALIGN_BOTTOM_RIGHT, /*!< Bottom right. */ - LABEL_ALIGN_BOTTOM, /*!< Bottom (aligned horizontally). */ - LABEL_ALIGN_BOTTOM_LEFT, /*!< Bottom left. */ - LABEL_ALIGN_LEFT /*!< Left (aligned vertically). */ -}; - -/** * \brief GUI label. * * A label can be conveniently positioned using a bounding box and an alignment @@ -76,7 +50,7 @@ unsigned int h; /*!< (+?) Height. */ const char *text; /*!< (+&) Text to show. */ enum label_flags flags; /*!< (+) Optional flags. */ - enum label_align align; /*!< (+) How to positionate label. */ + enum align align; /*!< (+) How to positionate label. */ struct theme *theme; /*!< (+&?) Theme to use. */ };
--- a/libui/ui/theme.c Thu Oct 15 10:45:40 2020 +0200 +++ b/libui/ui/theme.c Thu Oct 15 13:13:38 2020 +0200 @@ -30,6 +30,7 @@ #include <core/assets/fonts/f25-bank-printer.h> #include <core/assets/fonts/comic-neue.h> +#include "align.h" #include "button.h" #include "checkbox.h" #include "frame.h" @@ -89,48 +90,11 @@ if (!font_box(font, label->text, &tw, &th)) panic(); - /* 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; - break; - default: - x = label->x; - y = label->y; - break; - } + /* 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) { @@ -188,7 +152,7 @@ struct label label = { .text = cb->label, - .align = LABEL_ALIGN_LEFT, + .align = ALIGN_LEFT, .x = x, .y = cb->y, .w = w,