@plait/mind 0.2.0-next.7 → 0.2.0-next.9
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/constants/abstract-node.d.ts +4 -0
- package/constants/default.d.ts +1 -2
- package/constants/index.d.ts +4 -1
- package/constants/node-rule.d.ts +1 -0
- package/constants/node-style.d.ts +17 -0
- package/constants/node-topic-style.d.ts +4 -0
- package/draw/richtext.d.ts +4 -3
- package/esm2020/constants/abstract-node.mjs +5 -0
- package/esm2020/constants/default.mjs +2 -3
- package/esm2020/constants/index.mjs +5 -2
- package/esm2020/constants/node-rule.mjs +2 -0
- package/esm2020/constants/node-style.mjs +19 -0
- package/esm2020/constants/node-topic-style.mjs +5 -0
- package/esm2020/draw/abstract.mjs +4 -3
- package/esm2020/draw/indented-link.mjs +14 -14
- package/esm2020/draw/link/abstract-link.mjs +6 -4
- package/esm2020/draw/link/logic-link.mjs +7 -7
- package/esm2020/draw/link.mjs +6 -5
- package/esm2020/draw/richtext.mjs +7 -7
- package/esm2020/draw/shape.mjs +4 -4
- package/esm2020/drawer/quick-insert.drawer.mjs +11 -12
- package/esm2020/interfaces/abstract.mjs +1 -1
- package/esm2020/interfaces/element.mjs +6 -1
- package/esm2020/interfaces/node.mjs +1 -1
- package/esm2020/interfaces/options.mjs +2 -0
- package/esm2020/layout-option.mjs +5 -5
- package/esm2020/mind.component.mjs +2 -2
- package/esm2020/node.component.mjs +15 -13
- package/esm2020/plugins/emoji/emoji.drawer.mjs +3 -4
- package/esm2020/plugins/emoji/emoji.mjs +7 -3
- package/esm2020/plugins/emoji/index.mjs +1 -2
- package/esm2020/plugins/with-abstract.mjs +2 -2
- package/esm2020/plugins/with-dnd.mjs +12 -117
- package/esm2020/plugins/with-extend-mind.mjs +11 -0
- package/esm2020/plugins/with-mind.mjs +9 -7
- package/esm2020/public-api.mjs +2 -1
- package/esm2020/queries/get-available-sublayouts-by-element.mjs +4 -9
- package/esm2020/queries/get-branch-layouts.mjs +4 -4
- package/esm2020/queries/get-correct-layout-by-element.mjs +28 -31
- package/esm2020/queries/get-layout-by-element.mjs +10 -8
- package/esm2020/queries/index.mjs +1 -3
- package/esm2020/transforms/abstract-node.mjs +68 -0
- package/esm2020/transforms/index.mjs +6 -2
- package/esm2020/transforms/layout.mjs +3 -3
- package/esm2020/transforms/node.mjs +2 -2
- package/esm2020/utils/abstract/common.mjs +90 -70
- package/esm2020/utils/abstract/resize.mjs +3 -3
- package/esm2020/utils/clipboard.mjs +54 -14
- package/esm2020/utils/direction-corrector.mjs +11 -11
- package/esm2020/utils/dnd.mjs +118 -0
- package/esm2020/utils/draw-placeholder.mjs +5 -5
- package/esm2020/utils/drop-target-corrector.mjs +11 -10
- package/esm2020/utils/layout.mjs +1 -1
- package/esm2020/utils/mind.mjs +23 -58
- package/esm2020/utils/node-space.mjs +5 -5
- package/esm2020/utils/node-style/branch.mjs +33 -6
- package/esm2020/utils/node-style/node.mjs +6 -5
- package/esm2020/utils/path.mjs +4 -3
- package/esm2020/utils/shape.mjs +3 -3
- package/fesm2015/plait-mind.mjs +724 -602
- package/fesm2015/plait-mind.mjs.map +1 -1
- package/fesm2020/plait-mind.mjs +726 -600
- package/fesm2020/plait-mind.mjs.map +1 -1
- package/interfaces/abstract.d.ts +3 -0
- package/interfaces/element.d.ts +5 -2
- package/interfaces/options.d.ts +4 -0
- package/layout-option.d.ts +2 -1
- package/mind.component.d.ts +2 -2
- package/node.component.d.ts +5 -4
- package/package.json +1 -1
- package/plugins/emoji/emoji.d.ts +2 -1
- package/plugins/emoji/emoji.drawer.d.ts +3 -3
- package/plugins/emoji/index.d.ts +0 -1
- package/plugins/with-dnd.d.ts +0 -9
- package/plugins/with-extend-mind.d.ts +10 -0
- package/plugins/with-mind.d.ts +1 -1
- package/public-api.d.ts +1 -0
- package/queries/get-available-sublayouts-by-element.d.ts +2 -6
- package/queries/get-branch-layouts.d.ts +2 -1
- package/queries/get-correct-layout-by-element.d.ts +2 -1
- package/queries/index.d.ts +3 -4
- package/styles/styles.scss +0 -3
- package/transforms/abstract-node.d.ts +6 -0
- package/transforms/index.d.ts +3 -0
- package/utils/abstract/common.d.ts +6 -8
- package/utils/direction-corrector.d.ts +2 -1
- package/utils/dnd.d.ts +16 -0
- package/utils/drop-target-corrector.d.ts +2 -1
- package/utils/mind.d.ts +3 -3
- package/utils/node-space.d.ts +3 -2
- package/utils/node-style/branch.d.ts +3 -0
- package/utils/shape.d.ts +2 -3
- package/constants/node.d.ts +0 -17
- package/esm2020/constants/node.mjs +0 -19
- package/esm2020/plugins/emoji/with-mind-emoji.mjs +0 -8
- package/esm2020/queries/get-layout-parent-by-element.mjs +0 -17
- package/plugins/emoji/with-mind-emoji.d.ts +0 -8
- package/queries/get-layout-parent-by-element.d.ts +0 -8
package/fesm2020/plait-mind.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Component, ChangeDetectionStrategy, NgModule, Directive, Input } from '@angular/core';
|
|
3
3
|
import * as i2 from '@plait/core';
|
|
4
|
-
import { distanceBetweenPointAndRectangle,
|
|
5
|
-
import { AbstractNode,
|
|
4
|
+
import { distanceBetweenPointAndRectangle, PlaitBoard, PlaitNode, NODE_TO_PARENT, Path, ELEMENT_TO_COMPONENT, PlaitElement, Transforms, idCreator, isNullOrUndefined, clearSelectedElement, addSelectedElement, drawRoundRectangle, getRectangleByElements, RectangleClient, getSelectedElements, createG, drawAbstractRoundRectangle, PlaitPluginElementComponent, PlaitPointerType, NODE_TO_INDEX, createText, IS_TEXT_EDITABLE, MERGING, transformPoint, toPoint, depthFirstRecursion, PlaitModule, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, BOARD_TO_HOST, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
|
|
5
|
+
import { MindLayoutType, AbstractNode, getAbstractLayout, isIndentedLayout, isStandardLayout, isHorizontalLogicLayout, isVerticalLogicLayout, isTopLayout, isLeftLayout, isBottomLayout, isRightLayout, isHorizontalLayout, getNonAbstractChildren, getCorrectStartEnd, ConnectingPosition, GlobalLayout } from '@plait/layouts';
|
|
6
6
|
import { getSizeByText, ROOT_DEFAULT_HEIGHT, TEXT_DEFAULT_HEIGHT, drawRichtext, updateForeignObject, createForeignObject, updateRichText, setFullSelectionAndFocus, getRichtextContentSize, hasEditableTarget, RichtextModule } from '@plait/richtext';
|
|
7
7
|
import { fromEvent, Subject, timer } from 'rxjs';
|
|
8
8
|
import { take, takeUntil, filter, debounceTime } from 'rxjs/operators';
|
|
@@ -16,34 +16,44 @@ const ELEMENT_TO_NODE = new WeakMap();
|
|
|
16
16
|
|
|
17
17
|
const BASE = 4;
|
|
18
18
|
const PRIMARY_COLOR = '#6698FF';
|
|
19
|
-
const MINDMAP_KEY = 'plait-mindmap';
|
|
20
|
-
const MAX_RADIUS = BASE * 4;
|
|
21
19
|
const TRANSPARENT = 'transparent';
|
|
22
20
|
const GRAY_COLOR = '#AAAAAA';
|
|
23
21
|
const STROKE_WIDTH = 3;
|
|
22
|
+
const BRANCH_WIDTH = 3;
|
|
24
23
|
const EXTEND_OFFSET = 8;
|
|
25
24
|
const EXTEND_RADIUS = 16;
|
|
26
25
|
const QUICK_INSERT_CIRCLE_OFFSET = 9;
|
|
27
26
|
const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
|
|
28
27
|
const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
|
|
29
28
|
|
|
29
|
+
const DefaultAbstractNodeStyle = {
|
|
30
|
+
strokeColor: GRAY_COLOR,
|
|
31
|
+
strokeWidth: 2,
|
|
32
|
+
branchColor: GRAY_COLOR,
|
|
33
|
+
branchWidth: 2,
|
|
34
|
+
fill: '#FFFFFF'
|
|
35
|
+
};
|
|
36
|
+
const DefaultNodeStyle = {
|
|
37
|
+
strokeWidth: 3,
|
|
38
|
+
branchWidth: 3,
|
|
39
|
+
fill: '#FFFFFF'
|
|
40
|
+
};
|
|
41
|
+
const DefaultRootStyle = {
|
|
42
|
+
fill: '#F5F5F5',
|
|
43
|
+
strokeColor: '#F5F5F5',
|
|
44
|
+
};
|
|
45
|
+
const BRANCH_COLORS = ['#A287E1', '#6F81DB', '#6EC4C4', '#DFB85D', '#B1C774', '#77C386', '#C28976', '#E48484', '#E482D4', '#69B1E4'];
|
|
46
|
+
|
|
30
47
|
const TOPIC_COLOR = '#333';
|
|
31
48
|
const TOPIC_FONT_SIZE = 14;
|
|
32
|
-
const NODE_FILL = '#FFFFFF';
|
|
33
|
-
const ROOT_NODE_FILL = '#F5F5F5';
|
|
34
|
-
const ROOT_NODE_STROKE = '#F5F5F5';
|
|
35
49
|
const ROOT_TOPIC_FONT_SIZE = 18;
|
|
50
|
+
const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
|
|
51
|
+
|
|
36
52
|
const NODE_MIN_WIDTH = 18;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
(function (MindNodeShape) {
|
|
40
|
-
MindNodeShape["roundRectangle"] = "round-rectangle";
|
|
41
|
-
MindNodeShape["underline"] = "underline";
|
|
42
|
-
})(MindNodeShape || (MindNodeShape = {}));
|
|
43
|
-
const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //PRIMARY_COLOR 50% 透明度
|
|
53
|
+
|
|
54
|
+
const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //primary color 50% opacity
|
|
44
55
|
const ABSTRACT_INCLUDED_OUTLINE_OFFSET = 3.5;
|
|
45
56
|
const ABSTRACT_HANDLE_LENGTH = 10;
|
|
46
|
-
const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
|
|
47
57
|
const ABSTRACT_HANDLE_MASK_WIDTH = 8;
|
|
48
58
|
|
|
49
59
|
function getRectangleByNode(node) {
|
|
@@ -74,34 +84,35 @@ function hitMindElement(board, point, element) {
|
|
|
74
84
|
* 2. correct layout by incorrect layout direction
|
|
75
85
|
* @param element
|
|
76
86
|
*/
|
|
77
|
-
const getCorrectLayoutByElement = (element) => {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
const getCorrectLayoutByElement = (board, element) => {
|
|
88
|
+
const ancestors = MindElement.getAncestors(board, element);
|
|
89
|
+
ancestors.unshift(element);
|
|
90
|
+
const root = ancestors[ancestors.length - 1];
|
|
91
|
+
let rootLayout = getRootLayout(root);
|
|
92
|
+
if (PlaitMind.isMind(element)) {
|
|
93
|
+
return rootLayout;
|
|
83
94
|
}
|
|
84
|
-
const
|
|
85
|
-
let
|
|
86
|
-
let parentComponent = null;
|
|
87
|
-
let parent = component.parent.origin;
|
|
88
|
-
while (!layout && parent) {
|
|
89
|
-
parentComponent = PlaitElement.getComponent(parent);
|
|
90
|
-
layout = parentComponent.node.origin.layout;
|
|
91
|
-
parent = parentComponent.parent?.origin;
|
|
92
|
-
}
|
|
93
|
-
if ((AbstractNode.isAbstract(element) || isChildOfAbstract(MindElement.getNode(element))) &&
|
|
94
|
-
isIndentedLayout(layout)) {
|
|
95
|
-
return getAbstractLayout(layout);
|
|
96
|
-
}
|
|
97
|
-
// handle root standard
|
|
95
|
+
const node = MindElement.getNode(element);
|
|
96
|
+
let correctRootLayout = rootLayout;
|
|
98
97
|
if (rootLayout === MindLayoutType.standard) {
|
|
99
|
-
correctRootLayout =
|
|
98
|
+
correctRootLayout = node.left ? MindLayoutType.left : MindLayoutType.right;
|
|
99
|
+
}
|
|
100
|
+
let layout = null;
|
|
101
|
+
const elementWithLayout = ancestors.find(value => value.layout || AbstractNode.isAbstract(value));
|
|
102
|
+
if (elementWithLayout) {
|
|
103
|
+
if (AbstractNode.isAbstract(elementWithLayout)) {
|
|
104
|
+
const parent = MindElement.getParent(elementWithLayout);
|
|
105
|
+
const parentLayout = getCorrectLayoutByElement(board, parent);
|
|
106
|
+
layout = getAbstractLayout(parentLayout);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
layout = elementWithLayout?.layout;
|
|
110
|
+
}
|
|
100
111
|
}
|
|
101
|
-
if (
|
|
112
|
+
if (layout === MindLayoutType.standard || !layout) {
|
|
102
113
|
return correctRootLayout;
|
|
103
114
|
}
|
|
104
|
-
|
|
115
|
+
else {
|
|
105
116
|
const incorrectDirection = getInCorrectLayoutDirection(correctRootLayout, layout);
|
|
106
117
|
if (incorrectDirection) {
|
|
107
118
|
return correctLayoutByDirection(layout, incorrectDirection);
|
|
@@ -110,16 +121,13 @@ const getCorrectLayoutByElement = (element) => {
|
|
|
110
121
|
return layout;
|
|
111
122
|
}
|
|
112
123
|
}
|
|
113
|
-
else {
|
|
114
|
-
return correctRootLayout;
|
|
115
|
-
}
|
|
116
124
|
};
|
|
117
125
|
|
|
118
|
-
const getBranchLayouts = (element) => {
|
|
126
|
+
const getBranchLayouts = (board, element) => {
|
|
119
127
|
const layouts = [];
|
|
120
128
|
if (element.layout) {
|
|
121
|
-
//getCorrectLayoutByElement含有递归操作,
|
|
122
|
-
layouts.unshift(getCorrectLayoutByElement(element));
|
|
129
|
+
// TODO: getCorrectLayoutByElement 含有递归操作,getBranchLayouts 本身也有递归操作,有待优化
|
|
130
|
+
layouts.unshift(getCorrectLayoutByElement(board, element));
|
|
123
131
|
}
|
|
124
132
|
let parent = findParentElement(element);
|
|
125
133
|
while (parent) {
|
|
@@ -131,15 +139,10 @@ const getBranchLayouts = (element) => {
|
|
|
131
139
|
return layouts;
|
|
132
140
|
};
|
|
133
141
|
|
|
134
|
-
|
|
135
|
-
* get available sub layouts by element
|
|
136
|
-
* @param element
|
|
137
|
-
* @returns MindLayoutType[]
|
|
138
|
-
*/
|
|
139
|
-
const getAvailableSubLayoutsByElement = (element) => {
|
|
142
|
+
const getAvailableSubLayoutsByElement = (board, element) => {
|
|
140
143
|
const parentElement = findParentElement(element);
|
|
141
144
|
if (parentElement) {
|
|
142
|
-
const branchLayouts = getBranchLayouts(parentElement);
|
|
145
|
+
const branchLayouts = getBranchLayouts(board, parentElement);
|
|
143
146
|
if (branchLayouts[0] === MindLayoutType.standard) {
|
|
144
147
|
const node = MindElement.getNode(element);
|
|
145
148
|
branchLayouts[0] = node.left ? MindLayoutType.left : MindLayoutType.right;
|
|
@@ -155,20 +158,107 @@ const getAvailableSubLayoutsByElement = (element) => {
|
|
|
155
158
|
return undefined;
|
|
156
159
|
};
|
|
157
160
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
161
|
+
const getBranchDirectionsByLayouts = (branchLayouts) => {
|
|
162
|
+
const branchDirections = [];
|
|
163
|
+
branchLayouts.forEach(l => {
|
|
164
|
+
const directions = LayoutDirectionsMap[l];
|
|
165
|
+
directions.forEach(d => {
|
|
166
|
+
if (!branchDirections.includes(d) && !branchDirections.includes(getLayoutReverseDirection(d))) {
|
|
167
|
+
branchDirections.push(d);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
return branchDirections;
|
|
172
|
+
};
|
|
173
|
+
const isCorrectLayout = (root, layout) => {
|
|
174
|
+
const rootLayout = root.layout || getDefaultLayout();
|
|
175
|
+
return !getInCorrectLayoutDirection(rootLayout, layout);
|
|
176
|
+
};
|
|
177
|
+
const isMixedLayout = (parentLayout, layout) => {
|
|
178
|
+
return (!isIndentedLayout(parentLayout) && isIndentedLayout(layout)) || (isIndentedLayout(parentLayout) && !isIndentedLayout(layout));
|
|
179
|
+
};
|
|
180
|
+
const getInCorrectLayoutDirection = (rootLayout, layout) => {
|
|
181
|
+
const directions = LayoutDirectionsMap[rootLayout];
|
|
182
|
+
const subLayoutDirections = LayoutDirectionsMap[layout];
|
|
183
|
+
if (!subLayoutDirections) {
|
|
184
|
+
throw new Error(`unexpected layout: ${layout} on correct layout`);
|
|
185
|
+
}
|
|
186
|
+
return subLayoutDirections.find(d => directions.includes(getLayoutReverseDirection(d)));
|
|
187
|
+
};
|
|
188
|
+
const correctLayoutByDirection = (layout, direction) => {
|
|
189
|
+
const isHorizontal = direction === LayoutDirection.left || direction === LayoutDirection.right ? true : false;
|
|
190
|
+
let inverseDirectionLayout = MindLayoutType.standard;
|
|
191
|
+
switch (layout) {
|
|
192
|
+
case MindLayoutType.left:
|
|
193
|
+
inverseDirectionLayout = MindLayoutType.right;
|
|
194
|
+
break;
|
|
195
|
+
case MindLayoutType.right:
|
|
196
|
+
inverseDirectionLayout = MindLayoutType.left;
|
|
197
|
+
break;
|
|
198
|
+
case MindLayoutType.downward:
|
|
199
|
+
inverseDirectionLayout = MindLayoutType.upward;
|
|
200
|
+
break;
|
|
201
|
+
case MindLayoutType.upward:
|
|
202
|
+
inverseDirectionLayout = MindLayoutType.downward;
|
|
203
|
+
break;
|
|
204
|
+
case MindLayoutType.rightBottomIndented:
|
|
205
|
+
inverseDirectionLayout = isHorizontal ? MindLayoutType.leftBottomIndented : MindLayoutType.rightTopIndented;
|
|
206
|
+
break;
|
|
207
|
+
case MindLayoutType.leftBottomIndented:
|
|
208
|
+
inverseDirectionLayout = isHorizontal ? MindLayoutType.rightBottomIndented : MindLayoutType.leftTopIndented;
|
|
209
|
+
break;
|
|
210
|
+
case MindLayoutType.rightTopIndented:
|
|
211
|
+
inverseDirectionLayout = isHorizontal ? MindLayoutType.leftTopIndented : MindLayoutType.rightBottomIndented;
|
|
212
|
+
break;
|
|
213
|
+
case MindLayoutType.leftTopIndented:
|
|
214
|
+
inverseDirectionLayout = isHorizontal ? MindLayoutType.rightTopIndented : MindLayoutType.leftBottomIndented;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
return inverseDirectionLayout;
|
|
218
|
+
};
|
|
219
|
+
const getLayoutDirection$1 = (root) => {
|
|
220
|
+
const layout = root.layout || getDefaultLayout();
|
|
221
|
+
return LayoutDirectionsMap[layout];
|
|
222
|
+
};
|
|
223
|
+
const getDefaultLayout = () => {
|
|
224
|
+
return MindLayoutType.standard;
|
|
225
|
+
};
|
|
226
|
+
const getAvailableSubLayoutsByLayoutDirections = (directions) => {
|
|
227
|
+
const result = [];
|
|
228
|
+
const reverseDirections = directions.map(getLayoutReverseDirection);
|
|
229
|
+
for (const key in MindLayoutType) {
|
|
230
|
+
const layout = MindLayoutType[key];
|
|
231
|
+
const layoutDirections = LayoutDirectionsMap[layout];
|
|
232
|
+
if (layoutDirections) {
|
|
233
|
+
const hasSameDirection = layoutDirections.some(d => directions.includes(d));
|
|
234
|
+
const hasReverseDirection = layoutDirections.some(r => reverseDirections.includes(r));
|
|
235
|
+
if (hasSameDirection && !hasReverseDirection) {
|
|
236
|
+
result.push(layout);
|
|
237
|
+
}
|
|
168
238
|
}
|
|
169
|
-
parent = findParentElement(parent);
|
|
170
239
|
}
|
|
171
|
-
return
|
|
240
|
+
return result;
|
|
241
|
+
};
|
|
242
|
+
const getLayoutReverseDirection = (layoutDirection) => {
|
|
243
|
+
let reverseDirection = LayoutDirection.right;
|
|
244
|
+
switch (layoutDirection) {
|
|
245
|
+
case LayoutDirection.top:
|
|
246
|
+
reverseDirection = LayoutDirection.bottom;
|
|
247
|
+
break;
|
|
248
|
+
case LayoutDirection.bottom:
|
|
249
|
+
reverseDirection = LayoutDirection.top;
|
|
250
|
+
break;
|
|
251
|
+
case LayoutDirection.right:
|
|
252
|
+
reverseDirection = LayoutDirection.left;
|
|
253
|
+
break;
|
|
254
|
+
case LayoutDirection.left:
|
|
255
|
+
reverseDirection = LayoutDirection.right;
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
return reverseDirection;
|
|
259
|
+
};
|
|
260
|
+
const getRootLayout = (root) => {
|
|
261
|
+
return root.layout || getDefaultLayout();
|
|
172
262
|
};
|
|
173
263
|
|
|
174
264
|
const getLayoutByElement = (element) => {
|
|
@@ -176,17 +266,18 @@ const getLayoutByElement = (element) => {
|
|
|
176
266
|
if (layout) {
|
|
177
267
|
return layout;
|
|
178
268
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
269
|
+
const parent = MindElement.getParent(element);
|
|
270
|
+
if (AbstractNode.isAbstract(element)) {
|
|
271
|
+
return getAbstractLayout(getLayoutByElement(parent));
|
|
272
|
+
}
|
|
273
|
+
if (parent) {
|
|
274
|
+
return getLayoutByElement(parent);
|
|
183
275
|
}
|
|
184
|
-
return
|
|
276
|
+
return getDefaultLayout();
|
|
185
277
|
};
|
|
186
278
|
|
|
187
279
|
const MindQueries = {
|
|
188
280
|
getAvailableSubLayoutsByElement,
|
|
189
|
-
getLayoutParentByElement,
|
|
190
281
|
getBranchLayouts,
|
|
191
282
|
getLayoutByElement,
|
|
192
283
|
getCorrectLayoutByElement
|
|
@@ -257,6 +348,11 @@ const MindElement = {
|
|
|
257
348
|
return element.data.emojis;
|
|
258
349
|
}
|
|
259
350
|
};
|
|
351
|
+
var MindElementShape;
|
|
352
|
+
(function (MindElementShape) {
|
|
353
|
+
MindElementShape["roundRectangle"] = "round-rectangle";
|
|
354
|
+
MindElementShape["underline"] = "underline";
|
|
355
|
+
})(MindElementShape || (MindElementShape = {}));
|
|
260
356
|
|
|
261
357
|
const MindNode = {
|
|
262
358
|
get(root, path) {
|
|
@@ -311,109 +407,6 @@ var AbstractResizeState;
|
|
|
311
407
|
AbstractResizeState["end"] = "end";
|
|
312
408
|
})(AbstractResizeState || (AbstractResizeState = {}));
|
|
313
409
|
|
|
314
|
-
const getBranchDirectionsByLayouts = (branchLayouts) => {
|
|
315
|
-
const branchDirections = [];
|
|
316
|
-
branchLayouts.forEach(l => {
|
|
317
|
-
const directions = LayoutDirectionsMap[l];
|
|
318
|
-
directions.forEach(d => {
|
|
319
|
-
if (!branchDirections.includes(d) && !branchDirections.includes(getLayoutReverseDirection(d))) {
|
|
320
|
-
branchDirections.push(d);
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
return branchDirections;
|
|
325
|
-
};
|
|
326
|
-
const isCorrectLayout = (root, layout) => {
|
|
327
|
-
const rootLayout = root.layout || getDefaultLayout();
|
|
328
|
-
return !getInCorrectLayoutDirection(rootLayout, layout);
|
|
329
|
-
};
|
|
330
|
-
const isMixedLayout = (parentLayout, layout) => {
|
|
331
|
-
return (!isIndentedLayout(parentLayout) && isIndentedLayout(layout)) || (isIndentedLayout(parentLayout) && !isIndentedLayout(layout));
|
|
332
|
-
};
|
|
333
|
-
const getInCorrectLayoutDirection = (rootLayout, layout) => {
|
|
334
|
-
const directions = LayoutDirectionsMap[rootLayout];
|
|
335
|
-
const subLayoutDirections = LayoutDirectionsMap[layout];
|
|
336
|
-
if (!subLayoutDirections) {
|
|
337
|
-
throw new Error(`unexpected layout: ${layout} on correct layout`);
|
|
338
|
-
}
|
|
339
|
-
return subLayoutDirections.find(d => directions.includes(getLayoutReverseDirection(d)));
|
|
340
|
-
};
|
|
341
|
-
const correctLayoutByDirection = (layout, direction) => {
|
|
342
|
-
const isHorizontal = direction === LayoutDirection.left || direction === LayoutDirection.right ? true : false;
|
|
343
|
-
let inverseDirectionLayout = MindLayoutType.standard;
|
|
344
|
-
switch (layout) {
|
|
345
|
-
case MindLayoutType.left:
|
|
346
|
-
inverseDirectionLayout = MindLayoutType.right;
|
|
347
|
-
break;
|
|
348
|
-
case MindLayoutType.right:
|
|
349
|
-
inverseDirectionLayout = MindLayoutType.left;
|
|
350
|
-
break;
|
|
351
|
-
case MindLayoutType.downward:
|
|
352
|
-
inverseDirectionLayout = MindLayoutType.upward;
|
|
353
|
-
break;
|
|
354
|
-
case MindLayoutType.upward:
|
|
355
|
-
inverseDirectionLayout = MindLayoutType.downward;
|
|
356
|
-
break;
|
|
357
|
-
case MindLayoutType.rightBottomIndented:
|
|
358
|
-
inverseDirectionLayout = isHorizontal ? MindLayoutType.leftBottomIndented : MindLayoutType.rightTopIndented;
|
|
359
|
-
break;
|
|
360
|
-
case MindLayoutType.leftBottomIndented:
|
|
361
|
-
inverseDirectionLayout = isHorizontal ? MindLayoutType.rightBottomIndented : MindLayoutType.leftTopIndented;
|
|
362
|
-
break;
|
|
363
|
-
case MindLayoutType.rightTopIndented:
|
|
364
|
-
inverseDirectionLayout = isHorizontal ? MindLayoutType.leftTopIndented : MindLayoutType.rightBottomIndented;
|
|
365
|
-
break;
|
|
366
|
-
case MindLayoutType.leftTopIndented:
|
|
367
|
-
inverseDirectionLayout = isHorizontal ? MindLayoutType.rightTopIndented : MindLayoutType.leftBottomIndented;
|
|
368
|
-
break;
|
|
369
|
-
}
|
|
370
|
-
return inverseDirectionLayout;
|
|
371
|
-
};
|
|
372
|
-
const getLayoutDirection$1 = (root) => {
|
|
373
|
-
const layout = root.layout || getDefaultLayout();
|
|
374
|
-
return LayoutDirectionsMap[layout];
|
|
375
|
-
};
|
|
376
|
-
const getDefaultLayout = () => {
|
|
377
|
-
return MindLayoutType.standard;
|
|
378
|
-
};
|
|
379
|
-
const getAvailableSubLayoutsByLayoutDirections = (directions) => {
|
|
380
|
-
const result = [];
|
|
381
|
-
const reverseDirections = directions.map(getLayoutReverseDirection);
|
|
382
|
-
for (const key in MindLayoutType) {
|
|
383
|
-
const layout = MindLayoutType[key];
|
|
384
|
-
const layoutDirections = LayoutDirectionsMap[layout];
|
|
385
|
-
if (layoutDirections) {
|
|
386
|
-
const hasSameDirection = layoutDirections.some(d => directions.includes(d));
|
|
387
|
-
const hasReverseDirection = layoutDirections.some(r => reverseDirections.includes(r));
|
|
388
|
-
if (hasSameDirection && !hasReverseDirection) {
|
|
389
|
-
result.push(layout);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
return result;
|
|
394
|
-
};
|
|
395
|
-
const getLayoutReverseDirection = (layoutDirection) => {
|
|
396
|
-
let reverseDirection = LayoutDirection.right;
|
|
397
|
-
switch (layoutDirection) {
|
|
398
|
-
case LayoutDirection.top:
|
|
399
|
-
reverseDirection = LayoutDirection.bottom;
|
|
400
|
-
break;
|
|
401
|
-
case LayoutDirection.bottom:
|
|
402
|
-
reverseDirection = LayoutDirection.top;
|
|
403
|
-
break;
|
|
404
|
-
case LayoutDirection.right:
|
|
405
|
-
reverseDirection = LayoutDirection.left;
|
|
406
|
-
break;
|
|
407
|
-
case LayoutDirection.left:
|
|
408
|
-
reverseDirection = LayoutDirection.right;
|
|
409
|
-
break;
|
|
410
|
-
}
|
|
411
|
-
return reverseDirection;
|
|
412
|
-
};
|
|
413
|
-
const getRootLayout = (root) => {
|
|
414
|
-
return root.layout || getDefaultLayout();
|
|
415
|
-
};
|
|
416
|
-
|
|
417
410
|
function enterNodeEditing(element) {
|
|
418
411
|
const component = ELEMENT_TO_COMPONENT.get(element);
|
|
419
412
|
component.startEditText(false, false);
|
|
@@ -433,22 +426,146 @@ const separateChildren = (parentElement) => {
|
|
|
433
426
|
leftChildren.push(child);
|
|
434
427
|
continue;
|
|
435
428
|
}
|
|
436
|
-
if (i < rightNodeCount) {
|
|
437
|
-
rightChildren.push(child);
|
|
429
|
+
if (i < rightNodeCount) {
|
|
430
|
+
rightChildren.push(child);
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
leftChildren.push(child);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return { leftChildren, rightChildren };
|
|
437
|
+
};
|
|
438
|
+
const isSetAbstract = (element) => {
|
|
439
|
+
const parent = MindElement.getParent(element);
|
|
440
|
+
return !!getCorrespondingAbstract(parent, element);
|
|
441
|
+
};
|
|
442
|
+
const canSetAbstract = (element) => {
|
|
443
|
+
return !PlaitElement.isRootElement(element) && !AbstractNode.isAbstract(element) && !isSetAbstract(element);
|
|
444
|
+
};
|
|
445
|
+
const getCorrespondingAbstract = (parent, element) => {
|
|
446
|
+
if (!parent)
|
|
447
|
+
return undefined;
|
|
448
|
+
const elementIndex = parent.children.indexOf(element);
|
|
449
|
+
return parent.children.find(child => {
|
|
450
|
+
return AbstractNode.isAbstract(child) && elementIndex >= child.start && elementIndex <= child.end;
|
|
451
|
+
});
|
|
452
|
+
};
|
|
453
|
+
const getBehindAbstracts = (parent, element) => {
|
|
454
|
+
const index = parent.children.indexOf(element);
|
|
455
|
+
return parent.children.filter(child => AbstractNode.isAbstract(child) && child.start > index);
|
|
456
|
+
};
|
|
457
|
+
const getOverallAbstracts = (board, elements) => {
|
|
458
|
+
const overallAbstracts = [];
|
|
459
|
+
elements
|
|
460
|
+
.filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
|
|
461
|
+
.forEach(value => {
|
|
462
|
+
const parent = MindElement.getParent(value);
|
|
463
|
+
const abstract = getCorrespondingAbstract(parent, value);
|
|
464
|
+
if (abstract && overallAbstracts.indexOf(abstract) === -1) {
|
|
465
|
+
const { start, end } = abstract;
|
|
466
|
+
const parent = MindElement.getParent(value);
|
|
467
|
+
const isOverall = parent.children.slice(start, end + 1).every(includedElement => elements.indexOf(includedElement) > -1);
|
|
468
|
+
if (isOverall) {
|
|
469
|
+
overallAbstracts.push(abstract);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
return overallAbstracts;
|
|
474
|
+
};
|
|
475
|
+
const insertElementHandleAbstract = (board, path,
|
|
476
|
+
//由此区分拖拽和新增到概要概括最后一个节点
|
|
477
|
+
isExtendPreviousNode = true, abstractRefs = new Map()) => {
|
|
478
|
+
const parent = PlaitNode.parent(board, path);
|
|
479
|
+
const hasPreviousNode = path[path.length - 1] !== 0;
|
|
480
|
+
let behindAbstracts;
|
|
481
|
+
if (!hasPreviousNode) {
|
|
482
|
+
behindAbstracts = parent.children.filter(child => AbstractNode.isAbstract(child));
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
486
|
+
behindAbstracts = getBehindAbstracts(parent, selectedElement);
|
|
487
|
+
}
|
|
488
|
+
if (behindAbstracts.length) {
|
|
489
|
+
behindAbstracts.forEach(abstract => {
|
|
490
|
+
let newProperties = abstractRefs.get(abstract);
|
|
491
|
+
if (!newProperties) {
|
|
492
|
+
newProperties = { start: 0, end: 0 };
|
|
493
|
+
abstractRefs.set(abstract, newProperties);
|
|
494
|
+
}
|
|
495
|
+
newProperties.start = newProperties.start + 1;
|
|
496
|
+
newProperties.end = newProperties.end + 1;
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
if (!hasPreviousNode) {
|
|
500
|
+
return abstractRefs;
|
|
501
|
+
}
|
|
502
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
503
|
+
const correspondingAbstract = getCorrespondingAbstract(parent, selectedElement);
|
|
504
|
+
const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
|
|
505
|
+
if (correspondingAbstract && !isDragToLast) {
|
|
506
|
+
let newProperties = abstractRefs.get(correspondingAbstract);
|
|
507
|
+
if (!newProperties) {
|
|
508
|
+
newProperties = { start: 0, end: 0 };
|
|
509
|
+
abstractRefs.set(correspondingAbstract, newProperties);
|
|
510
|
+
}
|
|
511
|
+
newProperties.end = newProperties.end + 1;
|
|
512
|
+
}
|
|
513
|
+
return abstractRefs;
|
|
514
|
+
};
|
|
515
|
+
const deleteElementHandleAbstract = (board, deletableElements, abstractRefs = new Map()) => {
|
|
516
|
+
deletableElements.forEach(node => {
|
|
517
|
+
if (!PlaitMind.isMind(node)) {
|
|
518
|
+
const parent = PlaitNode.parent(board, PlaitBoard.findPath(board, node));
|
|
519
|
+
const behindAbstracts = getBehindAbstracts(parent, node).filter(abstract => !deletableElements.includes(abstract));
|
|
520
|
+
if (behindAbstracts.length) {
|
|
521
|
+
behindAbstracts.forEach(abstract => {
|
|
522
|
+
let newProperties = abstractRefs.get(abstract);
|
|
523
|
+
if (!newProperties) {
|
|
524
|
+
newProperties = { start: 0, end: 0 };
|
|
525
|
+
abstractRefs.set(abstract, newProperties);
|
|
526
|
+
}
|
|
527
|
+
newProperties.start = newProperties.start - 1;
|
|
528
|
+
newProperties.end = newProperties.end - 1;
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
const correspondingAbstract = getCorrespondingAbstract(parent, node);
|
|
532
|
+
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
533
|
+
let newProperties = abstractRefs.get(correspondingAbstract);
|
|
534
|
+
if (!newProperties) {
|
|
535
|
+
newProperties = { start: 0, end: 0 };
|
|
536
|
+
abstractRefs.set(correspondingAbstract, newProperties);
|
|
537
|
+
}
|
|
538
|
+
newProperties.end = newProperties.end - 1;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
return abstractRefs;
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
const setAbstractsByRefs = (board, abstractRefs) => {
|
|
546
|
+
abstractRefs.forEach((newProperty, element) => {
|
|
547
|
+
const start = element.start + newProperty.start;
|
|
548
|
+
const end = element.end + newProperty.end;
|
|
549
|
+
const path = PlaitBoard.findPath(board, element);
|
|
550
|
+
if (start > end) {
|
|
551
|
+
Transforms.removeNode(board, path);
|
|
438
552
|
}
|
|
439
553
|
else {
|
|
440
|
-
|
|
554
|
+
Transforms.setNode(board, { start, end }, path);
|
|
441
555
|
}
|
|
442
|
-
}
|
|
443
|
-
return { leftChildren, rightChildren };
|
|
444
|
-
};
|
|
445
|
-
const isSetAbstract = (element) => {
|
|
446
|
-
return !!getCorrespondingAbstract(element);
|
|
556
|
+
});
|
|
447
557
|
};
|
|
448
|
-
const
|
|
449
|
-
|
|
558
|
+
const setAbstractByStandardLayout = (board, element) => {
|
|
559
|
+
const rightNodeCount = element.rightNodeCount;
|
|
560
|
+
const abstract = element.children.find(child => {
|
|
561
|
+
return AbstractNode.isAbstract(child) && child.end >= rightNodeCount && child.start < rightNodeCount;
|
|
562
|
+
});
|
|
563
|
+
if (abstract) {
|
|
564
|
+
const path = PlaitBoard.findPath(board, abstract);
|
|
565
|
+
Transforms.setNode(board, { end: rightNodeCount - 1 }, path);
|
|
566
|
+
}
|
|
450
567
|
};
|
|
451
|
-
const
|
|
568
|
+
const insertAbstract = (board, elements) => {
|
|
452
569
|
let elementGroup = filterChildElement(elements);
|
|
453
570
|
const { parentElements, abstractIncludedGroups } = divideElementByParent(elementGroup);
|
|
454
571
|
abstractIncludedGroups.forEach((group, index) => {
|
|
@@ -478,52 +595,107 @@ const setAbstractByElements = (board, groupParent, group) => {
|
|
|
478
595
|
};
|
|
479
596
|
const insertAbstractNode = (board, path, start, end) => {
|
|
480
597
|
const mindElement = createMindElement('概要', 28, 20, {
|
|
481
|
-
strokeColor:
|
|
482
|
-
|
|
598
|
+
strokeColor: DefaultAbstractNodeStyle.strokeColor,
|
|
599
|
+
strokeWidth: DefaultAbstractNodeStyle.branchWidth,
|
|
600
|
+
branchColor: DefaultAbstractNodeStyle.branchColor,
|
|
601
|
+
branchWidth: DefaultAbstractNodeStyle.branchWidth
|
|
483
602
|
});
|
|
484
603
|
mindElement.start = start;
|
|
485
604
|
mindElement.end = end;
|
|
486
605
|
Transforms.insertNode(board, mindElement, path);
|
|
487
606
|
};
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
const path = PlaitBoard.findPath(board, abstract);
|
|
495
|
-
Transforms.setNode(board, { end: rightNodeCount - 1 }, path);
|
|
607
|
+
|
|
608
|
+
const setLayout = (board, layout, path) => {
|
|
609
|
+
correctLogicLayoutNode(board, layout, path);
|
|
610
|
+
const element = PlaitNode.get(board, path);
|
|
611
|
+
if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
|
|
612
|
+
MindTransforms.setAbstractByStandardLayout(board, element);
|
|
496
613
|
}
|
|
614
|
+
Transforms.setNode(board, { layout }, path);
|
|
497
615
|
};
|
|
498
|
-
const
|
|
499
|
-
const
|
|
500
|
-
if (
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
616
|
+
const correctLogicLayoutNode = (board, layout, path) => {
|
|
617
|
+
const node = PlaitNode.get(board, path);
|
|
618
|
+
if (node && layout) {
|
|
619
|
+
node.children?.forEach((value, index) => {
|
|
620
|
+
if (value.layout) {
|
|
621
|
+
if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
|
|
622
|
+
(isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
|
|
623
|
+
Transforms.setNode(board, { layout: null }, [...path, index]);
|
|
624
|
+
}
|
|
625
|
+
if (value.children?.length) {
|
|
626
|
+
correctLogicLayoutNode(board, layout, [...path, index]);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
}
|
|
511
631
|
};
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
632
|
+
|
|
633
|
+
const setTopic = (board, element, topic, width, height) => {
|
|
634
|
+
const newElement = {
|
|
635
|
+
data: { topic },
|
|
636
|
+
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
637
|
+
height: height / board.viewport.zoom
|
|
638
|
+
};
|
|
639
|
+
if (MindElement.hasEmojis(element)) {
|
|
640
|
+
newElement.data.emojis = element.data.emojis;
|
|
517
641
|
}
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
|
|
642
|
+
const path = PlaitBoard.findPath(board, element);
|
|
643
|
+
Transforms.setNode(board, newElement, path);
|
|
644
|
+
};
|
|
645
|
+
const setTopicSize = (board, element, width, height) => {
|
|
646
|
+
const newElement = {
|
|
647
|
+
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
648
|
+
height: height / board.viewport.zoom
|
|
649
|
+
};
|
|
650
|
+
const path = PlaitBoard.findPath(board, element);
|
|
651
|
+
Transforms.setNode(board, newElement, path);
|
|
652
|
+
};
|
|
653
|
+
const addEmoji = (board, element, emojiItem) => {
|
|
654
|
+
const emojis = element.data.emojis || [];
|
|
655
|
+
const newEmojis = [...emojis];
|
|
656
|
+
newEmojis.push(emojiItem);
|
|
657
|
+
const newElement = {
|
|
658
|
+
data: { topic: element.data.topic, emojis: newEmojis }
|
|
659
|
+
};
|
|
660
|
+
const path = PlaitBoard.findPath(board, element);
|
|
661
|
+
Transforms.setNode(board, newElement, path);
|
|
662
|
+
};
|
|
663
|
+
const removeEmoji = (board, element, emojiItem) => {
|
|
664
|
+
const emojis = element.data.emojis.filter(value => value !== emojiItem);
|
|
665
|
+
const newElement = {
|
|
666
|
+
data: { topic: element.data.topic }
|
|
667
|
+
};
|
|
668
|
+
if (emojis.length > 0) {
|
|
669
|
+
newElement.data.emojis = emojis;
|
|
521
670
|
}
|
|
671
|
+
const path = PlaitBoard.findPath(board, element);
|
|
672
|
+
Transforms.setNode(board, newElement, path);
|
|
522
673
|
};
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
674
|
+
const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
675
|
+
const newElement = {
|
|
676
|
+
data: { topic: element.data.topic }
|
|
677
|
+
};
|
|
678
|
+
const newEmojis = element.data.emojis.map(value => {
|
|
679
|
+
if (value === oldEmoji) {
|
|
680
|
+
return newEmoji;
|
|
681
|
+
}
|
|
682
|
+
return value;
|
|
526
683
|
});
|
|
684
|
+
newElement.data.emojis = newEmojis;
|
|
685
|
+
const path = PlaitBoard.findPath(board, element);
|
|
686
|
+
Transforms.setNode(board, newElement, path);
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
const MindTransforms = {
|
|
690
|
+
setLayout,
|
|
691
|
+
setTopic,
|
|
692
|
+
setTopicSize,
|
|
693
|
+
addEmoji,
|
|
694
|
+
removeEmoji,
|
|
695
|
+
replaceEmoji,
|
|
696
|
+
insertAbstract,
|
|
697
|
+
setAbstractsByRefs,
|
|
698
|
+
setAbstractByStandardLayout
|
|
527
699
|
};
|
|
528
700
|
|
|
529
701
|
function findParentElement(element) {
|
|
@@ -663,13 +835,13 @@ const shouldChangeRightNodeCount = (selectedElement) => {
|
|
|
663
835
|
return false;
|
|
664
836
|
};
|
|
665
837
|
const createDefaultMindMapElement = (point, rightNodeCount, layout) => {
|
|
666
|
-
const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape:
|
|
838
|
+
const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle, layout });
|
|
667
839
|
root.rightNodeCount = rightNodeCount;
|
|
668
840
|
root.isRoot = true;
|
|
669
841
|
root.type = 'mindmap';
|
|
670
842
|
root.points = [point];
|
|
671
843
|
const children = [1, 1, 1].map(() => {
|
|
672
|
-
return createMindElement('新建节点', 56, TEXT_DEFAULT_HEIGHT, { shape:
|
|
844
|
+
return createMindElement('新建节点', 56, TEXT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle });
|
|
673
845
|
});
|
|
674
846
|
root.children = children;
|
|
675
847
|
return root;
|
|
@@ -706,11 +878,14 @@ const createMindElement = (text, width, height, options) => {
|
|
|
706
878
|
if (options.branchColor) {
|
|
707
879
|
newElement.branchColor = options.branchColor;
|
|
708
880
|
}
|
|
881
|
+
if (!isNullOrUndefined(options.branchWidth)) {
|
|
882
|
+
newElement.branchWidth = options.branchWidth;
|
|
883
|
+
}
|
|
709
884
|
return newElement;
|
|
710
885
|
};
|
|
711
886
|
// layoutLevel 用来表示插入兄弟节点还是子节点
|
|
712
887
|
const insertMindElement = (board, inheritNode, path) => {
|
|
713
|
-
let fill, strokeColor, strokeWidth, shape =
|
|
888
|
+
let fill, strokeColor, strokeWidth, shape = MindElementShape.roundRectangle;
|
|
714
889
|
if (!inheritNode.isRoot) {
|
|
715
890
|
fill = inheritNode.fill;
|
|
716
891
|
strokeColor = inheritNode.strokeColor;
|
|
@@ -733,63 +908,23 @@ const findLastChild = (child) => {
|
|
|
733
908
|
return result;
|
|
734
909
|
};
|
|
735
910
|
const deleteSelectedELements = (board, selectedElements) => {
|
|
736
|
-
//翻转,从下到上修改,防止找不到 path
|
|
737
911
|
const deletableElements = filterChildElement(selectedElements).reverse();
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
behindAbstracts.forEach(abstract => {
|
|
745
|
-
let newProperties = accumulativeProperties.get(abstract);
|
|
746
|
-
if (!newProperties) {
|
|
747
|
-
newProperties = { start: abstract.start, end: abstract.end };
|
|
748
|
-
accumulativeProperties.set(abstract, newProperties);
|
|
749
|
-
relativeAbstracts.push(abstract);
|
|
750
|
-
}
|
|
751
|
-
newProperties.start = newProperties.start - 1;
|
|
752
|
-
newProperties.end = newProperties.end - 1;
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
const correspondingAbstract = getCorrespondingAbstract(node);
|
|
756
|
-
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
757
|
-
let newProperties = accumulativeProperties.get(correspondingAbstract);
|
|
758
|
-
if (!newProperties) {
|
|
759
|
-
newProperties = { start: correspondingAbstract.start, end: correspondingAbstract.end };
|
|
760
|
-
accumulativeProperties.set(correspondingAbstract, newProperties);
|
|
761
|
-
relativeAbstracts.push(correspondingAbstract);
|
|
762
|
-
}
|
|
763
|
-
newProperties.end = newProperties.end - 1;
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
});
|
|
767
|
-
const abstractHandles = relativeAbstracts.map(value => {
|
|
768
|
-
const newProperties = accumulativeProperties.get(value);
|
|
769
|
-
if (newProperties) {
|
|
770
|
-
const path = PlaitBoard.findPath(board, value);
|
|
771
|
-
return () => {
|
|
772
|
-
if (newProperties.start > newProperties.end) {
|
|
773
|
-
Transforms.removeNode(board, path);
|
|
774
|
-
}
|
|
775
|
-
else {
|
|
776
|
-
Transforms.setNode(board, newProperties, path);
|
|
777
|
-
}
|
|
778
|
-
};
|
|
779
|
-
}
|
|
780
|
-
return () => { };
|
|
781
|
-
});
|
|
782
|
-
const deletableHandles = deletableElements.map(node => {
|
|
783
|
-
const path = PlaitBoard.findPath(board, node);
|
|
912
|
+
const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
|
|
913
|
+
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
914
|
+
//翻转,从下到上修改,防止找不到 path
|
|
915
|
+
deletableElements
|
|
916
|
+
.map(element => {
|
|
917
|
+
const path = PlaitBoard.findPath(board, element);
|
|
784
918
|
return () => {
|
|
785
|
-
if (shouldChangeRightNodeCount(
|
|
786
|
-
changeRightNodeCount(board, path.slice(0,
|
|
919
|
+
if (shouldChangeRightNodeCount(element)) {
|
|
920
|
+
changeRightNodeCount(board, path.slice(0, 1), -1);
|
|
787
921
|
}
|
|
788
922
|
Transforms.removeNode(board, path);
|
|
789
923
|
};
|
|
924
|
+
})
|
|
925
|
+
.forEach(action => {
|
|
926
|
+
action();
|
|
790
927
|
});
|
|
791
|
-
abstractHandles.forEach(action => action());
|
|
792
|
-
deletableHandles.forEach(action => action());
|
|
793
928
|
};
|
|
794
929
|
const divideElementByParent = (elements) => {
|
|
795
930
|
const abstractIncludedGroups = [];
|
|
@@ -820,9 +955,12 @@ const getNodeShapeByElement = (element) => {
|
|
|
820
955
|
}
|
|
821
956
|
parent = findParentElement(parent);
|
|
822
957
|
}
|
|
823
|
-
return
|
|
958
|
+
return MindElementShape.roundRectangle;
|
|
824
959
|
};
|
|
825
960
|
|
|
961
|
+
/**
|
|
962
|
+
* Processing of branch color, width, style, etc. of the mind node
|
|
963
|
+
*/
|
|
826
964
|
const getBranchColorByMindElement = (board, element) => {
|
|
827
965
|
const ancestors = MindElement.getAncestors(board, element);
|
|
828
966
|
ancestors.unshift(element);
|
|
@@ -834,19 +972,40 @@ const getBranchColorByMindElement = (board, element) => {
|
|
|
834
972
|
const branch = ancestors[ancestors.length - 2];
|
|
835
973
|
if (branch) {
|
|
836
974
|
const index = root.children.indexOf(branch);
|
|
837
|
-
const length =
|
|
975
|
+
const length = BRANCH_COLORS.length;
|
|
838
976
|
const remainder = index % length;
|
|
839
|
-
return
|
|
977
|
+
return BRANCH_COLORS[remainder];
|
|
840
978
|
}
|
|
841
979
|
else {
|
|
842
980
|
throw new Error('root element should not have branch color');
|
|
843
981
|
}
|
|
844
982
|
};
|
|
983
|
+
const getBranchWidthByMindElement = (board, element) => {
|
|
984
|
+
const ancestors = MindElement.getAncestors(board, element);
|
|
985
|
+
ancestors.unshift(element);
|
|
986
|
+
const ancestor = ancestors.find(value => value.branchColor);
|
|
987
|
+
if (ancestor && ancestor.branchWidth) {
|
|
988
|
+
return ancestor.branchWidth;
|
|
989
|
+
}
|
|
990
|
+
return BRANCH_WIDTH;
|
|
991
|
+
};
|
|
992
|
+
const getAbstractBranchWidth = (board, element) => {
|
|
993
|
+
if (!isNullOrUndefined(element.branchWidth)) {
|
|
994
|
+
return element.branchWidth;
|
|
995
|
+
}
|
|
996
|
+
return DefaultAbstractNodeStyle.branchWidth;
|
|
997
|
+
};
|
|
998
|
+
const getAbstractBranchColor = (board, element) => {
|
|
999
|
+
if (element.branchColor) {
|
|
1000
|
+
return element.branchColor;
|
|
1001
|
+
}
|
|
1002
|
+
return DefaultAbstractNodeStyle.branchColor;
|
|
1003
|
+
};
|
|
845
1004
|
const getNextBranchColor = (root) => {
|
|
846
1005
|
const index = root.children.length;
|
|
847
|
-
const length =
|
|
1006
|
+
const length = BRANCH_COLORS.length;
|
|
848
1007
|
const remainder = index % length;
|
|
849
|
-
return
|
|
1008
|
+
return BRANCH_COLORS[remainder];
|
|
850
1009
|
};
|
|
851
1010
|
|
|
852
1011
|
const getStrokeByMindElement = (board, element) => {
|
|
@@ -860,12 +1019,12 @@ const getStrokeByMindElement = (board, element) => {
|
|
|
860
1019
|
const branch = ancestors[ancestors.length - 2];
|
|
861
1020
|
if (branch) {
|
|
862
1021
|
const index = root.children.indexOf(branch);
|
|
863
|
-
const length =
|
|
1022
|
+
const length = BRANCH_COLORS.length;
|
|
864
1023
|
const remainder = index % length;
|
|
865
|
-
return
|
|
1024
|
+
return BRANCH_COLORS[remainder];
|
|
866
1025
|
}
|
|
867
1026
|
else {
|
|
868
|
-
return
|
|
1027
|
+
return DefaultRootStyle.strokeColor;
|
|
869
1028
|
}
|
|
870
1029
|
};
|
|
871
1030
|
|
|
@@ -883,7 +1042,7 @@ function isVirtualKey(e) {
|
|
|
883
1042
|
|
|
884
1043
|
function drawLink(board, node, child, defaultStroke = null, isHorizontal = true, needDrawUnderline = true) {
|
|
885
1044
|
let beginX, beginY, endX, endY, beginNode = node, endNode = child;
|
|
886
|
-
const layout = MindQueries.getCorrectLayoutByElement(node.origin);
|
|
1045
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
|
|
887
1046
|
if (isHorizontal) {
|
|
888
1047
|
if (!isChildRight(node, child)) {
|
|
889
1048
|
beginNode = child;
|
|
@@ -895,7 +1054,7 @@ function drawLink(board, node, child, defaultStroke = null, isHorizontal = true,
|
|
|
895
1054
|
endY = endNode.y + endNode.height / 2;
|
|
896
1055
|
if (node.parent &&
|
|
897
1056
|
isIndentedLayout(MindQueries.getLayoutByElement(node.parent?.origin)) &&
|
|
898
|
-
getNodeShapeByElement(node.origin) ===
|
|
1057
|
+
getNodeShapeByElement(node.origin) === MindElementShape.underline) {
|
|
899
1058
|
if (isChildRight(node, child)) {
|
|
900
1059
|
beginY = node.y + node.height - node.vGap;
|
|
901
1060
|
}
|
|
@@ -970,7 +1129,7 @@ function drawLink(board, node, child, defaultStroke = null, isHorizontal = true,
|
|
|
970
1129
|
curve = [...line, ...curve];
|
|
971
1130
|
}
|
|
972
1131
|
}
|
|
973
|
-
if (needDrawUnderline && shape ===
|
|
1132
|
+
if (needDrawUnderline && shape === MindElementShape.underline) {
|
|
974
1133
|
if (child.left) {
|
|
975
1134
|
const underline = [
|
|
976
1135
|
[beginX - (beginNode.width - beginNode.hGap * 2), beginY],
|
|
@@ -1046,8 +1205,8 @@ const drawPlaceholderDropNodeG = (board, dropTarget, fakeDropNodeG) => {
|
|
|
1046
1205
|
}
|
|
1047
1206
|
};
|
|
1048
1207
|
const drawCurvePlaceholderDropNodeG = (board, targetRect, detectResult, targetIndex, targetComponent, parentComponent, fakeDropNodeG) => {
|
|
1049
|
-
const parentNodeLayout = MindQueries.getCorrectLayoutByElement(parentComponent.node.origin);
|
|
1050
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.parent.origin);
|
|
1208
|
+
const parentNodeLayout = MindQueries.getCorrectLayoutByElement(board, parentComponent.node.origin);
|
|
1209
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.parent.origin);
|
|
1051
1210
|
const strokeWidth = targetComponent.node.origin.branchWidth ? targetComponent.node.origin.branchWidth : STROKE_WIDTH;
|
|
1052
1211
|
let fakeX = targetComponent.node.x, fakeY = targetRect.y - 30, fakeRectangleStartX = targetRect.x, fakeRectangleEndX = targetRect.x + 30, fakeRectangleStartY = fakeY, fakeRectangleEndY = fakeRectangleStartY + 12, width = 30;
|
|
1053
1212
|
if (isLeftLayout(layout)) {
|
|
@@ -1178,8 +1337,8 @@ const drawStraightDropNodeG = (board, targetRect, detectResult, targetComponent,
|
|
|
1178
1337
|
height,
|
|
1179
1338
|
strokeWidth
|
|
1180
1339
|
};
|
|
1181
|
-
const parentLayout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1182
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin);
|
|
1340
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1341
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1183
1342
|
if (!isMixedLayout(parentLayout, layout)) {
|
|
1184
1343
|
// 构造一条直线
|
|
1185
1344
|
let linePoints = [
|
|
@@ -1389,29 +1548,29 @@ const directionDetector = (targetNode, centerPoint) => {
|
|
|
1389
1548
|
return null;
|
|
1390
1549
|
};
|
|
1391
1550
|
|
|
1392
|
-
const directionCorrector = (node, detectResults) => {
|
|
1393
|
-
if (!node.origin.isRoot) {
|
|
1394
|
-
const
|
|
1395
|
-
if (isStandardLayout(
|
|
1551
|
+
const directionCorrector = (board, node, detectResults) => {
|
|
1552
|
+
if (!node.origin.isRoot && !AbstractNode.isAbstract(node.origin)) {
|
|
1553
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, node?.parent.origin);
|
|
1554
|
+
if (isStandardLayout(parentLayout)) {
|
|
1396
1555
|
const idx = node.parent.children.findIndex(x => x === node);
|
|
1397
1556
|
const isLeft = idx >= (node.parent.origin.rightNodeCount || 0);
|
|
1398
1557
|
return getAllowedDirection(detectResults, [isLeft ? 'right' : 'left']);
|
|
1399
1558
|
}
|
|
1400
|
-
if (isLeftLayout(
|
|
1559
|
+
if (isLeftLayout(parentLayout)) {
|
|
1401
1560
|
return getAllowedDirection(detectResults, ['right']);
|
|
1402
1561
|
}
|
|
1403
|
-
if (isRightLayout(
|
|
1562
|
+
if (isRightLayout(parentLayout)) {
|
|
1404
1563
|
return getAllowedDirection(detectResults, ['left']);
|
|
1405
1564
|
}
|
|
1406
|
-
if (
|
|
1565
|
+
if (parentLayout === MindLayoutType.upward) {
|
|
1407
1566
|
return getAllowedDirection(detectResults, ['bottom']);
|
|
1408
1567
|
}
|
|
1409
|
-
if (
|
|
1568
|
+
if (parentLayout === MindLayoutType.downward) {
|
|
1410
1569
|
return getAllowedDirection(detectResults, ['top']);
|
|
1411
1570
|
}
|
|
1412
1571
|
}
|
|
1413
1572
|
else {
|
|
1414
|
-
const layout = MindQueries.getCorrectLayoutByElement(node?.origin);
|
|
1573
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node?.origin);
|
|
1415
1574
|
if (isStandardLayout(layout)) {
|
|
1416
1575
|
return getAllowedDirection(detectResults, ['top', 'bottom']);
|
|
1417
1576
|
}
|
|
@@ -1442,17 +1601,18 @@ const getAllowedDirection = (detectResults, illegalDirections) => {
|
|
|
1442
1601
|
};
|
|
1443
1602
|
|
|
1444
1603
|
/* 根据布局调整 target 以及 direction */
|
|
1445
|
-
const readjustmentDropTarget = (dropTarget) => {
|
|
1604
|
+
const readjustmentDropTarget = (board, dropTarget) => {
|
|
1446
1605
|
const { target, detectResult } = dropTarget;
|
|
1447
1606
|
const newDropTarget = { target, detectResult };
|
|
1448
1607
|
const targetComponent = PlaitElement.getComponent(target);
|
|
1449
1608
|
if (targetComponent.node.children.length > 0 && dropTarget.detectResult) {
|
|
1450
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin);
|
|
1451
|
-
const parentLayout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1609
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1610
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1611
|
+
const children = getNonAbstractChildren(targetComponent.node);
|
|
1452
1612
|
if (['right', 'left'].includes(dropTarget.detectResult)) {
|
|
1453
1613
|
if (!isMixedLayout(parentLayout, layout)) {
|
|
1454
1614
|
if (targetComponent.node.origin.isRoot) {
|
|
1455
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin);
|
|
1615
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1456
1616
|
// 标准布局,根节点
|
|
1457
1617
|
if (isStandardLayout(layout)) {
|
|
1458
1618
|
const rightNodeCount = targetComponent.node.origin.rightNodeCount;
|
|
@@ -1486,14 +1646,14 @@ const readjustmentDropTarget = (dropTarget) => {
|
|
|
1486
1646
|
return newDropTarget;
|
|
1487
1647
|
}
|
|
1488
1648
|
// 剩下是水平布局的默认情况:插入最后一个子节点的下方
|
|
1489
|
-
const lastChildNodeIndex =
|
|
1649
|
+
const lastChildNodeIndex = children.length - 1;
|
|
1490
1650
|
newDropTarget.target = targetComponent.node.children[lastChildNodeIndex].origin;
|
|
1491
1651
|
newDropTarget.detectResult = 'bottom';
|
|
1492
1652
|
}
|
|
1493
1653
|
else {
|
|
1494
1654
|
// 处理左右布局下的混合布局
|
|
1495
1655
|
if ([MindLayoutType.left, MindLayoutType.right].includes(parentLayout)) {
|
|
1496
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin);
|
|
1656
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1497
1657
|
if (isIndentedLayout(layout)) {
|
|
1498
1658
|
newDropTarget.target = targetComponent.node.children[0].origin;
|
|
1499
1659
|
newDropTarget.detectResult = isTopLayout(layout) ? 'bottom' : 'top';
|
|
@@ -1510,9 +1670,9 @@ const readjustmentDropTarget = (dropTarget) => {
|
|
|
1510
1670
|
return newDropTarget;
|
|
1511
1671
|
}
|
|
1512
1672
|
// 上下布局,插到右边
|
|
1513
|
-
const parentLayout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1673
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1514
1674
|
if (isVerticalLogicLayout(parentLayout)) {
|
|
1515
|
-
const lastChildNodeIndex =
|
|
1675
|
+
const lastChildNodeIndex = children.length - 1;
|
|
1516
1676
|
newDropTarget.target = targetComponent.node.children[lastChildNodeIndex].origin;
|
|
1517
1677
|
newDropTarget.detectResult = 'right';
|
|
1518
1678
|
return newDropTarget;
|
|
@@ -1623,7 +1783,7 @@ const getLocationScope = (board, handlePosition, parentChildren, element, parent
|
|
|
1623
1783
|
}
|
|
1624
1784
|
};
|
|
1625
1785
|
const getHitAbstractHandle = (board, element, point) => {
|
|
1626
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(element);
|
|
1786
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
1627
1787
|
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
1628
1788
|
const parentElement = MindElement.getParent(element);
|
|
1629
1789
|
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
@@ -1710,24 +1870,25 @@ function handleTouchedAbstract(board, touchedAbstract, endPoint) {
|
|
|
1710
1870
|
}
|
|
1711
1871
|
|
|
1712
1872
|
function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnderline = true) {
|
|
1713
|
-
const
|
|
1873
|
+
const branchWidth = getBranchWidthByMindElement(board, child.origin);
|
|
1874
|
+
const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin);
|
|
1875
|
+
const isUnderlineShape = getNodeShapeByElement(child.origin) === MindElementShape.underline;
|
|
1714
1876
|
let beginX, beginY, endX, endY, beginNode = node, endNode = child;
|
|
1715
1877
|
const beginRectangle = getRectangleByNode(beginNode);
|
|
1716
1878
|
const endRectangle = getRectangleByNode(endNode);
|
|
1717
1879
|
beginX = beginNode.x + beginNode.width / 2;
|
|
1718
1880
|
beginY = isChildUp(node, child) ? beginRectangle.y : beginRectangle.y + beginRectangle.height;
|
|
1719
1881
|
endX = node.left ? endNode.x + endNode.hGap + endRectangle.width : endNode.x + endNode.hGap;
|
|
1720
|
-
endY =
|
|
1882
|
+
endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
|
|
1721
1883
|
//根据位置,设置正负参数
|
|
1722
1884
|
let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
|
|
1723
|
-
const layout = MindQueries.getCorrectLayoutByElement(node.origin);
|
|
1724
|
-
const strokeWidth = child.origin.branchWidth ? child.origin.branchWidth : STROKE_WIDTH;
|
|
1885
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
|
|
1725
1886
|
if (beginNode.origin.isRoot) {
|
|
1726
1887
|
if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
|
|
1727
|
-
beginY +=
|
|
1888
|
+
beginY += branchWidth;
|
|
1728
1889
|
}
|
|
1729
1890
|
if (layout === MindLayoutType.leftTopIndented || layout === MindLayoutType.rightTopIndented) {
|
|
1730
|
-
beginY -=
|
|
1891
|
+
beginY -= branchWidth;
|
|
1731
1892
|
}
|
|
1732
1893
|
}
|
|
1733
1894
|
let curve = [
|
|
@@ -1738,13 +1899,12 @@ function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnde
|
|
|
1738
1899
|
[beginX, endY - (endNode.hGap * plusMinus[1]) / 5],
|
|
1739
1900
|
[beginX + (endNode.hGap * plusMinus[0]) / 4, endY],
|
|
1740
1901
|
[beginX + (endNode.hGap * plusMinus[0] * 3) / 5, endY],
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1902
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1903
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1904
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY]
|
|
1744
1905
|
];
|
|
1745
|
-
const stroke = defaultStroke || getBranchColorByMindElement(board, child.origin);
|
|
1746
1906
|
const points = pointsOnBezierCurves(curve);
|
|
1747
|
-
return PlaitBoard.getRoughSVG(board).curve(points, { stroke, strokeWidth });
|
|
1907
|
+
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1748
1908
|
}
|
|
1749
1909
|
|
|
1750
1910
|
var HorizontalPlacement;
|
|
@@ -1859,10 +2019,10 @@ const transformPlacement = (placement, direction) => {
|
|
|
1859
2019
|
|
|
1860
2020
|
function drawLogicLink(board, node, parent, isHorizontal) {
|
|
1861
2021
|
const branchColor = getBranchColorByMindElement(board, node.origin);
|
|
1862
|
-
const
|
|
2022
|
+
const branchWidth = getBranchWidthByMindElement(board, node.origin);
|
|
1863
2023
|
const hasStraightLine = !parent.origin.isRoot;
|
|
1864
|
-
const hasUnderlineShape = node.origin.shape ===
|
|
1865
|
-
const hasUnderlineShapeOfParent = parent.origin.shape ===
|
|
2024
|
+
const hasUnderlineShape = node.origin.shape === MindElementShape.underline;
|
|
2025
|
+
const hasUnderlineShapeOfParent = parent.origin.shape === MindElementShape.underline;
|
|
1866
2026
|
const nodeClient = getRectangleByNode(node);
|
|
1867
2027
|
const parentClient = getRectangleByNode(parent);
|
|
1868
2028
|
const linkDirection = getLayoutDirection(node, isHorizontal);
|
|
@@ -1899,13 +2059,17 @@ function drawLogicLink(board, node, parent, isHorizontal) {
|
|
|
1899
2059
|
const underlineEnd = movePoint(endPoint, nodeClient.width, linkDirection);
|
|
1900
2060
|
const underline = hasUnderlineShape && isHorizontal ? [underlineEnd, underlineEnd, underlineEnd] : [];
|
|
1901
2061
|
const points = pointsOnBezierCurves([...straightLine, ...curve, ...underline]);
|
|
1902
|
-
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth });
|
|
2062
|
+
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1903
2063
|
}
|
|
1904
2064
|
|
|
1905
|
-
function getEmojisRectangle(element) {
|
|
2065
|
+
function getEmojisRectangle(board, element) {
|
|
2066
|
+
const options = board.getMindOptions();
|
|
1906
2067
|
const count = element.data.emojis.length;
|
|
1907
2068
|
const fontSize = getEmojiFontSize(element);
|
|
1908
|
-
return {
|
|
2069
|
+
return {
|
|
2070
|
+
width: fontSize * count + count * 2 * options.emojiPadding + (count - 1) * options.spaceBetweenEmojis,
|
|
2071
|
+
height: element.height
|
|
2072
|
+
};
|
|
1909
2073
|
}
|
|
1910
2074
|
function getEmojiFontSize(element) {
|
|
1911
2075
|
if (PlaitMind.isMind(element)) {
|
|
@@ -1950,10 +2114,10 @@ const getVerticalSpaceBetweenNodeAndText = (element) => {
|
|
|
1950
2114
|
return nodeAndText;
|
|
1951
2115
|
};
|
|
1952
2116
|
const NodeSpace = {
|
|
1953
|
-
getNodeWidth(element) {
|
|
2117
|
+
getNodeWidth(board, element) {
|
|
1954
2118
|
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(element);
|
|
1955
2119
|
if (MindElement.hasEmojis(element)) {
|
|
1956
|
-
return nodeAndText + getEmojisRectangle(element).width + getHorizontalSpaceEmojiAndText(element) + element.width + nodeAndText;
|
|
2120
|
+
return nodeAndText + getEmojisRectangle(board, element).width + getHorizontalSpaceEmojiAndText(element) + element.width + nodeAndText;
|
|
1957
2121
|
}
|
|
1958
2122
|
return nodeAndText + element.width + nodeAndText;
|
|
1959
2123
|
},
|
|
@@ -1961,10 +2125,10 @@ const NodeSpace = {
|
|
|
1961
2125
|
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1962
2126
|
return nodeAndText + element.height + nodeAndText;
|
|
1963
2127
|
},
|
|
1964
|
-
getTextHorizontalSpace(element) {
|
|
2128
|
+
getTextHorizontalSpace(board, element) {
|
|
1965
2129
|
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(element);
|
|
1966
2130
|
if (MindElement.hasEmojis(element)) {
|
|
1967
|
-
return nodeAndText + getEmojisRectangle(element).width + getHorizontalSpaceEmojiAndText(element);
|
|
2131
|
+
return nodeAndText + getEmojisRectangle(board, element).width + getHorizontalSpaceEmojiAndText(element);
|
|
1968
2132
|
}
|
|
1969
2133
|
else {
|
|
1970
2134
|
return nodeAndText;
|
|
@@ -1984,8 +2148,8 @@ const NodeSpace = {
|
|
|
1984
2148
|
}
|
|
1985
2149
|
};
|
|
1986
2150
|
|
|
1987
|
-
function drawMindNodeRichtext(node, viewContainerRef) {
|
|
1988
|
-
const { x, y } = getRichtextRectangleByNode(node);
|
|
2151
|
+
function drawMindNodeRichtext(board, node, viewContainerRef) {
|
|
2152
|
+
const { x, y } = getRichtextRectangleByNode(board, node);
|
|
1989
2153
|
const classList = [];
|
|
1990
2154
|
if (node.origin.isRoot) {
|
|
1991
2155
|
classList.push('root-node');
|
|
@@ -2000,8 +2164,8 @@ function drawMindNodeRichtext(node, viewContainerRef) {
|
|
|
2000
2164
|
// COMPAT: last character can not show in safari browser
|
|
2001
2165
|
return drawRichtext(x, y, Math.ceil(node.origin.width), Math.ceil(node.origin.height), node.origin.data.topic, viewContainerRef, classList);
|
|
2002
2166
|
}
|
|
2003
|
-
function updateMindNodeTopicSize(node, g, isEditable) {
|
|
2004
|
-
const { x, y, width, height } = getRichtextRectangleByNode(node);
|
|
2167
|
+
function updateMindNodeTopicSize(board, node, g, isEditable) {
|
|
2168
|
+
const { x, y, width, height } = getRichtextRectangleByNode(board, node);
|
|
2005
2169
|
if (isEditable) {
|
|
2006
2170
|
// add 999, avoid changing lines when paste more text
|
|
2007
2171
|
updateForeignObject(g, width + 999, height + 999, x, y);
|
|
@@ -2011,18 +2175,18 @@ function updateMindNodeTopicSize(node, g, isEditable) {
|
|
|
2011
2175
|
updateForeignObject(g, Math.ceil(node.origin.width), Math.ceil(node.origin.height), x, y);
|
|
2012
2176
|
}
|
|
2013
2177
|
}
|
|
2014
|
-
function getRichtextRectangleByNode(node) {
|
|
2178
|
+
function getRichtextRectangleByNode(board, node) {
|
|
2015
2179
|
let { x, y, width, height } = getRectangleByNode(node);
|
|
2016
|
-
x = x + NodeSpace.getTextHorizontalSpace(node.origin);
|
|
2180
|
+
x = x + NodeSpace.getTextHorizontalSpace(board, node.origin);
|
|
2017
2181
|
y = y + NodeSpace.getTextVerticalSpace(node.origin);
|
|
2018
2182
|
return { width, height, x, y };
|
|
2019
2183
|
}
|
|
2020
2184
|
|
|
2021
2185
|
function drawRectangleNode(board, node) {
|
|
2022
2186
|
const { x, y, width, height } = getRectangleByNode(node);
|
|
2023
|
-
const fill = node.origin.fill ? node.origin.fill : node.origin.isRoot ?
|
|
2187
|
+
const fill = node.origin.fill ? node.origin.fill : node.origin.isRoot ? DefaultRootStyle.fill : DefaultNodeStyle.fill;
|
|
2024
2188
|
const stroke = getStrokeByMindElement(board, node.origin);
|
|
2025
|
-
const strokeWidth = node.origin.strokeWidth ? node.origin.strokeWidth :
|
|
2189
|
+
const strokeWidth = node.origin.strokeWidth ? node.origin.strokeWidth : DefaultNodeStyle.strokeWidth;
|
|
2026
2190
|
const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), x, y, x + width, y + height, {
|
|
2027
2191
|
stroke,
|
|
2028
2192
|
strokeWidth,
|
|
@@ -2034,6 +2198,8 @@ function drawRectangleNode(board, node) {
|
|
|
2034
2198
|
|
|
2035
2199
|
function drawAbstractLink(board, node, isHorizontal) {
|
|
2036
2200
|
const linkPadding = 15;
|
|
2201
|
+
const branchWidth = getAbstractBranchWidth(board, node.origin);
|
|
2202
|
+
const branchColor = getAbstractBranchColor(board, node.origin);
|
|
2037
2203
|
const parent = node.parent;
|
|
2038
2204
|
const abstractRectangle = getRectangleByNode(node);
|
|
2039
2205
|
let includedElements = parent.children.slice(node.origin.start, node.origin.end + 1).map(node => {
|
|
@@ -2063,8 +2229,8 @@ function drawAbstractLink(board, node, isHorizontal) {
|
|
|
2063
2229
|
let c2 = movePoint(bezierEndPoint, curveDistance, linkDirection);
|
|
2064
2230
|
let bezierConnectorPoint = movePoint(abstractConnectorPoint, -linkPadding, linkDirection);
|
|
2065
2231
|
const link = PlaitBoard.getRoughSVG(board).path(`M${bezierBeginPoint[0]},${bezierBeginPoint[1]} Q${c1[0]},${c1[1]} ${bezierConnectorPoint[0]},${bezierConnectorPoint[1]} Q${c2[0]},${c2[1]} ${bezierEndPoint[0]},${bezierEndPoint[1]} M${abstractConnectorPoint[0]},${abstractConnectorPoint[1]} L${bezierConnectorPoint[0]},${bezierConnectorPoint[1]}`, {
|
|
2066
|
-
stroke:
|
|
2067
|
-
strokeWidth:
|
|
2232
|
+
stroke: branchColor,
|
|
2233
|
+
strokeWidth: branchWidth
|
|
2068
2234
|
});
|
|
2069
2235
|
return link;
|
|
2070
2236
|
}
|
|
@@ -2112,9 +2278,8 @@ class EmojisDrawer {
|
|
|
2112
2278
|
this.g.classList.add('emojis');
|
|
2113
2279
|
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
2114
2280
|
x = x + NodeSpace.getEmojiHorizontalSpace(element);
|
|
2115
|
-
|
|
2116
|
-
const
|
|
2117
|
-
const foreignObject = createForeignObject(x, y, width, height);
|
|
2281
|
+
const { width, height } = getEmojisRectangle(this.board, element);
|
|
2282
|
+
const foreignObject = createForeignObject(x, y, width, height + NodeSpace.getEmojiVerticalSpace(element) * 2);
|
|
2118
2283
|
this.g.append(foreignObject);
|
|
2119
2284
|
const container = document.createElement('div');
|
|
2120
2285
|
container.classList.add('node-emojis-container');
|
|
@@ -2126,114 +2291,24 @@ class EmojisDrawer {
|
|
|
2126
2291
|
});
|
|
2127
2292
|
this.emojiDrawers.forEach(drawer => {
|
|
2128
2293
|
container.append(drawer.nativeElement);
|
|
2129
|
-
});
|
|
2130
|
-
return this.g;
|
|
2131
|
-
}
|
|
2132
|
-
return undefined;
|
|
2133
|
-
}
|
|
2134
|
-
destroy() {
|
|
2135
|
-
if (this.g) {
|
|
2136
|
-
this.g.remove();
|
|
2137
|
-
}
|
|
2138
|
-
this.emojiDrawers.forEach(drawer => drawer.destroy());
|
|
2139
|
-
this.emojiDrawers = [];
|
|
2140
|
-
}
|
|
2141
|
-
}
|
|
2142
|
-
|
|
2143
|
-
const setLayout = (board, layout, path) => {
|
|
2144
|
-
correctLogicLayoutNode(board, layout, path);
|
|
2145
|
-
const element = PlaitNode.get(board, path);
|
|
2146
|
-
if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
|
|
2147
|
-
handleAbstractIncluded(board, element);
|
|
2148
|
-
}
|
|
2149
|
-
Transforms.setNode(board, { layout }, path);
|
|
2150
|
-
};
|
|
2151
|
-
const correctLogicLayoutNode = (board, layout, path) => {
|
|
2152
|
-
const node = PlaitNode.get(board, path);
|
|
2153
|
-
if (node && layout) {
|
|
2154
|
-
node.children?.forEach((value, index) => {
|
|
2155
|
-
if (value.layout) {
|
|
2156
|
-
if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
|
|
2157
|
-
(isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
|
|
2158
|
-
Transforms.setNode(board, { layout: null }, [...path, index]);
|
|
2159
|
-
}
|
|
2160
|
-
if (value.children?.length) {
|
|
2161
|
-
correctLogicLayoutNode(board, layout, [...path, index]);
|
|
2162
|
-
}
|
|
2163
|
-
}
|
|
2164
|
-
});
|
|
2165
|
-
}
|
|
2166
|
-
};
|
|
2167
|
-
|
|
2168
|
-
const setTopic = (board, element, topic, width, height) => {
|
|
2169
|
-
const newElement = {
|
|
2170
|
-
data: { topic },
|
|
2171
|
-
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
2172
|
-
height: height / board.viewport.zoom
|
|
2173
|
-
};
|
|
2174
|
-
if (MindElement.hasEmojis(element)) {
|
|
2175
|
-
newElement.data.emojis = element.data.emojis;
|
|
2176
|
-
}
|
|
2177
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2178
|
-
Transforms.setNode(board, newElement, path);
|
|
2179
|
-
};
|
|
2180
|
-
const setTopicSize = (board, element, width, height) => {
|
|
2181
|
-
const newElement = {
|
|
2182
|
-
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
2183
|
-
height: height / board.viewport.zoom
|
|
2184
|
-
};
|
|
2185
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2186
|
-
Transforms.setNode(board, newElement, path);
|
|
2187
|
-
};
|
|
2188
|
-
const addEmoji = (board, element, emojiItem) => {
|
|
2189
|
-
const emojis = element.data.emojis || [];
|
|
2190
|
-
const newEmojis = [...emojis];
|
|
2191
|
-
newEmojis.push(emojiItem);
|
|
2192
|
-
const newElement = {
|
|
2193
|
-
data: { topic: element.data.topic, emojis: newEmojis }
|
|
2194
|
-
};
|
|
2195
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2196
|
-
Transforms.setNode(board, newElement, path);
|
|
2197
|
-
};
|
|
2198
|
-
const removeEmoji = (board, element, emojiItem) => {
|
|
2199
|
-
const emojis = element.data.emojis.filter(value => value !== emojiItem);
|
|
2200
|
-
const newElement = {
|
|
2201
|
-
data: { topic: element.data.topic }
|
|
2202
|
-
};
|
|
2203
|
-
if (emojis.length > 0) {
|
|
2204
|
-
newElement.data.emojis = emojis;
|
|
2205
|
-
}
|
|
2206
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2207
|
-
Transforms.setNode(board, newElement, path);
|
|
2208
|
-
};
|
|
2209
|
-
const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
2210
|
-
const newElement = {
|
|
2211
|
-
data: { topic: element.data.topic }
|
|
2212
|
-
};
|
|
2213
|
-
const newEmojis = element.data.emojis.map(value => {
|
|
2214
|
-
if (value === oldEmoji) {
|
|
2215
|
-
return newEmoji;
|
|
2294
|
+
});
|
|
2295
|
+
return this.g;
|
|
2216
2296
|
}
|
|
2217
|
-
return
|
|
2218
|
-
}
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
}
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
setTopicSize,
|
|
2228
|
-
addEmoji,
|
|
2229
|
-
removeEmoji,
|
|
2230
|
-
replaceEmoji
|
|
2231
|
-
};
|
|
2297
|
+
return undefined;
|
|
2298
|
+
}
|
|
2299
|
+
destroy() {
|
|
2300
|
+
if (this.g) {
|
|
2301
|
+
this.g.remove();
|
|
2302
|
+
}
|
|
2303
|
+
this.emojiDrawers.forEach(drawer => drawer.destroy());
|
|
2304
|
+
this.emojiDrawers = [];
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2232
2307
|
|
|
2233
2308
|
function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
|
|
2234
2309
|
const abstractIncludedG = createG();
|
|
2235
2310
|
const parentElement = MindElement.getParent(element);
|
|
2236
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(element);
|
|
2311
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
2237
2312
|
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
2238
2313
|
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
2239
2314
|
let abstractRectangle = getRectangleByElements(board, includedElements, true);
|
|
@@ -2313,7 +2388,8 @@ function hasAfterDraw(value) {
|
|
|
2313
2388
|
}
|
|
2314
2389
|
|
|
2315
2390
|
function findNewChildNodePath(board, element) {
|
|
2316
|
-
|
|
2391
|
+
const children = getNonAbstractChildren(element);
|
|
2392
|
+
return PlaitBoard.findPath(board, element).concat(children.length);
|
|
2317
2393
|
}
|
|
2318
2394
|
function findNewSiblingNodePath(board, element) {
|
|
2319
2395
|
const path = PlaitBoard.findPath(board, element);
|
|
@@ -2343,14 +2419,14 @@ class QuickInsertDrawer extends BaseDrawer {
|
|
|
2343
2419
|
*/
|
|
2344
2420
|
const shape = getNodeShapeByElement(element);
|
|
2345
2421
|
// 形状是矩形要偏移边框的线宽
|
|
2346
|
-
const
|
|
2422
|
+
const branchWidth = getBranchWidthByMindElement(this.board, element);
|
|
2347
2423
|
let offsetBorderLineWidth = 0;
|
|
2348
|
-
if (shape ===
|
|
2349
|
-
offsetBorderLineWidth =
|
|
2424
|
+
if (shape === MindElementShape.roundRectangle && offset === 0) {
|
|
2425
|
+
offsetBorderLineWidth = branchWidth;
|
|
2350
2426
|
}
|
|
2351
2427
|
let offsetRootBorderLineWidth = 0;
|
|
2352
2428
|
if (element.isRoot) {
|
|
2353
|
-
offsetRootBorderLineWidth =
|
|
2429
|
+
offsetRootBorderLineWidth = branchWidth;
|
|
2354
2430
|
}
|
|
2355
2431
|
// 当没有子节点时,需要缩小的偏移量
|
|
2356
2432
|
const extraOffset = 3;
|
|
@@ -2445,21 +2521,21 @@ class QuickInsertDrawer extends BaseDrawer {
|
|
|
2445
2521
|
offsetRootBorderLineWidth
|
|
2446
2522
|
}
|
|
2447
2523
|
};
|
|
2448
|
-
if (shape ===
|
|
2524
|
+
if (shape === MindElementShape.roundRectangle || element.isRoot) {
|
|
2449
2525
|
underlineCoordinates[MindLayoutType.left].startY -= height * 0.5;
|
|
2450
2526
|
underlineCoordinates[MindLayoutType.left].endY -= height * 0.5;
|
|
2451
2527
|
underlineCoordinates[MindLayoutType.right].startY -= height * 0.5;
|
|
2452
2528
|
underlineCoordinates[MindLayoutType.right].endY -= height * 0.5;
|
|
2453
2529
|
}
|
|
2454
2530
|
const branchColor = PlaitMind.isMind(element) ? getNextBranchColor(element) : getBranchColorByMindElement(this.board, element);
|
|
2455
|
-
let nodeLayout = MindQueries.getCorrectLayoutByElement(element);
|
|
2531
|
+
let nodeLayout = MindQueries.getCorrectLayoutByElement(this.board, element);
|
|
2456
2532
|
if (element.isRoot && isStandardLayout(nodeLayout)) {
|
|
2457
2533
|
const root = element;
|
|
2458
2534
|
nodeLayout = root.children.length >= root.rightNodeCount ? MindLayoutType.left : MindLayoutType.right;
|
|
2459
2535
|
}
|
|
2460
2536
|
const underlineCoordinate = underlineCoordinates[nodeLayout];
|
|
2461
2537
|
if (underlineCoordinate) {
|
|
2462
|
-
const underline = PlaitBoard.getRoughSVG(this.board).line(underlineCoordinate.startX, underlineCoordinate.startY, underlineCoordinate.endX, underlineCoordinate.endY, { stroke: branchColor, strokeWidth });
|
|
2538
|
+
const underline = PlaitBoard.getRoughSVG(this.board).line(underlineCoordinate.startX, underlineCoordinate.startY, underlineCoordinate.endX, underlineCoordinate.endY, { stroke: branchColor, strokeWidth: branchWidth });
|
|
2463
2539
|
const circleCoordinates = {
|
|
2464
2540
|
startX: underlineCoordinate.endX,
|
|
2465
2541
|
startY: underlineCoordinate.endY
|
|
@@ -2599,7 +2675,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2599
2675
|
this.destroyShape();
|
|
2600
2676
|
const shape = getNodeShapeByElement(this.node.origin);
|
|
2601
2677
|
switch (shape) {
|
|
2602
|
-
case
|
|
2678
|
+
case MindElementShape.roundRectangle:
|
|
2603
2679
|
this.shapeG = drawRectangleNode(this.board, this.node);
|
|
2604
2680
|
this.g.prepend(this.shapeG);
|
|
2605
2681
|
break;
|
|
@@ -2756,7 +2832,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2756
2832
|
}
|
|
2757
2833
|
}
|
|
2758
2834
|
drawRichtext() {
|
|
2759
|
-
const { richtextG, richtextComponentRef, foreignObject } = drawMindNodeRichtext(this.node, this.viewContainerRef);
|
|
2835
|
+
const { richtextG, richtextComponentRef, foreignObject } = drawMindNodeRichtext(this.board, this.node, this.viewContainerRef);
|
|
2760
2836
|
this.richtextComponentRef = richtextComponentRef;
|
|
2761
2837
|
this.richtextG = richtextG;
|
|
2762
2838
|
this.foreignObject = foreignObject;
|
|
@@ -2786,9 +2862,9 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2786
2862
|
});
|
|
2787
2863
|
const { x, y, width, height } = getRectangleByNode(this.node);
|
|
2788
2864
|
const stroke = getBranchColorByMindElement(this.board, this.element);
|
|
2789
|
-
const
|
|
2865
|
+
const branchWidth = getBranchWidthByMindElement(this.board, this.element);
|
|
2790
2866
|
const extendY = y + height / 2;
|
|
2791
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(this.element);
|
|
2867
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(this.board, this.element);
|
|
2792
2868
|
let extendLineXY = [
|
|
2793
2869
|
[x + width, extendY],
|
|
2794
2870
|
[x + width + EXTEND_OFFSET, extendY]
|
|
@@ -2800,7 +2876,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2800
2876
|
let circleOffset = [EXTEND_RADIUS / 2, 0];
|
|
2801
2877
|
if (isHorizontalLayout(nodeLayout) && !isIndentedLayout(nodeLayout)) {
|
|
2802
2878
|
extendLineYOffset =
|
|
2803
|
-
getNodeShapeByElement(this.node.origin) ===
|
|
2879
|
+
getNodeShapeByElement(this.node.origin) === MindElementShape.roundRectangle
|
|
2804
2880
|
? [0, 0]
|
|
2805
2881
|
: [height / 2, height / 2];
|
|
2806
2882
|
if (isLeftLayout(nodeLayout)) {
|
|
@@ -2832,7 +2908,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2832
2908
|
[extendLineXY[1][0] + extendLineXOffset[1], extendLineXY[1][1] + extendLineYOffset[1]]
|
|
2833
2909
|
];
|
|
2834
2910
|
const extendLine = this.roughSVG.line(extendLineXY[0][0], extendLineXY[0][1], extendLineXY[1][0], extendLineXY[1][1], {
|
|
2835
|
-
strokeWidth,
|
|
2911
|
+
strokeWidth: branchWidth,
|
|
2836
2912
|
stroke
|
|
2837
2913
|
});
|
|
2838
2914
|
//绘制箭头
|
|
@@ -2869,7 +2945,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2869
2945
|
const hideCircleG = this.roughSVG.circle(extendLineXY[1][0] + circleOffset[0], extendLineXY[1][1] + circleOffset[1], EXTEND_RADIUS - 1, {
|
|
2870
2946
|
fill: '#fff',
|
|
2871
2947
|
stroke,
|
|
2872
|
-
strokeWidth,
|
|
2948
|
+
strokeWidth: branchWidth,
|
|
2873
2949
|
fillStyle: 'solid'
|
|
2874
2950
|
});
|
|
2875
2951
|
collapseG.appendChild(hideCircleG);
|
|
@@ -2898,7 +2974,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2898
2974
|
}
|
|
2899
2975
|
updateRichtext() {
|
|
2900
2976
|
updateRichText(this.node.origin.data.topic, this.richtextComponentRef);
|
|
2901
|
-
updateMindNodeTopicSize(this.node, this.richtextG, this.isEditable);
|
|
2977
|
+
updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
|
|
2902
2978
|
}
|
|
2903
2979
|
startEditText(isEnd, isClear) {
|
|
2904
2980
|
if (!this.richtextComponentRef) {
|
|
@@ -2908,7 +2984,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2908
2984
|
this.isEditable = true;
|
|
2909
2985
|
IS_TEXT_EDITABLE.set(this.board, true);
|
|
2910
2986
|
this.disabledMaskG();
|
|
2911
|
-
updateMindNodeTopicSize(this.node, this.richtextG, this.isEditable);
|
|
2987
|
+
updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
|
|
2912
2988
|
if (richtextInstance.plaitReadonly) {
|
|
2913
2989
|
richtextInstance.plaitReadonly = false;
|
|
2914
2990
|
this.richtextComponentRef.changeDetectorRef.detectChanges();
|
|
@@ -3011,7 +3087,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
3011
3087
|
richtextInstance.plaitReadonly = true;
|
|
3012
3088
|
this.richtextComponentRef?.changeDetectorRef.markForCheck();
|
|
3013
3089
|
this.isEditable = false;
|
|
3014
|
-
updateMindNodeTopicSize(this.node, this.richtextG, this.isEditable);
|
|
3090
|
+
updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
|
|
3015
3091
|
IS_TEXT_EDITABLE.set(this.board, false);
|
|
3016
3092
|
};
|
|
3017
3093
|
}
|
|
@@ -3053,7 +3129,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3053
3129
|
}]
|
|
3054
3130
|
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }]; } });
|
|
3055
3131
|
|
|
3056
|
-
const getLayoutOptions = () => {
|
|
3132
|
+
const getLayoutOptions = (board) => {
|
|
3057
3133
|
function getMainAxle(element, parent) {
|
|
3058
3134
|
const strokeWidth = element.strokeWidth || STROKE_WIDTH;
|
|
3059
3135
|
if (element.isRoot) {
|
|
@@ -3076,7 +3152,7 @@ const getLayoutOptions = () => {
|
|
|
3076
3152
|
return NodeSpace.getNodeHeight(element);
|
|
3077
3153
|
},
|
|
3078
3154
|
getWidth(element) {
|
|
3079
|
-
return NodeSpace.getNodeWidth(element);
|
|
3155
|
+
return NodeSpace.getNodeWidth(board, element);
|
|
3080
3156
|
},
|
|
3081
3157
|
getHorizontalGap(element, parent) {
|
|
3082
3158
|
const _layout = (parent && parent.layout) || getRootLayout(element);
|
|
@@ -3106,7 +3182,7 @@ const getLayoutOptions = () => {
|
|
|
3106
3182
|
}
|
|
3107
3183
|
},
|
|
3108
3184
|
getVerticalConnectingPosition(element, parent) {
|
|
3109
|
-
if (element.shape ===
|
|
3185
|
+
if (element.shape === MindElementShape.underline && parent && isHorizontalLogicLayout(parent.layout)) {
|
|
3110
3186
|
return ConnectingPosition.bottom;
|
|
3111
3187
|
}
|
|
3112
3188
|
return undefined;
|
|
@@ -3132,7 +3208,7 @@ class PlaitMindComponent extends MindNodeComponent {
|
|
|
3132
3208
|
}
|
|
3133
3209
|
updateMindLayout(element = this.element) {
|
|
3134
3210
|
const mindLayoutType = element.layout || getDefaultLayout();
|
|
3135
|
-
this.root = GlobalLayout.layout(element, getLayoutOptions(), mindLayoutType);
|
|
3211
|
+
this.root = GlobalLayout.layout(element, getLayoutOptions(this.board), mindLayoutType);
|
|
3136
3212
|
this.updateMindNodeLocation(element);
|
|
3137
3213
|
}
|
|
3138
3214
|
updateMindNodeLocation(element) {
|
|
@@ -3175,6 +3251,119 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3175
3251
|
}]
|
|
3176
3252
|
}] });
|
|
3177
3253
|
|
|
3254
|
+
const isValidTarget = (origin, target) => {
|
|
3255
|
+
return origin !== target && !isChildElement(origin, target);
|
|
3256
|
+
};
|
|
3257
|
+
const addActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3258
|
+
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3259
|
+
if (isOrigin) {
|
|
3260
|
+
activeComponent.g.classList.add('dragging-origin');
|
|
3261
|
+
}
|
|
3262
|
+
else {
|
|
3263
|
+
activeComponent.g.classList.add('dragging-child');
|
|
3264
|
+
}
|
|
3265
|
+
!activeElement.isCollapsed &&
|
|
3266
|
+
activeElement.children.forEach(child => {
|
|
3267
|
+
addActiveOnDragOrigin(child, false);
|
|
3268
|
+
});
|
|
3269
|
+
};
|
|
3270
|
+
const removeActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3271
|
+
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3272
|
+
if (isOrigin) {
|
|
3273
|
+
activeComponent.g.classList.remove('dragging-origin');
|
|
3274
|
+
}
|
|
3275
|
+
else {
|
|
3276
|
+
activeComponent.g.classList.remove('dragging-child');
|
|
3277
|
+
}
|
|
3278
|
+
!activeElement.isCollapsed &&
|
|
3279
|
+
activeElement.children.forEach(child => {
|
|
3280
|
+
removeActiveOnDragOrigin(child, false);
|
|
3281
|
+
});
|
|
3282
|
+
};
|
|
3283
|
+
const updatePathByLayoutAndDropTarget = (targetPath, layout, dropTarget) => {
|
|
3284
|
+
// 上下布局:左右是兄弟节点,上下是子节点
|
|
3285
|
+
if (isVerticalLogicLayout(layout)) {
|
|
3286
|
+
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3287
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3288
|
+
}
|
|
3289
|
+
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3290
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3291
|
+
}
|
|
3292
|
+
// 如果是左,位置不变,右则插入到下一个兄弟节点
|
|
3293
|
+
if (dropTarget.detectResult === 'right') {
|
|
3294
|
+
targetPath = Path.next(targetPath);
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
// 水平布局/标准布局:上下是兄弟节点,左右是子节点
|
|
3298
|
+
if (isHorizontalLogicLayout(layout)) {
|
|
3299
|
+
if (dropTarget.detectResult === 'right') {
|
|
3300
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3301
|
+
}
|
|
3302
|
+
if (dropTarget.detectResult === 'left') {
|
|
3303
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3304
|
+
}
|
|
3305
|
+
// 如果是上,位置不变,下插入到下一个兄弟节点
|
|
3306
|
+
if (dropTarget.detectResult === 'bottom') {
|
|
3307
|
+
targetPath = Path.next(targetPath);
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
// 缩进布局:上下是兄弟节点,左右是子节点,但上(左上/右上),探测到上是子节点,下则位置不变,反之同理。
|
|
3311
|
+
if (isIndentedLayout(layout)) {
|
|
3312
|
+
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3313
|
+
targetPath = Path.next(targetPath);
|
|
3314
|
+
}
|
|
3315
|
+
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3316
|
+
targetPath = Path.next(targetPath);
|
|
3317
|
+
}
|
|
3318
|
+
if (isLeftLayout(layout) && dropTarget.detectResult === 'left') {
|
|
3319
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3320
|
+
}
|
|
3321
|
+
if (isRightLayout(layout) && dropTarget.detectResult === 'right') {
|
|
3322
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
return targetPath;
|
|
3326
|
+
};
|
|
3327
|
+
const updateRightNodeCount = (board, activeComponent, targetComponent, detectResult) => {
|
|
3328
|
+
let rightNodeCount;
|
|
3329
|
+
const mindElement = findUpElement(targetComponent.node.origin).root;
|
|
3330
|
+
const mindComponent = ELEMENT_TO_COMPONENT.get(mindElement);
|
|
3331
|
+
const activeIndex = mindComponent?.root.children.indexOf(activeComponent.node);
|
|
3332
|
+
const targetIndex = mindComponent?.root.children.indexOf(targetComponent.node);
|
|
3333
|
+
const isActiveOnRight = activeIndex !== -1 && activeIndex <= activeComponent.parent.origin.rightNodeCount - 1;
|
|
3334
|
+
const isTargetOnRight = targetComponent.parent && targetIndex !== -1 && targetIndex <= targetComponent.parent.origin.rightNodeCount - 1;
|
|
3335
|
+
const isBothOnRight = isActiveOnRight && isTargetOnRight;
|
|
3336
|
+
const rootChildCount = mindComponent.root.children?.length;
|
|
3337
|
+
const rootRightNodeCount = mindComponent?.root.origin.rightNodeCount;
|
|
3338
|
+
if (!isBothOnRight) {
|
|
3339
|
+
if (isActiveOnRight) {
|
|
3340
|
+
rightNodeCount = rootChildCount < rootRightNodeCount ? rootChildCount - 1 : rootRightNodeCount - 1;
|
|
3341
|
+
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, activeComponent.parent.origin));
|
|
3342
|
+
}
|
|
3343
|
+
if (isTargetOnRight && detectResult !== 'right') {
|
|
3344
|
+
rightNodeCount = rootChildCount < rootRightNodeCount ? rootRightNodeCount : rootRightNodeCount + 1;
|
|
3345
|
+
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, targetComponent.parent.origin));
|
|
3346
|
+
}
|
|
3347
|
+
//二级子节点拖动到根节点左侧
|
|
3348
|
+
if (targetComponent.node.origin.isRoot && detectResult === 'left' && activeIndex === -1) {
|
|
3349
|
+
rightNodeCount = rootChildCount;
|
|
3350
|
+
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, targetComponent.element));
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3353
|
+
};
|
|
3354
|
+
const IS_DRAGGING = new WeakMap();
|
|
3355
|
+
const isDragging = (board) => {
|
|
3356
|
+
return !!IS_DRAGGING.get(board);
|
|
3357
|
+
};
|
|
3358
|
+
const setIsDragging = (board, state) => {
|
|
3359
|
+
IS_DRAGGING.set(board, state);
|
|
3360
|
+
};
|
|
3361
|
+
const updateAbstractInDnd = (board, deletableElements, originPath) => {
|
|
3362
|
+
const refs = insertElementHandleAbstract(board, originPath, false);
|
|
3363
|
+
deleteElementHandleAbstract(board, deletableElements, refs);
|
|
3364
|
+
MindTransforms.setAbstractsByRefs(board, refs);
|
|
3365
|
+
};
|
|
3366
|
+
|
|
3178
3367
|
const DRAG_MOVE_BUFFER = 5;
|
|
3179
3368
|
const withDnd = (board) => {
|
|
3180
3369
|
const { mousedown, mousemove, globalMouseup, keydown } = board;
|
|
@@ -3253,7 +3442,7 @@ const withDnd = (board) => {
|
|
|
3253
3442
|
x: activeComponent.node.x + offsetX,
|
|
3254
3443
|
y: activeComponent.node.y + offsetY
|
|
3255
3444
|
};
|
|
3256
|
-
const textRectangle = getRichtextRectangleByNode(activeComponent.node);
|
|
3445
|
+
const textRectangle = getRichtextRectangleByNode(board, activeComponent.node);
|
|
3257
3446
|
const fakeNodeG = drawRectangleNode(board, fakeDraggingNode);
|
|
3258
3447
|
const richtextG = activeComponent.richtextG?.cloneNode(true);
|
|
3259
3448
|
updateForeignObject(richtextG, textRectangle.width + BASE * 10, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
|
|
@@ -3276,7 +3465,7 @@ const withDnd = (board) => {
|
|
|
3276
3465
|
}
|
|
3277
3466
|
const directions = directionDetector(node, detectCenterPoint);
|
|
3278
3467
|
if (directions) {
|
|
3279
|
-
detectResult = directionCorrector(node, directions);
|
|
3468
|
+
detectResult = directionCorrector(board, node, directions);
|
|
3280
3469
|
}
|
|
3281
3470
|
dropTarget = null;
|
|
3282
3471
|
if (detectResult && isValidTarget(activeComponent.node.origin, node.origin)) {
|
|
@@ -3286,7 +3475,7 @@ const withDnd = (board) => {
|
|
|
3286
3475
|
}
|
|
3287
3476
|
});
|
|
3288
3477
|
if (dropTarget?.target) {
|
|
3289
|
-
dropTarget = readjustmentDropTarget(dropTarget);
|
|
3478
|
+
dropTarget = readjustmentDropTarget(board, dropTarget);
|
|
3290
3479
|
drawPlaceholderDropNodeG(board, dropTarget, fakeDropNodeG);
|
|
3291
3480
|
}
|
|
3292
3481
|
}
|
|
@@ -3298,12 +3487,13 @@ const withDnd = (board) => {
|
|
|
3298
3487
|
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3299
3488
|
const targetComponent = PlaitElement.getComponent(dropTarget.target);
|
|
3300
3489
|
let targetPath = PlaitBoard.findPath(board, targetComponent.element);
|
|
3301
|
-
const
|
|
3302
|
-
const
|
|
3303
|
-
const layout = MindQueries.getCorrectLayoutByElement(
|
|
3490
|
+
const mindElement = findUpElement(dropTarget.target).root;
|
|
3491
|
+
const mindComponent = ELEMENT_TO_COMPONENT.get(mindElement);
|
|
3492
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, mindComponent?.root.origin);
|
|
3304
3493
|
targetPath = updatePathByLayoutAndDropTarget(targetPath, layout, dropTarget);
|
|
3305
3494
|
const originPath = PlaitBoard.findPath(board, activeComponent.element);
|
|
3306
3495
|
let newElement = { isCollapsed: false }, rightTargetPath = PlaitBoard.findPath(board, targetComponent.element);
|
|
3496
|
+
updateAbstractInDnd(board, [activeElement], targetPath);
|
|
3307
3497
|
if (isStandardLayout(layout)) {
|
|
3308
3498
|
updateRightNodeCount(board, activeComponent, targetComponent, dropTarget.detectResult);
|
|
3309
3499
|
}
|
|
@@ -3336,124 +3526,51 @@ const withDnd = (board) => {
|
|
|
3336
3526
|
};
|
|
3337
3527
|
return board;
|
|
3338
3528
|
};
|
|
3339
|
-
const isValidTarget = (origin, target) => {
|
|
3340
|
-
return origin !== target && !isChildElement(origin, target);
|
|
3341
|
-
};
|
|
3342
|
-
const addActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3343
|
-
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3344
|
-
if (isOrigin) {
|
|
3345
|
-
activeComponent.g.classList.add('dragging-origin');
|
|
3346
|
-
}
|
|
3347
|
-
else {
|
|
3348
|
-
activeComponent.g.classList.add('dragging-child');
|
|
3349
|
-
}
|
|
3350
|
-
!activeElement.isCollapsed &&
|
|
3351
|
-
activeElement.children.forEach(child => {
|
|
3352
|
-
addActiveOnDragOrigin(child, false);
|
|
3353
|
-
});
|
|
3354
|
-
};
|
|
3355
|
-
const removeActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3356
|
-
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3357
|
-
if (isOrigin) {
|
|
3358
|
-
activeComponent.g.classList.remove('dragging-origin');
|
|
3359
|
-
}
|
|
3360
|
-
else {
|
|
3361
|
-
activeComponent.g.classList.remove('dragging-child');
|
|
3362
|
-
}
|
|
3363
|
-
!activeElement.isCollapsed &&
|
|
3364
|
-
activeElement.children.forEach(child => {
|
|
3365
|
-
removeActiveOnDragOrigin(child, false);
|
|
3366
|
-
});
|
|
3367
|
-
};
|
|
3368
|
-
const updatePathByLayoutAndDropTarget = (targetPath, layout, dropTarget) => {
|
|
3369
|
-
// 上下布局:左右是兄弟节点,上下是子节点
|
|
3370
|
-
if (isVerticalLogicLayout(layout)) {
|
|
3371
|
-
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3372
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3373
|
-
}
|
|
3374
|
-
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3375
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3376
|
-
}
|
|
3377
|
-
// 如果是左,位置不变,右则插入到下一个兄弟节点
|
|
3378
|
-
if (dropTarget.detectResult === 'right') {
|
|
3379
|
-
targetPath = Path.next(targetPath);
|
|
3380
|
-
}
|
|
3381
|
-
}
|
|
3382
|
-
// 水平布局/标准布局:上下是兄弟节点,左右是子节点
|
|
3383
|
-
if (isHorizontalLogicLayout(layout)) {
|
|
3384
|
-
if (dropTarget.detectResult === 'right') {
|
|
3385
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3386
|
-
}
|
|
3387
|
-
if (dropTarget.detectResult === 'left') {
|
|
3388
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3389
|
-
}
|
|
3390
|
-
// 如果是上,位置不变,下插入到下一个兄弟节点
|
|
3391
|
-
if (dropTarget.detectResult === 'bottom') {
|
|
3392
|
-
targetPath = Path.next(targetPath);
|
|
3393
|
-
}
|
|
3394
|
-
}
|
|
3395
|
-
// 缩进布局:上下是兄弟节点,左右是子节点,但上(左上/右上),探测到上是子节点,下则位置不变,反之同理。
|
|
3396
|
-
if (isIndentedLayout(layout)) {
|
|
3397
|
-
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3398
|
-
targetPath = Path.next(targetPath);
|
|
3399
|
-
}
|
|
3400
|
-
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3401
|
-
targetPath = Path.next(targetPath);
|
|
3402
|
-
}
|
|
3403
|
-
if (isLeftLayout(layout) && dropTarget.detectResult === 'left') {
|
|
3404
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3405
|
-
}
|
|
3406
|
-
if (isRightLayout(layout) && dropTarget.detectResult === 'right') {
|
|
3407
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3408
|
-
}
|
|
3409
|
-
}
|
|
3410
|
-
return targetPath;
|
|
3411
|
-
};
|
|
3412
|
-
const updateRightNodeCount = (board, activeComponent, targetComponent, detectResult) => {
|
|
3413
|
-
let rightNodeCount;
|
|
3414
|
-
const mindmapElement = findUpElement(targetComponent.node.origin).root;
|
|
3415
|
-
const mindmapComponent = ELEMENT_TO_COMPONENT.get(mindmapElement);
|
|
3416
|
-
const activeIndex = mindmapComponent?.root.children.indexOf(activeComponent.node);
|
|
3417
|
-
const targetIndex = mindmapComponent?.root.children.indexOf(targetComponent.node);
|
|
3418
|
-
const isActiveOnRight = activeIndex !== -1 && activeIndex <= activeComponent.parent.origin.rightNodeCount - 1;
|
|
3419
|
-
const isTargetOnRight = targetComponent.parent && targetIndex !== -1 && targetIndex <= targetComponent.parent.origin.rightNodeCount - 1;
|
|
3420
|
-
const isBothOnRight = isActiveOnRight && isTargetOnRight;
|
|
3421
|
-
const rootChildCount = mindmapComponent.root.children?.length;
|
|
3422
|
-
const rootRightNodeCount = mindmapComponent?.root.origin.rightNodeCount;
|
|
3423
|
-
if (!isBothOnRight) {
|
|
3424
|
-
if (isActiveOnRight) {
|
|
3425
|
-
rightNodeCount = rootChildCount < rootRightNodeCount ? rootChildCount - 1 : rootRightNodeCount - 1;
|
|
3426
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, activeComponent.parent.origin));
|
|
3427
|
-
}
|
|
3428
|
-
if (isTargetOnRight && detectResult !== 'right') {
|
|
3429
|
-
rightNodeCount = rootChildCount < rootRightNodeCount ? rootRightNodeCount : rootRightNodeCount + 1;
|
|
3430
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, targetComponent.parent.origin));
|
|
3431
|
-
}
|
|
3432
|
-
//二级子节点拖动到根节点左侧
|
|
3433
|
-
if (targetComponent.node.origin.isRoot && detectResult === 'left' && activeIndex === -1) {
|
|
3434
|
-
rightNodeCount = rootChildCount;
|
|
3435
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, targetComponent.element));
|
|
3436
|
-
}
|
|
3437
|
-
}
|
|
3438
|
-
};
|
|
3439
|
-
const IS_DRAGGING = new WeakMap();
|
|
3440
|
-
const isDragging = (board) => {
|
|
3441
|
-
return !!IS_DRAGGING.get(board);
|
|
3442
|
-
};
|
|
3443
|
-
const setIsDragging = (board, state) => {
|
|
3444
|
-
IS_DRAGGING.set(board, state);
|
|
3445
|
-
};
|
|
3446
3529
|
|
|
3447
3530
|
const buildClipboardData = (board, selectedElements) => {
|
|
3448
3531
|
let result = [];
|
|
3449
|
-
|
|
3450
|
-
const
|
|
3451
|
-
|
|
3532
|
+
// get overall abstract
|
|
3533
|
+
const overallAbstracts = getOverallAbstracts(board, selectedElements);
|
|
3534
|
+
// keep correct order
|
|
3535
|
+
const newSelectedElements = selectedElements.filter((value) => !overallAbstracts.includes(value));
|
|
3536
|
+
newSelectedElements.push(...overallAbstracts);
|
|
3537
|
+
// get correct start and end in selected elements
|
|
3538
|
+
function getCorrectStartEnd(abstract) {
|
|
3539
|
+
const parent = MindElement.getParent(abstract);
|
|
3540
|
+
const startElement = parent.children[abstract.start];
|
|
3541
|
+
const index = selectedElements.indexOf(startElement);
|
|
3542
|
+
return { start: index, end: index + (abstract.end - abstract.start) };
|
|
3543
|
+
}
|
|
3544
|
+
const selectedMindNodes = newSelectedElements.map(value => MindElement.getNode(value));
|
|
3545
|
+
const nodesRectangle = getRectangleByElements(board, newSelectedElements, true);
|
|
3546
|
+
newSelectedElements.forEach((element, index) => {
|
|
3547
|
+
// handle relative location
|
|
3452
3548
|
const nodeRectangle = getRectangleByNode(selectedMindNodes[index]);
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3549
|
+
const points = [[nodeRectangle.x - nodesRectangle.x, nodeRectangle.y - nodesRectangle.y]];
|
|
3550
|
+
// handle invalid abstract
|
|
3551
|
+
if (AbstractNode.isAbstract(element) && overallAbstracts.includes(element)) {
|
|
3552
|
+
const { start, end } = getCorrectStartEnd(element);
|
|
3553
|
+
result.push({
|
|
3554
|
+
...element,
|
|
3555
|
+
points,
|
|
3556
|
+
start,
|
|
3557
|
+
end
|
|
3558
|
+
});
|
|
3559
|
+
}
|
|
3560
|
+
else {
|
|
3561
|
+
if (AbstractNode.isAbstract(element)) {
|
|
3562
|
+
let newElement = { ...element, points };
|
|
3563
|
+
delete newElement.start;
|
|
3564
|
+
delete newElement.end;
|
|
3565
|
+
result.push(newElement);
|
|
3566
|
+
}
|
|
3567
|
+
else {
|
|
3568
|
+
result.push({
|
|
3569
|
+
...element,
|
|
3570
|
+
points: points
|
|
3571
|
+
});
|
|
3572
|
+
}
|
|
3573
|
+
}
|
|
3457
3574
|
});
|
|
3458
3575
|
return result;
|
|
3459
3576
|
};
|
|
@@ -3479,17 +3596,22 @@ const insertClipboardData = (board, elements, targetPoint) => {
|
|
|
3479
3596
|
let newElement, path;
|
|
3480
3597
|
const selectedElements = getSelectedElements(board);
|
|
3481
3598
|
let newELements = [];
|
|
3599
|
+
const hasTargetParent = selectedElements.length === 1;
|
|
3600
|
+
const targetParent = selectedElements[0];
|
|
3601
|
+
const targetParentPath = targetParent && PlaitBoard.findPath(board, targetParent);
|
|
3602
|
+
const nonAbstractChildrenLength = targetParent && getNonAbstractChildren(targetParent).length;
|
|
3482
3603
|
elements.forEach((item, index) => {
|
|
3483
3604
|
newElement = copyNewNode(item);
|
|
3484
|
-
if (
|
|
3605
|
+
if (hasTargetParent) {
|
|
3485
3606
|
if (item.isRoot) {
|
|
3486
3607
|
newElement = transformRootToNode(board, newElement);
|
|
3487
3608
|
}
|
|
3488
|
-
|
|
3489
|
-
|
|
3609
|
+
// handle abstract start and end
|
|
3610
|
+
if (AbstractNode.isAbstract(newElement)) {
|
|
3611
|
+
newElement.start = newElement.start + nonAbstractChildrenLength;
|
|
3612
|
+
newElement.end = newElement.end + nonAbstractChildrenLength;
|
|
3490
3613
|
}
|
|
3491
|
-
|
|
3492
|
-
path = selectedElementPath.concat((selectedElements[0].children || []).length + index);
|
|
3614
|
+
path = [...targetParentPath, nonAbstractChildrenLength + index];
|
|
3493
3615
|
}
|
|
3494
3616
|
else {
|
|
3495
3617
|
const point = [targetPoint[0] + item.points[0][0], targetPoint[1] + item.points[0][1]];
|
|
@@ -3515,14 +3637,6 @@ const insertClipboardText = (board, parentElement, text, width, height) => {
|
|
|
3515
3637
|
return;
|
|
3516
3638
|
};
|
|
3517
3639
|
|
|
3518
|
-
const withEmoji = (board) => {
|
|
3519
|
-
const newBoard = board;
|
|
3520
|
-
newBoard.drawEmoji = (emoji, element) => {
|
|
3521
|
-
throw new Error('Not implement drawEmoji method error.');
|
|
3522
|
-
};
|
|
3523
|
-
return newBoard;
|
|
3524
|
-
};
|
|
3525
|
-
|
|
3526
3640
|
const withAbstract = (board) => {
|
|
3527
3641
|
const newBoard = board;
|
|
3528
3642
|
const { mousedown, mousemove, mouseup } = board;
|
|
@@ -3557,7 +3671,7 @@ const withAbstract = (board) => {
|
|
|
3557
3671
|
event.preventDefault();
|
|
3558
3672
|
const abstractComponent = PlaitElement.getComponent(activeAbstractElement);
|
|
3559
3673
|
const element = abstractComponent.element;
|
|
3560
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(activeAbstractElement);
|
|
3674
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, activeAbstractElement);
|
|
3561
3675
|
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
3562
3676
|
const parentElement = MindElement.getParent(element);
|
|
3563
3677
|
let children = parentElement.children;
|
|
@@ -3623,6 +3737,17 @@ const withAbstract = (board) => {
|
|
|
3623
3737
|
return board;
|
|
3624
3738
|
};
|
|
3625
3739
|
|
|
3740
|
+
const withExtendMind = (board) => {
|
|
3741
|
+
const newBoard = board;
|
|
3742
|
+
newBoard.drawEmoji = (emoji, element) => {
|
|
3743
|
+
throw new Error('Not implement drawEmoji method error.');
|
|
3744
|
+
};
|
|
3745
|
+
newBoard.getMindOptions = () => {
|
|
3746
|
+
return { spaceBetweenEmojis: 4, emojiPadding: 0 };
|
|
3747
|
+
};
|
|
3748
|
+
return newBoard;
|
|
3749
|
+
};
|
|
3750
|
+
|
|
3626
3751
|
const withMind = (board) => {
|
|
3627
3752
|
const { drawElement, dblclick, keydown, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
|
|
3628
3753
|
board.drawElement = (context) => {
|
|
@@ -3686,7 +3811,8 @@ const withMind = (board) => {
|
|
|
3686
3811
|
if (shouldChangeRightNodeCount(selectedElement)) {
|
|
3687
3812
|
changeRightNodeCount(board, selectedElementPath.slice(0, 1), 1);
|
|
3688
3813
|
}
|
|
3689
|
-
|
|
3814
|
+
const abstractRefs = insertElementHandleAbstract(board, Path.next(selectedElementPath));
|
|
3815
|
+
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
3690
3816
|
insertMindElement(board, selectedElement, findNewSiblingNodePath(board, selectedElement));
|
|
3691
3817
|
}
|
|
3692
3818
|
return;
|
|
@@ -3790,7 +3916,7 @@ const withMind = (board) => {
|
|
|
3790
3916
|
deleteSelectedELements(board, selectedElements);
|
|
3791
3917
|
deleteFragment(data);
|
|
3792
3918
|
};
|
|
3793
|
-
return
|
|
3919
|
+
return withExtendMind(withAbstract(withDnd(board)));
|
|
3794
3920
|
};
|
|
3795
3921
|
|
|
3796
3922
|
class MindEmojiBaseComponent {
|
|
@@ -3832,5 +3958,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3832
3958
|
* Generated bundle index. Do not edit.
|
|
3833
3959
|
*/
|
|
3834
3960
|
|
|
3835
|
-
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE,
|
|
3961
|
+
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_COLORS, BRANCH_WIDTH, DefaultAbstractNodeStyle, DefaultNodeStyle, DefaultRootStyle, ELEMENT_TO_NODE, EXTEND_OFFSET, EXTEND_RADIUS, GRAY_COLOR, LayoutDirection, LayoutDirectionsMap, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindQueries, MindTransforms, NODE_MIN_WIDTH, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, canSetAbstract, changeRightNodeCount, copyNewNode, correctLayoutByDirection, createDefaultMindMapElement, createMindElement, deleteElementHandleAbstract, deleteSelectedELements, directionCorrector, directionDetector, divideElementByParent, drawCurvePlaceholderDropNodeG, drawIndentNodeG, drawPlaceholderDropNodeG, drawStraightDropNodeG, extractNodesText, filterChildElement, findLastChild, findLocationLeftIndex, findParentElement, findUpElement, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultLayout, getEmojiFontSize, getEmojisRectangle, getHitAbstractHandle, getHorizontalFakeY, getInCorrectLayoutDirection, getIndentedFakePoint, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getNextBranchColor, getNodeShapeByElement, getOverallAbstracts, getRectangleByNode, getRectangleByResizingLocation, getRootLayout, getStrokeByMindElement, handleTouchedAbstract, hitMindElement, insertElementHandleAbstract, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isMixedLayout, isSetAbstract, isVirtualKey, readjustmentDropTarget, separateChildren, shouldChangeRightNodeCount, transformAbstractToNode, transformNodeToRoot, transformRootToNode, withExtendMind, withMind };
|
|
3836
3962
|
//# sourceMappingURL=plait-mind.mjs.map
|