drawnui-react 0.1.0-preview.2 → 0.1.0-preview.21
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 +17 -4
- package/SKIPPED.md +33 -27
- package/dist/controls/AnimatedFramesRenderer.d.ts +7 -0
- package/dist/controls/AnimatedFramesRenderer.js +16 -1
- package/dist/controls/DrawnGame.d.ts +40 -0
- package/dist/controls/DrawnGame.js +64 -0
- package/dist/controls/GridStructure.d.ts +16 -2
- package/dist/controls/GridStructure.js +40 -4
- package/dist/controls/SkiaBackdrop.d.ts +8 -2
- package/dist/controls/SkiaBackdrop.js +48 -8
- package/dist/controls/SkiaButton.d.ts +19 -2
- package/dist/controls/SkiaButton.js +41 -11
- package/dist/controls/SkiaCarousel.d.ts +9 -1
- package/dist/controls/SkiaCarousel.js +16 -3
- package/dist/controls/SkiaCheckbox.d.ts +0 -1
- package/dist/controls/SkiaCheckbox.js +0 -6
- package/dist/controls/SkiaDrawer.d.ts +2 -0
- package/dist/controls/SkiaDrawer.js +2 -0
- package/dist/controls/SkiaEditor.d.ts +12 -1
- package/dist/controls/SkiaEditor.js +46 -19
- package/dist/controls/SkiaGif.d.ts +3 -0
- package/dist/controls/SkiaGif.js +12 -2
- package/dist/controls/SkiaImage.js +15 -10
- package/dist/controls/SkiaLabel.d.ts +54 -3
- package/dist/controls/SkiaLabel.js +235 -52
- package/dist/controls/SkiaLabelFps.d.ts +16 -0
- package/dist/controls/SkiaLabelFps.js +41 -0
- package/dist/controls/SkiaLayout.d.ts +64 -7
- package/dist/controls/SkiaLayout.js +316 -19
- package/dist/controls/SkiaLottie.js +4 -2
- package/dist/controls/SkiaProgress.d.ts +2 -1
- package/dist/controls/SkiaProgress.js +6 -3
- package/dist/controls/SkiaRadioButton.js +4 -3
- package/dist/controls/SkiaScroll.d.ts +35 -5
- package/dist/controls/SkiaScroll.js +233 -23
- package/dist/controls/SkiaScrollBar.d.ts +27 -0
- package/dist/controls/SkiaScrollBar.js +51 -2
- package/dist/controls/SkiaShaderCarousel.d.ts +5 -0
- package/dist/controls/SkiaShaderCarousel.js +5 -0
- package/dist/controls/SkiaShape.d.ts +13 -2
- package/dist/controls/SkiaShape.js +50 -10
- package/dist/controls/SkiaSlider.d.ts +20 -2
- package/dist/controls/SkiaSlider.js +59 -5
- package/dist/controls/SkiaSprite.d.ts +1 -0
- package/dist/controls/SkiaSprite.js +4 -0
- package/dist/controls/SkiaSvg.js +1 -1
- package/dist/controls/SkiaSwitch.d.ts +0 -1
- package/dist/controls/SkiaSwitch.js +0 -6
- package/dist/controls/SkiaToggle.d.ts +25 -5
- package/dist/controls/SkiaToggle.js +58 -5
- package/dist/controls/SnappingLayout.d.ts +12 -1
- package/dist/controls/SnappingLayout.js +19 -1
- package/dist/core/Accessibility.d.ts +80 -0
- package/dist/core/Accessibility.js +365 -8
- package/dist/core/Animators.d.ts +37 -1
- package/dist/core/Animators.js +102 -9
- package/dist/core/Canvas.d.ts +108 -7
- package/dist/core/Canvas.js +363 -35
- package/dist/core/Easing.d.ts +12 -1
- package/dist/core/Easing.js +25 -1
- package/dist/core/Gestures.d.ts +48 -2
- package/dist/core/Gestures.js +95 -3
- package/dist/core/Hover.d.ts +47 -0
- package/dist/core/Hover.js +134 -0
- package/dist/core/KeyboardManager.d.ts +13 -0
- package/dist/core/KeyboardManager.js +18 -0
- package/dist/core/ScrollAnimators.js +9 -0
- package/dist/core/SkiaControl.d.ts +216 -7
- package/dist/core/SkiaControl.js +516 -59
- package/dist/core/SkiaEffect.d.ts +17 -0
- package/dist/core/SkiaEffect.js +43 -8
- package/dist/core/SkiaImageManager.js +1 -1
- package/dist/core/Styles.d.ts +51 -0
- package/dist/core/Styles.js +92 -0
- package/dist/core/Super.d.ts +17 -1
- package/dist/core/Super.js +35 -4
- package/dist/core/ViewsAdapter.d.ts +7 -2
- package/dist/core/ViewsAdapter.js +10 -3
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/react/SkiaShell.js +33 -14
- package/dist/react/index.d.ts +15 -4
- package/dist/react/index.js +102 -15
- package/dist/react/reconciler.js +34 -12
- package/dist/vite/index.d.ts +9 -0
- package/dist/vite/index.js +36 -3
- package/package.json +33 -3
package/dist/core/Animators.js
CHANGED
|
@@ -16,7 +16,20 @@ export class AnimatorBase {
|
|
|
16
16
|
StartFrameTimeNanos = 0;
|
|
17
17
|
OnStart;
|
|
18
18
|
OnStop;
|
|
19
|
+
/** Paused: the canvas does not tick it and it wakes no frames; Resume goes on from where it was (C# Pause / Resume). */
|
|
20
|
+
IsPaused = false;
|
|
21
|
+
/** Paused by the canvas because its control is hidden; resumed when it shows again. */
|
|
22
|
+
PausedWhileHidden = false;
|
|
23
|
+
/**
|
|
24
|
+
* Frame time (ns) before which nothing it shows changes: the canvas does not tick it and it keeps no frames coming
|
|
25
|
+
* until then, a timer wakes the frame loop at that time (a GIF or a sprite between two frames; DrawnUi.Rust frame
|
|
26
|
+
* animators sleep between changes). 0 = tick every frame.
|
|
27
|
+
*/
|
|
28
|
+
SleepUntilNanos = 0;
|
|
19
29
|
delayHandle = 0;
|
|
30
|
+
delayEnd = 0;
|
|
31
|
+
delayLeft = 0;
|
|
32
|
+
pausedAt = 0;
|
|
20
33
|
constructor(parent) { this.Parent = parent; }
|
|
21
34
|
Register() {
|
|
22
35
|
const parent = this.Parent;
|
|
@@ -29,7 +42,14 @@ export class AnimatorBase {
|
|
|
29
42
|
if (!parent.PostAnimators.includes(effect))
|
|
30
43
|
parent.PostAnimators.push(effect);
|
|
31
44
|
}
|
|
32
|
-
const
|
|
45
|
+
const superview = parent.Superview;
|
|
46
|
+
const ok = superview?.RegisterAnimator(this) ?? false;
|
|
47
|
+
// C# SkiaControl.RegisterAnimator: not attached yet, queue it; the parent starts it on its first arrange
|
|
48
|
+
if (!superview && !parent.IsDisposed) {
|
|
49
|
+
const pending = parent.PendingUnattachedAnimators ??= [];
|
|
50
|
+
if (!pending.includes(this))
|
|
51
|
+
pending.push(this);
|
|
52
|
+
}
|
|
33
53
|
parent.Repaint();
|
|
34
54
|
return ok;
|
|
35
55
|
}
|
|
@@ -42,6 +62,9 @@ export class AnimatorBase {
|
|
|
42
62
|
if (i >= 0)
|
|
43
63
|
parent.PostAnimators.splice(i, 1);
|
|
44
64
|
}
|
|
65
|
+
const pending = parent.PendingUnattachedAnimators?.indexOf(this) ?? -1;
|
|
66
|
+
if (pending >= 0)
|
|
67
|
+
parent.PendingUnattachedAnimators.splice(pending, 1);
|
|
45
68
|
parent.Superview?.UnregisterAnimator(this.Uid);
|
|
46
69
|
}
|
|
47
70
|
Start(delayMs = 0) {
|
|
@@ -50,6 +73,8 @@ export class AnimatorBase {
|
|
|
50
73
|
this.delayHandle = 0;
|
|
51
74
|
}
|
|
52
75
|
if (delayMs > 0) {
|
|
76
|
+
// the delay waits without frames
|
|
77
|
+
this.delayEnd = performance.now() + delayMs;
|
|
53
78
|
this.delayHandle = window.setTimeout(() => { this.delayHandle = 0; this.Start(); }, delayMs);
|
|
54
79
|
return;
|
|
55
80
|
}
|
|
@@ -62,7 +87,43 @@ export class AnimatorBase {
|
|
|
62
87
|
}
|
|
63
88
|
}
|
|
64
89
|
}
|
|
90
|
+
/** Freezes the run (and what is left of a start delay); Resume goes on from there. */
|
|
91
|
+
Pause() {
|
|
92
|
+
if (this.IsPaused)
|
|
93
|
+
return;
|
|
94
|
+
this.IsPaused = true;
|
|
95
|
+
this.pausedAt = performance.now();
|
|
96
|
+
if (this.delayHandle) {
|
|
97
|
+
clearTimeout(this.delayHandle);
|
|
98
|
+
this.delayHandle = 0;
|
|
99
|
+
this.delayLeft = Math.max(0, this.delayEnd - this.pausedAt);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Goes on from where Pause froze it: the paused time is not counted. */
|
|
103
|
+
Resume() {
|
|
104
|
+
if (!this.IsPaused)
|
|
105
|
+
return;
|
|
106
|
+
this.IsPaused = false;
|
|
107
|
+
const paused = (performance.now() - this.pausedAt) * 1_000_000;
|
|
108
|
+
if (this.StartFrameTimeNanos !== 0) {
|
|
109
|
+
this.StartFrameTimeNanos += paused;
|
|
110
|
+
this.LastFrameTimeNanos += paused;
|
|
111
|
+
}
|
|
112
|
+
if (this.SleepUntilNanos !== 0)
|
|
113
|
+
this.SleepUntilNanos += paused;
|
|
114
|
+
if (this.delayLeft > 0) {
|
|
115
|
+
const left = this.delayLeft;
|
|
116
|
+
this.delayLeft = 0;
|
|
117
|
+
this.Start(left);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this.Parent?.Repaint(); // frames again
|
|
121
|
+
}
|
|
65
122
|
Stop() {
|
|
123
|
+
this.IsPaused = false;
|
|
124
|
+
this.PausedWhileHidden = false;
|
|
125
|
+
this.SleepUntilNanos = 0;
|
|
126
|
+
this.delayLeft = 0;
|
|
66
127
|
if (this.delayHandle) {
|
|
67
128
|
clearTimeout(this.delayHandle);
|
|
68
129
|
this.delayHandle = 0;
|
|
@@ -96,6 +157,21 @@ export class AnimatorBase {
|
|
|
96
157
|
this.OnStop?.();
|
|
97
158
|
}
|
|
98
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* DrawnUi ActionOnTickAnimator: runs `action(frameTimeNanos)` on every frame until stopped, a game loop for
|
|
162
|
+
* DrawnGame or any per-frame work.
|
|
163
|
+
*/
|
|
164
|
+
export class ActionOnTickAnimator extends AnimatorBase {
|
|
165
|
+
action;
|
|
166
|
+
constructor(parent, action) {
|
|
167
|
+
super(parent);
|
|
168
|
+
this.action = action;
|
|
169
|
+
}
|
|
170
|
+
TickFrame(frameTimeNanos) {
|
|
171
|
+
this.action(frameTimeNanos);
|
|
172
|
+
return super.TickFrame(frameTimeNanos);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
99
175
|
/** DrawnUi SkiaValueAnimator: drives mValue from mMinValue to mMaxValue over Speed ms with Easing. */
|
|
100
176
|
export class SkiaValueAnimator extends AnimatorBase {
|
|
101
177
|
mValue = 0;
|
|
@@ -130,23 +206,21 @@ export class SkiaValueAnimator extends AnimatorBase {
|
|
|
130
206
|
}
|
|
131
207
|
/** Passed over mValue; subclasses derive their own reported value here. */
|
|
132
208
|
TransformReportedValue(_deltaT) { return this.mValue; }
|
|
133
|
-
/**
|
|
209
|
+
/**
|
|
210
|
+
* Updates mValue from elapsed time; true when the run is over. The eased value is not clamped to the range: a spring
|
|
211
|
+
* easing goes past its ends, and a run whose mMinValue is above mMaxValue (a ping-pong's way back) goes down.
|
|
212
|
+
*/
|
|
134
213
|
UpdateValue(_deltaT, deltaFromStart) {
|
|
135
214
|
const elapsedMs = deltaFromStart / 1_000_000;
|
|
136
215
|
const progress = this.Speed > 0 ? elapsedMs / this.Speed : 1;
|
|
137
216
|
const deltaValue = this.mMaxValue - this.mMinValue;
|
|
138
217
|
const eased = this.Easing.Ease(Math.min(progress, 1));
|
|
139
218
|
this.Progress = eased;
|
|
140
|
-
|
|
141
|
-
if (value < this.mMinValue) {
|
|
142
|
-
this.mValue = this.mMinValue;
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
if (value >= this.mMaxValue || progress >= 1) {
|
|
219
|
+
if (progress >= 1) {
|
|
146
220
|
this.mValue = this.mMaxValue;
|
|
147
221
|
return true;
|
|
148
222
|
}
|
|
149
|
-
this.mValue =
|
|
223
|
+
this.mValue = deltaValue * eased + this.mMinValue;
|
|
150
224
|
return false;
|
|
151
225
|
}
|
|
152
226
|
FinishedRunning() {
|
|
@@ -163,6 +237,25 @@ export class SkiaValueAnimator extends AnimatorBase {
|
|
|
163
237
|
return true;
|
|
164
238
|
}
|
|
165
239
|
}
|
|
240
|
+
/** DrawnUi PingPongAnimator: every repeat runs the other way (Repeat -1 = forever by default). */
|
|
241
|
+
export class PingPongAnimator extends SkiaValueAnimator {
|
|
242
|
+
/** One way done, the next starts (C# CycleFInished). */
|
|
243
|
+
CycleFinished;
|
|
244
|
+
constructor(parent) { super(parent); this.Repeat = -1; }
|
|
245
|
+
FinishedRunning() {
|
|
246
|
+
if (this.Repeat !== 0) {
|
|
247
|
+
this.CycleFinished?.();
|
|
248
|
+
if (this.Repeat > 0)
|
|
249
|
+
this.Repeat--;
|
|
250
|
+
[this.mMinValue, this.mMaxValue] = [this.mMaxValue, this.mMinValue];
|
|
251
|
+
this.mValue = this.mMinValue;
|
|
252
|
+
this.LastFrameTimeNanos = 0;
|
|
253
|
+
this.StartFrameTimeNanos = 0;
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
return super.FinishedRunning();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
166
259
|
/** DrawnUi RenderingAnimator: a value animator that paints itself above its Parent (IOverlayEffect). */
|
|
167
260
|
export class RenderingAnimator extends SkiaValueAnimator {
|
|
168
261
|
constructor(parent) { super(parent); }
|
package/dist/core/Canvas.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Surface } from "canvaskit-wasm";
|
|
2
|
-
import type { SkiaControl } from "./SkiaControl";
|
|
2
|
+
import type { DrawingContext, SkiaControl } from "./SkiaControl";
|
|
3
3
|
import type { AnimatorBase } from "./Animators";
|
|
4
4
|
import { SkiaAccessibilityManager } from "./Accessibility";
|
|
5
|
+
import { HoverManager } from "./Hover";
|
|
5
6
|
import { type Color, type RenderingModeType } from "./Types";
|
|
6
7
|
import { ContextMenuEventArgs, type GesturesMode, SkiaGesturesParameters, TouchActionEventArgs } from "./Gestures";
|
|
7
8
|
/**
|
|
@@ -14,6 +15,11 @@ export declare class Canvas {
|
|
|
14
15
|
readonly Element: HTMLCanvasElement;
|
|
15
16
|
/** Points a pointer may travel between Down and Up and still count as a tap (AppoMobi TouchEffect default). */
|
|
16
17
|
static TappedCancelMoveThresholdPoints: number;
|
|
18
|
+
/**
|
|
19
|
+
* A press held this long without moving past TappedCancelMoveThresholdPoints is a LongPressing, at the press point
|
|
20
|
+
* (AppoMobi TouchEffect, DrawnUi.Rust LONG_PRESS_MS); its release sends no Tapped. A timer, no frames while waiting.
|
|
21
|
+
*/
|
|
22
|
+
static LongPressTimeMs: number;
|
|
17
23
|
BackgroundColor: Color;
|
|
18
24
|
/** Accelerated = WebGL surface, Default = software. Read once at first frame. */
|
|
19
25
|
RenderingMode: RenderingModeType;
|
|
@@ -23,8 +29,22 @@ export declare class Canvas {
|
|
|
23
29
|
/** Frames per second over the last second of drawn frames. */
|
|
24
30
|
FPS: number;
|
|
25
31
|
private frameTimes;
|
|
32
|
+
/** DrawnView.WasRendered: a frame has been drawn on a ready surface (set after the first one completes). */
|
|
33
|
+
WasRendered: boolean;
|
|
34
|
+
/** DrawnView.CanRender: the surface (and its GPU context when accelerated) is ready to draw. */
|
|
35
|
+
get CanRender(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* DrawnView.WillFirstTimeDraw: raised once, right before the first frame drawn on a ready surface, with that
|
|
38
|
+
* frame's drawing context. The engine draws its first frame while it is being constructed (so the page never shows
|
|
39
|
+
* an unpainted canvas): pass it through the constructor's `init` to receive that frame.
|
|
40
|
+
*/
|
|
41
|
+
WillFirstTimeDraw?: (sender: Canvas, context: DrawingContext["Context"]) => void;
|
|
42
|
+
/** DrawnView.WasDrawn: raised after every frame has been drawn (the C# event passes no context). */
|
|
43
|
+
WasDrawn?: (sender: Canvas) => void;
|
|
26
44
|
/** Registry + rate-limited snapshot of accessible controls, rendered by the DOM overlay (DrawnUi AccessibilityManager). */
|
|
27
45
|
readonly AccessibilityManager: SkiaAccessibilityManager;
|
|
46
|
+
/** Mouse hover of the controls (drawnui-cross 6m): ReceivesHover / IsHovered / HoverChanged. */
|
|
47
|
+
readonly Hover: HoverManager;
|
|
28
48
|
private content?;
|
|
29
49
|
get Content(): SkiaControl | undefined;
|
|
30
50
|
set Content(value: SkiaControl | undefined);
|
|
@@ -35,7 +55,15 @@ export declare class Canvas {
|
|
|
35
55
|
private frameId;
|
|
36
56
|
private disposed;
|
|
37
57
|
private readonly observer;
|
|
38
|
-
|
|
58
|
+
/** The WebGL context is lost: no frames until the browser restores it. */
|
|
59
|
+
private contextLost;
|
|
60
|
+
/**
|
|
61
|
+
* Bumped when the WebGL context was restored: every GPU object made before (Image caches, picture caches that may
|
|
62
|
+
* replay them, kept composite surfaces, effect textures) is remade at its next draw (DrawnUi.Rust Gpu::epoch).
|
|
63
|
+
*/
|
|
64
|
+
GpuEpoch: number;
|
|
65
|
+
/** `init` runs before the first frame is drawn: the place to attach `WillFirstTimeDraw` / `WasDrawn` for that frame. */
|
|
66
|
+
constructor(Element: HTMLCanvasElement, init?: (canvas: Canvas) => void);
|
|
39
67
|
/** Request a redraw (full measure + arrange + render) on the next animation frame. */
|
|
40
68
|
Update(): void;
|
|
41
69
|
/** Deletes the current surface; a pending frame on it is cancelled first (drawing on a deleted surface faults). */
|
|
@@ -48,6 +76,17 @@ export declare class Canvas {
|
|
|
48
76
|
* redrawn content lands in the same paint and no blank frame is ever shown while dragging.
|
|
49
77
|
*/
|
|
50
78
|
private OnResized;
|
|
79
|
+
/** WebGL context lost: keep the browser restoring it (preventDefault) and stop the frames. */
|
|
80
|
+
private readonly onContextLost;
|
|
81
|
+
/**
|
|
82
|
+
* WebGL context restored (as DrawnUi.Rust and the C# Wasm / Blazor heads): every GL object of the lost generation is
|
|
83
|
+
* gone. The old Skia context is abandoned first, while its own GL handle is current and before the new context makes
|
|
84
|
+
* any object, so its GL calls reach only lost-generation objects. CanvasKit exposes no `abandonContext`;
|
|
85
|
+
* `releaseResourcesAndAbandonContext` is its only way to abandon, and after it freeing an old image or surface makes no
|
|
86
|
+
* GL call. Then the same WebGL object is registered again (the old handle deleted first, which clears the canvas'
|
|
87
|
+
* context object) with a new GrContext and surface; GpuEpoch makes the old generation's GPU objects remake themselves.
|
|
88
|
+
*/
|
|
89
|
+
private readonly onContextRestored;
|
|
51
90
|
/** Draws one frame immediately (outside the rAF loop) and presents it. */
|
|
52
91
|
private DrawNow;
|
|
53
92
|
private Draw;
|
|
@@ -62,8 +101,20 @@ export declare class Canvas {
|
|
|
62
101
|
UnregisterAnimator(uid: number): void;
|
|
63
102
|
/** Ticks every registered animator once; returns how many ran. */
|
|
64
103
|
protected ExecuteAnimators(frameTimeNanos: number): number;
|
|
104
|
+
private wakeTimer;
|
|
105
|
+
private wakeAtNanos;
|
|
106
|
+
/** One timer for the earliest sleeping animator: the frame loop wakes then, no frames run in between. */
|
|
107
|
+
private WakeAt;
|
|
65
108
|
/** Frames drawn so far (SkiaBackdrop uses it to refresh once after a cached record). */
|
|
66
109
|
FrameIndex: number;
|
|
110
|
+
/**
|
|
111
|
+
* DrawnView.WheelDeltaPerNotch: the Wheel.Delta one mouse-wheel notch produces, 100 CSS pixels in Chrome and Edge. A
|
|
112
|
+
* scroll moves by the event's share of a notch, so a touchpad, which sends many small events, scrolls as far as the
|
|
113
|
+
* fingers moved. 0 = units unknown: every event scrolls one line.
|
|
114
|
+
*/
|
|
115
|
+
WheelDeltaPerNotch: number;
|
|
116
|
+
/** Vsync time of the last frame the animators ran on (nanoseconds, the performance.now() timeline). */
|
|
117
|
+
FrameTimeNanos: number;
|
|
67
118
|
/** On-screen surface (SkiaBackdrop snapshots it). */
|
|
68
119
|
get Surface(): Surface | undefined;
|
|
69
120
|
/**
|
|
@@ -87,7 +138,13 @@ export declare class Canvas {
|
|
|
87
138
|
private readonly previousTouchArgs;
|
|
88
139
|
private readonly pendingGestures;
|
|
89
140
|
private readonly onPointer;
|
|
141
|
+
/** The mouse left the canvas: hover ends at once, also while content moves. */
|
|
142
|
+
private readonly onPointerLeave;
|
|
90
143
|
private readonly preventTouch;
|
|
144
|
+
/** Gestures="Enabled": touch / pen pointers whose Down a control used (see OnTouchAction). */
|
|
145
|
+
private readonly claimedTouches;
|
|
146
|
+
/** Gestures="Enabled": while a claimed touch is down the page may not take its drag. */
|
|
147
|
+
private readonly preventClaimedTouch;
|
|
91
148
|
/** Called when no control handled a context-menu request; return true to suppress the browser's canvas menu. */
|
|
92
149
|
ContextMenu?: (sender: Canvas, e: ContextMenuEventArgs) => boolean | void;
|
|
93
150
|
/** DOM contextmenu (right click / long press / Menu key) -> ContextMenuEventArgs routed through the tree like a tap. */
|
|
@@ -95,20 +152,64 @@ export declare class Canvas {
|
|
|
95
152
|
private cursorPointer;
|
|
96
153
|
/**
|
|
97
154
|
* DrawnUi.Blazor shows `cursor: pointer` over interactive controls through its overlay elements; here the overlay
|
|
98
|
-
* is pointer-events:none, so the
|
|
99
|
-
*
|
|
100
|
-
* (itself tappable, or a tappable span of a label)
|
|
101
|
-
*
|
|
155
|
+
* is pointer-events:none, so the canvas decides from the hover hit path (Hover.Path: the controls under the mouse by
|
|
156
|
+
* the routing rules of ProcessGestures, so nothing below a popup that blocks gestures below): a control in the
|
|
157
|
+
* accessibility tree (it has a role) that answers WantsPointerCursor (itself tappable, or a tappable span of a label)
|
|
158
|
+
* shows the hand. A popup's close-on-background-tap wrapper has no role, so its backdrop shows none. The canvas
|
|
159
|
+
* element's cursor is switched only when the answer changes. Mouse moves only, none in the frame loop.
|
|
102
160
|
*/
|
|
103
161
|
private UpdateCursor;
|
|
104
|
-
/**
|
|
162
|
+
/**
|
|
163
|
+
* Mouse wheel -> TouchActionResult.Wheel.
|
|
164
|
+
* Lock keeps every wheel on the canvas. Enabled shares it with the page, like DrawnUi.Blazor's
|
|
165
|
+
* TouchHandlingStyle.Manual: the page scrolls unless a control consumed this wheel. The browser needs that answer
|
|
166
|
+
* inside this handler, so the wheel is processed now instead of at the next frame (Blazor does the same, for the
|
|
167
|
+
* same reason); pending gestures are flushed first so the event order is kept.
|
|
168
|
+
*/
|
|
105
169
|
private readonly onWheel;
|
|
170
|
+
/**
|
|
171
|
+
* Processes one gesture immediately (after whatever is queued) and reports whether a control USED it: a consumer
|
|
172
|
+
* that marked the event Handled, or any consumer that is not a `BlockGesturesBelow` layer. A blocker returns itself
|
|
173
|
+
* for every gesture it keeps from the controls below (a shell page, a popup backdrop), which is not a use: counting
|
|
174
|
+
* it would block the page wheel over every shell app.
|
|
175
|
+
*/
|
|
176
|
+
private ProcessGestureNow;
|
|
177
|
+
/**
|
|
178
|
+
* The page axes a touch pan over the canvas hands to the browser: "pan-y" when the page (or a scrolling ancestor) can
|
|
179
|
+
* scroll vertically, "pan-x" horizontally, both, or "none". Mirrors MAUI's Gestures="Enabled" inside a native scroll
|
|
180
|
+
* view, where the parent takes the pans it scrolls in.
|
|
181
|
+
*/
|
|
182
|
+
private static PageScrollAxes;
|
|
183
|
+
/**
|
|
184
|
+
* Gestures="Enabled" shares touch pans with the page like MAUI's Enabled inside a native scroll view: along an axis
|
|
185
|
+
* the page can scroll, the browser takes the pan (and sends pointercancel), taps and the other axis stay on the
|
|
186
|
+
* canvas. A page that cannot scroll, and Lock, keep every touch. The browser reads touch-action when a touch starts,
|
|
187
|
+
* so it is kept current ahead of time: on attach, when the window / html / body resize, and after every touch.
|
|
188
|
+
*/
|
|
189
|
+
private readonly UpdateTouchAction;
|
|
190
|
+
private pageObserver?;
|
|
106
191
|
private AttachInput;
|
|
192
|
+
/** The page's own overscroll-behavior before Lock set it to none (html, body), put back on detach. */
|
|
193
|
+
private pageOverscroll?;
|
|
107
194
|
private DetachInput;
|
|
108
195
|
/** Port of DrawnUi.Blazor Canvas.OnTouchAction: per-pointer state machine producing Down / Panning / Tapped / Up. */
|
|
109
196
|
OnTouchAction(args: TouchActionEventArgs): void;
|
|
197
|
+
private readonly longPressTimers;
|
|
198
|
+
private readonly longPressed;
|
|
199
|
+
/** The long press of a new press: due LongPressTimeMs later unless the pointer moves away or lets go. */
|
|
200
|
+
private ArmLongPress;
|
|
201
|
+
private DisarmLongPress;
|
|
110
202
|
private OnGestureEvent;
|
|
111
203
|
private ProcessPendingGestures;
|
|
204
|
+
/**
|
|
205
|
+
* The control that consumed the current gesture keeps it until it lets go (DrawnUi Canvas.HadInput). Without this a
|
|
206
|
+
* gesture is re-routed by the pointer position on every event, so anything the finger drags away from — a drag
|
|
207
|
+
* handle, a slider thumb, a button being held — stops receiving Panning the moment the pointer leaves its box.
|
|
208
|
+
* Single pointer, which is what the web gives us here; C# keeps a set for multi-touch.
|
|
209
|
+
*/
|
|
210
|
+
private gestureOwner;
|
|
211
|
+
/** DrawnUi IsSavedGesture: the types replayed to the owner instead of being routed again. */
|
|
212
|
+
private static IsSavedGesture;
|
|
112
213
|
/** Entry into the control tree, same shape as DrawnUi Canvas.ProcessGestures. */
|
|
113
214
|
protected ProcessGestures(root: SkiaControl, args: SkiaGesturesParameters): SkiaControl | null;
|
|
114
215
|
}
|