@operato/board 0.2.44 → 0.2.48

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 (145) hide show
  1. package/@types/global/index.d.ts +1 -0
  2. package/CHANGELOG.md +57 -0
  3. package/assets/images/components/no-image.png +0 -0
  4. package/custom-elements.json +4272 -174
  5. package/demo/index-modeller.html +101 -0
  6. package/demo/index.html +3 -3
  7. package/dist/src/index.d.ts +1 -0
  8. package/dist/src/index.js +1 -0
  9. package/dist/src/index.js.map +1 -1
  10. package/dist/src/modeller/component-toolbar/component-detail.d.ts +4 -0
  11. package/dist/src/modeller/component-toolbar/component-detail.js +56 -0
  12. package/dist/src/modeller/component-toolbar/component-detail.js.map +1 -0
  13. package/dist/src/modeller/component-toolbar/component-menu.d.ts +4 -0
  14. package/dist/src/modeller/component-toolbar/component-menu.js +194 -0
  15. package/dist/src/modeller/component-toolbar/component-menu.js.map +1 -0
  16. package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +4 -0
  17. package/dist/src/modeller/component-toolbar/component-toolbar.js +170 -0
  18. package/dist/src/modeller/component-toolbar/component-toolbar.js.map +1 -0
  19. package/dist/src/modeller/edit-toolbar-style.d.ts +4 -0
  20. package/dist/src/modeller/edit-toolbar-style.js +227 -0
  21. package/dist/src/modeller/edit-toolbar-style.js.map +1 -0
  22. package/dist/src/modeller/edit-toolbar.d.ts +61 -0
  23. package/dist/src/modeller/edit-toolbar.js +644 -0
  24. package/dist/src/modeller/edit-toolbar.js.map +1 -0
  25. package/dist/src/modeller/property-sidebar/abstract-property.d.ts +10 -0
  26. package/dist/src/modeller/property-sidebar/abstract-property.js +58 -0
  27. package/dist/src/modeller/property-sidebar/abstract-property.js.map +1 -0
  28. package/dist/src/modeller/property-sidebar/data-binding/data-binding-mapper.d.ts +48 -0
  29. package/dist/src/modeller/property-sidebar/data-binding/data-binding-mapper.js +351 -0
  30. package/dist/src/modeller/property-sidebar/data-binding/data-binding-mapper.js.map +1 -0
  31. package/dist/src/modeller/property-sidebar/data-binding/data-binding.d.ts +8 -0
  32. package/dist/src/modeller/property-sidebar/data-binding/data-binding.js +432 -0
  33. package/dist/src/modeller/property-sidebar/data-binding/data-binding.js.map +1 -0
  34. package/dist/src/modeller/property-sidebar/effects/effects-shared-style.d.ts +4 -0
  35. package/dist/src/modeller/property-sidebar/effects/effects-shared-style.js +57 -0
  36. package/dist/src/modeller/property-sidebar/effects/effects-shared-style.js.map +1 -0
  37. package/dist/src/modeller/property-sidebar/effects/effects.d.ts +6 -0
  38. package/dist/src/modeller/property-sidebar/effects/effects.js +55 -0
  39. package/dist/src/modeller/property-sidebar/effects/effects.js.map +1 -0
  40. package/dist/src/modeller/property-sidebar/effects/property-animation.d.ts +22 -0
  41. package/dist/src/modeller/property-sidebar/effects/property-animation.js +127 -0
  42. package/dist/src/modeller/property-sidebar/effects/property-animation.js.map +1 -0
  43. package/dist/src/modeller/property-sidebar/effects/property-animations.d.ts +5 -0
  44. package/dist/src/modeller/property-sidebar/effects/property-animations.js +83 -0
  45. package/dist/src/modeller/property-sidebar/effects/property-animations.js.map +1 -0
  46. package/dist/src/modeller/property-sidebar/effects/property-event-hover.d.ts +4 -0
  47. package/dist/src/modeller/property-sidebar/effects/property-event-hover.js +124 -0
  48. package/dist/src/modeller/property-sidebar/effects/property-event-hover.js.map +1 -0
  49. package/dist/src/modeller/property-sidebar/effects/property-event-tap.d.ts +4 -0
  50. package/dist/src/modeller/property-sidebar/effects/property-event-tap.js +120 -0
  51. package/dist/src/modeller/property-sidebar/effects/property-event-tap.js.map +1 -0
  52. package/dist/src/modeller/property-sidebar/effects/property-event.d.ts +5 -0
  53. package/dist/src/modeller/property-sidebar/effects/property-event.js +59 -0
  54. package/dist/src/modeller/property-sidebar/effects/property-event.js.map +1 -0
  55. package/dist/src/modeller/property-sidebar/effects/property-shadow.d.ts +22 -0
  56. package/dist/src/modeller/property-sidebar/effects/property-shadow.js +106 -0
  57. package/dist/src/modeller/property-sidebar/effects/property-shadow.js.map +1 -0
  58. package/dist/src/modeller/property-sidebar/effects/value-converter.d.ts +1 -0
  59. package/dist/src/modeller/property-sidebar/effects/value-converter.js +23 -0
  60. package/dist/src/modeller/property-sidebar/effects/value-converter.js.map +1 -0
  61. package/dist/src/modeller/property-sidebar/inspector/inspector.d.ts +24 -0
  62. package/dist/src/modeller/property-sidebar/inspector/inspector.js +290 -0
  63. package/dist/src/modeller/property-sidebar/inspector/inspector.js.map +1 -0
  64. package/dist/src/modeller/property-sidebar/property-shared-style.d.ts +4 -0
  65. package/dist/src/modeller/property-sidebar/property-shared-style.js +131 -0
  66. package/dist/src/modeller/property-sidebar/property-shared-style.js.map +1 -0
  67. package/dist/src/modeller/property-sidebar/property-sidebar.d.ts +10 -0
  68. package/dist/src/modeller/property-sidebar/property-sidebar.js +313 -0
  69. package/dist/src/modeller/property-sidebar/property-sidebar.js.map +1 -0
  70. package/dist/src/modeller/property-sidebar/shapes/box-padding-editor-styles.d.ts +1 -0
  71. package/dist/src/modeller/property-sidebar/shapes/box-padding-editor-styles.js +94 -0
  72. package/dist/src/modeller/property-sidebar/shapes/box-padding-editor-styles.js.map +1 -0
  73. package/dist/src/modeller/property-sidebar/shapes/shapes.d.ts +6 -0
  74. package/dist/src/modeller/property-sidebar/shapes/shapes.js +406 -0
  75. package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -0
  76. package/dist/src/modeller/property-sidebar/specifics/specific-properties-builder.d.ts +4 -0
  77. package/dist/src/modeller/property-sidebar/specifics/specific-properties-builder.js +127 -0
  78. package/dist/src/modeller/property-sidebar/specifics/specific-properties-builder.js.map +1 -0
  79. package/dist/src/modeller/property-sidebar/specifics/specifics.d.ts +5 -0
  80. package/dist/src/modeller/property-sidebar/specifics/specifics.js +78 -0
  81. package/dist/src/modeller/property-sidebar/specifics/specifics.js.map +1 -0
  82. package/dist/src/modeller/property-sidebar/styles/styles.d.ts +8 -0
  83. package/dist/src/modeller/property-sidebar/styles/styles.js +562 -0
  84. package/dist/src/modeller/property-sidebar/styles/styles.js.map +1 -0
  85. package/dist/src/modeller/scene-viewer/confidential-overlay.d.ts +4 -0
  86. package/dist/src/modeller/scene-viewer/confidential-overlay.js +14 -0
  87. package/dist/src/modeller/scene-viewer/confidential-overlay.js.map +1 -0
  88. package/dist/src/modeller/scene-viewer/ox-scene-handler.d.ts +11 -0
  89. package/dist/src/modeller/scene-viewer/ox-scene-handler.js +36 -0
  90. package/dist/src/modeller/scene-viewer/ox-scene-handler.js.map +1 -0
  91. package/dist/src/modeller/scene-viewer/ox-scene-layer.d.ts +10 -0
  92. package/dist/src/modeller/scene-viewer/ox-scene-layer.js +42 -0
  93. package/dist/src/modeller/scene-viewer/ox-scene-layer.js.map +1 -0
  94. package/dist/src/modeller/scene-viewer/ox-scene-player.d.ts +1 -0
  95. package/dist/src/modeller/scene-viewer/ox-scene-player.js +99 -0
  96. package/dist/src/modeller/scene-viewer/ox-scene-player.js.map +1 -0
  97. package/dist/src/modeller/scene-viewer/ox-scene-property.d.ts +6 -0
  98. package/dist/src/modeller/scene-viewer/ox-scene-property.js +19 -0
  99. package/dist/src/modeller/scene-viewer/ox-scene-property.js.map +1 -0
  100. package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +39 -0
  101. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +245 -0
  102. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -0
  103. package/dist/src/ox-board-modeller.d.ts +13 -4
  104. package/dist/src/ox-board-modeller.js +130 -40
  105. package/dist/src/ox-board-modeller.js.map +1 -1
  106. package/dist/src/types.d.ts +12 -0
  107. package/dist/src/types.js +2 -0
  108. package/dist/src/types.js.map +1 -0
  109. package/dist/tsconfig.tsbuildinfo +1 -1
  110. package/package.json +26 -5
  111. package/src/index.ts +1 -0
  112. package/src/modeller/component-toolbar/component-detail.ts +53 -0
  113. package/src/modeller/component-toolbar/component-menu.ts +190 -0
  114. package/src/modeller/component-toolbar/component-toolbar.ts +161 -0
  115. package/src/modeller/edit-toolbar-style.ts +228 -0
  116. package/src/modeller/edit-toolbar.ts +640 -0
  117. package/src/modeller/property-sidebar/abstract-property.ts +73 -0
  118. package/src/modeller/property-sidebar/data-binding/data-binding-mapper.ts +371 -0
  119. package/src/modeller/property-sidebar/data-binding/data-binding.ts +449 -0
  120. package/src/modeller/property-sidebar/effects/effects-shared-style.ts +58 -0
  121. package/src/modeller/property-sidebar/effects/effects.ts +57 -0
  122. package/src/modeller/property-sidebar/effects/property-animation.ts +133 -0
  123. package/src/modeller/property-sidebar/effects/property-animations.ts +84 -0
  124. package/src/modeller/property-sidebar/effects/property-event-hover.ts +133 -0
  125. package/src/modeller/property-sidebar/effects/property-event-tap.ts +129 -0
  126. package/src/modeller/property-sidebar/effects/property-event.ts +65 -0
  127. package/src/modeller/property-sidebar/effects/property-shadow.ts +114 -0
  128. package/src/modeller/property-sidebar/effects/value-converter.ts +26 -0
  129. package/src/modeller/property-sidebar/inspector/inspector.ts +327 -0
  130. package/src/modeller/property-sidebar/property-shared-style.ts +132 -0
  131. package/src/modeller/property-sidebar/property-sidebar.ts +308 -0
  132. package/src/modeller/property-sidebar/shapes/box-padding-editor-styles.ts +94 -0
  133. package/src/modeller/property-sidebar/shapes/shapes.ts +409 -0
  134. package/src/modeller/property-sidebar/specifics/specific-properties-builder.ts +135 -0
  135. package/src/modeller/property-sidebar/specifics/specifics.ts +72 -0
  136. package/src/modeller/property-sidebar/styles/styles.ts +578 -0
  137. package/src/modeller/scene-viewer/confidential-overlay.ts +18 -0
  138. package/src/modeller/scene-viewer/ox-scene-handler.ts +40 -0
  139. package/src/modeller/scene-viewer/ox-scene-layer.ts +42 -0
  140. package/src/modeller/scene-viewer/ox-scene-player.ts +104 -0
  141. package/src/modeller/scene-viewer/ox-scene-property.ts +10 -0
  142. package/src/modeller/scene-viewer/ox-scene-viewer.ts +248 -0
  143. package/src/ox-board-modeller.ts +138 -42
  144. package/src/types.ts +26 -0
  145. package/yarn-error.log +18355 -0
@@ -0,0 +1,640 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import { Component, Scene } from '@hatiolab/things-scene'
6
+ import { LitElement, PropertyValues, html } from 'lit'
7
+ import { customElement, property, query, queryAll, state } from 'lit/decorators.js'
8
+
9
+ import { style } from './edit-toolbar-style'
10
+
11
+ const _isMacOS = navigator.userAgent.indexOf('Mac') != -1
12
+
13
+ @customElement('edit-toolbar')
14
+ export class EditToolbar extends LitElement {
15
+ static styles = [style]
16
+
17
+ @property({ type: Object }) scene?: Scene
18
+ @property({ type: Array }) selected: any[] = []
19
+ @property({ type: Boolean }) hideProperty: boolean = false
20
+
21
+ private cliped?: string
22
+
23
+ @query('#redo') private redo!: HTMLElement
24
+ @query('#undo') private undo!: HTMLElement
25
+
26
+ @query('#fullscreen') private fullscreen!: HTMLElement
27
+ @query('#cut') private cut!: HTMLElement
28
+ @query('#copy') private copy!: HTMLElement
29
+ @query('#paste') private paste!: HTMLElement
30
+ @query('#delete') private delete!: HTMLElement
31
+
32
+ @query('#forward') private forward!: HTMLElement
33
+ @query('#backward') private backward!: HTMLElement
34
+ @query('#front') private front!: HTMLElement
35
+ @query('#back') private back!: HTMLElement
36
+
37
+ @queryAll('[data-align]') private aligners!: NodeListOf<HTMLSpanElement>
38
+ @queryAll('[data-zorder]') private zorders!: NodeListOf<HTMLSpanElement>
39
+ @queryAll('[data-distribute]') private distributes!: NodeListOf<HTMLSpanElement>
40
+
41
+ firstUpdated() {
42
+ this.addEventListener('mousewheel', this.onWheelEvent.bind(this) as EventListener, false)
43
+
44
+ window.addEventListener('paste', (e: Event) => {
45
+ this.cliped = (e as ClipboardEvent).clipboardData?.getData('text/plain')
46
+ })
47
+
48
+ this.aligners.forEach(aligner => aligner.addEventListener('tap', this.onTapAlign.bind(this) as EventListener))
49
+ this.zorders.forEach(zorder => zorder.addEventListener('tap', this.onTapZorder.bind(this) as EventListener))
50
+ this.distributes.forEach(distribute =>
51
+ distribute.addEventListener('tap', this.onTapDistribute.bind(this) as EventListener)
52
+ )
53
+
54
+ this.undo.addEventListener('tap', this.onTapUndo.bind(this) as EventListener)
55
+ this.redo.addEventListener('tap', this.onTapRedo.bind(this) as EventListener)
56
+ this.fullscreen.addEventListener('tap', this.onTapFullscreen.bind(this) as EventListener)
57
+ this.cut.addEventListener('tap', this.onTapCut.bind(this) as EventListener)
58
+ this.copy.addEventListener('tap', this.onTapCopy.bind(this) as EventListener)
59
+ this.paste.addEventListener('tap', this.onTapPaste.bind(this) as EventListener)
60
+ this.delete.addEventListener('tap', this.onTapDelete.bind(this) as EventListener)
61
+
62
+ this.renderRoot
63
+ .querySelector('#font-increase')!
64
+ .addEventListener('tap', this.onTapFontIncrease.bind(this) as EventListener)
65
+ this.renderRoot
66
+ .querySelector('#font-decrease')!
67
+ .addEventListener('tap', this.onTapFontDecrease.bind(this) as EventListener)
68
+ this.renderRoot.querySelector('#group')!.addEventListener('tap', this.onTapGroup.bind(this) as EventListener)
69
+ this.renderRoot.querySelector('#ungroup')!.addEventListener('tap', this.onTapUngroup.bind(this) as EventListener)
70
+ this.renderRoot
71
+ .querySelector('#symmetry-x')!
72
+ .addEventListener('tap', this.onTapSymmetryX.bind(this) as EventListener)
73
+ this.renderRoot
74
+ .querySelector('#symmetry-y')!
75
+ .addEventListener('tap', this.onTapSymmetryY.bind(this) as EventListener)
76
+ this.renderRoot.querySelector('#rotate-cw')!.addEventListener('tap', this.onTapRotateCW.bind(this) as EventListener)
77
+ this.renderRoot
78
+ .querySelector('#rotate-ccw')!
79
+ .addEventListener('tap', this.onTapRotateCCW.bind(this) as EventListener)
80
+ this.renderRoot
81
+ .querySelector('#toggle-property')!
82
+ .addEventListener('tap', this.onTapToggle.bind(this) as EventListener)
83
+ this.renderRoot.querySelector('#fit-scene')!.addEventListener('tap', this.onTapFitScene.bind(this) as EventListener)
84
+ this.renderRoot.querySelector('#preview')!.addEventListener('tap', this.onTapPreview.bind(this) as EventListener)
85
+ }
86
+
87
+ updated(changes: PropertyValues<this>) {
88
+ changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene') as Scene)
89
+ changes.has('selected') && this.onSelectedChanged(this.selected, changes.get('selected') as Component[])
90
+ }
91
+
92
+ render() {
93
+ return html`
94
+ <div tools>
95
+ <span><slot></slot></span>
96
+
97
+ <span button id="undo" title="undo (${this.getShortcutString('cmd', 'z')})"> </span>
98
+ <span button id="redo" title="redo (${this.getShortcutString('cmd', 'shift', 'z')})"> </span>
99
+
100
+ <span class="vline"></span>
101
+
102
+ <span button id="cut" title="cut (${this.getShortcutString('cmd', 'x')})"> </span>
103
+ <span button id="copy" title="copy (${this.getShortcutString('cmd', 'c')})"> </span>
104
+ <span button id="paste" title="paste (${this.getShortcutString('cmd', 'v')})"> </span>
105
+ <span
106
+ button
107
+ id="delete"
108
+ title="delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})"
109
+ >
110
+ </span>
111
+
112
+ <span class="vline"></span>
113
+
114
+ <!-- TODO Implement style-copy
115
+ <span button id="style-copy" title="format painter"></span>
116
+ <span class="vline"></span>
117
+ -->
118
+
119
+ <span
120
+ button
121
+ data-align="left"
122
+ id="align-left"
123
+ title="align left (${this.getShortcutString('alt', 'shift', 'l')})"
124
+ >
125
+ </span>
126
+ <span
127
+ button
128
+ data-align="center"
129
+ id="align-center"
130
+ title="align center (${this.getShortcutString('alt', 'shift', 'c')})"
131
+ >
132
+ </span>
133
+ <span
134
+ button
135
+ data-align="right"
136
+ id="align-right"
137
+ title="align right (${this.getShortcutString('alt', 'shift', 'r')})"
138
+ >
139
+ </span>
140
+
141
+ <span button data-align="top" id="align-top" title="align top (${this.getShortcutString('alt', 'shift', 't')})">
142
+ </span>
143
+ <span
144
+ button
145
+ data-align="middle"
146
+ id="align-middle"
147
+ title="align middle (${this.getShortcutString('alt', 'shift', 'm')})"
148
+ >
149
+ </span>
150
+ <span
151
+ button
152
+ data-align="bottom"
153
+ id="align-bottom"
154
+ title="align bottom (${this.getShortcutString('alt', 'shift', 'b')})"
155
+ >
156
+ </span>
157
+
158
+ <span
159
+ button
160
+ data-distribute="HORIZONTAL"
161
+ id="distribute-horizontal"
162
+ title="distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})"
163
+ >
164
+ </span>
165
+
166
+ <span
167
+ button
168
+ data-distribute="VERTICAL"
169
+ id="distribute-vertical"
170
+ title="distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})"
171
+ >
172
+ </span>
173
+
174
+ <span class="vline"></span>
175
+
176
+ <span
177
+ button
178
+ id="front"
179
+ data-zorder="front"
180
+ title="bring to front (${this.getShortcutString('cmd', 'shift', 'f')})"
181
+ >
182
+ </span>
183
+ <span button id="back" data-zorder="back" title="send to back (${this.getShortcutString('cmd', 'shift', 'b')})">
184
+ </span>
185
+ <span button id="forward" data-zorder="forward" title="bring forward (${this.getShortcutString('cmd', 'f')})">
186
+ </span>
187
+ <span button id="backward" data-zorder="backward" title="send backward (${this.getShortcutString('cmd', 'b')})">
188
+ </span>
189
+
190
+ <span class="vline"></span>
191
+
192
+ <span button id="symmetry-x" title="symmetry-x (${this.getShortcutString('alt', 'shift', 'x')})"> </span>
193
+ <span button id="symmetry-y" title="symmetry-y (${this.getShortcutString('alt', 'shift', 'y')})"> </span>
194
+ <span button id="rotate-cw" title="rotate clockwise (${this.getShortcutString('alt', 'shift', 'e')})"> </span>
195
+ <span button id="rotate-ccw" title="rotate counter clockwise (${this.getShortcutString('alt', 'shift', 'w')})">
196
+ </span>
197
+
198
+ <span class="vline"></span>
199
+
200
+ <span button id="group" title="group (${this.getShortcutString('cmd', 'g')})"> </span>
201
+ <span button id="ungroup" title="ungroup (${this.getShortcutString('cmd', 'shift', 'g')})"> </span>
202
+
203
+ <span class="vline"></span>
204
+
205
+ <span button id="font-increase" title="increase font size"></span>
206
+ <span button id="font-decrease" title="decrease font size"></span>
207
+
208
+ <span class="vline"></span>
209
+ <span padding></span>
210
+
211
+ <span button id="fit-scene" title="fit scene (${this.getShortcutString('cmd', 'd')})"> </span>
212
+
213
+ <span class="vline"></span>
214
+
215
+ <span button id="preview" title="preview (${this.getShortcutString('ctrl', 'p')})"> </span>
216
+
217
+ <span button id="fullscreen" title="fullscreen (${this.getShortcutString('f11')})"> </span>
218
+
219
+ <span
220
+ button
221
+ id="toggle-property"
222
+ title="toggle property panel (${this.getShortcutString('cmd', 'h')})"
223
+ toggles="true"
224
+ >
225
+ </span>
226
+ </div>
227
+ `
228
+ }
229
+
230
+ onWheelEvent(e: Event) {
231
+ var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))
232
+ this.scrollLeft -= delta * 40
233
+
234
+ e.preventDefault()
235
+ }
236
+
237
+ getSymbol(key: string) {
238
+ var symbol
239
+ switch (key) {
240
+ case 'cmd':
241
+ case 'ctrl':
242
+ symbol = _isMacOS ? '⌘' : 'Ctrl'
243
+ break
244
+ case 'shift':
245
+ symbol = _isMacOS ? '⇧' : 'Shift'
246
+ break
247
+ case 'alt':
248
+ case 'option':
249
+ symbol = _isMacOS ? '⌥' : 'Alt'
250
+ break
251
+ case 'backspace':
252
+ symbol = _isMacOS ? '⌫' : 'BackSpace'
253
+ break
254
+ case 'delete':
255
+ symbol = _isMacOS ? '⌦' : 'Del'
256
+ break
257
+ default:
258
+ symbol = key.toUpperCase()
259
+ break
260
+ }
261
+
262
+ return symbol
263
+ }
264
+
265
+ private getShortcutString(...keys: string[]) {
266
+ var symbols = []
267
+ for (var i = 0; i < arguments.length; i++) {
268
+ symbols.push(this.getSymbol(arguments[i]))
269
+ }
270
+
271
+ return symbols.join(_isMacOS ? '' : '+')
272
+ }
273
+
274
+ onShortcut(e: KeyboardEvent) {
275
+ if (_isMacOS) var ctrlKey = e.metaKey
276
+ else var ctrlKey = e.ctrlKey
277
+
278
+ var altKey = e.altKey
279
+ var shiftKey = e.shiftKey
280
+
281
+ var defaultPrevent = ctrlKey || altKey
282
+
283
+ switch (e.code) {
284
+ case 'KeyZ':
285
+ if (ctrlKey && !shiftKey) this.onTapUndo()
286
+ else if (ctrlKey && shiftKey) this.onTapRedo()
287
+ break
288
+ case 'KeyY':
289
+ if (ctrlKey && !shiftKey) this.onTapRedo()
290
+ else if (altKey && shiftKey) this.onTapSymmetryY()
291
+ break
292
+ case 'KeyC':
293
+ if (ctrlKey && !shiftKey) this.onTapCopy()
294
+ else if (altKey && shiftKey) this.onTapAlign('center')
295
+ break
296
+ case 'KeyX':
297
+ if (ctrlKey && !shiftKey) this.onTapCut()
298
+ else if (altKey && shiftKey) this.onTapSymmetryX()
299
+ break
300
+ case 'KeyV':
301
+ if (ctrlKey && !shiftKey) {
302
+ this.onTapPaste()
303
+ defaultPrevent = false
304
+ } else if (altKey && shiftKey) this.onTapDistribute('VERTICAL')
305
+ break
306
+ case 'Delete':
307
+ case 'Backspace':
308
+ this.onTapDelete()
309
+ defaultPrevent = true
310
+ break
311
+ case 'KeyG':
312
+ if (ctrlKey && !shiftKey) this.onTapGroup()
313
+ else if (ctrlKey && shiftKey) this.onTapUngroup()
314
+ break
315
+ case 'KeyF':
316
+ if (ctrlKey && !shiftKey) this.scene?.zorder('forward')
317
+ else if (ctrlKey && shiftKey) this.scene?.zorder('front')
318
+ break
319
+ case 'KeyB':
320
+ if (ctrlKey && !shiftKey) this.scene?.zorder('backward')
321
+ else if (ctrlKey && shiftKey) this.scene?.zorder('back')
322
+ else if (altKey && shiftKey) this.onTapAlign('bottom')
323
+ break
324
+ // case 'Equal':
325
+ // if (ctrlKey) this.onTapZoom(zoomin)
326
+ // break
327
+ // case 'Minus':
328
+ // if (ctrlKey) this.onTapZoom(zoomout)
329
+ // break
330
+ case 'KeyH':
331
+ if (ctrlKey && !shiftKey) this.onTapToggle()
332
+ else if (altKey && shiftKey) this.onTapDistribute('HORIZONTAL')
333
+ break
334
+ case 'F11':
335
+ this.onTapFullscreen()
336
+ defaultPrevent = true
337
+ break
338
+ case 'KeyP':
339
+ if (ctrlKey) {
340
+ this.onTapPreview()
341
+ defaultPrevent = true
342
+ }
343
+ break
344
+ case 'KeyA':
345
+ if (ctrlKey) this.onTapSelectAll()
346
+ break
347
+ case 'KeyL':
348
+ if (altKey && shiftKey) this.onTapAlign('left')
349
+ break
350
+ case 'KeyR':
351
+ if (altKey && shiftKey) this.onTapAlign('right')
352
+ break
353
+ case 'KeyM':
354
+ if (altKey && shiftKey) this.onTapAlign('middle')
355
+ break
356
+ case 'KeyT':
357
+ if (altKey && shiftKey) this.onTapAlign('top')
358
+ break
359
+ case 'KeyY':
360
+ if (altKey && shiftKey) this.onTapSymmetryY()
361
+ break
362
+ case 'KeyD':
363
+ if (ctrlKey) {
364
+ this.onTapFitScene()
365
+ defaultPrevent = true
366
+ }
367
+ break
368
+ case 'KeyE':
369
+ if (altKey && shiftKey) this.onTapRotateCW()
370
+ else if (ctrlKey && shiftKey) this.onTapDownloadModel()
371
+ break
372
+ case 'KeyW':
373
+ if (altKey && shiftKey) this.onTapRotateCCW()
374
+ break
375
+ case 'Digit1':
376
+ if (ctrlKey) {
377
+ console.log('MODEL', this.scene && this.scene.model)
378
+ defaultPrevent = true
379
+ }
380
+ break
381
+ case 'Digit2':
382
+ if (ctrlKey) {
383
+ console.log('SELECTED', this.scene && this.scene.selected)
384
+ defaultPrevent = true
385
+ }
386
+ break
387
+
388
+ default:
389
+ return false
390
+ }
391
+
392
+ if (defaultPrevent) e.preventDefault()
393
+ return true
394
+ }
395
+
396
+ onExecute(command: string, undoable: boolean, redoable: boolean) {
397
+ !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled')
398
+ !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled')
399
+ }
400
+
401
+ onUndo(undoable: boolean, redoable: boolean) {
402
+ !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled')
403
+ !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled')
404
+ }
405
+
406
+ onRedo(undoable: boolean, redoable: boolean) {
407
+ !undoable ? this.undo.setAttribute('disabled', '') : this.undo.removeAttribute('disabled')
408
+ !redoable ? this.redo.setAttribute('disabled', '') : this.redo.removeAttribute('disabled')
409
+ }
410
+
411
+ onSceneChanged(after?: Scene, before?: Scene) {
412
+ // if (before) {
413
+ // before.off('execute', this.onExecute, this)
414
+ // before.off('undo', this.onUndo, this)
415
+ // before.off('redo', this.onRedo, this)
416
+ // }
417
+
418
+ if (after) {
419
+ after.on('execute', this.onExecute, this)
420
+ after.on('undo', this.onUndo, this)
421
+ after.on('redo', this.onRedo, this)
422
+ }
423
+ }
424
+
425
+ // @query('#align-left') private alignLeft!: HTMLElement
426
+ // @query('#align-center') private alignCenter!: HTMLElement
427
+ // @query('#align-right') private alignRight!: HTMLElement
428
+ // @query('#align-top') private alignTop!: HTMLElement
429
+ // @query('#align-middle') private alignMiddle!: HTMLElement
430
+ // @query('#align-bottom') private alignBottom!: HTMLElement
431
+
432
+ onSelectedChanged(after: Component[], before: Component[]) {
433
+ var alignable = after.length > 1
434
+
435
+ this.aligners.forEach(aligner =>
436
+ alignable ? aligner.removeAttribute('disabled') : aligner.setAttribute('disabled', '')
437
+ )
438
+
439
+ var movable = after.length === 1
440
+
441
+ /* forward, backward 이동은 한 컴포넌트만 가능하다. */
442
+ !movable ? this.forward.setAttribute('disabled', '') : this.forward.removeAttribute('disabled')
443
+ !movable ? this.backward.setAttribute('disabled', '') : this.backward.removeAttribute('disabled')
444
+
445
+ /* 여러 컴포넌트는 front, back 이동이 가능하다. */
446
+ !(alignable || movable) ? this.front.setAttribute('disabled', '') : this.front.removeAttribute('disabled')
447
+ !(alignable || movable) ? this.back.setAttribute('disabled', '') : this.back.removeAttribute('disabled')
448
+ }
449
+
450
+ onTapUndo() {
451
+ this.scene?.undo()
452
+ }
453
+
454
+ onTapRedo() {
455
+ this.scene?.redo()
456
+ }
457
+
458
+ onTapCut() {
459
+ this.scene?.cut()
460
+ }
461
+
462
+ onTapCopy() {
463
+ var copied = this.scene?.copy()
464
+
465
+ if (!copied) return
466
+
467
+ navigator.clipboard.writeText(copied)
468
+ this.cliped = copied
469
+ }
470
+
471
+ onTapPaste() {
472
+ setTimeout(() => {
473
+ this.cliped && this.scene?.paste(this.cliped)
474
+ }, 100)
475
+ }
476
+
477
+ onTapDelete() {
478
+ this.scene?.remove()
479
+ }
480
+
481
+ onTapSelectAll() {
482
+ this.scene?.select('(child)')
483
+ }
484
+
485
+ onTapFontIncrease(e: TouchEvent) {
486
+ var selected = this.scene?.selected
487
+ if (!selected || !selected.length) {
488
+ return
489
+ }
490
+
491
+ this.scene?.undoableChange(function () {
492
+ selected!.forEach(function (component) {
493
+ var fontSize = component.get('fontSize')
494
+
495
+ if (!fontSize) fontSize = '15'
496
+
497
+ if (fontSize) {
498
+ var size = parseInt(fontSize)
499
+ component.set('fontSize', size + 1)
500
+ }
501
+ })
502
+ })
503
+ }
504
+
505
+ onTapFontDecrease(e: TouchEvent) {
506
+ var selected = this.scene?.selected
507
+
508
+ if (!selected || !selected.length) {
509
+ return
510
+ }
511
+
512
+ this.scene?.undoableChange(function () {
513
+ selected!.forEach(function (component) {
514
+ var fontSize = component.get('fontSize')
515
+
516
+ if (!fontSize) fontSize = '15'
517
+
518
+ if (fontSize) {
519
+ var size = parseInt(fontSize)
520
+ if (size > 1) component.set('fontSize', size - 1)
521
+ }
522
+ })
523
+ })
524
+ }
525
+
526
+ onTapAlign(e: TouchEvent | string) {
527
+ if (!this.scene) return
528
+
529
+ var selected = this.scene.selected
530
+ if (selected.length <= 1) return
531
+
532
+ var align = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-align')
533
+
534
+ align && this.scene.align(align)
535
+ }
536
+
537
+ onTapZorder(e: TouchEvent | string) {
538
+ if (!this.scene) return
539
+
540
+ var selected = this.scene.selected
541
+ if (selected.length < 1) return
542
+
543
+ var zorder = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-zorder')
544
+
545
+ zorder && this.scene.zorder(zorder)
546
+ }
547
+
548
+ onTapSymmetryX() {
549
+ this.scene && this.scene.symmetryX()
550
+ }
551
+
552
+ onTapSymmetryY() {
553
+ this.scene && this.scene.symmetryY()
554
+ }
555
+
556
+ onTapRotateCW() {
557
+ if (!this.scene) return
558
+
559
+ var selected = this.scene.selected
560
+ if (selected.length && selected[0].isRootModel()) return
561
+
562
+ this.scene.undoableChange(function () {
563
+ selected.forEach(function (component) {
564
+ var rotation = component.get('rotation')
565
+
566
+ if (!rotation) rotation = 0
567
+
568
+ component.set('rotation', (rotation + Math.PI / 2) % (Math.PI * 2))
569
+ })
570
+ })
571
+ }
572
+
573
+ onTapRotateCCW() {
574
+ if (!this.scene) return
575
+
576
+ var selected = this.scene.selected
577
+ if (selected.length && selected[0].isRootModel()) return
578
+
579
+ this.scene.undoableChange(function () {
580
+ selected.forEach(function (component) {
581
+ var rotation = component.get('rotation')
582
+
583
+ if (!rotation) rotation = 0
584
+
585
+ component.set('rotation', (rotation - Math.PI / 2) % (Math.PI * 2))
586
+ })
587
+ })
588
+ }
589
+
590
+ onTapGroup() {
591
+ this.scene && this.scene.group()
592
+ }
593
+
594
+ onTapUngroup() {
595
+ this.scene && this.scene.ungroup()
596
+ }
597
+
598
+ onTapFullscreen() {
599
+ this.dispatchEvent(new CustomEvent('modeller-fullscreen'))
600
+ }
601
+
602
+ onTapToggle() {
603
+ this.hideProperty = !this.hideProperty
604
+ this.dispatchEvent(
605
+ new CustomEvent('hide-property-changed', {
606
+ bubbles: true,
607
+ composed: true,
608
+ detail: { value: this.hideProperty }
609
+ })
610
+ )
611
+ }
612
+
613
+ onTapFitScene() {
614
+ if (this.scene) {
615
+ this.scene.resize()
616
+ this.scene.fit('ratio')
617
+ }
618
+ }
619
+
620
+ onTapPreview() {
621
+ this.dispatchEvent(new CustomEvent('open-preview'))
622
+ }
623
+
624
+ onTapDownloadModel() {
625
+ this.dispatchEvent(new CustomEvent('download-model'))
626
+ }
627
+
628
+ onTapDistribute(e: TouchEvent | string) {
629
+ if (!this.scene) return
630
+
631
+ var selected = this.scene.selected
632
+ if (selected.length <= 1) {
633
+ return
634
+ }
635
+
636
+ var distribute = typeof e === 'string' ? e : (e.target as HTMLElement)!.getAttribute('data-distribute')
637
+
638
+ distribute && this.scene.distribute(distribute)
639
+ }
640
+ }