[Concept,12/18] expo: Support clicking on any type of object

Message ID 20251010034255.1099728-13-sjg@u-boot.org
State New
Headers
Series expo: Extend the boot menu |

Commit Message

Simon Glass Oct. 10, 2025, 3:42 a.m. UTC
  From: Simon Glass <sjg@chromium.org>

It is sometimes useful to be able to click on an image (sometimes called
an icon). Allow this within expo and return new click action.

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

 boot/bootflow_menu.c |  1 +
 boot/cedit.c         |  3 +++
 boot/scene.c         | 14 +++++++++++---
 include/expo.h       |  2 ++
 4 files changed, 17 insertions(+), 3 deletions(-)
  

Patch

diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c
index 3365b5c3b06..bbc9a189c98 100644
--- a/boot/bootflow_menu.c
+++ b/boot/bootflow_menu.c
@@ -313,6 +313,7 @@  int bootflow_menu_poll(struct expo *exp, int *seqp)
 	}
 	case EXPOACT_QUIT:
 		return -EPIPE;
+	case EXPOACT_CLICK:
 	default:
 		return -EAGAIN;
 	}
diff --git a/boot/cedit.c b/boot/cedit.c
index 691780512ca..70a0c22fe68 100644
--- a/boot/cedit.c
+++ b/boot/cedit.c
@@ -220,6 +220,9 @@  int cedit_do_action(struct expo *exp, struct scene *scn,
 		log_debug("quitting\n");
 		exp->done = true;
 		break;
+	case EXPOACT_CLICK:
+		/* not supported by cedit */
+		break;
 	}
 
 	return 0;
diff --git a/boot/scene.c b/boot/scene.c
index 4cf1b6d5852..dd13b74b4d7 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -1167,9 +1167,11 @@  bool scene_obj_within(const struct scene *scn, struct scene_obj *obj, int x,
 
 	switch (obj->type) {
 	case SCENEOBJT_NONE:
+		break;
 	case SCENEOBJT_IMAGE:
 	case SCENEOBJT_TEXT:
 	case SCENEOBJT_BOX:
+		within = is_within(obj, x, y);
 		break;
 	case SCENEOBJT_MENU: {
 		struct scene_obj_menu *menu;
@@ -1344,15 +1346,21 @@  int scene_send_click(struct scene *scn, int x, int y, struct expo_action *event)
 	obj = scene_find_obj_within(scn, x, y, false, false);
 	log_debug("non-popup obj %d '%s'\n", obj ? obj->id : -1,
 		  obj ? obj->name : "(none)");
-	if (!obj)
-		return 0;
+	if (!obj) {
+		obj = scene_find_obj_within(scn, x, y, true, true);
+		log_debug("non-popup any obj %d '%s'\n", obj ? obj->id : -1,
+			  obj ? obj->name : "(none)");
+		if (!obj)
+			return 0;
+	}
 
 	switch (obj->type) {
 	case SCENEOBJT_NONE:
 	case SCENEOBJT_IMAGE:
 	case SCENEOBJT_TEXT:
 	case SCENEOBJT_BOX:
-		/* These objects don't handle clicks directly */
+		event->type = EXPOACT_CLICK;
+		event->select.id = obj->id;
 		break;
 	case SCENEOBJT_MENU: {
 		struct scene_obj_menu *menu;
diff --git a/include/expo.h b/include/expo.h
index 619af627840..05f61cc9bd9 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -56,6 +56,7 @@  enum expo_id_t {
  * @EXPOACT_REPOINT_OPEN: menu closed, another menu opened (@prev_id indicates
  * the menu closed, @id indicates menu opened)
  * @EXPOACT_QUIT: request to exit the menu
+ * @EXPOACT_CLICK: click on an object
  */
 enum expoact_type {
 	EXPOACT_NONE,
@@ -68,6 +69,7 @@  enum expoact_type {
 	EXPOACT_POINT_CLOSE,
 	EXPOACT_REPOINT_OPEN,
 	EXPOACT_QUIT,
+	EXPOACT_CLICK,
 };
 
 /**