CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
host_api_canvas.cpp
Go to the documentation of this file.
1
8
12#include "cdc_views/Fonts.h"
14#include "cdc_hal/IDisplay.h"
15#include "host_str_conv.h"
16#include <goodisplay/gdey029T94.h>
17#include <cstring>
18#include <string>
19
20namespace {
21
22cdc::ui::CanvasView* canvas()
23{
25}
26
27} // namespace
28
29extern "C" {
30
31int host_view_canvas_push(const char* title, uint32_t key_action_id,
32 uint32_t widget_action_id)
33{
35 .pushCanvas(title, key_action_id, widget_action_id);
36}
37
38int host_view_canvas_get_body_size(uint16_t* w, uint16_t* h)
39{
40 auto* c = canvas();
41 if (!c || !w || !h) return HOST_ERR_NOT_FOUND;
42 c->getBodySize(w, h);
43 return HOST_OK;
44}
45
50
52{
53 auto* c = canvas();
54 if (!c) return HOST_ERR_NOT_FOUND;
55 c->clearBody();
56 return HOST_OK;
57}
58
60{
61 auto* c = canvas();
62 if (!c) return HOST_ERR_NOT_FOUND;
63 c->setTextSize(size);
64 return HOST_OK;
65}
66
68{
69 auto* c = canvas();
70 if (!c) return HOST_ERR_NOT_FOUND;
71 c->setTextInverted(inverted);
72 return HOST_OK;
73}
74
75int host_view_canvas_set_font(uint8_t font_id)
76{
77 auto* c = canvas();
78 if (!c) return HOST_ERR_NOT_FOUND;
79 if (font_id >= HOST_FONT_COUNT) return HOST_ERR_INVALID_ARG;
80 c->setFontId(font_id);
81 return HOST_OK;
82}
83
84int host_text_pick_font_that_fits(const char* text, int16_t max_width_px,
85 const uint8_t* candidates, uint32_t count,
86 uint8_t* out_font_id)
87{
88 if (!text || !candidates || !out_font_id || count == 0) {
90 }
91 auto* display = cdc::hal::getDisplayInstance();
92 if (!display) return HOST_ERR_NOT_FOUND;
93 auto* gfx = static_cast<Gdey029T94*>(display->getNativeHandle());
94 if (!gfx) return HOST_ERR_NOT_FOUND;
95
96 std::string cp = cdc::plugin_manager::toDisplay(text);
97 const GFXfont* candFonts[HOST_FONT_COUNT];
98 if (count > HOST_FONT_COUNT) count = HOST_FONT_COUNT;
99 for (uint32_t i = 0; i < count; ++i) {
100 candFonts[i] = cdc::ui::getGfxFont(candidates[i]);
101 }
102 const GFXfont* picked = cdc::ui::render::pickFontThatFits(
103 gfx, cp.c_str(), max_width_px, candFonts, count, false);
104
105 uint8_t pickedId = candidates[count - 1];
106 for (uint32_t i = 0; i < count; ++i) {
107 if (candFonts[i] == picked) {
108 pickedId = candidates[i];
109 break;
110 }
111 }
112 *out_font_id = pickedId;
113 return HOST_OK;
114}
115
116int host_view_canvas_draw_text(int16_t x, int16_t y, const char* text)
117{
118 auto* c = canvas();
119 if (!c) return HOST_ERR_NOT_FOUND;
120 c->drawText(x, y, cdc::plugin_manager::toDisplay(text).c_str());
121 return HOST_OK;
122}
123
124int host_view_canvas_draw_text_aligned(int16_t x, int16_t y, int16_t w,
125 const char* text, uint8_t align)
126{
127 auto* c = canvas();
128 if (!c) return HOST_ERR_NOT_FOUND;
129 c->drawTextAligned(x, y, w, cdc::plugin_manager::toDisplay(text).c_str(), align);
130 return HOST_OK;
131}
132
133int host_view_canvas_draw_rect(int16_t x, int16_t y, int16_t w, int16_t h, bool filled)
134{
135 auto* c = canvas();
136 if (!c) return HOST_ERR_NOT_FOUND;
137 c->drawRect(x, y, w, h, filled);
138 return HOST_OK;
139}
140
141int host_view_canvas_invert_rect(int16_t x, int16_t y, int16_t w, int16_t h)
142{
143 auto* c = canvas();
144 if (!c) return HOST_ERR_NOT_FOUND;
145 c->invertRect(x, y, w, h);
146 return HOST_OK;
147}
148
149int host_view_canvas_hline(int16_t x, int16_t y, int16_t w)
150{
151 auto* c = canvas();
152 if (!c) return HOST_ERR_NOT_FOUND;
153 c->drawHLine(x, y, w);
154 return HOST_OK;
155}
156
157int host_view_canvas_vline(int16_t x, int16_t y, int16_t h)
158{
159 auto* c = canvas();
160 if (!c) return HOST_ERR_NOT_FOUND;
161 c->drawVLine(x, y, h);
162 return HOST_OK;
163}
164
165int host_view_canvas_commit(bool full_refresh)
166{
167 auto* c = canvas();
168 if (!c) return HOST_ERR_NOT_FOUND;
169 c->commit(full_refresh);
170 return HOST_OK;
171}
172
173int host_view_canvas_add_slider(uint32_t widget_id, int32_t min, int32_t max,
174 int32_t initial, int32_t step)
175{
176 auto* c = canvas();
177 if (!c) return HOST_ERR_NOT_FOUND;
178 return c->addSlider(widget_id, min, max, initial, step) ? HOST_OK : HOST_ERR_INVALID_ARG;
179}
180
181int host_view_canvas_add_text(uint32_t widget_id, uint16_t max_len, const char* initial)
182{
183 auto* c = canvas();
184 if (!c) return HOST_ERR_NOT_FOUND;
185 std::string cp = cdc::plugin_manager::toDisplay(initial);
186 return c->addText(widget_id, max_len, initial ? cp.c_str() : nullptr)
188}
189
190int host_view_canvas_add_button(uint32_t widget_id)
191{
192 auto* c = canvas();
193 if (!c) return HOST_ERR_NOT_FOUND;
194 return c->addButton(widget_id) ? HOST_OK : HOST_ERR_INVALID_ARG;
195}
196
197int host_view_canvas_remove_widget(uint32_t widget_id)
198{
199 auto* c = canvas();
200 if (!c) return HOST_ERR_NOT_FOUND;
201 return c->removeWidget(widget_id) ? HOST_OK : HOST_ERR_NOT_FOUND;
202}
203
204int host_view_canvas_set_value(uint32_t widget_id, int32_t value)
205{
206 auto* c = canvas();
207 if (!c) return HOST_ERR_NOT_FOUND;
208 return c->setValue(widget_id, value) ? HOST_OK : HOST_ERR_NOT_FOUND;
209}
210
211int host_view_canvas_get_value(uint32_t widget_id, int32_t* out)
212{
213 auto* c = canvas();
214 if (!c) return HOST_ERR_NOT_FOUND;
215 return c->getValue(widget_id, out) ? HOST_OK : HOST_ERR_NOT_FOUND;
216}
217
218int host_view_canvas_set_text(uint32_t widget_id, const char* text)
219{
220 auto* c = canvas();
221 if (!c) return HOST_ERR_NOT_FOUND;
222 return c->setText(widget_id, cdc::plugin_manager::toDisplay(text).c_str())
224}
225
226int host_view_canvas_get_text(uint32_t widget_id, char* out, size_t cap)
227{
228 auto* c = canvas();
229 if (!c) return HOST_ERR_NOT_FOUND;
230 if (!out || cap == 0) return HOST_ERR_INVALID_ARG;
231 std::string tmp;
232 tmp.resize(cap);
233 int n = c->getText(widget_id, &tmp[0], cap);
234 if (n < 0) return HOST_ERR_NOT_FOUND;
235 tmp.resize(std::strlen(tmp.c_str()));
236 return cdc::plugin_manager::copyUtf8(tmp.c_str(), out, cap);
237}
238
239int host_view_canvas_set_focus(uint32_t widget_id)
240{
241 auto* c = canvas();
242 if (!c) return HOST_ERR_NOT_FOUND;
243 return c->setFocus(widget_id) ? HOST_OK : HOST_ERR_NOT_FOUND;
244}
245
247{
248 auto* c = canvas();
249 if (!c || !out) return HOST_ERR_NOT_FOUND;
250 *out = c->getFocus();
251 return HOST_OK;
252}
253
254int host_view_canvas_set_key_repeat(uint16_t initial_ms, uint16_t repeat_ms)
255{
256 auto* c = canvas();
257 if (!c) return HOST_ERR_NOT_FOUND;
258 c->setKeyRepeat(initial_ms, repeat_ms);
259 return HOST_OK;
260}
261
267
268} // extern "C"
Singleton that owns plugin-pushed UI views (lists, confirms, inputs).
int setCanvasLongPressAction(uint32_t action_id)
int pushCanvas(const char *title, uint32_t key_action_id, uint32_t widget_action_id)
int setViewFooter(const char *hint)
cdc::ui::CanvasView * canvasView()
static PluginUiState & instance() noexcept
Generic canvas view exposed to WASM plugins for custom UIs.
Definition CanvasView.h:22
int host_view_canvas_get_value(uint32_t widget_id, int32_t *out)
Read the integer value of a slider widget.
int host_view_canvas_invert_rect(int16_t x, int16_t y, int16_t w, int16_t h)
Invert all pixels inside the rectangle.
int host_view_canvas_push(const char *title, uint32_t key_action_id, uint32_t widget_action_id)
Push a new canvas view.
int host_view_canvas_get_focus(uint32_t *out)
Read the currently focused widget id, 0 if none.
int host_view_canvas_hline(int16_t x, int16_t y, int16_t w)
Draw a horizontal line.
int host_view_canvas_vline(int16_t x, int16_t y, int16_t h)
Draw a vertical line.
int host_view_canvas_clear(void)
Clear all draw state and widgets.
int host_view_canvas_draw_rect(int16_t x, int16_t y, int16_t w, int16_t h, bool filled)
Draw a rectangle outline or filled rectangle.
#define HOST_FONT_COUNT
Number of defined font ids.
Definition host_api.h:1007
int host_view_canvas_set_text_color(bool inverted)
Switch between normal and inverted (white on black) text.
int host_view_canvas_set_font(uint8_t font_id)
Switch the canvas font to one of the canonical HOST_FONT_* ids.
int host_view_canvas_add_button(uint32_t widget_id)
Add a focusable button widget bound to widget_id.
int host_view_canvas_set_focus(uint32_t widget_id)
Move keyboard focus to the given widget.
int host_view_canvas_get_text(uint32_t widget_id, char *out, size_t cap)
Read the text of a text-input widget.
int host_view_canvas_set_text_size(uint8_t size)
Set text size multiplier (Adafruit-GFX semantics).
int host_view_canvas_set_key_repeat(uint16_t initial_ms, uint16_t repeat_ms)
Configure key auto-repeat timing for the canvas.
int host_view_canvas_draw_text_aligned(int16_t x, int16_t y, int16_t w, const char *text, uint8_t align)
Draw text within a horizontal box.
int host_view_canvas_set_footer(const char *hint)
Override the footer hint of the canvas.
int host_view_canvas_draw_text(int16_t x, int16_t y, const char *text)
Draw text at (x, y) using the current text size/colour.
int host_view_canvas_remove_widget(uint32_t widget_id)
Remove a widget previously added to the canvas.
int host_text_pick_font_that_fits(const char *text, int16_t max_width_px, const uint8_t *candidates, uint32_t count, uint8_t *out_font_id)
Pick the largest HOST_FONT_* whose rendered text fits within max_width_px. Candidates are evaluated i...
int host_view_canvas_add_text(uint32_t widget_id, uint16_t max_len, const char *initial)
Add a T9 text input widget bound to widget_id.
int host_view_canvas_set_text(uint32_t widget_id, const char *text)
Set the text of a text-input widget.
int host_view_canvas_set_long_press_action(uint32_t action_id)
Set the action id fired on a canvas long-press.
int host_view_canvas_set_value(uint32_t widget_id, int32_t value)
Set the integer value of a slider widget.
int host_view_canvas_get_body_size(uint16_t *w, uint16_t *h)
Read the drawable body region (excluding header/footer).
int host_view_canvas_commit(bool full_refresh)
Flush draw state to the panel.
int host_view_canvas_add_slider(uint32_t widget_id, int32_t min, int32_t max, int32_t initial, int32_t step)
Add an integer slider widget bound to widget_id.
CDC Badge OS plugin host API - canonical C ABI contract.
#define HOST_OK
Definition host_api.h:37
#define HOST_ERR_INVALID_ARG
Definition host_api.h:39
#define HOST_ERR_NOT_FOUND
Definition host_api.h:41
Internal UTF-8 <-> CP437 helpers for the plugin host API boundary.
IDisplay * getDisplayInstance()
Returns lazily created singleton display instance.
std::string toDisplay(const char *utf8)
Decode a UTF-8 (with optional HTML entities) string into CP437 bytes.
int copyUtf8(const char *cp437, char *out, size_t out_size)
Encode a CP437 string into a caller buffer as UTF-8.
const GFXfont * pickFontThatFits(Gdey029T94 *gfx, const char *text, int maxWidthPx, const GFXfont *const *candidates, size_t count, bool cp437=false)
Picks the largest font from candidates whose rendered width of text fits within maxWidthPx....
const GFXfont * getGfxFont(FontId id)
Resolves a FontId to its underlying GFX font pointer.
Definition Fonts.cpp:26