[Concept,11/14] expo: Set dirty flag when an object bbox changes

Message ID 20251006165452.1675349-12-sjg@u-boot.org
State New
Headers
Series expo: Continue development of expo with mouse |

Commit Message

Simon Glass Oct. 6, 2025, 4:54 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

Add a flag to indicate that am object must be redrawn. Set this flag
when an object's bounding box changes.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 boot/scene.c      |  7 +++++++
 include/expo.h    |  2 ++
 test/boot/cedit.c | 21 +++++++++++++--------
 3 files changed, 22 insertions(+), 8 deletions(-)
  

Patch

diff --git a/boot/scene.c b/boot/scene.c
index a451ee1d325..242f21bbacf 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -1300,6 +1300,7 @@  int scene_sync_bbox(struct scene *scn)
 	list_for_each_entry(obj, &scn->obj_head, sibling) {
 		int req_width = obj->req_bbox.x1 - obj->req_bbox.x0;
 		int req_height = obj->req_bbox.y1 - obj->req_bbox.y0;
+		struct vid_bbox old_bbox = obj->bbox;
 
 		if (obj->flags & SCENEOF_SYNC_POS) {
 			if (obj->flags & SCENEOF_SIZE_VALID) {
@@ -1321,6 +1322,12 @@  int scene_sync_bbox(struct scene *scn)
 			obj->bbox.x1 = obj->bbox.x0 + req_width;
 		if (obj->flags & SCENEOF_SYNC_BBOX)
 			obj->bbox = obj->req_bbox;
+
+		/* Set dirty flag if bbox changed */
+		if (old_bbox.x0 != obj->bbox.x0 || old_bbox.y0 != obj->bbox.y0 ||
+		    old_bbox.x1 != obj->bbox.x1 || old_bbox.y1 != obj->bbox.y1)
+			obj->flags |= SCENEOF_DIRTY;
+
 		obj->flags &= ~(SCENEOF_SYNC_POS | SCENEOF_SYNC_SIZE |
 				SCENEOF_SYNC_WIDTH | SCENEOF_SYNC_BBOX);
 	}
diff --git a/include/expo.h b/include/expo.h
index 487b58fb916..fcc090d54f1 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -308,6 +308,7 @@  enum scene_obj_align {
  * @SCENEOF_SYNC_WIDTH: object's widget has changed
  * @SCENEOF_SYNC_BBOX: object's bounding box has changed
  * @SCENEOF_MANUAL: manually arrange the items associated with this object
+ * @SCENEOF_DIRTY: object has been modified and needs to be redrawn
  * @SCENEOF_LAST: used just as a check for the size of the flags mask
  */
 enum scene_obj_flags_t {
@@ -320,6 +321,7 @@  enum scene_obj_flags_t {
 	SCENEOF_SYNC_WIDTH	= BIT(6),
 	SCENEOF_SYNC_BBOX	= BIT(7),
 	SCENEOF_MANUAL		= BIT(8),
+	SCENEOF_DIRTY		= BIT(9),
 
 	SCENEOF_LAST,	/* check for size of flags below */
 };
diff --git a/test/boot/cedit.c b/test/boot/cedit.c
index 80150a29d37..bccc93f8926 100644
--- a/test/boot/cedit.c
+++ b/test/boot/cedit.c
@@ -593,20 +593,22 @@  static int cedit_mouse(struct unit_test_state *uts)
 	ut_assertok(click_check(uts, scn, item->label_id, EXPOACT_OPEN, &act));
 	ut_asserteq(ID_CPU_SPEED, act.select.id);
 	ut_assertok(cedit_do_action(exp, scn, vid_priv, &act));
-	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID, speed->obj.flags);
+	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID | SCENEOF_DIRTY,
+		    speed->obj.flags);
 
 	/* click outside the label to close the menu */
 	ut_assertok(scene_send_click(scn, 10, 10, &act));
 	ut_asserteq(EXPOACT_CLOSE, act.type);
 	ut_asserteq(ID_CPU_SPEED, act.select.id);
 	ut_assertok(cedit_do_action(exp, scn, vid_priv, &act));
-	ut_asserteq(SCENEOF_SIZE_VALID, speed->obj.flags);
+	ut_asserteq(SCENEOF_SIZE_VALID | SCENEOF_DIRTY, speed->obj.flags);
 
 	/* click on CPU speed to open it again */
 	ut_assertok(click_check(uts, scn, item->label_id, EXPOACT_OPEN, &act));
 	ut_asserteq(ID_CPU_SPEED, act.select.id);
 	ut_assertok(cedit_do_action(exp, scn, vid_priv, &act));
-	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID, speed->obj.flags);
+	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID | SCENEOF_DIRTY,
+		    speed->obj.flags);
 
 	/* click on the second item (1.5 GHz) */
 	item = scene_menuitem_find_seq(speed, 1);
@@ -619,7 +621,7 @@  static int cedit_mouse(struct unit_test_state *uts)
 
 	/* verify that the second item is now selected and menu is closed */
 	ut_asserteq(ID_CPU_SPEED_2, speed->cur_item_id);
-	ut_asserteq(SCENEOF_SIZE_VALID, speed->obj.flags);
+	ut_asserteq(SCENEOF_SIZE_VALID | SCENEOF_DIRTY, speed->obj.flags);
 	ut_asserteq(ID_CPU_SPEED, scn->highlight_id);
 
 	/* click on the power loss menu to open it */
@@ -629,7 +631,8 @@  static int cedit_mouse(struct unit_test_state *uts)
 				&act));
 	ut_asserteq(ID_POWER_LOSS, act.select.id);
 	ut_assertok(cedit_do_action(exp, scn, vid_priv, &act));
-	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID, loss->obj.flags);
+	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID | SCENEOF_DIRTY,
+		    loss->obj.flags);
 
 	/* click on CPU speed to open it again */
 	item = scene_menuitem_find_seq(speed, 0);
@@ -637,7 +640,8 @@  static int cedit_mouse(struct unit_test_state *uts)
 				&act));
 	ut_asserteq(ID_CPU_SPEED, act.select.id);
 	ut_assertok(cedit_do_action(exp, scn, vid_priv, &act));
-	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID, speed->obj.flags);
+	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID | SCENEOF_DIRTY,
+		    speed->obj.flags);
 
 	/* click on the lineedit */
 	ut_assertok(click_check(uts, scn, mach->edit_id,
@@ -647,8 +651,9 @@  static int cedit_mouse(struct unit_test_state *uts)
 	ut_assertok(cedit_do_action(exp, scn, vid_priv, &act));
 	ut_asserteq(ID_CPU_SPEED_2, speed->cur_item_id);
 	ut_asserteq(ID_MACHINE_NAME, scn->highlight_id);
-	ut_asserteq(SCENEOF_SIZE_VALID, loss->obj.flags);
-	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID, mach->obj.flags);
+	ut_asserteq(SCENEOF_SIZE_VALID | SCENEOF_DIRTY, loss->obj.flags);
+	ut_asserteq(SCENEOF_OPEN | SCENEOF_SIZE_VALID | SCENEOF_DIRTY,
+		    mach->obj.flags);
 
 	return 0;
 }