@operato/board 10.0.0-beta.3 → 10.0.0-beta.30

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 (47) hide show
  1. package/CHANGELOG.md +251 -0
  2. package/dist/src/component/container.js +1 -3
  3. package/dist/src/component/container.js.map +1 -1
  4. package/dist/src/component/etc.js +2 -10
  5. package/dist/src/component/etc.js.map +1 -1
  6. package/dist/src/component/line.js +4 -28
  7. package/dist/src/component/line.js.map +1 -1
  8. package/dist/src/component/shape.js +5 -29
  9. package/dist/src/component/shape.js.map +1 -1
  10. package/dist/src/component/text-and-media.js +2 -25
  11. package/dist/src/component/text-and-media.js.map +1 -1
  12. package/dist/src/data-storage/board-model-cache.d.ts +30 -0
  13. package/dist/src/data-storage/board-model-cache.js +93 -0
  14. package/dist/src/data-storage/board-model-cache.js.map +1 -0
  15. package/dist/src/graphql/playback-buffer.d.ts +79 -0
  16. package/dist/src/graphql/playback-buffer.js +139 -0
  17. package/dist/src/graphql/playback-buffer.js.map +1 -0
  18. package/dist/src/graphql/playback-buffer.test.d.ts +1 -0
  19. package/dist/src/graphql/playback-buffer.test.js +261 -0
  20. package/dist/src/graphql/playback-buffer.test.js.map +1 -0
  21. package/dist/src/graphql/playback-subscription.d.ts +89 -0
  22. package/dist/src/graphql/playback-subscription.js +258 -0
  23. package/dist/src/graphql/playback-subscription.js.map +1 -0
  24. package/dist/src/index.d.ts +2 -0
  25. package/dist/src/index.js +1 -0
  26. package/dist/src/index.js.map +1 -1
  27. package/dist/src/modeller/edit-toolbar-style.js +38 -1
  28. package/dist/src/modeller/edit-toolbar-style.js.map +1 -1
  29. package/dist/src/modeller/edit-toolbar.d.ts +8 -16
  30. package/dist/src/modeller/edit-toolbar.js +204 -199
  31. package/dist/src/modeller/edit-toolbar.js.map +1 -1
  32. package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +2 -1
  33. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +7 -11
  34. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -1
  35. package/dist/src/ox-board-modeller.d.ts +8 -1
  36. package/dist/src/ox-board-modeller.js +125 -6
  37. package/dist/src/ox-board-modeller.js.map +1 -1
  38. package/dist/src/ox-board-viewer.d.ts +50 -1
  39. package/dist/src/ox-board-viewer.js +270 -27
  40. package/dist/src/ox-board-viewer.js.map +1 -1
  41. package/dist/src/ox-playback-controls.d.ts +56 -0
  42. package/dist/src/ox-playback-controls.js +515 -0
  43. package/dist/src/ox-playback-controls.js.map +1 -0
  44. package/dist/src/selector/ox-board-selector.js +11 -1
  45. package/dist/src/selector/ox-board-selector.js.map +1 -1
  46. package/dist/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +13 -12
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { __decorate } from "tslib";
5
5
  import { html, LitElement } from 'lit';
6
- import { property, query, queryAll } from 'lit/decorators.js';
6
+ import { property, state } from 'lit/decorators.js';
7
7
  import { copyToClipboard, isMacOS } from '@operato/utils';
8
8
  import { style } from './edit-toolbar-style.js';
9
9
  const MACOS = isMacOS();
@@ -12,9 +12,17 @@ export class EditToolbar extends LitElement {
12
12
  super(...arguments);
13
13
  this.selected = [];
14
14
  this.hideProperty = false;
15
+ this._dimension = null;
16
+ this._gizmoAttached = false;
15
17
  }
16
18
  firstUpdated() {
17
19
  this.addEventListener('mousewheel', this.onWheelEvent.bind(this), false);
20
+ // 툴바 버튼 클릭 후 씬으로 포커스를 돌려서 키보드 단축키가 계속 작동하도록 한다
21
+ this.addEventListener('click', () => {
22
+ var _a, _b, _c;
23
+ ;
24
+ (_c = (_b = (_a = this.scene) === null || _a === void 0 ? void 0 : _a.root) === null || _b === void 0 ? void 0 : _b.element) === null || _c === void 0 ? void 0 : _c.focus();
25
+ });
18
26
  window.addEventListener('paste', (e) => {
19
27
  var _a;
20
28
  try {
@@ -24,33 +32,7 @@ export class EditToolbar extends LitElement {
24
32
  console.error('model paste failed', e);
25
33
  }
26
34
  });
27
- this.aligners.forEach(aligner => aligner.addEventListener('click', this.onTapAlign.bind(this)));
28
- this.zorders.forEach(zorder => zorder.addEventListener('click', this.onTapZorder.bind(this)));
29
- this.distributes.forEach(distribute => distribute.addEventListener('click', this.onTapDistribute.bind(this)));
30
- this.undo.addEventListener('click', this.onTapUndo.bind(this));
31
- this.redo.addEventListener('click', this.onTapRedo.bind(this));
32
- this.fullscreen.addEventListener('click', this.onTapFullscreen.bind(this));
33
- this.styleCopy.addEventListener('click', this.onStartStylePasteMode.bind(this));
34
- this.databindCopy.addEventListener('click', this.onStartDatabindPasteMode.bind(this));
35
- this.cut.addEventListener('click', this.onTapCut.bind(this));
36
- this.copy.addEventListener('click', this.onTapCopy.bind(this));
37
- this.paste.addEventListener('click', this.onTapPaste.bind(this));
38
- this.delete.addEventListener('click', this.onTapDelete.bind(this));
39
- this.renderRoot
40
- .querySelector('#font-increase')
41
- .addEventListener('click', this.onTapFontIncrease.bind(this));
42
- this.renderRoot
43
- .querySelector('#font-decrease')
44
- .addEventListener('click', this.onTapFontDecrease.bind(this));
45
- this.renderRoot.querySelector('#group').addEventListener('click', this.onTapGroup.bind(this));
46
- this.renderRoot.querySelector('#ungroup').addEventListener('click', this.onTapUngroup.bind(this));
47
- this.renderRoot
48
- .querySelector('#toggle-property')
49
- .addEventListener('click', this.onTapToggle.bind(this));
50
- this.renderRoot
51
- .querySelector('#fit-scene')
52
- .addEventListener('click', this.onTapFitScene.bind(this));
53
- this.renderRoot.querySelector('#preview').addEventListener('click', this.onTapPreview.bind(this));
35
+ // 모든 버튼은 템플릿 @click 디렉티브로 바인딩 — 조건부 렌더링 시에도 정상 작동
54
36
  }
55
37
  updated(changes) {
56
38
  changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene'));
@@ -61,127 +43,122 @@ export class EditToolbar extends LitElement {
61
43
  <div tools>
62
44
  <span><slot></slot></span>
63
45
 
64
- <span button id="undo" title="undo (${this.getShortcutString('cmd', 'z')})"> </span>
65
- <span button id="redo" title="redo (${this.getShortcutString('cmd', 'shift', 'z')})"> </span>
46
+ <span button id="undo" title="undo (${this.getShortcutString('cmd', 'z')})" @click=${this.onTapUndo}> </span>
47
+ <span button id="redo" title="redo (${this.getShortcutString('cmd', 'shift', 'z')})" @click=${this.onTapRedo}> </span>
66
48
 
67
49
  <span class="vline"></span>
68
50
 
69
- <span button id="style-copy" title="style copy (${this.getShortcutString('cmd', '1')})"> </span>
70
- <span button id="databind-copy" title="databind copy (${this.getShortcutString('cmd', '2')})"> </span>
51
+ <span button id="style-copy" title="style copy (${this.getShortcutString('cmd', '1')})" @click=${this.onStartStylePasteMode}> </span>
52
+ <span button id="databind-copy" title="databind copy (${this.getShortcutString('cmd', '2')})" @click=${this.onStartDatabindPasteMode}> </span>
71
53
 
72
54
  <span class="vline"></span>
73
55
 
74
- <span button id="cut" title="cut (${this.getShortcutString('cmd', 'x')})"> </span>
75
- <span button id="copy" title="copy (${this.getShortcutString('cmd', 'c')})"> </span>
76
- <span button id="paste" title="paste (${this.getShortcutString('cmd', 'v')})"> </span>
77
- <span
78
- button
79
- id="delete"
56
+ <span button id="cut" title="cut (${this.getShortcutString('cmd', 'x')})" @click=${this.onTapCut}> </span>
57
+ <span button id="copy" title="copy (${this.getShortcutString('cmd', 'c')})" @click=${this.onTapCopy}> </span>
58
+ <span button id="paste" title="paste (${this.getShortcutString('cmd', 'v')})" @click=${this.onTapPaste}> </span>
59
+ <span button id="delete"
80
60
  title="delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})"
81
- >
82
- </span>
61
+ @click=${this.onTapDelete}> </span>
83
62
 
84
63
  <span class="vline"></span>
85
64
 
86
- <span
87
- button
88
- data-align="left"
89
- id="align-left"
90
- title="align left (${this.getShortcutString('alt', 'shift', 'l')})"
91
- >
92
- </span>
93
- <span
94
- button
95
- data-align="center"
96
- id="align-center"
97
- title="align center (${this.getShortcutString('alt', 'shift', 'c')})"
98
- >
99
- </span>
100
- <span
101
- button
102
- data-align="right"
103
- id="align-right"
104
- title="align right (${this.getShortcutString('alt', 'shift', 'r')})"
105
- >
106
- </span>
65
+ <span button data-align="left" id="align-left"
66
+ title="align left (${this.getShortcutString('alt', 'shift', 'l')})" @click=${this.onTapAlign}> </span>
67
+ <span button data-align="center" id="align-center"
68
+ title="align center (${this.getShortcutString('alt', 'shift', 'c')})" @click=${this.onTapAlign}> </span>
69
+ <span button data-align="right" id="align-right"
70
+ title="align right (${this.getShortcutString('alt', 'shift', 'r')})" @click=${this.onTapAlign}> </span>
107
71
 
108
- <span button data-align="top" id="align-top" title="align top (${this.getShortcutString('alt', 'shift', 't')})">
109
- </span>
110
- <span
111
- button
112
- data-align="middle"
113
- id="align-middle"
114
- title="align middle (${this.getShortcutString('alt', 'shift', 'm')})"
115
- >
116
- </span>
117
- <span
118
- button
119
- data-align="bottom"
120
- id="align-bottom"
121
- title="align bottom (${this.getShortcutString('alt', 'shift', 'b')})"
122
- >
123
- </span>
72
+ <span button data-align="top" id="align-top"
73
+ title="align top (${this.getShortcutString('alt', 'shift', 't')})" @click=${this.onTapAlign}> </span>
74
+ <span button data-align="middle" id="align-middle"
75
+ title="align middle (${this.getShortcutString('alt', 'shift', 'm')})" @click=${this.onTapAlign}> </span>
76
+ <span button data-align="bottom" id="align-bottom"
77
+ title="align bottom (${this.getShortcutString('alt', 'shift', 'b')})" @click=${this.onTapAlign}> </span>
124
78
 
125
- <span
126
- button
127
- data-distribute="HORIZONTAL"
128
- id="distribute-horizontal"
129
- title="distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})"
130
- >
131
- </span>
79
+ <span button data-distribute="HORIZONTAL" id="distribute-horizontal"
80
+ title="distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})" @click=${this.onTapDistribute}> </span>
81
+ <span button data-distribute="VERTICAL" id="distribute-vertical"
82
+ title="distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})" @click=${this.onTapDistribute}> </span>
132
83
 
133
- <span
134
- button
135
- data-distribute="VERTICAL"
136
- id="distribute-vertical"
137
- title="distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})"
138
- >
139
- </span>
84
+ ${this._dimension === '3d'
85
+ ? html `
86
+ <span class="vline"></span>
140
87
 
141
- <span class="vline"></span>
88
+ <span button data-align="z-front" id="align-z-front" title="align Z front" @click=${this.onTapAlign}> </span>
89
+ <span button data-align="z-middle" id="align-z-middle" title="align Z middle" @click=${this.onTapAlign}> </span>
90
+ <span button data-align="z-back" id="align-z-back" title="align Z back" @click=${this.onTapAlign}> </span>
91
+ <span button data-distribute="Z" id="distribute-z" title="distribute Z" @click=${this.onTapDistribute}> </span>
92
+ `
93
+ : this._dimension === '2d'
94
+ ? html `
95
+ <span class="vline"></span>
142
96
 
143
- <span
144
- button
145
- id="front"
146
- data-zorder="front"
147
- title="bring to front (${this.getShortcutString('cmd', 'shift', 'f')})"
148
- >
149
- </span>
150
- <span button id="back" data-zorder="back" title="send to back (${this.getShortcutString('cmd', 'shift', 'b')})">
151
- </span>
152
- <span button id="forward" data-zorder="forward" title="bring forward (${this.getShortcutString('cmd', 'f')})">
153
- </span>
154
- <span button id="backward" data-zorder="backward" title="send backward (${this.getShortcutString('cmd', 'b')})">
155
- </span>
97
+ <span button id="front" data-zorder="front"
98
+ title="bring to front (${this.getShortcutString('cmd', 'shift', 'f')})" @click=${this.onTapZorder}> </span>
99
+ <span button id="back" data-zorder="back"
100
+ title="send to back (${this.getShortcutString('cmd', 'shift', 'b')})" @click=${this.onTapZorder}> </span>
101
+ <span button id="forward" data-zorder="forward"
102
+ title="bring forward (${this.getShortcutString('cmd', 'f')})" @click=${this.onTapZorder}> </span>
103
+ <span button id="backward" data-zorder="backward"
104
+ title="send backward (${this.getShortcutString('cmd', 'b')})" @click=${this.onTapZorder}> </span>
105
+ `
106
+ : ''}
156
107
 
157
- <span class="vline"></span>
108
+ ${this._dimension === '2d' ? html `
109
+ <span class="vline"></span>
110
+
111
+ <span button id="group" title="group (${this.getShortcutString('cmd', 'g')})" @click=${this.onTapGroup}> </span>
112
+ <span button id="ungroup" title="ungroup (${this.getShortcutString('cmd', 'shift', 'g')})" @click=${this.onTapUngroup}> </span>
113
+ ` : this._dimension === '3d' ? html `
114
+ <span class="vline"></span>
158
115
 
159
- <span button id="group" title="group (${this.getShortcutString('cmd', 'g')})"> </span>
160
- <span button id="ungroup" title="ungroup (${this.getShortcutString('cmd', 'shift', 'g')})"> </span>
116
+ <span button class="gizmo-btn" data-gizmo="translate" title="Move (W)"
117
+ @click=${() => this._setGizmoMode('translate')}>
118
+ <svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8">
119
+ <line x1="10" y1="2" x2="10" y2="18"/><line x1="2" y1="10" x2="18" y2="10"/>
120
+ <polyline points="10,2 7.5,5"/><polyline points="10,2 12.5,5"/>
121
+ <polyline points="18,10 15,7.5"/><polyline points="18,10 15,12.5"/>
122
+ <polyline points="10,18 7.5,15"/><polyline points="10,18 12.5,15"/>
123
+ <polyline points="2,10 5,7.5"/><polyline points="2,10 5,12.5"/>
124
+ </svg>
125
+ </span>
126
+ <span button class="gizmo-btn" data-gizmo="rotate" title="Rotate (E)"
127
+ @click=${() => this._setGizmoMode('rotate')}>
128
+ <svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8">
129
+ <path d="M14.5 3.5A7 7 0 1 0 17 10"/>
130
+ <polyline points="14,1 15,3.5 12.5,4.5"/>
131
+ </svg>
132
+ </span>
133
+ <span button class="gizmo-btn" data-gizmo="scale" title="Scale (R)"
134
+ @click=${() => this._setGizmoMode('scale')}>
135
+ <svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8">
136
+ <line x1="4" y1="16" x2="16" y2="4"/>
137
+ <rect x="2" y="13" width="4" height="4" rx="0.5" fill="currentColor"/>
138
+ <rect x="14" y="2" width="4" height="4" rx="0.5" fill="currentColor"/>
139
+ </svg>
140
+ </span>
141
+ ` : ''}
161
142
 
162
143
  <span class="vline"></span>
163
144
 
164
- <span button id="font-increase" title="increase font size"></span>
165
- <span button id="font-decrease" title="decrease font size" style="scale: 0.7;"></span>
145
+ <span button id="font-increase" title="increase font size" @click=${this.onTapFontIncrease}></span>
146
+ <span button id="font-decrease" title="decrease font size" style="scale: 0.7;" @click=${this.onTapFontDecrease}></span>
166
147
 
167
148
  <span class="vline"></span>
168
149
  <span padding></span>
169
150
 
170
- <span button id="fit-scene" title="fit scene (${this.getShortcutString('cmd', 'd')})"> </span>
151
+ <span button id="fit-scene" title="fit scene (${this.getShortcutString('cmd', 'd')})" @click=${this.onTapFitScene}> </span>
171
152
 
172
153
  <span class="vline"></span>
173
154
 
174
- <span button id="preview" title="preview (${this.getShortcutString('ctrl', 'p')})"> </span>
155
+ <span button id="preview" title="preview (${this.getShortcutString('ctrl', 'p')})" @click=${this.onTapPreview}> </span>
175
156
 
176
- <span button id="fullscreen" title="fullscreen (${this.getShortcutString('f11')})"> </span>
157
+ <span button id="fullscreen" title="fullscreen (${this.getShortcutString('f11')})" @click=${this.onTapFullscreen}> </span>
177
158
 
178
- <span
179
- button
180
- id="toggle-property"
159
+ <span button id="toggle-property"
181
160
  title="toggle property panel (${this.getShortcutString('cmd', 'h')})"
182
- toggles="true"
183
- >
184
- </span>
161
+ toggles="true" @click=${this.onTapToggle}> </span>
185
162
  </div>
186
163
  `;
187
164
  }
@@ -224,7 +201,7 @@ export class EditToolbar extends LitElement {
224
201
  return symbols.join(MACOS ? '' : '+');
225
202
  }
226
203
  onShortcut(e) {
227
- var _a, _b, _c, _d;
204
+ var _a, _b, _c, _d, _e, _f;
228
205
  if (MACOS)
229
206
  var ctrlKey = e.metaKey;
230
207
  else
@@ -275,23 +252,29 @@ export class EditToolbar extends LitElement {
275
252
  defaultPrevent = true;
276
253
  break;
277
254
  case 'KeyG':
278
- if (ctrlKey && !shiftKey)
279
- this.onTapGroup();
280
- else if (ctrlKey && shiftKey)
281
- this.onTapUngroup();
255
+ if (this._dimension === '2d') {
256
+ if (ctrlKey && !shiftKey)
257
+ this.onTapGroup();
258
+ else if (ctrlKey && shiftKey)
259
+ this.onTapUngroup();
260
+ }
282
261
  break;
283
262
  case 'KeyF':
284
- if (ctrlKey && !shiftKey)
285
- (_a = this.scene) === null || _a === void 0 ? void 0 : _a.zorder('forward');
286
- else if (ctrlKey && shiftKey)
287
- (_b = this.scene) === null || _b === void 0 ? void 0 : _b.zorder('front');
263
+ if (this._dimension === '2d') {
264
+ if (ctrlKey && !shiftKey)
265
+ (_a = this.scene) === null || _a === void 0 ? void 0 : _a.zorder('forward');
266
+ else if (ctrlKey && shiftKey)
267
+ (_b = this.scene) === null || _b === void 0 ? void 0 : _b.zorder('front');
268
+ }
288
269
  break;
289
270
  case 'KeyB':
290
- if (ctrlKey && !shiftKey)
291
- (_c = this.scene) === null || _c === void 0 ? void 0 : _c.zorder('backward');
292
- else if (ctrlKey && shiftKey)
293
- (_d = this.scene) === null || _d === void 0 ? void 0 : _d.zorder('back');
294
- else if (altKey && shiftKey)
271
+ if (this._dimension === '2d') {
272
+ if (ctrlKey && !shiftKey)
273
+ (_c = this.scene) === null || _c === void 0 ? void 0 : _c.zorder('backward');
274
+ else if (ctrlKey && shiftKey)
275
+ (_d = this.scene) === null || _d === void 0 ? void 0 : _d.zorder('back');
276
+ }
277
+ if (altKey && shiftKey)
295
278
  this.onTapAlign('bottom');
296
279
  break;
297
280
  case 'KeyH':
@@ -335,23 +318,38 @@ export class EditToolbar extends LitElement {
335
318
  this.onTapFitScene();
336
319
  defaultPrevent = true;
337
320
  }
321
+ else if (!shiftKey && !altKey) {
322
+ const target = e.composedPath()[0];
323
+ const tagName = target.tagName;
324
+ if (!target.isContentEditable && tagName !== 'INPUT' && tagName !== 'SELECT' && tagName !== 'TEXTAREA') {
325
+ this.onTapDataBinding();
326
+ defaultPrevent = true;
327
+ }
328
+ }
338
329
  break;
339
330
  case 'KeyE':
340
331
  if (ctrlKey && shiftKey)
341
332
  this.onTapDownloadModel();
342
333
  break;
334
+ case 'F10':
335
+ this.onTapEditModel();
336
+ defaultPrevent = true;
337
+ break;
343
338
  case 'Digit1':
344
339
  if (ctrlKey) {
345
- console.log('MODEL', this.scene && this.scene.model);
346
340
  defaultPrevent = true;
347
341
  }
348
342
  break;
349
343
  case 'Digit2':
350
344
  if (ctrlKey) {
351
- console.log('SELECTED', this.scene && this.scene.selected);
352
345
  defaultPrevent = true;
353
346
  }
354
347
  break;
348
+ case 'Escape':
349
+ (_e = this.scene) === null || _e === void 0 ? void 0 : _e.stopStylePasteMode();
350
+ (_f = this.scene) === null || _f === void 0 ? void 0 : _f.stopDatabindPasteMode();
351
+ defaultPrevent = true;
352
+ break;
355
353
  default:
356
354
  return false;
357
355
  }
@@ -359,40 +357,75 @@ export class EditToolbar extends LitElement {
359
357
  e.preventDefault();
360
358
  return true;
361
359
  }
360
+ _setDisabled(id, disabled) {
361
+ const el = this.renderRoot.querySelector(`#${id}`);
362
+ disabled ? el === null || el === void 0 ? void 0 : el.setAttribute('disabled', '') : el === null || el === void 0 ? void 0 : el.removeAttribute('disabled');
363
+ }
362
364
  onExecute(command, undoable, redoable) {
363
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
364
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
365
+ this._setDisabled('undo', !undoable);
366
+ this._setDisabled('redo', !redoable);
365
367
  }
366
368
  onUndo(undoable, redoable) {
367
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
368
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
369
+ this._setDisabled('undo', !undoable);
370
+ this._setDisabled('redo', !redoable);
369
371
  }
370
372
  onRedo(undoable, redoable) {
371
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
372
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
373
+ this._setDisabled('undo', !undoable);
374
+ this._setDisabled('redo', !redoable);
373
375
  }
374
376
  onSceneChanged(after, before) {
377
+ var _a, _b;
375
378
  if (before) {
376
379
  before.off('execute', this.onExecute, this);
377
380
  before.off('undo', this.onUndo, this);
378
381
  before.off('redo', this.onRedo, this);
382
+ before.off('dimension', this._onDimensionChanged, this);
383
+ before.off('gizmoattach', this._onGizmoAttachChanged, this);
379
384
  }
380
385
  if (after) {
381
386
  after.on('execute', this.onExecute, this);
382
387
  after.on('undo', this.onUndo, this);
383
388
  after.on('redo', this.onRedo, this);
389
+ after.on('dimension', this._onDimensionChanged, this);
390
+ after.on('gizmoattach', this._onGizmoAttachChanged, this);
391
+ // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)
392
+ const threed = (_b = (_a = after.model_layer) === null || _a === void 0 ? void 0 : _a.model) === null || _b === void 0 ? void 0 : _b.threed;
393
+ this._dimension = threed ? '3d' : '2d';
384
394
  }
385
395
  }
396
+ _onDimensionChanged(dimension) {
397
+ this._dimension = dimension;
398
+ }
399
+ _onGizmoAttachChanged(isAttached) {
400
+ this._gizmoAttached = isAttached;
401
+ }
402
+ _setGizmoMode(mode) {
403
+ var _a, _b;
404
+ ;
405
+ (_b = (_a = this.scene) === null || _a === void 0 ? void 0 : _a.root) === null || _b === void 0 ? void 0 : _b.setGizmoMode(mode);
406
+ }
386
407
  onSelectedChanged(after, before) {
408
+ var hasSelection = after.length > 0;
387
409
  var alignable = after.length > 1;
388
- this.aligners.forEach(aligner => alignable ? aligner.removeAttribute('disabled') : aligner.setAttribute('disabled', ''));
389
- var movable = after.length === 1;
390
- /* forward, backward 이동은 컴포넌트만 가능하다. */
391
- !movable ? this.forward.setAttribute('disabled', '') : this.forward.removeAttribute('disabled');
392
- !movable ? this.backward.setAttribute('disabled', '') : this.backward.removeAttribute('disabled');
393
- /* 여러 컴포넌트는 front, back 이동이 가능하다. */
394
- !(alignable || movable) ? this.front.setAttribute('disabled', '') : this.front.removeAttribute('disabled');
395
- !(alignable || movable) ? this.back.setAttribute('disabled', '') : this.back.removeAttribute('disabled');
410
+ ['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id => this._setDisabled(id, !hasSelection));
411
+ // 정렬 버튼
412
+ this.renderRoot.querySelectorAll('[data-align]').forEach(el => alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', ''));
413
+ if (this._dimension === '2d') {
414
+ var movable = after.length === 1;
415
+ /* forward, backward 이동은 컴포넌트만 가능하다. */
416
+ this._setDisabled('forward', !movable);
417
+ this._setDisabled('backward', !movable);
418
+ /* 여러 컴포넌트는 front, back 이동이 가능하다. */
419
+ this._setDisabled('front', !(alignable || movable));
420
+ this._setDisabled('back', !(alignable || movable));
421
+ }
422
+ // 분배 버튼
423
+ this.renderRoot.querySelectorAll('[data-distribute]').forEach(el => alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', ''));
424
+ if (this._dimension === '3d') {
425
+ this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {
426
+ hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '');
427
+ });
428
+ }
396
429
  }
397
430
  onTapUndo() {
398
431
  var _a;
@@ -403,12 +436,20 @@ export class EditToolbar extends LitElement {
403
436
  (_a = this.scene) === null || _a === void 0 ? void 0 : _a.redo();
404
437
  }
405
438
  onStartStylePasteMode() {
406
- var _a;
407
- (_a = this.scene) === null || _a === void 0 ? void 0 : _a.startStylePasteMode();
439
+ var _a, _b, _c;
440
+ if (((_a = this.selected) === null || _a === void 0 ? void 0 : _a.length) !== 1)
441
+ return;
442
+ if (this.selected[0] === ((_b = this.scene) === null || _b === void 0 ? void 0 : _b.root))
443
+ return;
444
+ (_c = this.scene) === null || _c === void 0 ? void 0 : _c.startStylePasteMode();
408
445
  }
409
446
  onStartDatabindPasteMode() {
410
- var _a;
411
- (_a = this.scene) === null || _a === void 0 ? void 0 : _a.startDatabindPasteMode();
447
+ var _a, _b, _c;
448
+ if (((_a = this.selected) === null || _a === void 0 ? void 0 : _a.length) !== 1)
449
+ return;
450
+ if (this.selected[0] === ((_b = this.scene) === null || _b === void 0 ? void 0 : _b.root))
451
+ return;
452
+ (_c = this.scene) === null || _c === void 0 ? void 0 : _c.startDatabindPasteMode();
412
453
  }
413
454
  onTapCut() {
414
455
  var _a;
@@ -523,9 +564,15 @@ export class EditToolbar extends LitElement {
523
564
  onTapPreview() {
524
565
  this.dispatchEvent(new CustomEvent('open-preview'));
525
566
  }
567
+ onTapDataBinding() {
568
+ this.dispatchEvent(new CustomEvent('open-data-binding'));
569
+ }
526
570
  onTapDownloadModel() {
527
571
  this.dispatchEvent(new CustomEvent('download-model'));
528
572
  }
573
+ onTapEditModel() {
574
+ this.dispatchEvent(new CustomEvent('edit-model'));
575
+ }
529
576
  onTapDistribute(e) {
530
577
  if (!this.scene)
531
578
  return;
@@ -548,51 +595,9 @@ __decorate([
548
595
  property({ type: Boolean })
549
596
  ], EditToolbar.prototype, "hideProperty", void 0);
550
597
  __decorate([
551
- query('#redo')
552
- ], EditToolbar.prototype, "redo", void 0);
553
- __decorate([
554
- query('#undo')
555
- ], EditToolbar.prototype, "undo", void 0);
556
- __decorate([
557
- query('#fullscreen')
558
- ], EditToolbar.prototype, "fullscreen", void 0);
559
- __decorate([
560
- query('#style-copy')
561
- ], EditToolbar.prototype, "styleCopy", void 0);
562
- __decorate([
563
- query('#databind-copy')
564
- ], EditToolbar.prototype, "databindCopy", void 0);
565
- __decorate([
566
- query('#cut')
567
- ], EditToolbar.prototype, "cut", void 0);
568
- __decorate([
569
- query('#copy')
570
- ], EditToolbar.prototype, "copy", void 0);
571
- __decorate([
572
- query('#paste')
573
- ], EditToolbar.prototype, "paste", void 0);
574
- __decorate([
575
- query('#delete')
576
- ], EditToolbar.prototype, "delete", void 0);
577
- __decorate([
578
- query('#forward')
579
- ], EditToolbar.prototype, "forward", void 0);
580
- __decorate([
581
- query('#backward')
582
- ], EditToolbar.prototype, "backward", void 0);
583
- __decorate([
584
- query('#front')
585
- ], EditToolbar.prototype, "front", void 0);
586
- __decorate([
587
- query('#back')
588
- ], EditToolbar.prototype, "back", void 0);
589
- __decorate([
590
- queryAll('[data-align]')
591
- ], EditToolbar.prototype, "aligners", void 0);
592
- __decorate([
593
- queryAll('[data-zorder]')
594
- ], EditToolbar.prototype, "zorders", void 0);
598
+ state()
599
+ ], EditToolbar.prototype, "_dimension", void 0);
595
600
  __decorate([
596
- queryAll('[data-distribute]')
597
- ], EditToolbar.prototype, "distributes", void 0);
601
+ state()
602
+ ], EditToolbar.prototype, "_gizmoAttached", void 0);
598
603
  //# sourceMappingURL=edit-toolbar.js.map