@realitycollective/iwsdk-uiextensions 0.1.0-preview.4
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/CHANGELOG.md +40 -0
- package/Examples/README.md +13 -0
- package/Examples/basic-window/main.ts +32 -0
- package/Examples/basic-window/window.uikitml +58 -0
- package/Examples/controls/controls.uikitml +49 -0
- package/Examples/controls/main.ts +48 -0
- package/Examples/dock-regions/main.ts +55 -0
- package/LICENSE +21 -0
- package/README.md +155 -0
- package/dist/component-set.d.ts +28 -0
- package/dist/component-set.js +108 -0
- package/dist/component-set.js.map +1 -0
- package/dist/components.d.ts +189 -0
- package/dist/components.js +97 -0
- package/dist/components.js.map +1 -0
- package/dist/factory.d.ts +44 -0
- package/dist/factory.js +63 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/manager-registry.d.ts +8 -0
- package/dist/manager-registry.js +11 -0
- package/dist/manager-registry.js.map +1 -0
- package/dist/region-registry-store.d.ts +7 -0
- package/dist/region-registry-store.js +11 -0
- package/dist/region-registry-store.js.map +1 -0
- package/dist/register.d.ts +19 -0
- package/dist/register.js +20 -0
- package/dist/register.js.map +1 -0
- package/dist/scene-host.d.ts +44 -0
- package/dist/scene-host.js +190 -0
- package/dist/scene-host.js.map +1 -0
- package/dist/systems/controls-system.d.ts +24 -0
- package/dist/systems/controls-system.js +24 -0
- package/dist/systems/controls-system.js.map +1 -0
- package/dist/systems/dock-region-system.d.ts +230 -0
- package/dist/systems/dock-region-system.js +102 -0
- package/dist/systems/dock-region-system.js.map +1 -0
- package/dist/systems/dock-system.d.ts +205 -0
- package/dist/systems/dock-system.js +135 -0
- package/dist/systems/dock-system.js.map +1 -0
- package/dist/systems/drag-system.d.ts +280 -0
- package/dist/systems/drag-system.js +167 -0
- package/dist/systems/drag-system.js.map +1 -0
- package/dist/systems/window-system.d.ts +439 -0
- package/dist/systems/window-system.js +244 -0
- package/dist/systems/window-system.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ECS components for UI Extensions.
|
|
3
|
+
*
|
|
4
|
+
* These compose with the IWSDK's own components - a window entity typically
|
|
5
|
+
* carries `PanelUI` (the IWSDK loads/renders the panel), `UIWindow` (ours),
|
|
6
|
+
* and the IWSDK interaction tags (`RayInteractable`, `PokeInteractable`).
|
|
7
|
+
* The systems in this package add/remove the IWSDK `Follower` / `ScreenSpace`
|
|
8
|
+
* components to realise dock modes rather than re-implementing them.
|
|
9
|
+
*/
|
|
10
|
+
import { Types } from '@iwsdk/core';
|
|
11
|
+
/** Region flow options mirrored as an enum object for the component schema. */
|
|
12
|
+
export declare const RegionFlowType: {
|
|
13
|
+
readonly Row: "row";
|
|
14
|
+
readonly Column: "column";
|
|
15
|
+
readonly Grid: "grid";
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Marks a panel entity as a managed window with chrome, focus, docking and
|
|
19
|
+
* drag behaviour. Pair with `PanelUI` whose markup contains the window chrome
|
|
20
|
+
* elements (see `WINDOW_CHROME_IDS` / the Examples folder).
|
|
21
|
+
*/
|
|
22
|
+
export declare const UIWindow: import("elics").Component<{
|
|
23
|
+
/** Stable id; auto-generated when empty. */
|
|
24
|
+
windowId: {
|
|
25
|
+
type: Types.String;
|
|
26
|
+
default: string;
|
|
27
|
+
};
|
|
28
|
+
/** Title text written into the `uix-title` element. */
|
|
29
|
+
title: {
|
|
30
|
+
type: Types.String;
|
|
31
|
+
default: string;
|
|
32
|
+
};
|
|
33
|
+
/** Current dock state. */
|
|
34
|
+
dockMode: {
|
|
35
|
+
type: Types.Enum;
|
|
36
|
+
enum: {
|
|
37
|
+
readonly WorldLocked: "world-locked";
|
|
38
|
+
readonly BodyFollow: "body-follow";
|
|
39
|
+
readonly HeadLocked: "head-locked";
|
|
40
|
+
};
|
|
41
|
+
default: "world-locked";
|
|
42
|
+
};
|
|
43
|
+
/** Whether the title bar drags the window. */
|
|
44
|
+
movable: {
|
|
45
|
+
type: Types.Boolean;
|
|
46
|
+
default: true;
|
|
47
|
+
};
|
|
48
|
+
/** Show/enable the close affordance. */
|
|
49
|
+
closable: {
|
|
50
|
+
type: Types.Boolean;
|
|
51
|
+
default: true;
|
|
52
|
+
};
|
|
53
|
+
/** Show/enable the minimize affordance. */
|
|
54
|
+
minimizable: {
|
|
55
|
+
type: Types.Boolean;
|
|
56
|
+
default: true;
|
|
57
|
+
};
|
|
58
|
+
/** Show/enable the pin (body-follow ⇄ world-locked) affordance. */
|
|
59
|
+
pinnable: {
|
|
60
|
+
type: Types.Boolean;
|
|
61
|
+
default: true;
|
|
62
|
+
};
|
|
63
|
+
/** Keep the window yawed toward the viewer while it is being dragged. */
|
|
64
|
+
billboardWhileDragging: {
|
|
65
|
+
type: Types.Boolean;
|
|
66
|
+
default: true;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Seconds a title-bar press must be held before it becomes a drag.
|
|
70
|
+
* Shorter presses stay clicks, so title-bar buttons don't fight the drag.
|
|
71
|
+
*/
|
|
72
|
+
dragDelay: {
|
|
73
|
+
type: Types.Float32;
|
|
74
|
+
default: number;
|
|
75
|
+
};
|
|
76
|
+
/** Head-relative offset used in `body-follow` mode (meters). */
|
|
77
|
+
followOffset: {
|
|
78
|
+
type: Types.Vec3;
|
|
79
|
+
default: [number, number, number];
|
|
80
|
+
};
|
|
81
|
+
/** `Follower` lerp speed for body-follow. */
|
|
82
|
+
followSpeed: {
|
|
83
|
+
type: Types.Float32;
|
|
84
|
+
default: number;
|
|
85
|
+
};
|
|
86
|
+
/** `Follower` positional deadzone for body-follow (meters). */
|
|
87
|
+
followTolerance: {
|
|
88
|
+
type: Types.Float32;
|
|
89
|
+
default: number;
|
|
90
|
+
};
|
|
91
|
+
/** Meters the focused window is nudged toward the viewer per focus depth. */
|
|
92
|
+
focusBias: {
|
|
93
|
+
type: Types.Float32;
|
|
94
|
+
default: number;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* World size box in meters, applied via `UIKitDocument.setTargetDimensions`
|
|
98
|
+
* once the document loads. IWSDK 0.5 removed `PanelUI.maxWidth/maxHeight`;
|
|
99
|
+
* this is the supported replacement. `0` leaves the document at its
|
|
100
|
+
* intrinsic markup size, scaled only by the entity transform.
|
|
101
|
+
*/
|
|
102
|
+
targetWidth: {
|
|
103
|
+
type: Types.Float32;
|
|
104
|
+
default: number;
|
|
105
|
+
};
|
|
106
|
+
targetHeight: {
|
|
107
|
+
type: Types.Float32;
|
|
108
|
+
default: number;
|
|
109
|
+
};
|
|
110
|
+
}>;
|
|
111
|
+
/**
|
|
112
|
+
* Internal bookkeeping the systems keep on window entities - which dock mode
|
|
113
|
+
* has actually been applied to engine components, and whether chrome wiring
|
|
114
|
+
* has run for the current PanelDocument.
|
|
115
|
+
*/
|
|
116
|
+
export declare const UIWindowState: import("elics").Component<{
|
|
117
|
+
appliedDockMode: {
|
|
118
|
+
type: Types.String;
|
|
119
|
+
default: string;
|
|
120
|
+
};
|
|
121
|
+
chromeWired: {
|
|
122
|
+
type: Types.Boolean;
|
|
123
|
+
default: false;
|
|
124
|
+
};
|
|
125
|
+
/** "Home" snapshot captured on adoption - the DOCK button returns here. */
|
|
126
|
+
homeDockMode: {
|
|
127
|
+
type: Types.String;
|
|
128
|
+
default: string;
|
|
129
|
+
};
|
|
130
|
+
homeRegion: {
|
|
131
|
+
type: Types.String;
|
|
132
|
+
default: string;
|
|
133
|
+
};
|
|
134
|
+
homePosition: {
|
|
135
|
+
type: Types.Vec3;
|
|
136
|
+
default: [number, number, number];
|
|
137
|
+
};
|
|
138
|
+
homeYaw: {
|
|
139
|
+
type: Types.Float32;
|
|
140
|
+
default: number;
|
|
141
|
+
};
|
|
142
|
+
}>;
|
|
143
|
+
/**
|
|
144
|
+
* A named layout region that docked windows snap to and are laid out within.
|
|
145
|
+
* Place the entity where the region should live (it can itself carry a
|
|
146
|
+
* `Follower` to make a body-locked region).
|
|
147
|
+
*/
|
|
148
|
+
export declare const UIDockRegion: import("elics").Component<{
|
|
149
|
+
regionId: {
|
|
150
|
+
type: Types.String;
|
|
151
|
+
default: string;
|
|
152
|
+
};
|
|
153
|
+
flow: {
|
|
154
|
+
type: Types.Enum;
|
|
155
|
+
enum: {
|
|
156
|
+
readonly Row: "row";
|
|
157
|
+
readonly Column: "column";
|
|
158
|
+
readonly Grid: "grid";
|
|
159
|
+
};
|
|
160
|
+
default: "column";
|
|
161
|
+
};
|
|
162
|
+
/** Distance between slot origins (meters). */
|
|
163
|
+
pitch: {
|
|
164
|
+
type: Types.Float32;
|
|
165
|
+
default: number;
|
|
166
|
+
};
|
|
167
|
+
/** Columns per row (grid flow only). */
|
|
168
|
+
columns: {
|
|
169
|
+
type: Types.Float32;
|
|
170
|
+
default: number;
|
|
171
|
+
};
|
|
172
|
+
/** Max docked windows (0 = unlimited). */
|
|
173
|
+
capacity: {
|
|
174
|
+
type: Types.Float32;
|
|
175
|
+
default: number;
|
|
176
|
+
};
|
|
177
|
+
/** Drop-capture radius (meters). */
|
|
178
|
+
snapRadius: {
|
|
179
|
+
type: Types.Float32;
|
|
180
|
+
default: number;
|
|
181
|
+
};
|
|
182
|
+
}>;
|
|
183
|
+
/** Present on a window entity while it is docked into a region. */
|
|
184
|
+
export declare const UIDockedTo: import("elics").Component<{
|
|
185
|
+
regionId: {
|
|
186
|
+
type: Types.String;
|
|
187
|
+
default: string;
|
|
188
|
+
};
|
|
189
|
+
}>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ECS components for UI Extensions.
|
|
3
|
+
*
|
|
4
|
+
* These compose with the IWSDK's own components - a window entity typically
|
|
5
|
+
* carries `PanelUI` (the IWSDK loads/renders the panel), `UIWindow` (ours),
|
|
6
|
+
* and the IWSDK interaction tags (`RayInteractable`, `PokeInteractable`).
|
|
7
|
+
* The systems in this package add/remove the IWSDK `Follower` / `ScreenSpace`
|
|
8
|
+
* components to realise dock modes rather than re-implementing them.
|
|
9
|
+
*/
|
|
10
|
+
import { Types, createComponent } from '@iwsdk/core';
|
|
11
|
+
import { DockMode } from '@realitycollective/webxr-uiextensions';
|
|
12
|
+
/** Region flow options mirrored as an enum object for the component schema. */
|
|
13
|
+
export const RegionFlowType = {
|
|
14
|
+
Row: 'row',
|
|
15
|
+
Column: 'column',
|
|
16
|
+
Grid: 'grid',
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Marks a panel entity as a managed window with chrome, focus, docking and
|
|
20
|
+
* drag behaviour. Pair with `PanelUI` whose markup contains the window chrome
|
|
21
|
+
* elements (see `WINDOW_CHROME_IDS` / the Examples folder).
|
|
22
|
+
*/
|
|
23
|
+
export const UIWindow = createComponent('UIWindow', {
|
|
24
|
+
/** Stable id; auto-generated when empty. */
|
|
25
|
+
windowId: { type: Types.String, default: '' },
|
|
26
|
+
/** Title text written into the `uix-title` element. */
|
|
27
|
+
title: { type: Types.String, default: '' },
|
|
28
|
+
/** Current dock state. */
|
|
29
|
+
dockMode: { type: Types.Enum, enum: DockMode, default: DockMode.WorldLocked },
|
|
30
|
+
/** Whether the title bar drags the window. */
|
|
31
|
+
movable: { type: Types.Boolean, default: true },
|
|
32
|
+
/** Show/enable the close affordance. */
|
|
33
|
+
closable: { type: Types.Boolean, default: true },
|
|
34
|
+
/** Show/enable the minimize affordance. */
|
|
35
|
+
minimizable: { type: Types.Boolean, default: true },
|
|
36
|
+
/** Show/enable the pin (body-follow ⇄ world-locked) affordance. */
|
|
37
|
+
pinnable: { type: Types.Boolean, default: true },
|
|
38
|
+
/** Keep the window yawed toward the viewer while it is being dragged. */
|
|
39
|
+
billboardWhileDragging: { type: Types.Boolean, default: true },
|
|
40
|
+
/**
|
|
41
|
+
* Seconds a title-bar press must be held before it becomes a drag.
|
|
42
|
+
* Shorter presses stay clicks, so title-bar buttons don't fight the drag.
|
|
43
|
+
*/
|
|
44
|
+
dragDelay: { type: Types.Float32, default: 0.3 },
|
|
45
|
+
/** Head-relative offset used in `body-follow` mode (meters). */
|
|
46
|
+
followOffset: { type: Types.Vec3, default: [0, -0.15, -1.2] },
|
|
47
|
+
/** `Follower` lerp speed for body-follow. */
|
|
48
|
+
followSpeed: { type: Types.Float32, default: 3 },
|
|
49
|
+
/** `Follower` positional deadzone for body-follow (meters). */
|
|
50
|
+
followTolerance: { type: Types.Float32, default: 0.35 },
|
|
51
|
+
/** Meters the focused window is nudged toward the viewer per focus depth. */
|
|
52
|
+
focusBias: { type: Types.Float32, default: 0.02 },
|
|
53
|
+
/**
|
|
54
|
+
* World size box in meters, applied via `UIKitDocument.setTargetDimensions`
|
|
55
|
+
* once the document loads. IWSDK 0.5 removed `PanelUI.maxWidth/maxHeight`;
|
|
56
|
+
* this is the supported replacement. `0` leaves the document at its
|
|
57
|
+
* intrinsic markup size, scaled only by the entity transform.
|
|
58
|
+
*/
|
|
59
|
+
targetWidth: { type: Types.Float32, default: 0 },
|
|
60
|
+
targetHeight: { type: Types.Float32, default: 0 },
|
|
61
|
+
}, 'UI Extensions managed window (chrome, focus, docking, drag)');
|
|
62
|
+
/**
|
|
63
|
+
* Internal bookkeeping the systems keep on window entities - which dock mode
|
|
64
|
+
* has actually been applied to engine components, and whether chrome wiring
|
|
65
|
+
* has run for the current PanelDocument.
|
|
66
|
+
*/
|
|
67
|
+
export const UIWindowState = createComponent('UIWindowState', {
|
|
68
|
+
appliedDockMode: { type: Types.String, default: '' },
|
|
69
|
+
chromeWired: { type: Types.Boolean, default: false },
|
|
70
|
+
/** "Home" snapshot captured on adoption - the DOCK button returns here. */
|
|
71
|
+
homeDockMode: { type: Types.String, default: '' },
|
|
72
|
+
homeRegion: { type: Types.String, default: '' },
|
|
73
|
+
homePosition: { type: Types.Vec3, default: [0, 0, 0] },
|
|
74
|
+
homeYaw: { type: Types.Float32, default: 0 },
|
|
75
|
+
}, 'Internal UI Extensions window bookkeeping');
|
|
76
|
+
/**
|
|
77
|
+
* A named layout region that docked windows snap to and are laid out within.
|
|
78
|
+
* Place the entity where the region should live (it can itself carry a
|
|
79
|
+
* `Follower` to make a body-locked region).
|
|
80
|
+
*/
|
|
81
|
+
export const UIDockRegion = createComponent('UIDockRegion', {
|
|
82
|
+
regionId: { type: Types.String, default: '' },
|
|
83
|
+
flow: { type: Types.Enum, enum: RegionFlowType, default: RegionFlowType.Column },
|
|
84
|
+
/** Distance between slot origins (meters). */
|
|
85
|
+
pitch: { type: Types.Float32, default: 0.35 },
|
|
86
|
+
/** Columns per row (grid flow only). */
|
|
87
|
+
columns: { type: Types.Float32, default: 2 },
|
|
88
|
+
/** Max docked windows (0 = unlimited). */
|
|
89
|
+
capacity: { type: Types.Float32, default: 0 },
|
|
90
|
+
/** Drop-capture radius (meters). */
|
|
91
|
+
snapRadius: { type: Types.Float32, default: 0.5 },
|
|
92
|
+
}, 'UI Extensions layout region for docking windows');
|
|
93
|
+
/** Present on a window entity while it is docked into a region. */
|
|
94
|
+
export const UIDockedTo = createComponent('UIDockedTo', {
|
|
95
|
+
regionId: { type: Types.String, default: '' },
|
|
96
|
+
}, 'Marks a UI Extensions window as docked into a region');
|
|
97
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AAEjE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,CACrC,UAAU,EACV;IACE,4CAA4C;IAC5C,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;IAC7C,uDAAuD;IACvD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;IAC1C,0BAA0B;IAC1B,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,WAAW,EAAE;IAC7E,8CAA8C;IAC9C,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IAC/C,wCAAwC;IACxC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IAChD,2CAA2C;IAC3C,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IACnD,mEAAmE;IACnE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IAChD,yEAAyE;IACzE,sBAAsB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IAC9D;;;OAGG;IACH,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE;IAChD,gEAAgE;IAChE,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE;IAC7D,6CAA6C;IAC7C,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;IAChD,+DAA+D;IAC/D,eAAe,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IACvD,6EAA6E;IAC7E,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IACjD;;;;;OAKG;IACH,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;IAChD,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;CAClD,EACD,6DAA6D,CAC9D,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAC1C,eAAe,EACf;IACE,eAAe,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;IACpD,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;IACpD,2EAA2E;IAC3E,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;IACjD,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;IAC/C,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;IACtD,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;CAC7C,EACD,2CAA2C,CAC5C,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CACzC,cAAc,EACd;IACE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;IAC7C,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,CAAC,MAAM,EAAE;IAChF,8CAA8C;IAC9C,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IAC7C,wCAAwC;IACxC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;IAC5C,0CAA0C;IAC1C,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;IAC7C,oCAAoC;IACpC,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE;CAClD,EACD,iDAAiD,CAClD,CAAC;AAEF,mEAAmE;AACnE,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,CACvC,YAAY,EACZ;IACE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;CAC9C,EACD,sDAAsD,CACvD,CAAC","sourcesContent":["/**\n * ECS components for UI Extensions.\n *\n * These compose with the IWSDK's own components - a window entity typically\n * carries `PanelUI` (the IWSDK loads/renders the panel), `UIWindow` (ours),\n * and the IWSDK interaction tags (`RayInteractable`, `PokeInteractable`).\n * The systems in this package add/remove the IWSDK `Follower` / `ScreenSpace`\n * components to realise dock modes rather than re-implementing them.\n */\nimport { Types, createComponent } from '@iwsdk/core';\nimport { DockMode } from '@realitycollective/webxr-uiextensions';\n\n/** Region flow options mirrored as an enum object for the component schema. */\nexport const RegionFlowType = {\n Row: 'row',\n Column: 'column',\n Grid: 'grid',\n} as const;\n\n/**\n * Marks a panel entity as a managed window with chrome, focus, docking and\n * drag behaviour. Pair with `PanelUI` whose markup contains the window chrome\n * elements (see `WINDOW_CHROME_IDS` / the Examples folder).\n */\nexport const UIWindow = createComponent(\n 'UIWindow',\n {\n /** Stable id; auto-generated when empty. */\n windowId: { type: Types.String, default: '' },\n /** Title text written into the `uix-title` element. */\n title: { type: Types.String, default: '' },\n /** Current dock state. */\n dockMode: { type: Types.Enum, enum: DockMode, default: DockMode.WorldLocked },\n /** Whether the title bar drags the window. */\n movable: { type: Types.Boolean, default: true },\n /** Show/enable the close affordance. */\n closable: { type: Types.Boolean, default: true },\n /** Show/enable the minimize affordance. */\n minimizable: { type: Types.Boolean, default: true },\n /** Show/enable the pin (body-follow ⇄ world-locked) affordance. */\n pinnable: { type: Types.Boolean, default: true },\n /** Keep the window yawed toward the viewer while it is being dragged. */\n billboardWhileDragging: { type: Types.Boolean, default: true },\n /**\n * Seconds a title-bar press must be held before it becomes a drag.\n * Shorter presses stay clicks, so title-bar buttons don't fight the drag.\n */\n dragDelay: { type: Types.Float32, default: 0.3 },\n /** Head-relative offset used in `body-follow` mode (meters). */\n followOffset: { type: Types.Vec3, default: [0, -0.15, -1.2] },\n /** `Follower` lerp speed for body-follow. */\n followSpeed: { type: Types.Float32, default: 3 },\n /** `Follower` positional deadzone for body-follow (meters). */\n followTolerance: { type: Types.Float32, default: 0.35 },\n /** Meters the focused window is nudged toward the viewer per focus depth. */\n focusBias: { type: Types.Float32, default: 0.02 },\n /**\n * World size box in meters, applied via `UIKitDocument.setTargetDimensions`\n * once the document loads. IWSDK 0.5 removed `PanelUI.maxWidth/maxHeight`;\n * this is the supported replacement. `0` leaves the document at its\n * intrinsic markup size, scaled only by the entity transform.\n */\n targetWidth: { type: Types.Float32, default: 0 },\n targetHeight: { type: Types.Float32, default: 0 },\n },\n 'UI Extensions managed window (chrome, focus, docking, drag)',\n);\n\n/**\n * Internal bookkeeping the systems keep on window entities - which dock mode\n * has actually been applied to engine components, and whether chrome wiring\n * has run for the current PanelDocument.\n */\nexport const UIWindowState = createComponent(\n 'UIWindowState',\n {\n appliedDockMode: { type: Types.String, default: '' },\n chromeWired: { type: Types.Boolean, default: false },\n /** \"Home\" snapshot captured on adoption - the DOCK button returns here. */\n homeDockMode: { type: Types.String, default: '' },\n homeRegion: { type: Types.String, default: '' },\n homePosition: { type: Types.Vec3, default: [0, 0, 0] },\n homeYaw: { type: Types.Float32, default: 0 },\n },\n 'Internal UI Extensions window bookkeeping',\n);\n\n/**\n * A named layout region that docked windows snap to and are laid out within.\n * Place the entity where the region should live (it can itself carry a\n * `Follower` to make a body-locked region).\n */\nexport const UIDockRegion = createComponent(\n 'UIDockRegion',\n {\n regionId: { type: Types.String, default: '' },\n flow: { type: Types.Enum, enum: RegionFlowType, default: RegionFlowType.Column },\n /** Distance between slot origins (meters). */\n pitch: { type: Types.Float32, default: 0.35 },\n /** Columns per row (grid flow only). */\n columns: { type: Types.Float32, default: 2 },\n /** Max docked windows (0 = unlimited). */\n capacity: { type: Types.Float32, default: 0 },\n /** Drop-capture radius (meters). */\n snapRadius: { type: Types.Float32, default: 0.5 },\n },\n 'UI Extensions layout region for docking windows',\n);\n\n/** Present on a window entity while it is docked into a region. */\nexport const UIDockedTo = createComponent(\n 'UIDockedTo',\n {\n regionId: { type: Types.String, default: '' },\n },\n 'Marks a UI Extensions window as docked into a region',\n);\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience factories - one call to spawn a managed window or dock region.
|
|
3
|
+
* Thin sugar over `createTransformEntity().addComponent(...)`; everything
|
|
4
|
+
* they do can be done manually with the components.
|
|
5
|
+
*/
|
|
6
|
+
import { type Entity, type World } from '@iwsdk/core';
|
|
7
|
+
import { RegionFlowType } from './components.js';
|
|
8
|
+
import { type WindowOptionsBase } from '@realitycollective/webxr-uiextensions';
|
|
9
|
+
/**
|
|
10
|
+
* Options for {@link createUIWindow}.
|
|
11
|
+
*
|
|
12
|
+
* Everything but `config` comes from the portable {@link WindowOptionsBase},
|
|
13
|
+
* so the same option names mean the same thing on every adapter. `maxWidth`
|
|
14
|
+
* and `maxHeight` route to `UIWindow.targetWidth/Height` here, because IWSDK
|
|
15
|
+
* 0.5 removed those fields from `PanelUI`; omit them to keep the markup's
|
|
16
|
+
* intrinsic size and scale through the entity transform.
|
|
17
|
+
*/
|
|
18
|
+
export interface CreateWindowOptions extends WindowOptionsBase {
|
|
19
|
+
/**
|
|
20
|
+
* URL of the UIKitML source (e.g. "/ui/my-window.uikitml"). IWSDK 0.5 parses
|
|
21
|
+
* UIKitML at runtime - the build-time plugin and its generated JSON are gone.
|
|
22
|
+
*/
|
|
23
|
+
config: string;
|
|
24
|
+
/** Keep the window yawed toward the viewer while it is being dragged. */
|
|
25
|
+
billboardWhileDragging?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function createUIWindow(world: World, options: CreateWindowOptions): Entity;
|
|
28
|
+
export interface CreateDockRegionOptions {
|
|
29
|
+
id: string;
|
|
30
|
+
flow?: (typeof RegionFlowType)[keyof typeof RegionFlowType];
|
|
31
|
+
pitch?: number;
|
|
32
|
+
columns?: number;
|
|
33
|
+
capacity?: number;
|
|
34
|
+
snapRadius?: number;
|
|
35
|
+
/** World position of the region origin. */
|
|
36
|
+
position?: [number, number, number];
|
|
37
|
+
/**
|
|
38
|
+
* Body-lock the region itself: it follows the player's head at
|
|
39
|
+
* `followOffset`, and every window docked into it comes along.
|
|
40
|
+
*/
|
|
41
|
+
follow?: boolean;
|
|
42
|
+
followOffset?: [number, number, number];
|
|
43
|
+
}
|
|
44
|
+
export declare function createDockRegion(world: World, options: CreateDockRegionOptions): Entity;
|
package/dist/factory.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience factories - one call to spawn a managed window or dock region.
|
|
3
|
+
* Thin sugar over `createTransformEntity().addComponent(...)`; everything
|
|
4
|
+
* they do can be done manually with the components.
|
|
5
|
+
*/
|
|
6
|
+
import { Follower, FollowBehavior, PanelUI, PokeInteractable, RayInteractable, } from '@iwsdk/core';
|
|
7
|
+
import { UIDockRegion, UIDockedTo, UIWindow, RegionFlowType } from './components.js';
|
|
8
|
+
import { DockMode, } from '@realitycollective/webxr-uiextensions';
|
|
9
|
+
export function createUIWindow(world, options) {
|
|
10
|
+
const entity = world
|
|
11
|
+
.createTransformEntity()
|
|
12
|
+
.addComponent(PanelUI, {
|
|
13
|
+
config: options.config,
|
|
14
|
+
})
|
|
15
|
+
.addComponent(UIWindow, {
|
|
16
|
+
// Applied by UIWindowSystem once the document loads - see components.ts.
|
|
17
|
+
targetWidth: options.maxWidth ?? 0,
|
|
18
|
+
targetHeight: options.maxHeight ?? 0,
|
|
19
|
+
windowId: options.id ?? '',
|
|
20
|
+
title: options.title ?? '',
|
|
21
|
+
dockMode: options.dockMode ?? DockMode.WorldLocked,
|
|
22
|
+
movable: options.movable ?? true,
|
|
23
|
+
closable: options.closable ?? true,
|
|
24
|
+
minimizable: options.minimizable ?? true,
|
|
25
|
+
pinnable: options.pinnable ?? true,
|
|
26
|
+
billboardWhileDragging: options.billboardWhileDragging ?? true,
|
|
27
|
+
followOffset: options.followOffset ?? [0, -0.15, -1.2],
|
|
28
|
+
followSpeed: options.followSpeed ?? 3,
|
|
29
|
+
followTolerance: options.followTolerance ?? 0.35,
|
|
30
|
+
})
|
|
31
|
+
.addComponent(RayInteractable)
|
|
32
|
+
.addComponent(PokeInteractable);
|
|
33
|
+
if (options.position) {
|
|
34
|
+
entity.object3D?.position.set(...options.position);
|
|
35
|
+
}
|
|
36
|
+
if (options.region) {
|
|
37
|
+
entity.addComponent(UIDockedTo, { regionId: options.region });
|
|
38
|
+
}
|
|
39
|
+
return entity;
|
|
40
|
+
}
|
|
41
|
+
export function createDockRegion(world, options) {
|
|
42
|
+
const entity = world.createTransformEntity().addComponent(UIDockRegion, {
|
|
43
|
+
regionId: options.id,
|
|
44
|
+
flow: options.flow ?? RegionFlowType.Column,
|
|
45
|
+
pitch: options.pitch ?? 0.35,
|
|
46
|
+
columns: options.columns ?? 2,
|
|
47
|
+
capacity: options.capacity ?? 0,
|
|
48
|
+
snapRadius: options.snapRadius ?? 0.5,
|
|
49
|
+
});
|
|
50
|
+
if (options.position) {
|
|
51
|
+
entity.object3D?.position.set(...options.position);
|
|
52
|
+
}
|
|
53
|
+
if (options.follow) {
|
|
54
|
+
entity.addComponent(Follower, {
|
|
55
|
+
// Camera, not player.head - the head rig is origin-locked outside XR.
|
|
56
|
+
target: world.camera,
|
|
57
|
+
offsetPosition: options.followOffset ?? [0, -0.2, -1.4],
|
|
58
|
+
behavior: FollowBehavior.PivotY,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return entity;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Convenience factories - one call to spawn a managed window or dock region.\n * Thin sugar over `createTransformEntity().addComponent(...)`; everything\n * they do can be done manually with the components.\n */\nimport {\n Follower,\n FollowBehavior,\n PanelUI,\n PokeInteractable,\n RayInteractable,\n type Entity,\n type World,\n} from '@iwsdk/core';\nimport { UIDockRegion, UIDockedTo, UIWindow, RegionFlowType } from './components.js';\nimport {\n DockMode,\n type WindowOptionsBase,\n} from '@realitycollective/webxr-uiextensions';\n\n/**\n * Options for {@link createUIWindow}.\n *\n * Everything but `config` comes from the portable {@link WindowOptionsBase},\n * so the same option names mean the same thing on every adapter. `maxWidth`\n * and `maxHeight` route to `UIWindow.targetWidth/Height` here, because IWSDK\n * 0.5 removed those fields from `PanelUI`; omit them to keep the markup's\n * intrinsic size and scale through the entity transform.\n */\nexport interface CreateWindowOptions extends WindowOptionsBase {\n /**\n * URL of the UIKitML source (e.g. \"/ui/my-window.uikitml\"). IWSDK 0.5 parses\n * UIKitML at runtime - the build-time plugin and its generated JSON are gone.\n */\n config: string;\n /** Keep the window yawed toward the viewer while it is being dragged. */\n billboardWhileDragging?: boolean;\n}\n\nexport function createUIWindow(world: World, options: CreateWindowOptions): Entity {\n const entity = world\n .createTransformEntity()\n .addComponent(PanelUI, {\n config: options.config,\n })\n .addComponent(UIWindow, {\n // Applied by UIWindowSystem once the document loads - see components.ts.\n targetWidth: options.maxWidth ?? 0,\n targetHeight: options.maxHeight ?? 0,\n windowId: options.id ?? '',\n title: options.title ?? '',\n dockMode: options.dockMode ?? DockMode.WorldLocked,\n movable: options.movable ?? true,\n closable: options.closable ?? true,\n minimizable: options.minimizable ?? true,\n pinnable: options.pinnable ?? true,\n billboardWhileDragging: options.billboardWhileDragging ?? true,\n followOffset: options.followOffset ?? [0, -0.15, -1.2],\n followSpeed: options.followSpeed ?? 3,\n followTolerance: options.followTolerance ?? 0.35,\n })\n .addComponent(RayInteractable)\n .addComponent(PokeInteractable);\n\n if (options.position) {\n entity.object3D?.position.set(...options.position);\n }\n if (options.region) {\n entity.addComponent(UIDockedTo, { regionId: options.region });\n }\n return entity;\n}\n\nexport interface CreateDockRegionOptions {\n id: string;\n flow?: (typeof RegionFlowType)[keyof typeof RegionFlowType];\n pitch?: number;\n columns?: number;\n capacity?: number;\n snapRadius?: number;\n /** World position of the region origin. */\n position?: [number, number, number];\n /**\n * Body-lock the region itself: it follows the player's head at\n * `followOffset`, and every window docked into it comes along.\n */\n follow?: boolean;\n followOffset?: [number, number, number];\n}\n\nexport function createDockRegion(world: World, options: CreateDockRegionOptions): Entity {\n const entity = world.createTransformEntity().addComponent(UIDockRegion, {\n regionId: options.id,\n flow: options.flow ?? RegionFlowType.Column,\n pitch: options.pitch ?? 0.35,\n columns: options.columns ?? 2,\n capacity: options.capacity ?? 0,\n snapRadius: options.snapRadius ?? 0.5,\n });\n if (options.position) {\n entity.object3D?.position.set(...options.position);\n }\n if (options.follow) {\n entity.addComponent(Follower, {\n // Camera, not player.head - the head rig is origin-locked outside XR.\n target: world.camera,\n offsetPosition: options.followOffset ?? [0, -0.2, -1.4],\n behavior: FollowBehavior.PivotY,\n });\n }\n return entity;\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @realitycollective/iwsdk-uiextensions - the Meta IWSDK adapter.
|
|
3
|
+
*
|
|
4
|
+
* The engine-free UX core (window manager, dock state, region math, drag
|
|
5
|
+
* math, control models, markup upgraders, adapter interfaces) lives in
|
|
6
|
+
* `@realitycollective/webxr-uiextensions` and is re-exported here in full,
|
|
7
|
+
* so this package remains a drop-in single dependency for IWSDK apps.
|
|
8
|
+
*
|
|
9
|
+
* What this package adds is the IWSDK binding: ECS components + systems
|
|
10
|
+
* that apply the core onto `@iwsdk/core` entities, plus the one-call
|
|
11
|
+
* factories and `registerUIExtensions`.
|
|
12
|
+
*/
|
|
13
|
+
export * from '@realitycollective/webxr-uiextensions';
|
|
14
|
+
export * from './components.js';
|
|
15
|
+
export * from './manager-registry.js';
|
|
16
|
+
export * from './region-registry-store.js';
|
|
17
|
+
export * from './component-set.js';
|
|
18
|
+
export * from './factory.js';
|
|
19
|
+
export * from './scene-host.js';
|
|
20
|
+
export * from './register.js';
|
|
21
|
+
export * from './systems/window-system.js';
|
|
22
|
+
export * from './systems/dock-system.js';
|
|
23
|
+
export * from './systems/drag-system.js';
|
|
24
|
+
export * from './systems/dock-region-system.js';
|
|
25
|
+
export * from './systems/controls-system.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @realitycollective/iwsdk-uiextensions - the Meta IWSDK adapter.
|
|
3
|
+
*
|
|
4
|
+
* The engine-free UX core (window manager, dock state, region math, drag
|
|
5
|
+
* math, control models, markup upgraders, adapter interfaces) lives in
|
|
6
|
+
* `@realitycollective/webxr-uiextensions` and is re-exported here in full,
|
|
7
|
+
* so this package remains a drop-in single dependency for IWSDK apps.
|
|
8
|
+
*
|
|
9
|
+
* What this package adds is the IWSDK binding: ECS components + systems
|
|
10
|
+
* that apply the core onto `@iwsdk/core` entities, plus the one-call
|
|
11
|
+
* factories and `registerUIExtensions`.
|
|
12
|
+
*/
|
|
13
|
+
// The portable core - re-exported for a single-dependency experience.
|
|
14
|
+
export * from '@realitycollective/webxr-uiextensions';
|
|
15
|
+
// IWSDK ECS binding
|
|
16
|
+
export * from './components.js';
|
|
17
|
+
export * from './manager-registry.js';
|
|
18
|
+
export * from './region-registry-store.js';
|
|
19
|
+
export * from './component-set.js';
|
|
20
|
+
export * from './factory.js';
|
|
21
|
+
export * from './scene-host.js';
|
|
22
|
+
export * from './register.js';
|
|
23
|
+
export * from './systems/window-system.js';
|
|
24
|
+
export * from './systems/dock-system.js';
|
|
25
|
+
export * from './systems/drag-system.js';
|
|
26
|
+
export * from './systems/dock-region-system.js';
|
|
27
|
+
export * from './systems/controls-system.js';
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,sEAAsE;AACtE,cAAc,uCAAuC,CAAC;AAEtD,oBAAoB;AACpB,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC","sourcesContent":["/**\n * @realitycollective/iwsdk-uiextensions - the Meta IWSDK adapter.\n *\n * The engine-free UX core (window manager, dock state, region math, drag\n * math, control models, markup upgraders, adapter interfaces) lives in\n * `@realitycollective/webxr-uiextensions` and is re-exported here in full,\n * so this package remains a drop-in single dependency for IWSDK apps.\n *\n * What this package adds is the IWSDK binding: ECS components + systems\n * that apply the core onto `@iwsdk/core` entities, plus the one-call\n * factories and `registerUIExtensions`.\n */\n// The portable core - re-exported for a single-dependency experience.\nexport * from '@realitycollective/webxr-uiextensions';\n\n// IWSDK ECS binding\nexport * from './components.js';\nexport * from './manager-registry.js';\nexport * from './region-registry-store.js';\nexport * from './component-set.js';\nexport * from './factory.js';\nexport * from './scene-host.js';\nexport * from './register.js';\nexport * from './systems/window-system.js';\nexport * from './systems/dock-system.js';\nexport * from './systems/drag-system.js';\nexport * from './systems/dock-region-system.js';\nexport * from './systems/controls-system.js';\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One `WindowManager` per IWSDK `World`, lazily created. App code and the
|
|
3
|
+
* systems in this package resolve the same instance through this registry,
|
|
4
|
+
* so window state has a single home without a global singleton.
|
|
5
|
+
*/
|
|
6
|
+
import type { World } from '@iwsdk/core';
|
|
7
|
+
import { WindowManager } from '@realitycollective/webxr-uiextensions';
|
|
8
|
+
export declare function windowManagerFor(world: World): WindowManager;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { WindowManager } from '@realitycollective/webxr-uiextensions';
|
|
2
|
+
const managers = new WeakMap();
|
|
3
|
+
export function windowManagerFor(world) {
|
|
4
|
+
let manager = managers.get(world);
|
|
5
|
+
if (!manager) {
|
|
6
|
+
manager = new WindowManager();
|
|
7
|
+
managers.set(world, manager);
|
|
8
|
+
}
|
|
9
|
+
return manager;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=manager-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager-registry.js","sourceRoot":"","sources":["../src/manager-registry.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAEtE,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAwB,CAAC;AAErD,MAAM,UAAU,gBAAgB,CAAC,KAAY;IAC3C,IAAI,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,aAAa,EAAE,CAAC;QAC9B,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["/**\n * One `WindowManager` per IWSDK `World`, lazily created. App code and the\n * systems in this package resolve the same instance through this registry,\n * so window state has a single home without a global singleton.\n */\nimport type { World } from '@iwsdk/core';\nimport { WindowManager } from '@realitycollective/webxr-uiextensions';\n\nconst managers = new WeakMap<World, WindowManager>();\n\nexport function windowManagerFor(world: World): WindowManager {\n let manager = managers.get(world);\n if (!manager) {\n manager = new WindowManager();\n managers.set(world, manager);\n }\n return manager;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One `RegionRegistry` per IWSDK `World` (same pattern as the window
|
|
3
|
+
* manager) so the drag and region systems share region state.
|
|
4
|
+
*/
|
|
5
|
+
import type { World } from '@iwsdk/core';
|
|
6
|
+
import { RegionRegistry } from '@realitycollective/webxr-uiextensions';
|
|
7
|
+
export declare function regionRegistryFor(world: World): RegionRegistry;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RegionRegistry } from '@realitycollective/webxr-uiextensions';
|
|
2
|
+
const registries = new WeakMap();
|
|
3
|
+
export function regionRegistryFor(world) {
|
|
4
|
+
let registry = registries.get(world);
|
|
5
|
+
if (!registry) {
|
|
6
|
+
registry = new RegionRegistry();
|
|
7
|
+
registries.set(world, registry);
|
|
8
|
+
}
|
|
9
|
+
return registry;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=region-registry-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region-registry-store.js","sourceRoot":"","sources":["../src/region-registry-store.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,MAAM,UAAU,GAAG,IAAI,OAAO,EAAyB,CAAC;AAExD,MAAM,UAAU,iBAAiB,CAAC,KAAY;IAC5C,IAAI,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QAChC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\n * One `RegionRegistry` per IWSDK `World` (same pattern as the window\n * manager) so the drag and region systems share region state.\n */\nimport type { World } from '@iwsdk/core';\nimport { RegionRegistry } from '@realitycollective/webxr-uiextensions';\n\nconst registries = new WeakMap<World, RegionRegistry>();\n\nexport function regionRegistryFor(world: World): RegionRegistry {\n let registry = registries.get(world);\n if (!registry) {\n registry = new RegionRegistry();\n registries.set(world, registry);\n }\n return registry;\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-call setup: register every UI Extensions system on a world.
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* const world = await World.create(container, { features: { spatialUI: true } });
|
|
6
|
+
* registerUIExtensions(world);
|
|
7
|
+
* ```
|
|
8
|
+
*/
|
|
9
|
+
import type { World } from '@iwsdk/core';
|
|
10
|
+
import type { WindowManager } from '@realitycollective/webxr-uiextensions';
|
|
11
|
+
export interface RegisterOptions {
|
|
12
|
+
/** Disable the title-bar drag system. */
|
|
13
|
+
drag?: boolean;
|
|
14
|
+
/** Disable dock regions. */
|
|
15
|
+
regions?: boolean;
|
|
16
|
+
/** Disable the `data-uix` control upgrades. */
|
|
17
|
+
controls?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function registerUIExtensions(world: World, options?: RegisterOptions): WindowManager;
|
package/dist/register.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { UIWindowSystem } from './systems/window-system.js';
|
|
2
|
+
import { UIDockSystem } from './systems/dock-system.js';
|
|
3
|
+
import { UIDragSystem } from './systems/drag-system.js';
|
|
4
|
+
import { UIDockRegionSystem } from './systems/dock-region-system.js';
|
|
5
|
+
import { UIControlsSystem } from './systems/controls-system.js';
|
|
6
|
+
import { windowManagerFor } from './manager-registry.js';
|
|
7
|
+
export function registerUIExtensions(world, options = {}) {
|
|
8
|
+
world.registerSystem(UIWindowSystem).registerSystem(UIDockSystem);
|
|
9
|
+
if (options.drag !== false) {
|
|
10
|
+
world.registerSystem(UIDragSystem);
|
|
11
|
+
}
|
|
12
|
+
if (options.regions !== false) {
|
|
13
|
+
world.registerSystem(UIDockRegionSystem);
|
|
14
|
+
}
|
|
15
|
+
if (options.controls !== false) {
|
|
16
|
+
world.registerSystem(UIControlsSystem);
|
|
17
|
+
}
|
|
18
|
+
return windowManagerFor(world);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAYzD,MAAM,UAAU,oBAAoB,CAClC,KAAY,EACZ,UAA2B,EAAE;IAE7B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IAClE,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAC9B,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QAC/B,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC","sourcesContent":["/**\n * One-call setup: register every UI Extensions system on a world.\n *\n * ```ts\n * const world = await World.create(container, { features: { spatialUI: true } });\n * registerUIExtensions(world);\n * ```\n */\nimport type { World } from '@iwsdk/core';\nimport { UIWindowSystem } from './systems/window-system.js';\nimport { UIDockSystem } from './systems/dock-system.js';\nimport { UIDragSystem } from './systems/drag-system.js';\nimport { UIDockRegionSystem } from './systems/dock-region-system.js';\nimport { UIControlsSystem } from './systems/controls-system.js';\nimport { windowManagerFor } from './manager-registry.js';\nimport type { WindowManager } from '@realitycollective/webxr-uiextensions';\n\nexport interface RegisterOptions {\n /** Disable the title-bar drag system. */\n drag?: boolean;\n /** Disable dock regions. */\n regions?: boolean;\n /** Disable the `data-uix` control upgrades. */\n controls?: boolean;\n}\n\nexport function registerUIExtensions(\n world: World,\n options: RegisterOptions = {},\n): WindowManager {\n world.registerSystem(UIWindowSystem).registerSystem(UIDockSystem);\n if (options.drag !== false) {\n world.registerSystem(UIDragSystem);\n }\n if (options.regions !== false) {\n world.registerSystem(UIDockRegionSystem);\n }\n if (options.controls !== false) {\n world.registerSystem(UIControlsSystem);\n }\n return windowManagerFor(world);\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IWSDK implementation of the core's `WindowHost` + `SceneTarget`.
|
|
3
|
+
*
|
|
4
|
+
* This is what makes a portable `SceneDescriptor` build the SAME playground
|
|
5
|
+
* on IWSDK as on plain three.js, and lets app behaviour be wired through
|
|
6
|
+
* `onPanelReady` instead of hand-written ECS queries:
|
|
7
|
+
*
|
|
8
|
+
* const host = createSceneHost(world);
|
|
9
|
+
* applyScene(host, PLAYGROUND);
|
|
10
|
+
* host.onPanelReady(({ id, panel }) => wireMyPanel(id, panel));
|
|
11
|
+
*
|
|
12
|
+
* Readiness is detected with a single ECS query on `PanelUI + PanelDocument`
|
|
13
|
+
* - the engine-specific mechanism stays here, behind the portable interface.
|
|
14
|
+
* Bare panels (a `PanelUI` entity with no `UIWindow`) are announced too, with
|
|
15
|
+
* `kind: 'panel'` and their config path as the id, so devtools and hand-built
|
|
16
|
+
* entities show up in the same stream as managed windows.
|
|
17
|
+
*/
|
|
18
|
+
import { type Entity, type World } from '@iwsdk/core';
|
|
19
|
+
import { type PanelHandle, type SceneTarget, type WindowHandle, type WindowHost } from '@realitycollective/webxr-uiextensions';
|
|
20
|
+
import { type CreateWindowOptions } from './factory.js';
|
|
21
|
+
/**
|
|
22
|
+
* The live panel on an entity, or `undefined` while IWSDK is still loading
|
|
23
|
+
* its document. Use it to reach a panel from an entity you already hold;
|
|
24
|
+
* `onPanelReady` stays the way to be TOLD when one appears.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getPanelHandle(entity: Entity): PanelHandle | undefined;
|
|
27
|
+
/** A window spawned by {@link IwsdkSceneHost.createWindow}. */
|
|
28
|
+
export interface IwsdkWindowHandle extends WindowHandle {
|
|
29
|
+
/** The ECS entity carrying `PanelUI`, `UIWindow` and the interaction tags. */
|
|
30
|
+
readonly entity: Entity;
|
|
31
|
+
}
|
|
32
|
+
export interface IwsdkSceneHost extends WindowHost, SceneTarget {
|
|
33
|
+
readonly world: World;
|
|
34
|
+
/**
|
|
35
|
+
* Spawn a managed window and get a handle back straight away. IWSDK loads
|
|
36
|
+
* the markup over later frames, so `handle.panel` is `undefined` at first
|
|
37
|
+
* and `handle.onReady` is how you wait for it without an ECS query.
|
|
38
|
+
*/
|
|
39
|
+
createWindow(options: CreateWindowOptions): IwsdkWindowHandle;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create the host for a world. Call AFTER `registerUIExtensions(world)`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createSceneHost(world: World): IwsdkSceneHost;
|