[Concept,07/16] expo: Refactor textedit to use label_id and edit_id

Message ID 20260118204303.1982533-8-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>

Update scene_obj_txtedit to follow the same pattern as textline, with
separate label_id and edit_id fields pointing to text objects rather
than embedding a scene_txt_generic directly.

This allows the label and edit text to be rendered as regular scene
objects and enables consistent handling between textline and textedit.

Changes include:
- Remove gen field from scene_obj_txtedit, add label_id and edit_id
- Update scene_texted() to not take a str_id parameter
- Update scene_txted_set_font() to set font on the edit text object
- Add scene_txted_render_deps() for rendering dependencies
- Update expo_dump to show label_id and edit_id
- Update test to create label and edit text objects separately

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

 boot/expo_dump.c      |  6 ++----
 boot/scene.c          | 18 ++++++------------
 boot/scene_textedit.c |  9 ++-------
 include/expo.h        | 11 ++++++-----
 test/boot/expo.c      | 26 +++++++++++++++++---------
 5 files changed, 33 insertions(+), 37 deletions(-)
  

Patch

diff --git a/boot/expo_dump.c b/boot/expo_dump.c
index eb0c7bce6fc..5f9ea22c50a 100644
--- a/boot/expo_dump.c
+++ b/boot/expo_dump.c
@@ -116,10 +116,8 @@  static void dump_textline(struct dump_ctx *ctx,
 static void dump_textedit(struct dump_ctx *ctx,
 			  struct scene_obj_txtedit *tedit)
 {
-	outf(ctx, "Textedit: str_id %x font_name '%s' font_size %x\n",
-	     tedit->gen.str_id,
-	     tedit->gen.font_name ? tedit->gen.font_name : "(default)",
-	     tedit->gen.font_size);
+	outf(ctx, "Textedit: label_id %x edit_id %x\n",
+	     tedit->label_id, tedit->edit_id);
 }
 
 static void obj_dump_(struct dump_ctx *ctx, struct scene_obj *obj)
diff --git a/boot/scene.c b/boot/scene.c
index 5c19bff6011..d515754c702 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -468,6 +468,7 @@  int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
 	case SCENEOBJT_MENU:
 	case SCENEOBJT_TEXTLINE:
 	case SCENEOBJT_BOX:
+	case SCENEOBJT_TEXTEDIT:
 		break;
 	case SCENEOBJT_IMAGE: {
 		struct scene_obj_img *img = (struct scene_obj_img *)obj;
@@ -479,18 +480,14 @@  int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
 			*widthp = width;
 		return height;
 	}
-	case SCENEOBJT_TEXT:
-	case SCENEOBJT_TEXTEDIT: {
+	case SCENEOBJT_TEXT: {
 		struct scene_txt_generic *gen;
 		struct expo *exp = scn->expo;
 		struct vidconsole_bbox bbox;
 		int len, ret, limit;
 		const char *str;
 
-		if (obj->type == SCENEOBJT_TEXT)
-			gen = &((struct scene_obj_txt *)obj)->gen;
-		else
-			gen = &((struct scene_obj_txtedit *)obj)->gen;
+		gen = &((struct scene_obj_txt *)obj)->gen;
 
 		str = expo_get_str(exp, gen->str_id);
 		if (!str)
@@ -753,14 +750,11 @@  static int scene_obj_render(struct scene_obj *obj, bool text_mode)
 			       obj->bbox.y1, box->width, vid_priv->colour_fg, box->fill);
 		break;
 	}
-	case SCENEOBJT_TEXTEDIT: {
-		struct scene_obj_txtedit *ted = (struct scene_obj_txtedit *)obj;
-
-		ret = scene_txt_render(exp, dev, cons, obj, &ted->gen, x, y,
-				       theme->menu_inset);
+	case SCENEOBJT_TEXTEDIT:
+		if (obj->flags & SCENEOF_OPEN)
+			scene_render_background(obj, true, false);
 		break;
 	}
-	}
 
 	return 0;
 }
diff --git a/boot/scene_textedit.c b/boot/scene_textedit.c
index 8242eb39806..3c1edf38592 100644
--- a/boot/scene_textedit.c
+++ b/boot/scene_textedit.c
@@ -18,7 +18,7 @@  enum {
 	INITIAL_SIZE	= SZ_4K,
 };
 
-int scene_texted(struct scene *scn, const char *name, uint id, uint str_id,
+int scene_texted(struct scene *scn, const char *name, uint id,
 		 struct scene_obj_txtedit **teditp)
 {
 	struct scene_obj_txtedit *ted;
@@ -37,9 +37,6 @@  int scene_texted(struct scene *scn, const char *name, uint id, uint str_id,
 	buf = abuf_data(&ted->buf);
 	*buf = '\0';
 
-	ret = scene_txt_generic_init(scn->expo, &ted->gen, name, str_id, buf);
-	if (ret)
-		return log_msg_ret("teg", ret);
 	if (teditp)
 		*teditp = ted;
 
@@ -54,8 +51,6 @@  int scene_txted_set_font(struct scene *scn, uint id, const char *font_name,
 	ted = scene_obj_find(scn, id, SCENEOBJT_TEXTEDIT);
 	if (!ted)
 		return log_msg_ret("find", -ENOENT);
-	ted->gen.font_name = font_name;
-	ted->gen.font_size = font_size;
 
-	return 0;
+	return scene_txt_set_font(scn, ted->edit_id, font_name, font_size);
 }
diff --git a/include/expo.h b/include/expo.h
index f9f85b38b9c..9d6300024fc 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -539,17 +539,19 @@  struct scene_obj_box {
 };
 
 /**
- * struct scene_obj_txtedit - information about a box in a scene
+ * struct scene_obj_txtedit - information about a textedit in a scene
  *
  * A text editor which allows users to edit a small text file
  *
  * @obj: Basic object information
- * @gen: Generic information common to all objects which show text
+ * @label_id: ID of the label text object (not string ID), or 0 if none
+ * @edit_id: ID of the editable text object (not string ID)
  * @buf: Text buffer containing current text
  */
 struct scene_obj_txtedit {
 	struct scene_obj obj;
-	struct scene_txt_generic gen;
+	uint label_id;
+	uint edit_id;
 	struct abuf buf;
 };
 
@@ -890,11 +892,10 @@  int scene_box_set_fill(struct scene *scn, uint id, bool fill);
  * @scn: Scene to update
  * @name: Name to use (this is allocated by this call)
  * @id: ID to use for the new object (0 to allocate one)
- * @strid: ID of the string to edit
  * @teditp: If non-NULL, returns the new object
  * Returns: ID number for the object (typically @id), or -ve on error
  */
-int scene_texted(struct scene *scn, const char *name, uint id, uint strid,
+int scene_texted(struct scene *scn, const char *name, uint id,
 		 struct scene_obj_txtedit **teditp);
 
 /**
diff --git a/test/boot/expo.c b/test/boot/expo.c
index 62b0b1a7c1b..7d76431208a 100644
--- a/test/boot/expo.c
+++ b/test/boot/expo.c
@@ -1503,7 +1503,6 @@  static int expo_render_textedit(struct unit_test_state *uts)
 	struct scene_obj_txtedit *ted;
 	struct scene_obj_menu *menu;
 	struct abuf buf, logo_copy;
-	struct abuf orig, *text;
 	struct scene *scn;
 	struct udevice *dev;
 	struct expo *exp;
@@ -1512,20 +1511,29 @@  static int expo_render_textedit(struct unit_test_state *uts)
 	ut_assertok(create_test_expo(uts, &exp, &scn, &menu, &buf, &logo_copy));
 	dev = exp->display;
 
-	id = scene_texted(scn, "texted", OBJ_TEXTED, STR_TEXTED, &ted);
-	ut_asserteq(OBJ_TEXTED, id);
+	id = scene_texted(scn, "texted", OBJ_TEXTED, &ted);
+	ut_assert(id > 0);
 	ut_assertok(scene_obj_set_bbox(scn, OBJ_TEXTED, 100, 200, 400, 300));
-	ut_assertok(scene_txted_set_font(scn, OBJ_TEXTED,
-					 "nimbus_sans_l_regular", 20));
-	ut_assertok(expo_edit_str(exp, STR_TEXTED, &orig, &text));
 
-	abuf_printf(text, "This\nis the initial contents of the text editor "
-		"but it is quite likely that more will be added later");
+	/* create the label text object */
+	id = scene_txt_str(scn, "ted-label", 0, 0, "Editor:", NULL);
+	ut_assert(id > 0);
+	ted->label_id = id;
+
+	/* create the edit text object pointing to the textedit buffer */
+	abuf_printf(&ted->buf, "This\nis the initial contents of the text "
+		"editor but it is quite likely that more will be added later");
+	id = scene_txt_str(scn, "ted-edit", STR_TEXTED, 0, abuf_data(&ted->buf),
+			   NULL);
+	ut_assert(id > 0);
+	ted->edit_id = id;
+	ut_assertok(scene_txt_set_font(scn, ted->edit_id,
+				       "nimbus_sans_l_regular", 20));
 
 	expo_set_scene_id(exp, SCENE1);
 	ut_assertok(scene_arrange(scn));
 	ut_assertok(expo_render(exp));
-	ut_asserteq(19601, video_compress_fb(uts, dev, false));
+	ut_asserteq(19651, video_compress_fb(uts, dev, false));
 
 	abuf_uninit(&buf);
 	abuf_uninit(&logo_copy);