|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Zero-heap composable widget layer (dwm-style) over ra8_box + ra8_ui. More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_widget_event_t |
| One input event delivered to ra8_widget_dispatch. More... | |
| struct | ra8_widget_vtable_t |
| Behaviour table shared by all widgets of one kind. More... | |
| struct | ra8_widget |
| struct | ra8_widget_panel |
| struct | ra8_widget_paint |
| struct | ra8_widget_label |
| struct | ra8_widget_button |
Typedefs | |
| typedef struct ra8_widget | ra8_widget_t |
| typedef struct ra8_widget_panel | ra8_widget_panel_t |
| typedef struct ra8_widget_paint | ra8_widget_paint_t |
| typedef struct ra8_widget_label | ra8_widget_label_t |
| typedef struct ra8_widget_button | ra8_widget_button_t |
Enumerations | |
| enum | ra8_widget_ev_kind_t : uint8_t { k_ra8_widget_ev_touch = 0U , k_ra8_widget_ev_button = 1U } |
| Input event kind routed to widgets. More... | |
| enum | ra8_widget_refresh_t : uint8_t { k_ra8_widget_refresh_none = 0U , k_ra8_widget_refresh_fast = 1U , k_ra8_widget_refresh_quality = 2U } |
| E-ink-style refresh hint carried by a dirty widget. More... | |
| enum | ra8_widget_axis_t : uint8_t { k_ra8_widget_axis_col = 0U , k_ra8_widget_axis_row = 1U } |
| Main axis a container stacks its children along. More... | |
| enum | ra8_widget_align_t : uint8_t { k_ra8_widget_align_left = 0U , k_ra8_widget_align_center = 1U , k_ra8_widget_align_right = 2U } |
| Horizontal placement of a leaf widget's text within its rect. More... | |
Functions | |
| ra8_err_t | ra8_widget_layout_stack (ra8_widget_t *widgets, uint16_t count, const ra8_ui_rect_t *frame, ra8_widget_axis_t axis, int16_t gap, int16_t pad, ra8_box_t *box_scratch, uint16_t box_cap) |
| Lay a stack of widgets out inside a frame (delegates to ra8_box). | |
| ra8_err_t | ra8_widget_dispatch (ra8_widget_t *widgets, uint16_t count, const ra8_widget_event_t *ev, bool *out_handled) |
| Route an event to the widget that should handle it. | |
| ra8_err_t | ra8_widget_invalidate (ra8_widget_t *w, ra8_widget_refresh_t refresh) |
| Mark a widget dirty with a refresh hint (folds upward in strength). | |
| ra8_err_t | ra8_widget_damage (const ra8_widget_t *widgets, uint16_t count, ra8_ui_rect_t *out_rect, ra8_widget_refresh_t *out_hint, uint16_t *out_count) |
| Compute the minimal damage rectangle + refresh hint to flush. | |
| ra8_err_t | ra8_widget_render_dirty (ra8_widget_t *widgets, uint16_t count) |
| Render every visible + dirty widget, clearing its damage. | |
| const ra8_widget_vtable_t * | ra8_widget_panel_vtable (void) |
| Return the shared vtable that every container panel uses. | |
| ra8_err_t | ra8_widget_panel_init (ra8_widget_t *w, ra8_widget_panel_t *panel) |
| Bind a widget instance to a container panel. | |
| ra8_err_t | ra8_widget_panel_compose (ra8_widget_t *panel_w, const ra8_ui_rect_t *frame, ra8_ui_rect_t *out_damage, ra8_widget_refresh_t *out_hint, uint16_t *out_dirty) |
| Run one top-level compose cycle over a panel and report the flush. | |
| const ra8_widget_vtable_t * | ra8_widget_label_vtable (void) |
| Return the shared vtable backing every text-label widget. | |
| ra8_err_t | ra8_widget_label_init (ra8_widget_t *w, ra8_widget_label_t *label) |
| Bind a widget instance to a text label. | |
| const ra8_widget_vtable_t * | ra8_widget_button_vtable (void) |
| Return the shared vtable backing every push-button widget. | |
| ra8_err_t | ra8_widget_button_init (ra8_widget_t *w, ra8_widget_button_t *button) |
| Bind a widget instance to a push button. | |
Zero-heap composable widget layer (dwm-style) over ra8_box + ra8_ui.
ra8_widget is the composable-UI layer issue #145 asks for: render everything as widgets the way a tiling WM (dwm) composes a screen from opt-in pieces. A status bar is a widget; a book view is a widget; an on-screen keyboard is a widget. A screen (or an app, issue #146) is just an array of widgets laid out by a container.
The split that keeps this testable on the host AND zero-heap on the RA8D2 (NASA Rule 3):
Everything is caller-owned plain data (static widget + box arrays, no globals, no allocation), so the same composition runs identically on the host test harness and on the board.
[Ring 5 / UI] {World: NS}
Definition in file ra8_widget.h.
| typedef struct ra8_widget_button ra8_widget_button_t |
| typedef struct ra8_widget_label ra8_widget_label_t |
| typedef struct ra8_widget_paint ra8_widget_paint_t |
| typedef struct ra8_widget_panel ra8_widget_panel_t |
| typedef struct ra8_widget ra8_widget_t |
| enum ra8_widget_align_t : uint8_t |
Horizontal placement of a leaf widget's text within its rect.
center and right need the string's pixel width, so they fall back to left when the paint backend supplies no ra8_widget_paint_t::text_size.
| Enumerator | |
|---|---|
| k_ra8_widget_align_left | Hug the left inner inset. |
| k_ra8_widget_align_center | Centre horizontally in the rect. |
| k_ra8_widget_align_right | Hug the right inner inset. |
Definition at line 540 of file ra8_widget.h.
| enum ra8_widget_axis_t : uint8_t |
Main axis a container stacks its children along.
| Enumerator | |
|---|---|
| k_ra8_widget_axis_col | Vertical stack (top -> bottom). |
| k_ra8_widget_axis_row | Horizontal stack (left -> right). |
Definition at line 175 of file ra8_widget.h.
| enum ra8_widget_ev_kind_t : uint8_t |
Input event kind routed to widgets.
Selects how ra8_widget_dispatch routes an event: a touch is delivered to the single widget whose rect contains (x, y), while a button is offered to each visible widget in order until one consumes it.
| Enumerator | |
|---|---|
| k_ra8_widget_ev_touch | A touch / tap at (x, y). |
| k_ra8_widget_ev_button | A physical button press (button_id). |
Definition at line 68 of file ra8_widget.h.
| enum ra8_widget_refresh_t : uint8_t |
E-ink-style refresh hint carried by a dirty widget.
Mirrors ra8_display_pal's display_refresh_hint_t. A widget that changed only text/glyphs marks fast (A2 partial update, no flash); a widget that redrew its whole area marks quality (GC16, ghost-free). The compositor folds the dirty widgets' hints into the strongest one for the flush.
| Enumerator | |
|---|---|
| k_ra8_widget_refresh_none | Clean – not dirty. |
| k_ra8_widget_refresh_fast | Partial / A2 (text-only change). |
| k_ra8_widget_refresh_quality | Full / GC16 (whole-area redraw). |
Definition at line 98 of file ra8_widget.h.
|
nodiscard |
Bind a widget instance to a push button.
Wires w to render + route button: sets its vtable to ra8_widget_button_vtable, points its ctx at button, and makes it visible. The caller still sets w's fixed / flex (and usually its action_id) for its parent's layout and hit routing.
| [in,out] | w | Widget to turn into a button (non-NULL). |
| [in] | button | Button descriptor (non-NULL; outlives w's use). |
| k_ra8_ok | Bound; w renders + routes button. |
| k_ra8_err_null_ptr | w or button is NULL. |
w and button are non-NULL. button outlives every render / dispatch of w. w is left unchanged.Definition at line 145 of file ra8_widget_button.c.
References k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_widget_button_vtable(), and s_tag.
Referenced by wk_build_tree().
| const ra8_widget_vtable_t * ra8_widget_button_vtable | ( | void | ) |
Return the shared vtable backing every push-button widget.
One immutable vtable serves all buttons: render paints the (optionally bordered) face and aligned label through the button's ra8_widget_paint_t; on_input latches a touch (flip pressed, bump presses, self-invalidate fast, call on_press) and consumes it, ignoring button events; measure is NULL. ra8_widget_button_init binds it.
Definition at line 140 of file ra8_widget_button.c.
References s_button_vt.
Referenced by ra8_widget_button_init().
|
nodiscard |
Compute the minimal damage rectangle + refresh hint to flush.
Unions the rects of every visible AND dirty widget into one bounding rectangle and folds their refresh hints into the strongest one. This is the single display_pal flush the compositor issues: changing only the status bar yields just the status bar's rect with the fast hint; a full redraw yields the whole frame with the quality hint.
| [in] | widgets | Widget array. |
| [in] | count | Number of widgets. |
| [out] | out_rect | Receives the union rect (w == h == 0 if nothing dirty). |
| [out] | out_hint | Receives the folded refresh hint (none if clean). |
| [out] | out_count | Receives the number of dirty widgets. |
| k_ra8_ok | Computed (see out_count). |
| k_ra8_err_null_ptr | Any output pointer, or widgets (count>0), NULL. |
Definition at line 299 of file ra8_widget.c.
References internal_rect_union(), k_ra8_err_null_ptr, k_ra8_ok, k_ra8_widget_refresh_none, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by ra8_widget_panel_compose(), wa_verify_or_halt(), and wd_check_damage().
|
nodiscard |
Route an event to the widget that should handle it.
For a touch event, finds the first visible widget whose rect contains (ev->x, ev->y) (earlier widgets win on overlap) and calls its on_input. For a button event, offers it to each visible widget in order until one consumes it. A widget with a NULL on_input never consumes.
| [in,out] | widgets | Widget array. |
| [in] | count | Number of widgets. |
| [in] | ev | The event to route. |
| [out] | out_handled | Receives true if some widget consumed the event. |
| k_ra8_ok | Routed (see out_handled). |
| k_ra8_err_null_ptr | widgets (with count>0), ev, or out_handled is NULL. |
Definition at line 252 of file ra8_widget.c.
References k_ra8_err_null_ptr, k_ra8_ok, k_ra8_widget_ev_touch, ra8_widget_event_t::kind, RA8_CHECK_NULL_PTR, ra8_ui_rect_contains(), s_tag, ra8_widget_event_t::x, and ra8_widget_event_t::y.
Referenced by internal_panel_on_input(), and wd_app_on_input().
|
nodiscard |
Mark a widget dirty with a refresh hint (folds upward in strength).
| [in,out] | w | Widget to invalidate. |
| [in] | refresh | k_ra8_widget_refresh_fast / _quality. |
| k_ra8_ok | Marked dirty. |
| k_ra8_err_null_ptr | w is NULL. |
| k_ra8_err_invalid_arg | refresh is k_ra8_widget_refresh_none. |
Definition at line 286 of file ra8_widget.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_widget_refresh_none, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by er_render_keyboard(), er_render_library(), er_render_reading(), internal_bg_on_input(), internal_button_on_input(), internal_kbd_on_input(), internal_nav_on_input(), internal_panel_render(), internal_rv_link(), internal_rv_on_input(), internal_tb_on_input(), wa_app_render(), wa_verify_or_halt(), wc_check_partial(), wc_invalidate_all(), wc_tick_live(), wd_app_render(), wd_check_damage(), wd_check_partial(), wd_invalidate_all(), wd_tick_live(), wk_invalidate_all(), and wk_on_button_press().
|
nodiscard |
Bind a widget instance to a text label.
Wires w to render label: sets its vtable to ra8_widget_label_vtable, points its ctx at label, and makes it visible. The caller still sets w's fixed / flex for its parent's layout.
| [in,out] | w | Widget to turn into a label (non-NULL). |
| [in] | label | Label descriptor (non-NULL; outlives w's use). |
| k_ra8_ok | Bound; w renders label. |
| k_ra8_err_null_ptr | w or label is NULL. |
w and label are non-NULL. label outlives every render of w. w is left unchanged.Definition at line 90 of file ra8_widget_label.c.
References k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_widget_label_vtable(), and s_tag.
Referenced by wk_build_tree().
| const ra8_widget_vtable_t * ra8_widget_label_vtable | ( | void | ) |
Return the shared vtable backing every text-label widget.
One immutable vtable serves all labels: render fills the background and draws the aligned text through the label's ra8_widget_paint_t; measure and on_input are NULL (a label sizes from its parent's fixed/flex and never consumes input). ra8_widget_label_init binds it, so callers rarely need it directly – it is exposed for tests and hand-built widgets.
Definition at line 85 of file ra8_widget_label.c.
References s_label_vt.
Referenced by ra8_widget_label_init().
|
nodiscard |
Lay a stack of widgets out inside a frame (delegates to ra8_box).
Builds a transient ra8_box tree – one container plus a leaf per visible widget (invisible widgets are skipped, dwm-style) carrying that widget's fixed / flex – runs ra8_box_layout, then copies each visible widget's computed rect back into widget->rect. Invisible widgets keep their old rect. No allocation: the caller supplies the ra8_box scratch.
| [in,out] | widgets | Widget array. |
| [in] | count | Number of widgets. |
| [in] | frame | Outer rectangle the stack fills. |
| [in] | axis | k_ra8_widget_axis_col / _row. |
| [in] | gap | Gap between children (pixels). |
| [in] | pad | Inner padding of the frame (pixels). |
| [in] | box_scratch | Caller ra8_box_t scratch (>= count + 1 nodes). |
| [in] | box_cap | Capacity of box_scratch. |
| k_ra8_ok | Laid out; every visible widget's rect set. |
| k_ra8_err_null_ptr | widgets, frame, or box_scratch NULL. |
| k_ra8_err_invalid_arg | box_cap < (visible count + 1). |
Definition at line 215 of file ra8_widget.c.
References internal_build_stack_tree(), k_ra8_box_none, k_ra8_ok, ra8_box_layout(), RA8_CHECK_NULL_PTR, ra8_box_t::rect, and s_tag.
Referenced by er_render_keyboard(), er_render_library(), er_render_reading(), internal_panel_layout(), wa_app_render(), and wd_app_render().
|
nodiscard |
Run one top-level compose cycle over a panel and report the flush.
The compositor pass the issue asks for, packaged as one call:
frame (panel_w->rect = *frame).Marking the whole tree dirty before the call yields a full-frame quality flush; marking only one child (e.g. the status bar) yields just that child's rect with its hint – the damage-tracked partial update.
| [in,out] | panel_w | The root panel widget (bound via panel_init). |
| [in] | frame | Outer rectangle the panel fills (the framebuffer). |
| [out] | out_damage | Receives the union rect to flush (empty if clean). |
| [out] | out_hint | Receives the folded refresh hint (none if clean). |
| [out] | out_dirty | Receives the number of dirty children composited. |
| k_ra8_ok | Composed; see out_dirty / out_damage. |
| k_ra8_err_null_ptr | Any pointer argument is NULL. |
| k_ra8_err_invalid_arg | panel_w is not a panel, or its scratch is too small (forwarded from the layout step). |
panel_w was bound by ra8_widget_panel_init. Definition at line 203 of file ra8_widget_panel.c.
References internal_compose_check(), internal_panel_layout(), k_ra8_ok, k_ra8_widget_refresh_none, ra8_widget_damage(), and ra8_widget_render_dirty().
Referenced by wc_compose(), wd_compose(), and wk_compose().
|
nodiscard |
Bind a widget instance to a container panel.
Wires w to act as a container: sets its vtable to ra8_widget_panel_vtable, points its ctx at panel, and makes it visible. The caller still sets w's fixed / flex for its parent's layout (a root panel is typically pinned by ra8_widget_panel_compose, which sets its rect directly).
| [in,out] | w | Widget to turn into a panel (non-NULL). |
| [in] | panel | Panel descriptor (non-NULL; children covers count). |
| k_ra8_ok | Bound; w renders/routes panel's children. |
| k_ra8_err_null_ptr | w or panel is NULL. |
| k_ra8_err_invalid_arg | panel has count > 0 but a NULL child array or box_cap < count + 1. |
w and panel are non-NULL. panel->box_scratch holds at least count + 1 nodes. w is left unchanged.Definition at line 185 of file ra8_widget_panel.c.
References k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_widget_panel_vtable(), and s_tag.
Referenced by wc_build_tree(), wd_build_tree(), and wk_build_tree().
| const ra8_widget_vtable_t * ra8_widget_panel_vtable | ( | void | ) |
Return the shared vtable that every container panel uses.
One immutable vtable backs all panels: its render lays out the panel's children inside the panel widget's rect and composites them (a dirty panel repaints its whole subtree); its on_input routes the event to the children via ra8_widget_dispatch; measure is NULL (a panel sizes from its parent's fixed/flex like any widget). ra8_widget_panel_init binds this vtable, so callers rarely need it directly – it is exposed for tests and for building a widget by hand.
Definition at line 180 of file ra8_widget_panel.c.
References s_panel_vt.
Referenced by ra8_widget_panel_init().
|
nodiscard |
Render every visible + dirty widget, clearing its damage.
Calls each visible, dirty widget's render (skipping NULL render callbacks) and then clears its dirty flag and resets refresh to none. The selection of which widgets render is pure (host-testable with a recording mock vtable); the pixel drawing inside render is the on-target part.
| [in,out] | widgets | Widget array. |
| [in] | count | Number of widgets. |
| k_ra8_ok | Rendered + cleared. |
| k_ra8_err_null_ptr | widgets is NULL while count > 0. |
Definition at line 331 of file ra8_widget.c.
References k_ra8_err_null_ptr, k_ra8_ok, and k_ra8_widget_refresh_none.
Referenced by er_render_current(), er_render_keyboard(), er_render_library(), er_render_nag_region(), er_render_reading(), internal_panel_render(), ra8_widget_panel_compose(), wa_app_render(), and wd_app_render().