ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_ui.h File Reference

Bounded UI interaction core: hit-testing, screen stack, paging. More...

#include <stdint.h>
#include "ra8_err.h"
Include dependency graph for ra8_ui.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_ui_rect_t
 Axis-aligned rectangle in framebuffer pixel coordinates. More...
struct  ra8_ui_target_t
 One tap target: a rectangle bound to an opaque action id. More...
struct  ra8_ui_nav_t
 Fixed-depth screen-id stack (caller-owned). More...
struct  ra8_ui_pager_t
 Clamped (current, total) page cursor. More...

Enumerations

enum  ra8_ui_limits_t : uint16_t { k_ra8_ui_nav_max_depth = 8U }
 Static-allocation caps for the interaction core. More...

Functions

bool ra8_ui_rect_contains (const ra8_ui_rect_t *r, int32_t px, int32_t py)
 Test whether a point lies inside a rectangle.
ra8_err_t ra8_ui_hit_test (const ra8_ui_target_t *targets, uint16_t count, int32_t px, int32_t py, uint16_t *out_action, bool *out_hit)
 Find the first tap target containing a point.
ra8_err_t ra8_ui_nav_init (ra8_ui_nav_t *nav, uint16_t root_screen)
 Initialise a navigation stack with a root screen.
ra8_err_t ra8_ui_nav_push (ra8_ui_nav_t *nav, uint16_t screen)
 Push a new screen onto the stack.
ra8_err_t ra8_ui_nav_pop (ra8_ui_nav_t *nav, uint16_t *out_screen)
 Pop the top screen, revealing the one beneath.
ra8_err_t ra8_ui_nav_replace (ra8_ui_nav_t *nav, uint16_t screen)
 Replace the top screen in place (no depth change).
ra8_err_t ra8_ui_nav_top (const ra8_ui_nav_t *nav, uint16_t *out_screen)
 Read the current (top) screen id.
ra8_err_t ra8_ui_pager_init (ra8_ui_pager_t *p, uint16_t total)
 Initialise a pager over total pages at page 0.
ra8_err_t ra8_ui_pager_next (ra8_ui_pager_t *p, bool *out_changed)
 Advance to the next page, clamping at the last page.
ra8_err_t ra8_ui_pager_prev (ra8_ui_pager_t *p, bool *out_changed)
 Step to the previous page, clamping at page 0.
ra8_err_t ra8_ui_pager_goto (ra8_ui_pager_t *p, uint16_t page, bool *out_changed)
 Jump to an absolute page, clamping into [0, total-1].

Detailed Description

Bounded UI interaction core: hit-testing, screen stack, paging.

ra8_ui is the interaction / controller layer for the e-reader UI (issue #80). The rendering engines (ra8_reflow, ra8_gfx) emit boxes and glyphs; none of them model interaction. This library fills that gap with three small, allocation-free, MC/DC-able units:

  • Hit-testing – given a flat list of tap targets (rectangles + an opaque action id) and a point, find the target the user tapped. This is how a tap on the framebuffer becomes an app action.
  • Screen-stack navigation – a fixed-depth stack of screen ids with push / pop / replace, modelling modal + drill-down flows (Library -> Reading -> Table-of-Contents -> back).
  • Paging – a clamped (current, total) page cursor for the reading view and any other paginated surface.

Everything is caller-owned plain data (no globals, no allocation), so the same logic runs identically on the host test harness and on the RA8D2. It is deliberately renderer-agnostic: callers pair it with ra8_gfx today and ra8_reflow box rectangles later.

[Ring 5 / UI] {World: NS}

Since
0.1.0

Definition in file ra8_ui.h.

Enumeration Type Documentation

◆ ra8_ui_limits_t

enum ra8_ui_limits_t : uint16_t

Static-allocation caps for the interaction core.

Enumerator
k_ra8_ui_nav_max_depth 

Max screen-stack depth.

Definition at line 54 of file ra8_ui.h.

Function Documentation

◆ ra8_ui_hit_test()

ra8_err_t ra8_ui_hit_test ( const ra8_ui_target_t * targets,
uint16_t count,
int32_t px,
int32_t py,
uint16_t * out_action,
bool * out_hit )
nodiscard

Find the first tap target containing a point.

Walks targets in order and returns the action id of the first rectangle that contains (px, py). Earlier entries win on overlap, so callers should order more-specific targets first.

Parameters
[in]targetsTarget array (may be NULL only if count == 0).
[in]countNumber of targets.
[in]pxPoint X (pixels).
[in]pyPoint Y (pixels).
[out]out_actionReceives the hit target's action id.
[out]out_hitReceives true if a target was hit, else false.
Returns
ra8_err_t
Return values
k_ra8_okSearch completed (see out_hit).
k_ra8_err_null_ptrout_action / out_hit NULL, or targets NULL while count > 0.
Precondition
out_action and out_hit are non-NULL.
targets covers count entries.
Postcondition
On a hit, *out_hit == true and *out_action is the hit id.
On a miss, *out_hit == false and *out_action is unchanged.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 42 of file ra8_ui.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_ui_rect_contains(), and s_tag.

Referenced by er_handle_keyboard_tap(), er_handle_tap(), and iu_tap().

◆ ra8_ui_nav_init()

ra8_err_t ra8_ui_nav_init ( ra8_ui_nav_t * nav,
uint16_t root_screen )
nodiscard

Initialise a navigation stack with a root screen.

Parameters
[out]navStack to initialise.
[in]root_screenScreen id placed at the stack base.
Returns
ra8_err_t
Return values
k_ra8_okInitialised (depth == 1).
k_ra8_err_null_ptrnav is NULL.
Precondition
nav is non-NULL.
None.
Postcondition
nav->depth == 1 and nav->stack[0] == root_screen.
No other slots are read.
Note
Not thread-safe (caller-owned mutable state).
Since
0.1.0

Definition at line 71 of file ra8_ui.c.

References ra8_ui_nav_t::depth, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ui_nav_t::stack.

Referenced by iu_nav_check(), and main().

◆ ra8_ui_nav_pop()

ra8_err_t ra8_ui_nav_pop ( ra8_ui_nav_t * nav,
uint16_t * out_screen )
nodiscard

Pop the top screen, revealing the one beneath.

The root screen is never popped (a pop at depth == 1 fails).

Parameters
[in,out]navInitialised stack.
[out]out_screenReceives the new top screen after the pop.
Returns
ra8_err_t
Return values
k_ra8_okPopped; *out_screen is the new top.
k_ra8_err_null_ptrnav or out_screen is NULL.
k_ra8_err_invalid_stateAlready at the root (depth <= 1).
Precondition
nav and out_screen are non-NULL.
nav->depth > 1 for success.
Postcondition
On success depth shrank by one and *out_screen is the top.
At the root the stack is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 93 of file ra8_ui.c.

References ra8_ui_nav_t::depth, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ui_nav_t::stack.

Referenced by er_handle_keyboard_tap(), er_handle_reading_tap(), er_handle_tap(), and iu_nav_check().

◆ ra8_ui_nav_push()

ra8_err_t ra8_ui_nav_push ( ra8_ui_nav_t * nav,
uint16_t screen )
nodiscard

Push a new screen onto the stack.

Parameters
[in,out]navInitialised stack.
[in]screenScreen id to push.
Returns
ra8_err_t
Return values
k_ra8_okPushed (depth incremented).
k_ra8_err_null_ptrnav is NULL.
k_ra8_err_no_memStack already at k_ra8_ui_nav_max_depth.
k_ra8_err_invalid_stateStack not initialised (depth == 0).
Precondition
nav is non-NULL and initialised.
nav->depth < k_ra8_ui_nav_max_depth for success.
Postcondition
On success the new screen is on top and depth grew by one.
On overflow the stack is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 79 of file ra8_ui.c.

References ra8_ui_nav_t::depth, k_ra8_err_invalid_state, k_ra8_err_no_mem, k_ra8_ok, k_ra8_ui_nav_max_depth, RA8_CHECK_NULL_PTR, s_tag, and ra8_ui_nav_t::stack.

Referenced by er_handle_tap(), and iu_nav_check().

◆ ra8_ui_nav_replace()

ra8_err_t ra8_ui_nav_replace ( ra8_ui_nav_t * nav,
uint16_t screen )
nodiscard

Replace the top screen in place (no depth change).

Parameters
[in,out]navInitialised stack.
[in]screenScreen id to install on top.
Returns
ra8_err_t
Return values
k_ra8_okReplaced.
k_ra8_err_null_ptrnav is NULL.
k_ra8_err_invalid_stateStack not initialised (depth == 0).
Precondition
nav is non-NULL and initialised.
None.
Postcondition
nav->stack[depth-1] == screen and depth is unchanged.
No other slots are touched.
Note
Not thread-safe.
Since
0.1.0

Definition at line 105 of file ra8_ui.c.

References ra8_ui_nav_t::depth, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ui_nav_t::stack.

◆ ra8_ui_nav_top()

ra8_err_t ra8_ui_nav_top ( const ra8_ui_nav_t * nav,
uint16_t * out_screen )
nodiscard

Read the current (top) screen id.

Parameters
[in]navInitialised stack.
[out]out_screenReceives the top screen id.
Returns
ra8_err_t
Return values
k_ra8_okReported.
k_ra8_err_null_ptrnav or out_screen is NULL.
k_ra8_err_invalid_stateStack not initialised (depth == 0).
Precondition
nav and out_screen are non-NULL.
nav->depth >= 1.
Postcondition
*out_screen is nav->stack[depth-1].
No state is modified.
Note
Pure read; not thread-safe vs concurrent mutation.
Since
0.1.0

Definition at line 115 of file ra8_ui.c.

References ra8_ui_nav_t::depth, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ui_nav_t::stack.

Referenced by er_handle_tap(), er_poll_buttons(), er_render_current(), er_render_nag_region(), and iu_nav_check().

◆ ra8_ui_pager_goto()

ra8_err_t ra8_ui_pager_goto ( ra8_ui_pager_t * p,
uint16_t page,
bool * out_changed )
nodiscard

Jump to an absolute page, clamping into [0, total-1].

Parameters
[in,out]pInitialised pager.
[in]pageRequested 0-based page index.
[out]out_changedReceives true if the page actually moved.
Returns
ra8_err_t
Return values
k_ra8_okDone (see out_changed).
k_ra8_err_null_ptrp or out_changed is NULL.
Precondition
p and out_changed are non-NULL; p->total >= 1.
None.
Postcondition
p->current is page clamped to [0, total-1].
*out_changed is true iff current moved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 168 of file ra8_ui.c.

References ra8_ui_pager_t::current, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ui_pager_t::total.

◆ ra8_ui_pager_init()

ra8_err_t ra8_ui_pager_init ( ra8_ui_pager_t * p,
uint16_t total )
nodiscard

Initialise a pager over total pages at page 0.

Parameters
[out]pPager to initialise.
[in]totalTotal page count (must be >= 1).
Returns
ra8_err_t
Return values
k_ra8_okInitialised at page 0.
k_ra8_err_null_ptrp is NULL.
k_ra8_err_invalid_argtotal is 0.
Precondition
p is non-NULL and total >= 1.
None.
Postcondition
p->current == 0 and p->total == total.
No other state exists.
Note
Not thread-safe.
Since
0.1.0

Definition at line 131 of file ra8_ui.c.

References ra8_ui_pager_t::current, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ui_pager_t::total.

◆ ra8_ui_pager_next()

ra8_err_t ra8_ui_pager_next ( ra8_ui_pager_t * p,
bool * out_changed )
nodiscard

Advance to the next page, clamping at the last page.

Parameters
[in,out]pInitialised pager.
[out]out_changedReceives true if the page actually moved.
Returns
ra8_err_t
Return values
k_ra8_okDone (see out_changed).
k_ra8_err_null_ptrp or out_changed is NULL.
Precondition
p and out_changed are non-NULL; p->total >= 1.
None.
Postcondition
p->current is min(current+1, total-1).
*out_changed is true iff current moved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 142 of file ra8_ui.c.

References ra8_ui_pager_t::current, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ui_pager_t::total.

◆ ra8_ui_pager_prev()

ra8_err_t ra8_ui_pager_prev ( ra8_ui_pager_t * p,
bool * out_changed )
nodiscard

Step to the previous page, clamping at page 0.

Parameters
[in,out]pInitialised pager.
[out]out_changedReceives true if the page actually moved.
Returns
ra8_err_t
Return values
k_ra8_okDone (see out_changed).
k_ra8_err_null_ptrp or out_changed is NULL.
Precondition
p and out_changed are non-NULL.
None.
Postcondition
p->current is max(current-1, 0).
*out_changed is true iff current moved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 155 of file ra8_ui.c.

References ra8_ui_pager_t::current, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_ui_rect_contains()

bool ra8_ui_rect_contains ( const ra8_ui_rect_t * r,
int32_t px,
int32_t py )

Test whether a point lies inside a rectangle.

Top-left inclusive, bottom-right exclusive: (px >= x) && (px < x + w) && (py >= y) && (py < y + h).

Parameters
[in]rRectangle to test (NULL yields false).
[in]pxPoint X (pixels).
[in]pyPoint Y (pixels).
Returns
true if the point is inside r, false otherwise.
Return values
trueThe point lies within r.
falseThe point is outside r, or r is NULL.
Precondition
None (NULL r is handled).
None.
Postcondition
No state is modified.
Return value reflects containment only.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 34 of file ra8_ui.c.

References ra8_ui_rect_t::h, ra8_ui_rect_t::w, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.

Referenced by er_handle_reading_tap(), ez_zone_hit(), internal_bg_on_input(), internal_tb_on_input(), ra8_kbd_hit(), ra8_ui_hit_test(), and ra8_widget_dispatch().