Mercurial > molko
changeset 609:d97674d33764
ui: grid menu be more flexible
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 11 Aug 2023 18:01:28 +0200 |
parents | 2527b000aaa5 |
children | 90ac81e4c190 |
files | examples/example-gridmenu/example-gridmenu.c libmlk-ui/mlk/ui/frame.c libmlk-ui/mlk/ui/gridmenu.c libmlk-ui/mlk/ui/gridmenu.h libmlk-ui/mlk/ui/label.c libmlk-ui/mlk/ui/label.h |
diffstat | 6 files changed, 120 insertions(+), 59 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/example-gridmenu/example-gridmenu.c Fri Aug 11 19:45:00 2023 +0200 +++ b/examples/example-gridmenu/example-gridmenu.c Fri Aug 11 18:01:28 2023 +0200 @@ -61,12 +61,6 @@ static struct mlk_style style; -static struct mlk_frame frame = { - .w = 300, - .h = 100, - .delegate = &mlk_frame_delegate, - .style = &mlk_style -}; static struct mlk_gridmenu menu = { .nrows = 3, .ncols = 2, @@ -131,7 +125,6 @@ mlk_painter_set_color(MLK_EXAMPLE_BG); mlk_painter_clear(); - mlk_frame_draw(&frame); mlk_gridmenu_draw(&menu); mlk_painter_present(); } @@ -146,10 +139,7 @@ }; mlk_gridmenu_resize(&menu, 0, 0, 300, 100); - mlk_align(MLK_ALIGN_CENTER, &menu.x, &menu.y, menu.w, menu.h, 0, 0, mlk_window.w, mlk_window.h); - frame.x = menu.x; - frame.y = menu.y; mlk_game_init(); mlk_game_push(&state);
--- a/libmlk-ui/mlk/ui/frame.c Fri Aug 11 19:45:00 2023 +0200 +++ b/libmlk-ui/mlk/ui/frame.c Fri Aug 11 18:01:28 2023 +0200 @@ -77,3 +77,12 @@ if (frame->delegate->draw) frame->delegate->draw(frame->delegate, frame); } + +void +mlk_frame_finish(struct mlk_frame *frame) +{ + assert(frame); + + if (frame->delegate->finish) + frame->delegate->finish(frame->delegate, frame); +}
--- a/libmlk-ui/mlk/ui/gridmenu.c Fri Aug 11 19:45:00 2023 +0200 +++ b/libmlk-ui/mlk/ui/gridmenu.c Fri Aug 11 18:01:28 2023 +0200 @@ -24,11 +24,12 @@ #include <mlk/core/font.h> #include <mlk/core/maths.h> #include <mlk/core/painter.h> -#include <mlk/core/texture.h> #include <mlk/core/trace.h> #include <mlk/core/window.h> #include "gridmenu.h" +#include "frame.h" +#include "label.h" #include "style.h" #include "ui_p.h" @@ -185,60 +186,49 @@ } static void -draw(struct mlk_gridmenu_delegate *self, const struct mlk_gridmenu *menu) +draw_frame(struct mlk_gridmenu_delegate *self, const struct mlk_gridmenu *menu) { (void)self; - const struct mlk_style *st = menu->style; - size_t pagesz, pagenr, item, c = 0, r = 0; - struct mlk_texture tex; - struct mlk_font *font; - unsigned long color; - int x, y; + struct mlk_frame frame; - /* - * Select the first top-left column based on the current selection and - * the number of rows/columns. - */ - pagesz = menu->nrows * menu->ncols; - pagenr = menu->selected / pagesz; + mlk_frame_init(&frame, menu->style, &mlk_frame_delegate); + frame.x = menu->x; + frame.y = menu->y; + frame.w = menu->w; + frame.h = menu->h; - for (size_t i = 0; i < pagesz; ++i) { - item = i + pagenr * pagesz; - - if (item >= menu->itemsz || !menu->items[item]) - continue; + mlk_frame_draw(&frame); + mlk_frame_finish(&frame); +} - x = (int)(menu->x + st->normal.geo.padding + (c * menu->eltw) + (c * menu->spacew)); - y = (int)(menu->y + st->normal.geo.padding + (r * menu->elth) + (r * menu->spaceh)); - - if (i == menu->selected % pagesz) { - color = st->selected.color.text; - font = st->selected.font; - } else { - color = st->normal.color.text; - font = st->normal.font; - } +static void +draw_item(struct mlk_gridmenu_delegate *self, + const struct mlk_gridmenu *menu, + const char *item, + unsigned int row, + unsigned int col, + int selected) +{ + (void)self; - if (mlk_font_render(font, &tex, menu->items[item], color) < 0) { - mlk_tracef(_("unable to render grid menu item: %s"), mlk_err()); - continue; - } + struct mlk_label label; - mlk_texture_draw(&tex, x, y); - mlk_texture_finish(&tex); + mlk_label_init(&label, menu->style, &mlk_label_delegate); + label.x = menu->x + menu->style->normal.geo.padding + (col * menu->eltw) + (col * menu->spacew); + label.y = menu->y + menu->style->normal.geo.padding + (row * menu->elth) + (row * menu->spaceh); + label.text = item; + label.selected = selected; - if (++c >= menu->ncols) { - ++r; - c = 0; - } - } + mlk_label_draw(&label); + mlk_label_finish(&label); } struct mlk_gridmenu_delegate mlk_gridmenu_delegate = { .resize = resize, .handle = handle, - .draw = draw + .draw_frame = draw_frame, + .draw_item = draw_item }; void @@ -310,6 +300,41 @@ { assert(menu); - if (menu->delegate->draw) - menu->delegate->draw(menu->delegate, menu); + size_t pagesz, pagenr, item; + unsigned int row = 0, col = 0; + int selected; + + if (menu->delegate->draw_frame) + menu->delegate->draw_frame(menu->delegate, menu); + + /* + * Select the first top-left column based on the current selection and + * the number of rows/columns. + */ + pagesz = menu->nrows * menu->ncols; + pagenr = menu->selected / pagesz; + + for (size_t i = 0; i < pagesz; ++i) { + item = i + pagenr * pagesz; + + if (item >= menu->itemsz || !menu->items[item]) + continue; + + selected = i == menu->selected % pagesz; + + if (menu->delegate->draw_item) + menu->delegate->draw_item( + menu->delegate, + menu, + menu->items[item], + row, + col, + selected + ); + + if (++col >= menu->ncols) { + ++row; + col = 0; + } + } }
--- a/libmlk-ui/mlk/ui/gridmenu.h Fri Aug 11 19:45:00 2023 +0200 +++ b/libmlk-ui/mlk/ui/gridmenu.h Fri Aug 11 18:01:28 2023 +0200 @@ -166,13 +166,32 @@ /** * (read-write, optional) * - * Draw this menu. + * Draw a frame box for this menu. * * \param self this delegate - * \param menu the menu to draw + * \param menu the underlying menu */ - void (*draw)(struct mlk_gridmenu_delegate *self, - const struct mlk_gridmenu *menu); + void (*draw_frame)(struct mlk_gridmenu_delegate *self, + const struct mlk_gridmenu *menu); + + /** + * (read-write, optional) + * + * Draw a specific item. + * + * \param self this delegate + * \param menu the underlying menu + * \param item the item content + * \param row the row number (relative) + * \param col the column number (relative) + * \param selected non-zero if the item is currently selected + */ + void (*draw_item)(struct mlk_gridmenu_delegate *self, + const struct mlk_gridmenu *menu, + const char *item, + unsigned int row, + unsigned int col, + int selected); /** * (read-write, optional) @@ -187,6 +206,9 @@ }; +/** + * \brief Default stateless delegate for gridmenu. + */ extern struct mlk_gridmenu_delegate mlk_gridmenu_delegate; #if defined(__cplusplus) @@ -238,7 +260,10 @@ mlk_gridmenu_update(struct mlk_gridmenu *menu, unsigned int ticks); /** - * Invoke ::mlk_gridmenu_delegate::draw. + * Invoke the functions: + * + * - ::mlk_gridmenu_delegate::draw_frame, + * - ::mlk_gridmenu_delegate::draw_item. */ void mlk_gridmenu_draw(const struct mlk_gridmenu *menu);
--- a/libmlk-ui/mlk/ui/label.c Fri Aug 11 19:45:00 2023 +0200 +++ b/libmlk-ui/mlk/ui/label.c Fri Aug 11 18:01:28 2023 +0200 @@ -41,7 +41,12 @@ { (void)self; - const struct mlk_style_attr *attr = &label->style->normal; + const struct mlk_style_attr *attr; + + if (label->selected) + attr = &label->style->selected; + else + attr = &label->style->normal; mlk_ui_draw_text( MLK_ALIGN_NONE,