Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | // SPDX-License-Identifier: GPL-2.0+ /* * Implementation of a menu in a scene * * Copyright 2025 Google LLC * Written by Simon Glass <sjg@chromium.org> */ #define LOG_CATEGORY LOGC_EXPO #include <expo.h> #include <log.h> #include <linux/err.h> #include <linux/sizes.h> #include "scene_internal.h" enum { INITIAL_SIZE = SZ_4K, }; int scene_texted(struct scene *scn, const char *name, uint id, uint line_chars, struct scene_obj_txtedit **teditp) { struct scene_obj_txtedit *ted; int ret; ret = scene_obj_add(scn, name, id, SCENEOBJT_TEXTEDIT, sizeof(struct scene_obj_txtedit), (struct scene_obj **)&ted); if (ret < 0) return log_msg_ret("obj", ret); ret = scene_txtin_init(&ted->tin, INITIAL_SIZE, line_chars); if (ret) return log_msg_ret("tin", ret); if (teditp) *teditp = ted; return ted->obj.id; } int scene_txted_set_font(struct scene *scn, uint id, const char *font_name, uint font_size) { struct scene_obj_txtedit *ted; ted = scene_obj_find(scn, id, SCENEOBJT_TEXTEDIT); if (!ted) return log_msg_ret("find", -ENOENT); return scene_txt_set_font(scn, ted->tin.edit_id, font_name, font_size); } int scene_txted_calc_dims(struct scene_obj_txtedit *ted, struct udevice *cons) { const struct expo_theme *theme = &ted->obj.scene->expo->theme; struct scene *scn = ted->obj.scene; struct scene_obj_txt *txt; int x0, ret; txt = scene_obj_find(scn, ted->tin.edit_id, SCENEOBJT_NONE); if (!txt) return log_msg_ret("txt", -ENOENT); /* * Set the edit text's bbox to fit within the textedit's bbox, after * the label. This ensures SCENEOF_SIZE_VALID is set so * vidconsole_measure() applies the width limit for word-wrapping. */ x0 = ted->obj.req_bbox.x0; if (ted->tin.label_id) { int width; ret = scene_obj_get_hw(scn, ted->tin.label_id, &width); if (ret < 0) return log_msg_ret("lab", ret); x0 += width + theme->textline_label_margin_x; } ret = scene_obj_set_bbox(scn, ted->tin.edit_id, x0, ted->obj.req_bbox.y0, ted->obj.req_bbox.x1, ted->obj.req_bbox.y1); if (ret < 0) return log_msg_ret("sbb", ret); /* Measure the edit text now that its bbox is set correctly */ ret = scene_obj_get_hw(scn, ted->tin.edit_id, NULL); if (ret < 0) return log_msg_ret("hw", ret); return 0; } int scene_txted_arrange(struct scene *scn, struct expo_arrange_info *arr, struct scene_obj_txtedit *ted) { struct scene_obj *edit; int x, y; int ret; x = scene_txtin_arrange(scn, arr, &ted->obj, &ted->tin); if (x < 0) return log_msg_ret("arr", x); /* constrain the edit text to fit within the textedit bbox */ y = ted->obj.req_bbox.y0; ret = scene_obj_set_bbox(scn, ted->tin.edit_id, x, y, ted->obj.req_bbox.x1, ted->obj.req_bbox.y1); if (ret < 0) return log_msg_ret("edi", ret); /* Re-measure text with the correct limit (bbox may have changed) */ ret = scene_obj_get_hw(scn, ted->tin.edit_id, NULL); if (ret < 0) return log_msg_ret("hw", ret); edit = scene_obj_find(scn, ted->tin.edit_id, SCENEOBJT_NONE); if (!edit) return log_msg_ret("fnd", -ENOENT); x += edit->dims.x; y += edit->dims.y; /* * Set dims based on content size, but don't call scene_obj_set_size() * as that would overwrite the user-specified req_bbox */ ted->obj.dims.x = x - ted->obj.req_bbox.x0; ted->obj.dims.y = y - ted->obj.req_bbox.y0; return 0; } |