@omnipad/vue 0.1.1-alpha.0
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/dist/index.d.ts +197 -0
- package/dist/omnipad-vue.css +1 -0
- package/dist/omnipad-vue.mjs +791 -0
- package/dist/omnipad-vue.umd.js +1 -0
- package/package.json +44 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { AllowedComponentProps } from 'vue';
|
|
2
|
+
import { Component } from 'vue';
|
|
3
|
+
import { ComponentCustomProperties } from 'vue';
|
|
4
|
+
import { ComponentCustomProps } from 'vue';
|
|
5
|
+
import { ComponentInternalInstance } from 'vue';
|
|
6
|
+
import { ComponentOptionsBase } from 'vue';
|
|
7
|
+
import { ComponentOptionsMixin } from 'vue';
|
|
8
|
+
import { ComponentProvideOptions } from 'vue';
|
|
9
|
+
import { ComponentPublicInstance } from 'vue';
|
|
10
|
+
import { ComputedRef } from 'vue';
|
|
11
|
+
import { ConfigTreeNode } from '@omnipad/core';
|
|
12
|
+
import { DebuggerEvent } from 'vue';
|
|
13
|
+
import { DefineComponent } from 'vue';
|
|
14
|
+
import { GlobalComponents } from 'vue';
|
|
15
|
+
import { GlobalDirectives } from 'vue';
|
|
16
|
+
import { KeyboardButtonConfig } from '@omnipad/core';
|
|
17
|
+
import { LayoutBox } from '@omnipad/core';
|
|
18
|
+
import { nextTick } from 'vue';
|
|
19
|
+
import { OnCleanup } from '@vue/reactivity';
|
|
20
|
+
import { PublicProps } from 'vue';
|
|
21
|
+
import { ShallowUnwrapRef } from 'vue';
|
|
22
|
+
import { Slot } from 'vue';
|
|
23
|
+
import { VNodeProps } from 'vue';
|
|
24
|
+
import { WatchOptions } from 'vue';
|
|
25
|
+
import { WatchStopHandle } from 'vue';
|
|
26
|
+
|
|
27
|
+
declare const __VLS_component: DefineComponent<InputZoneProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<InputZoneProps> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {
|
|
28
|
+
elementRef: HTMLDivElement;
|
|
29
|
+
}, HTMLDivElement>;
|
|
30
|
+
|
|
31
|
+
declare const __VLS_component_2: DefineComponent<__VLS_Props, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {
|
|
32
|
+
elementRef: HTMLDivElement;
|
|
33
|
+
}, HTMLDivElement>;
|
|
34
|
+
|
|
35
|
+
declare type __VLS_Props = {
|
|
36
|
+
/** The runtime tree node for auto-configuration. */
|
|
37
|
+
treeNode?: ConfigTreeNode;
|
|
38
|
+
/** Unique configuration ID (CID) for this layer. Used for profile serialization. */
|
|
39
|
+
widgetId?: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
declare function __VLS_template(): {
|
|
43
|
+
attrs: Partial<{}>;
|
|
44
|
+
slots: {
|
|
45
|
+
default?(_: {}): any;
|
|
46
|
+
};
|
|
47
|
+
refs: {
|
|
48
|
+
elementRef: HTMLDivElement;
|
|
49
|
+
};
|
|
50
|
+
rootEl: HTMLDivElement;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
declare function __VLS_template_2(): {
|
|
54
|
+
attrs: Partial<{}>;
|
|
55
|
+
slots: {
|
|
56
|
+
default?(_: {}): any;
|
|
57
|
+
};
|
|
58
|
+
refs: {
|
|
59
|
+
elementRef: HTMLDivElement;
|
|
60
|
+
};
|
|
61
|
+
rootEl: HTMLDivElement;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
declare type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
65
|
+
|
|
66
|
+
declare type __VLS_TemplateResult_2 = ReturnType<typeof __VLS_template_2>;
|
|
67
|
+
|
|
68
|
+
declare type __VLS_WithTemplateSlots<T, S> = T & {
|
|
69
|
+
new (): {
|
|
70
|
+
$slots: S;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
declare type __VLS_WithTemplateSlots_2<T, S> = T & {
|
|
75
|
+
new (): {
|
|
76
|
+
$slots: S;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export declare const InputZone: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
81
|
+
|
|
82
|
+
declare interface InputZoneProps {
|
|
83
|
+
/** The runtime tree node for automatic setup. */
|
|
84
|
+
treeNode?: ConfigTreeNode;
|
|
85
|
+
/** Unique configuration ID (CID) for this zone. Used for profile serialization. */
|
|
86
|
+
widgetId?: string;
|
|
87
|
+
/** Spatial layout configuration (position, size, anchor). */
|
|
88
|
+
layout?: LayoutBox;
|
|
89
|
+
/** If true, prevents the browser focus from leaving the game area when touching this zone. */
|
|
90
|
+
preventFocusLoss?: {
|
|
91
|
+
type: boolean;
|
|
92
|
+
default: undefined;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export declare function registerComponent(type: string, component: Component): void;
|
|
97
|
+
|
|
98
|
+
export declare const RootLayer: __VLS_WithTemplateSlots_2<typeof __VLS_component_2, __VLS_TemplateResult_2["slots"]>;
|
|
99
|
+
|
|
100
|
+
export declare const TargetZone: DefineComponent<TargetZoneProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<TargetZoneProps> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {
|
|
101
|
+
elementRef: HTMLDivElement;
|
|
102
|
+
}, HTMLDivElement>;
|
|
103
|
+
|
|
104
|
+
declare interface TargetZoneProps {
|
|
105
|
+
/** The runtime tree node for automatic setup. */
|
|
106
|
+
treeNode?: ConfigTreeNode;
|
|
107
|
+
/** Unique configuration ID (CID) for this zone. Used for profile serialization. */
|
|
108
|
+
widgetId?: string;
|
|
109
|
+
/** Whether the virtual visual cursor is enabled for this stage. */
|
|
110
|
+
cursorEnabled?: boolean;
|
|
111
|
+
/** Delay in milliseconds before the virtual cursor auto-hides after inactivity (0 to disable). */
|
|
112
|
+
cursorAutoDelay?: number;
|
|
113
|
+
/** Spatial layout configuration. Usually set to cover the entire game container. */
|
|
114
|
+
layout?: LayoutBox;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export declare const VirtualKeyboardButton: DefineComponent<VirtualKeyButtonButtonProps, {
|
|
118
|
+
uid: ComputedRef<any>;
|
|
119
|
+
onPointerDown: (e: PointerEvent) => void | undefined;
|
|
120
|
+
onPointerUp: (e: PointerEvent) => void | undefined;
|
|
121
|
+
}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<VirtualKeyButtonButtonProps> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {
|
|
122
|
+
elementRef: ({
|
|
123
|
+
$: ComponentInternalInstance;
|
|
124
|
+
$data: {};
|
|
125
|
+
$props: {
|
|
126
|
+
readonly layout?: LayoutBox | undefined;
|
|
127
|
+
readonly isActive?: boolean | undefined;
|
|
128
|
+
readonly label?: string | undefined;
|
|
129
|
+
} & VNodeProps & AllowedComponentProps & ComponentCustomProps;
|
|
130
|
+
$attrs: {
|
|
131
|
+
[x: string]: unknown;
|
|
132
|
+
};
|
|
133
|
+
$refs: {
|
|
134
|
+
[x: string]: unknown;
|
|
135
|
+
};
|
|
136
|
+
$slots: Readonly<{
|
|
137
|
+
[name: string]: Slot<any> | undefined;
|
|
138
|
+
}>;
|
|
139
|
+
$root: ComponentPublicInstance | null;
|
|
140
|
+
$parent: ComponentPublicInstance | null;
|
|
141
|
+
$host: Element | null;
|
|
142
|
+
$emit: (event: string, ...args: any[]) => void;
|
|
143
|
+
$el: HTMLDivElement;
|
|
144
|
+
$options: ComponentOptionsBase<Readonly<{
|
|
145
|
+
layout?: LayoutBox;
|
|
146
|
+
isActive?: boolean;
|
|
147
|
+
label?: string;
|
|
148
|
+
}> & Readonly<{}>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, {}, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & {
|
|
149
|
+
beforeCreate?: (() => void) | (() => void)[];
|
|
150
|
+
created?: (() => void) | (() => void)[];
|
|
151
|
+
beforeMount?: (() => void) | (() => void)[];
|
|
152
|
+
mounted?: (() => void) | (() => void)[];
|
|
153
|
+
beforeUpdate?: (() => void) | (() => void)[];
|
|
154
|
+
updated?: (() => void) | (() => void)[];
|
|
155
|
+
activated?: (() => void) | (() => void)[];
|
|
156
|
+
deactivated?: (() => void) | (() => void)[];
|
|
157
|
+
beforeDestroy?: (() => void) | (() => void)[];
|
|
158
|
+
beforeUnmount?: (() => void) | (() => void)[];
|
|
159
|
+
destroyed?: (() => void) | (() => void)[];
|
|
160
|
+
unmounted?: (() => void) | (() => void)[];
|
|
161
|
+
renderTracked?: ((e: DebuggerEvent) => void) | ((e: DebuggerEvent) => void)[];
|
|
162
|
+
renderTriggered?: ((e: DebuggerEvent) => void) | ((e: DebuggerEvent) => void)[];
|
|
163
|
+
errorCaptured?: ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: ComponentPublicInstance | null, info: string) => boolean | void)[];
|
|
164
|
+
};
|
|
165
|
+
$forceUpdate: () => void;
|
|
166
|
+
$nextTick: nextTick;
|
|
167
|
+
$watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (...args: [R, R, OnCleanup]) => any : (...args: [any, any, OnCleanup]) => any, options?: WatchOptions): WatchStopHandle;
|
|
168
|
+
} & Readonly<{}> & Omit<Readonly<{
|
|
169
|
+
layout?: LayoutBox;
|
|
170
|
+
isActive?: boolean;
|
|
171
|
+
label?: string;
|
|
172
|
+
}> & Readonly<{}>, never> & ShallowUnwrapRef< {}> & {} & ComponentCustomProperties & {} & {
|
|
173
|
+
$slots: {
|
|
174
|
+
default?(_: {}): any;
|
|
175
|
+
};
|
|
176
|
+
}) | null;
|
|
177
|
+
}, HTMLDivElement>;
|
|
178
|
+
|
|
179
|
+
declare interface VirtualKeyButtonButtonProps {
|
|
180
|
+
/** The runtime tree node for automatic setup. */
|
|
181
|
+
treeNode?: ConfigTreeNode;
|
|
182
|
+
/** Unique configuration ID (CID) for this zone. Used for profile serialization. */
|
|
183
|
+
widgetId?: string;
|
|
184
|
+
/** The text or symbol displayed on the button surface. */
|
|
185
|
+
label?: string;
|
|
186
|
+
/** The ID (CID) of the TargetZone this button sends signals to, usually global ID. */
|
|
187
|
+
targetStageId?: string;
|
|
188
|
+
/**
|
|
189
|
+
* Mapping definitions for keyboard events.
|
|
190
|
+
* Includes 'key', 'code', and legacy 'keyCode'.
|
|
191
|
+
*/
|
|
192
|
+
mapping?: KeyboardButtonConfig['mapping'];
|
|
193
|
+
/** Spatial layout configuration relative to its parent zone. */
|
|
194
|
+
layout?: LayoutBox;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export { }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--omnipad-btn-bg: rgba(255, 255, 255, .2);--omnipad-btn-border-color: rgba(255, 255, 255, .4);--omnipad-btn-border-width: 2px;--omnipad-btn-border-style: solid;--omnipad-btn-radius: 8px;--omnipad-btn-label-color: #ffffff;--omnipad-btn-font-family: "Upheaval", "monacoregular", sans-serif;--omnipad-btn-font-size: 18px;--omnipad-btn-font-weight: bold;--omnipad-btn-pressed-bg: rgba(255, 186, 67, .6);--omnipad-btn-pressed-border-color: #ffba43;--omnipad-btn-pressed-scale: .92;--omnipad-btn-pressed-opacity: 1;--omnipad-btn-transition-duration: .1s;--omnipad-btn-transition-timing: ease-out}.omnipad-button-base{background:var(--omnipad-btn-bg);border:var(--omnipad-btn-border-width) var(--omnipad-btn-border-style) var(--omnipad-btn-border-color);border-radius:var(--omnipad-btn-radius);display:flex;align-items:center;justify-content:center;transition:all var(--omnipad-btn-transition-duration) var(--omnipad-btn-transition-timing)}.omnipad-button-label-hollow{font-family:var(--omnipad-btn-font-family);font-size:var(--omnipad-btn-font-size);color:var(--omnipad-btn-label-color);font-weight:var(--omnipad-btn-font-weight);background:inherit;-webkit-background-clip:text;background-clip:text;color:transparent;filter:invert(1) grayscale(1) contrast(9);mix-blend-mode:destination-out}.omnipad-prevent{touch-action:none;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent}.omnipad-virtual-layer-base[data-v-6f1860f6]{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:1000}[data-v-6f1860f6] .omnipad-input-zone,[data-v-6f1860f6] .omnipad-button{pointer-events:auto}.omnipad-input-zone[data-v-02669919]{position:absolute;pointer-events:none}.omnipad-input-zone-trigger[data-v-02669919]{position:absolute;inset:0;pointer-events:auto;background:transparent;touch-action:none}.dynamic-widget-mount[data-v-02669919]{pointer-events:none}.omnipad-virtual-layer[data-v-a509fd6e]{position:relative;height:100%;width:100%;pointer-events:none}.omnipad-target-zone[data-v-b9d49b97]{pointer-events:none;overflow:hidden}.omnipad-virtual-cursor[data-v-b9d49b97]{position:absolute;width:20px;height:20px;transform:translate(-50%,-50%);pointer-events:none;transition:opacity .2s}.cursor-dot[data-v-b9d49b97]{width:100%;height:100%;border:2px solid white;border-radius:50%;background:#ff000080}.cursor-dot.is-down[data-v-b9d49b97]{transform:scale(.8);background:red}.focus-feedback-ring[data-v-b9d49b97]{position:absolute;width:60px;height:60px;transform:translate(-50%,-50%);border:2px solid rgba(100,200,255,.8);border-radius:50%;pointer-events:none;z-index:5}.pulse-enter-active[data-v-b9d49b97]{animation:ripple-out-b9d49b97 .5s ease-out forwards}@keyframes ripple-out-b9d49b97{0%{transform:translate(-50%,-50%) scale(.2);opacity:1}to{transform:translate(-50%,-50%) scale(1.5);opacity:0}}.omnipad-virtual-cursor[data-v-b9d49b97]{z-index:10}.omnipad-button-base[data-v-6cbe805c]{-webkit-user-select:none;user-select:none;touch-action:none;overflow:hidden;box-sizing:border-box;pointer-events:auto}.omnipad-button-base.omnipad-is-active[data-v-6cbe805c]{background:var(--omnipad-btn-pressed-bg);border-color:var(--omnipad-btn-pressed-border-color);opacity:var(--omnipad-btn-pressed-opacity);filter:brightness(1.2)}.omnipad-button-label[data-v-6cbe805c]{font-family:var(--omnipad-btn-font-family);font-size:var(--omnipad-btn-font-size);color:var(--omnipad-btn-label-color);font-weight:var(--omnipad-btn-font-weight)}
|
|
@@ -0,0 +1,791 @@
|
|
|
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;
|
|
481
|
+
}
|
|
482
|
+
function ee(e) {
|
|
483
|
+
const t = q[e];
|
|
484
|
+
return t || P({
|
|
485
|
+
render: () => oe("div", { style: "color:red" }, `[Unknown: ${e}]`)
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
function U(e) {
|
|
489
|
+
const t = se(), n = D(), i = D(null), o = (r) => {
|
|
490
|
+
n.value = r;
|
|
491
|
+
};
|
|
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();
|
|
503
|
+
}), {
|
|
504
|
+
core: t,
|
|
505
|
+
state: n,
|
|
506
|
+
elementRef: i
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
const De = { class: "omnipad-virtual-layer-base omnipad-prevent" }, Ce = /* @__PURE__ */ P({
|
|
510
|
+
__name: "VirtualLayerBase",
|
|
511
|
+
props: {
|
|
512
|
+
nodes: {}
|
|
513
|
+
},
|
|
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
|
|
519
|
+
}, null, 8, ["tree-node"]))), 128)),
|
|
520
|
+
k(t.$slots, "default", {}, void 0, !0)
|
|
521
|
+
]));
|
|
522
|
+
}
|
|
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.`
|
|
533
|
+
);
|
|
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")
|
|
539
|
+
);
|
|
540
|
+
return {
|
|
541
|
+
...n,
|
|
542
|
+
...l,
|
|
543
|
+
...u,
|
|
544
|
+
id: a.value,
|
|
545
|
+
type: e,
|
|
546
|
+
parentId: r.value,
|
|
547
|
+
// 特殊处理 Layout:深度合并,确保即便只传了 { width: 100 } 也不丢失原来的 left/top
|
|
548
|
+
layout: {
|
|
549
|
+
...n.layout || {},
|
|
550
|
+
...l.layout || {},
|
|
551
|
+
...u.layout || {}
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
});
|
|
555
|
+
return { uid: a, config: c };
|
|
556
|
+
}
|
|
557
|
+
const ke = ["id"], xe = /* @__PURE__ */ P({
|
|
558
|
+
__name: "InputZone",
|
|
559
|
+
props: {
|
|
560
|
+
treeNode: {},
|
|
561
|
+
widgetId: {},
|
|
562
|
+
layout: {},
|
|
563
|
+
preventFocusLoss: {}
|
|
564
|
+
},
|
|
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.`
|
|
579
|
+
), {
|
|
580
|
+
nodeToRender: $ ? b[0] : I || null,
|
|
581
|
+
isFromSlot: $
|
|
582
|
+
};
|
|
583
|
+
});
|
|
584
|
+
he(
|
|
585
|
+
i,
|
|
586
|
+
(d) => {
|
|
587
|
+
pe(() => {
|
|
588
|
+
d && d?.uid && r.value?.updateConfig({
|
|
589
|
+
dynamicWidgetId: d.uid
|
|
590
|
+
});
|
|
591
|
+
});
|
|
592
|
+
},
|
|
593
|
+
{ immediate: !0 }
|
|
594
|
+
);
|
|
595
|
+
const m = y(() => V(s.value.layout)), O = y(() => a.value?.isDynamicActive ? {
|
|
596
|
+
position: "absolute",
|
|
597
|
+
left: `${a.value.dynamicPosition.x}%`,
|
|
598
|
+
top: `${a.value.dynamicPosition.y}%`,
|
|
599
|
+
zIndex: 100,
|
|
600
|
+
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);
|
|
607
|
+
};
|
|
608
|
+
return (d, b) => (p(), E("div", {
|
|
609
|
+
id: h(o),
|
|
610
|
+
ref_key: "elementRef",
|
|
611
|
+
ref: c,
|
|
612
|
+
class: "omnipad-input-zone omnipad-prevent",
|
|
613
|
+
style: _(m.value)
|
|
614
|
+
}, [
|
|
615
|
+
L(te, { nodes: l.value }, {
|
|
616
|
+
default: K(() => [
|
|
617
|
+
k(d.$slots, "default", {}, void 0, !0)
|
|
618
|
+
]),
|
|
619
|
+
_: 3
|
|
620
|
+
}, 8, ["nodes"]),
|
|
621
|
+
h(r)?.isInterceptorRequired ? (p(), E("div", {
|
|
622
|
+
key: 0,
|
|
623
|
+
class: "omnipad-input-zone-trigger",
|
|
624
|
+
onPointerdown: ne,
|
|
625
|
+
onPointermove: ie,
|
|
626
|
+
onPointerup: S,
|
|
627
|
+
onPointercancel: S,
|
|
628
|
+
onLostpointercapture: S,
|
|
629
|
+
onPointerleave: S
|
|
630
|
+
}, [
|
|
631
|
+
G("div", {
|
|
632
|
+
class: "dynamic-widget-mount",
|
|
633
|
+
style: _(O.value)
|
|
634
|
+
}, [
|
|
635
|
+
u.value.isFromSlot ? (p(), C(Y(u.value.nodeToRender), {
|
|
636
|
+
key: 0,
|
|
637
|
+
ref: (I) => i.value = I
|
|
638
|
+
}, null, 512)) : u.value.nodeToRender ? (p(), C(Y(h(ee)(u.value.nodeToRender.type)), {
|
|
639
|
+
key: 1,
|
|
640
|
+
ref: (I) => i.value = I,
|
|
641
|
+
"tree-node": u.value.nodeToRender
|
|
642
|
+
}, null, 8, ["tree-node"])) : T("", !0)
|
|
643
|
+
], 4)
|
|
644
|
+
], 32)) : T("", !0)
|
|
645
|
+
], 12, ke));
|
|
646
|
+
}
|
|
647
|
+
}), Ue = /* @__PURE__ */ w(xe, [["__scopeId", "data-v-02669919"]]), Me = ["id"], $e = /* @__PURE__ */ P({
|
|
648
|
+
__name: "RootLayer",
|
|
649
|
+
props: {
|
|
650
|
+
treeNode: {},
|
|
651
|
+
widgetId: {}
|
|
652
|
+
},
|
|
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),
|
|
657
|
+
ref_key: "elementRef",
|
|
658
|
+
ref: o,
|
|
659
|
+
class: "omnipad-virtual-layer"
|
|
660
|
+
}, [
|
|
661
|
+
L(te, {
|
|
662
|
+
nodes: e.treeNode?.children || []
|
|
663
|
+
}, {
|
|
664
|
+
default: K(() => [
|
|
665
|
+
k(s.$slots, "default", {}, void 0, !0)
|
|
666
|
+
]),
|
|
667
|
+
_: 3
|
|
668
|
+
}, 8, ["nodes"])
|
|
669
|
+
], 8, Me));
|
|
670
|
+
}
|
|
671
|
+
}), Be = /* @__PURE__ */ w($e, [["__scopeId", "data-v-a509fd6e"]]), Fe = ["id"], Ye = /* @__PURE__ */ P({
|
|
672
|
+
__name: "TargetZone",
|
|
673
|
+
props: {
|
|
674
|
+
treeNode: {},
|
|
675
|
+
widgetId: {},
|
|
676
|
+
cursorEnabled: { type: Boolean },
|
|
677
|
+
cursorAutoDelay: {},
|
|
678
|
+
layout: {}
|
|
679
|
+
},
|
|
680
|
+
setup(e) {
|
|
681
|
+
const t = e, n = {
|
|
682
|
+
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),
|
|
692
|
+
ref_key: "elementRef",
|
|
693
|
+
ref: r,
|
|
694
|
+
class: "omnipad-target-zone",
|
|
695
|
+
style: _(a.value)
|
|
696
|
+
}, [
|
|
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", {
|
|
711
|
+
key: 0,
|
|
712
|
+
class: "omnipad-virtual-cursor",
|
|
713
|
+
style: _(c.value)
|
|
714
|
+
}, [
|
|
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 = {
|
|
722
|
+
key: 0,
|
|
723
|
+
class: "omnipad-button-label"
|
|
724
|
+
}, Ve = /* @__PURE__ */ P({
|
|
725
|
+
__name: "VirtualButtonBase",
|
|
726
|
+
props: {
|
|
727
|
+
layout: {},
|
|
728
|
+
isActive: { type: Boolean },
|
|
729
|
+
label: {}
|
|
730
|
+
},
|
|
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),
|
|
736
|
+
tabindex: "-1"
|
|
737
|
+
}, [
|
|
738
|
+
k(i.$slots, "default", {}, () => [
|
|
739
|
+
e.label ? (p(), E("span", Ke, me(e.label), 1)) : T("", !0)
|
|
740
|
+
], !0)
|
|
741
|
+
], 6));
|
|
742
|
+
}
|
|
743
|
+
}), Ze = /* @__PURE__ */ w(Ve, [["__scopeId", "data-v-6cbe805c"]]), We = /* @__PURE__ */ P({
|
|
744
|
+
__name: "VirtualKeyboardButton",
|
|
745
|
+
props: {
|
|
746
|
+
treeNode: {},
|
|
747
|
+
widgetId: {},
|
|
748
|
+
label: {},
|
|
749
|
+
targetStageId: {},
|
|
750
|
+
mapping: {},
|
|
751
|
+
layout: {}
|
|
752
|
+
},
|
|
753
|
+
setup(e, { expose: t }) {
|
|
754
|
+
const n = e, i = {
|
|
755
|
+
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),
|
|
769
|
+
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,
|
|
775
|
+
onPointerup: u,
|
|
776
|
+
onPointercancel: u,
|
|
777
|
+
onLostpointercapture: u
|
|
778
|
+
}, null, 8, ["id", "layout", "label", "is-active"]));
|
|
779
|
+
}
|
|
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);
|
|
785
|
+
export {
|
|
786
|
+
Ue as InputZone,
|
|
787
|
+
Be as RootLayer,
|
|
788
|
+
Le as TargetZone,
|
|
789
|
+
We as VirtualKeyboardButton,
|
|
790
|
+
x as registerComponent
|
|
791
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(m,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],n):(m=typeof globalThis<"u"?globalThis:m||self,n(m.OmnipadVue={},m.Vue))})(this,(function(m,n){"use strict";var G=Object.defineProperty,j=(e,t,o)=>t in e?G(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o,y=(e,t,o)=>j(e,typeof t!="symbol"?t+"":t,o),h={INPUT_ZONE:"input-zone",TARGET_ZONE:"target-zone",KEYBOARD_BUTTON:"keyboard-button",ROOT_LAYER:"root-layer"},p={KEYDOWN:"keydown",KEYUP:"keyup",POINTER:"pointer",POINTERMOVE:"pointermove",POINTERDOWN:"pointerdown",POINTERUP:"pointerup",MOUSE:"mouse",MOUSEMOVE:"mousemove",MOUSEDOWN:"mousedown",MOUSEUP:"mouseup",CLICK:"click"},B={PARENT_ID_KEY:"omnipad-parent-id-link"},U=(e,t=2)=>{const o=Math.pow(10,t);return Math.round(e*o)/o},T=(e,t)=>U(e*t/100),$=(e,t)=>t===0?0:U(e*100/t),x=(e,t)=>{let o=document.elementFromPoint(e,t);for(;o&&o.shadowRoot;){const i=o.shadowRoot.elementFromPoint(e,t);if(!i||i===o)break;o=i}return o},M=()=>{let e=document.activeElement;for(;e&&e.shadowRoot&&e.shadowRoot.activeElement;)e=e.shadowRoot.activeElement;return e},X=e=>{M()!==e&&(e.hasAttribute("tabindex")||e.setAttribute("tabindex","-1"),e.focus())},H=(e,t)=>{const o=new KeyboardEvent(e,{...t,which:t.keyCode,bubbles:!0,cancelable:!0,view:window});window.dispatchEvent(o)},q=(e,t,o,i={})=>{const r=x(t,o);if(!r)return;const s={bubbles:!0,cancelable:!0,composed:!0,clientX:t,clientY:o,view:window,...i};if(e.startsWith("pointer")){r.dispatchEvent(new PointerEvent(e,{isPrimary:!0,pointerId:1,pointerType:"mouse",...s}));const a=e.replace("pointer","mouse");r.dispatchEvent(new MouseEvent(a,s))}else r.dispatchEvent(new MouseEvent(e,s))},J=(e="omnipad")=>{const t=Date.now().toString(36),o=Math.random().toString(36).substring(2,6);return`${e}-${t}-${o}`},N=e=>{if(!e)return{};const t={};t.position="absolute",["left","top","right","bottom","width","height"].forEach(r=>{const s=e[r];s!==void 0&&(t[r]=typeof s=="number"?`${s}px`:s)}),e.zIndex!==void 0&&(t.zIndex=e.zIndex);const i={"top-left":"translate(0, 0)","top-center":"translate(-50%, 0)","top-right":"translate(-100%, 0)","center-left":"translate(0, -50%)",center:"translate(-50%, -50%)","center-right":"translate(-100%, -50%)","bottom-left":"translate(0, -100%)","bottom-center":"translate(-50%, -100%)","bottom-right":"translate(-100%, -100%)"};return e.anchor&&(t.transform=i[e.anchor]),t},Q=class{constructor(){y(this,"listeners",new Set)}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}emit(e){this.listeners.forEach(t=>{try{t(e)}catch(o){console.error("[OmniPad-Core] Emitter callback error:",o)}})}clear(){this.listeners.clear()}},b=class{constructor(e,t,o,i){y(this,"uid"),y(this,"type"),y(this,"config"),y(this,"state"),y(this,"rect",null),y(this,"stateEmitter",new Q),this.uid=e,this.type=t,this.config=o,this.state=i}subscribe(e){return e(this.state),this.stateEmitter.subscribe(e)}setState(e){this.state={...this.state,...e},this.stateEmitter.emit(this.state)}destroy(){this.reset(),this.stateEmitter.clear(),k.getInstance().unregister(this.uid)}updateRect(e){this.rect=e}updateConfig(e){this.config={...this.config,...e},this.stateEmitter.emit(this.state)}getState(){return this.state}getConfig(){return this.config}},C=Symbol.for("omnipad.registry.instance"),k=class W{constructor(){y(this,"entities",new Map)}static getInstance(){const t=globalThis;return t[C]||(t[C]=new W),t[C]}register(t){if(!t.uid){console.warn("[OmniPad-Core] Registry: Attempted to register entity without UID.",t);return}this.entities.has(t.uid),this.entities.set(t.uid,t)}unregister(t){this.entities.has(t)&&this.entities.delete(t)}getEntity(t){return this.entities.get(t)}getAllEntities(){return Array.from(this.entities.values())}getEntitiesByRoot(t){const o=this.getAllEntities();if(!t)return o;if(!this.entities.get(t))return console.warn(`[OmniPad-Core] Registry: Root entity ${t} not found.`),[];const r=new Map;o.forEach(l=>{if(l instanceof b){const d=l.getConfig();d.parentId&&(r.has(d.parentId)||r.set(d.parentId,[]),r.get(d.parentId).push(l))}});const s=[],a=[t],c=new Set;for(;a.length>0;){const l=a.shift();if(c.has(l))continue;c.add(l);const d=this.entities.get(l);if(d){s.push(d);const u=r.get(l);u&&u.forEach(g=>a.push(g.uid))}}return s}destroyByRoot(t){const o=this.getEntitiesByRoot(t);for(let i=o.length-1;i>=0;i--){const r=o[i];try{r.destroy()}catch(s){console.error(`[OmniPad-Core] Error during destroyByRoot at ${r.uid}:`,s)}}}clear(){this.entities.clear()}resetAll(){this.entities.forEach(t=>{"reset"in t&&t.reset()})}debugGetSnapshot(){return new Map(this.entities)}},ee={isDynamicActive:!1,dynamicPointerId:null,dynamicPosition:{x:0,y:0}},te=class extends b{constructor(e,t){super(e,h.INPUT_ZONE,t,ee)}onPointerDown(e){if(this.state.isDynamicActive||e.target!==e.currentTarget)return;e.cancelable&&e.preventDefault();const t=this.calculateRelativePosition(e.clientX,e.clientY);this.setState({isDynamicActive:!0,dynamicPointerId:e.pointerId,dynamicPosition:t})}onPointerMove(e){!this.state.isDynamicActive||(e.pointerId,this.state.dynamicPointerId)}onPointerUp(e){this.handleRelease(e)}onPointerCancel(e){this.handleRelease(e)}handleRelease(e){if(e.pointerId===this.state.dynamicPointerId){try{e.currentTarget.releasePointerCapture(e.pointerId)}catch{}this.setState({isDynamicActive:!1,dynamicPointerId:null})}}calculateRelativePosition(e,t){return this.rect?{x:$(e-this.rect.left,this.rect.width),y:$(t-this.rect.top,this.rect.height)}:{x:0,y:0}}get isInterceptorRequired(){return!!(this.config.dynamicWidgetId||this.config.preventFocusLoss)}reset(){this.setState({isDynamicActive:!1,dynamicPointerId:null})}},A={isActive:!1,isPressed:!1,pointerId:null,value:0},ne=class extends b{constructor(e,t){super(e,h.KEYBOARD_BUTTON,t,A)}onPointerDown(e){e.cancelable&&e.preventDefault(),e.target.setPointerCapture(e.pointerId),this.setState({isActive:!0,isPressed:!0,pointerId:e.pointerId}),this.sendInputSignal(p.KEYDOWN)}onPointerUp(e){e.cancelable&&e.preventDefault(),this.handleRelease(e)}onPointerCancel(e){this.handleRelease(e)}onPointerMove(e){e.cancelable&&e.preventDefault()}handleRelease(e){this.state.pointerId===e.pointerId&&(e.target.hasPointerCapture(e.pointerId)&&e.target.releasePointerCapture(e.pointerId),this.setState(A),this.sendInputSignal(p.KEYUP))}sendInputSignal(e){const t=this.config.targetStageId;if(!t)return;const o=k.getInstance().getEntity(t);if(o&&typeof o.handleSignal=="function"){const i={targetStageId:t,type:e,payload:{key:this.config.mapping.key,code:this.config.mapping.code,keyCode:this.config.mapping.keyCode}};o.handleSignal(i)}}reset(){this.state.isPressed&&this.sendInputSignal(p.KEYUP),this.setState(A)}},oe={isHighlighted:!1},ie=class extends b{constructor(e,t){super(e,h.ROOT_LAYER,t,oe)}reset(){}},re={position:{x:50,y:50},isVisible:!1,isPointerDown:!1,isFocusReturning:!1},se=class extends b{constructor(e,t){super(e,h.TARGET_ZONE,t,re),y(this,"hideTimer",null),y(this,"focusFeedbackTimer",null)}handleSignal(e){const{type:t,payload:o}=e;switch(this.ensureFocus(),t){case p.KEYDOWN:case p.KEYUP:H(t,o);break;case p.MOUSEMOVE:o.point&&(this.updateCursorPosition(o.point),this.config.cursorEnabled&&this.showCursor(),this.executeMouseAction(p.POINTERMOVE,o));break;case p.MOUSEDOWN:case p.MOUSEUP:case p.CLICK:this.config.cursorEnabled&&this.showCursor(),this.executeMouseAction(t.startsWith(p.MOUSE)?t.replace(p.MOUSE,p.POINTER):t,o);break}}executeMouseAction(e,t){if(!this.rect)return;e===p.POINTERDOWN&&this.setState({isPointerDown:!0}),e===p.POINTERUP&&this.setState({isPointerDown:!1});const o=t.point||this.state.position,i=this.rect.left+T(o.x,this.rect.width),r=this.rect.top+T(o.y,this.rect.height);q(e,i,r,{button:t.button??0,buttons:this.state.isPointerDown?1:0})}ensureFocus(){if(!this.rect)return;const e=this.rect.left+T(this.state.position.x,this.rect.width),t=this.rect.top+T(this.state.position.y,this.rect.height),o=x(e,t);o&&M()!==o&&(X(o),this.triggerFocusFeedback())}triggerFocusFeedback(){this.setState({isFocusReturning:!0}),this.focusFeedbackTimer&&clearTimeout(this.focusFeedbackTimer),this.focusFeedbackTimer=setTimeout(()=>this.setState({isFocusReturning:!1}),500)}updateCursorPosition(e){this.setState({position:{...e}})}showCursor(){this.setState({isVisible:!0}),this.hideTimer&&clearTimeout(this.hideTimer),this.config.cursorAutoDelay&&this.config.cursorAutoDelay>0&&(this.hideTimer=setTimeout(()=>this.setState({isVisible:!1}),this.config.cursorAutoDelay))}reset(){this.state.isPointerDown&&this.executeMouseAction(p.POINTERUP,{}),this.hideTimer&&clearTimeout(this.hideTimer),this.focusFeedbackTimer&&clearTimeout(this.focusFeedbackTimer),this.setState({isVisible:!1,isPointerDown:!1,isFocusReturning:!1})}};const V={};function I(e,t){V[e]=t}function F(e){const t=V[e];return t||n.defineComponent({render:()=>n.h("div",{style:"color:red"},`[Unknown: ${e}]`)})}function v(e){const t=n.shallowRef(),o=n.ref(),i=n.ref(null),r=a=>{o.value=a};let s=null;return n.onMounted(()=>{const a=e();t.value=a,k.getInstance().register(a),"subscribe"in a&&a.subscribe(r);let c=null;i.value&&(i.value instanceof Element?c=i.value:i.value.$el instanceof Element&&(c=i.value.$el)),c&&"updateRect"in a&&(s=new ResizeObserver(l=>{for(const d of l)a.updateRect(d.target.getBoundingClientRect())}),s.observe(c),a.updateRect(c.getBoundingClientRect()))}),n.onUnmounted(()=>{s&&s.disconnect(),t.value&&t.value.destroy()}),{core:t,state:o,elementRef:i}}const ae={class:"omnipad-virtual-layer-base omnipad-prevent"},ce=n.defineComponent({__name:"VirtualLayerBase",props:{nodes:{}},setup(e){return(t,o)=>(n.openBlock(),n.createElementBlock("div",ae,[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(e.nodes||[],i=>(n.openBlock(),n.createBlock(n.resolveDynamicComponent(n.unref(F)(i.type)),{key:i.uid,"tree-node":i},null,8,["tree-node"]))),128)),n.renderSlot(t.$slots,"default",{},void 0,!0)]))}}),_=(e,t)=>{const o=e.__vccOpts||e;for(const[i,r]of t)o[i]=r;return o},L=_(ce,[["__scopeId","data-v-6f1860f6"]]);function R(e,t,o={}){const i=t.treeNode,r=i&&i.type===e?i:void 0;i&&i.type!==e&&console.warn(`[OmniPad-Validation] Type mismatch! Component expected "${e}", but received "${i.type}". Config ignored.`);const s=n.inject(B.PARENT_ID_KEY,n.ref(void 0)),a=n.computed(()=>t.parentId||r?.config?.parentId||s.value),c=n.computed(()=>t.widgetId||r?.uid||J(e));n.provide(B.PARENT_ID_KEY,c);const l=n.computed(()=>{const d=r?.config||{},u=Object.fromEntries(Object.entries(t).filter(([g,w])=>w!==void 0&&g!=="treeNode"&&g!=="widgetId"));return{...o,...d,...u,id:c.value,type:e,parentId:a.value,layout:{...o.layout||{},...d.layout||{},...u.layout||{}}}});return{uid:c,config:l}}const le=["id"],Y=_(n.defineComponent({__name:"InputZone",props:{treeNode:{},widgetId:{},layout:{},preventFocusLoss:{}},setup(e){const t=e,o=n.useSlots(),i=n.ref(null),{uid:r,config:s}=R(h.INPUT_ZONE,t),{core:a,state:c,elementRef:l}=v(()=>new te(r.value,s.value)),d=n.computed(()=>{const f=t.treeNode?.config?.dynamicWidgetId;return t.treeNode?.children?.filter(E=>E.uid!==f)||[]}),u=n.computed(()=>{const E=(o.dynamicWidget?.()||[]).filter(O=>!(O.type===Comment||O.type===Text)),P=t.treeNode?.children?.find(O=>O.uid===t.treeNode?.config?.dynamicWidgetId),D=E.length>0;return E.length>1&&console.error(`[OmniPad-Validation] InputZone ${r.value} has multiple dynamic widgets in slot. Only the first one will be activated.`),D&&P&&console.warn(`[OmniPad-Validation] InputZone ${r.value} has both Slot and Config dynamic widgets. Config ignored.`),{nodeToRender:D?E[0]:P||null,isFromSlot:D}});n.watch(i,f=>{n.nextTick(()=>{f&&f?.uid&&a.value?.updateConfig({dynamicWidgetId:f.uid})})},{immediate:!0});const g=n.computed(()=>N(s.value.layout)),w=n.computed(()=>c.value?.isDynamicActive?{position:"absolute",left:`${c.value.dynamicPosition.x}%`,top:`${c.value.dynamicPosition.y}%`,zIndex:100,pointerEvents:"auto"}:{display:"none"}),he=f=>{a.value&&(a.value.onPointerDown(f),c.value?.isDynamicActive&&i.value&&typeof i.value.onPointerDown=="function"&&i.value.onPointerDown(f))},me=f=>{a.value&&(a.value.onPointerMove(f),c.value?.isDynamicActive&&i.value&&typeof i.value.onPointerMove=="function"&&i.value.onPointerMove(f))},S=f=>{c.value?.isDynamicActive&&i.value&&typeof i.value.onPointerUp=="function"&&i.value.onPointerUp(f),a.value&&a.value.onPointerUp(f)};return(f,E)=>(n.openBlock(),n.createElementBlock("div",{id:n.unref(r),ref_key:"elementRef",ref:l,class:"omnipad-input-zone omnipad-prevent",style:n.normalizeStyle(g.value)},[n.createVNode(L,{nodes:d.value},{default:n.withCtx(()=>[n.renderSlot(f.$slots,"default",{},void 0,!0)]),_:3},8,["nodes"]),n.unref(a)?.isInterceptorRequired?(n.openBlock(),n.createElementBlock("div",{key:0,class:"omnipad-input-zone-trigger",onPointerdown:he,onPointermove:me,onPointerup:S,onPointercancel:S,onLostpointercapture:S,onPointerleave:S},[n.createElementVNode("div",{class:"dynamic-widget-mount",style:n.normalizeStyle(w.value)},[u.value.isFromSlot?(n.openBlock(),n.createBlock(n.resolveDynamicComponent(u.value.nodeToRender),{key:0,ref:P=>i.value=P},null,512)):u.value.nodeToRender?(n.openBlock(),n.createBlock(n.resolveDynamicComponent(n.unref(F)(u.value.nodeToRender.type)),{key:1,ref:P=>i.value=P,"tree-node":u.value.nodeToRender},null,8,["tree-node"])):n.createCommentVNode("",!0)],4)],32)):n.createCommentVNode("",!0)],12,le))}}),[["__scopeId","data-v-02669919"]]),de=["id"],K=_(n.defineComponent({__name:"RootLayer",props:{treeNode:{},widgetId:{}},setup(e){const t=e,{uid:o,config:i}=R(h.ROOT_LAYER,t),{elementRef:r}=v(()=>new ie(o.value,i.value));return(s,a)=>(n.openBlock(),n.createElementBlock("div",{id:n.unref(o),ref_key:"elementRef",ref:r,class:"omnipad-virtual-layer"},[n.createVNode(L,{nodes:e.treeNode?.children||[]},{default:n.withCtx(()=>[n.renderSlot(s.$slots,"default",{},void 0,!0)]),_:3},8,["nodes"])],8,de))}}),[["__scopeId","data-v-a509fd6e"]]),ue=["id"],z=_(n.defineComponent({__name:"TargetZone",props:{treeNode:{},widgetId:{},cursorEnabled:{type:Boolean},cursorAutoDelay:{},layout:{}},setup(e){const t=e,o={cursorAutoDelay:2500},{uid:i,config:r}=R(h.TARGET_ZONE,t,o),{state:s,elementRef:a}=v(()=>new se(i.value,r.value)),c=n.computed(()=>N(r.value.layout)),l=n.computed(()=>s.value?{left:`${s.value.position.x}%`,top:`${s.value.position.y}%`,opacity:s.value.isVisible?1:0}:{display:"none"});return(d,u)=>(n.openBlock(),n.createElementBlock("div",{id:n.unref(i),ref_key:"elementRef",ref:a,class:"omnipad-target-zone",style:n.normalizeStyle(c.value)},[n.createVNode(n.Transition,{name:"pulse"},{default:n.withCtx(()=>[n.unref(s)?.isFocusReturning?(n.openBlock(),n.createElementBlock("div",{key:0,class:"focus-feedback-ring",style:n.normalizeStyle({left:`${n.unref(s).position.x}%`,top:`${n.unref(s).position.y}%`})},null,4)):n.createCommentVNode("",!0)]),_:1}),n.unref(r).cursorEnabled?(n.openBlock(),n.createElementBlock("div",{key:0,class:"omnipad-virtual-cursor",style:n.normalizeStyle(l.value)},[n.createElementVNode("div",{class:n.normalizeClass(["cursor-dot",{"is-down":n.unref(s)?.isPointerDown}])},null,2)],4)):n.createCommentVNode("",!0)],12,ue))}}),[["__scopeId","data-v-b9d49b97"]]),fe={key:0,class:"omnipad-button-label"},pe=_(n.defineComponent({__name:"VirtualButtonBase",props:{layout:{},isActive:{type:Boolean},label:{}},setup(e){const t=e,o=n.computed(()=>t.layout?N(t.layout):{});return(i,r)=>(n.openBlock(),n.createElementBlock("div",{class:n.normalizeClass(["omnipad-button-base",{"omnipad-is-active":e.isActive}]),style:n.normalizeStyle(o.value),tabindex:"-1"},[n.renderSlot(i.$slots,"default",{},()=>[e.label?(n.openBlock(),n.createElementBlock("span",fe,n.toDisplayString(e.label),1)):n.createCommentVNode("",!0)],!0)],6))}}),[["__scopeId","data-v-6cbe805c"]]),Z=n.defineComponent({__name:"VirtualKeyboardButton",props:{treeNode:{},widgetId:{},label:{},targetStageId:{},mapping:{},layout:{}},setup(e,{expose:t}){const o=e,i={label:"BTN"},{uid:r,config:s}=R(h.KEYBOARD_BUTTON,o,i),{core:a,state:c,elementRef:l}=v(()=>new ne(r.value,s.value)),d=g=>a.value?.onPointerDown(g),u=g=>a.value?.onPointerUp(g);return t({uid:r,onPointerDown:d,onPointerUp:u}),(g,w)=>(n.openBlock(),n.createBlock(pe,{id:n.unref(r),ref_key:"elementRef",ref:l,layout:n.unref(s).layout,label:n.unref(s).label,"is-active":n.unref(c)?.isPressed,onPointerdown:d,onPointerup:u,onPointercancel:u,onLostpointercapture:u},null,8,["id","layout","label","is-active"]))}});I(h.INPUT_ZONE,Y),I(h.ROOT_LAYER,K),I(h.TARGET_ZONE,z),I(h.KEYBOARD_BUTTON,Z),m.InputZone=Y,m.RootLayer=K,m.TargetZone=z,m.VirtualKeyboardButton=Z,m.registerComponent=I,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@omnipad/vue",
|
|
3
|
+
"version": "0.1.1-alpha.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "./dist/omnipad-vue.umd.js",
|
|
6
|
+
"module": "./dist/omnipad-vue.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/omnipad-vue.mjs",
|
|
15
|
+
"require": "./dist/omnipad-vue.umd.js"
|
|
16
|
+
},
|
|
17
|
+
"./style.css": "./dist/omnipad-vue.css"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [],
|
|
20
|
+
"author": "",
|
|
21
|
+
"license": "ISC",
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@vitejs/plugin-vue": "^6.0.3",
|
|
24
|
+
"typescript": "^5.9.3",
|
|
25
|
+
"vite": "^7.3.1",
|
|
26
|
+
"vite-plugin-dts": "^4.5.4",
|
|
27
|
+
"vue": "^3.5.27"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@omnipad/core": "0.1.1-alpha.0"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public",
|
|
34
|
+
"registry": "https://registry.npmjs.org/"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/omnipad-js/omnipad.git"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "vite build",
|
|
42
|
+
"dev": "vite build --watch"
|
|
43
|
+
}
|
|
44
|
+
}
|