From 7230fdb3837ad745adff4cf129dd04e893fe0a36 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 1 Jun 2023 10:23:00 -0600 Subject: [PATCH] expo: Add spacing around menus and items It looks better if menus have a bit of an inset, rather than be drawn hard up against the background. Also, menu items look better if they have a bit of spacing between them. Add theme options for these and implement the required changes. Signed-off-by: Simon Glass --- arch/sandbox/dts/test.dts | 2 ++ boot/expo.c | 2 ++ boot/scene.c | 6 ++++-- boot/scene_menu.c | 37 ++++++++++++++++++++++++------------- doc/develop/expo.rst | 6 ++++++ 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index ff9f9222e6..38d5739421 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -96,6 +96,8 @@ theme { font-size = <30>; + menu-inset = <3>; + menuitem-gap-y = <1>; }; /* diff --git a/boot/expo.c b/boot/expo.c index e99555163c..8c6fbc0e30 100644 --- a/boot/expo.c +++ b/boot/expo.c @@ -254,6 +254,8 @@ int expo_apply_theme(struct expo *exp, ofnode node) memset(theme, '\0', sizeof(struct expo_theme)); ofnode_read_u32(node, "font-size", &theme->font_size); + ofnode_read_u32(node, "menu-inset", &theme->menu_inset); + ofnode_read_u32(node, "menuitem-gap-y", &theme->menuitem_gap_y); list_for_each_entry(scn, &exp->scene_head, sibling) { ret = scene_apply_theme(scn, theme); diff --git a/boot/scene.c b/boot/scene.c index ea94b90584..6fbc1fc578 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -309,6 +309,7 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode) { struct scene *scn = obj->scene; struct expo *exp = scn->expo; + const struct expo_theme *theme = &exp->theme; struct udevice *dev = exp->display; struct udevice *cons = text_mode ? NULL : exp->cons; int x, y, ret; @@ -363,8 +364,9 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode) vid_priv = dev_get_uclass_priv(dev); if (obj->flags & SCENEOF_POINT) { vidconsole_push_colour(cons, fore, back, &old); - video_fill_part(dev, x, y, - x + obj->dim.w, y + obj->dim.h, + video_fill_part(dev, x - theme->menu_inset, y, + x + obj->dim.w, + y + obj->dim.h, vid_priv->colour_bg); } vidconsole_set_cursor_pos(cons, x, y); diff --git a/boot/scene_menu.c b/boot/scene_menu.c index dfe5692d6c..8a355f838c 100644 --- a/boot/scene_menu.c +++ b/boot/scene_menu.c @@ -98,7 +98,7 @@ static void menu_point_to_item(struct scene_obj_menu *menu, uint item_id) update_pointers(menu, item_id, true); } -static int scene_bbox_union(struct scene *scn, uint id, +static int scene_bbox_union(struct scene *scn, uint id, int inset, struct vidconsole_bbox *bbox) { struct scene_obj *obj; @@ -109,14 +109,14 @@ static int scene_bbox_union(struct scene *scn, uint id, if (!obj) return log_msg_ret("obj", -ENOENT); if (bbox->valid) { - bbox->x0 = min(bbox->x0, obj->dim.x); + bbox->x0 = min(bbox->x0, obj->dim.x - inset); bbox->y0 = min(bbox->y0, obj->dim.y); - bbox->x1 = max(bbox->x1, obj->dim.x + obj->dim.w); + bbox->x1 = max(bbox->x1, obj->dim.x + obj->dim.w + inset); bbox->y1 = max(bbox->y1, obj->dim.y + obj->dim.h); } else { - bbox->x0 = obj->dim.x; + bbox->x0 = obj->dim.x - inset; bbox->y0 = obj->dim.y; - bbox->x1 = obj->dim.x + obj->dim.w; + bbox->x1 = obj->dim.x + obj->dim.w + inset; bbox->y1 = obj->dim.y + obj->dim.h; bbox->valid = true; } @@ -135,22 +135,31 @@ static void scene_menu_calc_bbox(struct scene_obj_menu *menu, struct vidconsole_bbox *bbox, struct vidconsole_bbox *label_bbox) { + const struct expo_theme *theme = &menu->obj.scene->expo->theme; const struct scene_menitem *item; bbox->valid = false; - scene_bbox_union(menu->obj.scene, menu->title_id, bbox); + scene_bbox_union(menu->obj.scene, menu->title_id, 0, bbox); label_bbox->valid = false; list_for_each_entry(item, &menu->item_head, sibling) { - scene_bbox_union(menu->obj.scene, item->label_id, bbox); - scene_bbox_union(menu->obj.scene, item->key_id, bbox); - scene_bbox_union(menu->obj.scene, item->desc_id, bbox); - scene_bbox_union(menu->obj.scene, item->preview_id, bbox); + scene_bbox_union(menu->obj.scene, item->label_id, + theme->menu_inset, bbox); + scene_bbox_union(menu->obj.scene, item->key_id, 0, bbox); + scene_bbox_union(menu->obj.scene, item->desc_id, 0, bbox); + scene_bbox_union(menu->obj.scene, item->preview_id, 0, bbox); /* Get the bounding box of all labels */ - scene_bbox_union(menu->obj.scene, item->label_id, label_bbox); + scene_bbox_union(menu->obj.scene, item->label_id, + theme->menu_inset, label_bbox); } + + /* + * subtract the final menuitem's gap to keep the insert the same top + * and bottom + */ + label_bbox->y1 -= theme->menuitem_gap_y; } int scene_menu_calc_dims(struct scene_obj_menu *menu) @@ -182,6 +191,7 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu) const bool open = menu->obj.flags & SCENEOF_OPEN; struct expo *exp = scn->expo; const bool stack = exp->popup; + const struct expo_theme *theme = &exp->theme; struct scene_menitem *item; uint sel_id; int x, y; @@ -233,7 +243,8 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu) * Put the label on the left, then leave a space for the * pointer, then the key and the description */ - ret = scene_obj_set_pos(scn, item->label_id, x, y); + ret = scene_obj_set_pos(scn, item->label_id, + x + theme->menu_inset, y); if (ret < 0) return log_msg_ret("nam", ret); scene_obj_set_hide(scn, item->label_id, @@ -269,7 +280,7 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu) } if (!stack || open) - y += height; + y += height + theme->menuitem_gap_y; } if (sel_id) diff --git a/doc/develop/expo.rst b/doc/develop/expo.rst index 80e435c5e6..bd593dc2b3 100644 --- a/doc/develop/expo.rst +++ b/doc/develop/expo.rst @@ -162,6 +162,12 @@ properties: font-size Font size to use for all text (type: u32) +menu-inset + Number of pixels to inset the menu on the sides and top (type: u32) + +menuitem-gap-y + Number of pixels between menu items + API documentation ----------------- -- 2.39.5