@operato/board 10.0.0-beta.2 → 10.0.0-beta.21

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 (31) hide show
  1. package/CHANGELOG.md +175 -0
  2. package/dist/src/data-storage/board-model-cache.d.ts +30 -0
  3. package/dist/src/data-storage/board-model-cache.js +93 -0
  4. package/dist/src/data-storage/board-model-cache.js.map +1 -0
  5. package/dist/src/graphql/playback-subscription.d.ts +74 -0
  6. package/dist/src/graphql/playback-subscription.js +191 -0
  7. package/dist/src/graphql/playback-subscription.js.map +1 -0
  8. package/dist/src/index.d.ts +2 -0
  9. package/dist/src/index.js +1 -0
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/modeller/edit-toolbar-style.js +38 -1
  12. package/dist/src/modeller/edit-toolbar-style.js.map +1 -1
  13. package/dist/src/modeller/edit-toolbar.d.ts +7 -16
  14. package/dist/src/modeller/edit-toolbar.js +197 -199
  15. package/dist/src/modeller/edit-toolbar.js.map +1 -1
  16. package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +2 -1
  17. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +7 -11
  18. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -1
  19. package/dist/src/ox-board-modeller.d.ts +5 -1
  20. package/dist/src/ox-board-modeller.js +82 -5
  21. package/dist/src/ox-board-modeller.js.map +1 -1
  22. package/dist/src/ox-board-viewer.d.ts +50 -1
  23. package/dist/src/ox-board-viewer.js +269 -25
  24. package/dist/src/ox-board-viewer.js.map +1 -1
  25. package/dist/src/ox-playback-controls.d.ts +48 -0
  26. package/dist/src/ox-playback-controls.js +419 -0
  27. package/dist/src/ox-playback-controls.js.map +1 -0
  28. package/dist/src/selector/ox-board-selector.js +11 -1
  29. package/dist/src/selector/ox-board-selector.js.map +1 -1
  30. package/dist/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +12 -12
@@ -1 +1 @@
1
- {"version":3,"file":"edit-toolbar-style.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar-style.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiOvB,CAAA","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css } from 'lit'\n\nexport const style = css`\n :host {\n background-color: var(--edit-toolbar-background-color, var(--md-sys-color-secondary, #394e64));\n\n overflow-x: hidden;\n }\n\n [tools] {\n display: flex;\n align-items: center;\n overflow: none;\n padding: 0px 10px;\n }\n\n [tools] > * {\n padding: 0px;\n }\n\n [tools] > span[button] {\n min-width: 30px;\n }\n\n [tools] > span[padding] {\n flex: 1;\n }\n\n [tools] > .vline {\n display: block;\n flex: none;\n border-left: 1px solid rgba(255, 255, 255, 0.2);\n border-right: 1px solid rgba(0, 0, 0, 0.15);\n width: 0px;\n height: 18px;\n margin: 0 3px;\n }\n\n span[button] {\n min-height: 35px;\n\n background: var(--url-icon-htoolbar) no-repeat;\n background-position-x: 50%;\n opacity: 0.8;\n }\n span[button]:hover {\n opacity: 1;\n background-color: rgba(0, 0, 0, 0.1);\n cursor: pointer;\n }\n\n #fullscreen,\n #toggle-property {\n flex: none;\n }\n\n #align-left {\n background-position-y: 8px;\n }\n\n #align-center {\n background-position-y: -42px;\n }\n\n #align-right {\n background-position-y: -92px;\n }\n\n #align-top {\n background-position-y: -142px;\n }\n\n #align-middle {\n background-position-y: -192px;\n }\n\n #align-bottom {\n background-position-y: -242px;\n }\n\n #undo {\n background-position-y: -592px;\n }\n\n #redo {\n background-position-y: -642px;\n }\n\n #front {\n background-position-y: -292px;\n }\n\n #back {\n background-position-y: -342px;\n }\n\n #forward {\n background-position-y: -392px;\n }\n\n #backward {\n background-position-y: -442px;\n }\n\n #symmetry-x {\n background-position-y: -492px;\n }\n\n #symmetry-y {\n background-position-y: -542px;\n }\n\n #group {\n background-position-y: -492px;\n }\n\n #ungroup {\n background-position-y: -542px;\n }\n\n #fullscreen {\n background-position-y: -692px;\n }\n\n #toggle-property {\n background-position-y: -692px;\n float: right;\n }\n\n #zoomin {\n background-position-y: -742px;\n }\n\n #zoomout {\n background-position-y: -792px;\n }\n\n #fit-scene {\n background-position-y: -1492px;\n }\n\n #cut {\n background-position-y: -842px;\n }\n\n #copy {\n background-position-y: -892px;\n }\n\n #paste {\n background-position-y: -942px;\n }\n\n #delete {\n background-position-y: -992px;\n }\n\n #font-increase {\n background-position-y: -1042px;\n }\n\n #font-decrease {\n background-position-y: -1092px;\n }\n\n #style-copy {\n background-position-y: -1142px;\n }\n\n #databind-copy {\n background-position-y: -1692px;\n }\n\n #context-menu {\n background-position-y: -692px;\n }\n\n #symmetry-x {\n background-position-y: -1192px;\n }\n\n #symmetry-y {\n background-position-y: -1242px;\n }\n\n #rotate-cw {\n background-position-y: -1292px;\n }\n\n #rotate-ccw {\n background-position-y: -1342px;\n }\n\n #distribute-horizontal {\n background-position-y: -1542px;\n }\n\n #distribute-vertical {\n background-position-y: -1593px;\n }\n\n #toggle-property {\n background-position-y: -1392px;\n }\n\n #preview {\n background-position-y: -1640px;\n }\n\n /* bigger buttons */\n #fullscreen {\n background: var(--url-icon-fullscreen) 50% 10px no-repeat;\n width: var(--edit-toolbar-bigger-icon-size);\n height: var(--edit-toolbar-bigger-icon-size);\n border-left: var(--edit-toolbar-bigger-icon-line);\n }\n\n #toggle-property {\n background: var(--url-icon-collapse) 80% 10px no-repeat;\n width: var(--edit-toolbar-bigger-icon-size);\n height: var(--edit-toolbar-bigger-icon-size);\n border-left: var(--edit-toolbar-bigger-icon-line);\n }\n\n #toggle-property[active] {\n background: var(--url-icon-collapse-active) 80% 10px no-repeat;\n }\n`\n"]}
1
+ {"version":3,"file":"edit-toolbar-style.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar-style.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsQvB,CAAA","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css } from 'lit'\n\nexport const style = css`\n :host {\n background-color: var(--edit-toolbar-background-color, var(--md-sys-color-secondary, #394e64));\n\n overflow-x: hidden;\n }\n\n [tools] {\n display: flex;\n align-items: center;\n overflow: hidden;\n padding: 0px 10px;\n }\n\n [tools] > * {\n padding: 0px;\n }\n\n [tools] > span[button] {\n min-width: 30px;\n }\n\n [tools] > span[padding] {\n flex: 1;\n }\n\n [tools] > .vline {\n display: block;\n flex: none;\n border-left: 1px solid rgba(255, 255, 255, 0.2);\n border-right: 1px solid rgba(0, 0, 0, 0.15);\n width: 0px;\n height: 18px;\n margin: 0 3px;\n }\n\n span[button] {\n min-height: 35px;\n\n background: var(--url-icon-htoolbar) no-repeat;\n background-position-x: 50%;\n opacity: 0.8;\n }\n span[button]:hover {\n opacity: 1;\n background-color: rgba(0, 0, 0, 0.1);\n cursor: pointer;\n }\n\n #fullscreen,\n #toggle-property {\n flex: none;\n }\n\n #align-left {\n background-position-y: 8px;\n }\n\n #align-center {\n background-position-y: -42px;\n }\n\n #align-right {\n background-position-y: -92px;\n }\n\n #align-top {\n background-position-y: -142px;\n }\n\n #align-middle {\n background-position-y: -192px;\n }\n\n #align-bottom {\n background-position-y: -242px;\n }\n\n #undo {\n background-position-y: -592px;\n }\n\n #redo {\n background-position-y: -642px;\n }\n\n #front {\n background-position-y: -292px;\n }\n\n #back {\n background-position-y: -342px;\n }\n\n #forward {\n background-position-y: -392px;\n }\n\n #backward {\n background-position-y: -442px;\n }\n\n #symmetry-x {\n background-position-y: -492px;\n }\n\n #symmetry-y {\n background-position-y: -542px;\n }\n\n #group {\n background-position-y: -492px;\n }\n\n #ungroup {\n background-position-y: -542px;\n }\n\n #fullscreen {\n background-position-y: -692px;\n }\n\n #toggle-property {\n background-position-y: -692px;\n float: right;\n }\n\n #zoomin {\n background-position-y: -742px;\n }\n\n #zoomout {\n background-position-y: -792px;\n }\n\n #fit-scene {\n background-position-y: -1492px;\n }\n\n #cut {\n background-position-y: -842px;\n }\n\n #copy {\n background-position-y: -892px;\n }\n\n #paste {\n background-position-y: -942px;\n }\n\n #delete {\n background-position-y: -992px;\n }\n\n #font-increase {\n background-position-y: -1042px;\n }\n\n #font-decrease {\n background-position-y: -1092px;\n }\n\n #style-copy {\n background-position-y: -1142px;\n }\n\n #databind-copy {\n background-position-y: -1692px;\n }\n\n #context-menu {\n background-position-y: -692px;\n }\n\n #symmetry-x {\n background-position-y: -1192px;\n }\n\n #symmetry-y {\n background-position-y: -1242px;\n }\n\n #rotate-cw {\n background-position-y: -1292px;\n }\n\n #rotate-ccw {\n background-position-y: -1342px;\n }\n\n #distribute-horizontal {\n background-position-y: -1542px;\n }\n\n #distribute-vertical {\n background-position-y: -1593px;\n }\n\n #align-z-front {\n background-position-y: -142px;\n filter: hue-rotate(180deg);\n }\n\n #align-z-middle {\n background-position-y: -192px;\n filter: hue-rotate(180deg);\n }\n\n #align-z-back {\n background-position-y: -242px;\n filter: hue-rotate(180deg);\n }\n\n #distribute-z {\n background-position-y: -1593px;\n filter: hue-rotate(180deg);\n }\n\n .gizmo-btn {\n background: none !important;\n color: rgba(255, 255, 255, 0.5);\n min-width: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n border-radius: 3px;\n padding: 2px;\n }\n\n .gizmo-btn[disabled] {\n opacity: 0.3;\n pointer-events: none;\n }\n\n #toggle-property {\n background-position-y: -1392px;\n }\n\n #preview {\n background-position-y: -1640px;\n }\n\n /* bigger buttons */\n #fullscreen {\n background: var(--url-icon-fullscreen) 50% 10px no-repeat;\n width: var(--edit-toolbar-bigger-icon-size);\n height: var(--edit-toolbar-bigger-icon-size);\n border-left: var(--edit-toolbar-bigger-icon-line);\n }\n\n #toggle-property {\n background: var(--url-icon-collapse) 80% 10px no-repeat;\n width: var(--edit-toolbar-bigger-icon-size);\n height: var(--edit-toolbar-bigger-icon-size);\n border-left: var(--edit-toolbar-bigger-icon-line);\n }\n\n #toggle-property[active] {\n background: var(--url-icon-collapse-active) 80% 10px no-repeat;\n }\n`\n"]}
@@ -8,23 +8,9 @@ export declare class EditToolbar extends LitElement {
8
8
  scene?: Scene;
9
9
  selected: any[];
10
10
  hideProperty: boolean;
11
+ private _dimension;
12
+ private _gizmoAttached;
11
13
  private cliped?;
12
- private redo;
13
- private undo;
14
- private fullscreen;
15
- private styleCopy;
16
- private databindCopy;
17
- private cut;
18
- private copy;
19
- private paste;
20
- private delete;
21
- private forward;
22
- private backward;
23
- private front;
24
- private back;
25
- private aligners;
26
- private zorders;
27
- private distributes;
28
14
  firstUpdated(): void;
29
15
  updated(changes: PropertyValues<this>): void;
30
16
  render(): import("lit-html").TemplateResult<1>;
@@ -32,10 +18,14 @@ export declare class EditToolbar extends LitElement {
32
18
  getSymbol(key: string): string;
33
19
  private getShortcutString;
34
20
  onShortcut(e: KeyboardEvent): boolean;
21
+ private _setDisabled;
35
22
  onExecute(command: string, undoable: boolean, redoable: boolean): void;
36
23
  onUndo(undoable: boolean, redoable: boolean): void;
37
24
  onRedo(undoable: boolean, redoable: boolean): void;
38
25
  onSceneChanged(after?: Scene, before?: Scene): void;
26
+ private _onDimensionChanged;
27
+ private _onGizmoAttachChanged;
28
+ private _setGizmoMode;
39
29
  onSelectedChanged(after: Component[], before: Component[]): void;
40
30
  onTapUndo(): void;
41
31
  onTapRedo(): void;
@@ -56,6 +46,7 @@ export declare class EditToolbar extends LitElement {
56
46
  onTapToggle(): void;
57
47
  onTapFitScene(): void;
58
48
  onTapPreview(): void;
49
+ onTapDataBinding(): void;
59
50
  onTapDownloadModel(): void;
60
51
  onTapDistribute(e: TouchEvent | string): void;
61
52
  }
@@ -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>
158
110
 
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>
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>
115
+
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,6 +318,14 @@ 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)
@@ -342,16 +333,19 @@ export class EditToolbar extends LitElement {
342
333
  break;
343
334
  case 'Digit1':
344
335
  if (ctrlKey) {
345
- console.log('MODEL', this.scene && this.scene.model);
346
336
  defaultPrevent = true;
347
337
  }
348
338
  break;
349
339
  case 'Digit2':
350
340
  if (ctrlKey) {
351
- console.log('SELECTED', this.scene && this.scene.selected);
352
341
  defaultPrevent = true;
353
342
  }
354
343
  break;
344
+ case 'Escape':
345
+ (_e = this.scene) === null || _e === void 0 ? void 0 : _e.stopStylePasteMode();
346
+ (_f = this.scene) === null || _f === void 0 ? void 0 : _f.stopDatabindPasteMode();
347
+ defaultPrevent = true;
348
+ break;
355
349
  default:
356
350
  return false;
357
351
  }
@@ -359,40 +353,75 @@ export class EditToolbar extends LitElement {
359
353
  e.preventDefault();
360
354
  return true;
361
355
  }
356
+ _setDisabled(id, disabled) {
357
+ const el = this.renderRoot.querySelector(`#${id}`);
358
+ disabled ? el === null || el === void 0 ? void 0 : el.setAttribute('disabled', '') : el === null || el === void 0 ? void 0 : el.removeAttribute('disabled');
359
+ }
362
360
  onExecute(command, undoable, redoable) {
363
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
364
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
361
+ this._setDisabled('undo', !undoable);
362
+ this._setDisabled('redo', !redoable);
365
363
  }
366
364
  onUndo(undoable, redoable) {
367
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
368
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
365
+ this._setDisabled('undo', !undoable);
366
+ this._setDisabled('redo', !redoable);
369
367
  }
370
368
  onRedo(undoable, redoable) {
371
- !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled');
372
- !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled');
369
+ this._setDisabled('undo', !undoable);
370
+ this._setDisabled('redo', !redoable);
373
371
  }
374
372
  onSceneChanged(after, before) {
373
+ var _a, _b;
375
374
  if (before) {
376
375
  before.off('execute', this.onExecute, this);
377
376
  before.off('undo', this.onUndo, this);
378
377
  before.off('redo', this.onRedo, this);
378
+ before.off('dimension', this._onDimensionChanged, this);
379
+ before.off('gizmoattach', this._onGizmoAttachChanged, this);
379
380
  }
380
381
  if (after) {
381
382
  after.on('execute', this.onExecute, this);
382
383
  after.on('undo', this.onUndo, this);
383
384
  after.on('redo', this.onRedo, this);
385
+ after.on('dimension', this._onDimensionChanged, this);
386
+ after.on('gizmoattach', this._onGizmoAttachChanged, this);
387
+ // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)
388
+ const threed = (_b = (_a = after.model_layer) === null || _a === void 0 ? void 0 : _a.model) === null || _b === void 0 ? void 0 : _b.threed;
389
+ this._dimension = threed ? '3d' : '2d';
384
390
  }
385
391
  }
392
+ _onDimensionChanged(dimension) {
393
+ this._dimension = dimension;
394
+ }
395
+ _onGizmoAttachChanged(isAttached) {
396
+ this._gizmoAttached = isAttached;
397
+ }
398
+ _setGizmoMode(mode) {
399
+ var _a, _b;
400
+ ;
401
+ (_b = (_a = this.scene) === null || _a === void 0 ? void 0 : _a.root) === null || _b === void 0 ? void 0 : _b.setGizmoMode(mode);
402
+ }
386
403
  onSelectedChanged(after, before) {
404
+ var hasSelection = after.length > 0;
387
405
  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');
406
+ ['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id => this._setDisabled(id, !hasSelection));
407
+ // 정렬 버튼
408
+ this.renderRoot.querySelectorAll('[data-align]').forEach(el => alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', ''));
409
+ if (this._dimension === '2d') {
410
+ var movable = after.length === 1;
411
+ /* forward, backward 이동은 컴포넌트만 가능하다. */
412
+ this._setDisabled('forward', !movable);
413
+ this._setDisabled('backward', !movable);
414
+ /* 여러 컴포넌트는 front, back 이동이 가능하다. */
415
+ this._setDisabled('front', !(alignable || movable));
416
+ this._setDisabled('back', !(alignable || movable));
417
+ }
418
+ // 분배 버튼
419
+ this.renderRoot.querySelectorAll('[data-distribute]').forEach(el => alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', ''));
420
+ if (this._dimension === '3d') {
421
+ this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {
422
+ hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '');
423
+ });
424
+ }
396
425
  }
397
426
  onTapUndo() {
398
427
  var _a;
@@ -403,12 +432,20 @@ export class EditToolbar extends LitElement {
403
432
  (_a = this.scene) === null || _a === void 0 ? void 0 : _a.redo();
404
433
  }
405
434
  onStartStylePasteMode() {
406
- var _a;
407
- (_a = this.scene) === null || _a === void 0 ? void 0 : _a.startStylePasteMode();
435
+ var _a, _b, _c;
436
+ if (((_a = this.selected) === null || _a === void 0 ? void 0 : _a.length) !== 1)
437
+ return;
438
+ if (this.selected[0] === ((_b = this.scene) === null || _b === void 0 ? void 0 : _b.root))
439
+ return;
440
+ (_c = this.scene) === null || _c === void 0 ? void 0 : _c.startStylePasteMode();
408
441
  }
409
442
  onStartDatabindPasteMode() {
410
- var _a;
411
- (_a = this.scene) === null || _a === void 0 ? void 0 : _a.startDatabindPasteMode();
443
+ var _a, _b, _c;
444
+ if (((_a = this.selected) === null || _a === void 0 ? void 0 : _a.length) !== 1)
445
+ return;
446
+ if (this.selected[0] === ((_b = this.scene) === null || _b === void 0 ? void 0 : _b.root))
447
+ return;
448
+ (_c = this.scene) === null || _c === void 0 ? void 0 : _c.startDatabindPasteMode();
412
449
  }
413
450
  onTapCut() {
414
451
  var _a;
@@ -523,6 +560,9 @@ export class EditToolbar extends LitElement {
523
560
  onTapPreview() {
524
561
  this.dispatchEvent(new CustomEvent('open-preview'));
525
562
  }
563
+ onTapDataBinding() {
564
+ this.dispatchEvent(new CustomEvent('open-data-binding'));
565
+ }
526
566
  onTapDownloadModel() {
527
567
  this.dispatchEvent(new CustomEvent('download-model'));
528
568
  }
@@ -548,51 +588,9 @@ __decorate([
548
588
  property({ type: Boolean })
549
589
  ], EditToolbar.prototype, "hideProperty", void 0);
550
590
  __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);
591
+ state()
592
+ ], EditToolbar.prototype, "_dimension", void 0);
595
593
  __decorate([
596
- queryAll('[data-distribute]')
597
- ], EditToolbar.prototype, "distributes", void 0);
594
+ state()
595
+ ], EditToolbar.prototype, "_gizmoAttached", void 0);
598
596
  //# sourceMappingURL=edit-toolbar.js.map