summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <[email protected]>2025-05-02 08:46:24 -0600
committerSimon Glass <[email protected]>2025-05-30 09:49:32 +0100
commit9f44b544e1d8b23dec51567c657e81488a289d6d (patch)
tree6d8232cd634cc5a8b8c8b28543a6085f8eec6517
parentc43791c4871a0635594b1f08c57a54c4a533c710 (diff)
expo: Provide access to the current menu item
Add functions to allow a caller to find out the current menu item and to select a different one. Update the event handling so that an attempt to change the current item (e.g. by pressing the up-arrow key) is reported to the caller, since this may be used to cancel an autoboot timeout. Signed-off-by: Simon Glass <[email protected]>
-rw-r--r--boot/scene_menu.c44
-rw-r--r--include/expo.h20
-rw-r--r--test/boot/expo.c4
3 files changed, 64 insertions, 4 deletions
diff --git a/boot/scene_menu.c b/boot/scene_menu.c
index 17150af145d..06d7e9fc913 100644
--- a/boot/scene_menu.c
+++ b/boot/scene_menu.c
@@ -121,12 +121,21 @@ static int update_pointers(struct scene_obj_menu *menu, uint id, bool point)
*
* Sets the currently pointed-to / highlighted menu item
*/
-static void menu_point_to_item(struct scene_obj_menu *menu, uint item_id)
+static int menu_point_to_item(struct scene_obj_menu *menu, uint item_id)
{
- if (menu->cur_item_id)
- update_pointers(menu, menu->cur_item_id, false);
+ int ret;
+
+ if (menu->cur_item_id) {
+ ret = update_pointers(menu, menu->cur_item_id, false);
+ if (ret)
+ return log_msg_ret("mpi", ret);
+ }
menu->cur_item_id = item_id;
- update_pointers(menu, item_id, true);
+ ret = update_pointers(menu, item_id, true);
+ if (ret)
+ return log_msg_ret("mpu", ret);
+
+ return 0;
}
void scene_menu_calc_bbox(struct scene_obj_menu *menu,
@@ -483,6 +492,33 @@ int scene_menu_set_pointer(struct scene *scn, uint id, uint pointer_id)
return 0;
}
+int scene_menu_select_item(struct scene *scn, uint id, uint cur_item_id)
+{
+ struct scene_obj_menu *menu;
+ int ret;
+
+ menu = scene_obj_find(scn, id, SCENEOBJT_MENU);
+ if (!menu)
+ return log_msg_ret("menu", -ENOENT);
+
+ ret = menu_point_to_item(menu, cur_item_id);
+ if (ret)
+ return log_msg_ret("msi", ret);
+
+ return 0;
+}
+
+int scene_menu_get_cur_item(struct scene *scn, uint id)
+{
+ struct scene_obj_menu *menu;
+
+ menu = scene_obj_find(scn, id, SCENEOBJT_MENU);
+ if (!menu)
+ return log_msg_ret("menu", -ENOENT);
+
+ return menu->cur_item_id;
+}
+
int scene_menu_display(struct scene_obj_menu *menu)
{
struct scene *scn = menu->obj.scene;
diff --git a/include/expo.h b/include/expo.h
index f8d44c0ea20..a2b093c521d 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -690,6 +690,26 @@ int scene_menu_set_title(struct scene *scn, uint id, uint title_id);
int scene_menu_set_pointer(struct scene *scn, uint id, uint cur_item_id);
/**
+ * scene_menu_select_item() - move the pointer/highlight to an item
+ *
+ * @scn: Scene to update
+ * @id: ID of menu object to update
+ * @sel_id: ID of the menuitem to select
+ * Return 0 on success, -ENOENT if there was no such item
+ */
+int scene_menu_select_item(struct scene *scn, uint id, uint sel_id);
+
+/**
+ * scene_menu_get_cur_item() - get the currently pointed-to item
+ *
+ * @scn: Scene to update
+ * @id: ID of menu object to update
+ * Return ID of the current item the menu is pointing to, -ENOENT if @id is not
+ * valid, 0 if no item is pointed to
+ */
+int scene_menu_get_cur_item(struct scene *scn, uint id);
+
+/**
* scene_obj_get_hw() - Get width and height of an object in a scene
*
* @scn: Scene to check
diff --git a/test/boot/expo.c b/test/boot/expo.c
index 1d283a2ac95..616071ead48 100644
--- a/test/boot/expo.c
+++ b/test/boot/expo.c
@@ -588,6 +588,8 @@ static int expo_render_image(struct unit_test_state *uts)
expo_set_scene_id(exp, SCENE1);
ut_assertok(expo_render(exp));
+ ut_asserteq(0, scn->highlight_id);
+
/* move down */
ut_assertok(expo_send_key(exp, BKEY_DOWN));
@@ -595,6 +597,8 @@ static int expo_render_image(struct unit_test_state *uts)
ut_asserteq(EXPOACT_POINT_ITEM, act.type);
ut_asserteq(ITEM2, act.select.id);
+ ut_assertok(scene_menu_select_item(scn, OBJ_MENU, act.select.id));
+ ut_asserteq(ITEM2, scene_menu_get_cur_item(scn, OBJ_MENU));
ut_assertok(expo_render(exp));
/* make sure only the preview for the second item is shown */