[PATCH 36/40] expo: Add spacing around menus and items
Simon Glass
sjg at chromium.org
Thu Jun 1 18:23:00 CEST 2023
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 <sjg at chromium.org>
---
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 ff9f9222e6f9..38d5739421f6 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 e99555163ca4..8c6fbc0e30bc 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 ea94b90584ee..6fbc1fc578c2 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 dfe5692d6ce7..8a355f838cc8 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 80e435c5e65e..bd593dc2b3f5 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.41.0.rc0.172.g3f132b7071-goog
More information about the U-Boot
mailing list