|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
Stateless drawing helpers shared by every screen. More...
Go to the source code of this file.
Data Structures | |
| struct | ui_tile_look_t |
| Where a tile places its parts and in which faces: one look per grid, the menu's and SETUP's. Offsets are in pixels from the tile's top edge. More... | |
| struct | ui_hold_t |
Macros | |
| #define | UI_KEYS_FOOT (UI_ALERT_Y - UI_BAND_H - 4) |
| Where the key grid of the keypad and of the keyboard ends at the latest, in body coordinates: 4px above the alert band, y 492. | |
| #define | UI_TILE_PAD 8 |
| A tile's name and line keep this far from its sides, px. | |
| #define | UI_PILL_INSET 24 |
| #define | UI_TAG_X 8 |
| The home tag's left edge: 8px. | |
| #define | UI_TAG_Y 8 |
| The home tag's top edge: 8px. | |
| #define | UI_TAG_H 44 |
| The home tag's height: 44px (6.6mm). | |
| #define | UI_CHOICE_ROW_H 56 |
| The row height from which a choice face or row draws in the 20 x 36 face: 56px (8.4mm), the plan's choice row. | |
| #define | UI_HOLD_S 2.0f |
| #define | UI_HOLD_MAX_CREDIT_S 0.25f |
| #define | UI_HOLD_FLASH_PHASE_MS 25 |
| The flash as the command goes, by time: phases of UI_HOLD_FLASH_PHASE_MS (25ms) each, white, black, settled, the cycle twice, UI_HOLD_FLASH_MS (150ms) in all: 9 frames at 60Hz. | |
| #define | UI_HOLD_FLASH_CYCLE 3 |
| The phases of one cycle: white, black, settled. | |
| #define | UI_HOLD_FLASH_TIMES 2 |
| The cycles of one flash. | |
| #define | UI_HOLD_FLASH_MS (UI_HOLD_FLASH_PHASE_MS * UI_HOLD_FLASH_CYCLE * UI_HOLD_FLASH_TIMES) |
| The whole flash: 150ms. | |
Functions | |
| void | ui_panel (gfx_canvas_t *c, gfx_rect_t r, const char *title, gfx_color_t accent) |
| void | ui_panel_header (gfx_canvas_t *c, gfx_rect_t r, const char *title, gfx_color_t accent) |
| void | ui_button (gfx_canvas_t *c, gfx_rect_t r, const char *label, gfx_color_t fill, bool pressed, bool enabled) |
| Filled rounded button, its label in UI_FONT_LABEL. | |
| gfx_color_t | ui_button_off_fill (void) |
| The fill of a button that takes no press: the theme's ground (UI_BG), so with its faint label it reads dimmer than an enabled button in the dark theme and in the light one, and differs from every fill an enabled button takes (UI_PANEL, UI_PANEL_HI, UI_PANEL_SUNK, UI_EDGE_HI, an accent). | |
| void | ui_button_font (gfx_canvas_t *c, gfx_rect_t r, const char *label, gfx_color_t fill, bool pressed, bool enabled, const gfx_font_t *f) |
ui_button() with its label in face f. | |
| bool | ui_is_light (gfx_color_t c) |
| bool | ui_text_fits (const gfx_font_t *f, const char *s, int w, int h, int pad) |
Whether s in face f fits a box w x h px with pad px to spare at each side. | |
| const gfx_font_t * | ui_button_face (const char *label, int w, int h, int pad, const gfx_font_t *big, const gfx_font_t *small) |
The face for a button label: big when the label keeps pad px at each side of a w x h px key in it, else small. | |
| void | ui_card (gfx_canvas_t *c, gfx_rect_t r, gfx_color_t fill) |
| int | ui_text_wrap (gfx_canvas_t *c, gfx_rect_t first, int pitch, const char *t, const gfx_font_t *f, gfx_color_t col) |
| void | ui_tile (gfx_canvas_t *c, gfx_rect_t r, const ui_tile_look_t *look, ui_icon_fn icon, const char *name, const char *line, bool pressed) |
| A tile of a grid that opens what it names: the menu's, and SETUP's. | |
| void | ui_pill (gfx_canvas_t *c, gfx_rect_t r, const char *label, gfx_color_t dot, gfx_color_t fill) |
| A status pill in the label face, its label UI_PILL_INSET px in. | |
| void | ui_pill_font (gfx_canvas_t *c, gfx_rect_t r, const char *label, gfx_color_t dot, gfx_color_t fill, int inset, const gfx_font_t *f) |
ui_pill() with the label in face f, inset px from the left edge and centred in the pill's height. | |
| void | ui_pill_ink (gfx_canvas_t *c, gfx_rect_t r, const char *label, gfx_color_t dot, gfx_color_t fill, gfx_color_t ink, int inset, const gfx_font_t *f) |
ui_pill_font() with the label in colour ink, for a fill the theme's text colour does not read on. | |
| void | ui_bar (gfx_canvas_t *c, gfx_rect_t r, float frac, float peak_frac, gfx_color_t color) |
| void | ui_value (gfx_canvas_t *c, gfx_rect_t box, const char *number, const char *unit, gfx_color_t color) |
| void | ui_fmt (char *out, size_t n, float value, int decimals) |
| void | ui_clock (char *out, size_t n, uint32_t seconds) |
| gfx_rect_t | ui_home_tag_rect (const char *title) |
Where the home tag with title is drawn and hit. | |
| void | ui_home_tag (gfx_canvas_t *c, const char *title, bool pressed) |
Draw the home tag: a chevron and title in UI_FONT_TAG. | |
| void | ui_wordmark (gfx_canvas_t *c, const char *text, gfx_color_t fill) |
| The home tag's shape without the chevron: an identity mark, not a control. | |
| void | ui_chevron_left (gfx_canvas_t *c, int x, int cy, int size, gfx_color_t color) |
| void | ui_rule (gfx_canvas_t *c, int x, int y, int w, gfx_color_t color) |
| A 1px horizontal rule. | |
| const gfx_font_t * | ui_choice_font (int h) |
The face a choice face or row h px tall draws its text in. | |
| const gfx_font_t * | ui_choice_text_font (int h, int w, const char *text) |
The face a choice face or row draws text in. | |
| void | ui_choice_face (gfx_canvas_t *c, gfx_rect_t r, const char *text, bool pressed, bool open) |
| void | ui_choice_face_locked (gfx_canvas_t *c, gfx_rect_t r, const char *text) |
| void | ui_choice_list (gfx_canvas_t *c, gfx_rect_t r) |
| The open list's ground: a shadow 4px down and right, then the panel. | |
| void | ui_choice_row (gfx_canvas_t *c, gfx_rect_t r, const char *text, bool chosen, bool pressed) |
| gfx_color_t | ui_hold_fill (gfx_color_t base, gfx_color_t target, float held_s) |
| gfx_color_t | ui_hold_flash (gfx_color_t settled, int ms_left) |
| The fill while the flash runs. | |
| void | ui_hold_reset (ui_hold_t *h) |
| void | ui_hold_begin (ui_hold_t *h) |
| bool | ui_hold_leave (ui_hold_t *h) |
| bool | ui_hold_end (ui_hold_t *h) |
| float | ui_hold_credit (float dt_s) |
| bool | ui_hold_tick (ui_hold_t *h, float dt_s) |
| void | ui_hold_reached (ui_hold_t *h) |
| bool | ui_hold_left (ui_hold_t *h) |
| void | ui_hold_flash_step (ui_hold_t *h, float dt_s) |
| Time passed for the flash. | |
| int | ui_hold_flash_left (int ms_left, float dt_s) |
The flash's time left, ms_left, after dt_s seconds. | |
Stateless drawing helpers shared by every screen.
Every call takes explicit geometry and draws immediately. There is no retained widget tree: on this hardware the cost is in touching framebuffer pixels, and a retained tree touches them more often.
SPDX-License-Identifier: MIT
| #define UI_KEYS_FOOT (UI_ALERT_Y - UI_BAND_H - 4) |
Where the key grid of the keypad and of the keyboard ends at the latest, in body coordinates: 4px above the alert band, y 492.
An overlay paints its whole area; its keys end here when the area reaches further, so an alert covers no key on any screen.
| #define UI_PILL_INSET 24 |
Small status pill: a filled dot, then a label UI_PILL_INSET px from the pill's left edge, the dot centred half that from it.
| void ui_bar | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| float | frac, | ||
| float | peak_frac, | ||
| gfx_color_t | color ) |
Horizontal proportional bar, frac in 0..1, with an optional peak tick.
| void ui_button | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | label, | ||
| gfx_color_t | fill, | ||
| bool | pressed, | ||
| bool | enabled ) |
Filled rounded button, its label in UI_FONT_LABEL.
| c | Canvas. |
| r | The button. |
| label | Its label, centred, or NULL for none. |
| fill | Its colour while enabled. |
| pressed | Lightens the fill. |
| enabled | False draws it in ui_button_off_fill() with a dim edge and a faint label. |
| const gfx_font_t * ui_button_face | ( | const char * | label, |
| int | w, | ||
| int | h, | ||
| int | pad, | ||
| const gfx_font_t * | big, | ||
| const gfx_font_t * | small ) |
The face for a button label: big when the label keeps pad px at each side of a w x h px key in it, else small.
| label | The label; NULL is the empty text. |
| w | The key's width, in pixels. |
| h | The key's height, in pixels. |
| pad | The room to keep left and right of the label, in pixels. |
| big | The face used when it fits. |
| small | The face used when big leaves less than pad px. |
big or small. | void ui_button_font | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | label, | ||
| gfx_color_t | fill, | ||
| bool | pressed, | ||
| bool | enabled, | ||
| const gfx_font_t * | f ) |
ui_button() with its label in face f.
| c | Canvas. |
| r | The button. |
| label | Its label, centred, or NULL for none. |
| fill | Its colour. |
| pressed | Lightens the fill. |
| enabled | False dims it. |
| f | The label's face. |
| gfx_color_t ui_button_off_fill | ( | void | ) |
The fill of a button that takes no press: the theme's ground (UI_BG), so with its faint label it reads dimmer than an enabled button in the dark theme and in the light one, and differs from every fill an enabled button takes (UI_PANEL, UI_PANEL_HI, UI_PANEL_SUNK, UI_EDGE_HI, an accent).
| void ui_card | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| gfx_color_t | fill ) |
A raised surface with a hairline edge: the base of every panel.
| void ui_chevron_left | ( | gfx_canvas_t * | c, |
| int | x, | ||
| int | cy, | ||
| int | size, | ||
| gfx_color_t | color ) |
Left-pointing solid triangle, apex at (x, cy).
| void ui_choice_face_locked | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | text ) |
The face of a choice that takes no press now, as ui_tabs_render_locked() draws a segment row: sunk, its text and chevron dim, no accent.
| const gfx_font_t * ui_choice_font | ( | int | h | ) |
The face a choice face or row h px tall draws its text in.
| h | The face's or the row's height, in pixels. |
| void ui_choice_list | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r ) |
The open list's ground: a shadow 4px down and right, then the panel.
| c | the canvas |
| r | the list's box |
| void ui_choice_row | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | text, | ||
| bool | chosen, | ||
| bool | pressed ) |
One row of the open list: chosen is the choice in force, accented.
| const gfx_font_t * ui_choice_text_font | ( | int | h, |
| int | w, | ||
| const char * | text ) |
The face a choice face or row draws text in.
| h | The face's or the row's height, in pixels. |
| w | The width its text may take, in pixels. |
| text | The text; NULL is the empty text. |
h) when text fits w in it, else UI_FONT_HEAD (16 x 28). | void ui_clock | ( | char * | out, |
| size_t | n, | ||
| uint32_t | seconds ) |
Run clock as H:MM:SS, or MM:SS below an hour.
Shared so every screen prints the same number the same way.
| void ui_fmt | ( | char * | out, |
| size_t | n, | ||
| float | value, | ||
| int | decimals ) |
Format value with decimals decimal places (0 to 3); a non-finite value prints as "--".
| void ui_hold_begin | ( | ui_hold_t * | h | ) |
A press landed on the control: the hold starts from zero.
| float ui_hold_credit | ( | float | dt_s | ) |
What one frame is worth to a hold: dt_s, capped at UI_HOLD_MAX_CREDIT_S and floored at zero. Used by ui_hold_tick() and by any screen that keeps its own hold timer, so a late frame cannot complete a gesture that began inside it.
| bool ui_hold_end | ( | ui_hold_t * | h | ) |
The press lifted. Returns whether it was the press that fired, which the release consumes: a release that fired is not also a press.
| gfx_color_t ui_hold_fill | ( | gfx_color_t | base, |
| gfx_color_t | target, | ||
| float | held_s ) |
The fill for a button held held_s of UI_HOLD_S, fading base to target. held_s of 0 is base; the fade previews the colour the button is about to hold.
| gfx_color_t ui_hold_flash | ( | gfx_color_t | settled, |
| int | ms_left ) |
The fill while the flash runs.
150ms in all is short enough to read as a flash rather than an animation. The colour follows the time the flash has run, not the frames drawn: a frame later than a phase (25ms) skips that phase.
| settled | What the fill returns to: the settled phase and the end. |
| ms_left | The flash's time still to run, counting down from UI_HOLD_FLASH_MS; 0 or less is no flash. |
settled. | int ui_hold_flash_left | ( | int | ms_left, |
| float | dt_s ) |
The flash's time left, ms_left, after dt_s seconds.
One step goes no further than the start of the next phase, so every phase is drawn on at least one frame at any frame rate: at 10 frames a second the flash takes 6 frames, 600ms, instead of skipping phases.
| ms_left | The time left, in ms. |
| dt_s | The time passed, in seconds; under 0 counts as 0. |
| void ui_hold_flash_step | ( | ui_hold_t * | h, |
| float | dt_s ) |
Time passed for the flash.
The first step after ui_hold_reached() spends nothing, so the frame the flash starts on draws its first phase whatever the order of the reach and the step in a tick.
| h | The hold. |
| dt_s | The time, in seconds; the flash's time left falls by it as ui_hold_flash_left() spends it. |
| bool ui_hold_leave | ( | ui_hold_t * | h | ) |
The press left the control, so the gesture is over: contact with the control is the gesture, not contact with the panel. Sliding back on does not resume it. Returns whether a hold was actually abandoned, which is what tells the screen to drop its own record of the press.
| bool ui_hold_left | ( | ui_hold_t * | h | ) |
What the hold asked for has gone away – a stop, a failsafe, or the far end – possibly under a finger that is still down.
Both halves of the gesture end here. A press left standing would start a fresh hold the moment the state went away and ask for it again, from a contact the operator made to stop it. Returns whether such a press was ended, so the screen can drop its own record of it; clearing the press without fired would strand it, because the release consumes fired and a release of a press that is no longer held does nothing.
| void ui_hold_reached | ( | ui_hold_t * | h | ) |
What the hold asked for has arrived: flash, and stop filling.
fired is deliberately kept. It remembers that the press still under the finger is the one that fired, and the application calls this between the hold completing and the finger lifting; clearing it would make that release look like a fresh press.
| void ui_hold_reset | ( | ui_hold_t * | h | ) |
Nothing held, nothing fired, nothing flashing.
| bool ui_hold_tick | ( | ui_hold_t * | h, |
| float | dt_s ) |
Time passed. True on the one frame the hold completes, and never again until the press is lifted and made afresh.
| void ui_home_tag | ( | gfx_canvas_t * | c, |
| const char * | title, | ||
| bool | pressed ) |
Draw the home tag: a chevron and title in UI_FONT_TAG.
| c | The canvas, the panel's. |
| title | The screen's name. |
| pressed | A press is on it: the fill lightens. |
| gfx_rect_t ui_home_tag_rect | ( | const char * | title | ) |
Where the home tag with title is drawn and hit.
| title | The screen's name. |
| bool ui_is_light | ( | gfx_color_t | c | ) |
True when c is bright enough to need dark text on it.
| void ui_panel | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | title, | ||
| gfx_color_t | accent ) |
Panel with a chamfered top-left / bottom-right, 1px edge, optional title.
| void ui_panel_header | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | title, | ||
| gfx_color_t | accent ) |
The title strip a panel draws for itself; exposed for custom headers.
| void ui_pill | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | label, | ||
| gfx_color_t | dot, | ||
| gfx_color_t | fill ) |
A status pill in the label face, its label UI_PILL_INSET px in.
| c | The canvas. |
| r | The pill. |
| label | Its label; NULL draws the dot alone. |
| dot | The dot's colour. |
| fill | The pill's fill. |
| void ui_pill_font | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | label, | ||
| gfx_color_t | dot, | ||
| gfx_color_t | fill, | ||
| int | inset, | ||
| const gfx_font_t * | f ) |
ui_pill() with the label in face f, inset px from the left edge and centred in the pill's height.
| c | Canvas. |
| r | The pill. |
| label | Its label, or NULL for none. |
| dot | The dot's colour. |
| fill | The pill's colour. |
| inset | The label's start from the pill's left edge, in pixels; the dot is centred half that from it. |
| f | The label's face. |
| void ui_pill_ink | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const char * | label, | ||
| gfx_color_t | dot, | ||
| gfx_color_t | fill, | ||
| gfx_color_t | ink, | ||
| int | inset, | ||
| const gfx_font_t * | f ) |
ui_pill_font() with the label in colour ink, for a fill the theme's text colour does not read on.
| c | Canvas. |
| r | The pill. |
| label | Its label, or NULL for none. |
| dot | The dot's colour. |
| fill | The pill's colour. |
| ink | The label's colour. |
| inset | The label's start from the pill's left edge, in pixels. |
| f | The label's face. |
| void ui_rule | ( | gfx_canvas_t * | c, |
| int | x, | ||
| int | y, | ||
| int | w, | ||
| gfx_color_t | color ) |
A 1px horizontal rule.
| c | the canvas |
| x | its left end, px |
| y | its row, px |
| w | its length, px |
| color | its colour |
| bool ui_text_fits | ( | const gfx_font_t * | f, |
| const char * | s, | ||
| int | w, | ||
| int | h, | ||
| int | pad ) |
Whether s in face f fits a box w x h px with pad px to spare at each side.
The overlays pick the largest face of the type scale a label fits: a key of the keypad or the keyboard over a narrow host card takes a smaller face rather than overflow.
| f | The face; NULL fits nothing. |
| s | The text; NULL is the empty text. |
| w | The box's width, in pixels. |
| h | The box's height, in pixels: at least the face's cell height. |
| pad | The room to keep left and right of the text, in pixels. |
pad is at most w and the face's height at most h. | int ui_text_wrap | ( | gfx_canvas_t * | c, |
| gfx_rect_t | first, | ||
| int | pitch, | ||
| const char * | t, | ||
| const gfx_font_t * | f, | ||
| gfx_color_t | col ) |
t broken at spaces into lines as wide as first, each drawn left aligned in a box of first's size, pitch px under the one before. A word wider than a line is cut where the line ends. Draws when c is not NULL and returns the number of lines either way, 0 for an empty t, so a caller measures with the code that draws.
| void ui_tile | ( | gfx_canvas_t * | c, |
| gfx_rect_t | r, | ||
| const ui_tile_look_t * | look, | ||
| ui_icon_fn | icon, | ||
| const char * | name, | ||
| const char * | line, | ||
| bool | pressed ) |
A tile of a grid that opens what it names: the menu's, and SETUP's.
A rounded surface, icon in a square box placed by look, centred in x, the name under it in the text colour and the line under the name in the dim one, both centred and clipped to the tile less UI_TILE_PAD px on either side. A line wider than that breaks at the last space that fits onto a second row look->line_pitch px lower, where line_pitch is not 0 and that row ends inside the tile; a line with no such space or no such row is clipped.
| c | Canvas. |
| r | The tile. |
| look | Where its parts go and their faces. |
| icon | Its icon, or NULL for none. |
| name | Its name, or NULL for none. |
| line | The line under the name, or NULL for none. |
| pressed | Lightens the surface. |
| void ui_value | ( | gfx_canvas_t * | c, |
| gfx_rect_t | box, | ||
| const char * | number, | ||
| const char * | unit, | ||
| gfx_color_t | color ) |
Right-aligned numeric readout in the hero face, with a unit suffix.
| void ui_wordmark | ( | gfx_canvas_t * | c, |
| const char * | text, | ||
| gfx_color_t | fill ) |
The home tag's shape without the chevron: an identity mark, not a control.
| c | The canvas, the panel's. |
| text | The mark's text, in UI_FONT_TAG: near-black on a light fill, the theme's panel colour on a dark one. |
| fill | The mark's fill. |