@omnipad/vue 0.1.1-alpha.0 → 0.2.0-alpha.2

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.
@@ -1,560 +1,81 @@
1
- import { defineComponent as P, h as oe, shallowRef as se, ref as D, onMounted as re, onUnmounted as ae, openBlock as p, createElementBlock as E, Fragment as ce, renderList as le, createBlock as C, resolveDynamicComponent as Y, unref as h, renderSlot as k, inject as ue, computed as y, provide as de, useSlots as fe, watch as he, nextTick as pe, normalizeStyle as _, createVNode as L, withCtx as K, createElementVNode as G, createCommentVNode as T, Transition as ve, normalizeClass as j, toDisplayString as me } from "vue";
2
- var ge = Object.defineProperty, ye = (e, t, n) => t in e ? ge(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n, g = (e, t, n) => ye(e, typeof t != "symbol" ? t + "" : t, n), v = {
3
- // --- Zones ---
4
- /** Area responsible for capturing touches and spawning dynamic widgets */
5
- INPUT_ZONE: "input-zone",
6
- /** Area responsible for receiving signals and simulating DOM events */
7
- TARGET_ZONE: "target-zone",
8
- // --- Widgets ---
9
- /** Simulates a physical keyboard key press */
10
- KEYBOARD_BUTTON: "keyboard-button",
11
- /** The top-level managed container */
12
- ROOT_LAYER: "root-layer"
13
- }, f = {
14
- KEYDOWN: "keydown",
15
- KEYUP: "keyup",
16
- POINTER: "pointer",
17
- POINTERMOVE: "pointermove",
18
- POINTERDOWN: "pointerdown",
19
- POINTERUP: "pointerup",
20
- MOUSE: "mouse",
21
- MOUSEMOVE: "mousemove",
22
- MOUSEDOWN: "mousedown",
23
- MOUSEUP: "mouseup",
24
- CLICK: "click"
25
- }, W = {
26
- /** The key used to propagate Parent IDs through the component tree */
27
- PARENT_ID_KEY: "omnipad-parent-id-link"
28
- }, X = (e, t = 2) => {
29
- const n = Math.pow(10, t);
30
- return Math.round(e * n) / n;
31
- }, A = (e, t) => X(e * t / 100), z = (e, t) => t === 0 ? 0 : X(e * 100 / t), H = (e, t) => {
32
- let n = document.elementFromPoint(e, t);
33
- for (; n && n.shadowRoot; ) {
34
- const i = n.shadowRoot.elementFromPoint(e, t);
35
- if (!i || i === n) break;
36
- n = i;
37
- }
38
- return n;
39
- }, J = () => {
40
- let e = document.activeElement;
41
- for (; e && e.shadowRoot && e.shadowRoot.activeElement; )
42
- e = e.shadowRoot.activeElement;
43
- return e;
44
- }, Ee = (e) => {
45
- J() !== e && (e.hasAttribute("tabindex") || e.setAttribute("tabindex", "-1"), e.focus());
46
- }, Pe = (e, t) => {
47
- const n = new KeyboardEvent(e, {
48
- ...t,
49
- which: t.keyCode,
50
- // Support for legacy Flash engines
51
- bubbles: !0,
52
- cancelable: !0,
53
- view: window
54
- });
55
- window.dispatchEvent(n);
56
- }, be = (e, t, n, i = {}) => {
57
- const o = H(t, n);
58
- if (!o) return;
59
- const s = {
60
- bubbles: !0,
61
- cancelable: !0,
62
- composed: !0,
63
- // Crucial for piercing Shadow DOM boundaries
64
- clientX: t,
65
- clientY: n,
66
- view: window,
67
- ...i
68
- };
69
- if (e.startsWith("pointer")) {
70
- o.dispatchEvent(
71
- new PointerEvent(e, {
72
- isPrimary: !0,
73
- pointerId: 1,
74
- pointerType: "mouse",
75
- // Emulate mouse behavior for Flash MouseOver/Down logic
76
- ...s
77
- })
78
- );
79
- const r = e.replace("pointer", "mouse");
80
- o.dispatchEvent(new MouseEvent(r, s));
81
- } else
82
- o.dispatchEvent(new MouseEvent(e, s));
83
- }, Ie = (e = "omnipad") => {
84
- const t = Date.now().toString(36), n = Math.random().toString(36).substring(2, 6);
85
- return `${e}-${t}-${n}`;
86
- }, V = (e) => {
87
- if (!e) return {};
88
- const t = {};
89
- t.position = "absolute", ["left", "top", "right", "bottom", "width", "height"].forEach((o) => {
90
- const s = e[o];
91
- s !== void 0 && (t[o] = typeof s == "number" ? `${s}px` : s);
92
- }), e.zIndex !== void 0 && (t.zIndex = e.zIndex);
93
- const i = {
94
- "top-left": "translate(0, 0)",
95
- "top-center": "translate(-50%, 0)",
96
- "top-right": "translate(-100%, 0)",
97
- "center-left": "translate(0, -50%)",
98
- center: "translate(-50%, -50%)",
99
- "center-right": "translate(-100%, -50%)",
100
- "bottom-left": "translate(0, -100%)",
101
- "bottom-center": "translate(-50%, -100%)",
102
- "bottom-right": "translate(-100%, -100%)"
103
- };
104
- return e.anchor && (t.transform = i[e.anchor]), t;
105
- }, _e = class {
106
- constructor() {
107
- g(this, "listeners", /* @__PURE__ */ new Set());
108
- }
109
- /**
110
- * Registers a callback function to be executed whenever data is emitted.
111
- *
112
- * @param fn - The callback function.
113
- * @returns A function that, when called, unsubscribes the listener.
114
- */
115
- subscribe(e) {
116
- return this.listeners.add(e), () => this.listeners.delete(e);
117
- }
118
- /**
119
- * Broadcasts the provided data to all registered listeners.
120
- * Each listener is executed within a try-catch block to ensure that
121
- * an error in one subscriber doesn't prevent others from receiving the signal.
122
- *
123
- * @param data - The payload to be sent to all subscribers.
124
- */
125
- emit(e) {
126
- this.listeners.forEach((t) => {
127
- try {
128
- t(e);
129
- } catch (n) {
130
- console.error("[OmniPad-Core] Emitter callback error:", n);
131
- }
132
- });
133
- }
134
- /**
135
- * Removes all listeners and clears the subscription set.
136
- * Essential for preventing memory leaks when an Entity is destroyed.
137
- */
138
- clear() {
139
- this.listeners.clear();
140
- }
141
- }, R = class {
142
- constructor(e, t, n, i) {
143
- g(this, "uid"), g(this, "type"), g(this, "config"), g(this, "state"), g(this, "rect", null), g(this, "stateEmitter", new _e()), this.uid = e, this.type = t, this.config = n, this.state = i;
144
- }
145
- // --- IObservable Implementation ---
146
- subscribe(e) {
147
- return e(this.state), this.stateEmitter.subscribe(e);
148
- }
149
- // --- State Management ---
150
- /**
151
- * Updates the internal state and notifies all subscribers.
152
- *
153
- * @param partialState - Partial object containing updated state values.
154
- */
155
- setState(e) {
156
- this.state = { ...this.state, ...e }, this.stateEmitter.emit(this.state);
157
- }
158
- // --- Lifecycle ---
159
- destroy() {
160
- this.reset(), this.stateEmitter.clear(), Z.getInstance().unregister(this.uid);
161
- }
162
- updateRect(e) {
163
- this.rect = e;
164
- }
165
- updateConfig(e) {
166
- this.config = { ...this.config, ...e }, this.stateEmitter.emit(this.state);
167
- }
168
- getState() {
169
- return this.state;
170
- }
171
- getConfig() {
172
- return this.config;
173
- }
174
- }, B = /* @__PURE__ */ Symbol.for("omnipad.registry.instance"), Z = class Q {
175
- /**
176
- * Private constructor to enforce singleton pattern.
177
- */
178
- constructor() {
179
- g(this, "entities", /* @__PURE__ */ new Map());
180
- }
181
- /**
182
- * Retrieves the global instance of the Registry.
183
- * Uses globalThis to ensure the instance is unique even if the library is loaded multiple times.
184
- */
185
- static getInstance() {
186
- const t = globalThis;
187
- return t[B] || (t[B] = new Q()), t[B];
188
- }
189
- register(t) {
190
- if (!t.uid) {
191
- console.warn("[OmniPad-Core] Registry: Attempted to register entity without UID.", t);
192
- return;
193
- }
194
- this.entities.has(t.uid), this.entities.set(t.uid, t);
195
- }
196
- unregister(t) {
197
- this.entities.has(t) && this.entities.delete(t);
198
- }
199
- getEntity(t) {
200
- return this.entities.get(t);
201
- }
202
- getAllEntities() {
203
- return Array.from(this.entities.values());
204
- }
205
- getEntitiesByRoot(t) {
206
- const n = this.getAllEntities();
207
- if (!t) return n;
208
- if (!this.entities.get(t))
209
- return console.warn(`[OmniPad-Core] Registry: Root entity ${t} not found.`), [];
210
- const o = /* @__PURE__ */ new Map();
211
- n.forEach((c) => {
212
- if (c instanceof R) {
213
- const l = c.getConfig();
214
- l.parentId && (o.has(l.parentId) || o.set(l.parentId, []), o.get(l.parentId).push(c));
215
- }
216
- });
217
- const s = [], r = [t], a = /* @__PURE__ */ new Set();
218
- for (; r.length > 0; ) {
219
- const c = r.shift();
220
- if (a.has(c)) continue;
221
- a.add(c);
222
- const l = this.entities.get(c);
223
- if (l) {
224
- s.push(l);
225
- const u = o.get(c);
226
- u && u.forEach((m) => r.push(m.uid));
227
- }
228
- }
229
- return s;
230
- }
231
- destroyByRoot(t) {
232
- const n = this.getEntitiesByRoot(t);
233
- for (let i = n.length - 1; i >= 0; i--) {
234
- const o = n[i];
235
- try {
236
- o.destroy();
237
- } catch (s) {
238
- console.error(`[OmniPad-Core] Error during destroyByRoot at ${o.uid}:`, s);
239
- }
240
- }
241
- }
242
- clear() {
243
- this.entities.clear();
244
- }
245
- resetAll() {
246
- this.entities.forEach((t) => {
247
- "reset" in t && t.reset();
248
- });
249
- }
250
- debugGetSnapshot() {
251
- return new Map(this.entities);
252
- }
253
- }, Te = {
254
- isDynamicActive: !1,
255
- dynamicPointerId: null,
256
- dynamicPosition: { x: 0, y: 0 }
257
- }, Re = class extends R {
258
- constructor(e, t) {
259
- super(e, v.INPUT_ZONE, t, Te);
260
- }
261
- onPointerDown(e) {
262
- if (this.state.isDynamicActive || e.target !== e.currentTarget) return;
263
- e.cancelable && e.preventDefault();
264
- const t = this.calculateRelativePosition(e.clientX, e.clientY);
265
- this.setState({
266
- isDynamicActive: !0,
267
- dynamicPointerId: e.pointerId,
268
- dynamicPosition: t
269
- });
270
- }
271
- onPointerMove(e) {
272
- !this.state.isDynamicActive || (e.pointerId, this.state.dynamicPointerId);
273
- }
274
- onPointerUp(e) {
275
- this.handleRelease(e);
276
- }
277
- onPointerCancel(e) {
278
- this.handleRelease(e);
279
- }
280
- /**
281
- * Internal helper to handle pointer release and cleanup.
282
- */
283
- handleRelease(e) {
284
- if (e.pointerId === this.state.dynamicPointerId) {
285
- try {
286
- e.currentTarget.releasePointerCapture(e.pointerId);
287
- } catch {
288
- }
289
- this.setState({
290
- isDynamicActive: !1,
291
- dynamicPointerId: null
292
- });
293
- }
294
- }
295
- // --- Helper Calculations ---
296
- /**
297
- * Converts viewport pixels to percentage coordinates relative to the zone.
298
- */
299
- calculateRelativePosition(e, t) {
300
- return this.rect ? {
301
- x: z(e - this.rect.left, this.rect.width),
302
- y: z(t - this.rect.top, this.rect.height)
303
- } : { x: 0, y: 0 };
304
- }
305
- /**
306
- * Whether the interceptor layer should be enabled.
307
- */
308
- get isInterceptorRequired() {
309
- return !!(this.config.dynamicWidgetId || this.config.preventFocusLoss);
310
- }
311
- reset() {
312
- this.setState({
313
- isDynamicActive: !1,
314
- dynamicPointerId: null
315
- });
316
- }
317
- }, F = {
318
- isActive: !1,
319
- isPressed: !1,
320
- pointerId: null,
321
- value: 0
322
- }, we = class extends R {
323
- /**
324
- * Creates an instance of KeyboardButtonCore.
325
- *
326
- * @param uid - The unique entity ID.
327
- * @param config - The flat configuration object for the button.
328
- */
329
- constructor(e, t) {
330
- super(e, v.KEYBOARD_BUTTON, t, F);
331
- }
332
- // --- IPointerHandler Implementation ---
333
- onPointerDown(e) {
334
- e.cancelable && e.preventDefault(), e.target.setPointerCapture(e.pointerId), this.setState({
335
- isActive: !0,
336
- isPressed: !0,
337
- pointerId: e.pointerId
338
- }), this.sendInputSignal(f.KEYDOWN);
339
- }
340
- onPointerUp(e) {
341
- e.cancelable && e.preventDefault(), this.handleRelease(e);
342
- }
343
- onPointerCancel(e) {
344
- this.handleRelease(e);
345
- }
346
- onPointerMove(e) {
347
- e.cancelable && e.preventDefault();
348
- }
349
- // --- Internal Logic ---
350
- /**
351
- * Common logic for releasing the button state.
352
- *
353
- * @param e - The pointer event that triggered the release.
354
- */
355
- handleRelease(e) {
356
- this.state.pointerId === e.pointerId && (e.target.hasPointerCapture(e.pointerId) && e.target.releasePointerCapture(e.pointerId), this.setState(F), this.sendInputSignal(f.KEYUP));
357
- }
358
- /**
359
- * Dispatches input signals to the registered target stage.
360
- *
361
- * @param type - The action type (keydown or keyup).
362
- */
363
- sendInputSignal(e) {
364
- const t = this.config.targetStageId;
365
- if (!t) return;
366
- const n = Z.getInstance().getEntity(t);
367
- if (n && typeof n.handleSignal == "function") {
368
- const i = {
369
- targetStageId: t,
370
- type: e,
371
- payload: {
372
- key: this.config.mapping.key,
373
- code: this.config.mapping.code,
374
- keyCode: this.config.mapping.keyCode
375
- }
376
- };
377
- n.handleSignal(i);
378
- }
379
- }
380
- // --- IResettable Implementation ---
381
- reset() {
382
- this.state.isPressed && this.sendInputSignal(f.KEYUP), this.setState(F);
383
- }
384
- }, Oe = {
385
- isHighlighted: !1
386
- }, Se = class extends R {
387
- constructor(e, t) {
388
- super(e, v.ROOT_LAYER, t, Oe);
389
- }
390
- reset() {
391
- }
392
- }, Ne = {
393
- position: { x: 50, y: 50 },
394
- isVisible: !1,
395
- isPointerDown: !1,
396
- isFocusReturning: !1
397
- }, Ae = class extends R {
398
- constructor(e, t) {
399
- super(e, v.TARGET_ZONE, t, Ne), g(this, "hideTimer", null), g(this, "focusFeedbackTimer", null);
400
- }
401
- // --- ISignalReceiver Implementation ---
402
- handleSignal(e) {
403
- const { type: t, payload: n } = e;
404
- switch (this.ensureFocus(), t) {
405
- case f.KEYDOWN:
406
- case f.KEYUP:
407
- Pe(t, n);
408
- break;
409
- case f.MOUSEMOVE:
410
- n.point && (this.updateCursorPosition(n.point), this.config.cursorEnabled && this.showCursor(), this.executeMouseAction(f.POINTERMOVE, n));
411
- break;
412
- case f.MOUSEDOWN:
413
- case f.MOUSEUP:
414
- case f.CLICK:
415
- this.config.cursorEnabled && this.showCursor(), this.executeMouseAction(
416
- t.startsWith(f.MOUSE) ? t.replace(f.MOUSE, f.POINTER) : t,
417
- n
418
- );
419
- break;
420
- }
421
- }
422
- // --- Mouse & Pointer Simulation ---
423
- /**
424
- * Calculates pixel coordinates and dispatches simulated pointer events to the deepest element.
425
- *
426
- * @param pointerType - The specific pointer event type (e.g., pointermove, pointerdown).
427
- * @param payload - Data containing point coordinates or button info.
428
- */
429
- executeMouseAction(e, t) {
430
- if (!this.rect) return;
431
- e === f.POINTERDOWN && this.setState({ isPointerDown: !0 }), e === f.POINTERUP && this.setState({ isPointerDown: !1 });
432
- const n = t.point || this.state.position, i = this.rect.left + A(n.x, this.rect.width), o = this.rect.top + A(n.y, this.rect.height);
433
- be(e, i, o, {
434
- button: t.button ?? 0,
435
- buttons: this.state.isPointerDown ? 1 : 0
436
- });
437
- }
438
- // --- Focus Management ---
439
- /**
440
- * Checks if the target element under the virtual cursor has focus, and reclaims it if lost.
441
- */
442
- ensureFocus() {
443
- if (!this.rect) return;
444
- const e = this.rect.left + A(this.state.position.x, this.rect.width), t = this.rect.top + A(this.state.position.y, this.rect.height), n = H(e, t);
445
- n && J() !== n && (Ee(n), this.triggerFocusFeedback());
446
- }
447
- /**
448
- * Activates a temporary visual feedback state to indicate a focus-reclaim event.
449
- */
450
- triggerFocusFeedback() {
451
- this.setState({ isFocusReturning: !0 }), this.focusFeedbackTimer && clearTimeout(this.focusFeedbackTimer), this.focusFeedbackTimer = setTimeout(() => this.setState({ isFocusReturning: !1 }), 500);
452
- }
453
- // --- Cursor State Helpers ---
454
- /**
455
- * Updates the internal virtual cursor coordinates.
456
- */
457
- updateCursorPosition(e) {
458
- this.setState({ position: { ...e } });
459
- }
460
- /**
461
- * Makes the virtual cursor visible and sets a timeout for auto-hiding.
462
- */
463
- showCursor() {
464
- this.setState({ isVisible: !0 }), this.hideTimer && clearTimeout(this.hideTimer), this.config.cursorAutoDelay && this.config.cursorAutoDelay > 0 && (this.hideTimer = setTimeout(
465
- () => this.setState({ isVisible: !1 }),
466
- this.config.cursorAutoDelay
467
- ));
468
- }
469
- // --- IResettable Implementation ---
470
- reset() {
471
- this.state.isPointerDown && this.executeMouseAction(f.POINTERUP, {}), this.hideTimer && clearTimeout(this.hideTimer), this.focusFeedbackTimer && clearTimeout(this.focusFeedbackTimer), this.setState({
472
- isVisible: !1,
473
- isPointerDown: !1,
474
- isFocusReturning: !1
475
- });
476
- }
477
- };
478
- const q = {};
479
- function x(e, t) {
480
- q[e] = t;
1
+ import { Registry as G, CONTEXT as K, generateUID as X, CMP_TYPES as P, resolveLayoutStyle as S, InputZoneCore as H, RootLayerCore as J, TargetZoneCore as Q, KeyboardButtonCore as q, MouseButtonCore as ee, TrackpadCore as te } from "@omnipad/core";
2
+ import { defineComponent as b, h as oe, shallowRef as ne, ref as O, onMounted as ae, onUnmounted as ie, openBlock as p, createElementBlock as g, Fragment as re, renderList as le, createBlock as T, resolveDynamicComponent as A, unref as l, renderSlot as I, inject as se, computed as _, provide as ue, useSlots as ce, watch as de, nextTick as ve, normalizeStyle as $, createVNode as x, withCtx as V, createElementVNode as Y, createCommentVNode as B, Transition as pe, normalizeClass as z, toDisplayString as fe } from "vue";
3
+ const F = {};
4
+ function N(n, o) {
5
+ F[n] = o;
481
6
  }
482
- function ee(e) {
483
- const t = q[e];
484
- return t || P({
485
- render: () => oe("div", { style: "color:red" }, `[Unknown: ${e}]`)
7
+ function W(n) {
8
+ const o = F[n];
9
+ return o || b({
10
+ render: () => oe("div", { style: "color:red" }, `[Unknown: ${n}]`)
486
11
  });
487
12
  }
488
- function U(e) {
489
- const t = se(), n = D(), i = D(null), o = (r) => {
490
- n.value = r;
13
+ function D(n) {
14
+ const o = ne(), s = O(), e = O(null), i = (a) => {
15
+ s.value = a;
491
16
  };
492
- let s = null;
493
- return re(() => {
494
- const r = e();
495
- t.value = r, Z.getInstance().register(r), "subscribe" in r && r.subscribe(o);
496
- let a = null;
497
- i.value && (i.value instanceof Element ? a = i.value : i.value.$el instanceof Element && (a = i.value.$el)), a && "updateRect" in r && (s = new ResizeObserver((c) => {
498
- for (const l of c)
499
- r.updateRect(l.target.getBoundingClientRect());
500
- }), s.observe(a), r.updateRect(a.getBoundingClientRect()));
501
- }), ae(() => {
502
- s && s.disconnect(), t.value && t.value.destroy();
17
+ return ae(() => {
18
+ const a = n();
19
+ o.value = a, G.getInstance().register(a), "subscribe" in a && a.subscribe(i);
20
+ let t = null;
21
+ e.value && (e.value instanceof Element ? t = e.value : e.value.$el instanceof Element && (t = e.value.$el)), t && "bindRectProvider" in a && a.bindRectProvider(() => t.getBoundingClientRect());
22
+ }), ie(() => {
23
+ o.value && o.value.destroy();
503
24
  }), {
504
- core: t,
505
- state: n,
506
- elementRef: i
25
+ core: o,
26
+ state: s,
27
+ elementRef: e
507
28
  };
508
29
  }
509
- const De = { class: "omnipad-virtual-layer-base omnipad-prevent" }, Ce = /* @__PURE__ */ P({
30
+ const me = { class: "omnipad-virtual-layer-base omnipad-prevent" }, ye = /* @__PURE__ */ b({
510
31
  __name: "VirtualLayerBase",
511
32
  props: {
512
33
  nodes: {}
513
34
  },
514
- setup(e) {
515
- return (t, n) => (p(), E("div", De, [
516
- (p(!0), E(ce, null, le(e.nodes || [], (i) => (p(), C(Y(h(ee)(i.type)), {
517
- key: i.uid,
518
- "tree-node": i
35
+ setup(n) {
36
+ return (o, s) => (p(), g("div", me, [
37
+ (p(!0), g(re, null, le(n.nodes || [], (e) => (p(), T(A(l(W)(e.type)), {
38
+ key: e.uid,
39
+ "tree-node": e
519
40
  }, null, 8, ["tree-node"]))), 128)),
520
- k(t.$slots, "default", {}, void 0, !0)
41
+ I(o.$slots, "default", {}, void 0, !0)
521
42
  ]));
522
43
  }
523
- }), w = (e, t) => {
524
- const n = e.__vccOpts || e;
525
- for (const [i, o] of t)
526
- n[i] = o;
527
- return n;
528
- }, te = /* @__PURE__ */ w(Ce, [["__scopeId", "data-v-6f1860f6"]]);
529
- function M(e, t, n = {}) {
530
- const i = t.treeNode, o = i && i.type === e ? i : void 0;
531
- i && i.type !== e && console.warn(
532
- `[OmniPad-Validation] Type mismatch! Component expected "${e}", but received "${i.type}". Config ignored.`
44
+ }), h = (n, o) => {
45
+ const s = n.__vccOpts || n;
46
+ for (const [e, i] of o)
47
+ s[e] = i;
48
+ return s;
49
+ }, j = /* @__PURE__ */ h(ye, [["__scopeId", "data-v-6f1860f6"]]);
50
+ function E(n, o, s = {}) {
51
+ const e = o.treeNode, i = e && e.type === n ? e : void 0;
52
+ e && e.type !== n && console.warn(
53
+ `[OmniPad-Validation] Type mismatch! Component expected "${n}", but received "${e.type}". Config ignored.`
533
54
  );
534
- const s = ue(W.PARENT_ID_KEY, D(void 0)), r = y(() => t.parentId || o?.config?.parentId || s.value), a = y(() => t.widgetId || o?.uid || Ie(e));
535
- de(W.PARENT_ID_KEY, a);
536
- const c = y(() => {
537
- const l = o?.config || {}, u = Object.fromEntries(
538
- Object.entries(t).filter(([m, O]) => O !== void 0 && m !== "treeNode" && m !== "widgetId")
55
+ const a = se(K.PARENT_ID_KEY, O(void 0)), t = _(() => o.parentId || i?.config?.parentId || a.value), d = _(() => o.widgetId || i?.uid || X(n));
56
+ ue(K.PARENT_ID_KEY, d);
57
+ const m = _(() => {
58
+ const f = i?.config || {}, u = Object.fromEntries(
59
+ Object.entries(o).filter(([v, r]) => r !== void 0 && v !== "treeNode" && v !== "widgetId")
539
60
  );
540
61
  return {
541
- ...n,
542
- ...l,
62
+ ...s,
63
+ ...f,
543
64
  ...u,
544
- id: a.value,
545
- type: e,
546
- parentId: r.value,
65
+ id: d.value,
66
+ type: n,
67
+ parentId: t.value,
547
68
  // 特殊处理 Layout:深度合并,确保即便只传了 { width: 100 } 也不丢失原来的 left/top
548
69
  layout: {
549
- ...n.layout || {},
550
- ...l.layout || {},
70
+ ...s.layout || {},
71
+ ...f.layout || {},
551
72
  ...u.layout || {}
552
73
  }
553
74
  };
554
75
  });
555
- return { uid: a, config: c };
76
+ return { uid: d, config: m };
556
77
  }
557
- const ke = ["id"], xe = /* @__PURE__ */ P({
78
+ const Pe = ["id"], _e = /* @__PURE__ */ b({
558
79
  __name: "InputZone",
559
80
  props: {
560
81
  treeNode: {},
@@ -562,113 +83,117 @@ const ke = ["id"], xe = /* @__PURE__ */ P({
562
83
  layout: {},
563
84
  preventFocusLoss: {}
564
85
  },
565
- setup(e) {
566
- const t = e, n = fe(), i = D(null), { uid: o, config: s } = M(v.INPUT_ZONE, t), { core: r, state: a, elementRef: c } = U(
567
- () => new Re(o.value, s.value)
568
- ), l = y(() => {
569
- const d = t.treeNode?.config?.dynamicWidgetId;
570
- return t.treeNode?.children?.filter((b) => b.uid !== d) || [];
571
- }), u = y(() => {
572
- const b = (n.dynamicWidget?.() || []).filter((N) => !(N.type === Comment || N.type === Text)), I = t.treeNode?.children?.find(
573
- (N) => N.uid === t.treeNode?.config?.dynamicWidgetId
574
- ), $ = b.length > 0;
575
- return b.length > 1 && console.error(
576
- `[OmniPad-Validation] InputZone ${o.value} has multiple dynamic widgets in slot. Only the first one will be activated.`
577
- ), $ && I && console.warn(
578
- `[OmniPad-Validation] InputZone ${o.value} has both Slot and Config dynamic widgets. Config ignored.`
86
+ setup(n) {
87
+ const o = n, s = ce(), e = O(null), { uid: i, config: a } = E(P.INPUT_ZONE, o), { core: t, state: d, elementRef: m } = D(
88
+ () => new H(i.value, a.value)
89
+ ), f = _(() => {
90
+ const c = o.treeNode?.config?.dynamicWidgetId;
91
+ return o.treeNode?.children?.filter((w) => w.uid !== c) || [];
92
+ }), u = _(() => {
93
+ const w = (s.dynamicWidget?.() || []).filter((k) => !(k.type === Comment || k.type === Text)), C = o.treeNode?.children?.find(
94
+ (k) => k.uid === o.treeNode?.config?.dynamicWidgetId
95
+ ), U = w.length > 0;
96
+ return w.length > 1 && console.error(
97
+ `[OmniPad-Validation] InputZone ${i.value} has multiple dynamic widgets in slot. Only the first one will be activated.`
98
+ ), U && C && console.warn(
99
+ `[OmniPad-Validation] InputZone ${i.value} has both Slot and Config dynamic widgets. Config ignored.`
579
100
  ), {
580
- nodeToRender: $ ? b[0] : I || null,
581
- isFromSlot: $
101
+ nodeToRender: U ? w[0] : C || null,
102
+ isFromSlot: U
582
103
  };
583
104
  });
584
- he(
585
- i,
586
- (d) => {
587
- pe(() => {
588
- d && d?.uid && r.value?.updateConfig({
589
- dynamicWidgetId: d.uid
105
+ de(
106
+ e,
107
+ (c) => {
108
+ ve(() => {
109
+ c && c?.uid && t.value?.updateConfig({
110
+ dynamicWidgetId: c.uid
590
111
  });
591
112
  });
592
113
  },
593
114
  { immediate: !0 }
594
115
  );
595
- const m = y(() => V(s.value.layout)), O = y(() => a.value?.isDynamicActive ? {
116
+ const v = _(() => S(a.value.layout)), r = _(() => d.value?.isDynamicActive ? {
596
117
  position: "absolute",
597
- left: `${a.value.dynamicPosition.x}%`,
598
- top: `${a.value.dynamicPosition.y}%`,
118
+ left: `${d.value.dynamicPosition.x}%`,
119
+ top: `${d.value.dynamicPosition.y}%`,
599
120
  zIndex: 100,
600
121
  pointerEvents: "auto"
601
- } : { display: "none" }), ne = (d) => {
602
- r.value && (r.value.onPointerDown(d), a.value?.isDynamicActive && i.value && typeof i.value.onPointerDown == "function" && i.value.onPointerDown(d));
603
- }, ie = (d) => {
604
- r.value && (r.value.onPointerMove(d), a.value?.isDynamicActive && i.value && typeof i.value.onPointerMove == "function" && i.value.onPointerMove(d));
605
- }, S = (d) => {
606
- a.value?.isDynamicActive && i.value && typeof i.value.onPointerUp == "function" && i.value.onPointerUp(d), r.value && r.value.onPointerUp(d);
122
+ } : { display: "none" }), R = (c) => {
123
+ t.value && (t.value.onPointerDown(c), d.value?.isDynamicActive && e.value && typeof e.value.onPointerDown == "function" && e.value.onPointerDown(c));
124
+ }, y = (c) => {
125
+ t.value && (t.value.onPointerMove(c), d.value?.isDynamicActive && e.value && typeof e.value.onPointerMove == "function" && e.value.onPointerMove(c));
126
+ }, M = (c) => {
127
+ d.value?.isDynamicActive && e.value && typeof e.value.onPointerUp == "function" && e.value.onPointerUp(c), t.value && t.value.onPointerUp(c);
128
+ }, Z = (c) => {
129
+ d.value?.isDynamicActive && e.value && typeof e.value.onPointerCancel == "function" && e.value.onPointerCancel(c), t.value && t.value.onPointerCancel(c);
607
130
  };
608
- return (d, b) => (p(), E("div", {
609
- id: h(o),
131
+ return (c, w) => (p(), g("div", {
132
+ id: l(i),
610
133
  ref_key: "elementRef",
611
- ref: c,
134
+ ref: m,
612
135
  class: "omnipad-input-zone omnipad-prevent",
613
- style: _(m.value)
136
+ style: $(v.value)
614
137
  }, [
615
- L(te, { nodes: l.value }, {
616
- default: K(() => [
617
- k(d.$slots, "default", {}, void 0, !0)
138
+ x(j, { nodes: f.value }, {
139
+ default: V(() => [
140
+ I(c.$slots, "default", {}, void 0, !0)
618
141
  ]),
619
142
  _: 3
620
143
  }, 8, ["nodes"]),
621
- h(r)?.isInterceptorRequired ? (p(), E("div", {
144
+ u.value.nodeToRender || l(t)?.isInterceptorRequired ? (p(), g("div", {
622
145
  key: 0,
623
146
  class: "omnipad-input-zone-trigger",
624
- onPointerdown: ne,
625
- onPointermove: ie,
626
- onPointerup: S,
627
- onPointercancel: S,
628
- onLostpointercapture: S,
629
- onPointerleave: S
147
+ onPointerdown: R,
148
+ onPointermove: y,
149
+ onPointerup: M,
150
+ onPointercancel: Z,
151
+ onLostpointercapture: Z
630
152
  }, [
631
- G("div", {
153
+ Y("div", {
632
154
  class: "dynamic-widget-mount",
633
- style: _(O.value)
155
+ style: $(r.value)
634
156
  }, [
635
- u.value.isFromSlot ? (p(), C(Y(u.value.nodeToRender), {
157
+ u.value.isFromSlot ? (p(), T(A(u.value.nodeToRender), {
636
158
  key: 0,
637
- ref: (I) => i.value = I
638
- }, null, 512)) : u.value.nodeToRender ? (p(), C(Y(h(ee)(u.value.nodeToRender.type)), {
159
+ ref: (C) => e.value = C
160
+ }, null, 512)) : u.value.nodeToRender ? (p(), T(A(l(W)(u.value.nodeToRender.type)), {
639
161
  key: 1,
640
- ref: (I) => i.value = I,
162
+ ref: (C) => e.value = C,
641
163
  "tree-node": u.value.nodeToRender
642
- }, null, 8, ["tree-node"])) : T("", !0)
164
+ }, null, 8, ["tree-node"])) : B("", !0)
643
165
  ], 4)
644
- ], 32)) : T("", !0)
645
- ], 12, ke));
166
+ ], 32)) : B("", !0)
167
+ ], 12, Pe));
646
168
  }
647
- }), Ue = /* @__PURE__ */ w(xe, [["__scopeId", "data-v-02669919"]]), Me = ["id"], $e = /* @__PURE__ */ P({
169
+ }), ge = /* @__PURE__ */ h(_e, [["__scopeId", "data-v-e0c28ebd"]]), be = ["id"], Re = /* @__PURE__ */ b({
648
170
  __name: "RootLayer",
649
171
  props: {
650
172
  treeNode: {},
651
173
  widgetId: {}
652
174
  },
653
- setup(e) {
654
- const t = e, { uid: n, config: i } = M(v.ROOT_LAYER, t), { elementRef: o } = U(() => new Se(n.value, i.value));
655
- return (s, r) => (p(), E("div", {
656
- id: h(n),
175
+ setup(n) {
176
+ const o = n, { uid: s, config: e } = E(P.ROOT_LAYER, o), { elementRef: i } = D(() => new J(s.value, e.value));
177
+ return (a, t) => (p(), g("div", {
178
+ id: l(s),
657
179
  ref_key: "elementRef",
658
- ref: o,
180
+ ref: i,
659
181
  class: "omnipad-virtual-layer"
660
182
  }, [
661
- L(te, {
662
- nodes: e.treeNode?.children || []
183
+ x(j, {
184
+ nodes: n.treeNode?.children || []
663
185
  }, {
664
- default: K(() => [
665
- k(s.$slots, "default", {}, void 0, !0)
186
+ default: V(() => [
187
+ I(a.$slots, "default", {}, void 0, !0)
666
188
  ]),
667
189
  _: 3
668
190
  }, 8, ["nodes"])
669
- ], 8, Me));
191
+ ], 8, be));
670
192
  }
671
- }), Be = /* @__PURE__ */ w($e, [["__scopeId", "data-v-a509fd6e"]]), Fe = ["id"], Ye = /* @__PURE__ */ P({
193
+ }), we = /* @__PURE__ */ h(Re, [["__scopeId", "data-v-9e46ef9c"]]), Ce = ["id"], Te = {
194
+ key: 0,
195
+ class: "omnipad-default-focus-border-feedback"
196
+ }, Ie = /* @__PURE__ */ b({
672
197
  __name: "TargetZone",
673
198
  props: {
674
199
  treeNode: {},
@@ -677,70 +202,84 @@ const ke = ["id"], xe = /* @__PURE__ */ P({
677
202
  cursorAutoDelay: {},
678
203
  layout: {}
679
204
  },
680
- setup(e) {
681
- const t = e, n = {
205
+ setup(n) {
206
+ const o = n, s = {
682
207
  cursorAutoDelay: 2500
683
- }, { uid: i, config: o } = M(v.TARGET_ZONE, t, n), { state: s, elementRef: r } = U(
684
- () => new Ae(i.value, o.value)
685
- ), a = y(() => V(o.value.layout)), c = y(() => s.value ? {
686
- left: `${s.value.position.x}%`,
687
- top: `${s.value.position.y}%`,
688
- opacity: s.value.isVisible ? 1 : 0
689
- } : { display: "none" });
690
- return (l, u) => (p(), E("div", {
691
- id: h(i),
208
+ }, { uid: e, config: i } = E(
209
+ P.TARGET_ZONE,
210
+ o,
211
+ s
212
+ ), { core: a, state: t, elementRef: d } = D(
213
+ () => new Q(e.value, i.value)
214
+ ), m = _(() => S(i.value.layout)), f = _(() => t.value ? {
215
+ left: `${t.value.position.x}%`,
216
+ top: `${t.value.position.y}%`,
217
+ opacity: t.value.isVisible ? 1 : 0
218
+ } : { display: "none" }), u = (y) => a.value?.onPointerDown(y), v = (y) => a.value?.onPointerMove(y), r = (y) => a.value?.onPointerUp(y), R = (y) => a.value?.onPointerCancel(y);
219
+ return (y, M) => (p(), g("div", {
220
+ id: l(e),
692
221
  ref_key: "elementRef",
693
- ref: r,
222
+ ref: d,
694
223
  class: "omnipad-target-zone",
695
- style: _(a.value)
224
+ style: $(m.value),
225
+ onPointerdown: u,
226
+ onPointermove: v,
227
+ onPointerup: r,
228
+ onPointercancel: R,
229
+ onLostpointercapture: R
696
230
  }, [
697
- L(ve, { name: "pulse" }, {
698
- default: K(() => [
699
- h(s)?.isFocusReturning ? (p(), E("div", {
700
- key: 0,
701
- class: "focus-feedback-ring",
702
- style: _({
703
- left: `${h(s).position.x}%`,
704
- top: `${h(s).position.y}%`
705
- })
706
- }, null, 4)) : T("", !0)
707
- ]),
708
- _: 1
709
- }),
710
- h(o).cursorEnabled ? (p(), E("div", {
231
+ I(y.$slots, "focus-feedback", {
232
+ state: l(t),
233
+ isReturning: l(t)?.isFocusReturning,
234
+ cursorPos: l(t)?.position
235
+ }, () => [
236
+ x(pe, { name: "omnipad-default-focus-fade" }, {
237
+ default: V(() => [
238
+ l(t)?.isFocusReturning ? (p(), g("div", Te)) : B("", !0)
239
+ ]),
240
+ _: 1
241
+ })
242
+ ], !0),
243
+ l(i).cursorEnabled ? (p(), g("div", {
711
244
  key: 0,
712
245
  class: "omnipad-virtual-cursor",
713
- style: _(c.value)
246
+ style: $(f.value)
714
247
  }, [
715
- G("div", {
716
- class: j(["cursor-dot", { "is-down": h(s)?.isPointerDown }])
717
- }, null, 2)
718
- ], 4)) : T("", !0)
719
- ], 12, Fe));
720
- }
721
- }), Le = /* @__PURE__ */ w(Ye, [["__scopeId", "data-v-b9d49b97"]]), Ke = {
248
+ I(y.$slots, "cursor", {
249
+ state: l(t),
250
+ isDown: l(t)?.isPointerDown,
251
+ cursorPos: l(t)?.position
252
+ }, () => [
253
+ Y("div", {
254
+ class: z(["omnipad-default-cursor-dot", { "is-down": l(t)?.isPointerDown }])
255
+ }, null, 2)
256
+ ], !0)
257
+ ], 4)) : B("", !0)
258
+ ], 44, Ce));
259
+ }
260
+ }), Ne = /* @__PURE__ */ h(Ie, [["__scopeId", "data-v-70b706ac"]]), De = {
722
261
  key: 0,
723
262
  class: "omnipad-button-label"
724
- }, Ve = /* @__PURE__ */ P({
263
+ }, he = /* @__PURE__ */ b({
725
264
  __name: "VirtualButtonBase",
726
265
  props: {
727
266
  layout: {},
728
267
  isActive: { type: Boolean },
729
268
  label: {}
730
269
  },
731
- setup(e) {
732
- const t = e, n = y(() => t.layout ? V(t.layout) : {});
733
- return (i, o) => (p(), E("div", {
734
- class: j(["omnipad-button-base", { "omnipad-is-active": e.isActive }]),
735
- style: _(n.value),
270
+ setup(n) {
271
+ const o = n, s = _(() => o.layout ? S(o.layout) : {});
272
+ return (e, i) => (p(), g("div", {
273
+ class: z(["omnipad-button-base", { "is-active": n.isActive }]),
274
+ style: $(s.value),
736
275
  tabindex: "-1"
737
276
  }, [
738
- k(i.$slots, "default", {}, () => [
739
- e.label ? (p(), E("span", Ke, me(e.label), 1)) : T("", !0)
277
+ I(e.$slots, "default", {}, () => [
278
+ n.label ? (p(), g("span", De, fe(n.label), 1)) : B("", !0)
740
279
  ], !0)
741
280
  ], 6));
742
281
  }
743
- }), Ze = /* @__PURE__ */ w(Ve, [["__scopeId", "data-v-6cbe805c"]]), We = /* @__PURE__ */ P({
282
+ }), L = /* @__PURE__ */ h(he, [["__scopeId", "data-v-3db6d4f9"]]), Ee = /* @__PURE__ */ b({
744
283
  __name: "VirtualKeyboardButton",
745
284
  props: {
746
285
  treeNode: {},
@@ -750,42 +289,125 @@ const ke = ["id"], xe = /* @__PURE__ */ P({
750
289
  mapping: {},
751
290
  layout: {}
752
291
  },
753
- setup(e, { expose: t }) {
754
- const n = e, i = {
292
+ setup(n, { expose: o }) {
293
+ const s = n, e = {
755
294
  label: "BTN"
756
- }, { uid: o, config: s } = M(
757
- v.KEYBOARD_BUTTON,
758
- n,
759
- i
760
- ), { core: r, state: a, elementRef: c } = U(
761
- () => new we(o.value, s.value)
762
- ), l = (m) => r.value?.onPointerDown(m), u = (m) => r.value?.onPointerUp(m);
763
- return t({
764
- uid: o,
765
- onPointerDown: l,
766
- onPointerUp: u
767
- }), (m, O) => (p(), C(Ze, {
768
- id: h(o),
295
+ }, { uid: i, config: a } = E(
296
+ P.KEYBOARD_BUTTON,
297
+ s,
298
+ e
299
+ ), { core: t, state: d, elementRef: m } = D(
300
+ () => new q(i.value, a.value)
301
+ ), f = (r) => t.value?.onPointerDown(r), u = (r) => t.value?.onPointerUp(r), v = (r) => t.value?.onPointerCancel(r);
302
+ return o({
303
+ uid: i,
304
+ onPointerDown: f,
305
+ onPointerUp: u,
306
+ onPointerCancel: v
307
+ }), (r, R) => (p(), T(L, {
308
+ id: l(i),
309
+ ref_key: "elementRef",
310
+ ref: m,
311
+ layout: l(a).layout,
312
+ label: l(a).label,
313
+ "is-active": l(d)?.isPressed,
314
+ onPointerdown: f,
315
+ onPointerup: u,
316
+ onPointercancel: v,
317
+ onLostpointercapture: v
318
+ }, null, 8, ["id", "layout", "label", "is-active"]));
319
+ }
320
+ }), $e = /* @__PURE__ */ b({
321
+ __name: "VirtualMouseButton",
322
+ props: {
323
+ treeNode: {},
324
+ widgetId: {},
325
+ label: {},
326
+ targetStageId: {},
327
+ button: {},
328
+ fixedPoint: {},
329
+ layout: {}
330
+ },
331
+ setup(n, { expose: o }) {
332
+ const s = n, e = {
333
+ label: "LMB",
334
+ button: 0
335
+ }, { uid: i, config: a } = E(
336
+ P.MOUSE_BUTTON,
337
+ s,
338
+ e
339
+ ), { core: t, state: d, elementRef: m } = D(
340
+ () => new ee(i.value, a.value)
341
+ ), f = (r) => t.value?.onPointerDown(r), u = (r) => t.value?.onPointerUp(r), v = (r) => t.value?.onPointerCancel(r);
342
+ return o({
343
+ uid: i,
344
+ onPointerDown: f,
345
+ onPointerUp: u,
346
+ onPointerCancel: v
347
+ }), (r, R) => (p(), T(L, {
348
+ id: l(i),
349
+ ref_key: "elementRef",
350
+ ref: m,
351
+ layout: l(a).layout,
352
+ label: l(a).label,
353
+ "is-active": l(d)?.isPressed,
354
+ onPointerdown: f,
355
+ onPointerup: u,
356
+ onPointercancel: v,
357
+ onLostpointercapture: v
358
+ }, null, 8, ["id", "layout", "label", "is-active"]));
359
+ }
360
+ }), Be = /* @__PURE__ */ b({
361
+ __name: "VirtualTrackpad",
362
+ props: {
363
+ treeNode: {},
364
+ widgetId: {},
365
+ label: {},
366
+ sensitivity: {},
367
+ targetStageId: {},
368
+ layout: {}
369
+ },
370
+ setup(n, { expose: o }) {
371
+ const s = n, { uid: e, config: i } = E(P.TRACKPAD, s, {
372
+ label: "TRACKPAD",
373
+ sensitivity: 1
374
+ }), { core: a, state: t, elementRef: d } = D(
375
+ () => new te(e.value, i.value)
376
+ ), m = (r) => a.value?.onPointerDown(r), f = (r) => a.value?.onPointerMove(r), u = (r) => a.value?.onPointerUp(r), v = (r) => a.value?.onPointerCancel(r);
377
+ return o({
378
+ uid: e,
379
+ onPointerDown: m,
380
+ onPointerMove: f,
381
+ onPointerUp: u,
382
+ onPointerCancel: v
383
+ }), (r, R) => (p(), T(L, {
384
+ id: l(e),
769
385
  ref_key: "elementRef",
770
- ref: c,
771
- layout: h(s).layout,
772
- label: h(s).label,
773
- "is-active": h(a)?.isPressed,
774
- onPointerdown: l,
386
+ ref: d,
387
+ class: "omnipad-trackpad",
388
+ layout: l(i).layout,
389
+ label: l(i).label,
390
+ "is-active": l(t)?.isPressed,
391
+ onPointerdown: m,
392
+ onPointermove: f,
775
393
  onPointerup: u,
776
- onPointercancel: u,
777
- onLostpointercapture: u
394
+ onPointercancel: v,
395
+ onLostpointercapture: v
778
396
  }, null, 8, ["id", "layout", "label", "is-active"]));
779
397
  }
780
- });
781
- x(v.INPUT_ZONE, Ue);
782
- x(v.ROOT_LAYER, Be);
783
- x(v.TARGET_ZONE, Le);
784
- x(v.KEYBOARD_BUTTON, We);
398
+ }), ke = /* @__PURE__ */ h(Be, [["__scopeId", "data-v-c28e3a2e"]]);
399
+ N(P.INPUT_ZONE, ge);
400
+ N(P.ROOT_LAYER, we);
401
+ N(P.TARGET_ZONE, Ne);
402
+ N(P.KEYBOARD_BUTTON, Ee);
403
+ N(P.MOUSE_BUTTON, $e);
404
+ N(P.TRACKPAD, ke);
785
405
  export {
786
- Ue as InputZone,
787
- Be as RootLayer,
788
- Le as TargetZone,
789
- We as VirtualKeyboardButton,
790
- x as registerComponent
406
+ ge as InputZone,
407
+ we as RootLayer,
408
+ Ne as TargetZone,
409
+ Ee as VirtualKeyboardButton,
410
+ $e as VirtualMouseButton,
411
+ ke as VirtualTrackpad,
412
+ N as registerComponent
791
413
  };