# HG changeset patch # User David Demelier # Date 1602780327 -7200 # Node ID aa6e70e330a1ded4fbe73e2e2ca94d082b53c344 # Parent 1008a796a9e75d2c1681298709aa98d5fea87f60 ui: make label less smart It should not contain alignment because it should be handled by the user tself. diff -r 1008a796a9e7 -r aa6e70e330a1 examples/example-drawable.c --- a/examples/example-drawable.c Thu Oct 15 18:09:45 2020 +0200 +++ b/examples/example-drawable.c Thu Oct 15 18:45:27 2020 +0200 @@ -41,30 +41,12 @@ #define H 720 static struct label help = { - .text = "Keys: to reset. Click anywhere to spawn a drawable.", .x = 10, .y = 10, - .w = W, - .h = H, - .align = ALIGN_TOP_LEFT, + .text = "Keys: to reset. Click anywhere to spawn a drawable.", .flags = LABEL_FLAGS_SHADOW }; -#if 0 -// TODO: for the moment only animations are supported. -static unsigned int which_selection; -static char which_text[128]; -static struct label which = { - .text = buf, - .x = 10, - .y = 40, - .w = W, - .h = 32, - .flags = LABEL_NO_HCENTER, - .color = 0x4f8fbaff -}; -#endif - static struct drawable_stack stack; /* diff -r 1008a796a9e7 -r aa6e70e330a1 examples/example-label.c --- a/examples/example-label.c Thu Oct 15 18:09:45 2020 +0200 +++ b/examples/example-label.c Thu Oct 15 18:45:27 2020 +0200 @@ -24,12 +24,74 @@ #include #include +#include #include #include #define W (1280) #define H (720) +struct { + enum align align; + struct label label; +} table[] = { + { + .align = ALIGN_TOP_LEFT, + .label = { + .text = "Top left" + } + }, + { + .align = ALIGN_TOP, + .label = { + .text = "Top", + } + }, + { + .align = ALIGN_TOP_RIGHT, + .label = { + .text = "Top right", + } + }, + { + .align = ALIGN_RIGHT, + .label = { + .text = "Right", + } + }, + { + .align = ALIGN_BOTTOM_RIGHT, + .label = { + .text = "Bottom right", + } + }, + { + .align = ALIGN_BOTTOM, + .label = { + .text = "Bottom", + } + }, + { + .align = ALIGN_BOTTOM_LEFT, + .label = { + .text = "Bottom left", + } + }, + { + .align = ALIGN_LEFT, + .label = { + .text = "Left", + } + }, + { + .align = ALIGN_CENTER, + .label = { + .text = "The world is Malikania.", + .flags = LABEL_FLAGS_SHADOW + } + } +}; + static void init(void) { @@ -37,6 +99,13 @@ !window_init("Example - Label", W, H) || !theme_init()) panic(); + + for (size_t i = 0; i < NELEM(table); ++i) { + struct label *l = &table[i].label; + + label_query(l); + align(table[i].align, &l->x, &l->y, l->w, l->h, 0, 0, W, H); + } } static void @@ -51,81 +120,6 @@ run(void) { struct clock clock = {0}; - struct label labels[] = { - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "Top left", - .align = ALIGN_TOP_LEFT - }, - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "Top", - .align = ALIGN_TOP - }, - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "Top right", - .align = ALIGN_TOP_RIGHT - }, - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "Right", - .align = ALIGN_RIGHT - }, - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "Bottom right", - .align = ALIGN_BOTTOM_RIGHT - }, - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "Bottom", - .align = ALIGN_BOTTOM - }, - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "Bottom left", - .align = ALIGN_BOTTOM_LEFT - }, - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "Left", - .align = ALIGN_LEFT - }, - { - .x = 0, - .y = 0, - .w = W, - .h = H, - .text = "The world is Malikania.", - .flags = LABEL_FLAGS_SHADOW, - .align = ALIGN_CENTER - }, - }; struct label mlabel = { .text = "This one follows your mouse and is not aligned." }; @@ -154,8 +148,8 @@ painter_set_color(0x4f8fbaff); painter_clear(); - for (size_t i = 0; i < NELEM(labels); ++i) - label_draw(&labels[i]); + for (size_t i = 0; i < NELEM(table); ++i) + label_draw(&table[i].label); label_draw(&mlabel); painter_present(); diff -r 1008a796a9e7 -r aa6e70e330a1 examples/example-sound.c --- a/examples/example-sound.c Thu Oct 15 18:09:45 2020 +0200 +++ b/examples/example-sound.c Thu Oct 15 18:45:27 2020 +0200 @@ -39,9 +39,6 @@ .text = "Keys: start,

pause, resume, stop, loop", .x = 10, .y = 10, - .w = W, - .h = H, - .align = ALIGN_TOP_LEFT, .flags = LABEL_FLAGS_SHADOW }; diff -r 1008a796a9e7 -r aa6e70e330a1 examples/example-ui.c --- a/examples/example-ui.c Thu Oct 15 18:09:45 2020 +0200 +++ b/examples/example-ui.c Thu Oct 15 18:45:27 2020 +0200 @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -101,10 +102,7 @@ .text = "Preferences", .x = FRAME_ORIGIN_X, .y = FRAME_ORIGIN_Y, - .w = FRAME_WIDTH, - .h = HEADER_HEIGHT, .flags = LABEL_FLAGS_SHADOW, - .align = ALIGN_LEFT } }, .autosave = { @@ -114,9 +112,7 @@ }, .label = { .text = "Auto save game", - .align = ALIGN_LEFT, .flags = LABEL_FLAGS_SHADOW, - .h = ELEMENT_HEIGHT } }, .quit = { @@ -137,35 +133,57 @@ } static void -resize(void) +resize_header(void) { - const unsigned int padding = theme_default()->padding; + struct frame *h = &ui.panel.frame; + struct label *l = &ui.header.label; /* Header. */ - ui.header.label.x = ui.panel.frame.x; - ui.header.label.y = ui.panel.frame.y; + label_query(l); + align(ALIGN_LEFT, &l->x, &l->y, l->w, l->h, h->x, h->y, h->w, HEADER_HEIGHT); + + l->x += theme_default()->padding; +} + +static void +resize_autosave(void) +{ + unsigned int padding = theme_default()->padding; + struct frame *f = &ui.panel.frame; + struct checkbox *c = &ui.autosave.cb; + struct label *l = &ui.autosave.label; - /* Auto save. */ - ui.autosave.cb.x = ui.panel.frame.x + padding; - ui.autosave.cb.y = ui.panel.frame.y + HEADER_HEIGHT + padding; - ui.autosave.label.w = ui.panel.frame.w - ui.autosave.cb.w - padding; - ui.autosave.label.x = ui.autosave.cb.x + ui.autosave.cb.w; - ui.autosave.label.y = ui.autosave.cb.y; + c->x = f->x + padding; + c->y = f->y + HEADER_HEIGHT + padding; + + l->w = f->w - c->w - padding; + l->x = c->x + c->w + padding; + l->y = c->y; +} + +static void +resize_button(void) +{ + unsigned int padding = theme_default()->padding; + struct frame *f = &ui.panel.frame; + struct button *b = &ui.quit.button; /* Button. */ - ui.quit.button.w = ui.panel.frame.w / 4; + b->w = f->w / 4; + + align(ALIGN_BOTTOM_RIGHT, &b->x, &b->y, b->w, b->h, + f->x, f->y, f->w, f->h); - align( - ALIGN_BOTTOM_RIGHT, - &ui.quit.button.x, - &ui.quit.button.y, - ui.quit.button.w, - ui.quit.button.h, - ui.panel.frame.x + padding, - ui.panel.frame.y + padding, - ui.panel.frame.w - padding * 2, - ui.panel.frame.h - padding * 2 - ); + b->x -= padding; + b->y -= padding; +} + +static void +resize(void) +{ + resize_header(); + resize_autosave(); + resize_button(); } static void diff -r 1008a796a9e7 -r aa6e70e330a1 librpg/rpg/inventory_dialog.c --- a/librpg/rpg/inventory_dialog.c Thu Oct 15 18:09:45 2020 +0200 +++ b/librpg/rpg/inventory_dialog.c Thu Oct 15 18:45:27 2020 +0200 @@ -195,7 +195,6 @@ 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 = ALIGN_LEFT; /* Description label. */ dlg->fdesc.w = dlg->ldesc.w = LABEL_WIDTH; @@ -203,7 +202,6 @@ 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 = ALIGN_LEFT; /* Button sort. */ dlg->bsort.x = dlg->x; diff -r 1008a796a9e7 -r aa6e70e330a1 librpg/rpg/message.c --- a/librpg/rpg/message.c Thu Oct 15 18:09:45 2020 +0200 +++ b/librpg/rpg/message.c Thu Oct 15 18:45:27 2020 +0200 @@ -100,7 +100,6 @@ .h = msg->h, .theme = &theme, .text = msg->text[i], - .align = ALIGN_TOP_LEFT, .flags = LABEL_FLAGS_SHADOW }; diff -r 1008a796a9e7 -r aa6e70e330a1 libui/ui/button.c --- a/libui/ui/button.c Thu Oct 15 18:09:45 2020 +0200 +++ b/libui/ui/button.c Thu Oct 15 18:45:27 2020 +0200 @@ -60,15 +60,14 @@ (void)t; - const struct label label = { + struct label label = { .text = button->text, - .x = button->x, - .y = button->y, - .w = button->w, - .h = button->h, - .align = ALIGN_CENTER }; + label_query(&label); + align(ALIGN_CENTER, &label.x, &label.y, label.w, label.h, + button->x, button->y, button->w, button->h); + painter_set_color(0x577277ff); painter_draw_rectangle(button->x, button->y, button->w, button->h); diff -r 1008a796a9e7 -r aa6e70e330a1 libui/ui/label.c --- a/libui/ui/label.c Thu Oct 15 18:09:45 2020 +0200 +++ b/libui/ui/label.c Thu Oct 15 18:45:27 2020 +0200 @@ -41,28 +41,9 @@ 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]; @@ -70,7 +51,7 @@ if (!font_render(font, &tex, label->text)) panic(); - texture_draw(&tex, x + 1, y + 1); + texture_draw(&tex, label->x + 1, label->y + 1); texture_finish(&tex); } @@ -80,11 +61,23 @@ if (!font_render(font, &tex, label->text)) panic(); - texture_draw(&tex, x, y); + texture_draw(&tex, label->x, label->y); texture_finish(&tex); } void +label_query(struct label *label) +{ + assert(label); + assert(label->text); + + struct theme *t = label->theme ? label->theme : theme_default(); + + if (!font_box(t->fonts[THEME_FONT_INTERFACE], label->text, &label->w, &label->h)) + panic(); +} + +void label_draw(const struct label *label) { assert(label); diff -r 1008a796a9e7 -r aa6e70e330a1 libui/ui/label.h --- a/libui/ui/label.h Thu Oct 15 18:09:45 2020 +0200 +++ b/libui/ui/label.h Thu Oct 15 18:45:27 2020 +0200 @@ -25,8 +25,6 @@ * \ingroup ui */ -#include "align.h" - struct action; struct theme; @@ -41,9 +39,9 @@ /** * \brief GUI label. * - * A label can be conveniently positioned using a bounding box and an alignment - * in that case the fields `w`, `h` and `align` must be specified, otherwise - * the label is drawn immediately at `x` and `y` field. + * A label has a position and a size. The size is only provided to the user as + * information and is not used during rendering. It should be computed using the + * \ref label_query command each time you change the theme or text. */ struct label { int x; /*!< (+) Position in x. */ @@ -52,7 +50,6 @@ unsigned int h; /*!< (+?) Height. */ const char *text; /*!< (+&) Text to show. */ enum label_flags flags; /*!< (+) Optional flags. */ - enum align align; /*!< (+) How to positionate label. */ struct theme *theme; /*!< (+&?) Theme to use. */ }; @@ -68,6 +65,16 @@ label_draw_default(struct theme *t, const struct label *label); /** + * Update the `w` and `h` fields with the dimensions the text would needs with + * the current theme. + * + * \pre label != NULL + * \param label the label + */ +void +label_query(struct label *label); + +/** * Draw the label. * * \pre label != NULL