[Concept,10/16] expo: Add arrangement support for textedit

Message ID 20260118204303.1982533-11-sjg@u-boot.org
State New
Headers
Series expo: Continue preparations for textedit (part D) |

Commit Message

Simon Glass Jan. 18, 2026, 8:42 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Add scene_txted_arrange() to position the label and edit text objects
within a textedit, following the same pattern as textline:

  - Position the label at the textedit's position
  - Position edit text after the label (with margin)
  - Set the SCENEOF_POINT flag when highlighted but not open
  - Calculate the overall dimensions of the textedit

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 boot/scene.c          | 10 +++++++++-
 boot/scene_internal.h | 14 ++++++++++++++
 boot/scene_textedit.c | 37 +++++++++++++++++++++++++++++++++++++
 test/boot/expo.c      |  2 +-
 4 files changed, 61 insertions(+), 2 deletions(-)
  

Patch

diff --git a/boot/scene.c b/boot/scene.c
index d515754c702..882a250e17d 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -868,7 +868,6 @@  int scene_arrange(struct scene *scn)
 		case SCENEOBJT_IMAGE:
 		case SCENEOBJT_TEXT:
 		case SCENEOBJT_BOX:
-		case SCENEOBJT_TEXTEDIT:
 			break;
 		case SCENEOBJT_MENU: {
 			struct scene_obj_menu *menu;
@@ -888,6 +887,15 @@  int scene_arrange(struct scene *scn)
 				return log_msg_ret("arr", ret);
 			break;
 		}
+		case SCENEOBJT_TEXTEDIT: {
+			struct scene_obj_txtedit *ted;
+
+			ted = (struct scene_obj_txtedit *)obj,
+			ret = scene_txted_arrange(scn, &arr, ted);
+			if (ret)
+				return log_msg_ret("arr", ret);
+			break;
+		}
 		}
 	}
 	ret = scene_sync_bbox(scn);
diff --git a/boot/scene_internal.h b/boot/scene_internal.h
index 5cc81f031a0..1e5bd3d2a28 100644
--- a/boot/scene_internal.h
+++ b/boot/scene_internal.h
@@ -162,6 +162,20 @@  int scene_menu_arrange(struct scene *scn, struct expo_arrange_info *arr,
 int scene_textline_arrange(struct scene *scn, struct expo_arrange_info *arr,
 			   struct scene_obj_textline *tline);
 
+/**
+ * scene_txted_arrange() - Set the position of things in a textedit
+ *
+ * This updates any items associated with a textedit to make sure they are
+ * positioned correctly relative to the textedit.
+ *
+ * @scn: Scene to update
+ * @arr: Arrangement information
+ * @ted: textedit to process
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_txted_arrange(struct scene *scn, struct expo_arrange_info *arr,
+			struct scene_obj_txtedit *ted);
+
 /**
  * scene_apply_theme() - Apply a theme to a scene
  *
diff --git a/boot/scene_textedit.c b/boot/scene_textedit.c
index a55285f00cd..8714a4b5705 100644
--- a/boot/scene_textedit.c
+++ b/boot/scene_textedit.c
@@ -55,3 +55,40 @@  int scene_txted_set_font(struct scene *scn, uint id, const char *font_name,
 
 	return scene_txt_set_font(scn, ted->edit_id, font_name, font_size);
 }
+
+int scene_txted_arrange(struct scene *scn, struct expo_arrange_info *arr,
+			struct scene_obj_txtedit *ted)
+{
+	const bool open = ted->obj.flags & SCENEOF_OPEN;
+	const struct expo_theme *theme = &scn->expo->theme;
+	bool point;
+	int x, y;
+	int ret;
+
+	x = ted->obj.req_bbox.x0;
+	y = ted->obj.req_bbox.y0;
+	if (ted->label_id) {
+		ret = scene_obj_set_pos(scn, ted->label_id, x, y);
+		if (ret < 0)
+			return log_msg_ret("tit", ret);
+
+		x += arr->label_width + theme->textline_label_margin_x;
+	}
+
+	/* constrain the edit text to fit within the textedit bbox */
+	ret = scene_obj_set_bbox(scn, ted->edit_id, x, y,
+				 ted->obj.req_bbox.x1, ted->obj.req_bbox.y1);
+	if (ret < 0)
+		return log_msg_ret("edi", ret);
+
+	point = scn->highlight_id == ted->obj.id;
+	point &= !open;
+	scene_obj_flag_clrset(scn, ted->edit_id, SCENEOF_POINT,
+			      point ? SCENEOF_POINT : 0);
+
+	ted->obj.dims.x = x - ted->obj.req_bbox.x0;
+	ted->obj.dims.y = y - ted->obj.req_bbox.y0;
+	scene_obj_set_size(scn, ted->obj.id, ted->obj.dims.x, ted->obj.dims.y);
+
+	return 0;
+}
diff --git a/test/boot/expo.c b/test/boot/expo.c
index dc9ebe702b8..b6ee4892d7a 100644
--- a/test/boot/expo.c
+++ b/test/boot/expo.c
@@ -1533,7 +1533,7 @@  static int expo_render_textedit(struct unit_test_state *uts)
 	expo_set_scene_id(exp, SCENE1);
 	ut_assertok(scene_arrange(scn));
 	ut_assertok(expo_render(exp));
-	ut_asserteq(19651, video_compress_fb(uts, dev, false));
+	ut_asserteq(19493, video_compress_fb(uts, dev, false));
 
 	abuf_uninit(&buf);
 	abuf_uninit(&logo_copy);