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(-) 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); -- 2.43.0