@plait/mind 0.9.0 → 0.11.0
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/README.md +132 -13
- package/base/base.drawer.d.ts +4 -3
- package/constants/default.d.ts +1 -1
- package/constants/node-topic-style.d.ts +1 -0
- package/drawer/node-active.drawer.d.ts +13 -0
- package/drawer/node-collapse.drawer.d.ts +8 -0
- package/drawer/{emojis.drawer.d.ts → node-emojis.drawer.d.ts} +1 -1
- package/drawer/{quick-insert.drawer.d.ts → node-insert.drawer.d.ts} +2 -2
- package/esm2020/base/base.drawer.mjs +13 -1
- package/esm2020/constants/default.mjs +2 -2
- package/esm2020/constants/node-rule.mjs +1 -1
- package/esm2020/constants/node-topic-style.mjs +2 -1
- package/esm2020/drawer/node-active.drawer.mjs +43 -0
- package/esm2020/drawer/node-collapse.drawer.mjs +108 -0
- package/esm2020/drawer/node-emojis.drawer.mjs +72 -0
- package/esm2020/drawer/node-insert.drawer.mjs +98 -0
- package/esm2020/interfaces/element.mjs +5 -2
- package/esm2020/mind.component.mjs +2 -1
- package/esm2020/mind.module.mjs +5 -5
- package/esm2020/node.component.mjs +57 -424
- package/esm2020/plugins/with-abstract-resize.mjs +3 -3
- package/esm2020/plugins/with-mind-create.mjs +22 -15
- package/esm2020/plugins/with-mind.mjs +9 -8
- package/esm2020/plugins/with-node-dnd.mjs +2 -2
- package/esm2020/plugins/with-node-hover.mjs +65 -0
- package/esm2020/transforms/node.mjs +10 -7
- package/esm2020/utils/abstract/resize.mjs +4 -6
- package/esm2020/utils/dnd/common.mjs +8 -2
- package/esm2020/utils/draw/abstract-outline.mjs +7 -7
- package/esm2020/utils/draw/node-dnd.mjs +3 -3
- package/esm2020/utils/mind.mjs +4 -4
- package/esm2020/utils/node/adjust-node.mjs +4 -5
- package/esm2020/utils/node/common.mjs +3 -3
- package/esm2020/utils/node/create-node.mjs +4 -3
- package/fesm2015/plait-mind.mjs +547 -726
- package/fesm2015/plait-mind.mjs.map +1 -1
- package/fesm2020/plait-mind.mjs +547 -714
- package/fesm2020/plait-mind.mjs.map +1 -1
- package/interfaces/element.d.ts +1 -0
- package/mind.module.d.ts +2 -2
- package/node.component.d.ts +15 -31
- package/package.json +1 -1
- package/plugins/with-mind-create.d.ts +3 -5
- package/plugins/with-node-dnd.d.ts +1 -1
- package/plugins/with-node-hover.d.ts +5 -0
- package/styles/mixins.scss +13 -15
- package/styles/styles.scss +11 -10
- package/utils/abstract/resize.d.ts +2 -2
- package/utils/draw/abstract-outline.d.ts +0 -1
- package/utils/node/common.d.ts +1 -1
- package/esm2020/drawer/emojis.drawer.mjs +0 -72
- package/esm2020/drawer/quick-insert.drawer.mjs +0 -98
- package/esm2020/utils/draw/node-topic.mjs +0 -32
- package/utils/draw/node-topic.d.ts +0 -16
package/fesm2015/plait-mind.mjs
CHANGED
|
@@ -1,55 +1,19 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, ChangeDetectionStrategy, NgModule, Directive, Input, HostListener } from '@angular/core';
|
|
2
|
+
import { Component, ChangeDetectionStrategy, NgModule, NgZone, Directive, Input, HostListener } from '@angular/core';
|
|
3
3
|
import * as i2 from '@plait/core';
|
|
4
|
-
import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor,
|
|
4
|
+
import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitBoard, depthFirstRecursion, Path, drawLinearPath, createG, updateForeignObject, PlaitNode, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, drawAbstractRoundRectangle, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, transformPoint, toPoint, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, PlaitPluginKey, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
|
|
5
5
|
import { MindLayoutType, isIndentedLayout, getNonAbstractChildren, isStandardLayout, AbstractNode, isLeftLayout, isRightLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
|
|
6
|
-
import {
|
|
7
|
-
import { fromEvent, Subject
|
|
8
|
-
import {
|
|
9
|
-
import { Node, Path as Path$1, Editor, Operation } from 'slate';
|
|
6
|
+
import { getTextSize, TEXT_DEFAULT_HEIGHT, TextManage, TextModule } from '@plait/text';
|
|
7
|
+
import { fromEvent, Subject } from 'rxjs';
|
|
8
|
+
import { Node, Path as Path$1 } from 'slate';
|
|
10
9
|
import { isKeyHotkey } from 'is-hotkey';
|
|
11
10
|
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
11
|
+
import { take, filter } from 'rxjs/operators';
|
|
12
12
|
import * as i1 from '@angular/common';
|
|
13
13
|
import { CommonModule } from '@angular/common';
|
|
14
14
|
|
|
15
15
|
const ELEMENT_TO_NODE = new WeakMap();
|
|
16
16
|
|
|
17
|
-
const BASE = 4;
|
|
18
|
-
const PRIMARY_COLOR = '#6698FF';
|
|
19
|
-
const TRANSPARENT = 'transparent';
|
|
20
|
-
const GRAY_COLOR = '#AAAAAA';
|
|
21
|
-
const STROKE_WIDTH = 3;
|
|
22
|
-
const BRANCH_WIDTH = 3;
|
|
23
|
-
const EXTEND_OFFSET = 8;
|
|
24
|
-
const EXTEND_RADIUS = 16;
|
|
25
|
-
const QUICK_INSERT_CIRCLE_OFFSET = 9;
|
|
26
|
-
const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
|
|
27
|
-
const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
|
|
28
|
-
|
|
29
|
-
const DefaultAbstractNodeStyle = {
|
|
30
|
-
strokeColor: GRAY_COLOR,
|
|
31
|
-
strokeWidth: 2,
|
|
32
|
-
branchColor: GRAY_COLOR,
|
|
33
|
-
branchWidth: 2
|
|
34
|
-
};
|
|
35
|
-
const DefaultNodeStyle = {
|
|
36
|
-
strokeWidth: 3,
|
|
37
|
-
branchWidth: 3,
|
|
38
|
-
fill: 'none'
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const TOPIC_COLOR = '#333';
|
|
42
|
-
const TOPIC_FONT_SIZE = 14;
|
|
43
|
-
const ROOT_TOPIC_FONT_SIZE = 18;
|
|
44
|
-
const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
|
|
45
|
-
|
|
46
|
-
const NODE_MIN_WIDTH = 18;
|
|
47
|
-
|
|
48
|
-
const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //primary color 50% opacity
|
|
49
|
-
const ABSTRACT_INCLUDED_OUTLINE_OFFSET = 3.5;
|
|
50
|
-
const ABSTRACT_HANDLE_LENGTH = 10;
|
|
51
|
-
const ABSTRACT_HANDLE_MASK_WIDTH = 8;
|
|
52
|
-
|
|
53
17
|
const MindNode = {
|
|
54
18
|
get(root, path) {
|
|
55
19
|
let node = root;
|
|
@@ -185,36 +149,17 @@ const MindThemeColor = {
|
|
|
185
149
|
}
|
|
186
150
|
};
|
|
187
151
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
function getRectangleByElement(board, originPoint, element) {
|
|
201
|
-
const nodeRectangle = {
|
|
202
|
-
x: originPoint[0],
|
|
203
|
-
y: originPoint[1],
|
|
204
|
-
width: NodeSpace.getNodeWidth(board, element),
|
|
205
|
-
height: NodeSpace.getNodeHeight(board, element)
|
|
206
|
-
};
|
|
207
|
-
return nodeRectangle;
|
|
208
|
-
}
|
|
209
|
-
function isHitMindElement(board, point, element) {
|
|
210
|
-
const node = MindElement.getNode(element);
|
|
211
|
-
if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
|
|
212
|
-
return true;
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
152
|
+
const BASE = 4;
|
|
153
|
+
const PRIMARY_COLOR = '#6698FF';
|
|
154
|
+
const TRANSPARENT = 'transparent';
|
|
155
|
+
const GRAY_COLOR = '#AAAAAA';
|
|
156
|
+
const STROKE_WIDTH = 3;
|
|
157
|
+
const BRANCH_WIDTH = 3;
|
|
158
|
+
const EXTEND_OFFSET = 8;
|
|
159
|
+
const EXTEND_DIAMETER = 16;
|
|
160
|
+
const QUICK_INSERT_CIRCLE_OFFSET = 9;
|
|
161
|
+
const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
|
|
162
|
+
const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
|
|
218
163
|
|
|
219
164
|
function getEmojisWidthHeight(board, element) {
|
|
220
165
|
const options = board.getMindOptions();
|
|
@@ -234,6 +179,79 @@ function getEmojiFontSize(element) {
|
|
|
234
179
|
}
|
|
235
180
|
}
|
|
236
181
|
|
|
182
|
+
const NodeDefaultSpace = {
|
|
183
|
+
horizontal: {
|
|
184
|
+
nodeAndText: BASE * 3,
|
|
185
|
+
emojiAndText: BASE * 1.5
|
|
186
|
+
},
|
|
187
|
+
vertical: {
|
|
188
|
+
nodeAndText: BASE * 1.5
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const RootDefaultSpace = {
|
|
192
|
+
horizontal: {
|
|
193
|
+
nodeAndText: BASE * 4,
|
|
194
|
+
emojiAndText: BASE * 2
|
|
195
|
+
},
|
|
196
|
+
vertical: {
|
|
197
|
+
nodeAndText: BASE * 2
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
|
|
201
|
+
const isMind = PlaitMind.isMind(element);
|
|
202
|
+
const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
|
|
203
|
+
return nodeAndText;
|
|
204
|
+
};
|
|
205
|
+
const getVerticalSpaceBetweenNodeAndText = (element) => {
|
|
206
|
+
const isMind = PlaitMind.isMind(element);
|
|
207
|
+
const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
|
|
208
|
+
return nodeAndText;
|
|
209
|
+
};
|
|
210
|
+
const getSpaceEmojiAndText = (element) => {
|
|
211
|
+
const isMind = PlaitMind.isMind(element);
|
|
212
|
+
const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
|
|
213
|
+
return emojiAndText;
|
|
214
|
+
};
|
|
215
|
+
const NodeSpace = {
|
|
216
|
+
getNodeWidth(board, element) {
|
|
217
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
218
|
+
if (MindElement.hasEmojis(element)) {
|
|
219
|
+
return (NodeSpace.getEmojiLeftSpace(board, element) +
|
|
220
|
+
getEmojisWidthHeight(board, element).width +
|
|
221
|
+
getSpaceEmojiAndText(element) +
|
|
222
|
+
element.width +
|
|
223
|
+
nodeAndText);
|
|
224
|
+
}
|
|
225
|
+
return nodeAndText + element.width + nodeAndText;
|
|
226
|
+
},
|
|
227
|
+
getNodeHeight(board, element) {
|
|
228
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
229
|
+
return nodeAndText + element.height + nodeAndText;
|
|
230
|
+
},
|
|
231
|
+
getTextLeftSpace(board, element) {
|
|
232
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
233
|
+
if (MindElement.hasEmojis(element)) {
|
|
234
|
+
return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
return nodeAndText;
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
getTextTopSpace(element) {
|
|
241
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
242
|
+
return nodeAndText;
|
|
243
|
+
},
|
|
244
|
+
getEmojiLeftSpace(board, element) {
|
|
245
|
+
const options = board.getMindOptions();
|
|
246
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
247
|
+
return nodeAndText - options.emojiPadding;
|
|
248
|
+
},
|
|
249
|
+
getEmojiTopSpace(element) {
|
|
250
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
251
|
+
return nodeAndText;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
237
255
|
function getEmojiRectangle(board, element) {
|
|
238
256
|
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
239
257
|
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
@@ -260,18 +278,38 @@ const isHitEmojis = (board, element, point) => {
|
|
|
260
278
|
return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
|
|
261
279
|
};
|
|
262
280
|
|
|
263
|
-
function
|
|
281
|
+
function getTopicRectangleByNode(board, node) {
|
|
282
|
+
let nodeRectangle = getRectangleByNode(node);
|
|
283
|
+
return getTopicRectangleByElement(board, nodeRectangle, node.origin);
|
|
284
|
+
}
|
|
285
|
+
function getTopicRectangleByElement(board, nodeRectangle, element) {
|
|
286
|
+
const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
|
|
287
|
+
const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
|
|
288
|
+
const width = Math.ceil(element.width);
|
|
289
|
+
const height = Math.ceil(element.height);
|
|
290
|
+
return { height, width, x, y };
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const NODE_MIN_WIDTH = 18;
|
|
294
|
+
|
|
295
|
+
function editTopic(element) {
|
|
264
296
|
const component = PlaitElement.getComponent(element);
|
|
265
|
-
component.
|
|
297
|
+
component.editTopic();
|
|
266
298
|
}
|
|
267
299
|
|
|
300
|
+
const TOPIC_COLOR = '#333';
|
|
301
|
+
const TOPIC_FONT_SIZE = 14;
|
|
302
|
+
const ROOT_TOPIC_FONT_SIZE = 18;
|
|
303
|
+
const ROOT_TOPIC_HEIGHT = 25;
|
|
304
|
+
const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
|
|
305
|
+
|
|
268
306
|
const adjustRootToNode = (board, node) => {
|
|
269
307
|
const newNode = Object.assign({}, node);
|
|
270
308
|
delete newNode.isRoot;
|
|
271
309
|
delete newNode.rightNodeCount;
|
|
272
310
|
delete newNode.type;
|
|
273
311
|
const text = Node.string(node.data.topic.children[0]) || ' ';
|
|
274
|
-
const { width, height } =
|
|
312
|
+
const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT);
|
|
275
313
|
newNode.width = Math.max(width, NODE_MIN_WIDTH);
|
|
276
314
|
newNode.height = height;
|
|
277
315
|
if (newNode.layout === MindLayoutType.standard) {
|
|
@@ -297,7 +335,7 @@ const adjustNodeToRoot = (board, node) => {
|
|
|
297
335
|
newElement === null || newElement === void 0 ? true : delete newElement.fill;
|
|
298
336
|
newElement === null || newElement === void 0 ? true : delete newElement.shape;
|
|
299
337
|
newElement === null || newElement === void 0 ? true : delete newElement.strokeWidth;
|
|
300
|
-
const { width, height } =
|
|
338
|
+
const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
|
|
301
339
|
newElement.width = Math.max(width, NODE_MIN_WIDTH);
|
|
302
340
|
newElement.height = height;
|
|
303
341
|
return Object.assign(Object.assign({}, newElement), { layout: (_a = newElement.layout) !== null && _a !== void 0 ? _a : MindLayoutType.right, isCollapsed: false, isRoot: true, type: 'mindmap' });
|
|
@@ -310,7 +348,7 @@ const createEmptyMind = (board, point) => {
|
|
|
310
348
|
return rootElement;
|
|
311
349
|
};
|
|
312
350
|
const createDefaultMind = (point, rightNodeCount, layout) => {
|
|
313
|
-
const root = createMindElement('思维导图', 72,
|
|
351
|
+
const root = createMindElement('思维导图', 72, ROOT_TOPIC_HEIGHT, { layout });
|
|
314
352
|
root.rightNodeCount = rightNodeCount;
|
|
315
353
|
root.isRoot = true;
|
|
316
354
|
root.type = 'mindmap';
|
|
@@ -417,7 +455,7 @@ const insertMindElement = (board, inheritNode, path) => {
|
|
|
417
455
|
clearSelectedElement(board);
|
|
418
456
|
addSelectedElement(board, newElement);
|
|
419
457
|
setTimeout(() => {
|
|
420
|
-
|
|
458
|
+
editTopic(newElement);
|
|
421
459
|
});
|
|
422
460
|
};
|
|
423
461
|
const findLastChild = (child) => {
|
|
@@ -547,6 +585,18 @@ const getRootLayout = (root) => {
|
|
|
547
585
|
return root.layout || getDefaultLayout();
|
|
548
586
|
};
|
|
549
587
|
|
|
588
|
+
const DefaultAbstractNodeStyle = {
|
|
589
|
+
strokeColor: GRAY_COLOR,
|
|
590
|
+
strokeWidth: 2,
|
|
591
|
+
branchColor: GRAY_COLOR,
|
|
592
|
+
branchWidth: 2
|
|
593
|
+
};
|
|
594
|
+
const DefaultNodeStyle = {
|
|
595
|
+
strokeWidth: 3,
|
|
596
|
+
branchWidth: 3,
|
|
597
|
+
fill: 'none'
|
|
598
|
+
};
|
|
599
|
+
|
|
550
600
|
const getAvailableProperty = (board, element, propertyKey) => {
|
|
551
601
|
return element[propertyKey];
|
|
552
602
|
};
|
|
@@ -649,6 +699,12 @@ const isDragging = (board) => {
|
|
|
649
699
|
};
|
|
650
700
|
const setIsDragging = (board, state) => {
|
|
651
701
|
IS_DRAGGING.set(board, state);
|
|
702
|
+
if (state) {
|
|
703
|
+
PlaitBoard.getBoardContainer(board).classList.add('mind-node-dragging');
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
PlaitBoard.getBoardContainer(board).classList.remove('mind-node-dragging');
|
|
707
|
+
}
|
|
652
708
|
};
|
|
653
709
|
const hasPreviousOrNextOfDropPath = (parent, dropTarget, dropPath) => {
|
|
654
710
|
let children = getNonAbstractChildren(parent);
|
|
@@ -862,23 +918,10 @@ const getPathByDropTarget = (board, dropTarget) => {
|
|
|
862
918
|
return targetPath;
|
|
863
919
|
};
|
|
864
920
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
function drawRoundRectangleByElement(board, nodeRectangle, element) {
|
|
870
|
-
const defaultRootFill = getMindThemeColor(board).rootFill;
|
|
871
|
-
const fill = element.fill ? element.fill : element.isRoot ? defaultRootFill : DefaultNodeStyle.fill;
|
|
872
|
-
const stroke = getStrokeByMindElement(board, element);
|
|
873
|
-
const strokeWidth = element.strokeWidth ? element.strokeWidth : DefaultNodeStyle.strokeWidth;
|
|
874
|
-
const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), nodeRectangle.x, nodeRectangle.y, nodeRectangle.x + nodeRectangle.width, nodeRectangle.y + nodeRectangle.height, {
|
|
875
|
-
stroke,
|
|
876
|
-
strokeWidth,
|
|
877
|
-
fill,
|
|
878
|
-
fillStyle: 'solid'
|
|
879
|
-
});
|
|
880
|
-
return nodeG;
|
|
881
|
-
}
|
|
921
|
+
const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //primary color 50% opacity
|
|
922
|
+
const ABSTRACT_INCLUDED_OUTLINE_OFFSET = 3.5;
|
|
923
|
+
const ABSTRACT_HANDLE_LENGTH = 10;
|
|
924
|
+
const ABSTRACT_HANDLE_MASK_WIDTH = 8;
|
|
882
925
|
|
|
883
926
|
var HorizontalPlacement;
|
|
884
927
|
(function (HorizontalPlacement) {
|
|
@@ -1127,20 +1170,19 @@ function drawLink(board, parentNode, node, isHorizontal, needDrawUnderline, defa
|
|
|
1127
1170
|
}
|
|
1128
1171
|
|
|
1129
1172
|
const drawFakeDragNode = (board, element, offsetX, offsetY) => {
|
|
1130
|
-
var _a;
|
|
1131
1173
|
const activeComponent = PlaitElement.getComponent(element);
|
|
1132
1174
|
const dragFakeNodeG = createG();
|
|
1133
1175
|
dragFakeNodeG.classList.add('dragging', 'fake-node', 'plait-board-attached');
|
|
1134
1176
|
const fakeDraggingNode = Object.assign(Object.assign({}, activeComponent.node), { children: [], x: activeComponent.node.x + offsetX, y: activeComponent.node.y + offsetY });
|
|
1135
1177
|
const textRectangle = getTopicRectangleByNode(board, activeComponent.node);
|
|
1136
1178
|
const fakeNodeG = drawRoundRectangleByNode(board, fakeDraggingNode);
|
|
1137
|
-
const richtextG =
|
|
1179
|
+
const richtextG = activeComponent.textManage.g.cloneNode(true);
|
|
1138
1180
|
updateForeignObject(richtextG, textRectangle.width, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
|
|
1139
1181
|
dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(fakeNodeG);
|
|
1140
1182
|
dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(richtextG);
|
|
1141
1183
|
// draw emojis
|
|
1142
1184
|
if (MindElement.hasEmojis(element)) {
|
|
1143
|
-
const fakeEmojisG = activeComponent.
|
|
1185
|
+
const fakeEmojisG = activeComponent.nodeEmojisDrawer.g.cloneNode(true);
|
|
1144
1186
|
const foreignRectangle = getEmojiForeignRectangle(board, element);
|
|
1145
1187
|
updateForeignObject(fakeEmojisG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
|
|
1146
1188
|
dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(fakeEmojisG);
|
|
@@ -1581,9 +1623,7 @@ function findLocationLeftIndex(board, parentChildren, location, isHorizontal) {
|
|
|
1581
1623
|
}
|
|
1582
1624
|
function handleTouchedAbstract(board, touchedAbstract, endPoint) {
|
|
1583
1625
|
let touchedHandle;
|
|
1584
|
-
const abstract = getSelectedElements(board)
|
|
1585
|
-
.filter(element => AbstractNode.isAbstract(element))
|
|
1586
|
-
.find(element => {
|
|
1626
|
+
const abstract = getSelectedElements(board).filter(element => AbstractNode.isAbstract(element)).find(element => {
|
|
1587
1627
|
touchedHandle = getHitAbstractHandle(board, element, endPoint);
|
|
1588
1628
|
return touchedHandle;
|
|
1589
1629
|
});
|
|
@@ -1592,13 +1632,13 @@ function handleTouchedAbstract(board, touchedAbstract, endPoint) {
|
|
|
1592
1632
|
}
|
|
1593
1633
|
if (touchedAbstract) {
|
|
1594
1634
|
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1595
|
-
component.
|
|
1635
|
+
component.activeDrawer.updateAbstractOutline(touchedAbstract);
|
|
1596
1636
|
touchedAbstract = undefined;
|
|
1597
1637
|
}
|
|
1598
1638
|
if (abstract) {
|
|
1599
1639
|
touchedAbstract = abstract;
|
|
1600
1640
|
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1601
|
-
component.
|
|
1641
|
+
component.activeDrawer.updateAbstractOutline(touchedAbstract, touchedHandle);
|
|
1602
1642
|
}
|
|
1603
1643
|
return touchedAbstract;
|
|
1604
1644
|
}
|
|
@@ -1823,6 +1863,9 @@ const MindElement = {
|
|
|
1823
1863
|
},
|
|
1824
1864
|
getEmojis(element) {
|
|
1825
1865
|
return element.data.emojis;
|
|
1866
|
+
},
|
|
1867
|
+
getEditor(element) {
|
|
1868
|
+
return PlaitElement.getComponent(element).textManage.componentRef.instance.editor;
|
|
1826
1869
|
}
|
|
1827
1870
|
};
|
|
1828
1871
|
var MindElementShape;
|
|
@@ -1836,118 +1879,53 @@ var BranchShape;
|
|
|
1836
1879
|
BranchShape["polyline"] = "polyline";
|
|
1837
1880
|
})(BranchShape || (BranchShape = {}));
|
|
1838
1881
|
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1882
|
+
function getRectangleByNode(node) {
|
|
1883
|
+
const x = node.x + node.hGap;
|
|
1884
|
+
let y = node.y + node.vGap;
|
|
1885
|
+
const width = node.width - node.hGap * 2;
|
|
1886
|
+
const height = node.height - node.vGap * 2;
|
|
1887
|
+
return {
|
|
1888
|
+
x,
|
|
1889
|
+
y,
|
|
1890
|
+
width,
|
|
1891
|
+
height
|
|
1892
|
+
};
|
|
1893
|
+
}
|
|
1894
|
+
function getRectangleByElement(board, originPoint, element) {
|
|
1895
|
+
const nodeRectangle = {
|
|
1896
|
+
x: originPoint[0],
|
|
1897
|
+
y: originPoint[1],
|
|
1898
|
+
width: NodeSpace.getNodeWidth(board, element),
|
|
1899
|
+
height: NodeSpace.getNodeHeight(board, element)
|
|
1900
|
+
};
|
|
1901
|
+
return nodeRectangle;
|
|
1902
|
+
}
|
|
1903
|
+
function isHitMindElement(board, point, element) {
|
|
1904
|
+
const node = MindElement.getNode(element);
|
|
1905
|
+
if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
|
|
1906
|
+
return true;
|
|
1846
1907
|
}
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
horizontal: {
|
|
1850
|
-
nodeAndText: BASE * 4,
|
|
1851
|
-
emojiAndText: BASE * 2
|
|
1852
|
-
},
|
|
1853
|
-
vertical: {
|
|
1854
|
-
nodeAndText: BASE * 2
|
|
1908
|
+
else {
|
|
1909
|
+
return false;
|
|
1855
1910
|
}
|
|
1856
|
-
};
|
|
1857
|
-
const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
|
|
1858
|
-
const isMind = PlaitMind.isMind(element);
|
|
1859
|
-
const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
|
|
1860
|
-
return nodeAndText;
|
|
1861
|
-
};
|
|
1862
|
-
const getVerticalSpaceBetweenNodeAndText = (element) => {
|
|
1863
|
-
const isMind = PlaitMind.isMind(element);
|
|
1864
|
-
const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
|
|
1865
|
-
return nodeAndText;
|
|
1866
|
-
};
|
|
1867
|
-
const getSpaceEmojiAndText = (element) => {
|
|
1868
|
-
const isMind = PlaitMind.isMind(element);
|
|
1869
|
-
const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
|
|
1870
|
-
return emojiAndText;
|
|
1871
|
-
};
|
|
1872
|
-
const NodeSpace = {
|
|
1873
|
-
getNodeWidth(board, element) {
|
|
1874
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
1875
|
-
if (MindElement.hasEmojis(element)) {
|
|
1876
|
-
return (NodeSpace.getEmojiLeftSpace(board, element) +
|
|
1877
|
-
getEmojisWidthHeight(board, element).width +
|
|
1878
|
-
getSpaceEmojiAndText(element) +
|
|
1879
|
-
element.width +
|
|
1880
|
-
nodeAndText);
|
|
1881
|
-
}
|
|
1882
|
-
return nodeAndText + element.width + nodeAndText;
|
|
1883
|
-
},
|
|
1884
|
-
getNodeHeight(board, element) {
|
|
1885
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1886
|
-
return nodeAndText + element.height + nodeAndText;
|
|
1887
|
-
},
|
|
1888
|
-
getTextLeftSpace(board, element) {
|
|
1889
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
1890
|
-
if (MindElement.hasEmojis(element)) {
|
|
1891
|
-
return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
|
|
1892
|
-
}
|
|
1893
|
-
else {
|
|
1894
|
-
return nodeAndText;
|
|
1895
|
-
}
|
|
1896
|
-
},
|
|
1897
|
-
getTextTopSpace(element) {
|
|
1898
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1899
|
-
return nodeAndText;
|
|
1900
|
-
},
|
|
1901
|
-
getEmojiLeftSpace(board, element) {
|
|
1902
|
-
const options = board.getMindOptions();
|
|
1903
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
1904
|
-
return nodeAndText - options.emojiPadding;
|
|
1905
|
-
},
|
|
1906
|
-
getEmojiTopSpace(element) {
|
|
1907
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1908
|
-
return nodeAndText;
|
|
1909
|
-
}
|
|
1910
|
-
};
|
|
1911
|
-
|
|
1912
|
-
function getTopicRectangleByNode(board, node) {
|
|
1913
|
-
let nodeRectangle = getRectangleByNode(node);
|
|
1914
|
-
return getTopicRectangleByElement(board, nodeRectangle, node.origin);
|
|
1915
|
-
}
|
|
1916
|
-
function getTopicRectangleByElement(board, nodeRectangle, element) {
|
|
1917
|
-
const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
|
|
1918
|
-
const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
|
|
1919
|
-
const width = Math.ceil(element.width);
|
|
1920
|
-
const height = Math.ceil(element.height);
|
|
1921
|
-
return { height, width, x, y };
|
|
1922
1911
|
}
|
|
1923
1912
|
|
|
1924
|
-
function
|
|
1925
|
-
const rectangle =
|
|
1926
|
-
return
|
|
1927
|
-
}
|
|
1928
|
-
function drawTopicByElement(board, rectangle, element, viewContainerRef) {
|
|
1929
|
-
const containerRef = viewContainerRef || PlaitBoard.getComponent(board).viewContainerRef;
|
|
1930
|
-
const classList = [];
|
|
1931
|
-
if (element.isRoot) {
|
|
1932
|
-
classList.push('root-node');
|
|
1933
|
-
classList.push('font-size-18');
|
|
1934
|
-
}
|
|
1935
|
-
else {
|
|
1936
|
-
classList.push('child-node');
|
|
1937
|
-
}
|
|
1938
|
-
// COMPAT: last character can not show in safari browser
|
|
1939
|
-
return drawRichtext(rectangle.x, rectangle.y, rectangle.width, rectangle.height, element.data.topic, containerRef, classList);
|
|
1913
|
+
function drawRoundRectangleByNode(board, node) {
|
|
1914
|
+
const rectangle = getRectangleByNode(node);
|
|
1915
|
+
return drawRoundRectangleByElement(board, rectangle, node.origin);
|
|
1940
1916
|
}
|
|
1941
|
-
function
|
|
1942
|
-
const
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1917
|
+
function drawRoundRectangleByElement(board, nodeRectangle, element) {
|
|
1918
|
+
const defaultRootFill = getMindThemeColor(board).rootFill;
|
|
1919
|
+
const fill = element.fill ? element.fill : element.isRoot ? defaultRootFill : DefaultNodeStyle.fill;
|
|
1920
|
+
const stroke = getStrokeByMindElement(board, element);
|
|
1921
|
+
const strokeWidth = element.strokeWidth ? element.strokeWidth : DefaultNodeStyle.strokeWidth;
|
|
1922
|
+
const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), nodeRectangle.x, nodeRectangle.y, nodeRectangle.x + nodeRectangle.width, nodeRectangle.y + nodeRectangle.height, {
|
|
1923
|
+
stroke,
|
|
1924
|
+
strokeWidth,
|
|
1925
|
+
fill,
|
|
1926
|
+
fillStyle: 'solid'
|
|
1927
|
+
});
|
|
1928
|
+
return nodeG;
|
|
1951
1929
|
}
|
|
1952
1930
|
|
|
1953
1931
|
function drawAbstractLink(board, node, isHorizontal) {
|
|
@@ -2028,7 +2006,7 @@ class EmojiDrawer {
|
|
|
2028
2006
|
}
|
|
2029
2007
|
}
|
|
2030
2008
|
}
|
|
2031
|
-
class
|
|
2009
|
+
class NodeEmojisDrawer {
|
|
2032
2010
|
constructor(board, viewContainerRef) {
|
|
2033
2011
|
this.board = board;
|
|
2034
2012
|
this.viewContainerRef = viewContainerRef;
|
|
@@ -2156,12 +2134,13 @@ const correctLogicLayoutNode = (board, layout, path) => {
|
|
|
2156
2134
|
}
|
|
2157
2135
|
};
|
|
2158
2136
|
|
|
2137
|
+
const normalizeWidthAndHeight = (board, width, height) => {
|
|
2138
|
+
const newWidth = width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom;
|
|
2139
|
+
const newHeight = height / board.viewport.zoom;
|
|
2140
|
+
return { width: newWidth, height: newHeight };
|
|
2141
|
+
};
|
|
2159
2142
|
const setTopic = (board, element, topic, width, height) => {
|
|
2160
|
-
const newElement = {
|
|
2161
|
-
data: { topic },
|
|
2162
|
-
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
2163
|
-
height: height / board.viewport.zoom
|
|
2164
|
-
};
|
|
2143
|
+
const newElement = Object.assign({ data: { topic } }, normalizeWidthAndHeight(board, width, height));
|
|
2165
2144
|
if (MindElement.hasEmojis(element)) {
|
|
2166
2145
|
newElement.data.emojis = element.data.emojis;
|
|
2167
2146
|
}
|
|
@@ -2169,12 +2148,9 @@ const setTopic = (board, element, topic, width, height) => {
|
|
|
2169
2148
|
Transforms.setNode(board, newElement, path);
|
|
2170
2149
|
};
|
|
2171
2150
|
const setTopicSize = (board, element, width, height) => {
|
|
2172
|
-
const newElement = {
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
};
|
|
2176
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2177
|
-
if (newElement.width !== element.width || newElement.height !== element.height) {
|
|
2151
|
+
const newElement = Object.assign({}, normalizeWidthAndHeight(board, width, height));
|
|
2152
|
+
if (element.width !== newElement.width || element.height !== newElement.height) {
|
|
2153
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2178
2154
|
Transforms.setNode(board, newElement, path);
|
|
2179
2155
|
}
|
|
2180
2156
|
};
|
|
@@ -2270,75 +2246,22 @@ const MindTransforms = {
|
|
|
2270
2246
|
setRightNodeCountByRefs
|
|
2271
2247
|
};
|
|
2272
2248
|
|
|
2273
|
-
function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
|
|
2274
|
-
const abstractIncludedG = createG();
|
|
2275
|
-
const parentElement = MindElement.getParent(element);
|
|
2276
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
2277
|
-
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
2278
|
-
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
2279
|
-
let abstractRectangle = getRectangleByElements(board, includedElements, true);
|
|
2280
|
-
abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
|
|
2281
|
-
if (resizingLocation) {
|
|
2282
|
-
abstractRectangle = getRectangleByResizingLocation(abstractRectangle, resizingLocation, activeHandlePosition, isHorizontal);
|
|
2283
|
-
}
|
|
2284
|
-
const rectangle = drawAbstractRoundRectangle(roughSVG, abstractRectangle.x, abstractRectangle.y, abstractRectangle.x + abstractRectangle.width, abstractRectangle.y + abstractRectangle.height, isHorizontal, {
|
|
2285
|
-
stroke: PRIMARY_COLOR,
|
|
2286
|
-
strokeWidth: 1,
|
|
2287
|
-
fillStyle: 'solid'
|
|
2288
|
-
});
|
|
2289
|
-
const startPlacement = [HorizontalPlacement.center, VerticalPlacement.top];
|
|
2290
|
-
const endPlacement = [HorizontalPlacement.center, VerticalPlacement.bottom];
|
|
2291
|
-
const linkDirection = getLayoutDirection(MindElement.getNode(element), isHorizontal);
|
|
2292
|
-
transformPlacement(startPlacement, linkDirection);
|
|
2293
|
-
transformPlacement(endPlacement, linkDirection);
|
|
2294
|
-
let startCenterPoint = getPointByPlacement(abstractRectangle, startPlacement);
|
|
2295
|
-
let endCenterPoint = getPointByPlacement(abstractRectangle, endPlacement);
|
|
2296
|
-
const startPoint1 = moveXOfPoint(startCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2297
|
-
const startPoint2 = moveXOfPoint(startCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2298
|
-
const endPoint1 = moveXOfPoint(endCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2299
|
-
const endPoint2 = moveXOfPoint(endCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2300
|
-
const startHandle = roughSVG.line(startPoint1[0], startPoint1[1], startPoint2[0], startPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.start));
|
|
2301
|
-
const endHandle = roughSVG.line(endPoint1[0], endPoint1[1], endPoint2[0], endPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.end));
|
|
2302
|
-
changeBoardClass(board, activeHandlePosition, isHorizontal);
|
|
2303
|
-
startHandle.setAttribute('stroke-linecap', 'round');
|
|
2304
|
-
endHandle.setAttribute('stroke-linecap', 'round');
|
|
2305
|
-
abstractIncludedG.append(startHandle);
|
|
2306
|
-
abstractIncludedG.append(endHandle);
|
|
2307
|
-
abstractIncludedG.append(rectangle);
|
|
2308
|
-
return abstractIncludedG;
|
|
2309
|
-
}
|
|
2310
|
-
function getHandleOption(isHover) {
|
|
2311
|
-
return isHover
|
|
2312
|
-
? {
|
|
2313
|
-
stroke: PRIMARY_COLOR,
|
|
2314
|
-
strokeWidth: 4,
|
|
2315
|
-
fillStyle: 'solid'
|
|
2316
|
-
}
|
|
2317
|
-
: {
|
|
2318
|
-
stroke: ABSTRACT_HANDLE_COLOR,
|
|
2319
|
-
strokeWidth: 3,
|
|
2320
|
-
fillStyle: 'solid'
|
|
2321
|
-
};
|
|
2322
|
-
}
|
|
2323
|
-
function changeBoardClass(board, activeHandlePosition, isHorizontal) {
|
|
2324
|
-
if (activeHandlePosition) {
|
|
2325
|
-
if (isHorizontal) {
|
|
2326
|
-
PlaitBoard.getBoardNativeElement(board).classList.add('abstract-resizing-horizontal');
|
|
2327
|
-
}
|
|
2328
|
-
else {
|
|
2329
|
-
PlaitBoard.getBoardNativeElement(board).classList.add('abstract-resizing-vertical');
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
else {
|
|
2333
|
-
PlaitBoard.getBoardNativeElement(board).classList.remove('abstract-resizing-horizontal');
|
|
2334
|
-
PlaitBoard.getBoardNativeElement(board).classList.remove('abstract-resizing-vertical');
|
|
2335
|
-
}
|
|
2336
|
-
}
|
|
2337
|
-
|
|
2338
2249
|
class BaseDrawer {
|
|
2339
2250
|
constructor(board) {
|
|
2340
2251
|
this.board = board;
|
|
2341
2252
|
}
|
|
2253
|
+
draw(element, parentG, data) {
|
|
2254
|
+
this.destroy();
|
|
2255
|
+
if (this.canDraw && this.canDraw(element, data)) {
|
|
2256
|
+
const g = this.baseDraw(element, data);
|
|
2257
|
+
if (g) {
|
|
2258
|
+
parentG.append(g);
|
|
2259
|
+
}
|
|
2260
|
+
if (hasAfterDraw(this)) {
|
|
2261
|
+
this.afterDraw(element);
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2342
2265
|
destroy() {
|
|
2343
2266
|
if (this.g) {
|
|
2344
2267
|
this.g.remove();
|
|
@@ -2361,14 +2284,14 @@ function findNewSiblingNodePath(board, element) {
|
|
|
2361
2284
|
return Path$1.next(path);
|
|
2362
2285
|
}
|
|
2363
2286
|
|
|
2364
|
-
class
|
|
2287
|
+
class NodeInsertDrawer extends BaseDrawer {
|
|
2365
2288
|
canDraw(element) {
|
|
2366
2289
|
if (PlaitBoard.isReadonly(this.board) || (element === null || element === void 0 ? void 0 : element.isCollapsed)) {
|
|
2367
2290
|
return false;
|
|
2368
2291
|
}
|
|
2369
2292
|
return true;
|
|
2370
2293
|
}
|
|
2371
|
-
|
|
2294
|
+
baseDraw(element) {
|
|
2372
2295
|
const quickInsertG = createG();
|
|
2373
2296
|
this.g = quickInsertG;
|
|
2374
2297
|
quickInsertG.classList.add('quick-insert');
|
|
@@ -2394,7 +2317,7 @@ class QuickInsertDrawer extends BaseDrawer {
|
|
|
2394
2317
|
}
|
|
2395
2318
|
let beginPoint = getPointByPlacement(nodeClient, placement);
|
|
2396
2319
|
if (element.children.length > 0 && !element.isRoot) {
|
|
2397
|
-
beginPoint = moveXOfPoint(beginPoint,
|
|
2320
|
+
beginPoint = moveXOfPoint(beginPoint, EXTEND_DIAMETER + 8, linkDirection);
|
|
2398
2321
|
distance = 5;
|
|
2399
2322
|
}
|
|
2400
2323
|
const endPoint = moveXOfPoint(beginPoint, distance, linkDirection);
|
|
@@ -2403,7 +2326,7 @@ class QuickInsertDrawer extends BaseDrawer {
|
|
|
2403
2326
|
stroke: branchColor,
|
|
2404
2327
|
strokeWidth: branchWidth
|
|
2405
2328
|
});
|
|
2406
|
-
const circle = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1],
|
|
2329
|
+
const circle = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
|
|
2407
2330
|
fill: QUICK_INSERT_CIRCLE_COLOR,
|
|
2408
2331
|
stroke: QUICK_INSERT_CIRCLE_COLOR,
|
|
2409
2332
|
fillStyle: 'solid'
|
|
@@ -2444,71 +2367,271 @@ class QuickInsertDrawer extends BaseDrawer {
|
|
|
2444
2367
|
}
|
|
2445
2368
|
}
|
|
2446
2369
|
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2370
|
+
function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
|
|
2371
|
+
const abstractIncludedG = createG();
|
|
2372
|
+
const parentElement = MindElement.getParent(element);
|
|
2373
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
2374
|
+
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
2375
|
+
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
2376
|
+
let abstractRectangle = getRectangleByElements(board, includedElements, true);
|
|
2377
|
+
abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
|
|
2378
|
+
if (resizingLocation) {
|
|
2379
|
+
abstractRectangle = getRectangleByResizingLocation(abstractRectangle, resizingLocation, activeHandlePosition, isHorizontal);
|
|
2450
2380
|
}
|
|
2451
|
-
|
|
2381
|
+
const rectangle = drawAbstractRoundRectangle(roughSVG, abstractRectangle.x, abstractRectangle.y, abstractRectangle.x + abstractRectangle.width, abstractRectangle.y + abstractRectangle.height, isHorizontal, {
|
|
2382
|
+
stroke: PRIMARY_COLOR,
|
|
2383
|
+
strokeWidth: 1,
|
|
2384
|
+
fillStyle: 'solid'
|
|
2385
|
+
});
|
|
2386
|
+
const startPlacement = [HorizontalPlacement.center, VerticalPlacement.top];
|
|
2387
|
+
const endPlacement = [HorizontalPlacement.center, VerticalPlacement.bottom];
|
|
2388
|
+
const linkDirection = getLayoutDirection(MindElement.getNode(element), isHorizontal);
|
|
2389
|
+
transformPlacement(startPlacement, linkDirection);
|
|
2390
|
+
transformPlacement(endPlacement, linkDirection);
|
|
2391
|
+
let startCenterPoint = getPointByPlacement(abstractRectangle, startPlacement);
|
|
2392
|
+
let endCenterPoint = getPointByPlacement(abstractRectangle, endPlacement);
|
|
2393
|
+
const startPoint1 = moveXOfPoint(startCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2394
|
+
const startPoint2 = moveXOfPoint(startCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2395
|
+
const endPoint1 = moveXOfPoint(endCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2396
|
+
const endPoint2 = moveXOfPoint(endCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2397
|
+
const startHandle = roughSVG.line(startPoint1[0], startPoint1[1], startPoint2[0], startPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.start));
|
|
2398
|
+
const endHandle = roughSVG.line(endPoint1[0], endPoint1[1], endPoint2[0], endPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.end));
|
|
2399
|
+
handleBoardClass(board, activeHandlePosition, isHorizontal);
|
|
2400
|
+
startHandle.setAttribute('stroke-linecap', 'round');
|
|
2401
|
+
endHandle.setAttribute('stroke-linecap', 'round');
|
|
2402
|
+
abstractIncludedG.append(startHandle);
|
|
2403
|
+
abstractIncludedG.append(endHandle);
|
|
2404
|
+
abstractIncludedG.append(rectangle);
|
|
2405
|
+
return abstractIncludedG;
|
|
2406
|
+
}
|
|
2407
|
+
function getHandleOption(isHover) {
|
|
2408
|
+
return isHover
|
|
2409
|
+
? {
|
|
2410
|
+
stroke: PRIMARY_COLOR,
|
|
2411
|
+
strokeWidth: 4,
|
|
2412
|
+
fillStyle: 'solid'
|
|
2413
|
+
}
|
|
2414
|
+
: {
|
|
2415
|
+
stroke: ABSTRACT_HANDLE_COLOR,
|
|
2416
|
+
strokeWidth: 3,
|
|
2417
|
+
fillStyle: 'solid'
|
|
2418
|
+
};
|
|
2419
|
+
}
|
|
2420
|
+
function handleBoardClass(board, activeHandlePosition, isHorizontal) {
|
|
2421
|
+
if (activeHandlePosition) {
|
|
2422
|
+
if (isHorizontal) {
|
|
2423
|
+
PlaitBoard.getBoardContainer(board).classList.add('abstract-resizing-horizontal');
|
|
2424
|
+
}
|
|
2425
|
+
else {
|
|
2426
|
+
PlaitBoard.getBoardContainer(board).classList.add('abstract-resizing-vertical');
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
else {
|
|
2430
|
+
PlaitBoard.getBoardContainer(board).classList.remove('abstract-resizing-horizontal');
|
|
2431
|
+
PlaitBoard.getBoardContainer(board).classList.remove('abstract-resizing-vertical');
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
class NodeActiveDrawer extends BaseDrawer {
|
|
2436
|
+
canDraw(element, data) {
|
|
2437
|
+
if (data.selected) {
|
|
2438
|
+
return true;
|
|
2439
|
+
}
|
|
2440
|
+
else {
|
|
2441
|
+
return false;
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
baseDraw(element, data) {
|
|
2445
|
+
const activeG = createG();
|
|
2446
|
+
this.g = activeG;
|
|
2447
|
+
if (AbstractNode.isAbstract(element)) {
|
|
2448
|
+
this.abstractOutlineG = drawAbstractIncludedOutline(this.board, PlaitBoard.getRoughSVG(this.board), element);
|
|
2449
|
+
activeG.append(this.abstractOutlineG);
|
|
2450
|
+
}
|
|
2451
|
+
const node = MindElement.getNode(element);
|
|
2452
|
+
let { x, y, width, height } = getRectangleByNode(node);
|
|
2453
|
+
const strokeG = drawRoundRectangle(PlaitBoard.getRoughSVG(this.board), x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, strokeWidth: 2, fill: '' }, true);
|
|
2454
|
+
this.g.appendChild(strokeG);
|
|
2455
|
+
if (!data.isEditing) {
|
|
2456
|
+
const fillG = drawRoundRectangle(PlaitBoard.getRoughSVG(this.board), x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, fill: PRIMARY_COLOR, fillStyle: 'solid' }, true);
|
|
2457
|
+
fillG.style.opacity = '0.15';
|
|
2458
|
+
this.g.appendChild(fillG);
|
|
2459
|
+
}
|
|
2460
|
+
return activeG;
|
|
2461
|
+
}
|
|
2462
|
+
updateAbstractOutline(element, activeHandlePosition, resizingLocation) {
|
|
2463
|
+
if (this.abstractOutlineG) {
|
|
2464
|
+
this.abstractOutlineG.remove();
|
|
2465
|
+
}
|
|
2466
|
+
this.abstractOutlineG = drawAbstractIncludedOutline(this.board, PlaitBoard.getRoughSVG(this.board), element, activeHandlePosition, resizingLocation);
|
|
2467
|
+
this.g.append(this.abstractOutlineG);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
class CollapseDrawer extends BaseDrawer {
|
|
2472
|
+
canDraw(element) {
|
|
2473
|
+
if (element.children.length && !PlaitMind.isMind(element)) {
|
|
2474
|
+
return true;
|
|
2475
|
+
}
|
|
2476
|
+
return false;
|
|
2477
|
+
}
|
|
2478
|
+
baseDraw(element) {
|
|
2479
|
+
const collapseG = createG();
|
|
2480
|
+
this.g = collapseG;
|
|
2481
|
+
collapseG.classList.add('collapse-container');
|
|
2482
|
+
const node = MindElement.getNode(element);
|
|
2483
|
+
const stroke = getBranchColorByMindElement(this.board, element);
|
|
2484
|
+
const branchWidth = getBranchWidthByMindElement(this.board, element);
|
|
2485
|
+
const layout = MindQueries.getLayoutByElement(element);
|
|
2486
|
+
const isUnderlineShape = getShapeByElement(this.board, element) === MindElementShape.underline;
|
|
2487
|
+
const isHorizontal = isHorizontalLayout(layout);
|
|
2488
|
+
const nodeClient = getRectangleByNode(node);
|
|
2489
|
+
let linkDirection = getLayoutDirection(node, isHorizontal);
|
|
2490
|
+
if (isIndentedLayout(layout)) {
|
|
2491
|
+
linkDirection = isTopLayout(layout) ? LayoutDirection.top : LayoutDirection.bottom;
|
|
2492
|
+
}
|
|
2493
|
+
let placement = [HorizontalPlacement.right, VerticalPlacement.middle];
|
|
2494
|
+
transformPlacement(placement, linkDirection);
|
|
2495
|
+
// underline shape and horizontal
|
|
2496
|
+
if (isHorizontal && isUnderlineShape && !element.isRoot) {
|
|
2497
|
+
placement[1] = VerticalPlacement.bottom;
|
|
2498
|
+
}
|
|
2499
|
+
let startPoint = getPointByPlacement(nodeClient, placement);
|
|
2500
|
+
const endPoint = moveXOfPoint(startPoint, EXTEND_OFFSET, linkDirection);
|
|
2501
|
+
const circleCenter = moveXOfPoint(endPoint, EXTEND_DIAMETER / 2, linkDirection);
|
|
2502
|
+
const arrowPoints = this.getArrowPoints(circleCenter, linkDirection);
|
|
2503
|
+
const arrowLine = drawLinearPath(arrowPoints, {
|
|
2504
|
+
stroke,
|
|
2505
|
+
strokeWidth: 2
|
|
2506
|
+
});
|
|
2507
|
+
const extendLine = PlaitBoard.getRoughSVG(this.board).line(startPoint[0], startPoint[1], endPoint[0], endPoint[1], {
|
|
2508
|
+
strokeWidth: branchWidth,
|
|
2509
|
+
stroke
|
|
2510
|
+
});
|
|
2511
|
+
const badge = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
|
|
2512
|
+
fill: stroke,
|
|
2513
|
+
stroke,
|
|
2514
|
+
fillStyle: 'solid'
|
|
2515
|
+
});
|
|
2516
|
+
const hideCircleG = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
|
|
2517
|
+
fill: '#fff',
|
|
2518
|
+
stroke,
|
|
2519
|
+
strokeWidth: branchWidth > 3 ? 3 : branchWidth,
|
|
2520
|
+
fillStyle: 'solid'
|
|
2521
|
+
});
|
|
2522
|
+
if (element.isCollapsed) {
|
|
2523
|
+
let numberOffset = 0;
|
|
2524
|
+
if (getChildrenCount(element) >= 10)
|
|
2525
|
+
numberOffset = -2;
|
|
2526
|
+
if (getChildrenCount(element) === 1)
|
|
2527
|
+
numberOffset = 1;
|
|
2528
|
+
const badgeText = createText(circleCenter[0] - 4 + numberOffset, circleCenter[1] + 4, stroke, `${getChildrenCount(element)}`);
|
|
2529
|
+
badge.setAttribute('style', 'opacity: 0.15');
|
|
2530
|
+
badgeText.setAttribute('style', 'font-size: 12px');
|
|
2531
|
+
collapseG.appendChild(badge);
|
|
2532
|
+
collapseG.appendChild(badgeText);
|
|
2533
|
+
collapseG.appendChild(extendLine);
|
|
2534
|
+
}
|
|
2535
|
+
else {
|
|
2536
|
+
collapseG.appendChild(hideCircleG);
|
|
2537
|
+
collapseG.appendChild(arrowLine);
|
|
2538
|
+
}
|
|
2539
|
+
collapseG.appendChild(extendLine);
|
|
2540
|
+
return collapseG;
|
|
2541
|
+
}
|
|
2542
|
+
afterDraw(element) {
|
|
2543
|
+
if (!this.g) {
|
|
2544
|
+
throw new Error(`can not find quick insert g`);
|
|
2545
|
+
}
|
|
2546
|
+
fromEvent(this.g, 'mouseup')
|
|
2547
|
+
.pipe(filter(() => !PlaitBoard.isPointer(this.board, PlaitPointerType.hand) || !!PlaitBoard.isReadonly(this.board)), take(1))
|
|
2548
|
+
.subscribe(() => {
|
|
2549
|
+
const isCollapsed = !element.isCollapsed;
|
|
2550
|
+
const newElement = { isCollapsed };
|
|
2551
|
+
const path = PlaitBoard.findPath(this.board, element);
|
|
2552
|
+
Transforms.setNode(this.board, newElement, path);
|
|
2553
|
+
});
|
|
2554
|
+
}
|
|
2555
|
+
getArrowPoints(circleCenter, linkDirection) {
|
|
2556
|
+
let arrowTopPoint = moveXOfPoint(circleCenter, 2, linkDirection);
|
|
2557
|
+
arrowTopPoint = moveYOfPoint(arrowTopPoint, 4, linkDirection);
|
|
2558
|
+
const arrowMiddlePoint = moveXOfPoint(circleCenter, -2, linkDirection);
|
|
2559
|
+
let arrowBottomPoint = moveXOfPoint(circleCenter, 2, linkDirection);
|
|
2560
|
+
arrowBottomPoint = moveYOfPoint(arrowBottomPoint, -4, linkDirection);
|
|
2561
|
+
return [arrowTopPoint, arrowMiddlePoint, arrowBottomPoint];
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
class MindNodeComponent extends PlaitPluginElementComponent {
|
|
2566
|
+
constructor(viewContainerRef, cdr) {
|
|
2452
2567
|
super(cdr);
|
|
2453
2568
|
this.viewContainerRef = viewContainerRef;
|
|
2454
2569
|
this.cdr = cdr;
|
|
2455
|
-
this.render2 = render2;
|
|
2456
|
-
this.ngZone = ngZone;
|
|
2457
|
-
this.isEditable = false;
|
|
2458
|
-
this.activeG = [];
|
|
2459
2570
|
this.shapeG = null;
|
|
2460
2571
|
this.destroy$ = new Subject();
|
|
2461
2572
|
this.trackBy = (index, node) => {
|
|
2462
2573
|
return node.origin.id;
|
|
2463
2574
|
};
|
|
2464
2575
|
}
|
|
2576
|
+
initializeDrawer() {
|
|
2577
|
+
this.nodeEmojisDrawer = new NodeEmojisDrawer(this.board, this.viewContainerRef);
|
|
2578
|
+
this.nodeInsertDrawer = new NodeInsertDrawer(this.board);
|
|
2579
|
+
this.activeDrawer = new NodeActiveDrawer(this.board);
|
|
2580
|
+
this.collapseDrawer = new CollapseDrawer(this.board);
|
|
2581
|
+
this.textManage = new TextManage(this.board, this.viewContainerRef, () => {
|
|
2582
|
+
return getTopicRectangleByNode(this.board, this.node);
|
|
2583
|
+
}, (point) => {
|
|
2584
|
+
return isHitMindElement(this.board, point, this.element);
|
|
2585
|
+
}, (textManageRef) => {
|
|
2586
|
+
const width = textManageRef.width;
|
|
2587
|
+
const height = textManageRef.height;
|
|
2588
|
+
if (textManageRef.newValue) {
|
|
2589
|
+
MindTransforms.setTopic(this.board, this.element, textManageRef.newValue, width, height);
|
|
2590
|
+
}
|
|
2591
|
+
else {
|
|
2592
|
+
MindTransforms.setTopicSize(this.board, this.element, width, height);
|
|
2593
|
+
}
|
|
2594
|
+
});
|
|
2595
|
+
}
|
|
2465
2596
|
ngOnInit() {
|
|
2466
|
-
this.emojisDrawer = new EmojisDrawer(this.board, this.viewContainerRef);
|
|
2467
|
-
this.quickInsertDrawer = new QuickInsertDrawer(this.board);
|
|
2468
2597
|
super.ngOnInit();
|
|
2598
|
+
this.initializeDrawer();
|
|
2469
2599
|
this.node = MindElement.getNode(this.element);
|
|
2470
2600
|
this.index = NODE_TO_INDEX.get(this.element) || 0;
|
|
2471
2601
|
this.roughSVG = PlaitBoard.getRoughSVG(this.board);
|
|
2472
2602
|
this.parentG = PlaitElement.getComponent(MindElement.getRoot(this.board, this.element)).rootG;
|
|
2473
2603
|
this.drawShape();
|
|
2474
2604
|
this.drawLink();
|
|
2475
|
-
this.
|
|
2476
|
-
this.
|
|
2477
|
-
this.updateActiveClass();
|
|
2478
|
-
this.drawMaskG();
|
|
2605
|
+
this.drawText();
|
|
2606
|
+
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
|
|
2479
2607
|
this.drawEmojis();
|
|
2480
2608
|
this.drawExtend();
|
|
2481
|
-
|
|
2609
|
+
}
|
|
2610
|
+
editTopic() {
|
|
2611
|
+
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: true });
|
|
2612
|
+
this.textManage.edit(() => {
|
|
2613
|
+
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: false });
|
|
2614
|
+
});
|
|
2482
2615
|
}
|
|
2483
2616
|
onContextChanged(value, previous) {
|
|
2484
|
-
var _a, _b;
|
|
2485
2617
|
const newNode = MindElement.getNode(value.element);
|
|
2486
|
-
// resolve move node richtext lose issue
|
|
2487
|
-
if (this.node !== newNode) {
|
|
2488
|
-
if (this.foreignObject && this.foreignObject.children.length <= 0) {
|
|
2489
|
-
(_a = this.foreignObject) === null || _a === void 0 ? void 0 : _a.appendChild((_b = this.richtextComponentRef) === null || _b === void 0 ? void 0 : _b.instance.editable);
|
|
2490
|
-
}
|
|
2491
|
-
}
|
|
2492
2618
|
const isEqualNode = RectangleClient.isEqual(this.node, newNode);
|
|
2493
2619
|
this.node = newNode;
|
|
2494
2620
|
const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
|
|
2495
2621
|
if (!isEqualNode || value.element !== previous.element || isChangeTheme) {
|
|
2496
|
-
this.
|
|
2497
|
-
this.updateActiveClass();
|
|
2622
|
+
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
|
|
2498
2623
|
this.drawShape();
|
|
2499
2624
|
this.drawLink();
|
|
2500
|
-
this.updateRichtext();
|
|
2501
|
-
this.drawMaskG();
|
|
2502
|
-
this.drawExtend();
|
|
2503
|
-
this.drawQuickInsert();
|
|
2504
2625
|
this.drawEmojis();
|
|
2626
|
+
this.drawExtend();
|
|
2627
|
+
this.textManage.updateText(this.element.data.topic);
|
|
2628
|
+
this.textManage.updateRectangle();
|
|
2505
2629
|
}
|
|
2506
2630
|
else {
|
|
2507
2631
|
const hasSameSelected = value.selected === previous.selected;
|
|
2508
2632
|
const hasSameParent = value.parent === previous.parent;
|
|
2509
2633
|
if (!hasSameSelected) {
|
|
2510
|
-
this.
|
|
2511
|
-
this.updateActiveClass();
|
|
2634
|
+
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
|
|
2512
2635
|
}
|
|
2513
2636
|
if (!hasSameParent) {
|
|
2514
2637
|
this.drawLink();
|
|
@@ -2516,22 +2639,11 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2516
2639
|
}
|
|
2517
2640
|
}
|
|
2518
2641
|
drawEmojis() {
|
|
2519
|
-
const g = this.
|
|
2642
|
+
const g = this.nodeEmojisDrawer.drawEmojis(this.element);
|
|
2520
2643
|
if (g) {
|
|
2521
2644
|
this.g.append(g);
|
|
2522
2645
|
}
|
|
2523
2646
|
}
|
|
2524
|
-
drawQuickInsert() {
|
|
2525
|
-
var _a;
|
|
2526
|
-
this.quickInsertDrawer.destroy();
|
|
2527
|
-
if (this.quickInsertDrawer.canDraw(this.element)) {
|
|
2528
|
-
const g = this.quickInsertDrawer.draw(this.element);
|
|
2529
|
-
if (hasAfterDraw(this.quickInsertDrawer)) {
|
|
2530
|
-
this.quickInsertDrawer.afterDraw(this.element);
|
|
2531
|
-
}
|
|
2532
|
-
(_a = this.extendG) === null || _a === void 0 ? void 0 : _a.appendChild(g);
|
|
2533
|
-
}
|
|
2534
|
-
}
|
|
2535
2647
|
drawShape() {
|
|
2536
2648
|
this.destroyShape();
|
|
2537
2649
|
const shape = getShapeByElement(this.board, this.node.origin);
|
|
@@ -2573,393 +2685,33 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2573
2685
|
this.linkG.remove();
|
|
2574
2686
|
}
|
|
2575
2687
|
}
|
|
2576
|
-
drawMaskG() {
|
|
2577
|
-
this.destroyMaskG();
|
|
2578
|
-
const lineWidthOffset = 2;
|
|
2579
|
-
const extendOffset = 15;
|
|
2580
|
-
const nodeLayout = MindQueries.getLayoutByElement(this.node.origin);
|
|
2581
|
-
const isTop = isTopLayout(nodeLayout);
|
|
2582
|
-
const isRight = isRightLayout(nodeLayout);
|
|
2583
|
-
const isBottom = isBottomLayout(nodeLayout);
|
|
2584
|
-
const isLeft = isLeftLayout(nodeLayout);
|
|
2585
|
-
const { x, y, width, height } = getRectangleByNode(this.node);
|
|
2586
|
-
let drawX = x;
|
|
2587
|
-
let drawY = y;
|
|
2588
|
-
let drawWidth = x + width;
|
|
2589
|
-
let drawHeight = y + height;
|
|
2590
|
-
switch (true) {
|
|
2591
|
-
case isTop:
|
|
2592
|
-
drawX = x - lineWidthOffset;
|
|
2593
|
-
drawY = y - extendOffset;
|
|
2594
|
-
drawWidth = x + width + lineWidthOffset;
|
|
2595
|
-
drawHeight = y + height + lineWidthOffset;
|
|
2596
|
-
break;
|
|
2597
|
-
case isBottom:
|
|
2598
|
-
drawX = x - lineWidthOffset;
|
|
2599
|
-
drawY = y - lineWidthOffset;
|
|
2600
|
-
drawWidth = x + width + lineWidthOffset;
|
|
2601
|
-
drawHeight = y + height + extendOffset;
|
|
2602
|
-
break;
|
|
2603
|
-
case isLeft:
|
|
2604
|
-
drawX = x - extendOffset;
|
|
2605
|
-
drawY = y - lineWidthOffset;
|
|
2606
|
-
drawWidth = x + width + lineWidthOffset;
|
|
2607
|
-
drawHeight = y + height + lineWidthOffset;
|
|
2608
|
-
break;
|
|
2609
|
-
case isRight:
|
|
2610
|
-
drawX = x - lineWidthOffset;
|
|
2611
|
-
drawY = y - lineWidthOffset;
|
|
2612
|
-
drawWidth = x + width + extendOffset;
|
|
2613
|
-
drawHeight = y + height + lineWidthOffset;
|
|
2614
|
-
break;
|
|
2615
|
-
}
|
|
2616
|
-
this.maskG = drawRoundRectangle(this.roughSVG, drawX, drawY, drawWidth, drawHeight, { stroke: 'none', fill: 'rgba(255,255,255,0)', fillStyle: 'solid' }, true);
|
|
2617
|
-
this.maskG.classList.add('mask');
|
|
2618
|
-
this.maskG.setAttribute('visibility', 'visible');
|
|
2619
|
-
this.g.append(this.maskG);
|
|
2620
|
-
if (this.isEditable) {
|
|
2621
|
-
this.disabledMaskG();
|
|
2622
|
-
}
|
|
2623
|
-
fromEvent(this.maskG, 'mouseenter')
|
|
2624
|
-
.pipe(takeUntil(this.destroy$), filter(() => {
|
|
2625
|
-
return PlaitBoard.isFocus(this.board) && !this.element.isCollapsed && !this.handActive;
|
|
2626
|
-
}))
|
|
2627
|
-
.subscribe(() => {
|
|
2628
|
-
this.g.classList.add('hovered');
|
|
2629
|
-
});
|
|
2630
|
-
fromEvent(this.maskG, 'mouseleave')
|
|
2631
|
-
.pipe(takeUntil(this.destroy$), filter(() => {
|
|
2632
|
-
return PlaitBoard.isFocus(this.board) && !this.element.isCollapsed;
|
|
2633
|
-
}))
|
|
2634
|
-
.subscribe(() => {
|
|
2635
|
-
this.g.classList.remove('hovered');
|
|
2636
|
-
});
|
|
2637
|
-
}
|
|
2638
|
-
destroyMaskG() {
|
|
2639
|
-
if (this.maskG) {
|
|
2640
|
-
this.maskG.remove();
|
|
2641
|
-
this.g.classList.remove('hovered');
|
|
2642
|
-
}
|
|
2643
|
-
}
|
|
2644
|
-
enableMaskG() {
|
|
2645
|
-
if (this.maskG) {
|
|
2646
|
-
this.maskG.setAttribute('visibility', 'visible');
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
disabledMaskG() {
|
|
2650
|
-
if (this.maskG) {
|
|
2651
|
-
this.maskG.setAttribute('visibility', 'hidden');
|
|
2652
|
-
}
|
|
2653
|
-
}
|
|
2654
|
-
drawActiveG() {
|
|
2655
|
-
var _a, _b;
|
|
2656
|
-
this.destroyActiveG();
|
|
2657
|
-
(_a = this.abstractIncludedOutlineG) === null || _a === void 0 ? void 0 : _a.remove();
|
|
2658
|
-
if (this.selected) {
|
|
2659
|
-
if (AbstractNode.isAbstract(this.element)) {
|
|
2660
|
-
this.updateAbstractIncludedOutline();
|
|
2661
|
-
}
|
|
2662
|
-
let { x, y, width, height } = getRectangleByNode(this.node);
|
|
2663
|
-
const selectedStrokeG = drawRoundRectangle(this.roughSVG, x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, strokeWidth: 2, fill: '' }, true);
|
|
2664
|
-
// 影响 mask 移入移出事件
|
|
2665
|
-
selectedStrokeG.style.pointerEvents = 'none';
|
|
2666
|
-
this.g.appendChild(selectedStrokeG);
|
|
2667
|
-
this.activeG.push(selectedStrokeG);
|
|
2668
|
-
if (((_b = this.richtextComponentRef) === null || _b === void 0 ? void 0 : _b.instance.plaitReadonly) === true) {
|
|
2669
|
-
const selectedBackgroundG = drawRoundRectangle(this.roughSVG, x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, fill: PRIMARY_COLOR, fillStyle: 'solid' }, true);
|
|
2670
|
-
selectedBackgroundG.style.opacity = '0.15';
|
|
2671
|
-
// 影响双击事件
|
|
2672
|
-
selectedBackgroundG.style.pointerEvents = 'none';
|
|
2673
|
-
this.g.appendChild(selectedBackgroundG);
|
|
2674
|
-
this.activeG.push(selectedBackgroundG, selectedStrokeG);
|
|
2675
|
-
}
|
|
2676
|
-
}
|
|
2677
|
-
}
|
|
2678
|
-
destroyActiveG() {
|
|
2679
|
-
this.activeG.forEach(g => g.remove());
|
|
2680
|
-
this.activeG = [];
|
|
2681
|
-
}
|
|
2682
|
-
updateActiveClass() {
|
|
2683
|
-
if (!this.g) {
|
|
2684
|
-
return;
|
|
2685
|
-
}
|
|
2686
|
-
if (this.selected) {
|
|
2687
|
-
this.render2.addClass(this.g, 'active');
|
|
2688
|
-
}
|
|
2689
|
-
else {
|
|
2690
|
-
this.render2.removeClass(this.g, 'active');
|
|
2691
|
-
}
|
|
2692
|
-
}
|
|
2693
|
-
drawRichtext() {
|
|
2694
|
-
const { richtextG, richtextComponentRef, foreignObject } = drawTopicByNode(this.board, this.node, this.viewContainerRef);
|
|
2695
|
-
this.richtextComponentRef = richtextComponentRef;
|
|
2696
|
-
this.richtextG = richtextG;
|
|
2697
|
-
this.foreignObject = foreignObject;
|
|
2698
|
-
this.render2.addClass(richtextG, 'richtext');
|
|
2699
|
-
this.g.append(richtextG);
|
|
2700
|
-
}
|
|
2701
2688
|
drawExtend() {
|
|
2702
2689
|
this.destroyExtend();
|
|
2703
|
-
// create extend
|
|
2704
2690
|
this.extendG = createG();
|
|
2705
|
-
const collapseG = createG();
|
|
2706
2691
|
this.extendG.classList.add('extend');
|
|
2707
|
-
collapseG.classList.add('collapse-container');
|
|
2708
2692
|
this.g.append(this.extendG);
|
|
2709
|
-
this.
|
|
2710
|
-
if (this.node.origin.isRoot) {
|
|
2711
|
-
return;
|
|
2712
|
-
}
|
|
2713
|
-
// interactive
|
|
2714
|
-
fromEvent(collapseG, 'mouseup')
|
|
2715
|
-
.pipe(filter(() => !this.handActive || !!PlaitBoard.isReadonly(this.board)), take(1))
|
|
2716
|
-
.subscribe(() => {
|
|
2717
|
-
const isCollapsed = !this.node.origin.isCollapsed;
|
|
2718
|
-
const newElement = { isCollapsed };
|
|
2719
|
-
const path = PlaitBoard.findPath(this.board, this.element);
|
|
2720
|
-
Transforms.setNode(this.board, newElement, path);
|
|
2721
|
-
});
|
|
2722
|
-
const { x, y, width, height } = getRectangleByNode(this.node);
|
|
2723
|
-
const stroke = getBranchColorByMindElement(this.board, this.element);
|
|
2724
|
-
const branchWidth = getBranchWidthByMindElement(this.board, this.element);
|
|
2725
|
-
const extendY = y + height / 2;
|
|
2726
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(this.board, this.element);
|
|
2727
|
-
let extendLineXY = [
|
|
2728
|
-
[x + width, extendY],
|
|
2729
|
-
[x + width + EXTEND_OFFSET, extendY]
|
|
2730
|
-
];
|
|
2731
|
-
let arrowYOffset = [-4, 1, -0.6, 4];
|
|
2732
|
-
let arrowXOffset = [10, 5.5, 5.5, 10];
|
|
2733
|
-
let extendLineXOffset = [0, 0];
|
|
2734
|
-
let extendLineYOffset = [0, 0];
|
|
2735
|
-
let circleOffset = [EXTEND_RADIUS / 2, 0];
|
|
2736
|
-
if (isHorizontalLayout(nodeLayout) && !isIndentedLayout(nodeLayout)) {
|
|
2737
|
-
extendLineYOffset =
|
|
2738
|
-
getShapeByElement(this.board, this.node.origin) === MindElementShape.roundRectangle
|
|
2739
|
-
? [0, 0]
|
|
2740
|
-
: [height / 2, height / 2];
|
|
2741
|
-
if (isLeftLayout(nodeLayout)) {
|
|
2742
|
-
//左
|
|
2743
|
-
extendLineXOffset = [-width, -width - EXTEND_OFFSET * 2];
|
|
2744
|
-
circleOffset = [-EXTEND_RADIUS / 2, 0];
|
|
2745
|
-
arrowXOffset = [-10, -5.5, -5.5, -10];
|
|
2746
|
-
}
|
|
2747
|
-
}
|
|
2748
|
-
else {
|
|
2749
|
-
arrowXOffset = [-4, 0.6, -1, 4];
|
|
2750
|
-
if (isTopLayout(nodeLayout)) {
|
|
2751
|
-
//上
|
|
2752
|
-
extendLineXOffset = [-width / 2, -width / 2 - EXTEND_OFFSET];
|
|
2753
|
-
extendLineYOffset = [-height / 2, -height / 2 - EXTEND_OFFSET];
|
|
2754
|
-
arrowYOffset = [-10, -5.5, -5.5, -10];
|
|
2755
|
-
circleOffset = [0, -EXTEND_RADIUS / 2];
|
|
2756
|
-
}
|
|
2757
|
-
else {
|
|
2758
|
-
//下
|
|
2759
|
-
extendLineXOffset = [-width / 2, -width / 2 - EXTEND_OFFSET];
|
|
2760
|
-
extendLineYOffset = [height / 2, height / 2 + EXTEND_OFFSET];
|
|
2761
|
-
arrowYOffset = [10, 5.5, 5.5, 10];
|
|
2762
|
-
circleOffset = [0, EXTEND_RADIUS / 2];
|
|
2763
|
-
}
|
|
2764
|
-
}
|
|
2765
|
-
extendLineXY = [
|
|
2766
|
-
[extendLineXY[0][0] + extendLineXOffset[0], extendLineXY[0][1] + extendLineYOffset[0]],
|
|
2767
|
-
[extendLineXY[1][0] + extendLineXOffset[1], extendLineXY[1][1] + extendLineYOffset[1]]
|
|
2768
|
-
];
|
|
2769
|
-
const extendLine = this.roughSVG.line(extendLineXY[0][0], extendLineXY[0][1], extendLineXY[1][0], extendLineXY[1][1], {
|
|
2770
|
-
strokeWidth: branchWidth,
|
|
2771
|
-
stroke
|
|
2772
|
-
});
|
|
2773
|
-
//绘制箭头
|
|
2774
|
-
const hideArrowTopLine = this.roughSVG.line(extendLineXY[1][0] + arrowXOffset[0], extendLineXY[1][1] + arrowYOffset[0], extendLineXY[1][0] + arrowXOffset[1], extendLineXY[1][1] + arrowYOffset[1], {
|
|
2775
|
-
stroke,
|
|
2776
|
-
strokeWidth: 2
|
|
2777
|
-
});
|
|
2778
|
-
const hideArrowBottomLine = this.roughSVG.line(extendLineXY[1][0] + arrowXOffset[2], extendLineXY[1][1] + arrowYOffset[2], extendLineXY[1][0] + arrowXOffset[3], extendLineXY[1][1] + arrowYOffset[3], {
|
|
2779
|
-
stroke,
|
|
2780
|
-
strokeWidth: 2
|
|
2781
|
-
});
|
|
2782
|
-
if (this.node.origin.isCollapsed) {
|
|
2783
|
-
const badge = this.roughSVG.circle(extendLineXY[1][0] + circleOffset[0], extendLineXY[1][1] + circleOffset[1], EXTEND_RADIUS, {
|
|
2784
|
-
fill: stroke,
|
|
2785
|
-
stroke,
|
|
2786
|
-
fillStyle: 'solid'
|
|
2787
|
-
});
|
|
2788
|
-
let numberOffset = 0;
|
|
2789
|
-
if (getChildrenCount(this.node.origin) >= 10)
|
|
2790
|
-
numberOffset = -2;
|
|
2791
|
-
if (getChildrenCount(this.node.origin) === 1)
|
|
2792
|
-
numberOffset = 1;
|
|
2793
|
-
const badgeText = createText(extendLineXY[1][0] + circleOffset[0] - 4 + numberOffset, extendLineXY[1][1] + circleOffset[1] + 4, stroke, `${getChildrenCount(this.node.origin)}`);
|
|
2693
|
+
if (this.element.isCollapsed) {
|
|
2794
2694
|
this.g.classList.add('collapsed');
|
|
2795
|
-
badge.setAttribute('style', 'opacity: 0.15');
|
|
2796
|
-
badgeText.setAttribute('style', 'font-size: 12px');
|
|
2797
|
-
collapseG.appendChild(badge);
|
|
2798
|
-
collapseG.appendChild(badgeText);
|
|
2799
|
-
collapseG.appendChild(extendLine);
|
|
2800
2695
|
}
|
|
2801
2696
|
else {
|
|
2802
2697
|
this.g.classList.remove('collapsed');
|
|
2803
|
-
if (this.node.origin.children.length > 0) {
|
|
2804
|
-
const hideCircleG = this.roughSVG.circle(extendLineXY[1][0] + circleOffset[0], extendLineXY[1][1] + circleOffset[1], EXTEND_RADIUS - 1, {
|
|
2805
|
-
fill: '#fff',
|
|
2806
|
-
stroke,
|
|
2807
|
-
strokeWidth: branchWidth > 3 ? 3 : branchWidth,
|
|
2808
|
-
fillStyle: 'solid'
|
|
2809
|
-
});
|
|
2810
|
-
collapseG.appendChild(hideCircleG);
|
|
2811
|
-
collapseG.appendChild(hideArrowTopLine);
|
|
2812
|
-
collapseG.appendChild(hideArrowBottomLine);
|
|
2813
|
-
}
|
|
2814
2698
|
}
|
|
2699
|
+
this.nodeInsertDrawer.draw(this.element, this.extendG);
|
|
2700
|
+
this.collapseDrawer.draw(this.element, this.extendG);
|
|
2815
2701
|
}
|
|
2816
2702
|
destroyExtend() {
|
|
2817
2703
|
if (this.extendG) {
|
|
2818
2704
|
this.extendG.remove();
|
|
2819
2705
|
}
|
|
2820
2706
|
}
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
}
|
|
2825
|
-
if (this.richtextComponentRef) {
|
|
2826
|
-
this.richtextComponentRef.destroy();
|
|
2827
|
-
}
|
|
2828
|
-
}
|
|
2829
|
-
updateAbstractIncludedOutline(activeHandlePosition, resizingLocation) {
|
|
2830
|
-
var _a;
|
|
2831
|
-
(_a = this.abstractIncludedOutlineG) === null || _a === void 0 ? void 0 : _a.remove();
|
|
2832
|
-
this.abstractIncludedOutlineG = drawAbstractIncludedOutline(this.board, this.roughSVG, this.element, activeHandlePosition, resizingLocation);
|
|
2833
|
-
PlaitBoard.getHost(this.board).append(this.abstractIncludedOutlineG);
|
|
2834
|
-
}
|
|
2835
|
-
updateRichtext() {
|
|
2836
|
-
updateRichText(this.node.origin.data.topic, this.richtextComponentRef);
|
|
2837
|
-
updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
|
|
2838
|
-
}
|
|
2839
|
-
startEditText(isEnd, isClear) {
|
|
2840
|
-
if (!this.richtextComponentRef) {
|
|
2841
|
-
throw new Error('undefined richtextComponentRef');
|
|
2842
|
-
}
|
|
2843
|
-
const richtextInstance = this.richtextComponentRef.instance;
|
|
2844
|
-
this.isEditable = true;
|
|
2845
|
-
IS_TEXT_EDITABLE.set(this.board, true);
|
|
2846
|
-
this.disabledMaskG();
|
|
2847
|
-
updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
|
|
2848
|
-
if (richtextInstance.plaitReadonly) {
|
|
2849
|
-
richtextInstance.plaitReadonly = false;
|
|
2850
|
-
this.richtextComponentRef.changeDetectorRef.detectChanges();
|
|
2851
|
-
this.drawActiveG();
|
|
2852
|
-
const location = isEnd ? Editor.end(richtextInstance.editor, [0]) : [0];
|
|
2853
|
-
setFullSelectionAndFocus(richtextInstance.editor, location);
|
|
2854
|
-
if (isClear) {
|
|
2855
|
-
Editor.deleteBackward(richtextInstance.editor);
|
|
2856
|
-
}
|
|
2857
|
-
// handle invalid width and height (old data)
|
|
2858
|
-
let { width, height } = getRichtextContentSize(richtextInstance.editable);
|
|
2859
|
-
if (width !== this.element.width || height !== this.element.height) {
|
|
2860
|
-
MindTransforms.setTopicSize(this.board, this.element, width, height);
|
|
2861
|
-
}
|
|
2862
|
-
}
|
|
2863
|
-
let richtext = richtextInstance.plaitValue;
|
|
2864
|
-
// use debounceTime to wait DOM render complete
|
|
2865
|
-
const valueChange$ = richtextInstance.plaitChange
|
|
2866
|
-
.pipe(debounceTime(0), filter(event => {
|
|
2867
|
-
// 过滤掉 operations 中全是 set_selection 的操作
|
|
2868
|
-
return !event.operations.every(op => Operation.isSelectionOperation(op));
|
|
2869
|
-
}))
|
|
2870
|
-
.subscribe(event => {
|
|
2871
|
-
if (richtext === event.value) {
|
|
2872
|
-
return;
|
|
2873
|
-
}
|
|
2874
|
-
this.updateRichtext();
|
|
2875
|
-
// 更新富文本、更新宽高
|
|
2876
|
-
let { width, height } = getRichtextContentSize(richtextInstance.editable);
|
|
2877
|
-
MindTransforms.setTopic(this.board, this.element, event.value, width, height);
|
|
2878
|
-
MERGING.set(this.board, true);
|
|
2879
|
-
});
|
|
2880
|
-
const composition$ = richtextInstance.plaitComposition.pipe(debounceTime(0)).subscribe(event => {
|
|
2881
|
-
let { width, height } = getRichtextContentSize(richtextInstance.editable);
|
|
2882
|
-
if (width < NODE_MIN_WIDTH) {
|
|
2883
|
-
width = NODE_MIN_WIDTH;
|
|
2884
|
-
}
|
|
2885
|
-
if (event.isComposing && (width !== this.node.origin.width || height !== this.node.origin.height)) {
|
|
2886
|
-
const newElement = {
|
|
2887
|
-
width: width / this.board.viewport.zoom,
|
|
2888
|
-
height: height / this.board.viewport.zoom
|
|
2889
|
-
};
|
|
2890
|
-
const path = PlaitBoard.findPath(this.board, this.element);
|
|
2891
|
-
Transforms.setNode(this.board, newElement, path);
|
|
2892
|
-
MERGING.set(this.board, true);
|
|
2893
|
-
}
|
|
2894
|
-
});
|
|
2895
|
-
const mousedown$ = fromEvent(document, 'mousedown').subscribe((event) => {
|
|
2896
|
-
const point = transformPoint(this.board, toPoint(event.x, event.y, PlaitBoard.getHost(this.board)));
|
|
2897
|
-
const clickInNode = isHitMindElement(this.board, point, this.element);
|
|
2898
|
-
if (clickInNode && !hasEditableTarget(richtextInstance.editor, event.target)) {
|
|
2899
|
-
event.preventDefault();
|
|
2900
|
-
}
|
|
2901
|
-
else if (!clickInNode) {
|
|
2902
|
-
// handle composition input state, like: Chinese IME Composition Input
|
|
2903
|
-
timer(0).subscribe(() => {
|
|
2904
|
-
exitHandle();
|
|
2905
|
-
this.enableMaskG();
|
|
2906
|
-
});
|
|
2907
|
-
}
|
|
2908
|
-
});
|
|
2909
|
-
const editor = richtextInstance.editor;
|
|
2910
|
-
const { keydown } = editor;
|
|
2911
|
-
editor.keydown = (event) => {
|
|
2912
|
-
if (event.isComposing) {
|
|
2913
|
-
return;
|
|
2914
|
-
}
|
|
2915
|
-
if (event.key === 'Escape') {
|
|
2916
|
-
event.preventDefault();
|
|
2917
|
-
event.stopPropagation();
|
|
2918
|
-
exitHandle();
|
|
2919
|
-
this.drawActiveG();
|
|
2920
|
-
this.enableMaskG();
|
|
2921
|
-
return;
|
|
2922
|
-
}
|
|
2923
|
-
if (event.key === 'Enter' && !event.shiftKey) {
|
|
2924
|
-
event.preventDefault();
|
|
2925
|
-
event.stopPropagation();
|
|
2926
|
-
exitHandle();
|
|
2927
|
-
this.drawActiveG();
|
|
2928
|
-
this.enableMaskG();
|
|
2929
|
-
return;
|
|
2930
|
-
}
|
|
2931
|
-
if (event.key === 'Tab') {
|
|
2932
|
-
event.preventDefault();
|
|
2933
|
-
event.stopPropagation();
|
|
2934
|
-
exitHandle();
|
|
2935
|
-
this.drawActiveG();
|
|
2936
|
-
this.drawMaskG();
|
|
2937
|
-
}
|
|
2938
|
-
};
|
|
2939
|
-
const exitHandle = () => {
|
|
2940
|
-
this.ngZone.run(() => {
|
|
2941
|
-
var _a;
|
|
2942
|
-
// unsubscribe
|
|
2943
|
-
valueChange$.unsubscribe();
|
|
2944
|
-
composition$.unsubscribe();
|
|
2945
|
-
mousedown$.unsubscribe();
|
|
2946
|
-
editor.keydown = keydown; // reset keydown
|
|
2947
|
-
// editable status
|
|
2948
|
-
MERGING.set(this.board, false);
|
|
2949
|
-
richtextInstance.plaitReadonly = true;
|
|
2950
|
-
(_a = this.richtextComponentRef) === null || _a === void 0 ? void 0 : _a.changeDetectorRef.markForCheck();
|
|
2951
|
-
this.isEditable = false;
|
|
2952
|
-
updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
|
|
2953
|
-
IS_TEXT_EDITABLE.set(this.board, false);
|
|
2954
|
-
});
|
|
2955
|
-
};
|
|
2707
|
+
drawText() {
|
|
2708
|
+
this.textManage.draw(this.element.data.topic);
|
|
2709
|
+
this.g.append(this.textManage.g);
|
|
2956
2710
|
}
|
|
2957
2711
|
ngOnDestroy() {
|
|
2958
|
-
var _a;
|
|
2959
2712
|
super.ngOnDestroy();
|
|
2960
|
-
|
|
2961
|
-
this.
|
|
2962
|
-
this.emojisDrawer.destroy();
|
|
2713
|
+
this.textManage.destroy();
|
|
2714
|
+
this.nodeEmojisDrawer.destroy();
|
|
2963
2715
|
this.destroy$.next();
|
|
2964
2716
|
this.destroy$.complete();
|
|
2965
2717
|
if (ELEMENT_TO_NODE.get(this.element) === this.node) {
|
|
@@ -2967,7 +2719,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2967
2719
|
}
|
|
2968
2720
|
}
|
|
2969
2721
|
}
|
|
2970
|
-
MindNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindNodeComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }
|
|
2722
|
+
MindNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindNodeComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2971
2723
|
MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: MindNodeComponent, selector: "plait-mind-node", usesInheritance: true, ngImport: i0, template: `
|
|
2972
2724
|
<plait-children
|
|
2973
2725
|
*ngIf="!element.isCollapsed"
|
|
@@ -2992,7 +2744,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
2992
2744
|
`,
|
|
2993
2745
|
changeDetection: ChangeDetectionStrategy.OnPush
|
|
2994
2746
|
}]
|
|
2995
|
-
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }
|
|
2747
|
+
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
|
|
2996
2748
|
|
|
2997
2749
|
const getLayoutOptions = (board) => {
|
|
2998
2750
|
function getMainAxle(element, parent) {
|
|
@@ -3065,6 +2817,7 @@ class PlaitMindComponent extends MindNodeComponent {
|
|
|
3065
2817
|
ngOnInit() {
|
|
3066
2818
|
this.updateMindLayout();
|
|
3067
2819
|
super.ngOnInit();
|
|
2820
|
+
this.g.classList.add('root');
|
|
3068
2821
|
}
|
|
3069
2822
|
beforeContextChange(value) {
|
|
3070
2823
|
if (value.element !== this.element && this.initialized) {
|
|
@@ -3105,19 +2858,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3105
2858
|
class MindModule {
|
|
3106
2859
|
}
|
|
3107
2860
|
MindModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3108
|
-
MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [CommonModule,
|
|
3109
|
-
MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule,
|
|
2861
|
+
MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [CommonModule, TextModule, PlaitModule], exports: [PlaitMindComponent, MindNodeComponent] });
|
|
2862
|
+
MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule, TextModule, PlaitModule] });
|
|
3110
2863
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, decorators: [{
|
|
3111
2864
|
type: NgModule,
|
|
3112
2865
|
args: [{
|
|
3113
2866
|
declarations: [PlaitMindComponent, MindNodeComponent],
|
|
3114
|
-
imports: [CommonModule,
|
|
2867
|
+
imports: [CommonModule, TextModule, PlaitModule],
|
|
3115
2868
|
exports: [PlaitMindComponent, MindNodeComponent]
|
|
3116
2869
|
}]
|
|
3117
2870
|
}] });
|
|
3118
2871
|
|
|
3119
2872
|
const DRAG_MOVE_BUFFER = 5;
|
|
3120
|
-
const
|
|
2873
|
+
const withNodeDnd = (board) => {
|
|
3121
2874
|
const { mousedown, mousemove, globalMouseup } = board;
|
|
3122
2875
|
let activeElements = [];
|
|
3123
2876
|
let correspondingElements = [];
|
|
@@ -3465,7 +3218,7 @@ const withAbstract = (board) => {
|
|
|
3465
3218
|
newProperty =
|
|
3466
3219
|
abstractHandlePosition === AbstractHandlePosition.start ? { start: locationIndex + 1 } : { end: locationIndex };
|
|
3467
3220
|
}
|
|
3468
|
-
abstractComponent.
|
|
3221
|
+
abstractComponent.activeDrawer.updateAbstractOutline(activeAbstractElement, abstractHandlePosition, location);
|
|
3469
3222
|
}
|
|
3470
3223
|
mousemove(event);
|
|
3471
3224
|
};
|
|
@@ -3482,7 +3235,7 @@ const withAbstract = (board) => {
|
|
|
3482
3235
|
}
|
|
3483
3236
|
else {
|
|
3484
3237
|
const abstractComponent = PlaitElement.getComponent(activeAbstractElement);
|
|
3485
|
-
abstractComponent.
|
|
3238
|
+
abstractComponent.activeDrawer.updateAbstractOutline(activeAbstractElement);
|
|
3486
3239
|
}
|
|
3487
3240
|
activeAbstractElement = undefined;
|
|
3488
3241
|
}
|
|
@@ -3534,22 +3287,29 @@ const withCreateMind = (board) => {
|
|
|
3534
3287
|
const nodeG = drawRoundRectangleByElement(board, nodeRectangle, emptyMind);
|
|
3535
3288
|
const topicRectangle = getTopicRectangleByElement(newBoard, nodeRectangle, emptyMind);
|
|
3536
3289
|
if (!fakeCreateNodeRef) {
|
|
3537
|
-
const
|
|
3290
|
+
const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, () => {
|
|
3291
|
+
return topicRectangle;
|
|
3292
|
+
});
|
|
3293
|
+
PlaitBoard.getComponent(board)
|
|
3294
|
+
.viewContainerRef.injector.get(NgZone)
|
|
3295
|
+
.run(() => {
|
|
3296
|
+
textManage.draw(emptyMind.data.topic);
|
|
3297
|
+
});
|
|
3538
3298
|
fakeCreateNodeRef = {
|
|
3539
|
-
|
|
3299
|
+
g: createG(),
|
|
3540
3300
|
nodeG,
|
|
3541
|
-
|
|
3542
|
-
topicG: richtextG
|
|
3301
|
+
textManage
|
|
3543
3302
|
};
|
|
3544
|
-
|
|
3545
|
-
PlaitBoard.getHost(board).append(
|
|
3303
|
+
fakeCreateNodeRef.g.classList.add('root');
|
|
3304
|
+
PlaitBoard.getHost(board).append(fakeCreateNodeRef.g);
|
|
3305
|
+
fakeCreateNodeRef.g.append(...[fakeCreateNodeRef.nodeG, textManage.g]);
|
|
3546
3306
|
}
|
|
3547
3307
|
else {
|
|
3308
|
+
fakeCreateNodeRef.textManage.updateRectangle(topicRectangle);
|
|
3548
3309
|
fakeCreateNodeRef.nodeG.remove();
|
|
3549
3310
|
fakeCreateNodeRef.nodeG = nodeG;
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
updateForeignObject(fakeCreateNodeRef.topicG, topicRectangle.width, topicRectangle.height, topicRectangle.x, topicRectangle.y);
|
|
3311
|
+
fakeCreateNodeRef.g.append(nodeG);
|
|
3312
|
+
fakeCreateNodeRef.g.append(fakeCreateNodeRef.textManage.g);
|
|
3553
3313
|
}
|
|
3554
3314
|
}
|
|
3555
3315
|
});
|
|
@@ -3586,9 +3346,8 @@ const withCreateMind = (board) => {
|
|
|
3586
3346
|
};
|
|
3587
3347
|
function destroy() {
|
|
3588
3348
|
if (fakeCreateNodeRef) {
|
|
3589
|
-
fakeCreateNodeRef.
|
|
3590
|
-
fakeCreateNodeRef.
|
|
3591
|
-
fakeCreateNodeRef.topicG.remove();
|
|
3349
|
+
fakeCreateNodeRef.textManage.destroy();
|
|
3350
|
+
fakeCreateNodeRef.g.remove();
|
|
3592
3351
|
fakeCreateNodeRef = null;
|
|
3593
3352
|
}
|
|
3594
3353
|
}
|
|
@@ -3620,6 +3379,68 @@ const isExpandHotkey = (keyboardEvent) => {
|
|
|
3620
3379
|
return isKeyHotkey('mod+/', keyboardEvent);
|
|
3621
3380
|
};
|
|
3622
3381
|
|
|
3382
|
+
const withNodeHover = (board) => {
|
|
3383
|
+
const { mousemove, mouseleave } = board;
|
|
3384
|
+
let hoveredMindElement = null;
|
|
3385
|
+
board.mousemove = (event) => {
|
|
3386
|
+
throttleRAF(() => {
|
|
3387
|
+
let target = null;
|
|
3388
|
+
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
3389
|
+
depthFirstRecursion(board, element => {
|
|
3390
|
+
if (target) {
|
|
3391
|
+
return;
|
|
3392
|
+
}
|
|
3393
|
+
if (!MindElement.isMindElement(board, element)) {
|
|
3394
|
+
return;
|
|
3395
|
+
}
|
|
3396
|
+
const isHitElement = isHitMindElement(board, point, element);
|
|
3397
|
+
if (isHitElement) {
|
|
3398
|
+
target = element;
|
|
3399
|
+
}
|
|
3400
|
+
}, node => {
|
|
3401
|
+
if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
|
|
3402
|
+
return true;
|
|
3403
|
+
}
|
|
3404
|
+
else {
|
|
3405
|
+
return false;
|
|
3406
|
+
}
|
|
3407
|
+
}, true);
|
|
3408
|
+
if (hoveredMindElement && target && hoveredMindElement === target) {
|
|
3409
|
+
return;
|
|
3410
|
+
}
|
|
3411
|
+
if (hoveredMindElement) {
|
|
3412
|
+
removeHovered(hoveredMindElement);
|
|
3413
|
+
}
|
|
3414
|
+
if (target) {
|
|
3415
|
+
addHovered(target);
|
|
3416
|
+
hoveredMindElement = target;
|
|
3417
|
+
}
|
|
3418
|
+
else {
|
|
3419
|
+
hoveredMindElement = null;
|
|
3420
|
+
}
|
|
3421
|
+
});
|
|
3422
|
+
mousemove(event);
|
|
3423
|
+
};
|
|
3424
|
+
board.mouseleave = (event) => {
|
|
3425
|
+
if (hoveredMindElement) {
|
|
3426
|
+
removeHovered(hoveredMindElement);
|
|
3427
|
+
hoveredMindElement = null;
|
|
3428
|
+
}
|
|
3429
|
+
mouseleave(event);
|
|
3430
|
+
};
|
|
3431
|
+
return board;
|
|
3432
|
+
};
|
|
3433
|
+
const addHovered = (element) => {
|
|
3434
|
+
const component = PlaitElement.getComponent(element);
|
|
3435
|
+
component.g.classList.add('hovered');
|
|
3436
|
+
};
|
|
3437
|
+
const removeHovered = (element) => {
|
|
3438
|
+
const component = PlaitElement.getComponent(element);
|
|
3439
|
+
if (component && component.g) {
|
|
3440
|
+
component.g.classList.remove('hovered');
|
|
3441
|
+
}
|
|
3442
|
+
};
|
|
3443
|
+
|
|
3623
3444
|
const withMind = (board) => {
|
|
3624
3445
|
const { drawElement, dblclick, keydown, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
|
|
3625
3446
|
board.drawElement = (context) => {
|
|
@@ -3746,7 +3567,7 @@ const withMind = (board) => {
|
|
|
3746
3567
|
if (!isVirtualKey(event)) {
|
|
3747
3568
|
event.preventDefault();
|
|
3748
3569
|
const selectedElement = selectedElements[0];
|
|
3749
|
-
|
|
3570
|
+
editTopic(selectedElement);
|
|
3750
3571
|
return;
|
|
3751
3572
|
}
|
|
3752
3573
|
}
|
|
@@ -3768,7 +3589,7 @@ const withMind = (board) => {
|
|
|
3768
3589
|
.forEach(mindMap => {
|
|
3769
3590
|
depthFirstRecursion(mindMap, node => {
|
|
3770
3591
|
if (!PlaitBoard.hasBeenTextEditing(board) && isHitMindElement(board, point, node)) {
|
|
3771
|
-
|
|
3592
|
+
editTopic(node);
|
|
3772
3593
|
}
|
|
3773
3594
|
}, node => {
|
|
3774
3595
|
if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
|
|
@@ -3804,7 +3625,7 @@ const withMind = (board) => {
|
|
|
3804
3625
|
}
|
|
3805
3626
|
else {
|
|
3806
3627
|
const text = data === null || data === void 0 ? void 0 : data.getData(`text/plain`);
|
|
3807
|
-
const { width, height } =
|
|
3628
|
+
const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT);
|
|
3808
3629
|
const selectedElements = getSelectedElements(board);
|
|
3809
3630
|
if (text && selectedElements.length === 1) {
|
|
3810
3631
|
insertClipboardText(board, selectedElements[0], text, width, height);
|
|
@@ -3822,7 +3643,7 @@ const withMind = (board) => {
|
|
|
3822
3643
|
MindTransforms.removeElements(board, selectedElements);
|
|
3823
3644
|
deleteFragment(data);
|
|
3824
3645
|
};
|
|
3825
|
-
return withMindHotkey(withMindExtend(withCreateMind(withAbstract(
|
|
3646
|
+
return withNodeHover(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board))))));
|
|
3826
3647
|
};
|
|
3827
3648
|
|
|
3828
3649
|
class MindEmojiBaseComponent {
|
|
@@ -3876,5 +3697,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3876
3697
|
* Generated bundle index. Do not edit.
|
|
3877
3698
|
*/
|
|
3878
3699
|
|
|
3879
|
-
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_WIDTH, BaseDrawer, BranchShape, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE,
|
|
3700
|
+
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_WIDTH, BaseDrawer, BranchShape, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_DIAMETER, EXTEND_OFFSET, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, 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, ROOT_TOPIC_HEIGHT, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
|
|
3880
3701
|
//# sourceMappingURL=plait-mind.mjs.map
|