@typecad/ui 1.0.0-alpha.6 → 1.0.0-alpha.8
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 +6 -0
- package/dist/engine-index.js +2 -2
- package/dist/preview/host-ui-runtime.d.ts +1 -0
- package/dist/preview/host-ui-runtime.js +56 -11
- package/dist/ui-engine/font-assets.d.ts +8 -0
- package/dist/ui-engine/font-assets.js +13 -0
- package/dist/ui-engine/layout-engine.js +19 -6
- package/dist/ui-engine/model.d.ts +1 -1
- package/dist/ui-engine/model.js +10 -4
- package/dist/ui-engine/runtime-header/antialiasing.js +52 -32
- package/dist/ui-engine/runtime-header/blend-bodies.js +4 -4
- package/dist/ui-engine/runtime-header/canvas-helpers.js +42 -69
- package/dist/ui-engine/runtime-header/canvas-scrollbar.js +22 -10
- package/dist/ui-engine/runtime-header/color-mono-refresh.js +10 -10
- package/dist/ui-engine/runtime-header/cuttlefish-gfx.d.ts +1 -0
- package/dist/ui-engine/runtime-header/cuttlefish-gfx.js +563 -0
- package/dist/ui-engine/runtime-header/dirty-scroll-mutators.js +26 -10
- package/dist/ui-engine/runtime-header/display-shim.js +8 -8
- package/dist/ui-engine/runtime-header/forward-decls.js +52 -10
- package/dist/ui-engine/runtime-header/image-drawing.js +154 -84
- package/dist/ui-engine/runtime-header/init-press-input.js +20 -5
- package/dist/ui-engine/runtime-header/keyboard.js +62 -18
- package/dist/ui-engine/runtime-header/node-decoration.js +8 -9
- package/dist/ui-engine/runtime-header/node-draw-body.d.ts +1 -0
- package/dist/ui-engine/runtime-header/node-draw-body.js +1402 -0
- package/dist/ui-engine/runtime-header/paint-order-coords.js +48 -18
- package/dist/ui-engine/runtime-header/paint-rects-repair.js +38 -17
- package/dist/ui-engine/runtime-header/scroll-physics.js +15 -18
- package/dist/ui-engine/runtime-header/state-bindings-nav.js +23 -13
- package/dist/ui-engine/runtime-header/structs.js +12 -10
- package/dist/ui-engine/runtime-header/text-rendering.js +132 -71
- package/dist/ui-engine/runtime-header/tick/bindings-phase.js +29 -10
- package/dist/ui-engine/runtime-header/tick/dirty-draw-phase.js +336 -749
- package/dist/ui-engine/runtime-header/tick/flush-phase.js +7 -3
- package/dist/ui-engine/runtime-header/tick/scroll-canvas-phase.js +19 -3
- package/dist/ui-engine/runtime-header/tick/transitions-phase.js +31 -24
- package/dist/ui-engine/runtime-header/touch-keyboard-fwd.js +46 -41
- package/dist/ui-engine/runtime-header/types-defines.js +23 -3
- package/dist/ui-engine/runtime-header.d.ts +10 -1
- package/dist/ui-engine/runtime-header.js +7 -1
- package/dist/ui-engine/transpile-ui.js +2 -2
- package/dist/ui-engine/ua-stylesheet.js +46 -3
- package/dist/ui-engine/ui-lowering.d.ts +1 -3
- package/dist/ui-engine/ui-lowering.js +18 -24
- package/dist/ui-engine/ui-registry.js +1 -6
- package/package.json +2 -2
- package/src/engine-index.ts +2 -2
- package/src/preview/host-ui-runtime.ts +56 -12
- package/src/ui-engine/font-assets.ts +13 -0
- package/src/ui-engine/layout-engine.ts +19 -6
- package/src/ui-engine/model.ts +10 -5
- package/src/ui-engine/runtime-header/antialiasing.ts +52 -32
- package/src/ui-engine/runtime-header/blend-bodies.ts +4 -4
- package/src/ui-engine/runtime-header/canvas-helpers.ts +42 -69
- package/src/ui-engine/runtime-header/canvas-scrollbar.ts +22 -10
- package/src/ui-engine/runtime-header/color-mono-refresh.ts +10 -10
- package/src/ui-engine/runtime-header/cuttlefish-gfx.ts +566 -0
- package/src/ui-engine/runtime-header/dirty-scroll-mutators.ts +26 -10
- package/src/ui-engine/runtime-header/display-shim.ts +8 -8
- package/src/ui-engine/runtime-header/forward-decls.ts +52 -10
- package/src/ui-engine/runtime-header/image-drawing.ts +154 -84
- package/src/ui-engine/runtime-header/init-press-input.ts +20 -5
- package/src/ui-engine/runtime-header/keyboard.ts +62 -18
- package/src/ui-engine/runtime-header/node-decoration.ts +8 -9
- package/src/ui-engine/runtime-header/node-draw-body.ts +1402 -0
- package/src/ui-engine/runtime-header/paint-order-coords.ts +48 -18
- package/src/ui-engine/runtime-header/paint-rects-repair.ts +38 -17
- package/src/ui-engine/runtime-header/scroll-physics.ts +15 -18
- package/src/ui-engine/runtime-header/state-bindings-nav.ts +23 -13
- package/src/ui-engine/runtime-header/structs.ts +12 -10
- package/src/ui-engine/runtime-header/text-rendering.ts +132 -71
- package/src/ui-engine/runtime-header/tick/bindings-phase.ts +29 -10
- package/src/ui-engine/runtime-header/tick/dirty-draw-phase.ts +336 -749
- package/src/ui-engine/runtime-header/tick/flush-phase.ts +7 -3
- package/src/ui-engine/runtime-header/tick/scroll-canvas-phase.ts +19 -3
- package/src/ui-engine/runtime-header/tick/transitions-phase.ts +31 -24
- package/src/ui-engine/runtime-header/touch-keyboard-fwd.ts +46 -41
- package/src/ui-engine/runtime-header/types-defines.ts +23 -3
- package/src/ui-engine/runtime-header.ts +17 -1
- package/src/ui-engine/transpile-ui.ts +2 -2
- package/src/ui-engine/ua-stylesheet.ts +46 -3
- package/src/ui-engine/ui-lowering.ts +19 -26
- package/src/ui-engine/ui-registry.ts +1 -7
- package/dist/ui-engine/scroll-memory-diagnostics.d.ts +0 -16
- package/dist/ui-engine/scroll-memory-diagnostics.js +0 -58
- package/src/ui-engine/scroll-memory-diagnostics.ts +0 -79
|
@@ -49,7 +49,7 @@ static inline void ui_kb_insert(char c) {
|
|
|
49
49
|
if (__ui_kb_target >= 0) {
|
|
50
50
|
strncpy(__ui_nodes[__ui_kb_target].textBuffer, __ui_kb_buffer, UI_TEXT_BUF);
|
|
51
51
|
__ui_nodes[__ui_kb_target].textBuffer[UI_TEXT_BUF] = 0;
|
|
52
|
-
ui_mark_dirty((
|
|
52
|
+
ui_mark_dirty(static_cast<uint16_t>(__ui_kb_target));
|
|
53
53
|
}
|
|
54
54
|
#endif
|
|
55
55
|
}
|
|
@@ -62,7 +62,7 @@ static inline void ui_kb_delete() {
|
|
|
62
62
|
if (__ui_kb_target >= 0) {
|
|
63
63
|
strncpy(__ui_nodes[__ui_kb_target].textBuffer, __ui_kb_buffer, UI_TEXT_BUF);
|
|
64
64
|
__ui_nodes[__ui_kb_target].textBuffer[UI_TEXT_BUF] = 0;
|
|
65
|
-
ui_mark_dirty((
|
|
65
|
+
ui_mark_dirty(static_cast<uint16_t>(__ui_kb_target));
|
|
66
66
|
}
|
|
67
67
|
#endif
|
|
68
68
|
}
|
|
@@ -92,7 +92,7 @@ static inline void ui_kb_open(uint16_t nodeIdx, uint8_t inputPosition) {
|
|
|
92
92
|
__ui_kb_buffer[UI_TEXT_BUF] = 0;
|
|
93
93
|
__ui_kb_len = strlen(__ui_kb_buffer);
|
|
94
94
|
uint16_t ml = __ui_nodes[nodeIdx].maxlen;
|
|
95
|
-
__ui_kb_maxlen = (ml > 0 && ml <= UI_TEXT_BUF) ? (
|
|
95
|
+
__ui_kb_maxlen = (ml > 0 && ml <= UI_TEXT_BUF) ? static_cast<uint8_t>(ml) : UI_TEXT_BUF;
|
|
96
96
|
__ui_kb_shift = 0;
|
|
97
97
|
__ui_kb_bs_held = 0;
|
|
98
98
|
// Load the key set via the dispatch table.
|
|
@@ -113,7 +113,7 @@ static inline void ui_kb_open(uint16_t nodeIdx, uint8_t inputPosition) {
|
|
|
113
113
|
// keystroke. (The full-screen-flash concern above doesn't apply — there's no
|
|
114
114
|
// opaque overlay being skipped.) Seed the blink phase so the caret is ON for
|
|
115
115
|
// the first ~530ms (bit 0x20 set → visible), so focus feels immediate.
|
|
116
|
-
if (__ui_kb_target >= 0) ui_mark_dirty((
|
|
116
|
+
if (__ui_kb_target >= 0) ui_mark_dirty(static_cast<uint16_t>(__ui_kb_target));
|
|
117
117
|
__ui_kb_blink = 0x20;
|
|
118
118
|
#endif
|
|
119
119
|
}
|
|
@@ -140,7 +140,7 @@ static inline void ui_kb_close() {
|
|
|
140
140
|
int16_t screenRoot = -1;
|
|
141
141
|
for (uint16_t i = 0; i < __ui_node_count; i++) {
|
|
142
142
|
if (__ui_nodes[i].parent == UI_NO_PARENT && __ui_nodes[i].screenId == __ui_active_screen) {
|
|
143
|
-
screenRoot = (
|
|
143
|
+
screenRoot = static_cast<int16_t>(i);
|
|
144
144
|
break;
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -156,7 +156,7 @@ static inline void ui_kb_close() {
|
|
|
156
156
|
// scroll clipping — safe here since these nodes are bounded in size, unlike
|
|
157
157
|
// the screen root.
|
|
158
158
|
for (uint16_t i = 0; i < __ui_node_count; i++) {
|
|
159
|
-
if ((
|
|
159
|
+
if (static_cast<int16_t>(i) == screenRoot) continue;
|
|
160
160
|
UIRect r;
|
|
161
161
|
ui_node_current_paint_rect(i, &r);
|
|
162
162
|
if (r.w > 0 && r.h > 0 &&
|
|
@@ -173,8 +173,8 @@ static inline void ui_kb_key_rect(uint8_t idx, UIRect* out) {
|
|
|
173
173
|
uint8_t col = idx % __ui_kb_cols;
|
|
174
174
|
uint8_t row = idx / __ui_kb_cols;
|
|
175
175
|
int16_t keysH = __ui_kb_box.h - UI_KB_TEXT_H; // key area height (below text row)
|
|
176
|
-
out->x = __ui_kb_box.x + (
|
|
177
|
-
out->y = __ui_kb_box.y + UI_KB_TEXT_H + (
|
|
176
|
+
out->x = __ui_kb_box.x + static_cast<int16_t>(col) * __ui_kb_box.w / __ui_kb_cols;
|
|
177
|
+
out->y = __ui_kb_box.y + UI_KB_TEXT_H + static_cast<int16_t>(row) * keysH / __ui_kb_rows;
|
|
178
178
|
out->w = __ui_kb_box.w / __ui_kb_cols;
|
|
179
179
|
out->h = keysH / __ui_kb_rows;
|
|
180
180
|
}
|
|
@@ -192,8 +192,8 @@ static inline void ui_kb_handle_touch(int16_t tx, int16_t ty) {
|
|
|
192
192
|
UIRect r;
|
|
193
193
|
ui_kb_key_rect(i, &r);
|
|
194
194
|
if (tx >= r.x && tx < r.x + r.w && ty >= r.y && ty < r.y + r.h) {
|
|
195
|
-
__ui_kb_pressed_key = (
|
|
196
|
-
__ui_kb_repaint_key = (
|
|
195
|
+
__ui_kb_pressed_key = static_cast<int8_t>(i); // remember for release
|
|
196
|
+
__ui_kb_repaint_key = static_cast<int8_t>(i);
|
|
197
197
|
__ui_kb_dirty = 2; // targeted: redraw just this key's highlight
|
|
198
198
|
// Backspace starts deleting immediately + arms auto-repeat.
|
|
199
199
|
if (k.special == 2) {
|
|
@@ -273,7 +273,7 @@ static inline void ui_kb_draw_key(uint8_t i) {
|
|
|
273
273
|
UI_COLOR_T border = ks.borderColor;
|
|
274
274
|
// Shift-active highlight: brighten the shift key's background — but only
|
|
275
275
|
// when not pressed, so the press inversion stays high-contrast.
|
|
276
|
-
if (k.special == 1 && __ui_kb_shift && (
|
|
276
|
+
if (k.special == 1 && __ui_kb_shift && static_cast<int8_t>(i) != __ui_kb_pressed_key) {
|
|
277
277
|
#if UI_COLOR_DEPTH == 888
|
|
278
278
|
bg = 0xBDEFFF;
|
|
279
279
|
#else
|
|
@@ -281,7 +281,7 @@ static inline void ui_kb_draw_key(uint8_t i) {
|
|
|
281
281
|
#endif
|
|
282
282
|
}
|
|
283
283
|
// Pressed key: invert colors for clear tap feedback.
|
|
284
|
-
if ((
|
|
284
|
+
if (static_cast<int8_t>(i) == __ui_kb_pressed_key) { UI_COLOR_T t = bg; bg = fg; fg = t; }
|
|
285
285
|
ui_display_fill_rect(r.x + 1, r.y + 1, r.w - 2, r.h - 2, bg);
|
|
286
286
|
ui_display_draw_rect(r.x + 1, r.y + 1, r.w - 2, r.h - 2, border);
|
|
287
287
|
ui_display_set_text_color(fg, bg);
|
|
@@ -295,14 +295,14 @@ static inline void ui_kb_draw_key(uint8_t i) {
|
|
|
295
295
|
case 3: labelStr = "OK"; break;
|
|
296
296
|
case 4: labelStr = __ui_kb_cols <= 4 ? "ABC" : "123"; break;
|
|
297
297
|
default:
|
|
298
|
-
single[0] = (__ui_kb_shift && k.ch >= 'a' && k.ch <= 'z') ?
|
|
298
|
+
single[0] = (__ui_kb_shift && k.ch >= 'a' && k.ch <= 'z') ? static_cast<char>(k.ch - 32) : k.ch;
|
|
299
299
|
single[1] = 0;
|
|
300
300
|
labelStr = single;
|
|
301
301
|
break;
|
|
302
302
|
}
|
|
303
303
|
// Center: textW = len * 6px, textH = 8px. Position inside the key rect.
|
|
304
304
|
uint8_t len = strlen(labelStr);
|
|
305
|
-
int16_t textW = (
|
|
305
|
+
int16_t textW = static_cast<int16_t>(len) * 6;
|
|
306
306
|
int16_t textH = 8;
|
|
307
307
|
int16_t cx = r.x + (r.w - textW) / 2;
|
|
308
308
|
int16_t cy = r.y + (r.h - textH) / 2;
|
|
@@ -328,15 +328,59 @@ static inline void ui_kb_draw_text_row() {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
// Draw the full keyboard overlay (background + text row + all keys).
|
|
331
|
+
// Renders into a dedicated offscreen canvas first, then pushes in a single
|
|
332
|
+
// SPI transaction — avoids the per-key/per-rect display writes that show up
|
|
333
|
+
// as visible row-by-row painting on SPI TFTs.
|
|
334
|
+
// (__ui_kb_canvas is forward-declared in the touch-keyboard-fwd slice.)
|
|
331
335
|
static inline void ui_kb_draw() {
|
|
332
|
-
|
|
333
|
-
|
|
336
|
+
int16_t kw = __ui_kb_box.w;
|
|
337
|
+
int16_t kh = __ui_kb_box.h;
|
|
338
|
+
if (kw <= 0 || kh <= 0) return;
|
|
339
|
+
// (Re)allocate the keyboard canvas to exact size (see repair-canvas comment
|
|
340
|
+
// — stride mismatch corrupts the push when reusing a differently-sized canvas).
|
|
341
|
+
// ui_create_canvas_best prefers PSRAM when available (a full-width keyboard
|
|
342
|
+
// canvas can be ~30KB, too big for no-PSRAM internal SRAM) and falls back to
|
|
343
|
+
// SRAM — same policy as the list/scroll viewport canvases.
|
|
344
|
+
if (!__ui_kb_canvas || !display_canvasBuffer(__ui_kb_canvas) ||
|
|
345
|
+
display_canvasWidth(__ui_kb_canvas) != kw ||
|
|
346
|
+
display_canvasHeight(__ui_kb_canvas) != kh) {
|
|
347
|
+
display_deleteCanvas(__ui_kb_canvas);
|
|
348
|
+
__ui_kb_canvas = ui_create_canvas_best(kw, kh);
|
|
349
|
+
}
|
|
350
|
+
if (!__ui_kb_canvas || !display_canvasBuffer(__ui_kb_canvas)) {
|
|
351
|
+
// Canvas alloc failed — fall back to direct draw (slow but correct).
|
|
352
|
+
ui_display_fill_rect(__ui_kb_box.x, __ui_kb_box.y, kw, kh, __ui_kb_bg);
|
|
353
|
+
ui_kb_draw_text_row();
|
|
354
|
+
for (uint8_t i = 0; i < __ui_kb_keyCount; i++) {
|
|
355
|
+
if (__ui_kb_keys[i].special == 255) continue;
|
|
356
|
+
ui_kb_draw_key(i);
|
|
357
|
+
}
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
// Redirect drawing into the canvas. All ui_display_* calls below go to RAM.
|
|
361
|
+
CuttlefishDisplayTarget* __kb_prev_target = ui_display_get_target();
|
|
362
|
+
ui_display_set_target(__ui_kb_canvas);
|
|
363
|
+
// Opaque background over the keyboard box (canvas-local 0,0).
|
|
364
|
+
ui_display_fill_rect(0, 0, kw, kh, __ui_kb_bg);
|
|
365
|
+
// Text row + keys: temporarily shift box origin to canvas-local so the
|
|
366
|
+
// existing draw_text_row / draw_key functions compute coords at (0,0).
|
|
367
|
+
int16_t saveBoxX = __ui_kb_box.x;
|
|
368
|
+
int16_t saveBoxY = __ui_kb_box.y;
|
|
369
|
+
__ui_kb_box.x = 0;
|
|
370
|
+
__ui_kb_box.y = 0;
|
|
334
371
|
ui_kb_draw_text_row();
|
|
335
|
-
// Keys: one rect per key, label centered.
|
|
336
372
|
for (uint8_t i = 0; i < __ui_kb_keyCount; i++) {
|
|
337
|
-
if (__ui_kb_keys[i].special == 255) continue;
|
|
373
|
+
if (__ui_kb_keys[i].special == 255) continue;
|
|
338
374
|
ui_kb_draw_key(i);
|
|
339
375
|
}
|
|
376
|
+
__ui_kb_box.x = saveBoxX;
|
|
377
|
+
__ui_kb_box.y = saveBoxY;
|
|
378
|
+
// Restore display target and push the canvas in one transaction.
|
|
379
|
+
ui_display_set_target(__kb_prev_target);
|
|
380
|
+
display_startWrite();
|
|
381
|
+
display_setAddrWindow(saveBoxX, saveBoxY, kw, kh);
|
|
382
|
+
display_writePixels(display_canvasBuffer(__ui_kb_canvas), static_cast<uint32_t>(kw) * kh);
|
|
383
|
+
display_endWrite();
|
|
340
384
|
}
|
|
341
385
|
`;
|
|
342
386
|
}
|
|
@@ -18,19 +18,19 @@ static inline void ui_draw_gradient_fill(uint16_t i, int16_t drawY) {
|
|
|
18
18
|
uint8_t dir = __ui_nodes[i].gradientEnabled; // 1=vertical, 2=horizontal
|
|
19
19
|
if (dir == 1) {
|
|
20
20
|
// Vertical: top=c1, bottom=c2. Draw row by row.
|
|
21
|
-
int16_t yStart =
|
|
22
|
-
int16_t yEnd =
|
|
21
|
+
int16_t yStart = static_cast<int16_t>(clipY - by);
|
|
22
|
+
int16_t yEnd = static_cast<int16_t>(clipY + clipH - by);
|
|
23
23
|
for (int16_t y = yStart; y < yEnd; y++) {
|
|
24
|
-
uint8_t op =
|
|
24
|
+
uint8_t op = static_cast<uint8_t>(static_cast<uint16_t>(y) * 100 / (bh > 1 ? bh - 1 : 1));
|
|
25
25
|
uint32_t col = ui_blend(c1, c2, op);
|
|
26
26
|
ui_display_draw_fast_hline(clipX, by + y, clipW, col);
|
|
27
27
|
}
|
|
28
28
|
} else {
|
|
29
29
|
// Horizontal: left=c1, right=c2. Draw column by column.
|
|
30
|
-
int16_t xStart =
|
|
31
|
-
int16_t xEnd =
|
|
30
|
+
int16_t xStart = static_cast<int16_t>(clipX - bx);
|
|
31
|
+
int16_t xEnd = static_cast<int16_t>(clipX + clipW - bx);
|
|
32
32
|
for (int16_t x = xStart; x < xEnd; x++) {
|
|
33
|
-
uint8_t op =
|
|
33
|
+
uint8_t op = static_cast<uint8_t>(static_cast<uint16_t>(x) * 100 / (bw > 1 ? bw - 1 : 1));
|
|
34
34
|
uint32_t col = ui_blend(c1, c2, op);
|
|
35
35
|
ui_display_draw_fast_vline(bx + x, clipY, clipH, col);
|
|
36
36
|
}
|
|
@@ -79,7 +79,7 @@ static inline void ui_draw_shadow(uint16_t i, int16_t drawY, uint8_t insetOnly)
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
for (int8_t pass = blur; pass >= 1; pass--) {
|
|
82
|
-
uint8_t opacity =
|
|
82
|
+
uint8_t opacity = static_cast<uint8_t>(static_cast<uint16_t>(baseAlpha) / (pass + 1));
|
|
83
83
|
uint32_t col = ui_blend(shadowCol, inset ? (__ui_nodes[i].hasBg ? __ui_nodes[i].bg : clearCol) : clearCol, opacity);
|
|
84
84
|
if (inset) {
|
|
85
85
|
// Inset: draw inside the element, shrinking inward by pass.
|
|
@@ -104,7 +104,7 @@ static inline void ui_draw_shadow(uint16_t i, int16_t drawY, uint8_t insetOnly)
|
|
|
104
104
|
int16_t sw = bw + 2 * pass;
|
|
105
105
|
int16_t sh_ = bh + 2 * pass;
|
|
106
106
|
if (radius > 0) {
|
|
107
|
-
uint8_t r = radius + (
|
|
107
|
+
uint8_t r = radius + static_cast<uint8_t>(pass);
|
|
108
108
|
if (r > sw / 2) r = sw / 2;
|
|
109
109
|
if (r > sh_ / 2) r = sh_ / 2;
|
|
110
110
|
ui_display_fill_round_rect(sx, sy, sw, sh_, r, col);
|
|
@@ -176,7 +176,6 @@ static inline void ui_draw_node_border(uint16_t i, int16_t drawX, int16_t drawY,
|
|
|
176
176
|
if (__ui_nodes[i].hasPerSideBorder) {
|
|
177
177
|
int16_t w = __ui_nodes[i].box.w;
|
|
178
178
|
int16_t h = __ui_nodes[i].box.h;
|
|
179
|
-
uint8_t st = __ui_nodes[i].borderStyle;
|
|
180
179
|
// Top edge
|
|
181
180
|
if (__ui_nodes[i].borderTopWidth > 0) {
|
|
182
181
|
ui_display_fill_rect(drawX, drawY, w, __ui_nodes[i].borderTopWidth, color);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function emitNodeDrawBody(): string;
|