Commit Graph

85 Commits

Author SHA1 Message Date
Simon Glass
3e75f480ef expo: Always send keys to highlighted textline
Move textline key handling outside the loop so keys are always sent
to the highlighted textline, regardless of whether it is open. This
allows the textline to respond to keyboard input even if not in a popup
expo.

Otherwise continue to send keys to menus as now.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-07 11:57:04 -07:00
Simon Glass
7c059e682e expo: Add scene_render_obj() to render by object ID
Add a function to render a single object by its ID. This provides a
convenient way to render individual objects without needing to look up
the object pointer first.

Assume that text mode is not used.

Co-developed-by: Claude <claude@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-07 11:53:55 -07:00
Simon Glass
ce66b13ea3 expo: Refactor scene_send_key() to use a current object
The highlight_id needs to be considered for non-popup expos as well. As
a first step, use the variable 'cur' for the current object, i.e. the
one that is highlighted.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-07 11:53:55 -07:00
Simon Glass
8b54227528 expo: Allow entering text into textline in non-popup expos
Currently textlines only support text entry when with popup expos. In
some cases we want to have menu items to support this, e.g. to enter a
passphrase to unlock an encrypted disk.

Add the missing logic.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-11-14 12:00:31 -07:00
Simon Glass
6926f89a20 expo: Support hiding password entry
Some fields may have sensitive information. Allow it to be obscured
during entry, in case someone is watching the display nearby.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-11-14 12:00:31 -07:00
Simon Glass
bea3b16617 expo: Avoid setting SCENEOF_SIZE_VALID with menu items
The font size of menu items might change, thus requiring the size to
be updated. So it is not correct to mark the items as fixed size.

Drop this code.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-14 10:57:31 +01:00
Simon Glass
dd14a85c36 expo: Avoid setting SCENEOF_SIZE_VALID with calculated size
When the size of an object is calculated from its contents, we should
not set the SCENEOF_SIZE_VALID flag. This flag prevents the object from
resizing if the font is changed, for example. The flag is intended to
mean that the size was explicitly set by the controller, so we should
generally not set it in the expo implementation.

It is also inefficient to search for the object ID when we already
have the object.

Update scene_set_default_bbox() to just set the size and request that
it be synced.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-14 10:57:31 +01:00
Simon Glass
47e05ed19e expo: Support clicking on any type of object
It is sometimes useful to be able to click on an image (sometimes called
an icon). Allow this within expo and return new click action.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-10 03:11:18 +01:00
Simon Glass
92cc80eab9 expo: Allow searching for any object type by position
At present only highlightable objects can be clicked on, i.e. menus and
textlines. Update scene_find_obj_within() so that it can find any type
of object, if requested. Update all the callers to false, so things work
the same.

Since the scene is drawn by iterating through the list of objects, when
the user clicks somewhere we should look at the top-most object under
the mouse first. So reverse the direction of the object search.

Update the tests to cover this new feature.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-10 03:11:12 +01:00
Simon Glass
d221a4178c expo: Allow searching click positions from top to bottom
Since the scene is drawn by iterating through the list of objects, when
the user clicks somewhere we should look at the top-most object under
the mouse first.

This is not true when a menu is popped up, since we only care about the
menu in that case.

Add a way to reverse the direction of the object search. For now there
are no new test cases, since OBJ_OVERLAP is a text object and cannot
currently be clicked on.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-10 03:10:42 +01:00
Simon Glass
4d4caecd26 expo: Export scene_find_obj_within() and add a test
It is easier to test this function directly than via click_check(). Set up
a test expo with an extra overlapping object and add some tests.

Update the existing render test to take account of the new object.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-10 03:10:36 +01:00
Simon Glass
9480aff0b5 expo: Provide a version of scene_within() with takes an obj
When the object pointer is already available we don't want to have to
look it up. Provide a new is_within() function which takes an object
pointer instead of an ID.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-10 02:24:07 +01:00
Simon Glass
9c11744488 expo: Provide user-friendly output of scene enums
Add a few functions which can convert a flag and an object type to
strings.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-10 02:24:07 +01:00
Simon Glass
56f7bf5ed8 expo: Add selective rendering for dirty objects in scene
Support rendering only the dirty objects in a scene.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-06 10:11:05 -06:00
Simon Glass
5484c25772 expo: Add a way to calculate the bbox of dirty objects
When rendering an expo we should normally only need to draw the objects
which are marked dirty. Add a way to calculate the bounding box of
these.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-06 10:11:05 -06:00
Simon Glass
f2909a4cde expo: Set dirty flag when an object bbox changes
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>
2025-10-06 10:11:04 -06:00
Simon Glass
3e8147c8e4 expo: Drop struct scene_obj_bbox in favour of vid_bbox
Replace the scene_obj_bbox with the common vid_bbox structure to avoid
having the same structs with different names.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-06 10:04:36 -06:00
Simon Glass
0efc5f0ffc expo: Allow manual positioning of menu items
Sometimes we want to position items individually rather than relying on
the automatic scene layout. Provide a flag for this, expanding the type
to cope.

Also add an assertion that the flags fit in the available space.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-09-25 09:47:09 -06:00
Simon Glass
f5ec16dbea expo: Support sending a click to a scene
Implement clicking on an object in the scene. For now only menus and
textlines respond to this. For menus the behaviour is different for
popups than for normal menus.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-09-15 13:23:12 -06:00
Simon Glass
9d34fbe2e8 expo: Allow checking if a position is within a textline
For a textline it is possible to click into the edit field. Provide a
function to check whether a position is within this field.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-09-15 13:23:12 -06:00
Simon Glass
1e65b5e22e expo: Provide a way to check if a position is within a menu
To implement mouse clicks we need a way to figure out what the user has
clicked on. As a starting point, create a scene_menu_within() function
which returns the item containing an x, y coordinate.

Provide a helper function in scene.c for use with this. Add a simple
for completeness.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-09-15 13:23:12 -06:00
Simon Glass
e3e1b7aeb2 expo: Tidy up a few key-related comments
Fix up send_key_obj() to mention a missing argument. Add a bit more
detail in scene_send_key() to explain what 'processing' means.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-09-15 13:23:12 -06:00
Simon Glass
9f3b86c8f6 expo: Support boxes fully
At present boxes are not supported in the expo_build format. Also, it is
now possible to draw filled boxes, a recently added feature to the video
API.

Expand the box feature slightly to resolve these two items.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-09-15 13:23:12 -06:00
Simon Glass
f4b0561e8a expo: Guard against a crash in scene_textline_calc_dims()
If there is no console (e.g. in a test) this function segfaults. Add
the console as a parameter so it is clear that it is needed. Check for
it in the caller.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-09-15 13:23:12 -06:00
Simon Glass
9fa8a01d50 video: Support drawing filled boxes
At present only an outline boxes is supported, albeit with a thickness
parameter. Provide a way to draw a filled rectangle.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-09-15 13:23:12 -06:00
Simon Glass
2b226cb9e7 expo: Allow changing scene_img data
In some cases we want to change the image data used by a scene_img. Add
a function to handle this.

Adjust the BMP function to use a const for the data, since it is not
allowed to change it.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-06-05 13:59:50 -06:00
Simon Glass
e27b36c015 expo: Tidy up insets and improve tests
Insets are handled inconsistently at present, since menus use them to
offset the label text, whereas textlines don't. This is done because
menus need the margin to be visible when opened. However this causes an
alignment issue when menus and textlines appear in the same cedit.

Remove the offsets from menus and compensate by adjusting the bounding
boxes used for highlighting and the opened menu.

Line up menu items and textlines vertically and add a style option for
textlines to control how much padding is added.

Add a test to check the positions of objects in a cedit, since this is
more direct than the rendering tests. Add style information so that the
impact can be seen.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-24 08:19:02 +01:00
Simon Glass
44ac51e503 expo: Separate requested bbox from actual
With fixed coordinates it is difficult to create scenes that can work on
any display size. Add a separate 'requested' bounding box for each
object and sync it when required.

With future work, this will allow scaling the nominal coordinates so
that an expo can be rendered correctly on a wider range of displays.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-24 08:19:02 +01:00
Simon Glass
8441847f9f expo: Check dimensions before arranging a scene
It is possible that positions, styling or even text have changed since
the scene was initially arranged, so recalculate the dimensions of all
objects before arranging the scene.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-24 08:19:01 +01:00
Simon Glass
a6ec4daf24 expo: Move menu dims calculations into scene_menu_arrange()
A menu's dimensions are currently only used for positioning the
component parts of the menu, i.e. the label, key, description and
preview.

Move the logic for this entirely into the scene_menu file and drop the
logic at the top level.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-24 08:19:01 +01:00
Simon Glass
bd5e1e62e8 expo: Provide a few functions for working with dimensions
Allow expanding dimensions using the dimensions of an object or another
dimensions struct.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-24 08:19:01 +01:00
Simon Glass
3434950961 expo: Drop the extra parameter to scene_calc_dims()
We always call this with false first, then true. Drop the parameter and
handle this within the function itself.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-24 08:19:01 +01:00
Simon Glass
817db7d12d expo: Avoid arranging the scene willy nilly
Moving from one scene to another should not result in the scene being
re-arranged. Drop this, so that tests can have more control of when
scenes are arranged.

Also drop the scene_arrange() call when applying a theme, for the same
reason.

Add the now-required scene_arrange() to cedit and bootmenu

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-24 08:19:01 +01:00
Simon Glass
c0df894714 expo: Provide a way to position things relative to display
It is often necessary to centre objects within the display area. Add a
special position value to indicate this.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:52 -06:00
Simon Glass
5214728e0b expo: Support highlighting menu items
Expo normally uses a pointer to show the current item. Add support for
highlighting as well, since this makes it easier for the user to see the
current item.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:52 -06:00
Simon Glass
c256ad374f expo: Begin implementation of a text editor
It is useful to be able to edit text, e.g. to allow the user to edit the
environment or the command-line arguments for the OS.

Add the beginnings of an implementation. Future work is needed to finish
this: keypress handling and scrolling. For now it just displays the
text.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:52 -06:00
Simon Glass
eb84e601b3 expo: Support object alignment
Add support for left, right and centred alignment for text, in the
horizontal dimension.

Also support top, bottom and centred in the vertical dimension, for the
text object as a whole.

Alignment is not yet implemented for images. It has no meaning for
menus. A textline object uses a text object internally, so alignment
is supported there.

Provide some documentation to explain how objects are positioned.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:52 -06:00
Simon Glass
59f4889d42 expo: Implement a box
It is useful to be able to draw a box around elements in the menu. Add
support for an unfilled box with a selectable thickness.

Note that there is no support for selecting the colour for any expo
objects yet.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:52 -06:00
Simon Glass
a2d70450dd expo: Support rendering multiple lines of text
Use the measurement info to write each line of text separately, thus
respecting word-wrapping and newlines.

Fix up the comment for scene_obj_render() while we are here.

Since a lineedit does not support alignment, add a special case to just
display the text if there is no measurement. This happens assuming the
lineedit is initially empty.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:52 -06:00
Simon Glass
eed9bc702a expo: Tidy up scene_txt_render()
Add an early return if there is no string. Move all declarations to the
top of the function.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:51 -06:00
Simon Glass
222f0ed473 expo: Move text-rendering into its own function
The code to render text is quite long, so put it in its own function.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:51 -06:00
Simon Glass
b12300aa80 expo: Create a struct for generic text attributes
In preparation for adding more text types, refactor the common fields
into a new structure. This will allow common code to be used.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:51 -06:00
Simon Glass
dc3e8f2a82 expo: Support setting the size and bounds of an object
Add a function to allow the size of an object to be set independently
of its position.

Also add a function to permit the object's bounding box to be set
independently of its dimensions.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:51 -06:00
Simon Glass
6e169237d2 expo: Make bounding-box calculation more flexible
In some cases it is useful to obtain more than just two bounding boxes
from a menu, e.g. to line up all descriptions vertically.

Use an array to obtain bounding-box information and calculate it
separately for each item.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:51 -06:00
Simon Glass
8d4237592a expo: Separate dimensions from the bounding box
At present each object has a width and height and the bounding box is
implicit in that.

This is not flexible enough to handle objects which are larger than
their contents might need. For example, when centring a text object we
might want to have it stretch across the whole width of the display even
if the text itself does not need that much space.

Create a new 'dimensions' field and convert the existing width/height
into x1/y1 coordinates.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:51 -06:00
Simon Glass
6e1bc5458a expo: Rename x and y in struct scene_obj_bbox
These coordinates are the top left values, so rename them to x0 and y0
in preparation for changing the width and height to x1 and y1

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:51 -06:00
Simon Glass
bddff11f93 expo: Rename scene_dim to scene_obj_bbox
At present we assume that each object is a simple box and that it fills
the whole box.

This is quite limiting for text objects, which we may want to centre
within the box. We need a position within the box where drawing starts.

Rename the scene_dim struct to indicate that it is a bounding box.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:51 -06:00
Simon Glass
45dc64e095 abuf: Add a helper for initing and allocating a buffer
This construct appears in various places. Reduce code size by adding a
function for it.

It inits the abuf, then allocates it to the requested size.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-02 09:45:30 -06:00
Simon Glass
3a9da4f932 video: truetype: Support a limit on the width of a line
Expo needs to be able to word-wrap lines so that they are displayed as
the user expects. Add a limit on the width of each line and support this
in the measurement algorithm.

Add a log category to truetype while we are here.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-01 17:31:39 -06:00
Simon Glass
30ad08e2c0 video: Begin support for measuring multiple lines of text
Update the vidconsole API so that measure() can measure multiple lines
of text. This will make it easier to implement multi-line fields in
expo.

Tidy up the function comments while we are here.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-05-01 17:31:39 -06:00