aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/scene_menu.c67
-rw-r--r--test/boot/expo.c2
2 files changed, 55 insertions, 14 deletions
diff --git a/boot/scene_menu.c b/boot/scene_menu.c
index fa79cecdbd..154be7f012 100644
--- a/boot/scene_menu.c
+++ b/boot/scene_menu.c
@@ -33,6 +33,51 @@ void scene_menu_destroy(struct scene_obj_menu *menu)
scene_menuitem_destroy(item);
}
+static struct scene_menitem *scene_menuitem_find(struct scene_obj_menu *menu,
+ int id)
+{
+ struct scene_menitem *item;
+
+ list_for_each_entry(item, &menu->item_head, sibling) {
+ if (item->id == id)
+ return item;
+ }
+
+ return NULL;
+}
+
+/**
+ * update_pointers() - Update the pointer object and handle highlights
+ *
+ * @menu: Menu to update
+ * @id: ID of menu item to select/deselect
+ * @point: true if @id is being selected, false if it is being deselected
+ */
+static int update_pointers(struct scene_obj_menu *menu, uint id, bool point)
+{
+ struct scene *scn = menu->obj.scene;
+ const struct scene_menitem *item;
+ int ret;
+
+ item = scene_menuitem_find(menu, id);
+ if (!item)
+ return log_msg_ret("itm", -ENOENT);
+
+ /* adjust the pointer object to point to the selected item */
+ if (menu->pointer_id && item && point) {
+ struct scene_obj *label;
+
+ label = scene_obj_find(scn, item->label_id, SCENEOBJT_NONE);
+
+ ret = scene_obj_set_pos(scn, menu->pointer_id,
+ menu->obj.dim.x + 200, label->dim.y);
+ if (ret < 0)
+ return log_msg_ret("ptr", ret);
+ }
+
+ return 0;
+}
+
/**
* menu_point_to_item() - Point to a particular menu item
*
@@ -40,7 +85,10 @@ void scene_menu_destroy(struct scene_obj_menu *menu)
*/
static void 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);
menu->cur_item_id = item_id;
+ update_pointers(menu, item_id, true);
}
static int scene_bbox_union(struct scene *scn, uint id,
@@ -125,6 +173,7 @@ int scene_menu_calc_dims(struct scene_obj_menu *menu)
int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
{
struct scene_menitem *item;
+ uint sel_id;
int y, cur_y;
int ret;
@@ -147,7 +196,7 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
* small. This can be updated once text measuring is supported in
* vidconsole
*/
- cur_y = -1;
+ sel_id = menu->cur_item_id;
list_for_each_entry(item, &menu->item_head, sibling) {
int height;
@@ -160,8 +209,8 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
y += height;
/* select an item if not done already */
- if (!menu->cur_item_id)
- menu_point_to_item(menu, item->id);
+ if (!sel_id)
+ sel_id = item->id;
/*
* Put the label on the left, then leave a space for the
@@ -207,16 +256,8 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
y += height;
}
- if (menu->pointer_id && cur_y != -1) {
- /*
- * put the pointer to the right of and level with the item it
- * points to
- */
- ret = scene_obj_set_pos(scn, menu->pointer_id,
- menu->obj.dim.x + 200, cur_y);
- if (ret < 0)
- return log_msg_ret("ptr", ret);
- }
+ if (sel_id)
+ menu_point_to_item(menu, sel_id);
return 0;
}
diff --git a/test/boot/expo.c b/test/boot/expo.c
index c0ef03b591..453316ece7 100644
--- a/test/boot/expo.c
+++ b/test/boot/expo.c
@@ -378,7 +378,7 @@ static int expo_object_menu(struct unit_test_state *uts)
ut_asserteq(-4, prev1->obj.dim.x);
ut_asserteq(menu->obj.dim.y + 32, prev1->obj.dim.y);
- ut_asserteq(false, prev1->obj.flags & SCENEOF_HIDE);
+ ut_asserteq(true, prev1->obj.flags & SCENEOF_HIDE);
expo_destroy(exp);