@fmsim/board 2.0.0-beta.2 → 2.0.0-beta.23

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 (59) hide show
  1. package/custom-elements.json +2271 -1078
  2. package/demo/index-modeller.html +1 -1
  3. package/demo/index-player.html +2 -2
  4. package/demo/index-viewer.html +2 -2
  5. package/demo/index.html +2 -2
  6. package/dist/src/component/etc.js +17 -0
  7. package/dist/src/component/etc.js.map +1 -1
  8. package/dist/src/data-storage/board-model-cache.d.ts +13 -0
  9. package/dist/src/data-storage/board-model-cache.js +66 -0
  10. package/dist/src/data-storage/board-model-cache.js.map +1 -0
  11. package/dist/src/index.d.ts +3 -0
  12. package/dist/src/index.js +2 -0
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/modeller/edit-toolbar-style.js +43 -3
  15. package/dist/src/modeller/edit-toolbar-style.js.map +1 -1
  16. package/dist/src/modeller/edit-toolbar.d.ts +8 -14
  17. package/dist/src/modeller/edit-toolbar.js +208 -211
  18. package/dist/src/modeller/edit-toolbar.js.map +1 -1
  19. package/dist/src/modeller/property-sidebar/property-sidebar.js +3 -16
  20. package/dist/src/modeller/property-sidebar/property-sidebar.js.map +1 -1
  21. package/dist/src/modeller/property-sidebar/shapes/shapes.js +31 -0
  22. package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -1
  23. package/dist/src/modeller/property-sidebar/styles/styles.d.ts +6 -4
  24. package/dist/src/modeller/property-sidebar/styles/styles.js +139 -436
  25. package/dist/src/modeller/property-sidebar/styles/styles.js.map +1 -1
  26. package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +2 -1
  27. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +5 -1
  28. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -1
  29. package/dist/src/ox-board-component-info.d.ts +1 -0
  30. package/dist/src/ox-board-component-info.js +5 -1
  31. package/dist/src/ox-board-component-info.js.map +1 -1
  32. package/dist/src/ox-board-list.js +2 -2
  33. package/dist/src/ox-board-list.js.map +1 -1
  34. package/dist/src/ox-board-modeller.d.ts +5 -2
  35. package/dist/src/ox-board-modeller.js +14 -4
  36. package/dist/src/ox-board-modeller.js.map +1 -1
  37. package/dist/src/ox-board-viewer.d.ts +22 -2
  38. package/dist/src/ox-board-viewer.js +246 -21
  39. package/dist/src/ox-board-viewer.js.map +1 -1
  40. package/dist/src/ox-editor-board-selector.d.ts +3 -0
  41. package/dist/src/ox-editor-board-selector.js +38 -9
  42. package/dist/src/ox-editor-board-selector.js.map +1 -1
  43. package/dist/src/ox-playback-controls.d.ts +60 -0
  44. package/dist/src/ox-playback-controls.js +512 -0
  45. package/dist/src/ox-playback-controls.js.map +1 -0
  46. package/dist/src/playback/playback-engine.d.ts +78 -0
  47. package/dist/src/playback/playback-engine.js +215 -0
  48. package/dist/src/playback/playback-engine.js.map +1 -0
  49. package/dist/src/selector/board-creation-popup.js +2 -2
  50. package/dist/src/selector/board-creation-popup.js.map +1 -1
  51. package/dist/src/selector/board-thumbnail-card.js +6 -6
  52. package/dist/src/selector/board-thumbnail-card.js.map +1 -1
  53. package/dist/src/selector/ox-board-creation-card.js +2 -2
  54. package/dist/src/selector/ox-board-creation-card.js.map +1 -1
  55. package/dist/src/selector/ox-board-selector.js +21 -10
  56. package/dist/src/selector/ox-board-selector.js.map +1 -1
  57. package/dist/tsconfig.tsbuildinfo +1 -1
  58. package/icons/icon-htoolbar.png +0 -0
  59. package/package.json +3 -6
@@ -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';
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,29 +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.cut.addEventListener('click', this.onTapCut.bind(this));
34
- this.copy.addEventListener('click', this.onTapCopy.bind(this));
35
- this.paste.addEventListener('click', this.onTapPaste.bind(this));
36
- this.delete.addEventListener('click', this.onTapDelete.bind(this));
37
- this.renderRoot
38
- .querySelector('#font-increase')
39
- .addEventListener('click', this.onTapFontIncrease.bind(this));
40
- this.renderRoot
41
- .querySelector('#font-decrease')
42
- .addEventListener('click', this.onTapFontDecrease.bind(this));
43
- this.renderRoot.querySelector('#group').addEventListener('click', this.onTapGroup.bind(this));
44
- this.renderRoot.querySelector('#ungroup').addEventListener('click', this.onTapUngroup.bind(this));
45
- this.renderRoot
46
- .querySelector('#toggle-property')
47
- .addEventListener('click', this.onTapToggle.bind(this));
48
- this.renderRoot.querySelector('#fit-scene').addEventListener('click', this.onTapFitScene.bind(this));
49
- this.renderRoot.querySelector('#preview').addEventListener('click', this.onTapPreview.bind(this));
35
+ // 모든 버튼은 템플릿 @click 디렉티브로 바인딩 — 조건부 렌더링 시에도 정상 작동
50
36
  }
51
37
  updated(changes) {
52
38
  changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene'));
@@ -59,128 +45,123 @@ export class EditToolbar extends LitElement {
59
45
 
60
46
  ${this.hasEmptySlot() ? html `` : html `<span class="vline"></span>`}
61
47
 
62
- <span button id="undo" title="undo (${this.getShortcutString('cmd', 'z')})"> </span>
63
- <span button id="redo" title="redo (${this.getShortcutString('cmd', 'shift', 'z')})"> </span>
48
+ <span button id="undo" title="undo (${this.getShortcutString('cmd', 'z')})" @click=${this.onTapUndo}> </span>
49
+ <span button id="redo" title="redo (${this.getShortcutString('cmd', 'shift', 'z')})" @click=${this.onTapRedo}> </span>
64
50
 
65
51
  <span class="vline"></span>
66
52
 
67
- <span button id="cut" title="cut (${this.getShortcutString('cmd', 'x')})"> </span>
68
- <span button id="copy" title="copy (${this.getShortcutString('cmd', 'c')})"> </span>
69
- <span button id="paste" title="paste (${this.getShortcutString('cmd', 'v')})"> </span>
70
- <span
71
- button
72
- id="delete"
73
- title="delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})"
74
- >
75
- </span>
53
+ <span button id="style-copy" title="style copy (${this.getShortcutString('cmd', '1')})" @click=${this.onStartStylePasteMode}> </span>
54
+ <span button id="databind-copy" title="databind copy (${this.getShortcutString('cmd', '2')})" @click=${this.onStartDatabindPasteMode}> </span>
76
55
 
77
56
  <span class="vline"></span>
78
57
 
79
- <!-- TODO Implement style-copy
80
- <span button id="style-copy" title="format painter"></span>
58
+ <span button id="cut" title="cut (${this.getShortcutString('cmd', 'x')})" @click=${this.onTapCut}> </span>
59
+ <span button id="copy" title="copy (${this.getShortcutString('cmd', 'c')})" @click=${this.onTapCopy}> </span>
60
+ <span button id="paste" title="paste (${this.getShortcutString('cmd', 'v')})" @click=${this.onTapPaste}> </span>
61
+ <span button id="delete"
62
+ title="delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})"
63
+ @click=${this.onTapDelete}> </span>
64
+
81
65
  <span class="vline"></span>
82
- -->
83
66
 
84
- <span
85
- button
86
- data-align="left"
87
- id="align-left"
88
- title="align left (${this.getShortcutString('alt', 'shift', 'l')})"
89
- >
90
- </span>
91
- <span
92
- button
93
- data-align="center"
94
- id="align-center"
95
- title="align center (${this.getShortcutString('alt', 'shift', 'c')})"
96
- >
97
- </span>
98
- <span
99
- button
100
- data-align="right"
101
- id="align-right"
102
- title="align right (${this.getShortcutString('alt', 'shift', 'r')})"
103
- >
104
- </span>
67
+ <span button data-align="left" id="align-left"
68
+ title="align left (${this.getShortcutString('alt', 'shift', 'l')})" @click=${this.onTapAlign}> </span>
69
+ <span button data-align="center" id="align-center"
70
+ title="align center (${this.getShortcutString('alt', 'shift', 'c')})" @click=${this.onTapAlign}> </span>
71
+ <span button data-align="right" id="align-right"
72
+ title="align right (${this.getShortcutString('alt', 'shift', 'r')})" @click=${this.onTapAlign}> </span>
105
73
 
106
- <span button data-align="top" id="align-top" title="align top (${this.getShortcutString('alt', 'shift', 't')})">
107
- </span>
108
- <span
109
- button
110
- data-align="middle"
111
- id="align-middle"
112
- title="align middle (${this.getShortcutString('alt', 'shift', 'm')})"
113
- >
114
- </span>
115
- <span
116
- button
117
- data-align="bottom"
118
- id="align-bottom"
119
- title="align bottom (${this.getShortcutString('alt', 'shift', 'b')})"
120
- >
121
- </span>
74
+ <span button data-align="top" id="align-top"
75
+ title="align top (${this.getShortcutString('alt', 'shift', 't')})" @click=${this.onTapAlign}> </span>
76
+ <span button data-align="middle" id="align-middle"
77
+ title="align middle (${this.getShortcutString('alt', 'shift', 'm')})" @click=${this.onTapAlign}> </span>
78
+ <span button data-align="bottom" id="align-bottom"
79
+ title="align bottom (${this.getShortcutString('alt', 'shift', 'b')})" @click=${this.onTapAlign}> </span>
122
80
 
123
- <span
124
- button
125
- data-distribute="HORIZONTAL"
126
- id="distribute-horizontal"
127
- title="distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})"
128
- >
129
- </span>
81
+ <span button data-distribute="HORIZONTAL" id="distribute-horizontal"
82
+ title="distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})" @click=${this.onTapDistribute}> </span>
83
+ <span button data-distribute="VERTICAL" id="distribute-vertical"
84
+ title="distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})" @click=${this.onTapDistribute}> </span>
130
85
 
131
- <span
132
- button
133
- data-distribute="VERTICAL"
134
- id="distribute-vertical"
135
- title="distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})"
136
- >
137
- </span>
86
+ ${this._dimension === '3d'
87
+ ? html `
88
+ <span class="vline"></span>
138
89
 
139
- <span class="vline"></span>
90
+ <span button data-align="z-front" id="align-z-front" title="align Z front" @click=${this.onTapAlign}> </span>
91
+ <span button data-align="z-middle" id="align-z-middle" title="align Z middle" @click=${this.onTapAlign}> </span>
92
+ <span button data-align="z-back" id="align-z-back" title="align Z back" @click=${this.onTapAlign}> </span>
93
+ <span button data-distribute="Z" id="distribute-z" title="distribute Z" @click=${this.onTapDistribute}> </span>
94
+ `
95
+ : this._dimension === '2d'
96
+ ? html `
97
+ <span class="vline"></span>
140
98
 
141
- <span
142
- button
143
- id="front"
144
- data-zorder="front"
145
- title="bring to front (${this.getShortcutString('cmd', 'shift', 'f')})"
146
- >
147
- </span>
148
- <span button id="back" data-zorder="back" title="send to back (${this.getShortcutString('cmd', 'shift', 'b')})">
149
- </span>
150
- <span button id="forward" data-zorder="forward" title="bring forward (${this.getShortcutString('cmd', 'f')})">
151
- </span>
152
- <span button id="backward" data-zorder="backward" title="send backward (${this.getShortcutString('cmd', 'b')})">
153
- </span>
99
+ <span button id="front" data-zorder="front"
100
+ title="bring to front (${this.getShortcutString('cmd', 'shift', 'f')})" @click=${this.onTapZorder}> </span>
101
+ <span button id="back" data-zorder="back"
102
+ title="send to back (${this.getShortcutString('cmd', 'shift', 'b')})" @click=${this.onTapZorder}> </span>
103
+ <span button id="forward" data-zorder="forward"
104
+ title="bring forward (${this.getShortcutString('cmd', 'f')})" @click=${this.onTapZorder}> </span>
105
+ <span button id="backward" data-zorder="backward"
106
+ title="send backward (${this.getShortcutString('cmd', 'b')})" @click=${this.onTapZorder}> </span>
107
+ `
108
+ : ''}
154
109
 
155
- <span class="vline"></span>
110
+ ${this._dimension === '2d' ? html `
111
+ <span class="vline"></span>
112
+
113
+ <span button id="group" title="group (${this.getShortcutString('cmd', 'g')})" @click=${this.onTapGroup}> </span>
114
+ <span button id="ungroup" title="ungroup (${this.getShortcutString('cmd', 'shift', 'g')})" @click=${this.onTapUngroup}> </span>
115
+ ` : this._dimension === '3d' ? html `
116
+ <span class="vline"></span>
156
117
 
157
- <span button id="group" title="group (${this.getShortcutString('cmd', 'g')})"> </span>
158
- <span button id="ungroup" title="ungroup (${this.getShortcutString('cmd', 'shift', 'g')})"> </span>
118
+ <span button class="gizmo-btn" data-gizmo="translate" title="Move (W)"
119
+ @click=${() => this._setGizmoMode('translate')}>
120
+ <svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8">
121
+ <line x1="10" y1="2" x2="10" y2="18"/><line x1="2" y1="10" x2="18" y2="10"/>
122
+ <polyline points="10,2 7.5,5"/><polyline points="10,2 12.5,5"/>
123
+ <polyline points="18,10 15,7.5"/><polyline points="18,10 15,12.5"/>
124
+ <polyline points="10,18 7.5,15"/><polyline points="10,18 12.5,15"/>
125
+ <polyline points="2,10 5,7.5"/><polyline points="2,10 5,12.5"/>
126
+ </svg>
127
+ </span>
128
+ <span button class="gizmo-btn" data-gizmo="rotate" title="Rotate (E)"
129
+ @click=${() => this._setGizmoMode('rotate')}>
130
+ <svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8">
131
+ <path d="M14.5 3.5A7 7 0 1 0 17 10"/>
132
+ <polyline points="14,1 15,3.5 12.5,4.5"/>
133
+ </svg>
134
+ </span>
135
+ <span button class="gizmo-btn" data-gizmo="scale" title="Scale (R)"
136
+ @click=${() => this._setGizmoMode('scale')}>
137
+ <svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8">
138
+ <line x1="4" y1="16" x2="16" y2="4"/>
139
+ <rect x="2" y="13" width="4" height="4" rx="0.5" fill="currentColor"/>
140
+ <rect x="14" y="2" width="4" height="4" rx="0.5" fill="currentColor"/>
141
+ </svg>
142
+ </span>
143
+ ` : ''}
159
144
 
160
145
  <span class="vline"></span>
161
146
 
162
- <span button id="font-increase" title="increase font size"></span>
163
- <span button id="font-decrease" title="decrease font size"></span>
147
+ <span button id="font-increase" title="increase font size" @click=${this.onTapFontIncrease}></span>
148
+ <span button id="font-decrease" title="decrease font size" style="scale: 0.7;" @click=${this.onTapFontDecrease}></span>
164
149
 
165
150
  <span class="vline"></span>
166
151
  <span>(v${process.env['APP-VERSION']})</span>
167
152
  <span padding></span>
168
153
 
169
- <span button id="fit-scene" title="fit scene (${this.getShortcutString('cmd', 'd')})"> </span>
154
+ <span button id="fit-scene" title="fit scene (${this.getShortcutString('cmd', 'd')})" @click=${this.onTapFitScene}> </span>
170
155
 
171
156
  <span class="vline"></span>
172
157
 
173
- <span button id="preview" title="preview (${this.getShortcutString('ctrl', 'p')})"> </span>
158
+ <span button id="preview" title="preview (${this.getShortcutString('ctrl', 'p')})" @click=${this.onTapPreview}> </span>
174
159
 
175
- <span button id="fullscreen" title="fullscreen (${this.getShortcutString('f11')})"> </span>
160
+ <span button id="fullscreen" title="fullscreen (${this.getShortcutString('f11')})" @click=${this.onTapFullscreen}> </span>
176
161
 
177
- <span
178
- button
179
- id="toggle-property"
162
+ <span button id="toggle-property"
180
163
  title="toggle property panel (${this.getShortcutString('cmd', 'h')})"
181
- toggles="true"
182
- >
183
- </span>
164
+ toggles="true" @click=${this.onTapToggle}> </span>
184
165
  </div>
185
166
  `;
186
167
  }
@@ -227,7 +208,7 @@ export class EditToolbar extends LitElement {
227
208
  return symbols.join(MACOS ? '' : '+');
228
209
  }
229
210
  onShortcut(e) {
230
- var _a, _b, _c, _d;
211
+ var _a, _b, _c, _d, _e, _f;
231
212
  if (MACOS)
232
213
  var ctrlKey = e.metaKey;
233
214
  else
@@ -246,6 +227,14 @@ export class EditToolbar extends LitElement {
246
227
  if (ctrlKey && !shiftKey)
247
228
  this.onTapRedo();
248
229
  break;
230
+ case 'Digit1':
231
+ if (ctrlKey)
232
+ this.onStartStylePasteMode();
233
+ break;
234
+ case 'Digit2':
235
+ if (ctrlKey)
236
+ this.onStartDatabindPasteMode();
237
+ break;
249
238
  case 'KeyC':
250
239
  if (ctrlKey && !shiftKey)
251
240
  this.onTapCopy();
@@ -270,31 +259,31 @@ export class EditToolbar extends LitElement {
270
259
  defaultPrevent = true;
271
260
  break;
272
261
  case 'KeyG':
273
- if (ctrlKey && !shiftKey)
274
- this.onTapGroup();
275
- else if (ctrlKey && shiftKey)
276
- this.onTapUngroup();
262
+ if (this._dimension === '2d') {
263
+ if (ctrlKey && !shiftKey)
264
+ this.onTapGroup();
265
+ else if (ctrlKey && shiftKey)
266
+ this.onTapUngroup();
267
+ }
277
268
  break;
278
269
  case 'KeyF':
279
- if (ctrlKey && !shiftKey)
280
- (_a = this.scene) === null || _a === void 0 ? void 0 : _a.zorder('forward');
281
- else if (ctrlKey && shiftKey)
282
- (_b = this.scene) === null || _b === void 0 ? void 0 : _b.zorder('front');
270
+ if (this._dimension === '2d') {
271
+ if (ctrlKey && !shiftKey)
272
+ (_a = this.scene) === null || _a === void 0 ? void 0 : _a.zorder('forward');
273
+ else if (ctrlKey && shiftKey)
274
+ (_b = this.scene) === null || _b === void 0 ? void 0 : _b.zorder('front');
275
+ }
283
276
  break;
284
277
  case 'KeyB':
285
- if (ctrlKey && !shiftKey)
286
- (_c = this.scene) === null || _c === void 0 ? void 0 : _c.zorder('backward');
287
- else if (ctrlKey && shiftKey)
288
- (_d = this.scene) === null || _d === void 0 ? void 0 : _d.zorder('back');
289
- else if (altKey && shiftKey)
278
+ if (this._dimension === '2d') {
279
+ if (ctrlKey && !shiftKey)
280
+ (_c = this.scene) === null || _c === void 0 ? void 0 : _c.zorder('backward');
281
+ else if (ctrlKey && shiftKey)
282
+ (_d = this.scene) === null || _d === void 0 ? void 0 : _d.zorder('back');
283
+ }
284
+ if (altKey && shiftKey)
290
285
  this.onTapAlign('bottom');
291
286
  break;
292
- // case 'Equal':
293
- // if (ctrlKey) this.onTapZoom(zoomin)
294
- // break
295
- // case 'Minus':
296
- // if (ctrlKey) this.onTapZoom(zoomout)
297
- // break
298
287
  case 'KeyH':
299
288
  if (ctrlKey && !shiftKey)
300
289
  this.onTapToggle();
@@ -341,17 +330,10 @@ export class EditToolbar extends LitElement {
341
330
  if (ctrlKey && shiftKey)
342
331
  this.onTapDownloadModel();
343
332
  break;
344
- case 'Digit1':
345
- if (ctrlKey) {
346
- console.log('MODEL', this.scene && this.scene.model);
347
- defaultPrevent = true;
348
- }
349
- break;
350
- case 'Digit2':
351
- if (ctrlKey) {
352
- console.log('SELECTED', this.scene && this.scene.selected);
353
- defaultPrevent = true;
354
- }
333
+ case 'Escape':
334
+ (_e = this.scene) === null || _e === void 0 ? void 0 : _e.stopStylePasteMode();
335
+ (_f = this.scene) === null || _f === void 0 ? void 0 : _f.stopDatabindPasteMode();
336
+ defaultPrevent = true;
355
337
  break;
356
338
  default:
357
339
  return false;
@@ -360,46 +342,75 @@ export class EditToolbar extends LitElement {
360
342
  e.preventDefault();
361
343
  return true;
362
344
  }
345
+ _setDisabled(id, disabled) {
346
+ const el = this.renderRoot.querySelector(`#${id}`);
347
+ disabled ? el === null || el === void 0 ? void 0 : el.setAttribute('disabled', '') : el === null || el === void 0 ? void 0 : el.removeAttribute('disabled');
348
+ }
363
349
  onExecute(command, undoable, redoable) {
364
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
365
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
350
+ this._setDisabled('undo', !undoable);
351
+ this._setDisabled('redo', !redoable);
366
352
  }
367
353
  onUndo(undoable, redoable) {
368
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
369
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
354
+ this._setDisabled('undo', !undoable);
355
+ this._setDisabled('redo', !redoable);
370
356
  }
371
357
  onRedo(undoable, redoable) {
372
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
373
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
358
+ this._setDisabled('undo', !undoable);
359
+ this._setDisabled('redo', !redoable);
374
360
  }
375
361
  onSceneChanged(after, before) {
362
+ var _a, _b;
376
363
  if (before) {
377
364
  before.off('execute', this.onExecute, this);
378
365
  before.off('undo', this.onUndo, this);
379
366
  before.off('redo', this.onRedo, this);
367
+ before.off('dimension', this._onDimensionChanged, this);
368
+ before.off('gizmoattach', this._onGizmoAttachChanged, this);
380
369
  }
381
370
  if (after) {
382
371
  after.on('execute', this.onExecute, this);
383
372
  after.on('undo', this.onUndo, this);
384
373
  after.on('redo', this.onRedo, this);
374
+ after.on('dimension', this._onDimensionChanged, this);
375
+ after.on('gizmoattach', this._onGizmoAttachChanged, this);
376
+ // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)
377
+ const threed = (_b = (_a = after.model_layer) === null || _a === void 0 ? void 0 : _a.model) === null || _b === void 0 ? void 0 : _b.threed;
378
+ this._dimension = threed ? '3d' : '2d';
385
379
  }
386
380
  }
387
- // @query('#align-left') private alignLeft!: HTMLElement
388
- // @query('#align-center') private alignCenter!: HTMLElement
389
- // @query('#align-right') private alignRight!: HTMLElement
390
- // @query('#align-top') private alignTop!: HTMLElement
391
- // @query('#align-middle') private alignMiddle!: HTMLElement
392
- // @query('#align-bottom') private alignBottom!: HTMLElement
381
+ _onDimensionChanged(dimension) {
382
+ this._dimension = dimension;
383
+ }
384
+ _onGizmoAttachChanged(isAttached) {
385
+ this._gizmoAttached = isAttached;
386
+ }
387
+ _setGizmoMode(mode) {
388
+ var _a, _b;
389
+ ;
390
+ (_b = (_a = this.scene) === null || _a === void 0 ? void 0 : _a.root) === null || _b === void 0 ? void 0 : _b.setGizmoMode(mode);
391
+ }
393
392
  onSelectedChanged(after, before) {
393
+ var hasSelection = after.length > 0;
394
394
  var alignable = after.length > 1;
395
- this.aligners.forEach(aligner => alignable ? aligner.removeAttribute('disabled') : aligner.setAttribute('disabled', ''));
396
- var movable = after.length === 1;
397
- /* forward, backward 이동은 한 컴포넌트만 가능하다. */
398
- !movable ? this.forward.setAttribute('disabled', '') : this.forward.removeAttribute('disabled');
399
- !movable ? this.backward.setAttribute('disabled', '') : this.backward.removeAttribute('disabled');
400
- /* 여러 컴포넌트는 front, back 이동이 가능하다. */
401
- !(alignable || movable) ? this.front.setAttribute('disabled', '') : this.front.removeAttribute('disabled');
402
- !(alignable || movable) ? this.back.setAttribute('disabled', '') : this.back.removeAttribute('disabled');
395
+ ['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id => this._setDisabled(id, !hasSelection));
396
+ // 정렬 버튼
397
+ this.renderRoot.querySelectorAll('[data-align]').forEach(el => alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', ''));
398
+ if (this._dimension === '2d') {
399
+ var movable = after.length === 1;
400
+ /* forward, backward 이동은 한 컴포넌트만 가능하다. */
401
+ this._setDisabled('forward', !movable);
402
+ this._setDisabled('backward', !movable);
403
+ /* 여러 컴포넌트는 front, back 이동이 가능하다. */
404
+ this._setDisabled('front', !(alignable || movable));
405
+ this._setDisabled('back', !(alignable || movable));
406
+ }
407
+ // 분배 버튼
408
+ this.renderRoot.querySelectorAll('[data-distribute]').forEach(el => alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', ''));
409
+ if (this._dimension === '3d') {
410
+ this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {
411
+ hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '');
412
+ });
413
+ }
403
414
  }
404
415
  onTapUndo() {
405
416
  var _a;
@@ -409,6 +420,22 @@ export class EditToolbar extends LitElement {
409
420
  var _a;
410
421
  (_a = this.scene) === null || _a === void 0 ? void 0 : _a.redo();
411
422
  }
423
+ onStartStylePasteMode() {
424
+ var _a, _b, _c;
425
+ if (((_a = this.selected) === null || _a === void 0 ? void 0 : _a.length) !== 1)
426
+ return;
427
+ if (this.selected[0] === ((_b = this.scene) === null || _b === void 0 ? void 0 : _b.root))
428
+ return;
429
+ (_c = this.scene) === null || _c === void 0 ? void 0 : _c.startStylePasteMode();
430
+ }
431
+ onStartDatabindPasteMode() {
432
+ var _a, _b, _c;
433
+ if (((_a = this.selected) === null || _a === void 0 ? void 0 : _a.length) !== 1)
434
+ return;
435
+ if (this.selected[0] === ((_b = this.scene) === null || _b === void 0 ? void 0 : _b.root))
436
+ return;
437
+ (_c = this.scene) === null || _c === void 0 ? void 0 : _c.startDatabindPasteMode();
438
+ }
412
439
  onTapCut() {
413
440
  var _a;
414
441
  (_a = this.scene) === null || _a === void 0 ? void 0 : _a.cut();
@@ -476,10 +503,16 @@ export class EditToolbar extends LitElement {
476
503
  if (!this.scene)
477
504
  return;
478
505
  var selected = this.scene.selected;
479
- if (selected.length <= 1)
480
- return;
481
506
  var align = typeof e === 'string' ? e : e.target.getAttribute('data-align');
482
- align && this.scene.align(align);
507
+ if (!align) {
508
+ return;
509
+ }
510
+ if (selected.length <= 1) {
511
+ this.scene.place(align);
512
+ }
513
+ else {
514
+ this.scene.align(align);
515
+ }
483
516
  }
484
517
  onTapZorder(e) {
485
518
  if (!this.scene)
@@ -541,45 +574,9 @@ __decorate([
541
574
  property({ type: Boolean })
542
575
  ], EditToolbar.prototype, "hideProperty", void 0);
543
576
  __decorate([
544
- query('#redo')
545
- ], EditToolbar.prototype, "redo", void 0);
546
- __decorate([
547
- query('#undo')
548
- ], EditToolbar.prototype, "undo", void 0);
549
- __decorate([
550
- query('#fullscreen')
551
- ], EditToolbar.prototype, "fullscreen", void 0);
552
- __decorate([
553
- query('#cut')
554
- ], EditToolbar.prototype, "cut", void 0);
555
- __decorate([
556
- query('#copy')
557
- ], EditToolbar.prototype, "copy", void 0);
558
- __decorate([
559
- query('#paste')
560
- ], EditToolbar.prototype, "paste", void 0);
561
- __decorate([
562
- query('#delete')
563
- ], EditToolbar.prototype, "delete", void 0);
564
- __decorate([
565
- query('#forward')
566
- ], EditToolbar.prototype, "forward", void 0);
567
- __decorate([
568
- query('#backward')
569
- ], EditToolbar.prototype, "backward", void 0);
570
- __decorate([
571
- query('#front')
572
- ], EditToolbar.prototype, "front", void 0);
573
- __decorate([
574
- query('#back')
575
- ], EditToolbar.prototype, "back", void 0);
576
- __decorate([
577
- queryAll('[data-align]')
578
- ], EditToolbar.prototype, "aligners", void 0);
579
- __decorate([
580
- queryAll('[data-zorder]')
581
- ], EditToolbar.prototype, "zorders", void 0);
577
+ state()
578
+ ], EditToolbar.prototype, "_dimension", void 0);
582
579
  __decorate([
583
- queryAll('[data-distribute]')
584
- ], EditToolbar.prototype, "distributes", void 0);
580
+ state()
581
+ ], EditToolbar.prototype, "_gizmoAttached", void 0);
585
582
  //# sourceMappingURL=edit-toolbar.js.map