@tomorrowevening/hermes 0.0.36 → 0.0.37

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.
Files changed (69) hide show
  1. package/dist/hermes.cjs.js +16 -16
  2. package/dist/hermes.esm.js +1446 -1498
  3. package/dist/hermes.umd.js +16 -16
  4. package/dist/style.css +1 -1
  5. package/package.json +2 -1
  6. package/src/core/Application.ts +111 -0
  7. package/src/core/RemoteController.ts +60 -0
  8. package/src/core/remote/BaseRemote.ts +16 -0
  9. package/src/core/remote/RemoteComponents.ts +45 -0
  10. package/src/core/remote/RemoteTheatre.ts +300 -0
  11. package/src/core/remote/RemoteThree.ts +143 -0
  12. package/src/core/remote/RemoteTweakpane.ts +194 -0
  13. package/src/core/types.ts +56 -0
  14. package/src/editor/Editor.tsx +20 -0
  15. package/src/editor/components/Draggable.tsx +40 -0
  16. package/src/editor/components/DraggableItem.tsx +22 -0
  17. package/src/editor/components/Dropdown.tsx +38 -0
  18. package/src/editor/components/DropdownItem.tsx +64 -0
  19. package/src/editor/components/NavButton.tsx +11 -0
  20. package/src/editor/components/content.ts +2 -0
  21. package/src/editor/components/icons/CloseIcon.tsx +7 -0
  22. package/src/editor/components/icons/DragIcon.tsx +9 -0
  23. package/src/editor/components/types.ts +41 -0
  24. package/src/editor/global.ts +20 -0
  25. package/src/editor/multiView/CameraWindow.tsx +74 -0
  26. package/src/editor/multiView/InfiniteGridHelper.ts +24 -0
  27. package/src/editor/multiView/InfiniteGridMaterial.ts +127 -0
  28. package/src/editor/multiView/MultiView.scss +101 -0
  29. package/src/editor/multiView/MultiView.tsx +636 -0
  30. package/src/editor/multiView/MultiViewData.ts +59 -0
  31. package/src/editor/multiView/UVMaterial.ts +55 -0
  32. package/src/editor/scss/_debug.scss +58 -0
  33. package/src/editor/scss/_draggable.scss +43 -0
  34. package/src/editor/scss/_dropdown.scss +84 -0
  35. package/src/editor/scss/_sidePanel.scss +278 -0
  36. package/src/editor/scss/_theme.scss +9 -0
  37. package/src/editor/scss/index.scss +67 -0
  38. package/src/editor/sidePanel/Accordion.tsx +41 -0
  39. package/src/editor/sidePanel/ChildObject.tsx +57 -0
  40. package/src/editor/sidePanel/ContainerObject.tsx +11 -0
  41. package/src/editor/sidePanel/SidePanel.tsx +64 -0
  42. package/src/editor/sidePanel/ToggleBtn.tsx +27 -0
  43. package/src/editor/sidePanel/inspector/Inspector.tsx +119 -0
  44. package/src/editor/sidePanel/inspector/InspectorField.tsx +198 -0
  45. package/src/editor/sidePanel/inspector/InspectorGroup.tsx +50 -0
  46. package/src/editor/sidePanel/inspector/SceneInspector.tsx +84 -0
  47. package/src/editor/sidePanel/inspector/inspector.scss +161 -0
  48. package/src/editor/sidePanel/inspector/utils/InspectAnimation.tsx +102 -0
  49. package/src/editor/sidePanel/inspector/utils/InspectCamera.tsx +75 -0
  50. package/src/editor/sidePanel/inspector/utils/InspectLight.tsx +62 -0
  51. package/src/editor/sidePanel/inspector/utils/InspectMaterial.tsx +710 -0
  52. package/src/editor/sidePanel/inspector/utils/InspectTransform.tsx +113 -0
  53. package/src/editor/sidePanel/types.ts +130 -0
  54. package/src/editor/sidePanel/utils.ts +278 -0
  55. package/src/editor/utils.ts +117 -0
  56. package/src/example/CustomEditor.tsx +78 -0
  57. package/src/example/components/App.css +6 -0
  58. package/src/example/components/App.tsx +246 -0
  59. package/src/example/constants.ts +52 -0
  60. package/src/example/index.scss +45 -0
  61. package/src/example/main.tsx +37 -0
  62. package/src/example/three/BaseScene.ts +42 -0
  63. package/src/example/three/CustomMaterial.ts +72 -0
  64. package/src/example/three/FBXAnimation.ts +26 -0
  65. package/src/example/three/Scene1.ts +225 -0
  66. package/src/example/three/Scene2.ts +138 -0
  67. package/src/example/three/loader.ts +110 -0
  68. package/src/index.ts +27 -0
  69. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,300 @@
1
+ // Libs
2
+ import { createRafDriver, getProject } from '@theatre/core';
3
+ import { IProject, IProjectConfig, IRafDriver, ISheet, ISheetObject } from '@theatre/core';
4
+ import studio from '@theatre/studio';
5
+ // Core
6
+ import Application from '../Application';
7
+ import BaseRemote from './BaseRemote';
8
+ import { isColor } from '@/editor/utils';
9
+ import { BroadcastData, DataUpdateCallback, EditorEvent, VoidCallback, noop } from '../types';
10
+
11
+ export default class RemoteTheatre extends BaseRemote {
12
+ project: IProject | undefined;
13
+ sheets: Map<string, ISheet> = new Map();
14
+ sheetObjects: Map<string, ISheetObject> = new Map();
15
+ sheetObjectCBs: Map<string, DataUpdateCallback> = new Map();
16
+ sheetObjectUnsubscribe: Map<string, VoidCallback> = new Map();
17
+
18
+ private static rafDriver: IRafDriver | null = null;
19
+
20
+ init(projectName: string, projectConfig?: IProjectConfig | undefined): Promise<void> {
21
+ this.project = getProject(projectName, projectConfig);
22
+ return this.project.ready;
23
+ }
24
+
25
+ override dispose(): void {
26
+ this.project = undefined;
27
+ this.sheets = new Map();
28
+ this.sheetObjects = new Map();
29
+ this.sheetObjectCBs = new Map();
30
+ this.sheetObjectUnsubscribe = new Map();
31
+ }
32
+
33
+ sheet(name: string): ISheet | undefined {
34
+ if (this.project === undefined) {
35
+ console.error('Theatre Project hasn\'t been created yet.');
36
+ return undefined;
37
+ }
38
+
39
+ let sheet = this.sheets.get(name);
40
+ if (sheet !== undefined) return sheet;
41
+
42
+ sheet = this.project?.sheet(name);
43
+ this.sheets.set(name, sheet);
44
+ return sheet;
45
+ }
46
+
47
+ playSheet(name: string, params?: any) {
48
+ this.sheet(name)?.sequence.play(params);
49
+
50
+ this.app.send({
51
+ event: 'playSheet',
52
+ target: 'editor',
53
+ data: {
54
+ sheet: name,
55
+ value: params,
56
+ },
57
+ });
58
+ }
59
+
60
+ pauseSheet(name: string) {
61
+ this.sheet(name)?.sequence.pause();
62
+
63
+ this.app.send({
64
+ event: 'pauseSheet',
65
+ target: 'editor',
66
+ data: {
67
+ sheet: name,
68
+ },
69
+ });
70
+ }
71
+
72
+ clearSheetObjects(sheetName: string) {
73
+ this.sheetObjects.forEach((value: ISheetObject, key: string) => {
74
+ const sameSheet = key.search(`${sheetName}_`) > -1;
75
+ if (sameSheet) this.unsubscribe(value);
76
+ });
77
+ }
78
+
79
+ sheetObject(
80
+ sheetName: string,
81
+ key: string,
82
+ props: any,
83
+ onUpdate?: DataUpdateCallback,
84
+ ): ISheetObject | undefined {
85
+ if (this.project === undefined) {
86
+ console.error('Theatre Project hasn\'t been created yet.');
87
+ return undefined;
88
+ }
89
+ const sheet = this.sheet(sheetName);
90
+ if (sheet === undefined) return undefined;
91
+
92
+ const objName = `${sheetName}_${key}`;
93
+ let obj = this.sheetObjects.get(objName);
94
+ if (obj !== undefined) {
95
+ obj = sheet.object(key, {...props, ...obj.value}, {reconfigure: true});
96
+ } else {
97
+ obj = sheet.object(key, props);
98
+ }
99
+
100
+ this.sheetObjects.set(objName, obj);
101
+ this.sheetObjectCBs.set(objName, onUpdate !== undefined ? onUpdate : noop);
102
+
103
+ const unsubscribe = obj.onValuesChange((values: any) => {
104
+ if (this.app.editor) {
105
+ for (const i in values) {
106
+ const value = values[i];
107
+ if (typeof value === 'object') {
108
+ if (isColor(value)) {
109
+ values[i] = {
110
+ r: value.r,
111
+ g: value.g,
112
+ b: value.b,
113
+ a: value.a,
114
+ };
115
+ }
116
+ }
117
+ }
118
+ this.app.send({
119
+ event: 'updateSheetObject',
120
+ target: 'app',
121
+ data: {
122
+ sheet: sheetName,
123
+ sheetObject: objName,
124
+ values: values,
125
+ },
126
+ });
127
+ }
128
+
129
+ const callback = this.sheetObjectCBs.get(objName);
130
+ if (callback !== undefined) callback(values);
131
+ });
132
+ this.sheetObjectUnsubscribe.set(objName, unsubscribe);
133
+
134
+ return obj;
135
+ }
136
+
137
+ unsubscribe(sheetObject: ISheetObject) {
138
+ if (this.project === undefined) {
139
+ console.error('Theatre Project hasn\'t been created yet.');
140
+ return undefined;
141
+ }
142
+
143
+ const sheetName = sheetObject.address.sheetId;
144
+ const sheetObjectName = sheetObject.address.objectKey;
145
+ const sheet = this.sheets.get(sheetName);
146
+ sheet?.detachObject(sheetObjectName);
147
+
148
+ const id = `${sheetName}_${sheetObjectName}`;
149
+ const unsubscribe = this.sheetObjectUnsubscribe.get(id);
150
+ if (unsubscribe !== undefined) {
151
+ this.sheetObjects.delete(id);
152
+ this.sheetObjectCBs.delete(id);
153
+ this.sheetObjectUnsubscribe.delete(id);
154
+ unsubscribe();
155
+ }
156
+ }
157
+
158
+ public static getRafDriver(): IRafDriver {
159
+ if (!RemoteTheatre.rafDriver) {
160
+ RemoteTheatre.rafDriver = createRafDriver();
161
+ }
162
+ return RemoteTheatre.rafDriver;
163
+ }
164
+ }
165
+
166
+ let activeSheet: ISheet | undefined;
167
+
168
+ export function HandleAppRemoteTheatre(app: Application, msg: BroadcastData) {
169
+ app.components.forEach((component: any) => {
170
+ if (component instanceof RemoteTheatre) {
171
+ let value = undefined;
172
+ const theatre = component as RemoteTheatre;
173
+ switch (msg.event) {
174
+ case 'setSheet':
175
+ // @ts-ignore
176
+ value = theatre.sheets.get(msg.data.sheet);
177
+ if (value !== undefined) {
178
+ activeSheet = value as ISheet;
179
+ studio.setSelection([value]);
180
+ }
181
+ break;
182
+ case 'setSheetObject':
183
+ // @ts-ignore
184
+ value = theatre.sheetObjects.get(`${msg.data.sheet}_${msg.data.key}`);
185
+ if (value !== undefined) {
186
+ studio.setSelection([value]);
187
+ }
188
+ break;
189
+ case 'updateSheetObject':
190
+ // @ts-ignore
191
+ value = theatre.sheets.get(msg.data.sheet); // pause current animation
192
+ // @ts-ignore
193
+ if (value !== undefined) value.sequence.pause();
194
+ // @ts-ignore
195
+ value = theatre.sheetObjectCBs.get(msg.data.sheetObject);
196
+ // @ts-ignore
197
+ if (value !== undefined) value(msg.data.values);
198
+ break;
199
+ case 'updateTimeline':
200
+ // @ts-ignore
201
+ value = theatre.sheets.get(msg.data.sheet);
202
+ if (activeSheet !== undefined) {
203
+ (activeSheet as ISheet).sequence.position = msg.data.position;
204
+ }
205
+ break;
206
+ }
207
+ }
208
+ });
209
+ }
210
+
211
+ export function UpdateRemoteTheatre(app: Application) {
212
+ if (app.editor) {
213
+ let theatre: RemoteTheatre;
214
+ app.components.forEach((component: any) => {
215
+ if (component instanceof RemoteTheatre) {
216
+ theatre = component;
217
+ }
218
+ });
219
+
220
+ studio.ui.restore();
221
+ studio.onSelectionChange((value: any[]) => {
222
+ if (value.length < 1) return;
223
+
224
+ value.forEach((obj: any) => {
225
+ let id = obj.address.sheetId;
226
+ let type: EditorEvent = 'setSheet';
227
+ let data = {};
228
+ switch (obj.type) {
229
+ case 'Theatre_Sheet_PublicAPI':
230
+ type = 'setSheet';
231
+ data = {
232
+ sheet: obj.address.sheetId,
233
+ };
234
+ activeSheet = theatre.sheets.get(obj.address.sheetId);
235
+ break;
236
+
237
+ case 'Theatre_SheetObject_PublicAPI':
238
+ type = 'setSheetObject';
239
+ id += `_${obj.address.objectKey}`;
240
+ data = {
241
+ id: id,
242
+ sheet: obj.address.sheetId,
243
+ key: obj.address.objectKey,
244
+ };
245
+ break;
246
+ }
247
+ app.send({ event: type, target: 'app', data: data });
248
+ });
249
+ });
250
+
251
+ // Timeline
252
+ let position = 0;
253
+ const onRafUpdate = () => {
254
+ // RemoteTheatre.getRafDriver().tick(performance.now());
255
+
256
+ if (
257
+ activeSheet !== undefined &&
258
+ position !== activeSheet.sequence.position
259
+ ) {
260
+ position = activeSheet.sequence.position;
261
+ const t = activeSheet as ISheet;
262
+ app.send({
263
+ event: 'updateTimeline',
264
+ target: 'app',
265
+ data: {
266
+ position: position,
267
+ sheet: t.address.sheetId,
268
+ },
269
+ });
270
+ }
271
+ };
272
+ const onRaf = () => {
273
+ onRafUpdate();
274
+ requestAnimationFrame(onRaf);
275
+ };
276
+ onRafUpdate(); // Initial position
277
+ onRaf();
278
+ } else {
279
+ studio.ui.hide();
280
+ }
281
+ }
282
+
283
+ export function HandleEditorRemoteTheatre(app: Application, msg: BroadcastData) {
284
+ if (app.editor) {
285
+ app.components.forEach((component: any) => {
286
+ if (component instanceof RemoteTheatre) {
287
+ const theatre = component;
288
+ switch (msg.event) {
289
+ case 'playSheet':
290
+ theatre.sheet(msg.data.sheet)?.sequence.play(msg.data.value);
291
+ break;
292
+ case 'pauseSheet':
293
+ theatre.sheet(msg.data.sheet)?.sequence.pause();
294
+ break;
295
+ }
296
+ return;
297
+ }
298
+ });
299
+ }
300
+ }
@@ -0,0 +1,143 @@
1
+ import { Camera, Scene } from 'three';
2
+ import BaseRemote from './BaseRemote';
3
+ import { stripObject, stripScene } from '@/editor/sidePanel/utils';
4
+ import { hierarchyUUID, resetThreeObjects } from '@/editor/utils';
5
+ import Application from '../Application';
6
+ import { BroadcastData } from '../types';
7
+ import { ToolEvents, debugDispatcher } from '@/editor/global';
8
+
9
+ export default class RemoteThree extends BaseRemote {
10
+ scene?: Scene = undefined;
11
+
12
+ getObject(uuid: string) {
13
+ if (!this.app.debugEnabled) return;
14
+ this.app.send({
15
+ event: 'getObject',
16
+ target: 'app',
17
+ data: uuid,
18
+ });
19
+ }
20
+
21
+ setObject(value: any) {
22
+ const stripped = stripObject(value);
23
+ this.app.send({
24
+ event: 'setObject',
25
+ target: 'editor',
26
+ data: stripped,
27
+ });
28
+ }
29
+
30
+ requestMethod(uuid: string, key: string, value?: any, subitem?: string) {
31
+ this.app.send({
32
+ event: 'requestMethod',
33
+ target: 'app',
34
+ data: {
35
+ uuid,
36
+ key,
37
+ value,
38
+ subitem,
39
+ },
40
+ });
41
+ }
42
+
43
+ updateObject(uuid: string, key: string, value: any) {
44
+ this.app.send({
45
+ event: 'updateObject',
46
+ target: 'app',
47
+ data: {
48
+ uuid,
49
+ key,
50
+ value
51
+ },
52
+ });
53
+ }
54
+
55
+ createTexture(uuid: string, key: string, value: any) {
56
+ this.app.send({
57
+ event: 'createTexture',
58
+ target: 'app',
59
+ data: {
60
+ uuid,
61
+ key,
62
+ value
63
+ },
64
+ });
65
+ }
66
+
67
+ setScene(value: Scene) {
68
+ if (value === undefined) return;
69
+ this.scene = value;
70
+
71
+ if (!this.app.debugEnabled) return;
72
+ resetThreeObjects();
73
+ hierarchyUUID(this.scene);
74
+ const stripped = stripScene(this.scene);
75
+ this.app.send({
76
+ event: 'setScene',
77
+ target: 'editor',
78
+ data: stripped,
79
+ });
80
+ }
81
+
82
+ addCamera(camera: Camera) {
83
+ if (!this.app.debugEnabled) return;
84
+ const stripped = stripObject(camera);
85
+ this.app.send({
86
+ event: 'addCamera',
87
+ target: 'editor',
88
+ data: stripped,
89
+ });
90
+ }
91
+
92
+ removeCamera(camera: Camera) {
93
+ if (!this.app.debugEnabled) return;
94
+ const stripped = stripObject(camera);
95
+ this.app.send({
96
+ event: 'removeCamera',
97
+ target: 'editor',
98
+ data: stripped,
99
+ });
100
+ }
101
+ }
102
+
103
+ export function HandleAppRemoteThree(_: Application, msg: BroadcastData) {
104
+ switch (msg.event) {
105
+ case 'getObject':
106
+ // @ts-ignore
107
+ debugDispatcher.dispatchEvent({ type: ToolEvents.GET_OBJECT, value: msg.data });
108
+ break;
109
+ case 'updateObject':
110
+ // @ts-ignore
111
+ debugDispatcher.dispatchEvent({ type: ToolEvents.UPDATE_OBJECT, value: msg.data });
112
+ break;
113
+ case 'createTexture':
114
+ // @ts-ignore
115
+ debugDispatcher.dispatchEvent({ type: ToolEvents.CREATE_TEXTURE, value: msg.data });
116
+ break;
117
+ case 'requestMethod':
118
+ // @ts-ignore
119
+ debugDispatcher.dispatchEvent({ type: ToolEvents.REQUEST_METHOD, value: msg.data });
120
+ break;
121
+ }
122
+ }
123
+
124
+ export function HandleEditorRemoteThree(_: Application, msg: BroadcastData) {
125
+ switch (msg.event) {
126
+ case 'setObject':
127
+ // @ts-ignore
128
+ debugDispatcher.dispatchEvent({ type: ToolEvents.SET_OBJECT, value: msg.data });
129
+ break;
130
+ case 'setScene':
131
+ // @ts-ignore
132
+ debugDispatcher.dispatchEvent({ type: ToolEvents.SET_SCENE, value: msg.data });
133
+ break;
134
+ case 'addCamera':
135
+ // @ts-ignore
136
+ debugDispatcher.dispatchEvent({ type: ToolEvents.ADD_CAMERA, value: msg.data });
137
+ break;
138
+ case 'removeCamera':
139
+ // @ts-ignore
140
+ debugDispatcher.dispatchEvent({ type: ToolEvents.REMOVE_CAMERA, value: msg.data });
141
+ break;
142
+ }
143
+ }
@@ -0,0 +1,194 @@
1
+ // Libs
2
+ import { Pane } from 'tweakpane';
3
+ import * as EssentialsPlugin from '@tweakpane/plugin-essentials';
4
+ // Core
5
+ import Application from '../Application';
6
+ import BaseRemote from './BaseRemote';
7
+ import { BroadcastData, DataUpdateCallback, VoidCallback, noop } from '../types';
8
+
9
+ export default class RemoteTweakpane extends BaseRemote {
10
+ bindCBs: Map<string, DataUpdateCallback>;
11
+ buttonCBs: Map<string, VoidCallback>;
12
+
13
+ protected pane?: Pane | undefined = undefined;
14
+ protected appCallbacks = 0;
15
+ protected editorCallbacks = 0;
16
+ protected inspectorFolder: any = undefined;
17
+
18
+ constructor(app: Application) {
19
+ super(app);
20
+ this.bindCBs = new Map();
21
+ this.buttonCBs = new Map();
22
+
23
+ if (app.editor) this.createGUI();
24
+ }
25
+
26
+ protected createGUI() {
27
+ this.pane = new Pane({ title: 'GUI' });
28
+ this.pane.registerPlugin(EssentialsPlugin);
29
+ }
30
+
31
+ override dispose(): void {
32
+ this.bindCBs.clear();
33
+ this.buttonCBs.clear();
34
+ this.appCallbacks = 0;
35
+ this.editorCallbacks = 0;
36
+
37
+ if (this.app.editor) {
38
+ this.pane?.dispose();
39
+ this.pane = undefined;
40
+ }
41
+ }
42
+
43
+ addFolder(name: string, params: any = undefined, parent: any = undefined) {
44
+ if (this.app.editor) {
45
+ if (this.pane === undefined) this.createGUI();
46
+
47
+ const container = parent !== undefined ? parent : this.pane;
48
+ return container.addFolder({
49
+ title: name,
50
+ ...params,
51
+ });
52
+ } else {
53
+ this.app.send({
54
+ event: 'addFolder',
55
+ target: 'app',
56
+ data: {
57
+ name,
58
+ params,
59
+ parent
60
+ }
61
+ });
62
+ }
63
+ }
64
+
65
+ get bindID(): string {
66
+ return `debug_${Math.max(this.appCallbacks, this.editorCallbacks)}`;
67
+ }
68
+
69
+ // Binding
70
+
71
+ bind(obj: any, name: string, params: any, parent: any = undefined) {
72
+ const bindID = this.bindID;
73
+ const callback = params.onChange !== undefined ? params.onChange : noop;
74
+ this.bindCBs.set(bindID, callback);
75
+
76
+ if (this.app.editor) {
77
+ if (this.pane === undefined) this.createGUI();
78
+
79
+ const container = parent !== undefined ? parent : this.pane;
80
+ container
81
+ .addBinding(obj, name, params)
82
+ .on('change', (evt: any) => {
83
+ this.app.send({
84
+ event: 'updateBind',
85
+ target: 'app',
86
+ data: {
87
+ id: bindID,
88
+ value: evt.value,
89
+ }
90
+ });
91
+ });
92
+ this.editorCallbacks++;
93
+ } else {
94
+ this.app.send({
95
+ event: 'bindObject',
96
+ target: 'app',
97
+ data: {
98
+ id: bindID,
99
+ name,
100
+ params,
101
+ parent
102
+ }
103
+ });
104
+ this.appCallbacks++;
105
+ }
106
+ }
107
+
108
+ triggerBind(id: string, data: any) {
109
+ const cb = this.bindCBs.get(id);
110
+ if (cb !== undefined) cb(data);
111
+ else console.warn(`No callback for: ${id}`, data);
112
+ }
113
+
114
+ // Buttons
115
+
116
+ button(name: string, callback: VoidCallback, parent: any = undefined) {
117
+ const bindID = this.bindID;
118
+ this.buttonCBs.set(bindID, callback);
119
+
120
+ if (this.app.editor) {
121
+ if (this.pane === undefined) this.createGUI();
122
+
123
+ const container = parent !== undefined ? parent : this.pane;
124
+ container
125
+ .addButton({ title: name })
126
+ .on('click', () => {
127
+ this.app.send({
128
+ event: 'clickButton',
129
+ target: 'app',
130
+ data: {
131
+ id: bindID,
132
+ }
133
+ });
134
+ });
135
+ this.editorCallbacks++;
136
+ } else {
137
+ this.app.send({
138
+ event: 'addButton',
139
+ target: 'app',
140
+ data: {
141
+ id: bindID,
142
+ name,
143
+ callback,
144
+ parent
145
+ }
146
+ });
147
+ this.appCallbacks++;
148
+ }
149
+ }
150
+
151
+ triggerButton(id: string) {
152
+ const cb = this.buttonCBs.get(id);
153
+ if (cb !== undefined) cb();
154
+ }
155
+
156
+ // Inspector
157
+
158
+ createInspector() {
159
+ this.inspectorFolder = this.addFolder('Inspector', this.pane);
160
+ }
161
+
162
+ clearInspector() {
163
+ const total = this.inspectorFolder.children.length - 1;
164
+ for (let i = total; i > -1; --i) {
165
+ this.inspectorFolder.remove(this.inspectorFolder.children[i]);
166
+ }
167
+ }
168
+ }
169
+
170
+ export function HandleAppRemoteTweakpane(app: Application, msg: BroadcastData) {
171
+ app.components.forEach((component: any) => {
172
+ if (component instanceof RemoteTweakpane) {
173
+ const tweakpane: RemoteTweakpane = component;
174
+ switch (msg.event) {
175
+ case 'addFolder':
176
+ tweakpane.addFolder(msg.data.name, msg.data.params, msg.data.parent);
177
+ break;
178
+ case 'bindObject':
179
+ tweakpane.bind(msg.data.name, msg.data.params, msg.data.parent);
180
+ break;
181
+ case 'updateBind':
182
+ tweakpane.triggerBind(msg.data.id, msg.data.value);
183
+ break;
184
+ case 'addButton':
185
+ tweakpane.button(msg.data.name, msg.data.callback, msg.data.parent);
186
+ break;
187
+ case 'clickButton':
188
+ tweakpane.triggerButton(msg.data.id);
189
+ break;
190
+ }
191
+ return;
192
+ }
193
+ });
194
+ }
@@ -0,0 +1,56 @@
1
+ // Interfaces
2
+
3
+ export interface BroadcastData {
4
+ target: ApplicationMode
5
+ event: EditorEvent
6
+ data?: any
7
+ }
8
+
9
+ // Types
10
+
11
+ export type ApplicationMode = 'app' | 'editor'
12
+
13
+ export type VoidCallback = () => void
14
+
15
+ export type DataUpdateCallback = (data: any) => void
16
+
17
+ export type EditorEvent =
18
+ | 'custom'
19
+ // Theatre
20
+ | 'setSheet'
21
+ | 'setSheetObject'
22
+ | 'updateSheetObject'
23
+ | 'updateTimeline'
24
+ | 'playSheet'
25
+ | 'pauseSheet'
26
+ // Three
27
+ | 'getObject'
28
+ | 'setObject'
29
+ | 'updateObject'
30
+ | 'setScene'
31
+ | 'createTexture'
32
+ | 'requestMethod'
33
+ | 'addCamera'
34
+ | 'removeCamera'
35
+ // GUI
36
+ | 'addFolder'
37
+ | 'bindObject'
38
+ | 'updateBind'
39
+ | 'addButton'
40
+ | 'clickButton'
41
+ // Components
42
+ | 'selectComponent'
43
+ | 'draggableListUpdate'
44
+
45
+ export type VoidFunc = () => void
46
+
47
+ export type BroadcastCallback = (data: BroadcastData) => void
48
+
49
+ export type TheatreUpdateCallback = (data: any) => void
50
+
51
+ // Consts
52
+
53
+ export const noop = () => {};
54
+
55
+ export const defaultTheatreCallback: TheatreUpdateCallback = () => {};
56
+
@@ -0,0 +1,20 @@
1
+ import { CSSProperties, Ref } from 'react';
2
+ import './scss/index.scss';
3
+
4
+ type EditorProps = {
5
+ header?: JSX.Element | JSX.Element[]
6
+ children?: JSX.Element | JSX.Element[]
7
+ footer?: JSX.Element | JSX.Element[]
8
+ ref?: Ref<any>
9
+ style?: CSSProperties
10
+ }
11
+
12
+ export default function Editor(props: EditorProps) {
13
+ return (
14
+ <div className='editor' ref={props.ref} style={props.style}>
15
+ <header>{props.header}</header>
16
+ {props.children}
17
+ <footer>{props.footer}</footer>
18
+ </div>
19
+ );
20
+ }