@typecad/ui 1.0.0-alpha.13 → 1.0.0-alpha.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1457 -1469
- package/dist/cli.js +22 -19
- package/dist/preview/host-ui-runtime.js +0 -1
- package/dist/ui-engine/model.js +7 -1
- package/dist/ui-engine/runtime-header/canvas-scrollbar.js +115 -115
- package/dist/ui-engine/runtime-header/dirty-scroll-mutators.js +182 -182
- package/dist/ui-engine/runtime-header/forward-decls.js +227 -216
- package/dist/ui-engine/runtime-header/init-press-input.js +138 -138
- package/dist/ui-engine/runtime-header/keyboard.js +676 -676
- package/dist/ui-engine/runtime-header/node-draw-body.js +1658 -1656
- package/dist/ui-engine/runtime-header/paint-order-coords.js +259 -259
- package/dist/ui-engine/runtime-header/paint-rects-repair.js +736 -736
- package/dist/ui-engine/runtime-header/scroll-physics.js +4 -4
- package/dist/ui-engine/runtime-header/structs.js +228 -228
- package/dist/ui-engine/runtime-header/text-rendering.js +888 -888
- package/dist/ui-engine/runtime-header/tick/bindings-phase.js +118 -118
- package/dist/ui-engine/runtime-header/tick/dirty-draw-phase.js +896 -896
- package/dist/ui-engine/runtime-header/tick/scroll-canvas-phase.js +24 -24
- package/dist/ui-engine/runtime-header/touch-keyboard-fwd.js +11 -11
- package/dist/ui-engine/runtime-header/types-defines.js +110 -110
- package/dist/ui-engine/shadcn-kit.d.ts +1 -1
- package/dist/ui-engine/shadcn-kit.js +4 -0
- package/dist/ui-engine/ui-lowering.d.ts +1 -1
- package/dist/ui-engine/ui-lowering.js +14 -5
- package/dist/ui-engine/ui-registry.js +9 -1
- package/dist/wizard/display-catalog.d.ts +0 -3
- package/dist/wizard/display-catalog.js +3 -12
- package/dist/wizard/index.d.ts +2 -0
- package/dist/wizard/index.js +1 -0
- package/dist/wizard/integration-wizard.d.ts +3 -0
- package/dist/wizard/integration-wizard.js +69 -20
- package/dist/wizard/package-writer.d.ts +20 -0
- package/dist/wizard/package-writer.js +79 -0
- package/package.json +4 -4
- package/src/cli.ts +90 -87
- package/src/preview/host-ui-runtime.ts +0 -1
- package/src/ui-engine/model.ts +6 -1
- package/src/ui-engine/runtime-header/canvas-scrollbar.ts +121 -121
- package/src/ui-engine/runtime-header/dirty-scroll-mutators.ts +188 -188
- package/src/ui-engine/runtime-header/forward-decls.ts +238 -227
- package/src/ui-engine/runtime-header/init-press-input.ts +144 -144
- package/src/ui-engine/runtime-header/keyboard.ts +689 -689
- package/src/ui-engine/runtime-header/node-draw-body.ts +1683 -1681
- package/src/ui-engine/runtime-header/paint-order-coords.ts +265 -265
- package/src/ui-engine/runtime-header/paint-rects-repair.ts +742 -742
- package/src/ui-engine/runtime-header/scroll-physics.ts +4 -4
- package/src/ui-engine/runtime-header/structs.ts +234 -234
- package/src/ui-engine/runtime-header/text-rendering.ts +894 -894
- package/src/ui-engine/runtime-header/tick/bindings-phase.ts +124 -124
- package/src/ui-engine/runtime-header/tick/dirty-draw-phase.ts +902 -902
- package/src/ui-engine/runtime-header/tick/scroll-canvas-phase.ts +30 -30
- package/src/ui-engine/runtime-header/touch-keyboard-fwd.ts +11 -11
- package/src/ui-engine/runtime-header/types-defines.ts +116 -116
- package/src/ui-engine/shadcn-kit.ts +4 -0
- package/src/ui-engine/ui-lowering.ts +12 -4
- package/src/ui-engine/ui-registry.ts +9 -1
- package/src/wizard/display-catalog.ts +261 -273
- package/src/wizard/index.ts +46 -38
- package/src/wizard/integration-wizard.ts +679 -619
- package/src/wizard/package-writer.ts +98 -0
|
@@ -1,227 +1,238 @@
|
|
|
1
|
-
// Slice of the C++ runtime header (original source lines 622-752).
|
|
2
|
-
// navigate, canvas/scroll/text/paint/clip/AA/image forward declarations, persistent canvas globals.
|
|
3
|
-
// See docs/superpowers/specs/2026-07-12-split-runtime-header-design.md.
|
|
4
|
-
//
|
|
5
|
-
// EMIT BOUNDARY: This file is the structural head of the UI runtime header
|
|
6
|
-
// surface (C) — every partial emitter in this directory produces bytes that are
|
|
7
|
-
// assembled into the C++ header inlined into user
|
|
8
|
-
// are covered by the TypeCAD Runtime Exception (see RUNTIME_EXCEPTION.md at the
|
|
9
|
-
// repository root) and are not subject to the license of this tool source.
|
|
10
|
-
export function emitForwardDecls(): string {
|
|
11
|
-
return `
|
|
12
|
-
// ──
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
static inline
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// ── <
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
static
|
|
33
|
-
static
|
|
34
|
-
static
|
|
35
|
-
static
|
|
36
|
-
static
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
static
|
|
45
|
-
static uint8_t
|
|
46
|
-
static
|
|
47
|
-
static
|
|
48
|
-
static
|
|
49
|
-
static
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
static
|
|
58
|
-
static
|
|
59
|
-
static
|
|
60
|
-
static
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
static
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
static inline
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
static inline
|
|
148
|
-
static inline
|
|
149
|
-
static inline uint8_t
|
|
150
|
-
static inline
|
|
151
|
-
static inline uint8_t
|
|
152
|
-
static inline
|
|
153
|
-
static inline
|
|
154
|
-
|
|
155
|
-
static inline
|
|
156
|
-
static inline void
|
|
157
|
-
static inline void
|
|
158
|
-
static inline
|
|
159
|
-
static inline void
|
|
160
|
-
static inline
|
|
161
|
-
static inline
|
|
162
|
-
static inline uint8_t
|
|
163
|
-
static inline void
|
|
164
|
-
static inline void
|
|
165
|
-
static inline
|
|
166
|
-
static inline void
|
|
167
|
-
static inline void
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
static inline
|
|
172
|
-
|
|
173
|
-
static inline
|
|
174
|
-
static inline void
|
|
175
|
-
static inline void
|
|
176
|
-
static inline void
|
|
177
|
-
static inline void
|
|
178
|
-
static inline void
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
static inline
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
static inline
|
|
186
|
-
static inline
|
|
187
|
-
static inline
|
|
188
|
-
static inline
|
|
189
|
-
static inline void
|
|
190
|
-
|
|
191
|
-
static inline
|
|
192
|
-
static inline
|
|
193
|
-
static inline
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
static inline
|
|
197
|
-
|
|
198
|
-
static inline
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
static
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
static
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
static
|
|
224
|
-
static
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
1
|
+
// Slice of the C++ runtime header (original source lines 622-752).
|
|
2
|
+
// navigate, canvas/scroll/text/paint/clip/AA/image forward declarations, persistent canvas globals.
|
|
3
|
+
// See docs/superpowers/specs/2026-07-12-split-runtime-header-design.md.
|
|
4
|
+
//
|
|
5
|
+
// EMIT BOUNDARY: This file is the structural head of the UI runtime header
|
|
6
|
+
// surface (C) — every partial emitter in this directory produces bytes that are
|
|
7
|
+
// assembled into the C++ header inlined into user programs. The emitted bytes
|
|
8
|
+
// are covered by the TypeCAD Runtime Exception (see RUNTIME_EXCEPTION.md at the
|
|
9
|
+
// repository root) and are not subject to the license of this tool source.
|
|
10
|
+
export function emitForwardDecls(): string {
|
|
11
|
+
return `
|
|
12
|
+
// ── Runtime clock + clamp (thin-HAL contract) ────────────────────────────
|
|
13
|
+
// The UI runtime's timing contracts (debounce, press/repeat, toasts,
|
|
14
|
+
// animations, scroll physics) need a monotonic millisecond clock. The
|
|
15
|
+
// framework strategy provides __tc_now_ms() (Zephyr: kernel uptime,
|
|
16
|
+
// native: steady_clock) — the same clock the async runtime and Time.now()
|
|
17
|
+
// lower onto. All comparisons are subtraction-based, so the 32-bit wrap
|
|
18
|
+
// (~49.7 days) is harmless.
|
|
19
|
+
extern uint32_t __tc_now_ms(void);
|
|
20
|
+
// Integer clamp used by progress/range draws and the keyboard value steps.
|
|
21
|
+
static inline long __ui_constrain(long x, long lo, long hi) { return (x < lo) ? lo : ((x > hi) ? hi : x); }
|
|
22
|
+
|
|
23
|
+
// ── Modal <select> + <drawer> declarations ────────────────────────────────
|
|
24
|
+
// Declared here (the earliest runtime-header module) because ui_navigate,
|
|
25
|
+
// ui_is_effectively_visible, ui_init, and ui_tick all reference them;
|
|
26
|
+
// definitions live in the touch/keyboard modules below.
|
|
27
|
+
// ── Modal <select> option list ────────────────────────────────────────────
|
|
28
|
+
// Tapping a select opens a centered list of its options; tapping a row sets
|
|
29
|
+
// the value, tapping outside dismisses. Mirrors the preview's select modal.
|
|
30
|
+
static int16_t __ui_select_menu = -1; // node index while open, -1 closed
|
|
31
|
+
static uint8_t __ui_select_menu_dirty = 0; // overlay needs stamping this frame
|
|
32
|
+
static inline void ui_select_menu_open(uint16_t nodeIdx);
|
|
33
|
+
static inline void ui_select_menu_close(uint8_t repaint);
|
|
34
|
+
static inline void ui_select_menu_geom(uint16_t nodeIdx, UIRect* out, int16_t* rowH);
|
|
35
|
+
static inline void ui_select_menu_draw();
|
|
36
|
+
static inline void ui_select_menu_tap(int16_t tx, int16_t ty);
|
|
37
|
+
|
|
38
|
+
// ── <drawer> slide-in panels ──────────────────────────────────────────────
|
|
39
|
+
// Author-styled absolute panels; the runtime slides the subtree in from the
|
|
40
|
+
// drawer's edge (transform offsets), hides it while closed, and closes on
|
|
41
|
+
// outside taps. Mirrors the preview's drawer implementation.
|
|
42
|
+
#define UI_DRAWER_MAX 4
|
|
43
|
+
static int16_t __ui_drawer_idx[UI_DRAWER_MAX]; // node index per slot, -1 free; int16 — node indices exceed 127 in real apps
|
|
44
|
+
static uint8_t __ui_drawer_open[UI_DRAWER_MAX]; // target state (0 closed, 1 open)
|
|
45
|
+
static uint8_t __ui_drawer_progress[UI_DRAWER_MAX]; // 0 closed .. 1 open
|
|
46
|
+
static uint8_t __ui_drawer_slots = 0; // discovered drawers (init scan)
|
|
47
|
+
static int16_t __ui_drawer_last_dx[UI_DRAWER_MAX]; // last applied slide dx (delta bookkeeping)
|
|
48
|
+
static int16_t __ui_drawer_last_dy[UI_DRAWER_MAX]; // last applied slide dy
|
|
49
|
+
static uint32_t __ui_toast_elapsed[UI_DRAWER_MAX]; // <toast>: ms since fully open
|
|
50
|
+
// Compose-region inflation for an open drawer's subtree compose: nodes the
|
|
51
|
+
// overlap classification skipped (their own ladder would paint their FULL
|
|
52
|
+
// rect over the open panel) still owe pixels — their uncovered sliver. The
|
|
53
|
+
// dirty pass unions their paint rect here; the drawer's subtree compose
|
|
54
|
+
// consumes it and clears the flag. Per-frame, reset at pass start.
|
|
55
|
+
static UIRect __ui_drawer_inflate_rect[UI_DRAWER_MAX];
|
|
56
|
+
static uint8_t __ui_drawer_inflate_used[UI_DRAWER_MAX];
|
|
57
|
+
static int8_t __ui_drawer_slot_of(uint16_t nodeIdx);
|
|
58
|
+
static void ui_drawer_discover();
|
|
59
|
+
static void ui_drawer_open(uint16_t nodeIdx);
|
|
60
|
+
static void ui_drawer_close(uint16_t nodeIdx);
|
|
61
|
+
static void ui_drawer_close_all();
|
|
62
|
+
static void ui_drawer_apply(uint8_t slot, uint8_t progress);
|
|
63
|
+
static void ui_drawer_tick(uint32_t deltaMs);
|
|
64
|
+
|
|
65
|
+
// Early forward declaration: ui_navigate (below) calls ui_release_canvas_state
|
|
66
|
+
// and ui_set_pressed (defined later) during screen changes. Needed on native
|
|
67
|
+
// (single TU, no Arduino auto-prototyper).
|
|
68
|
+
static inline void ui_release_canvas_state();
|
|
69
|
+
static inline void ui_set_pressed(uint16_t nodeIdx, uint8_t pressed);
|
|
70
|
+
static inline void ui_refresh_active_screen_bg_node();
|
|
71
|
+
static inline CuttlefishCanvas16* ui_get_framebuffer();
|
|
72
|
+
// Set when the next frame must be composed from the active screen background;
|
|
73
|
+
// declared before ui_navigate because navigation can request that composition.
|
|
74
|
+
static uint8_t __ui_fb_needs_compose = 1;
|
|
75
|
+
|
|
76
|
+
// Navigate to a screen by index. Marks the new screen's nodes dirty, releases
|
|
77
|
+
// persistent canvas state, and requests a complete off-screen composition when
|
|
78
|
+
// the full-frame path is available. The physical panel is never cleared here on
|
|
79
|
+
// that path: navigation must not expose an intermediate frame while the next
|
|
80
|
+
// frame is built. Without a full-frame buffer, the fallback remains best-effort;
|
|
81
|
+
// no-TE TFT hardware cannot provide a strict tear-free guarantee.
|
|
82
|
+
static inline void ui_navigate(uint8_t screenIdx) {
|
|
83
|
+
if (screenIdx >= __ui_screen_count || screenIdx == __ui_active_screen) return;
|
|
84
|
+
__ui_active_screen = screenIdx;
|
|
85
|
+
ui_refresh_active_screen_bg_node();
|
|
86
|
+
// Reset scroll/touch state so the old screen's scroll container doesn't
|
|
87
|
+
// interfere with the new screen. Release any currently-pressed button FIRST:
|
|
88
|
+
// navigation fires from a button's click handler during touch-down, so the
|
|
89
|
+
// matching touch-up release would otherwise be suppressed by the reset below
|
|
90
|
+
// and the button would stay stuck in its :pressed color.
|
|
91
|
+
if (__ui_touch_node >= 0 && __ui_touch_node < __ui_node_count &&
|
|
92
|
+
__ui_nodes[__ui_touch_node].kind == NODE_BUTTON && __ui_nodes[__ui_touch_node].value != 0) {
|
|
93
|
+
ui_set_pressed(static_cast<uint16_t>(__ui_touch_node), 0);
|
|
94
|
+
}
|
|
95
|
+
__ui_scroll_node = -1;
|
|
96
|
+
__ui_touch_node = -1;
|
|
97
|
+
__ui_touch_state = 0;
|
|
98
|
+
__ui_kb_visible = 0;
|
|
99
|
+
__ui_select_menu = -1;
|
|
100
|
+
__ui_select_menu_dirty = 0;
|
|
101
|
+
// Drawers reset closed on navigation (device parity with the preview).
|
|
102
|
+
ui_drawer_close_all();
|
|
103
|
+
for (uint8_t s = 0; s < __ui_drawer_slots; s++) ui_drawer_apply(s, 0);
|
|
104
|
+
// Free every persistent canvas so the new screen allocates into a clean,
|
|
105
|
+
// unfragmented heap. Without this, the previous screen's canvas buffer stays
|
|
106
|
+
// resident and fragments the heap, so the new screen's buffer can't get a
|
|
107
|
+
// contiguous block (the "works first, then blanks until reset" symptom).
|
|
108
|
+
ui_release_canvas_state();
|
|
109
|
+
// A framebuffer-capable target keeps the old frame visible until the new one
|
|
110
|
+
// is complete. Targets without enough memory retain the legacy clear fallback
|
|
111
|
+
// so stale pixels from the old screen cannot remain; this constrained path is
|
|
112
|
+
// best-effort because the panel has no TE/vblank synchronization.
|
|
113
|
+
if (ui_get_framebuffer()) {
|
|
114
|
+
__ui_fb_needs_compose = 1;
|
|
115
|
+
} else {
|
|
116
|
+
#ifndef UI_REFRESH_DEFERRED
|
|
117
|
+
UI_COLOR_T navBg = (UI_COLOR_T)0;
|
|
118
|
+
if (__ui_active_screen_bg_node < __ui_node_count) {
|
|
119
|
+
navBg = __ui_nodes[__ui_active_screen_bg_node].hasBg
|
|
120
|
+
? __ui_nodes[__ui_active_screen_bg_node].bg
|
|
121
|
+
: __ui_nodes[__ui_active_screen_bg_node].clearColor;
|
|
122
|
+
}
|
|
123
|
+
display_fillScreen(navBg);
|
|
124
|
+
#endif
|
|
125
|
+
}
|
|
126
|
+
// Mark all nodes dirty so the new screen fully redraws.
|
|
127
|
+
for (uint16_t i = 0; i < __ui_node_count; i++) {
|
|
128
|
+
__ui_nodes[i].dirty = 1;
|
|
129
|
+
__ui_nodes[i].lastTextHeight = 0;
|
|
130
|
+
__ui_nodes[i].layoutCacheKey = 0;
|
|
131
|
+
if (__ui_nodes[i].scrollable) {
|
|
132
|
+
// The next screen needs a complete scroll-canvas seed; subsequent local
|
|
133
|
+
// child updates can use retained-canvas repairs.
|
|
134
|
+
__ui_nodes[i].lastPaintedScrollY = static_cast<int16_t>(
|
|
135
|
+
__ui_nodes[i].scrollY - (__ui_nodes[i].box.h > 0 ? __ui_nodes[i].box.h : 1));
|
|
136
|
+
}
|
|
137
|
+
if (__ui_nodes[i].kind == NODE_PROGRESS || __ui_nodes[i].kind == NODE_RANGE) __ui_nodes[i].lastTextWidth = -1;
|
|
138
|
+
else __ui_nodes[i].lastTextWidth = 0;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
extern const uint16_t __ui_font_face_count;
|
|
142
|
+
|
|
143
|
+
#define UI_NO_PARENT 0xFFFF // sentinel: out of uint16_t node-index range
|
|
144
|
+
|
|
145
|
+
// Forward declarations suppress Arduino's auto-prototyper, which would insert
|
|
146
|
+
// prototypes before UIFontFace/UIFontGlyph are declared.
|
|
147
|
+
static inline const UIFontFace* ui_font_face(uint8_t id);
|
|
148
|
+
static inline const UIFontGlyph* ui_font_glyph(const UIFontFace* face, uint16_t codepoint);
|
|
149
|
+
static inline uint8_t ui_font_alpha_at(const UIFontFace* face, const UIFontGlyph* glyph, uint16_t pixelIndex);
|
|
150
|
+
static inline uint16_t ui_asset_text_width(const char* text, const UIFontFace* face);
|
|
151
|
+
static inline uint8_t ui_asset_text_height(const UIFontFace* face);
|
|
152
|
+
static inline uint8_t ui_draw_asset_text(const char* text, int16_t x, int16_t y, UI_COLOR_T fg, UI_COLOR_T bg, uint8_t antialias, uint8_t fontFace);
|
|
153
|
+
static inline uint16_t ui_text_width(const char* text, uint8_t ts, uint8_t fontFace, int8_t letterSpacing);
|
|
154
|
+
struct UITextLine;
|
|
155
|
+
static inline uint8_t ui_text_next_line(const char** cursor, uint16_t maxWidth, uint8_t whiteSpaceMode, uint8_t ts, uint8_t fontFace, int8_t letterSpacing, UITextLine* out);
|
|
156
|
+
static inline void ui_text_layout_metrics(const char* text, uint16_t maxWidth, uint8_t whiteSpaceMode, uint8_t ts, uint8_t fontFace, int8_t letterSpacing, uint8_t lineHeight, uint16_t* outW, uint16_t* outH);
|
|
157
|
+
static inline void ui_invalidate_text_layout_cache(uint16_t nodeIdx);
|
|
158
|
+
static inline uint16_t ui_node_text_max_width(uint16_t nodeIdx);
|
|
159
|
+
static inline void ui_node_text_layout_metrics(uint16_t nodeIdx, uint16_t textMaxW, uint16_t* outW, uint16_t* outH);
|
|
160
|
+
static inline uint8_t ui_rects_intersect(int16_t ax, int16_t ay, int16_t aw, int16_t ah, int16_t bx, int16_t by, int16_t bw, int16_t bh);
|
|
161
|
+
static inline uint8_t ui_is_effectively_visible(uint16_t nodeIdx);
|
|
162
|
+
static inline uint8_t ui_node_draws_before(uint16_t a, uint16_t b);
|
|
163
|
+
static inline void ui_node_paint_rect(uint16_t nodeIdx, int16_t baseX, int16_t baseY, int16_t drawX, int16_t drawY, uint16_t textW, uint16_t textH, UIRect* out);
|
|
164
|
+
static inline void ui_node_current_paint_rect(uint16_t nodeIdx, UIRect* out);
|
|
165
|
+
static inline uint8_t ui_subtree_current_paint_rect(uint16_t nodeIdx, UIRect* out);
|
|
166
|
+
static inline void ui_mark_overlapping_higher_layers_dirty(uint16_t nodeIdx);
|
|
167
|
+
static inline void ui_mark_overlapping_higher_layers_dirty_for_rect(uint16_t nodeIdx, const UIRect* r);
|
|
168
|
+
static inline void ui_mark_scroll_view_dirty(uint16_t scrollNode);
|
|
169
|
+
static inline UI_COLOR_T ui_parent_clear_color(uint16_t nodeIdx);
|
|
170
|
+
static inline void ui_release_canvas_state();
|
|
171
|
+
static inline void ui_set_visible(uint16_t nodeIdx, uint8_t visible);
|
|
172
|
+
static inline void ui_invalidate_scroll_canvas_for_node(uint16_t nodeIdx);
|
|
173
|
+
static inline uint8_t ui_clip_rect_to_rect(UIRect* r, const UIRect* clip);
|
|
174
|
+
static inline void ui_fill_rect_clipped(int16_t x, int16_t y, int16_t w, int16_t h, const UIRect* clip, UI_COLOR_T color);
|
|
175
|
+
static inline void ui_hline_clipped(int16_t x, int16_t y, int16_t w, const UIRect* clip, UI_COLOR_T color);
|
|
176
|
+
static inline void ui_vline_clipped(int16_t x, int16_t y, int16_t h, const UIRect* clip, UI_COLOR_T color);
|
|
177
|
+
static inline void ui_draw_rect_outline_clipped(int16_t x, int16_t y, int16_t w, int16_t h, uint8_t style, uint8_t width, const UIRect* clip, UI_COLOR_T color);
|
|
178
|
+
static inline void ui_draw_node_decoration_clipped(uint16_t nodeIdx, int16_t drawY, const UIRect* clip);
|
|
179
|
+
// Forward declarations for functions used before their definition in the
|
|
180
|
+
// single native translation unit (Arduino's auto-prototyper hides this;
|
|
181
|
+
// native emits one TU so explicit forwards are needed).
|
|
182
|
+
static inline int8_t ui_rich_link_hit(uint16_t nodeIdx, int16_t px, int16_t py);
|
|
183
|
+
#ifdef UI_AA
|
|
184
|
+
static inline CuttlefishCanvas16* ui_aa_begin(int16_t w, int16_t h, UI_COLOR_T bg);
|
|
185
|
+
static inline void ui_aa_end(CuttlefishCanvas16* c);
|
|
186
|
+
static inline void ui_aa_push(CuttlefishCanvas16* c, int16_t dx, int16_t dy);
|
|
187
|
+
static inline void ui_aa_line(CuttlefishCanvas16* c, float x0, float y0, float x1, float y1, UI_COLOR_T color);
|
|
188
|
+
static inline void ui_aa_circle(CuttlefishCanvas16* c, int16_t cx, int16_t cy, float r, UI_COLOR_T color);
|
|
189
|
+
static inline void ui_aa_fill_circle(CuttlefishCanvas16* c, int16_t cx, int16_t cy, float r, UI_COLOR_T color);
|
|
190
|
+
#endif
|
|
191
|
+
static inline uint8_t ui_repair_current_node_paint_with_parent(uint16_t nodeIdx, UIRect* r);
|
|
192
|
+
static inline void ui_clear_node_paint_rect(uint16_t nodeIdx, const UIRect* paintRect);
|
|
193
|
+
static inline uint8_t ui_try_repair_geometry_fill(uint16_t nodeIdx, const UIRect* oldRect);
|
|
194
|
+
// Band renderers (defined in node-draw-body; forward-declared so the NODE_LIST
|
|
195
|
+
// case can fall back to ui_render_list_bands before its definition site).
|
|
196
|
+
static inline uint8_t ui_render_node_bands(uint16_t nodeIdx, int16_t prX, int16_t prY, int16_t prW, int16_t prH);
|
|
197
|
+
static inline uint8_t ui_render_screen_bands(int16_t rx, int16_t ry, int16_t rw, int16_t rh);
|
|
198
|
+
static inline uint8_t ui_render_list_bands(uint16_t i);
|
|
199
|
+
static inline uint8_t ui_render_list_direct(uint16_t i);
|
|
200
|
+
static inline void ui_draw_node_border(uint16_t i, int16_t drawX, int16_t drawY, UI_COLOR_T color);
|
|
201
|
+
static inline void ui_draw_node_outline(uint16_t i, int16_t drawX, int16_t drawY);
|
|
202
|
+
static inline void ui_draw_gradient_fill(uint16_t i, int16_t drawY);
|
|
203
|
+
static inline uint8_t ui_rotation_quadrant(int16_t deg);
|
|
204
|
+
static inline int16_t ui_rotated_face_w(uint16_t nodeIdx, int16_t w, int16_t h);
|
|
205
|
+
static inline int16_t ui_rotated_face_h(uint16_t nodeIdx, int16_t w, int16_t h);
|
|
206
|
+
static inline void ui_draw_image_rotated(const UIImage* img, int16_t x, int16_t y, int16_t rotateDeg);
|
|
207
|
+
static inline void ui_draw_image_with_fit(const UIImage* img, int16_t x, int16_t y, int16_t rotateDeg,
|
|
208
|
+
uint8_t fitMode, int16_t targetW, int16_t targetH);
|
|
209
|
+
static inline void ui_draw_scaled_image(const UIImage* img, int16_t x, int16_t y, int16_t rotateDeg,
|
|
210
|
+
int16_t drawW, int16_t drawH);
|
|
211
|
+
|
|
212
|
+
static CuttlefishDisplayTarget* __ui_gfx = display_defaultTarget();
|
|
213
|
+
// Full-frame composition is required for the first frame and after navigation.
|
|
214
|
+
// Once composed, subsequent dirty updates can safely modify the retained
|
|
215
|
+
// framebuffer without rebuilding unchanged nodes. The flags are declared
|
|
216
|
+
// before ui_navigate above because navigation sets the compose request.
|
|
217
|
+
// Persistent canvas slots, all freed on screen change (ui_navigate) so each
|
|
218
|
+
// screen starts with a clean heap. Without this, the first screen's canvas
|
|
219
|
+
// buffer stays resident and fragments the heap, so a later screen's buffer
|
|
220
|
+
// can't get a contiguous block — manifesting as that element blanking until a
|
|
221
|
+
// hard reset. File-scoped (not function-static) so ui_release_canvas_state can
|
|
222
|
+
// reach them.
|
|
223
|
+
static CuttlefishCanvas16* __ui_container_canvas = nullptr; // Mode B shift-and-repair
|
|
224
|
+
static CuttlefishCanvas16* __ui_list_canvas = nullptr; // virtualized <list> viewport
|
|
225
|
+
static int16_t __ui_list_canvas_node = -1; // node currently represented by __ui_list_canvas
|
|
226
|
+
static CuttlefishCanvas16* __ui_node_canvas = nullptr; // <canvas> element offscreen
|
|
227
|
+
static CuttlefishCanvas16* __ui_repair_canvas = nullptr; // buffered-paint / exposed-strip
|
|
228
|
+
static CuttlefishCanvas16* __ui_band_canvas = nullptr; // band renderer (no-PSRAM scroll)
|
|
229
|
+
static CuttlefishCanvas16* __ui_kb_canvas = nullptr; // on-screen keyboard overlay
|
|
230
|
+
static int16_t __ui_canvas_fallback_w = 0; // dimensions for direct <canvas> fallback
|
|
231
|
+
static int16_t __ui_canvas_fallback_h = 0;
|
|
232
|
+
// Draw offset: normally zero. The <canvas> allocation fallback sets it so
|
|
233
|
+
// callback-local coordinates draw into the node's current display/canvas target.
|
|
234
|
+
static int16_t __ui_draw_off_x = 0;
|
|
235
|
+
static int16_t __ui_draw_off_y = 0;
|
|
236
|
+
|
|
237
|
+
// Release every persistent canvas so the next screen allocates into a clean`;
|
|
238
|
+
}
|