[PATCH 34/40] expo: Draw the current opened menu on top

Simon Glass sjg at chromium.org
Thu Jun 1 18:22:58 CEST 2023


When a menu is opened, it must be displayed over all other objects in
the scene, so that all its items are visible.

Handle this by drawing the menu object a second time, after all other
objects have been drawn. Draw all of the objects which are dependent
on the menu object.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 boot/expo.c           | 12 ++++++++++++
 boot/scene.c          | 31 +++++++++++++++++++++++++++++++
 boot/scene_internal.h | 20 ++++++++++++++++++++
 boot/scene_menu.c     | 17 +++++++++++++++++
 4 files changed, 80 insertions(+)

diff --git a/boot/expo.c b/boot/expo.c
index d5e935966bfd..e99555163ca4 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -172,6 +172,18 @@ int expo_set_scene_id(struct expo *exp, uint scene_id)
 	return 0;
 }
 
+int expo_first_scene_id(struct expo *exp)
+{
+	struct scene *scn;
+
+	if (list_empty(&exp->scene_head))
+		return -ENOENT;
+
+	scn = list_first_entry(&exp->scene_head, struct scene, sibling);
+
+	return scn->id;
+}
+
 int expo_render(struct expo *exp)
 {
 	struct udevice *dev = exp->display;
diff --git a/boot/scene.c b/boot/scene.c
index fb199ef29538..bc213bc08b87 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -421,6 +421,30 @@ int scene_arrange(struct scene *scn)
 	return 0;
 }
 
+int scene_render_deps(struct scene *scn, uint id)
+{
+	struct scene_obj *obj;
+	int ret;
+
+	if (!id)
+		return 0;
+	obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
+	if (!obj)
+		return log_msg_ret("obj", -ENOENT);
+
+	if (!(obj->flags & SCENEOF_HIDE)) {
+		ret = scene_obj_render(obj, false);
+		if (ret && ret != -ENOTSUPP)
+			return log_msg_ret("ren", ret);
+
+		if (obj->type == SCENEOBJT_MENU)
+			scene_menu_render_deps(scn,
+					       (struct scene_obj_menu *)obj);
+	}
+
+	return 0;
+}
+
 int scene_render(struct scene *scn)
 {
 	struct expo *exp = scn->expo;
@@ -435,6 +459,13 @@ int scene_render(struct scene *scn)
 		}
 	}
 
+	/* render any highlighted object on top of the others */
+	if (scn->highlight_id && !exp->text_mode) {
+		ret = scene_render_deps(scn, scn->highlight_id);
+		if (ret && ret != -ENOTSUPP)
+			return log_msg_ret("dep", ret);
+	}
+
 	return 0;
 }
 
diff --git a/boot/scene_internal.h b/boot/scene_internal.h
index 2544c961dab4..dc98ecd02146 100644
--- a/boot/scene_internal.h
+++ b/boot/scene_internal.h
@@ -160,6 +160,26 @@ int scene_send_key(struct scene *scn, int key, struct expo_action *event);
  */
 void scene_menu_render(struct scene_obj_menu *menu);
 
+/**
+ * scene_render_deps() - Render an object and its dependencies
+ *
+ * @scn: Scene to render
+ * @id: Object ID to render (or 0 for none)
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_render_deps(struct scene *scn, uint id);
+
+/**
+ * scene_menu_render_deps() - Render a menu and its dependencies
+ *
+ * Renders the menu and all of its attached objects
+ *
+ * @scn: Scene to render
+ * @menu: Menu render
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_menu_render_deps(struct scene *scn, struct scene_obj_menu *menu);
+
 /**
  * scene_menu_calc_dims() - Calculate the dimensions of a menu
  *
diff --git a/boot/scene_menu.c b/boot/scene_menu.c
index 20ded91fb3d6..6aab27611d71 100644
--- a/boot/scene_menu.c
+++ b/boot/scene_menu.c
@@ -544,3 +544,20 @@ void scene_menu_render(struct scene_obj_menu *menu)
 			vid_priv->colour_fg);
 	vidconsole_pop_colour(cons, &old);
 }
+
+int scene_menu_render_deps(struct scene *scn, struct scene_obj_menu *menu)
+{
+	struct scene_menitem *item;
+
+	scene_render_deps(scn, menu->title_id);
+	scene_render_deps(scn, menu->cur_item_id);
+	scene_render_deps(scn, menu->pointer_id);
+
+	list_for_each_entry(item, &menu->item_head, sibling) {
+		scene_render_deps(scn, item->key_id);
+		scene_render_deps(scn, item->label_id);
+		scene_render_deps(scn, item->desc_id);
+	}
+
+	return 0;
+}
-- 
2.41.0.rc0.172.g3f132b7071-goog



More information about the U-Boot mailing list