@fmsim/board 2.0.0-beta.9 → 2.0.0-beta.92

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 (102) hide show
  1. package/custom-elements.json +7351 -3944
  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 +36 -0
  7. package/dist/src/component/etc.js.map +1 -1
  8. package/dist/src/component/index.d.ts +1 -0
  9. package/dist/src/component/index.js +1 -0
  10. package/dist/src/component/index.js.map +1 -1
  11. package/dist/src/component/restful-property-editor-backdrop-faces.d.ts +50 -0
  12. package/dist/src/component/restful-property-editor-backdrop-faces.js +524 -0
  13. package/dist/src/component/restful-property-editor-backdrop-faces.js.map +1 -0
  14. package/dist/src/data-storage/board-model-cache.d.ts +13 -0
  15. package/dist/src/data-storage/board-model-cache.js +66 -0
  16. package/dist/src/data-storage/board-model-cache.js.map +1 -0
  17. package/dist/src/index.d.ts +3 -0
  18. package/dist/src/index.js +2 -0
  19. package/dist/src/index.js.map +1 -1
  20. package/dist/src/layers/mcs-mouse-event-handler.js +8 -0
  21. package/dist/src/layers/mcs-mouse-event-handler.js.map +1 -1
  22. package/dist/src/layers/movement-layer.d.ts +4 -4
  23. package/dist/src/layers/movement-layer.js +16 -8
  24. package/dist/src/layers/movement-layer.js.map +1 -1
  25. package/dist/src/modeller/bulk-create-dialog.d.ts +51 -0
  26. package/dist/src/modeller/bulk-create-dialog.js +531 -0
  27. package/dist/src/modeller/bulk-create-dialog.js.map +1 -0
  28. package/dist/src/modeller/bulk-create.d.ts +101 -0
  29. package/dist/src/modeller/bulk-create.js +199 -0
  30. package/dist/src/modeller/bulk-create.js.map +1 -0
  31. package/dist/src/modeller/component-toolbar/component-menu.d.ts +1 -1
  32. package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +1 -1
  33. package/dist/src/modeller/edit-toolbar.d.ts +13 -0
  34. package/dist/src/modeller/edit-toolbar.js +168 -7
  35. package/dist/src/modeller/edit-toolbar.js.map +1 -1
  36. package/dist/src/modeller/property-sidebar/abstract-property.js +10 -2
  37. package/dist/src/modeller/property-sidebar/abstract-property.js.map +1 -1
  38. package/dist/src/modeller/property-sidebar/data-binding/data-binding.d.ts +1 -1
  39. package/dist/src/modeller/property-sidebar/effects/effects.d.ts +10 -1
  40. package/dist/src/modeller/property-sidebar/effects/effects.js +66 -1
  41. package/dist/src/modeller/property-sidebar/effects/effects.js.map +1 -1
  42. package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.d.ts +44 -0
  43. package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.js +70 -0
  44. package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.js.map +1 -0
  45. package/dist/src/modeller/property-sidebar/effects/property-event.d.ts +13 -3
  46. package/dist/src/modeller/property-sidebar/effects/property-event.js +20 -11
  47. package/dist/src/modeller/property-sidebar/effects/property-event.js.map +1 -1
  48. package/dist/src/modeller/property-sidebar/property-sidebar.d.ts +1 -1
  49. package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.d.ts +75 -0
  50. package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js +346 -0
  51. package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js.map +1 -0
  52. package/dist/src/modeller/property-sidebar/shapes/shapes.d.ts +22 -1
  53. package/dist/src/modeller/property-sidebar/shapes/shapes.js +94 -2
  54. package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -1
  55. package/dist/src/modeller/property-sidebar/specifics/specifics.d.ts +25 -1
  56. package/dist/src/modeller/property-sidebar/specifics/specifics.js +112 -2
  57. package/dist/src/modeller/property-sidebar/specifics/specifics.js.map +1 -1
  58. package/dist/src/modeller/property-sidebar/styles/styles.d.ts +1 -1
  59. package/dist/src/modeller/scene-viewer/ox-scene-layer.d.ts +4 -3
  60. package/dist/src/modeller/scene-viewer/ox-scene-layer.js +2 -1
  61. package/dist/src/modeller/scene-viewer/ox-scene-layer.js.map +1 -1
  62. package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +2 -1
  63. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +5 -1
  64. package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -1
  65. package/dist/src/ox-board-component-info.d.ts +1 -0
  66. package/dist/src/ox-board-component-info.js +35 -2
  67. package/dist/src/ox-board-component-info.js.map +1 -1
  68. package/dist/src/ox-board-list.js +2 -2
  69. package/dist/src/ox-board-list.js.map +1 -1
  70. package/dist/src/ox-board-modeller.d.ts +6 -3
  71. package/dist/src/ox-board-modeller.js +14 -1
  72. package/dist/src/ox-board-modeller.js.map +1 -1
  73. package/dist/src/ox-board-viewer.d.ts +113 -13
  74. package/dist/src/ox-board-viewer.js +764 -98
  75. package/dist/src/ox-board-viewer.js.map +1 -1
  76. package/dist/src/ox-editor-board-selector.d.ts +3 -0
  77. package/dist/src/ox-editor-board-selector.js +38 -9
  78. package/dist/src/ox-editor-board-selector.js.map +1 -1
  79. package/dist/src/ox-playback-controls.d.ts +157 -0
  80. package/dist/src/ox-playback-controls.js +1089 -0
  81. package/dist/src/ox-playback-controls.js.map +1 -0
  82. package/dist/src/playback/carrier-tracking-store.d.ts +51 -0
  83. package/dist/src/playback/carrier-tracking-store.js +115 -0
  84. package/dist/src/playback/carrier-tracking-store.js.map +1 -0
  85. package/dist/src/playback/playback-engine.d.ts +106 -0
  86. package/dist/src/playback/playback-engine.js +395 -0
  87. package/dist/src/playback/playback-engine.js.map +1 -0
  88. package/dist/src/selector/board-creation-popup.js +2 -2
  89. package/dist/src/selector/board-creation-popup.js.map +1 -1
  90. package/dist/src/selector/board-thumbnail-card.js +6 -6
  91. package/dist/src/selector/board-thumbnail-card.js.map +1 -1
  92. package/dist/src/selector/ox-board-creation-card.js +2 -2
  93. package/dist/src/selector/ox-board-creation-card.js.map +1 -1
  94. package/dist/src/selector/ox-board-selector.js +21 -10
  95. package/dist/src/selector/ox-board-selector.js.map +1 -1
  96. package/dist/tsconfig.tsbuildinfo +1 -1
  97. package/icons/components/text.png +0 -0
  98. package/icons/fab/mode-2d.svg +25 -0
  99. package/icons/fab/mode-3d.svg +25 -0
  100. package/icons/fab/playback-play.svg +49 -0
  101. package/icons/fab/playback-stop.svg +50 -0
  102. package/package.json +8 -4
@@ -1 +1 @@
1
- {"version":3,"file":"edit-toolbar.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { html, LitElement, PropertyValues } from 'lit'\nimport { property, state } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { copyToClipboard, isMacOS } from '@operato/utils'\n\nimport { style } from './edit-toolbar-style'\n\nconst MACOS = isMacOS()\n\nexport class EditToolbar extends LitElement {\n static styles = [style]\n\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: any[] = []\n @property({ type: Boolean }) hideProperty: boolean = false\n\n @state() private _dimension: '2d' | '3d' | null = null\n @state() private _gizmoAttached = false\n\n private cliped?: string\n\n firstUpdated() {\n this.addEventListener('mousewheel', this.onWheelEvent.bind(this) as EventListener, false)\n\n // 툴바 버튼 클릭 후 씬으로 포커스를 돌려서 키보드 단축키가 계속 작동하도록 한다\n this.addEventListener('click', () => {\n ;(this.scene?.root as any)?.element?.focus()\n })\n\n window.addEventListener('paste', (e: Event) => {\n try {\n this.cliped = (e as ClipboardEvent).clipboardData?.getData('text/plain')\n } catch (e) {\n console.error('model paste failed', e)\n }\n })\n // 모든 버튼은 템플릿 @click 디렉티브로 바인딩 — 조건부 렌더링 시에도 정상 작동\n }\n\n updated(changes: PropertyValues<this>) {\n changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene') as Scene)\n changes.has('selected') && this.onSelectedChanged(this.selected, changes.get('selected') as Component[])\n }\n\n render() {\n return html`\n <div tools>\n <span><slot></slot></span>\n\n ${this.hasEmptySlot() ? html`` : html`<span class=\"vline\"></span>`}\n\n <span button id=\"undo\" title=\"undo (${this.getShortcutString('cmd', 'z')})\" @click=${this.onTapUndo}> </span>\n <span button id=\"redo\" title=\"redo (${this.getShortcutString('cmd', 'shift', 'z')})\" @click=${this.onTapRedo}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"style-copy\" title=\"style copy (${this.getShortcutString('cmd', '1')})\" @click=${this.onStartStylePasteMode}> </span>\n <span button id=\"databind-copy\" title=\"databind copy (${this.getShortcutString('cmd', '2')})\" @click=${this.onStartDatabindPasteMode}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"cut\" title=\"cut (${this.getShortcutString('cmd', 'x')})\" @click=${this.onTapCut}> </span>\n <span button id=\"copy\" title=\"copy (${this.getShortcutString('cmd', 'c')})\" @click=${this.onTapCopy}> </span>\n <span button id=\"paste\" title=\"paste (${this.getShortcutString('cmd', 'v')})\" @click=${this.onTapPaste}> </span>\n <span button id=\"delete\"\n title=\"delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})\"\n @click=${this.onTapDelete}> </span>\n\n <span class=\"vline\"></span>\n\n <span button data-align=\"left\" id=\"align-left\"\n title=\"align left (${this.getShortcutString('alt', 'shift', 'l')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"center\" id=\"align-center\"\n title=\"align center (${this.getShortcutString('alt', 'shift', 'c')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"right\" id=\"align-right\"\n title=\"align right (${this.getShortcutString('alt', 'shift', 'r')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-align=\"top\" id=\"align-top\"\n title=\"align top (${this.getShortcutString('alt', 'shift', 't')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"middle\" id=\"align-middle\"\n title=\"align middle (${this.getShortcutString('alt', 'shift', 'm')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"bottom\" id=\"align-bottom\"\n title=\"align bottom (${this.getShortcutString('alt', 'shift', 'b')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-distribute=\"HORIZONTAL\" id=\"distribute-horizontal\"\n title=\"distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})\" @click=${this.onTapDistribute}> </span>\n <span button data-distribute=\"VERTICAL\" id=\"distribute-vertical\"\n title=\"distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})\" @click=${this.onTapDistribute}> </span>\n\n ${this._dimension === '3d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button data-align=\"z-front\" id=\"align-z-front\" title=\"align Z front\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-middle\" id=\"align-z-middle\" title=\"align Z middle\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-back\" id=\"align-z-back\" title=\"align Z back\" @click=${this.onTapAlign}> </span>\n <span button data-distribute=\"Z\" id=\"distribute-z\" title=\"distribute Z\" @click=${this.onTapDistribute}> </span>\n `\n : this._dimension === '2d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"front\" data-zorder=\"front\"\n title=\"bring to front (${this.getShortcutString('cmd', 'shift', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"back\" data-zorder=\"back\"\n title=\"send to back (${this.getShortcutString('cmd', 'shift', 'b')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"forward\" data-zorder=\"forward\"\n title=\"bring forward (${this.getShortcutString('cmd', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"backward\" data-zorder=\"backward\"\n title=\"send backward (${this.getShortcutString('cmd', 'b')})\" @click=${this.onTapZorder}> </span>\n `\n : ''}\n\n ${this._dimension === '2d' ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"group\" title=\"group (${this.getShortcutString('cmd', 'g')})\" @click=${this.onTapGroup}> </span>\n <span button id=\"ungroup\" title=\"ungroup (${this.getShortcutString('cmd', 'shift', 'g')})\" @click=${this.onTapUngroup}> </span>\n ` : this._dimension === '3d' ? html`\n <span class=\"vline\"></span>\n\n <span button class=\"gizmo-btn\" data-gizmo=\"translate\" title=\"Move (W)\"\n @click=${() => this._setGizmoMode('translate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"10\" y1=\"2\" x2=\"10\" y2=\"18\"/><line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\"/>\n <polyline points=\"10,2 7.5,5\"/><polyline points=\"10,2 12.5,5\"/>\n <polyline points=\"18,10 15,7.5\"/><polyline points=\"18,10 15,12.5\"/>\n <polyline points=\"10,18 7.5,15\"/><polyline points=\"10,18 12.5,15\"/>\n <polyline points=\"2,10 5,7.5\"/><polyline points=\"2,10 5,12.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"rotate\" title=\"Rotate (E)\"\n @click=${() => this._setGizmoMode('rotate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <path d=\"M14.5 3.5A7 7 0 1 0 17 10\"/>\n <polyline points=\"14,1 15,3.5 12.5,4.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"scale\" title=\"Scale (R)\"\n @click=${() => this._setGizmoMode('scale')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"4\" y1=\"16\" x2=\"16\" y2=\"4\"/>\n <rect x=\"2\" y=\"13\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n <rect x=\"14\" y=\"2\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n </svg>\n </span>\n ` : ''}\n\n <span class=\"vline\"></span>\n\n <span button id=\"font-increase\" title=\"increase font size\" @click=${this.onTapFontIncrease}></span>\n <span button id=\"font-decrease\" title=\"decrease font size\" style=\"scale: 0.7;\" @click=${this.onTapFontDecrease}></span>\n\n <span class=\"vline\"></span>\n <span>(v${process.env['APP-VERSION']})</span>\n <span padding></span>\n\n <span button id=\"fit-scene\" title=\"fit scene (${this.getShortcutString('cmd', 'd')})\" @click=${this.onTapFitScene}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"preview\" title=\"preview (${this.getShortcutString('ctrl', 'p')})\" @click=${this.onTapPreview}> </span>\n\n <span button id=\"fullscreen\" title=\"fullscreen (${this.getShortcutString('f11')})\" @click=${this.onTapFullscreen}> </span>\n\n <span button id=\"toggle-property\"\n title=\"toggle property panel (${this.getShortcutString('cmd', 'h')})\"\n toggles=\"true\" @click=${this.onTapToggle}> </span>\n </div>\n `\n }\n\n hasEmptySlot() {\n const slot = this.renderRoot.querySelector('slot') as HTMLSlotElement\n return slot?.assignedNodes().length === 0\n }\n\n onWheelEvent(e: Event) {\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n getSymbol(key: string) {\n var symbol\n switch (key) {\n case 'cmd':\n case 'ctrl':\n symbol = MACOS ? '⌘' : 'Ctrl'\n break\n case 'shift':\n symbol = MACOS ? '⇧' : 'Shift'\n break\n case 'alt':\n case 'option':\n symbol = MACOS ? '⌥' : 'Alt'\n break\n case 'backspace':\n symbol = MACOS ? '⌫' : 'BackSpace'\n break\n case 'delete':\n symbol = MACOS ? '⌦' : 'Del'\n break\n default:\n symbol = key.toUpperCase()\n break\n }\n\n return symbol\n }\n\n private getShortcutString(...keys: string[]) {\n var symbols = []\n for (var i = 0; i < arguments.length; i++) {\n symbols.push(this.getSymbol(arguments[i]))\n }\n\n return symbols.join(MACOS ? '' : '+')\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n var altKey = e.altKey\n var shiftKey = e.shiftKey\n\n var defaultPrevent = ctrlKey || altKey\n\n switch (e.code) {\n case 'KeyZ':\n if (ctrlKey && !shiftKey) this.onTapUndo()\n else if (ctrlKey && shiftKey) this.onTapRedo()\n break\n case 'KeyY':\n if (ctrlKey && !shiftKey) this.onTapRedo()\n break\n case 'Digit1':\n if (ctrlKey) this.onStartStylePasteMode()\n break\n case 'Digit2':\n if (ctrlKey) this.onStartDatabindPasteMode()\n break\n case 'KeyC':\n if (ctrlKey && !shiftKey) this.onTapCopy()\n else if (altKey && shiftKey) this.onTapAlign('center')\n break\n case 'KeyX':\n if (ctrlKey && !shiftKey) this.onTapCut()\n break\n case 'KeyV':\n if (ctrlKey && !shiftKey) {\n this.onTapPaste()\n defaultPrevent = false\n } else if (altKey && shiftKey) this.onTapDistribute('VERTICAL')\n break\n case 'Delete':\n case 'Backspace':\n this.onTapDelete()\n defaultPrevent = true\n break\n case 'KeyG':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.onTapGroup()\n else if (ctrlKey && shiftKey) this.onTapUngroup()\n }\n break\n case 'KeyF':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.scene?.zorder('forward')\n else if (ctrlKey && shiftKey) this.scene?.zorder('front')\n }\n break\n case 'KeyB':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.scene?.zorder('backward')\n else if (ctrlKey && shiftKey) this.scene?.zorder('back')\n }\n if (altKey && shiftKey) this.onTapAlign('bottom')\n break\n case 'KeyH':\n if (ctrlKey && !shiftKey) this.onTapToggle()\n else if (altKey && shiftKey) this.onTapDistribute('HORIZONTAL')\n break\n case 'F11':\n this.onTapFullscreen()\n defaultPrevent = true\n break\n case 'KeyP':\n if (ctrlKey) {\n this.onTapPreview()\n defaultPrevent = true\n }\n break\n case 'KeyA':\n if (ctrlKey) this.onTapSelectAll()\n break\n case 'KeyL':\n if (altKey && shiftKey) this.onTapAlign('left')\n break\n case 'KeyR':\n if (altKey && shiftKey) this.onTapAlign('right')\n break\n case 'KeyM':\n if (altKey && shiftKey) this.onTapAlign('middle')\n break\n case 'KeyT':\n if (altKey && shiftKey) this.onTapAlign('top')\n break\n case 'KeyD':\n if (ctrlKey) {\n this.onTapFitScene()\n defaultPrevent = true\n }\n break\n case 'KeyE':\n if (ctrlKey && shiftKey) this.onTapDownloadModel()\n break\n\n case 'Escape':\n this.scene?.stopStylePasteMode()\n this.scene?.stopDatabindPasteMode()\n defaultPrevent = true\n break\n\n default:\n return false\n }\n\n if (defaultPrevent) e.preventDefault()\n return true\n }\n\n private _setDisabled(id: string, disabled: boolean) {\n const el = this.renderRoot.querySelector(`#${id}`)\n disabled ? el?.setAttribute('disabled', '') : el?.removeAttribute('disabled')\n }\n\n onExecute(command: string, undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onUndo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onRedo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onSceneChanged(after?: Scene, before?: Scene) {\n if (before) {\n before.off('execute', this.onExecute, this)\n before.off('undo', this.onUndo, this)\n before.off('redo', this.onRedo, this)\n before.off('dimension', this._onDimensionChanged, this)\n before.off('gizmoattach', this._onGizmoAttachChanged, this)\n }\n\n if (after) {\n after.on('execute', this.onExecute, this)\n after.on('undo', this.onUndo, this)\n after.on('redo', this.onRedo, this)\n after.on('dimension', this._onDimensionChanged, this)\n after.on('gizmoattach', this._onGizmoAttachChanged, this)\n\n // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)\n const threed = (after as any).model_layer?.model?.threed\n this._dimension = threed ? '3d' : '2d'\n }\n }\n\n private _onDimensionChanged(dimension: '2d' | '3d') {\n this._dimension = dimension\n }\n\n private _onGizmoAttachChanged(isAttached: boolean) {\n this._gizmoAttached = isAttached\n }\n\n private _setGizmoMode(mode: 'translate' | 'rotate' | 'scale') {\n ;(this.scene?.root as any)?.setGizmoMode(mode)\n }\n\n onSelectedChanged(after: Component[], before: Component[]) {\n var hasSelection = after.length > 0\n var alignable = after.length > 1\n\n // 선택 필요 버튼\n ;['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id =>\n this._setDisabled(id, !hasSelection)\n )\n\n // 정렬 버튼\n this.renderRoot.querySelectorAll('[data-align]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '2d') {\n var movable = after.length === 1\n\n /* forward, backward 이동은 한 컴포넌트만 가능하다. */\n this._setDisabled('forward', !movable)\n this._setDisabled('backward', !movable)\n\n /* 여러 컴포넌트는 front, back 이동이 가능하다. */\n this._setDisabled('front', !(alignable || movable))\n this._setDisabled('back', !(alignable || movable))\n }\n\n // 분배 버튼\n this.renderRoot.querySelectorAll('[data-distribute]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '3d') {\n this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {\n hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '')\n })\n }\n }\n\n onTapUndo() {\n this.scene?.undo()\n }\n\n onTapRedo() {\n this.scene?.redo()\n }\n\n onStartStylePasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startStylePasteMode()\n }\n\n onStartDatabindPasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startDatabindPasteMode()\n }\n\n onTapCut() {\n this.scene?.cut()\n }\n\n async onTapCopy() {\n var copied = this.scene?.copy()\n\n if (!copied) return\n\n await copyToClipboard(copied)\n this.cliped = copied\n }\n\n onTapPaste() {\n setTimeout(() => {\n this.cliped && this.scene?.paste(this.cliped)\n }, 100)\n }\n\n onTapDelete() {\n this.scene?.remove()\n }\n\n onTapSelectAll() {\n this.scene?.select('(child)')\n }\n\n onTapFontIncrease(e: TouchEvent) {\n var selected = this.scene?.selected\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n component.set('fontSize', size + 1)\n }\n })\n })\n }\n\n onTapFontDecrease(e: TouchEvent) {\n var selected = this.scene?.selected\n\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n if (size > 1) component.set('fontSize', size - 1)\n }\n })\n })\n }\n\n onTapAlign(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n\n var align = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-align')\n if (!align) {\n return\n }\n\n if (selected.length <= 1) {\n this.scene.place(align)\n } else {\n this.scene.align(align)\n }\n }\n\n onTapZorder(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length < 1) return\n\n var zorder = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-zorder')\n\n zorder && this.scene.zorder(zorder)\n }\n\n onTapGroup() {\n this.scene && this.scene.group()\n }\n\n onTapUngroup() {\n this.scene && this.scene.ungroup()\n }\n\n onTapFullscreen() {\n this.dispatchEvent(new CustomEvent('modeller-fullscreen'))\n }\n\n onTapToggle() {\n this.hideProperty = !this.hideProperty\n this.dispatchEvent(\n new CustomEvent('hide-property-changed', {\n bubbles: true,\n composed: true,\n detail: { value: this.hideProperty }\n })\n )\n }\n\n onTapFitScene() {\n if (this.scene) {\n this.scene.resize()\n this.scene.fit('ratio')\n }\n }\n\n onTapPreview() {\n this.dispatchEvent(new CustomEvent('open-preview'))\n }\n\n onTapDownloadModel() {\n this.dispatchEvent(new CustomEvent('download-model'))\n }\n\n onTapDistribute(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length <= 1) {\n return\n }\n\n var distribute = typeof e === 'string' ? e : (e.target as HTMLElement)!.getAttribute('data-distribute')\n\n distribute && this.scene.distribute(distribute)\n }\n}\n"]}
1
+ {"version":3,"file":"edit-toolbar.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { html, LitElement, PropertyValues } from 'lit'\nimport { property, state } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { copyToClipboard, isMacOS } from '@operato/utils'\nimport { OxPopup } from '@operato/popup'\n\nimport { style } from './edit-toolbar-style'\nimport './bulk-create-dialog.js'\nimport type { BulkCreateDialog } from './bulk-create-dialog.js'\n\nconst MACOS = isMacOS()\n\n/**\n * 컴포넌트 model JSON 만으로 type-aware bounding box (width, height) 추출.\n *\n * things-scene 의 component.bounds 는 *path 의 bounding box* 인데, model JSON 만\n * 으로는 path 를 그릴 수 없으므로 type-specific 필드를 직접 본다.\n * - width/height 명시 (Rect, Container 등) → 그대로\n * - rx/ry (Ellipse 등) → 2*rx, 2*ry\n * - points 배열 (Line, Polygon 등) → 점들의 bounding box\n * - 그 외 → 50x50 fallback\n *\n * bulk-paste 가 영역 안에 N 개 복제할 때 *원본 크기를 보존* 하기 위해 사용.\n */\nfunction deriveBoundsFromModel(model: Record<string, any>): { width: number; height: number } {\n if (typeof model.width === 'number' && typeof model.height === 'number') {\n return { width: model.width, height: model.height }\n }\n if (typeof model.rx === 'number' && typeof model.ry === 'number') {\n return { width: 2 * Math.abs(model.rx), height: 2 * Math.abs(model.ry) }\n }\n if (Array.isArray(model.points) && model.points.length > 0) {\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (const p of model.points) {\n if (typeof p?.x === 'number') {\n if (p.x < minX) minX = p.x\n if (p.x > maxX) maxX = p.x\n }\n if (typeof p?.y === 'number') {\n if (p.y < minY) minY = p.y\n if (p.y > maxY) maxY = p.y\n }\n }\n if (isFinite(minX) && isFinite(maxX) && isFinite(minY) && isFinite(maxY)) {\n return { width: maxX - minX, height: maxY - minY }\n }\n }\n return { width: 50, height: 50 }\n}\n\nexport class EditToolbar extends LitElement {\n static styles = [style]\n\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: any[] = []\n @property({ type: Boolean }) hideProperty: boolean = false\n\n @state() private _dimension: '2d' | '3d' | null = null\n @state() private _gizmoAttached = false\n\n private cliped?: string\n\n firstUpdated() {\n this.addEventListener('mousewheel', this.onWheelEvent.bind(this) as EventListener, false)\n\n // 툴바 버튼 클릭 후 씬으로 포커스를 돌려서 키보드 단축키가 계속 작동하도록 한다\n this.addEventListener('click', () => {\n ;(this.scene?.root as any)?.element?.focus()\n })\n\n window.addEventListener('paste', (e: Event) => {\n try {\n this.cliped = (e as ClipboardEvent).clipboardData?.getData('text/plain')\n } catch (e) {\n console.error('model paste failed', e)\n }\n })\n // 모든 버튼은 템플릿 @click 디렉티브로 바인딩 — 조건부 렌더링 시에도 정상 작동\n }\n\n updated(changes: PropertyValues<this>) {\n changes.has('scene') && this.onSceneChanged(this.scene, changes.get('scene') as Scene)\n changes.has('selected') && this.onSelectedChanged(this.selected, changes.get('selected') as Component[])\n }\n\n render() {\n return html`\n <div tools>\n <span><slot></slot></span>\n\n ${this.hasEmptySlot() ? html`` : html`<span class=\"vline\"></span>`}\n\n <span button id=\"undo\" title=\"undo (${this.getShortcutString('cmd', 'z')})\" @click=${this.onTapUndo}> </span>\n <span button id=\"redo\" title=\"redo (${this.getShortcutString('cmd', 'shift', 'z')})\" @click=${this.onTapRedo}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"style-copy\" title=\"style copy (${this.getShortcutString('cmd', '1')})\" @click=${this.onStartStylePasteMode}> </span>\n <span button id=\"databind-copy\" title=\"databind copy (${this.getShortcutString('cmd', '2')})\" @click=${this.onStartDatabindPasteMode}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"cut\" title=\"cut (${this.getShortcutString('cmd', 'x')})\" @click=${this.onTapCut}> </span>\n <span button id=\"copy\" title=\"copy (${this.getShortcutString('cmd', 'c')})\" @click=${this.onTapCopy}> </span>\n <span button id=\"paste\" title=\"paste (${this.getShortcutString('cmd', 'v')})\" @click=${this.onTapPaste}> </span>\n <span button id=\"delete\"\n title=\"delete (${this.getShortcutString('backspace')}, ${this.getShortcutString('delete')})\"\n @click=${this.onTapDelete}> </span>\n\n <span class=\"vline\"></span>\n\n <span button data-align=\"left\" id=\"align-left\"\n title=\"align left (${this.getShortcutString('alt', 'shift', 'l')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"center\" id=\"align-center\"\n title=\"align center (${this.getShortcutString('alt', 'shift', 'c')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"right\" id=\"align-right\"\n title=\"align right (${this.getShortcutString('alt', 'shift', 'r')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-align=\"top\" id=\"align-top\"\n title=\"align top (${this.getShortcutString('alt', 'shift', 't')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"middle\" id=\"align-middle\"\n title=\"align middle (${this.getShortcutString('alt', 'shift', 'm')})\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"bottom\" id=\"align-bottom\"\n title=\"align bottom (${this.getShortcutString('alt', 'shift', 'b')})\" @click=${this.onTapAlign}> </span>\n\n <span button data-distribute=\"HORIZONTAL\" id=\"distribute-horizontal\"\n title=\"distribute horizontally (${this.getShortcutString('alt', 'shift', 'h')})\" @click=${this.onTapDistribute}> </span>\n <span button data-distribute=\"VERTICAL\" id=\"distribute-vertical\"\n title=\"distribute vertically (${this.getShortcutString('alt', 'shift', 'v')})\" @click=${this.onTapDistribute}> </span>\n\n ${this._dimension === '3d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button data-align=\"z-front\" id=\"align-z-front\" title=\"align Z front\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-middle\" id=\"align-z-middle\" title=\"align Z middle\" @click=${this.onTapAlign}> </span>\n <span button data-align=\"z-back\" id=\"align-z-back\" title=\"align Z back\" @click=${this.onTapAlign}> </span>\n <span button data-distribute=\"Z\" id=\"distribute-z\" title=\"distribute Z\" @click=${this.onTapDistribute}> </span>\n `\n : this._dimension === '2d'\n ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"front\" data-zorder=\"front\"\n title=\"bring to front (${this.getShortcutString('cmd', 'shift', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"back\" data-zorder=\"back\"\n title=\"send to back (${this.getShortcutString('cmd', 'shift', 'b')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"forward\" data-zorder=\"forward\"\n title=\"bring forward (${this.getShortcutString('cmd', 'f')})\" @click=${this.onTapZorder}> </span>\n <span button id=\"backward\" data-zorder=\"backward\"\n title=\"send backward (${this.getShortcutString('cmd', 'b')})\" @click=${this.onTapZorder}> </span>\n `\n : ''}\n\n ${this._dimension === '2d' ? html`\n <span class=\"vline\"></span>\n\n <span button id=\"group\" title=\"group (${this.getShortcutString('cmd', 'g')})\" @click=${this.onTapGroup}> </span>\n <span button id=\"ungroup\" title=\"ungroup (${this.getShortcutString('cmd', 'shift', 'g')})\" @click=${this.onTapUngroup}> </span>\n ` : this._dimension === '3d' ? html`\n <span class=\"vline\"></span>\n\n <span button class=\"gizmo-btn\" data-gizmo=\"translate\" title=\"Move (W)\"\n @click=${() => this._setGizmoMode('translate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"10\" y1=\"2\" x2=\"10\" y2=\"18\"/><line x1=\"2\" y1=\"10\" x2=\"18\" y2=\"10\"/>\n <polyline points=\"10,2 7.5,5\"/><polyline points=\"10,2 12.5,5\"/>\n <polyline points=\"18,10 15,7.5\"/><polyline points=\"18,10 15,12.5\"/>\n <polyline points=\"10,18 7.5,15\"/><polyline points=\"10,18 12.5,15\"/>\n <polyline points=\"2,10 5,7.5\"/><polyline points=\"2,10 5,12.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"rotate\" title=\"Rotate (E)\"\n @click=${() => this._setGizmoMode('rotate')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <path d=\"M14.5 3.5A7 7 0 1 0 17 10\"/>\n <polyline points=\"14,1 15,3.5 12.5,4.5\"/>\n </svg>\n </span>\n <span button class=\"gizmo-btn\" data-gizmo=\"scale\" title=\"Scale (R)\"\n @click=${() => this._setGizmoMode('scale')}>\n <svg viewBox=\"0 0 20 20\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <line x1=\"4\" y1=\"16\" x2=\"16\" y2=\"4\"/>\n <rect x=\"2\" y=\"13\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n <rect x=\"14\" y=\"2\" width=\"4\" height=\"4\" rx=\"0.5\" fill=\"currentColor\"/>\n </svg>\n </span>\n ` : ''}\n\n <span class=\"vline\"></span>\n\n <span button id=\"font-increase\" title=\"increase font size\" @click=${this.onTapFontIncrease}></span>\n <span button id=\"font-decrease\" title=\"decrease font size\" style=\"scale: 0.7;\" @click=${this.onTapFontDecrease}></span>\n\n <span class=\"vline\"></span>\n <span>(v${process.env['APP-VERSION']})</span>\n <span padding></span>\n\n <span button id=\"fit-scene\" title=\"fit scene (${this.getShortcutString('cmd', 'd')})\" @click=${this.onTapFitScene}> </span>\n\n <span class=\"vline\"></span>\n\n <span button id=\"preview\" title=\"preview (${this.getShortcutString('ctrl', 'p')})\" @click=${this.onTapPreview}> </span>\n\n <span button id=\"fullscreen\" title=\"fullscreen (${this.getShortcutString('f11')})\" @click=${this.onTapFullscreen}> </span>\n\n <span button id=\"toggle-property\"\n title=\"toggle property panel (${this.getShortcutString('cmd', 'h')})\"\n toggles=\"true\" @click=${this.onTapToggle}> </span>\n </div>\n `\n }\n\n hasEmptySlot() {\n const slot = this.renderRoot.querySelector('slot') as HTMLSlotElement\n return slot?.assignedNodes().length === 0\n }\n\n onWheelEvent(e: Event) {\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n getSymbol(key: string) {\n var symbol\n switch (key) {\n case 'cmd':\n case 'ctrl':\n symbol = MACOS ? '⌘' : 'Ctrl'\n break\n case 'shift':\n symbol = MACOS ? '⇧' : 'Shift'\n break\n case 'alt':\n case 'option':\n symbol = MACOS ? '⌥' : 'Alt'\n break\n case 'backspace':\n symbol = MACOS ? '⌫' : 'BackSpace'\n break\n case 'delete':\n symbol = MACOS ? '⌦' : 'Del'\n break\n default:\n symbol = key.toUpperCase()\n break\n }\n\n return symbol\n }\n\n private getShortcutString(...keys: string[]) {\n var symbols = []\n for (var i = 0; i < arguments.length; i++) {\n symbols.push(this.getSymbol(arguments[i]))\n }\n\n return symbols.join(MACOS ? '' : '+')\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n var altKey = e.altKey\n var shiftKey = e.shiftKey\n\n var defaultPrevent = ctrlKey || altKey\n\n switch (e.code) {\n case 'KeyZ':\n if (ctrlKey && !shiftKey) this.onTapUndo()\n else if (ctrlKey && shiftKey) this.onTapRedo()\n break\n case 'KeyY':\n if (ctrlKey && !shiftKey) this.onTapRedo()\n break\n case 'Digit1':\n if (ctrlKey) this.onStartStylePasteMode()\n break\n case 'Digit2':\n if (ctrlKey) this.onStartDatabindPasteMode()\n break\n case 'KeyC':\n if (ctrlKey && !shiftKey) this.onTapCopy()\n else if (altKey && shiftKey) this.onTapAlign('center')\n break\n case 'KeyX':\n if (ctrlKey && !shiftKey) this.onTapCut()\n break\n case 'KeyV':\n if (ctrlKey && shiftKey && !altKey) {\n // Ctrl+Shift+V = Bulk Paste (Paste Special 컨벤션) — 클립보드의\n // 단일 컴포넌트를 N개로 일괄 붙여넣기.\n this.onBulkPaste()\n defaultPrevent = true\n } else if (ctrlKey && !shiftKey) {\n this.onTapPaste()\n defaultPrevent = false\n } else if (altKey && shiftKey) this.onTapDistribute('VERTICAL')\n break\n case 'Delete':\n case 'Backspace':\n this.onTapDelete()\n defaultPrevent = true\n break\n case 'KeyG':\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) this.onTapGroup()\n else if (ctrlKey && shiftKey) this.onTapUngroup()\n }\n break\n case 'BracketRight':\n // Ctrl+] = Bring Forward, Ctrl+Shift+] = Bring to Front\n // (Photoshop / Illustrator 표준 컨벤션)\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) {\n this.scene?.zorder('forward')\n defaultPrevent = true\n } else if (ctrlKey && shiftKey) {\n this.scene?.zorder('front')\n defaultPrevent = true\n }\n }\n break\n case 'BracketLeft':\n // Ctrl+[ = Send Backward, Ctrl+Shift+[ = Send to Back\n if (this._dimension === '2d') {\n if (ctrlKey && !shiftKey) {\n this.scene?.zorder('backward')\n defaultPrevent = true\n } else if (ctrlKey && shiftKey) {\n this.scene?.zorder('back')\n defaultPrevent = true\n }\n }\n break\n case 'KeyB':\n // zorder 는 BracketLeft 로 이동. KeyB 의 Alt+Shift+B = align bottom 만 유지.\n if (altKey && shiftKey) this.onTapAlign('bottom')\n break\n case 'KeyH':\n if (ctrlKey && !shiftKey) this.onTapToggle()\n else if (altKey && shiftKey) this.onTapDistribute('HORIZONTAL')\n break\n case 'F11':\n this.onTapFullscreen()\n defaultPrevent = true\n break\n case 'KeyP':\n if (ctrlKey) {\n this.onTapPreview()\n defaultPrevent = true\n }\n break\n case 'KeyA':\n if (ctrlKey) this.onTapSelectAll()\n break\n case 'KeyL':\n if (altKey && shiftKey) this.onTapAlign('left')\n break\n case 'KeyR':\n if (altKey && shiftKey) this.onTapAlign('right')\n break\n case 'KeyM':\n if (altKey && shiftKey) this.onTapAlign('middle')\n break\n case 'KeyT':\n if (altKey && shiftKey) this.onTapAlign('top')\n break\n case 'KeyD':\n if (ctrlKey) {\n this.onTapFitScene()\n defaultPrevent = true\n }\n break\n case 'KeyE':\n if (ctrlKey && shiftKey) this.onTapDownloadModel()\n break\n\n case 'Escape':\n this.scene?.stopStylePasteMode()\n this.scene?.stopDatabindPasteMode()\n defaultPrevent = true\n break\n\n default:\n return false\n }\n\n if (defaultPrevent) e.preventDefault()\n return true\n }\n\n private _setDisabled(id: string, disabled: boolean) {\n const el = this.renderRoot.querySelector(`#${id}`)\n disabled ? el?.setAttribute('disabled', '') : el?.removeAttribute('disabled')\n }\n\n onExecute(command: string, undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onUndo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onRedo(undoable: boolean, redoable: boolean) {\n this._setDisabled('undo', !undoable)\n this._setDisabled('redo', !redoable)\n }\n\n onSceneChanged(after?: Scene, before?: Scene) {\n if (before) {\n before.off('execute', this.onExecute, this)\n before.off('undo', this.onUndo, this)\n before.off('redo', this.onRedo, this)\n before.off('dimension', this._onDimensionChanged, this)\n before.off('gizmoattach', this._onGizmoAttachChanged, this)\n }\n\n if (after) {\n after.on('execute', this.onExecute, this)\n after.on('undo', this.onUndo, this)\n after.on('redo', this.onRedo, this)\n after.on('dimension', this._onDimensionChanged, this)\n after.on('gizmoattach', this._onGizmoAttachChanged, this)\n\n // scene 설정 시 현재 dimension을 즉시 반영 (초기 이벤트를 놓친 경우 대비)\n const threed = (after as any).model_layer?.model?.threed\n this._dimension = threed ? '3d' : '2d'\n }\n }\n\n private _onDimensionChanged(dimension: '2d' | '3d') {\n this._dimension = dimension\n }\n\n private _onGizmoAttachChanged(isAttached: boolean) {\n this._gizmoAttached = isAttached\n }\n\n private _setGizmoMode(mode: 'translate' | 'rotate' | 'scale') {\n ;(this.scene?.root as any)?.setGizmoMode(mode)\n }\n\n onSelectedChanged(after: Component[], before: Component[]) {\n var hasSelection = after.length > 0\n var alignable = after.length > 1\n\n // 선택 필요 버튼\n ;['style-copy', 'databind-copy', 'cut', 'copy', 'delete'].forEach(id =>\n this._setDisabled(id, !hasSelection)\n )\n\n // 정렬 버튼\n this.renderRoot.querySelectorAll('[data-align]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '2d') {\n var movable = after.length === 1\n\n /* forward, backward 이동은 한 컴포넌트만 가능하다. */\n this._setDisabled('forward', !movable)\n this._setDisabled('backward', !movable)\n\n /* 여러 컴포넌트는 front, back 이동이 가능하다. */\n this._setDisabled('front', !(alignable || movable))\n this._setDisabled('back', !(alignable || movable))\n }\n\n // 분배 버튼\n this.renderRoot.querySelectorAll('[data-distribute]').forEach(el =>\n alignable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '')\n )\n\n if (this._dimension === '3d') {\n this.renderRoot.querySelectorAll('.gizmo-btn').forEach(btn => {\n hasSelection ? btn.removeAttribute('disabled') : btn.setAttribute('disabled', '')\n })\n }\n }\n\n onTapUndo() {\n this.scene?.undo()\n }\n\n onTapRedo() {\n this.scene?.redo()\n }\n\n onStartStylePasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startStylePasteMode()\n }\n\n onStartDatabindPasteMode() {\n if (this.selected?.length !== 1) return\n if (this.selected[0] === this.scene?.root) return\n this.scene?.startDatabindPasteMode()\n }\n\n onTapCut() {\n this.scene?.cut()\n }\n\n async onTapCopy() {\n var copied = this.scene?.copy()\n\n if (!copied) return\n\n await copyToClipboard(copied)\n this.cliped = copied\n }\n\n onTapPaste() {\n setTimeout(() => {\n this.cliped && this.scene?.paste(this.cliped)\n }, 100)\n }\n\n onTapDelete() {\n this.scene?.remove()\n }\n\n /**\n * 멀티 컴포넌트 일괄 붙여넣기 — Ctrl+Shift+V 진입점.\n *\n * 흐름:\n * 1. 클립보드 (this.cliped) 검증 — *단일* 컴포넌트만 허용\n * 2. scene.startBulkCreateMode → AddLayer 가 캔버스 위에 드래그 박스 그림\n * 3. 사용자가 영역 드래그 → Promise resolve({area, template})\n * ESC/취소 → Promise resolve(null)\n * 4. 영역이 결정되면 dialog 오픈\n */\n async onBulkPaste() {\n if (!this.cliped) {\n console.warn('bulk-paste: 먼저 Ctrl+C 로 컴포넌트를 복사하세요.')\n return\n }\n let parsed: any[]\n try {\n parsed = JSON.parse(this.cliped)\n } catch (e) {\n console.warn('bulk-paste: 클립보드 파싱 실패', e)\n return\n }\n if (!Array.isArray(parsed) || parsed.length === 0) {\n console.warn('bulk-paste: 클립보드 비어있음')\n return\n }\n if (parsed.length > 1) {\n console.warn('bulk-paste: 단일 컴포넌트만 일괄 붙여넣기 가능. 다중은 일반 paste 사용.')\n return\n }\n\n const template = parsed[0]\n // bulk 모드 임을 시각 구분하기 위해 파란 점선 (일반 add 의 검정과 색만 차별).\n const result = await this.scene?.startBulkCreateMode(template, { boxStrokeStyle: '#2964c2' })\n if (result) {\n this._openBulkCreateDialog(template, result.area)\n }\n }\n\n private _openBulkCreateDialog(\n template: Record<string, any>,\n initialArea: { left: number; top: number; width: number; height: number }\n ) {\n const dialogEl = document.createElement('bulk-create-dialog') as BulkCreateDialog\n dialogEl.template = template\n dialogEl.initialArea = initialArea\n // 충돌 검사용 — scene 의 모든 컴포넌트 id 수집.\n // (scene.ids 는 indexMap 기반인데 fmsim 의 일부 컴포넌트는 indexMap 미등록\n // 되는 케이스가 있어 직접 컴포넌트 트리 walk.)\n const existingIds = new Set<string>()\n const collectIds = (comp: any) => {\n if (!comp) return\n const id = comp?.state?.id ?? comp?.model?.id\n if (typeof id === 'string' && id) existingIds.add(id)\n const children = comp.components || []\n for (const c of children) collectIds(c)\n }\n const root = (this.scene as any)?.root\n if (root) collectIds(root)\n dialogEl.existingIds = existingIds\n dialogEl.onConfirm = (models) => {\n const scene = this.scene\n if (!scene || !models.length) {\n popup?.close()\n return\n }\n // cliped 의 template model 자체에서 type-aware bounds 추출. things-scene 의\n // component.bounds (= path bounding box) 와 동일 결과를 model JSON 의\n // type-specific 필드 (width/height, rx/ry, points) 만으로 계산.\n const bounds = deriveBoundsFromModel(template)\n scene.undoableChange(() => {\n for (const m of models) {\n const cx = m.left + m.width / 2\n const cy = m.top + m.height / 2\n scene.add(m, {\n left: cx - bounds.width / 2,\n top: cy - bounds.height / 2,\n width: bounds.width,\n height: bounds.height\n })\n }\n })\n popup?.close()\n }\n dialogEl.onCancel = () => {\n popup?.close()\n }\n const popup = OxPopup.open({\n template: dialogEl,\n backdrop: true\n })\n }\n\n onTapSelectAll() {\n this.scene?.select('(child)')\n }\n\n onTapFontIncrease(e: TouchEvent) {\n var selected = this.scene?.selected\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n component.set('fontSize', size + 1)\n }\n })\n })\n }\n\n onTapFontDecrease(e: TouchEvent) {\n var selected = this.scene?.selected\n\n if (!selected || !selected.length) {\n return\n }\n\n this.scene?.undoableChange(function () {\n selected!.forEach(function (component: Component) {\n var fontSize = component.get('fontSize')\n\n if (!fontSize) fontSize = '15'\n\n if (fontSize) {\n var size = parseInt(fontSize)\n if (size > 1) component.set('fontSize', size - 1)\n }\n })\n })\n }\n\n onTapAlign(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n\n var align = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-align')\n if (!align) {\n return\n }\n\n if (selected.length <= 1) {\n this.scene.place(align)\n } else {\n this.scene.align(align)\n }\n }\n\n onTapZorder(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length < 1) return\n\n var zorder = typeof e === 'string' ? e : (e.target as HTMLElement).getAttribute('data-zorder')\n\n zorder && this.scene.zorder(zorder)\n }\n\n onTapGroup() {\n this.scene && this.scene.group()\n }\n\n onTapUngroup() {\n this.scene && this.scene.ungroup()\n }\n\n onTapFullscreen() {\n this.dispatchEvent(new CustomEvent('modeller-fullscreen'))\n }\n\n onTapToggle() {\n this.hideProperty = !this.hideProperty\n this.dispatchEvent(\n new CustomEvent('hide-property-changed', {\n bubbles: true,\n composed: true,\n detail: { value: this.hideProperty }\n })\n )\n }\n\n onTapFitScene() {\n if (this.scene) {\n this.scene.resize()\n this.scene.fit('ratio')\n }\n }\n\n onTapPreview() {\n this.dispatchEvent(new CustomEvent('open-preview'))\n }\n\n onTapDownloadModel() {\n this.dispatchEvent(new CustomEvent('download-model'))\n }\n\n onTapDistribute(e: TouchEvent | string) {\n if (!this.scene) return\n\n var selected = this.scene.selected\n if (selected.length <= 1) {\n return\n }\n\n var distribute = typeof e === 'string' ? e : (e.target as HTMLElement)!.getAttribute('data-distribute')\n\n distribute && this.scene.distribute(distribute)\n }\n}\n"]}
@@ -23,9 +23,17 @@ export class AbstractProperty extends LitElement {
23
23
  case 'checkbox':
24
24
  value = element.checked;
25
25
  break;
26
- case 'number':
27
- value = Number(element.valueAsNumber);
26
+ case 'number': {
27
+ // Empty or invalid numeric input (e.g. user cleared the field)
28
+ // produces NaN via `valueAsNumber`. Persisting NaN poisons every
29
+ // downstream Math.* call and eventually surfaces as
30
+ // "BufferGeometry computeBoundingSphere: radius is NaN".
31
+ // Emit `undefined` so the component falls back to its default
32
+ // (e.g. Placeable's defaultDepth = operation - floor).
33
+ const n = element.valueAsNumber;
34
+ value = Number.isFinite(n) ? n : undefined;
28
35
  break;
36
+ }
29
37
  case 'text':
30
38
  value = String(element.value);
31
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-property.js","sourceRoot":"","sources":["../../../../src/modeller/property-sidebar/abstract-property.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAEhC,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,IAAI,OAAO,GAAG,CAAC,CAAC,MAAqB,CAAA;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAE3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QAED,IAAI,KAAK,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;QAElD,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,wBAAwB,CAAC,OAAoB;QAC3C,IAAI,KAAK,CAAA;QAET,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;YACxB,KAAK,OAAO;gBACV,QAAS,OAAe,CAAC,IAAI,EAAE,CAAC;oBAC9B,KAAK,UAAU;wBACb,KAAK,GAAI,OAAe,CAAC,OAAO,CAAA;wBAChC,MAAK;oBACP,KAAK,QAAQ;wBACX,KAAK,GAAG,MAAM,CAAE,OAAe,CAAC,aAAa,CAAC,CAAA;wBAC9C,MAAK;oBACP,KAAK,MAAM;wBACT,KAAK,GAAG,MAAM,CAAE,OAAe,CAAC,KAAK,CAAC,CAAA;gBAC1C,CAAC;gBACD,MAAK;YAEP,KAAK,cAAc;gBACjB,KAAK,GAAI,OAAe,CAAC,MAAM,CAAA;gBAC/B,MAAK;YAEP,KAAK,eAAe;gBAClB,KAAK,GAAI,OAAe,CAAC,QAAQ,CAAA;gBACjC,MAAK;YAEP;gBACE,KAAK,GAAI,OAAe,CAAC,KAAK,CAAA;gBAC9B,MAAK;QACT,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,mBAAmB,CAAC,GAAW,EAAE,KAAU;QACzC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;YACjC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,CAAC,GAAG,CAAC,EAAE,KAAK;aACb;SACF,CAAC,CACH,CAAA;IACH,CAAC;CACF","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { LitElement } from 'lit'\n\nexport class AbstractProperty extends LitElement {\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n _onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this._getValueFromEventTarget(element)\n\n this._onAfterValueChange(key, value)\n }\n\n _getValueFromEventTarget(element: HTMLElement) {\n var value\n\n switch (element.tagName) {\n case 'INPUT':\n switch ((element as any).type) {\n case 'checkbox':\n value = (element as any).checked\n break\n case 'number':\n value = Number((element as any).valueAsNumber)\n break\n case 'text':\n value = String((element as any).value)\n }\n break\n\n case 'PAPER-BUTTON':\n value = (element as any).active\n break\n\n case 'PAPER-LISTBOX':\n value = (element as any).selected\n break\n\n default:\n value = (element as any).value\n break\n }\n\n return value\n }\n\n _onAfterValueChange(key: string, value: any) {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n [key]: value\n }\n })\n )\n }\n}\n"]}
1
+ {"version":3,"file":"abstract-property.js","sourceRoot":"","sources":["../../../../src/modeller/property-sidebar/abstract-property.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAEhC,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,IAAI,OAAO,GAAG,CAAC,CAAC,MAAqB,CAAA;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAE3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QAED,IAAI,KAAK,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;QAElD,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,wBAAwB,CAAC,OAAoB;QAC3C,IAAI,KAAK,CAAA;QAET,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;YACxB,KAAK,OAAO;gBACV,QAAS,OAAe,CAAC,IAAI,EAAE,CAAC;oBAC9B,KAAK,UAAU;wBACb,KAAK,GAAI,OAAe,CAAC,OAAO,CAAA;wBAChC,MAAK;oBACP,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACd,+DAA+D;wBAC/D,iEAAiE;wBACjE,oDAAoD;wBACpD,yDAAyD;wBACzD,8DAA8D;wBAC9D,uDAAuD;wBACvD,MAAM,CAAC,GAAI,OAAe,CAAC,aAAa,CAAA;wBACxC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;wBAC1C,MAAK;oBACP,CAAC;oBACD,KAAK,MAAM;wBACT,KAAK,GAAG,MAAM,CAAE,OAAe,CAAC,KAAK,CAAC,CAAA;gBAC1C,CAAC;gBACD,MAAK;YAEP,KAAK,cAAc;gBACjB,KAAK,GAAI,OAAe,CAAC,MAAM,CAAA;gBAC/B,MAAK;YAEP,KAAK,eAAe;gBAClB,KAAK,GAAI,OAAe,CAAC,QAAQ,CAAA;gBACjC,MAAK;YAEP;gBACE,KAAK,GAAI,OAAe,CAAC,KAAK,CAAA;gBAC9B,MAAK;QACT,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,mBAAmB,CAAC,GAAW,EAAE,KAAU;QACzC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;YACjC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,CAAC,GAAG,CAAC,EAAE,KAAK;aACb;SACF,CAAC,CACH,CAAA;IACH,CAAC;CACF","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { LitElement } from 'lit'\n\nexport class AbstractProperty extends LitElement {\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n _onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this._getValueFromEventTarget(element)\n\n this._onAfterValueChange(key, value)\n }\n\n _getValueFromEventTarget(element: HTMLElement) {\n var value\n\n switch (element.tagName) {\n case 'INPUT':\n switch ((element as any).type) {\n case 'checkbox':\n value = (element as any).checked\n break\n case 'number': {\n // Empty or invalid numeric input (e.g. user cleared the field)\n // produces NaN via `valueAsNumber`. Persisting NaN poisons every\n // downstream Math.* call and eventually surfaces as\n // \"BufferGeometry computeBoundingSphere: radius is NaN\".\n // Emit `undefined` so the component falls back to its default\n // (e.g. Placeable's defaultDepth = operation - floor).\n const n = (element as any).valueAsNumber\n value = Number.isFinite(n) ? n : undefined\n break\n }\n case 'text':\n value = String((element as any).value)\n }\n break\n\n case 'PAPER-BUTTON':\n value = (element as any).active\n break\n\n case 'PAPER-LISTBOX':\n value = (element as any).selected\n break\n\n default:\n value = (element as any).value\n break\n }\n\n return value\n }\n\n _onAfterValueChange(key: string, value: any) {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n [key]: value\n }\n })\n )\n }\n}\n"]}
@@ -9,7 +9,7 @@ import { PropertyValues } from 'lit';
9
9
  import { Properties, Scene } from '@hatiolab/things-scene';
10
10
  import { AbstractProperty } from '../abstract-property.js';
11
11
  import { DataBindingMapper } from './data-binding-mapper.js';
12
- declare const PropertyDataBinding_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types.js").ScopedElementsHost>;
12
+ declare const PropertyDataBinding_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
13
13
  export declare class PropertyDataBinding extends PropertyDataBinding_base {
14
14
  static styles: import("lit").CSSResult[];
15
15
  value?: Properties;
@@ -6,7 +6,7 @@ import { Component, Properties, Scene } from '@hatiolab/things-scene';
6
6
  import { AbstractProperty } from '../abstract-property.js';
7
7
  import { PropertyEvent } from './property-event.js';
8
8
  import { PropertyShadow } from './property-shadow.js';
9
- declare const PropertyEffects_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types.js").ScopedElementsHost>;
9
+ declare const PropertyEffects_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
10
10
  export declare class PropertyEffects extends PropertyEffects_base {
11
11
  static styles: import("lit").CSSResult[];
12
12
  value?: Properties;
@@ -18,5 +18,14 @@ export declare class PropertyEffects extends PropertyEffects_base {
18
18
  'property-event': typeof PropertyEvent;
19
19
  };
20
20
  render(): import("lit-html").TemplateResult<1>;
21
+ /**
22
+ * 3D 그림자 토글 — material3d.castShadow / receiveShadow 만 갱신.
23
+ *
24
+ * material3d 는 단일 객체 속성이므로 기존 material3d 전체를 보존한 채 해당
25
+ * 키만 덮어써 dispatch 한다 ({ castShadow } 만 보내면 set() 의 top-level shallow
26
+ * merge 로 material3d 전체가 사라짐). value-key 를 두지 않아 AbstractProperty
27
+ * 의 제너릭 change 핸들러는 이 입력을 무시한다.
28
+ */
29
+ private _onShadow3dChange;
21
30
  }
22
31
  export {};
@@ -25,7 +25,15 @@ export class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {
25
25
  };
26
26
  }
27
27
  render() {
28
+ var _a, _b, _c;
28
29
  const value = this.value || {};
30
+ // 3D 그림자 편집은 단일 선택 + 3D 표현 가능한 컴포넌트에서만 노출.
31
+ // (material3d 는 컴포넌트별 객체라 다중 선택 일괄 병합은 위험 — 단일로 제한.)
32
+ const target = this.selected.length == 1 ? this.selected[0] : null;
33
+ const is3d = !!((_a = target === null || target === void 0 ? void 0 : target.is3dish) === null || _a === void 0 ? void 0 : _a.call(target));
34
+ const material3d = value.material3d || {};
35
+ const castShadow = (_b = material3d.castShadow) !== null && _b !== void 0 ? _b : true;
36
+ const receiveShadow = (_c = material3d.receiveShadow) !== null && _c !== void 0 ? _c : false;
29
37
  return html `
30
38
  <fieldset>
31
39
  <legend>
@@ -35,11 +43,68 @@ export class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {
35
43
  <property-shadow value-key="shadow" .value=${value.shadow || {}}> </property-shadow>
36
44
  </fieldset>
37
45
 
46
+ ${is3d
47
+ ? html `
48
+ <fieldset>
49
+ <legend>
50
+ <ox-i18n topic="board-modeller/effects/shadow-3d" msgid="label.shadow-3d">3D shadow</ox-i18n>
51
+ </legend>
52
+
53
+ <div>
54
+ <input
55
+ id="cb-cast-shadow"
56
+ type="checkbox"
57
+ .checked=${castShadow}
58
+ @change=${(e) => this._onShadow3dChange('castShadow', e)}
59
+ />
60
+ <label for="cb-cast-shadow">
61
+ <ox-i18n msgid="label.cast-shadow">cast shadow</ox-i18n>
62
+ </label>
63
+
64
+ <input
65
+ id="cb-receive-shadow"
66
+ type="checkbox"
67
+ .checked=${receiveShadow}
68
+ @change=${(e) => this._onShadow3dChange('receiveShadow', e)}
69
+ />
70
+ <label for="cb-receive-shadow">
71
+ <ox-i18n msgid="label.receive-shadow">receive shadow</ox-i18n>
72
+ </label>
73
+ </div>
74
+ </fieldset>
75
+ `
76
+ : nothing}
77
+
38
78
  ${this.selected.length == 1
39
- ? html ` <property-event value-key="event" .scene=${this.scene} .value=${value.event || {}}> </property-event> `
79
+ ? html `
80
+ <property-event
81
+ value-key="eventHandlers"
82
+ .scene=${this.scene}
83
+ .value=${value.eventHandlers || []}
84
+ >
85
+ </property-event>
86
+ `
40
87
  : nothing}
41
88
  `;
42
89
  }
90
+ /**
91
+ * 3D 그림자 토글 — material3d.castShadow / receiveShadow 만 갱신.
92
+ *
93
+ * material3d 는 단일 객체 속성이므로 기존 material3d 전체를 보존한 채 해당
94
+ * 키만 덮어써 dispatch 한다 ({ castShadow } 만 보내면 set() 의 top-level shallow
95
+ * merge 로 material3d 전체가 사라짐). value-key 를 두지 않아 AbstractProperty
96
+ * 의 제너릭 change 핸들러는 이 입력을 무시한다.
97
+ */
98
+ _onShadow3dChange(key, e) {
99
+ var _a;
100
+ const checked = e.target.checked;
101
+ const current = ((_a = this.value) === null || _a === void 0 ? void 0 : _a.material3d) || {};
102
+ this.dispatchEvent(new CustomEvent('property-change', {
103
+ bubbles: true,
104
+ composed: true,
105
+ detail: { material3d: { ...current, [key]: checked } }
106
+ }));
107
+ }
43
108
  }
44
109
  PropertyEffects.styles = [PropertySharedStyle];
45
110
  __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"effects.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/effects/effects.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,0BAA0B,CAAA;AAEjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,OAAO,eAAgB,SAAQ,mBAAmB,CAAC,gBAAgB,CAAC;IAA1E;;QAK6B,aAAQ,GAAgB,EAAE,CAAA;IA8BvD,CAAC;IA5BC,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,iBAAiB,EAAE,cAAc;YACjC,gBAAgB,EAAE,aAAa;SAChC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,OAAO,IAAI,CAAA;;;;;;qDAMsC,KAAK,CAAC,MAAM,IAAI,EAAE;;;QAG/D,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC;YACzB,CAAC,CAAC,IAAI,CAAA,6CAA6C,IAAI,CAAC,KAAK,WAAW,KAAK,CAAC,KAAK,IAAI,EAAE,sBAAsB;YAC/G,CAAC,CAAC,OAAO;KACZ,CAAA;IACH,CAAC;;AAjCM,sBAAM,GAAG,CAAC,mBAAmB,CAAC,AAAxB,CAAwB;AAET;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAmB;AAClB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAc;AACd;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;iDAA2B","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/i18n/ox-i18n.js'\n\nimport { html, nothing } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component, Properties, Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { AbstractProperty } from '../abstract-property.js'\nimport { PropertySharedStyle } from '../property-shared-style.js'\nimport { PropertyEvent } from './property-event.js'\nimport { PropertyShadow } from './property-shadow.js'\n\nexport class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {\n static styles = [PropertySharedStyle]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: Component[] = []\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n static get scopedElements() {\n return {\n 'property-shadow': PropertyShadow,\n 'property-event': PropertyEvent\n }\n }\n\n render() {\n const value = this.value || {}\n\n return html`\n <fieldset>\n <legend>\n <ox-i18n topic=\"board-modeller/effects/shadow\" msgid=\"label.shadow\">shadow</ox-i18n>\n </legend>\n\n <property-shadow value-key=\"shadow\" .value=${value.shadow || {}}> </property-shadow>\n </fieldset>\n\n ${this.selected.length == 1\n ? html` <property-event value-key=\"event\" .scene=${this.scene} .value=${value.event || {}}> </property-event> `\n : nothing}\n `\n }\n}\n"]}
1
+ {"version":3,"file":"effects.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/effects/effects.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/i18n/ox-i18n.js'\n\nimport { html, nothing } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component, Properties, Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { AbstractProperty } from '../abstract-property.js'\nimport { PropertySharedStyle } from '../property-shared-style.js'\nimport { PropertyEvent } from './property-event.js'\nimport { PropertyShadow } from './property-shadow.js'\n\nexport class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {\n static styles = [PropertySharedStyle]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: Component[] = []\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n static get scopedElements() {\n return {\n 'property-shadow': PropertyShadow,\n 'property-event': PropertyEvent\n }\n }\n\n render() {\n const value = this.value || {}\n\n // 3D 그림자 편집은 단일 선택 + 3D 표현 가능한 컴포넌트에서만 노출.\n // (material3d 는 컴포넌트별 객체라 다중 선택 일괄 병합은 위험 — 단일로 제한.)\n const target = this.selected.length == 1 ? (this.selected[0] as any) : null\n const is3d = !!target?.is3dish?.()\n const material3d = (value.material3d as any) || {}\n const castShadow = material3d.castShadow ?? true\n const receiveShadow = material3d.receiveShadow ?? false\n\n return html`\n <fieldset>\n <legend>\n <ox-i18n topic=\"board-modeller/effects/shadow\" msgid=\"label.shadow\">shadow</ox-i18n>\n </legend>\n\n <property-shadow value-key=\"shadow\" .value=${value.shadow || {}}> </property-shadow>\n </fieldset>\n\n ${is3d\n ? html`\n <fieldset>\n <legend>\n <ox-i18n topic=\"board-modeller/effects/shadow-3d\" msgid=\"label.shadow-3d\">3D shadow</ox-i18n>\n </legend>\n\n <div>\n <input\n id=\"cb-cast-shadow\"\n type=\"checkbox\"\n .checked=${castShadow}\n @change=${(e: Event) => this._onShadow3dChange('castShadow', e)}\n />\n <label for=\"cb-cast-shadow\">\n <ox-i18n msgid=\"label.cast-shadow\">cast shadow</ox-i18n>\n </label>\n\n <input\n id=\"cb-receive-shadow\"\n type=\"checkbox\"\n .checked=${receiveShadow}\n @change=${(e: Event) => this._onShadow3dChange('receiveShadow', e)}\n />\n <label for=\"cb-receive-shadow\">\n <ox-i18n msgid=\"label.receive-shadow\">receive shadow</ox-i18n>\n </label>\n </div>\n </fieldset>\n `\n : nothing}\n\n ${this.selected.length == 1\n ? html`\n <property-event\n value-key=\"eventHandlers\"\n .scene=${this.scene}\n .value=${value.eventHandlers || []}\n >\n </property-event>\n `\n : nothing}\n `\n }\n\n /**\n * 3D 그림자 토글 — material3d.castShadow / receiveShadow 만 갱신.\n *\n * material3d 는 단일 객체 속성이므로 기존 material3d 전체를 보존한 채 해당\n * 키만 덮어써 dispatch 한다 ({ castShadow } 만 보내면 set() 의 top-level shallow\n * merge 로 material3d 전체가 사라짐). value-key 를 두지 않아 AbstractProperty\n * 의 제너릭 change 핸들러는 이 입력을 무시한다.\n */\n private _onShadow3dChange(key: 'castShadow' | 'receiveShadow', e: Event) {\n const checked = (e.target as HTMLInputElement).checked\n const current = (this.value?.material3d as any) || {}\n\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: { material3d: { ...current, [key]: checked } }\n })\n )\n }\n}\n"]}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ *
4
+ * 기존 PropertyEvent UI 는 legacy `state.event = { tap: {...} }` 단일 객체
5
+ * 모델 위에 만들어졌으나, things-scene v10 의 신규 모델은
6
+ * `state.eventHandlers: EventHandler[]` 다중 핸들러 배열. dispatcher 가
7
+ * legacy fallback 도 지원하지만, UI 가 신규 모델로 직접 read/write 하도록
8
+ * 정합화한다.
9
+ *
10
+ * 정책 — 사용자 의도에 따른 *최소 호환*:
11
+ * - 신규 모델의 multi-trigger / multi-handler 는 미지원
12
+ * - 기존 UI 그대로 — tap (click) 단일 핸들러만
13
+ * - 다른 trigger 의 핸들러가 이미 배열에 있으면 *건드리지 않는다*
14
+ * (UI 가 모르는 항목은 보존)
15
+ */
16
+ /**
17
+ * EventHandler — things-scene v10 의 신규 모델 spec 미러.
18
+ * things-scene root export 에 아직 포함되지 않아 inline 정의.
19
+ * (참조: things-scene/src/interfaces/event-handler.ts:29)
20
+ */
21
+ export interface EventHandler {
22
+ trigger: string;
23
+ action?: string;
24
+ code?: string;
25
+ target?: string;
26
+ value?: any;
27
+ options?: Record<string, any>;
28
+ disabled?: boolean;
29
+ }
30
+ /** legacy tap 객체 형태 — PropertyEventTap UI 가 다루는 모양. */
31
+ export interface LegacyTap {
32
+ action?: string;
33
+ target?: string;
34
+ value?: any;
35
+ pressed?: boolean;
36
+ options?: Record<string, any>;
37
+ }
38
+ /** trigger 가 click/tap 인 첫 핸들러를 legacy tap 객체로 변환. */
39
+ export declare function eventHandlersToLegacyTap(handlers: EventHandler[] | undefined): LegacyTap;
40
+ /**
41
+ * 기존 배열에서 click/tap 항목을 새 값으로 교체 (또는 push, 또는 제거).
42
+ * 다른 trigger 항목은 그대로 보존.
43
+ */
44
+ export declare function applyLegacyTapToHandlers(handlers: EventHandler[] | undefined, newTap: LegacyTap | undefined): EventHandler[];
@@ -0,0 +1,70 @@
1
+ /** trigger 가 click/tap 인 첫 핸들러를 legacy tap 객체로 변환. */
2
+ export function eventHandlersToLegacyTap(handlers) {
3
+ var _a, _b;
4
+ if (!Array.isArray(handlers))
5
+ return {};
6
+ const h = handlers.find(h => h.trigger === 'click' || h.trigger === 'tap');
7
+ if (!h)
8
+ return {};
9
+ // action='script' 인 경우 code 를 value 자리로 노출 — legacy UI 가 value
10
+ // 텍스트 영역에 script 를 넣어 쓰던 관습 보존.
11
+ if (h.action === 'script') {
12
+ return { action: 'script', target: h.target, value: (_a = h.code) !== null && _a !== void 0 ? _a : '' };
13
+ }
14
+ return {
15
+ action: h.action,
16
+ target: h.target,
17
+ value: h.value,
18
+ pressed: (_b = h.options) === null || _b === void 0 ? void 0 : _b.pressed,
19
+ options: h.options
20
+ };
21
+ }
22
+ /** legacy tap 객체 → EventHandler. action 없으면 null (= 삭제 의미). */
23
+ function legacyTapToEventHandler(tap) {
24
+ var _a;
25
+ if (!tap)
26
+ return null;
27
+ // action 이 비어있고 target/value 도 없으면 의미 있는 데이터 없음 → 제거
28
+ const hasContent = !!(tap.action || tap.target || tap.value);
29
+ if (!hasContent)
30
+ return null;
31
+ if (tap.action === 'script') {
32
+ return {
33
+ trigger: 'click',
34
+ action: 'script',
35
+ code: typeof tap.value === 'string' ? tap.value : '',
36
+ target: tap.target
37
+ };
38
+ }
39
+ // pressed 는 legacy 의 *최상위 키* 였지만 신규 모델에선 options 의 일부.
40
+ const options = { ...((_a = tap.options) !== null && _a !== void 0 ? _a : {}) };
41
+ if (tap.pressed !== undefined)
42
+ options.pressed = tap.pressed;
43
+ return {
44
+ trigger: 'click',
45
+ action: tap.action,
46
+ target: tap.target,
47
+ value: tap.value,
48
+ ...(Object.keys(options).length > 0 ? { options } : {})
49
+ };
50
+ }
51
+ /**
52
+ * 기존 배열에서 click/tap 항목을 새 값으로 교체 (또는 push, 또는 제거).
53
+ * 다른 trigger 항목은 그대로 보존.
54
+ */
55
+ export function applyLegacyTapToHandlers(handlers, newTap) {
56
+ const out = Array.isArray(handlers) ? [...handlers] : [];
57
+ const idx = out.findIndex(h => h.trigger === 'click' || h.trigger === 'tap');
58
+ const newHandler = legacyTapToEventHandler(newTap);
59
+ if (newHandler) {
60
+ if (idx >= 0)
61
+ out[idx] = newHandler;
62
+ else
63
+ out.push(newHandler);
64
+ }
65
+ else if (idx >= 0) {
66
+ out.splice(idx, 1);
67
+ }
68
+ return out;
69
+ }
70
+ //# sourceMappingURL=event-handler-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-handler-adapter.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/effects/event-handler-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * 기존 PropertyEvent UI 는 legacy `state.event = { tap: {...} }` 단일 객체\n * 모델 위에 만들어졌으나, things-scene v10 의 신규 모델은\n * `state.eventHandlers: EventHandler[]` 다중 핸들러 배열. dispatcher 가\n * legacy fallback 도 지원하지만, UI 가 신규 모델로 직접 read/write 하도록\n * 정합화한다.\n *\n * 정책 — 사용자 의도에 따른 *최소 호환*:\n * - 신규 모델의 multi-trigger / multi-handler 는 미지원\n * - 기존 UI 그대로 — tap (click) 단일 핸들러만\n * - 다른 trigger 의 핸들러가 이미 배열에 있으면 *건드리지 않는다*\n * (UI 가 모르는 항목은 보존)\n */\n/**\n * EventHandler — things-scene v10 의 신규 모델 spec 미러.\n * things-scene root export 에 아직 포함되지 않아 inline 정의.\n * (참조: things-scene/src/interfaces/event-handler.ts:29)\n */\nexport interface EventHandler {\n trigger: string\n action?: string\n code?: string\n target?: string\n value?: any\n options?: Record<string, any>\n disabled?: boolean\n}\n\n/** legacy tap 객체 형태 — PropertyEventTap UI 가 다루는 모양. */\nexport interface LegacyTap {\n action?: string\n target?: string\n value?: any\n pressed?: boolean\n options?: Record<string, any>\n}\n\n/** trigger 가 click/tap 인 첫 핸들러를 legacy tap 객체로 변환. */\nexport function eventHandlersToLegacyTap(handlers: EventHandler[] | undefined): LegacyTap {\n if (!Array.isArray(handlers)) return {}\n const h = handlers.find(h => h.trigger === 'click' || h.trigger === 'tap')\n if (!h) return {}\n\n // action='script' 인 경우 code 를 value 자리로 노출 — legacy UI 가 value\n // 텍스트 영역에 script 를 넣어 쓰던 관습 보존.\n if (h.action === 'script') {\n return { action: 'script', target: h.target, value: h.code ?? '' }\n }\n\n return {\n action: h.action,\n target: h.target,\n value: h.value,\n pressed: h.options?.pressed,\n options: h.options\n }\n}\n\n/** legacy tap 객체 → EventHandler. action 없으면 null (= 삭제 의미). */\nfunction legacyTapToEventHandler(tap: LegacyTap | undefined): EventHandler | null {\n if (!tap) return null\n // action 이 비어있고 target/value 도 없으면 의미 있는 데이터 없음 → 제거\n const hasContent = !!(tap.action || tap.target || tap.value)\n if (!hasContent) return null\n\n if (tap.action === 'script') {\n return {\n trigger: 'click',\n action: 'script',\n code: typeof tap.value === 'string' ? tap.value : '',\n target: tap.target\n }\n }\n\n // pressed 는 legacy 의 *최상위 키* 였지만 신규 모델에선 options 의 일부.\n const options: Record<string, any> = { ...(tap.options ?? {}) }\n if (tap.pressed !== undefined) options.pressed = tap.pressed\n\n return {\n trigger: 'click',\n action: tap.action,\n target: tap.target,\n value: tap.value,\n ...(Object.keys(options).length > 0 ? { options } : {})\n }\n}\n\n/**\n * 기존 배열에서 click/tap 항목을 새 값으로 교체 (또는 push, 또는 제거).\n * 다른 trigger 항목은 그대로 보존.\n */\nexport function applyLegacyTapToHandlers(\n handlers: EventHandler[] | undefined,\n newTap: LegacyTap | undefined\n): EventHandler[] {\n const out: EventHandler[] = Array.isArray(handlers) ? [...handlers] : []\n const idx = out.findIndex(h => h.trigger === 'click' || h.trigger === 'tap')\n const newHandler = legacyTapToEventHandler(newTap)\n\n if (newHandler) {\n if (idx >= 0) out[idx] = newHandler\n else out.push(newHandler)\n } else if (idx >= 0) {\n out.splice(idx, 1)\n }\n return out\n}\n"]}
@@ -2,12 +2,22 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
  import { LitElement } from 'lit';
5
- import { Properties, Scene } from '@hatiolab/things-scene';
5
+ import { Scene } from '@hatiolab/things-scene';
6
6
  import { PropertyEventTap } from './property-event-tap';
7
- declare const PropertyEvent_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types").ScopedElementsHost>;
7
+ import { EventHandler } from './event-handler-adapter.js';
8
+ declare const PropertyEvent_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
9
+ /**
10
+ * things-scene v10 의 신규 모델 (`state.eventHandlers: EventHandler[]`) 위에서
11
+ * 기존 단일-tap UI 를 그대로 동작시키는 어댑터.
12
+ *
13
+ * read : eventHandlers 배열에서 trigger='click'/'tap' 인 첫 항목 → legacy tap
14
+ * 객체로 변환 후 PropertyEventTap 에 전달.
15
+ * write: PropertyEventTap 이 emit 한 legacy tap 변경 → click 항목을 update/push
16
+ * 한 새 배열로 외부에 emit. 다른 trigger 의 핸들러는 보존.
17
+ */
8
18
  export declare class PropertyEvent extends PropertyEvent_base {
9
19
  static styles: import("lit").CSSResult[];
10
- value?: Properties;
20
+ value?: EventHandler[];
11
21
  scene?: Scene;
12
22
  firstUpdated(): void;
13
23
  static get scopedElements(): {