ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_widget_book.c
Go to the documentation of this file.
1
23
24#include "ra8_widget_book.h"
25
26#include "ra8_check.h"
27#include "ra8_ui.h"
28#include "ra8_widget.h"
29#include "ra8_widget_internal.h"
30
32static const char* s_tag = "ra8_widget_book_grid";
33
43
61static ra8_ui_rect_t internal_bg_content(const ra8_ui_rect_t* rect, int16_t pad)
62{
63 const int32_t p = (int32_t)pad;
64 ra8_ui_rect_t r = {};
65 r.x = rect->x + p;
66 r.y = rect->y + p;
67 r.w = rect->w - (p + p);
68 r.h = rect->h - (p + p);
69 return r;
70}
71
94 uint16_t idx,
95 uint16_t cols,
96 uint16_t rows,
97 int16_t gap)
98{
99 const int32_t g = (int32_t)gap;
100 const int32_t col = (int32_t)(idx % cols);
101 const int32_t row = (int32_t)(idx / cols);
102 const int32_t cell_w = (content->w - (g * (int32_t)(cols - 1U))) / (int32_t)cols;
103 const int32_t cell_h = (content->h - (g * (int32_t)(rows - 1U))) / (int32_t)rows;
104 ra8_ui_rect_t cell = {};
105 cell.x = content->x + (col * (cell_w + g));
106 cell.y = content->y + (row * (cell_h + g));
107 cell.w = cell_w;
108 cell.h = cell_h;
109 return cell;
110}
111
131static void internal_bg_label(const ra8_widget_paint_t* paint,
132 const ra8_ui_rect_t* row,
133 const char* text,
134 uint32_t fg,
135 uint32_t bg)
136{
137 if (text == nullptr) {
138 return;
139 }
140 int32_t tx = 0;
141 int32_t ty = 0;
142 priv_widget_text_pos(paint, row, text, (int16_t)0, k_ra8_widget_align_left, &tx, &ty);
143 paint->draw_text(paint->user, tx, ty, text, fg, bg);
144}
145
165 const ra8_widget_book_t* book,
166 const ra8_ui_rect_t* cell)
167{
168 const ra8_widget_paint_t* p = g->paint;
169 const int32_t bar_h = (int32_t)g->bar_h;
170 const int32_t lbl_h = (int32_t)g->label_h;
171 const int32_t bar_y = (cell->y + cell->h) - bar_h;
172 const int32_t auth_y = bar_y - lbl_h;
173 const int32_t title_y = auth_y - lbl_h;
174 const ra8_ui_rect_t cover = {cell->x, cell->y, cell->w, title_y - cell->y};
175 if (cover.h > 0) {
176 priv_widget_fill_box(p, &cover, book->cover, book->cover, (int16_t)0);
177 }
178 if (p->draw_text != nullptr) {
179 const ra8_ui_rect_t title = {cell->x, title_y, cell->w, lbl_h};
180 internal_bg_label(p, &title, book->title, g->title_fg, book->cover);
181 const ra8_ui_rect_t author = {cell->x, auth_y, cell->w, lbl_h};
182 internal_bg_label(p, &author, book->author, g->author_fg, book->cover);
183 }
184 const ra8_ui_rect_t bar = {cell->x, bar_y, cell->w, bar_h};
185 priv_widget_fill_box(p, &bar, g->bar_track, g->bar_track, (int16_t)0);
186 const int32_t fw =
187 priv_widget_fill_frac(book->percent, (uint32_t)k_ra8_widget_book_pct_full, cell->w);
188 if ((fw > 0) && (p->fill_rect != nullptr)) {
189 p->fill_rect(p->user, cell->x, bar_y, fw, bar_h, g->bar_fill);
190 }
191}
192
210static uint16_t internal_bg_rows(uint16_t count, uint16_t cols)
211{
212 return (uint16_t)(((uint32_t)count + (uint32_t)cols - 1U) / (uint32_t)cols);
213}
214
232{
234 if (g == nullptr) {
235 return;
236 }
237 if (g->paint == nullptr) {
238 return;
239 }
240 priv_widget_fill_box(g->paint, &w->rect, g->bg, g->bg, (int16_t)0);
241 if ((g->count == (uint16_t)k_ra8_widget_book_none) || (g->books == nullptr)) {
242 return;
243 }
244 const uint16_t cols = (g->cols >= (uint16_t)k_ra8_widget_book_min_cols)
245 ? g->cols
246 : (uint16_t)k_ra8_widget_book_min_cols;
247 const uint16_t rows = internal_bg_rows(g->count, cols);
248 const ra8_ui_rect_t content = internal_bg_content(&w->rect, g->pad);
249 for (uint16_t i = 0U; i < g->count; ++i) {
250 const ra8_ui_rect_t cell = internal_bg_cell(&content, i, cols, rows, g->gap);
251 internal_bg_card(g, &g->books[i], &cell);
252 }
253}
254
275{
277 if (g == nullptr) {
278 return false;
279 }
280 if (ev->kind != k_ra8_widget_ev_touch) {
281 return false;
282 }
283 if (g->count == (uint16_t)k_ra8_widget_book_none) {
284 return false;
285 }
286 const uint16_t cols = (g->cols >= (uint16_t)k_ra8_widget_book_min_cols)
287 ? g->cols
288 : (uint16_t)k_ra8_widget_book_min_cols;
289 const uint16_t rows = internal_bg_rows(g->count, cols);
290 const ra8_ui_rect_t content = internal_bg_content(&w->rect, g->pad);
291 for (uint16_t i = 0U; i < g->count; ++i) {
292 const ra8_ui_rect_t cell = internal_bg_cell(&content, i, cols, rows, g->gap);
293 if (ra8_ui_rect_contains(&cell, ev->x, ev->y)) {
294 g->selected = i;
296 if (g->on_open != nullptr) {
297 g->on_open(w, i);
298 }
299 return true;
300 }
301 }
302 return false;
303}
304
307 .measure = nullptr,
308 .render = internal_bg_render,
309 .on_input = internal_bg_on_input,
310};
311
313{
314 return &s_bg_vt;
315}
316
318{
319 RA8_CHECK_NULL_PTR(w, s_tag, "w must not be nullptr");
320 RA8_CHECK_NULL_PTR(grid, s_tag, "grid must not be nullptr");
322 w->ctx = grid;
323 w->visible = true;
324 return k_ra8_ok;
325}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Bounded UI interaction core: hit-testing, screen stack, paging.
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.
Definition ra8_ui.c:34
Zero-heap composable widget layer (dwm-style) over ra8_box + ra8_ui.
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).
Definition ra8_widget.c:286
@ k_ra8_widget_refresh_fast
Partial / A2 (text-only change).
Definition ra8_widget.h:100
@ k_ra8_widget_ev_touch
A touch / tap at (x, y).
Definition ra8_widget.h:69
@ k_ra8_widget_align_left
Hug the left inner inset.
Definition ra8_widget.h:541
static const ra8_widget_vtable_t s_bg_vt
The single immutable vtable shared by every book grid.
static uint16_t internal_bg_rows(uint16_t count, uint16_t cols)
Row count for count cards laid cols wide (ceil division).
static void internal_bg_render(ra8_widget_t *w)
Book-grid vtable render: fill the background, tile + paint the cards.
static bool internal_bg_on_input(ra8_widget_t *w, const ra8_widget_event_t *ev)
Book-grid vtable input: route a touch to the card it hit.
ra8_err_t ra8_widget_book_grid_init(ra8_widget_t *w, ra8_widget_book_grid_t *grid)
Bind a widget instance to a book grid.
static void internal_bg_label(const ra8_widget_paint_t *paint, const ra8_ui_rect_t *row, const char *text, uint32_t fg, uint32_t bg)
Draw one card label (title / author) left-aligned in its row.
const ra8_widget_vtable_t * ra8_widget_book_grid_vtable(void)
Return the shared vtable backing every book-grid widget.
static void internal_bg_card(const ra8_widget_book_grid_t *g, const ra8_widget_book_t *book, const ra8_ui_rect_t *cell)
Paint one book card (cover / title / author / progress) into a cell.
ra8_widget_book_geom_t
Grid geometry constants (no magic numbers).
@ k_ra8_widget_book_none
Empty grid (no cards).
@ k_ra8_widget_book_min_cols
Minimum columns; cols == 0 -> 1.
@ k_ra8_widget_book_pct_full
Full read-progress percentage.
static ra8_ui_rect_t internal_bg_cell(const ra8_ui_rect_t *content, uint16_t idx, uint16_t cols, uint16_t rows, int16_t gap)
Compute card idx's cell inside the content rect.
static ra8_ui_rect_t internal_bg_content(const ra8_ui_rect_t *rect, int16_t pad)
Inset the grid rect by its padding to the content rectangle.
Book-card + book-grid leaf widget for the ra8_widget tree (#145 Phase 2).
Module-private paint helpers shared by the concrete leaf-widget TUs.
void priv_widget_fill_box(const ra8_widget_paint_t *paint, const ra8_ui_rect_t *rect, uint32_t fill, uint32_t border, int16_t border_w)
Fill a widget rect with an optional 1-or-more-pixel border.
int32_t priv_widget_fill_frac(uint32_t value, uint32_t total, int32_t width)
Filled width in pixels for a value / total bar spanning width.
void priv_widget_text_pos(const ra8_widget_paint_t *paint, const ra8_ui_rect_t *rect, const char *text, int16_t pad, ra8_widget_align_t align, int32_t *out_x, int32_t *out_y)
Compute where a leaf widget's text should start within its rect.
Axis-aligned rectangle in framebuffer pixel coordinates.
Definition ra8_ui.h:72
int32_t w
Width (pixels, >= 0).
Definition ra8_ui.h:75
int32_t h
Height (pixels, >= 0).
Definition ra8_ui.h:76
int32_t x
Left edge (pixels).
Definition ra8_ui.h:73
int32_t y
Top edge (pixels).
Definition ra8_ui.h:74
A tappable N-column grid of book cards.
One book card's data: cover colour, title, author, read progress.
One input event delivered to ra8_widget_dispatch.
Definition ra8_widget.h:77
int32_t x
Touch X (for k_ra8_widget_ev_touch).
Definition ra8_widget.h:81
ra8_widget_ev_kind_t kind
Touch or button.
Definition ra8_widget.h:78
int32_t y
Touch Y (for k_ra8_widget_ev_touch).
Definition ra8_widget.h:82
Drawing backend the concrete leaf widgets paint through (a DI seam).
One widget instance (caller-owned, no allocation).
Behaviour table shared by all widgets of one kind.
Definition ra8_widget.h:121