polarvo-layout 1.0.19 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/FastMenu/DesignFastmenu.vue +2 -2
- package/src/components/FastMenu/DisplayFastMenu.vue +2 -2
- package/src/components/FastMenu/LayoutFastMenu.vue +18 -10
- package/src/components/Layout/CanvasContainer.vue +30 -6
- package/src/components/SideBar/ElementSideBar.vue +2 -2
- package/src/components/SideBar/LayoutSettingSideBar.vue +18 -10
- package/src/components/SideBar/LayoutSideBar.vue +19 -8
- package/src/configs/index.js +1 -0
- package/src/core/engines/DisplayEngine.js +72 -64
- package/src/core/engines/FreeDropEngine.js +40 -42
- package/src/core/engines/GridDropEngine.js +33 -43
- package/src/core/engines/HistoryEngine.js +55 -51
- package/src/core/engines/LayoutEngine.js +89 -68
- package/src/core/engines/originals/FreeDropEngine_0402.js +786 -0
- package/src/core/engines/originals/GridDropEngine_0402.js +557 -0
- package/src/core/managers/EngineManager.js +93 -131
- package/src/core/managers/originals/EngineManager_0402.js +826 -0
- package/src/library/DisplayLibrary.js +14 -17
- package/src/library/FreeDropLibrary.js +6 -4
- package/src/library/GridDropLibrary.js +3 -5
- package/src/library/LayoutLibrary.js +45 -48
- package/src/library/originals/DisplayLibrary_0402.js +137 -0
- package/src/library/originals/FreeDropLibrary_0402.js +185 -0
- package/src/library/originals/GridDropLibrary_0402.js +202 -0
- package/src/library/originals/HistoryLibrary_0402.js +98 -0
- package/src/library/originals/LayoutLibrary_0402.js +264 -0
- package/src/utils/index.js +8 -3
|
@@ -37,30 +37,27 @@ function useDisplay(api) {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
// layoutName 세팅 감지
|
|
40
|
-
_subscribe('
|
|
41
|
-
state.displayMode = displayMode;
|
|
42
|
-
state.displaySize = {
|
|
40
|
+
_subscribe('layout:setLayoutName', ({ $screenConfig }) => {
|
|
41
|
+
state.displayMode = $screenConfig.displayMode;
|
|
42
|
+
state.displaySize = { ...$screenConfig.displaySize };
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
// activeMenu 변경 감지
|
|
46
|
-
_subscribe('display:updateActiveMenu', ({ menu }) => {
|
|
47
|
-
state.activeMenu = menu;
|
|
46
|
+
_subscribe('display:updateActiveMenu', ({ $menu }) => {
|
|
47
|
+
state.activeMenu = $menu;
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
// activeDesign 변경 감지
|
|
51
|
-
_subscribe('display:updateActiveDesign', ({ design }) => {
|
|
52
|
-
state.activeDesign = design;
|
|
51
|
+
_subscribe('display:updateActiveDesign', ({ $design }) => {
|
|
52
|
+
state.activeDesign = $design;
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
// displayMode 변경 감지 (displaySize가 함께 초기화됨)
|
|
56
|
-
_subscribe('display:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// displaySize 변경 감지 (px 또는 percent 값 변경 감지)
|
|
62
|
-
_subscribe('display:updateDisplaySize', ({ displaySize }) => {
|
|
63
|
-
state.displaySize = { ...displaySize };
|
|
56
|
+
_subscribe('display:displayChanged', ({ type, $displayMode, $displaySize }) => {
|
|
57
|
+
if (type === 'mode') {
|
|
58
|
+
state.displayMode = $displayMode;
|
|
59
|
+
}
|
|
60
|
+
state.displaySize = { ...$displaySize };
|
|
64
61
|
});
|
|
65
62
|
|
|
66
63
|
_subscribe('display:restoredState', ({ stateData }) => {
|
|
@@ -118,9 +115,9 @@ function useDisplay(api) {
|
|
|
118
115
|
|
|
119
116
|
const setDisplaySize = (type, size) => {
|
|
120
117
|
try {
|
|
121
|
-
api.display.setDisplaySize(type, size);
|
|
118
|
+
return api.display.setDisplaySize(type, size);
|
|
122
119
|
} catch (error) {
|
|
123
|
-
console.error('[
|
|
120
|
+
console.error('[DisplayLibrary] setDisplaySize 실행 중 오류 발생:', error);
|
|
124
121
|
}
|
|
125
122
|
};
|
|
126
123
|
|
|
@@ -62,6 +62,8 @@ function useFreeDrop(api) {
|
|
|
62
62
|
const index = state.elements.findIndex((el) => el.id === element.id);
|
|
63
63
|
if (index !== -1) {
|
|
64
64
|
state.elements[index] = element;
|
|
65
|
+
state.activeElement = element;
|
|
66
|
+
state.activeId = element?.id ?? null;
|
|
65
67
|
}
|
|
66
68
|
});
|
|
67
69
|
|
|
@@ -74,12 +76,12 @@ function useFreeDrop(api) {
|
|
|
74
76
|
|
|
75
77
|
_subscribe('freeDrop:requestUpdateData', ({ elements, guides }) => {
|
|
76
78
|
state.elements = elements;
|
|
77
|
-
state.guides = guides;
|
|
79
|
+
state.guides = guides ?? { x: null, y: null, w: null, h: null };
|
|
78
80
|
});
|
|
79
81
|
|
|
80
|
-
_subscribe('system:
|
|
81
|
-
state.elements = elements;
|
|
82
|
-
state.guides = guides;
|
|
82
|
+
_subscribe('system:requestElementsScale', ({ $elements, guides }) => {
|
|
83
|
+
state.elements = $elements;
|
|
84
|
+
state.guides = guides ?? { x: null, y: null, w: null, h: null };
|
|
83
85
|
});
|
|
84
86
|
|
|
85
87
|
_subscribe('freeDrop:requestUpdateLocalBounds', ({ elementId, position, size, guides }) => {
|
|
@@ -51,11 +51,9 @@ function useGridDrop(api) {
|
|
|
51
51
|
const index = state.elements.findIndex((el) => el.id === element.id);
|
|
52
52
|
if (index !== -1) {
|
|
53
53
|
state.elements[index] = element;
|
|
54
|
-
|
|
55
54
|
state.activeElement = element;
|
|
56
55
|
state.activeId = element?.id ?? null;
|
|
57
|
-
|
|
58
|
-
}
|
|
56
|
+
}
|
|
59
57
|
});
|
|
60
58
|
|
|
61
59
|
_subscribe('gridDrop:toggleLock', ({ elementId }) => {
|
|
@@ -69,8 +67,8 @@ function useGridDrop(api) {
|
|
|
69
67
|
state.elements = elements;
|
|
70
68
|
});
|
|
71
69
|
|
|
72
|
-
_subscribe('system:
|
|
73
|
-
state.elements = elements;
|
|
70
|
+
_subscribe('system:requestElementsScale', ({ $elements }) => {
|
|
71
|
+
state.elements = $elements;
|
|
74
72
|
});
|
|
75
73
|
|
|
76
74
|
_subscribe('gridDrop:requestUpdateLocalBounds', ({ elementId, position, size }) => {
|
|
@@ -9,6 +9,9 @@ function useLayout(api) {
|
|
|
9
9
|
elements: null,
|
|
10
10
|
layoutData: null,
|
|
11
11
|
activeSection: null,
|
|
12
|
+
activeMode: null,
|
|
13
|
+
activeConfig: null,
|
|
14
|
+
|
|
12
15
|
activeData: null,
|
|
13
16
|
|
|
14
17
|
gapSize: null,
|
|
@@ -45,37 +48,43 @@ function useLayout(api) {
|
|
|
45
48
|
});
|
|
46
49
|
|
|
47
50
|
// layoutName 변경 감지 (layoutData, gridNumber, gridRatio가 함께 초기화됨)
|
|
48
|
-
_subscribe('layout:setLayoutName', ({ screenConfig, gridNumber, gridRatio }) => {
|
|
49
|
-
state.layoutName = screenConfig.layoutName;
|
|
50
|
-
state.layoutData =
|
|
51
|
-
state.gridNumber = gridNumber;
|
|
52
|
-
state.gridRatio = gridRatio;
|
|
53
|
-
state.gapSize = screenConfig.gapSize;
|
|
51
|
+
_subscribe('layout:setLayoutName', ({ $screenConfig, $layoutData, $gridNumber, $gridRatio }) => {
|
|
52
|
+
state.layoutName = $screenConfig.layoutName;
|
|
53
|
+
state.layoutData = $layoutData;
|
|
54
|
+
state.gridNumber = $gridNumber;
|
|
55
|
+
state.gridRatio = $gridRatio;
|
|
56
|
+
state.gapSize = $screenConfig.gapSize;
|
|
57
|
+
|
|
58
|
+
state.activeSection = 'section1'; // 초기 활성 섹션 설정 (필요에 따라 조정)
|
|
59
|
+
state.activeMode = $layoutData.section1?.mode || 'free';
|
|
60
|
+
state.activeConfig = $layoutData.section1?.config || {};
|
|
54
61
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
state.
|
|
58
|
-
state.
|
|
59
|
-
state.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
|
|
63
|
+
_subscribe('layout:updateLayoutName', ({ $layoutName, $layoutData, $gridNumber, $gridRatio, $gapSize }) => {
|
|
64
|
+
state.layoutName = $layoutName;
|
|
65
|
+
state.layoutData = $layoutData;
|
|
66
|
+
state.gridNumber = $gridNumber;
|
|
67
|
+
state.gridRatio = $gridRatio;
|
|
68
|
+
if ($gapSize != null) {
|
|
69
|
+
state.gapSize = $gapSize;
|
|
62
70
|
}
|
|
63
71
|
});
|
|
64
72
|
|
|
65
73
|
// gapSize 변경 감지
|
|
66
|
-
_subscribe('layout:updateGapSize', ({ gapSize }) => {
|
|
67
|
-
state.gapSize = gapSize;
|
|
74
|
+
_subscribe('layout:updateGapSize', ({ $gapSize }) => {
|
|
75
|
+
state.gapSize = $gapSize;
|
|
68
76
|
});
|
|
69
77
|
|
|
70
|
-
//
|
|
71
|
-
_subscribe('layout:updateRatio', ({ gridRatio }) => {
|
|
72
|
-
state.gridRatio = gridRatio;
|
|
78
|
+
// gridRatio 변경 감지
|
|
79
|
+
_subscribe('layout:updateRatio', ({ $type, $gridRatio }) => {
|
|
80
|
+
state.gridRatio[$type] = [...$gridRatio[$type]];
|
|
73
81
|
});
|
|
74
82
|
|
|
75
83
|
// activeSection 변경 감지 (activeData가 함께 초기화됨)
|
|
76
|
-
_subscribe('system:updateActiveSection', ({
|
|
77
|
-
state.activeSection =
|
|
78
|
-
state.
|
|
84
|
+
_subscribe('system:updateActiveSection', ({ $section, $mode, $config }) => {
|
|
85
|
+
state.activeSection = $section;
|
|
86
|
+
state.activeMode = $mode;
|
|
87
|
+
state.activeConfig = $config;
|
|
79
88
|
});
|
|
80
89
|
|
|
81
90
|
// elements 변경 감지
|
|
@@ -86,32 +95,29 @@ function useLayout(api) {
|
|
|
86
95
|
}
|
|
87
96
|
});
|
|
88
97
|
|
|
89
|
-
_subscribe('system:setElements', ({ elements }) => {
|
|
90
|
-
state.elements = elements;
|
|
98
|
+
_subscribe('system:setElements', ({ $elements }) => {
|
|
99
|
+
state.elements = $elements;
|
|
91
100
|
});
|
|
92
101
|
|
|
93
|
-
_subscribe('
|
|
94
|
-
state.
|
|
95
|
-
state.
|
|
102
|
+
_subscribe('layout:updateLayoutData', ({ $layoutData, $section, $mode, $config }) => {
|
|
103
|
+
state.activeSection = $section;
|
|
104
|
+
state.layoutData[$section] = { ...$layoutData[$section] };
|
|
105
|
+
state.activeMode = $mode;
|
|
106
|
+
state.activeConfig = $config;
|
|
96
107
|
});
|
|
97
108
|
|
|
98
|
-
_subscribe('system:requestUpdateData', ({
|
|
99
|
-
state.
|
|
100
|
-
state.activeData = activeData;
|
|
101
|
-
state.elements = elements;
|
|
109
|
+
_subscribe('system:requestUpdateData', ({ $elements }) => {
|
|
110
|
+
state.elements = $elements;
|
|
102
111
|
});
|
|
103
112
|
|
|
104
|
-
_subscribe('system:
|
|
105
|
-
state.elements = elements;
|
|
113
|
+
_subscribe('system:requestElementsScale', ({ $elements }) => {
|
|
114
|
+
state.elements = $elements;
|
|
106
115
|
});
|
|
107
116
|
|
|
108
117
|
_subscribe('system:restoredState', ({ stateData }) => {
|
|
109
118
|
state.elements = stateData.elements;
|
|
110
119
|
state.layoutData = stateData.layoutData;
|
|
111
120
|
state.activeSection = stateData.activeSection;
|
|
112
|
-
|
|
113
|
-
// state.layoutData = cloneDeep(api.layout.getLayoutData());
|
|
114
|
-
// state.activeData = cloneDeep(api.layout.getActiveData());
|
|
115
121
|
});
|
|
116
122
|
|
|
117
123
|
_subscribe('layout:restoredState', ({ stateData }) => {
|
|
@@ -144,7 +150,7 @@ function useLayout(api) {
|
|
|
144
150
|
};
|
|
145
151
|
|
|
146
152
|
// 메서드
|
|
147
|
-
|
|
153
|
+
const getContainerSize = () => {
|
|
148
154
|
try {
|
|
149
155
|
return api.layout.getContainerSize();
|
|
150
156
|
} catch (error) {
|
|
@@ -160,7 +166,7 @@ function useLayout(api) {
|
|
|
160
166
|
console.error('[LayoutLibrary] setContainerSize 실행 중 오류 발생:', error);
|
|
161
167
|
}
|
|
162
168
|
};
|
|
163
|
-
|
|
169
|
+
|
|
164
170
|
const setLayoutName = (name, userData = null, setting = false) => {
|
|
165
171
|
try {
|
|
166
172
|
api.layout.setLayoutName(name, userData, setting);
|
|
@@ -179,20 +185,12 @@ function useLayout(api) {
|
|
|
179
185
|
|
|
180
186
|
const setRatio = (type, index, ratio) => {
|
|
181
187
|
try {
|
|
182
|
-
api.layout.setRatio(type, index, ratio);
|
|
188
|
+
return api.layout.setRatio(type, index, ratio);
|
|
183
189
|
} catch (error) {
|
|
184
190
|
console.error('[useLayout] setRatio 실행 중 오류 발생:', error);
|
|
185
191
|
}
|
|
186
192
|
};
|
|
187
193
|
|
|
188
|
-
// const setUserLayoutData = (userData) => {
|
|
189
|
-
// try {
|
|
190
|
-
// api.layout.setUserLayoutData(userData);
|
|
191
|
-
// } catch (error) {
|
|
192
|
-
// console.error('[useLayout] setUserLayoutData 실행 중 오류 발생:', error);
|
|
193
|
-
// }
|
|
194
|
-
// };
|
|
195
|
-
|
|
196
194
|
const setActiveSection = (name) => {
|
|
197
195
|
try {
|
|
198
196
|
api.layout.setActiveSection(name);
|
|
@@ -227,7 +225,7 @@ function useLayout(api) {
|
|
|
227
225
|
|
|
228
226
|
const setSectionConfig = (type, config) => {
|
|
229
227
|
try {
|
|
230
|
-
api.layout.setSectionConfig(type, config);
|
|
228
|
+
return api.layout.setSectionConfig(type, config);
|
|
231
229
|
} catch (error) {
|
|
232
230
|
console.error('[useLayout] setSectionConfig 실행 중 오류 발생:', error);
|
|
233
231
|
}
|
|
@@ -241,7 +239,6 @@ function useLayout(api) {
|
|
|
241
239
|
setLayoutName,
|
|
242
240
|
setGapSize,
|
|
243
241
|
setRatio,
|
|
244
|
-
// setUserLayoutData,
|
|
245
242
|
setActiveSection,
|
|
246
243
|
setElements,
|
|
247
244
|
updateActiveElement,
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { reactive, readonly } from 'vue';
|
|
2
|
+
|
|
3
|
+
function useDisplay(api) {
|
|
4
|
+
const state = reactive({
|
|
5
|
+
activeMenu: null,
|
|
6
|
+
activeDesign: null,
|
|
7
|
+
displayMode: 'desktop',
|
|
8
|
+
displaySize: null,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const _subscriptions = [];
|
|
12
|
+
|
|
13
|
+
const syncState = () => {
|
|
14
|
+
try {
|
|
15
|
+
const displayState = api.getDisplayState();
|
|
16
|
+
Object.assign(state, displayState);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.error('[DisplayLibrary] 상태 동기화 중 오류 발생:', error);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const _subscribe = (name, handler) => {
|
|
23
|
+
const unsubscribe = api.eventBus.subscribe(name, handler);
|
|
24
|
+
_subscriptions.push(unsubscribe);
|
|
25
|
+
return unsubscribe;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// 이벤트 구독
|
|
29
|
+
const _setupSubscriptions = () => {
|
|
30
|
+
// 다시 초기화 되는 경우를 대비
|
|
31
|
+
_subscribe('system:engineInitialized', () => {
|
|
32
|
+
syncState();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
_subscribe('system:enginesReset', () => {
|
|
36
|
+
syncState();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// layoutName 세팅 감지
|
|
40
|
+
_subscribe('display:setLayoutName', ({ displayMode, displaySize }) => {
|
|
41
|
+
state.displayMode = displayMode;
|
|
42
|
+
state.displaySize = { ...displaySize };
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// activeMenu 변경 감지
|
|
46
|
+
_subscribe('display:updateActiveMenu', ({ menu }) => {
|
|
47
|
+
state.activeMenu = menu;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// activeDesign 변경 감지
|
|
51
|
+
_subscribe('display:updateActiveDesign', ({ design }) => {
|
|
52
|
+
state.activeDesign = design;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// displayMode 변경 감지 (displaySize가 함께 초기화됨)
|
|
56
|
+
_subscribe('display:updateDisplayMode', ({ displayMode, displaySize }) => {
|
|
57
|
+
state.displayMode = displayMode;
|
|
58
|
+
state.displaySize = { ...displaySize };
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// displaySize 변경 감지 (px 또는 percent 값 변경 감지)
|
|
62
|
+
_subscribe('display:updateDisplaySize', ({ displaySize }) => {
|
|
63
|
+
state.displaySize = { ...displaySize };
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
_subscribe('display:restoredState', ({ stateData }) => {
|
|
67
|
+
state.displayMode = stateData.displayMode;
|
|
68
|
+
state.displaySize = { ...stateData.displaySize };
|
|
69
|
+
state.activeMenu = stateData.activeMenu;
|
|
70
|
+
state.activeDesign = stateData.activeDesign;
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
if (api.eventBus) {
|
|
75
|
+
_setupSubscriptions();
|
|
76
|
+
|
|
77
|
+
// 초기화가 이미 완료된 경우 즉시 동기화
|
|
78
|
+
if (api.isReady && api.isReady()) {
|
|
79
|
+
syncState();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 라이브러리 cleanup
|
|
84
|
+
const cleanup = () => {
|
|
85
|
+
_subscriptions.forEach((unsubscribe) => {
|
|
86
|
+
if (typeof unsubscribe === 'function') {
|
|
87
|
+
unsubscribe();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
_subscriptions.length = 0;
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// 메서드
|
|
95
|
+
const setActiveMenu = (name) => {
|
|
96
|
+
try {
|
|
97
|
+
api.display.setActiveMenu(name);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error('[DisplayLibrary] setActiveMenu 실행 중 오류 발생:', error);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const setActiveDesign = (name) => {
|
|
104
|
+
try {
|
|
105
|
+
api.display.setActiveDesign(name);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error('[DisplayLibrary] setActiveDesign 실행 중 오류 발생:', error);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const setDisplayMode = (mode) => {
|
|
112
|
+
try {
|
|
113
|
+
api.display.setDisplayMode(mode);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error('[DisplayLibrary] setDisplayMode 실행 중 오류 발생:', error);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const setDisplaySize = (type, size) => {
|
|
120
|
+
try {
|
|
121
|
+
api.display.setDisplaySize(type, size);
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error('[useDisplay] setDisplaySize 실행 중 오류 발생:', error);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
state: readonly(state),
|
|
129
|
+
cleanup,
|
|
130
|
+
setActiveMenu,
|
|
131
|
+
setActiveDesign,
|
|
132
|
+
setDisplayMode,
|
|
133
|
+
setDisplaySize,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default useDisplay;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { cloneDeep } from 'lodash-es';
|
|
2
|
+
import { reactive, readonly } from 'vue';
|
|
3
|
+
|
|
4
|
+
function useFreeDrop(api) {
|
|
5
|
+
const state = reactive({
|
|
6
|
+
handles: [],
|
|
7
|
+
elements: [],
|
|
8
|
+
guides: { x: null, y: null, w: null, h: null },
|
|
9
|
+
activeElement: null,
|
|
10
|
+
activeId: null,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const _subscriptions = [];
|
|
14
|
+
|
|
15
|
+
const syncState = () => {
|
|
16
|
+
try {
|
|
17
|
+
const freeDropState = api.getFreeDropState();
|
|
18
|
+
Object.assign(state, freeDropState);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error('[FreeDropLibrary] 상태 동기화 중 오류 발생:', error);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const _subscribe = (name, handler) => {
|
|
25
|
+
const unsubscribe = api.eventBus.subscribe(name, handler);
|
|
26
|
+
_subscriptions.push(unsubscribe);
|
|
27
|
+
return unsubscribe;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// 이벤트 구독
|
|
31
|
+
const _setupSubscriptions = () => {
|
|
32
|
+
// 다시 초기화 되는 경우를 대비
|
|
33
|
+
_subscribe('system:engineInitialized', () => {
|
|
34
|
+
syncState();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
_subscribe('system:enginesReset', () => {
|
|
38
|
+
syncState();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
_subscribe('freeDrop:setElements', ({ elements }) => {
|
|
42
|
+
state.elements = elements;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
_subscribe('freeDrop:setActiveElement', ({ action, activeElement }) => {
|
|
46
|
+
if (!activeElement) {
|
|
47
|
+
state.guides = { x: null, y: null, w: null, h: null };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 신규 추가인 경우에만 elements 업데이트 (새 요소 1개만 추가)
|
|
51
|
+
if (action === 'add' && activeElement) {
|
|
52
|
+
state.elements = [...state.elements, activeElement];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// state.elements = elements;
|
|
56
|
+
state.activeElement = activeElement;
|
|
57
|
+
state.activeId = activeElement?.id ?? null;
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
_subscribe('freeDrop:requestUpdateActiveElement', ({ element }) => {
|
|
61
|
+
// state.elements = elements;
|
|
62
|
+
const index = state.elements.findIndex((el) => el.id === element.id);
|
|
63
|
+
if (index !== -1) {
|
|
64
|
+
state.elements[index] = element;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
_subscribe('freeDrop:toggleLock', ({ elementId }) => {
|
|
69
|
+
const element = state.elements.find((el) => el.id === elementId);
|
|
70
|
+
if (element) {
|
|
71
|
+
element.isLocked = !element.isLocked;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
_subscribe('freeDrop:requestUpdateData', ({ elements, guides }) => {
|
|
76
|
+
state.elements = elements;
|
|
77
|
+
state.guides = guides;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
_subscribe('system:requestUpdateElements', ({ elements, guides }) => {
|
|
81
|
+
state.elements = elements;
|
|
82
|
+
state.guides = guides;
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
_subscribe('freeDrop:requestUpdateLocalBounds', ({ elementId, position, size, guides }) => {
|
|
86
|
+
const element = state.elements.find((el) => el.id === elementId);
|
|
87
|
+
|
|
88
|
+
if (element) {
|
|
89
|
+
state.guides = guides;
|
|
90
|
+
state.elements = state.elements.map((element) =>
|
|
91
|
+
element.id === state.activeId ? { ...state.activeElement, position: { ...position }, size: { ...size } } : element,
|
|
92
|
+
);
|
|
93
|
+
} else {
|
|
94
|
+
state.elements.push(state.activeElement);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
_subscribe('freeDrop:restoredState', ({ elements }) => {
|
|
99
|
+
state.elements = elements;
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
if (api.eventBus) {
|
|
104
|
+
_setupSubscriptions();
|
|
105
|
+
|
|
106
|
+
// 초기화가 이미 완료된 경우 즉시 동기화
|
|
107
|
+
if (api.isReady && api.isReady()) {
|
|
108
|
+
syncState();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 라이브러리 cleanup
|
|
113
|
+
const cleanup = () => {
|
|
114
|
+
_subscriptions.forEach((unsubscribe) => {
|
|
115
|
+
if (typeof unsubscribe === 'function') {
|
|
116
|
+
unsubscribe();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
_subscriptions.length = 0;
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// 메서드
|
|
124
|
+
const getElementStyle = (element) => {
|
|
125
|
+
try {
|
|
126
|
+
return api.freeDrop.getElementStyle(element);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.warn('[FreeDropLibrary] getElementStyle 실행 중 오류 발생:', error);
|
|
129
|
+
return {};
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const setActiveElement = (element, type) => {
|
|
134
|
+
try {
|
|
135
|
+
api.freeDrop.setActiveElement(element, type);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.warn('[FreeDropLibrary] setActiveElement 실행 중 오류 발생:', error);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const addElement = (event, elName) => {
|
|
142
|
+
try {
|
|
143
|
+
api.freeDrop.addElement(event, elName);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.warn('[FreeDropLibrary] addElement 실행 중 오류 발생:', error);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const toggleLock = () => {
|
|
150
|
+
try {
|
|
151
|
+
api.freeDrop.toggleLock();
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.warn('[FreeDropLibrary] toggleLock 실행 중 오류 발생:', error);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const handleMouseDown = (event, id) => {
|
|
158
|
+
try {
|
|
159
|
+
api.freeDrop.handleMouseDown(event, id);
|
|
160
|
+
} catch (error) {
|
|
161
|
+
console.warn('[FreeDropLibrary] handleMouseDown 실행 중 오류 발생:', error);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const startResize = (event, direction) => {
|
|
166
|
+
try {
|
|
167
|
+
api.freeDrop.startResize(event, direction);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.warn('[FreeDropLibrary] startResize 실행 중 오류 발생:', error);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
state: readonly(state),
|
|
175
|
+
cleanup,
|
|
176
|
+
getElementStyle,
|
|
177
|
+
setActiveElement,
|
|
178
|
+
addElement,
|
|
179
|
+
toggleLock,
|
|
180
|
+
handleMouseDown,
|
|
181
|
+
startResize,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export default useFreeDrop;
|