From 4c87e073a4573159f97eb4ed80ec4088f33c7008 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 1 Jun 2023 10:22:58 -0600 Subject: [PATCH] expo: Draw the current opened menu on top 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 --- 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 d5e935966b..e99555163c 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 fb199ef295..bc213bc08b 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 2544c961da..dc98ecd021 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 20ded91fb3..6aab27611d 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.39.5