]> Git Repo - J-u-boot.git/blob - doc/develop/expo.rst
expo: Add spacing around menus and items
[J-u-boot.git] / doc / develop / expo.rst
1 .. SPDX-License-Identifier: GPL-2.0+
2
3 Expo menu
4 =========
5
6 U-Boot provides a menu implementation for use with selecting bootflows and
7 changing U-Boot settings. This is in early stages of development.
8
9 Motivation
10 ----------
11
12 U-Boot already has a text-based menu system accessed via the
13 :doc:`../usage/cmd/bootmenu`. This works using environment variables, or via
14 some EFI-specific hacks.
15
16 The command makes use of a lower-level `menu` implementation, which is quite
17 flexible and can be used to make menu hierarchies.
18
19 However this system is not flexible enough for use with standard boot. It does
20 not support a graphical user interface and cannot currently support anything
21 more than a very simple list of items. While it does support multiple menus in
22 hierarchies, these are implemented by the caller. See for example `eficonfig.c`.
23
24 Another challenge with the current menu implementation is that it controls
25 the event loop, such that bootmenu_loop() does not return until a key is
26 pressed. This makes it difficult to implement dynamic displays or to do other
27 things while the menu is running, such as searching for more bootflows.
28
29 For these reasons an attempt has been made to develop a more flexible system
30 which can handle menus as well as other elements. This is called 'expo', short
31 for exposition, in an attempt to avoid common words like display, screen, menu
32 and the like. The primary goal is to support Verified Boot for Embedded (VBE),
33 although it is available to any boot method, using the 'bootflow menu' command.
34
35 Efforts have been made to use common code with the existing menu, including
36 key processing in particular.
37
38 Previous work looked at integrating Nuklear into U-Boot. This works fine and
39 could provide a way to provide a more flexible UI, perhaps with expo dealing
40 with the interface to Nuklear. But this is quite a big step and it may be years
41 before this becomes desirable, if at all. For now, U-Boot only needs a fairly
42 simple set of menus and options, so rendering them directly is fairly
43 straightforward.
44
45 Concepts
46 --------
47
48 The creator of the expo is here called a `controller` and it controls most
49 aspects of the expo. This is the code that you must write to use expo.
50
51 An `expo` is a set of scenes which can be presented to the user one at a time,
52 to show information and obtain input from the user.
53
54 A `scene` is a collection of objects which are displayed together on the screen.
55 Only one scene is visible at a time and scenes do not share objects.
56
57 A `scene object` is something that appears in the scene, such as some text, an
58 image or a menu. Objects can be positioned and hidden.
59
60 A `menu object` contains a title, a set of `menu items` and a pointer to the
61 current item. Menu items consist of a keypress (indicating what to press to
62 select the item), label and description. All three are shown in a single line
63 within the menu. Items can also have a preview image, which is shown when the
64 item is highlighted.
65
66 All components have a name. This is purely for debugging, so it is easy to see
67 what object is referred to. Of course the ID numbers can help as well, but they
68 are less easy to distinguish.
69
70 While the expo implementation provides support for handling keypresses and
71 rendering on the display or serial port, it does not actually deal with reading
72 input from the user, nor what should be done when a particular menu item is
73 selected. This is deliberate since having the event loop outside the expo is
74 more flexible, particularly in a single-threaded environment like U-Boot.
75
76 Everything within an expo has a unique ID number. This is done so that it is
77 easy to refer to things after the expo has been created. The expectation is that
78 the controller declares an enum containing all of the elements in the expo,
79 passing the ID of each object as it is created. When a menu item is selected,
80 its ID is returned. When a object's font or position needs to change, the ID is
81 passed to expo functions to indicate which object it is. It is possible for expo
82 to auto-allocate IDs, but this is not recommended. The use of IDs is a
83 convenience, removing the need for the controller to store pointers to objects,
84 or even the IDs of objects. Programmatic creation of many items in a loop can be
85 handled by allocating space in the enum for a maximum number of items, then
86 adding the loop count to the enum values to obtain unique IDs.
87
88 Where dynamic IDs are need, use expo_set_dynamic_start() to set the start value,
89 so that they are allocated above the starting (enum) IDs.
90
91 All text strings are stored in a structure attached to the expo, referenced by
92 a text ID. This makes it easier at some point to implement multiple languages or
93 to support Unicode strings.
94
95 Menu objects do not have their own text and image objects. Instead they simply
96 refer to objects which have been created. So a menu item is just a collection
97 of IDs of text and image objects. When adding a menu item you must create these
98 objects first, then create the menu item, passing in the relevant IDs.
99
100 Creating an expo
101 ----------------
102
103 To create an expo, use `expo_new()` followed by `scene_new()` to create a scene.
104 Then add objects to the scene, using functions like `scene_txt_str()` and
105 `scene_menu()`. For every menu item, add text and image objects, then create
106 the menu item with `scene_menuitem()`, referring to those objects.
107
108 Layout
109 ------
110
111 Individual objects can be positioned using `scene_obj_set_pos()`. Menu items
112 cannot be positioned manually: this is done by `scene_arrange()` which is called
113 automatically when something changes. The menu itself determines the position of
114 its items.
115
116 Rendering
117 ---------
118
119 Rendering is performed by calling `expo_render()`. This uses either the
120 vidconsole, if present, or the serial console in `text mode`. Expo handles
121 presentation automatically in either case, without any change in how the expo is
122 created.
123
124 For the vidconsole, Truetype fonts can be used if enabled, to enhance the
125 quality of the display. For text mode, each menu item is shown in a single line,
126 allowing easy selection using arrow keys.
127
128 Input
129 -----
130
131 The controller is responsible for collecting keyboard input. A good way to do
132 this is to use `cli_ch_process()`, since it handles conversion of escape
133 sequences into keys. However, expo has some special menu-key codes for
134 navigating the interface. These are defined in `enum bootmenu_key` and include
135 `BKEY_UP` for moving up and `BKEY_SELECT` for selecting an item. You can use
136 `bootmenu_conv_key()` to convert an ASCII key into one of these.
137
138 Once a keypress is decoded, call `expo_send_key()` to send it to the expo. This
139 may cause an update to the expo state and may produce an action.
140
141 Actions
142 -------
143
144 Call `expo_action_get()` in the event loop to check for any actions that the
145 expo wants to report. These can include selecting a particular menu item, or
146 quitting the menu. Processing of these is the responsibility of your controller.
147
148 Event loop
149 ----------
150
151 Expo is intended to be used in an event loop. For an example loop, see
152 `bootflow_menu_run()`. It is possible to perform other work in your event loop,
153 such as scanning devices for more bootflows.
154
155 Themes
156 ------
157
158 Expo supports simple themes, for setting the font size, for example. Use the
159 expo_apply_theme() function to load a theme, passing a node with the required
160 properties:
161
162 font-size
163     Font size to use for all text (type: u32)
164
165 menu-inset
166     Number of pixels to inset the menu on the sides and top (type: u32)
167
168 menuitem-gap-y
169     Number of pixels between menu items
170
171
172 API documentation
173 -----------------
174
175 .. kernel-doc:: include/expo.h
176
177 Future ideas
178 ------------
179
180 Some ideas for future work:
181
182 - Default menu item and a timeout
183 - Higher-level / automatic / more flexible layout of objects
184 - Image formats other than BMP
185 - Use of ANSI sequences to control a serial terminal
186 - Colour selection
187 - Better support for handling lots of settings, e.g. with radio/option widgets
188 - Mouse support
189 - Integrate Nuklear, NxWidgets or some other library for a richer UI
190 - Optimise rendering by only updating the display with changes since last render
191 - Use expo to replace the existing menu implementation
192 - Add a Kconfig option to drop the names to save code / data space
193 - Add a Kconfig option to disable vidconsole support to save code / data space
194 - Support both graphical and text menus at the same time on different devices
195 - Support unicode
196 - Support curses for proper serial-terminal menus
197
198 .. Simon Glass <[email protected]>
199 .. 7-Oct-22
This page took 0.039728 seconds and 4 git commands to generate.