@plait/mind 0.2.2 → 0.3.1
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/{drawer/base/base.d.ts → base/base.drawer.d.ts} +1 -1
- package/{plugins/emoji → base}/emoji-base.component.d.ts +2 -2
- package/{plugins/emoji → base}/index.d.ts +1 -1
- package/draw/abstract.d.ts +2 -1
- package/draw/indented-link.d.ts +1 -1
- package/draw/link/logic-link.d.ts +1 -1
- package/draw/node.d.ts +5 -0
- package/draw/topic.d.ts +16 -0
- package/{plugins/emoji → drawer}/emoji.drawer.d.ts +3 -3
- package/drawer/quick-insert.drawer.d.ts +1 -1
- package/esm2020/base/base.drawer.mjs +17 -0
- package/esm2020/base/emoji-base.component.mjs +33 -0
- package/esm2020/base/index.mjs +3 -0
- package/esm2020/draw/abstract.mjs +8 -7
- package/esm2020/draw/indented-link.mjs +3 -3
- package/esm2020/draw/link/abstract-link.mjs +9 -15
- package/esm2020/draw/link/logic-link.mjs +9 -9
- package/esm2020/draw/node.mjs +21 -0
- package/esm2020/draw/topic.mjs +32 -0
- package/esm2020/drawer/emoji.drawer.mjs +73 -0
- package/esm2020/drawer/quick-insert.drawer.mjs +3 -3
- package/esm2020/interfaces/index.mjs +2 -2
- package/esm2020/interfaces/pointer.mjs +5 -0
- package/esm2020/mind.component.mjs +2 -2
- package/esm2020/mind.module.mjs +5 -5
- package/esm2020/node.component.mjs +11 -10
- package/esm2020/plugins/with-abstract-resize.board.mjs +12 -0
- package/esm2020/plugins/with-abstract-resize.mjs +107 -0
- package/esm2020/plugins/with-mind-create.mjs +85 -0
- package/esm2020/plugins/with-mind-extend.mjs +11 -0
- package/esm2020/plugins/with-mind.board.mjs +2 -0
- package/esm2020/plugins/with-mind.mjs +30 -16
- package/esm2020/plugins/with-node-dnd.mjs +162 -0
- package/esm2020/public-api.mjs +5 -3
- package/esm2020/transforms/abstract-node.mjs +3 -2
- package/esm2020/transforms/emoji.mjs +37 -0
- package/esm2020/transforms/index.mjs +7 -3
- package/esm2020/transforms/node.mjs +40 -33
- package/esm2020/utils/abstract/common.mjs +64 -31
- package/esm2020/utils/abstract/resize.mjs +3 -2
- package/esm2020/utils/clipboard.mjs +16 -18
- package/esm2020/utils/dnd/common.mjs +35 -0
- package/esm2020/utils/dnd/detector.mjs +268 -0
- package/esm2020/utils/dnd/draw.mjs +161 -0
- package/esm2020/utils/index.mjs +6 -6
- package/esm2020/utils/mind.mjs +6 -129
- package/esm2020/utils/node/adjust-node.mjs +49 -0
- package/esm2020/utils/node/common.mjs +6 -0
- package/esm2020/utils/node/create-node.mjs +61 -0
- package/esm2020/utils/node/index.mjs +4 -0
- package/esm2020/utils/point-placement.mjs +22 -2
- package/esm2020/utils/position/emoji.mjs +31 -0
- package/esm2020/utils/position/index.mjs +4 -0
- package/esm2020/utils/position/node.mjs +34 -0
- package/esm2020/utils/position/topic.mjs +14 -0
- package/esm2020/utils/space/emoji.mjs +19 -0
- package/esm2020/utils/space/layout-options.mjs +72 -0
- package/esm2020/utils/space/node-space.mjs +77 -0
- package/fesm2015/plait-mind.mjs +1464 -1631
- package/fesm2015/plait-mind.mjs.map +1 -1
- package/fesm2020/plait-mind.mjs +1486 -1642
- package/fesm2020/plait-mind.mjs.map +1 -1
- package/interfaces/index.d.ts +1 -1
- package/interfaces/pointer.d.ts +3 -0
- package/mind.module.d.ts +2 -2
- package/node.component.d.ts +3 -3
- package/package.json +3 -3
- package/{interfaces/abstract.d.ts → plugins/with-abstract-resize.board.d.ts} +2 -2
- package/plugins/with-mind-create.d.ts +11 -0
- package/plugins/with-mind-extend.d.ts +3 -0
- package/plugins/{with-extend-mind.d.ts → with-mind.board.d.ts} +4 -4
- package/plugins/with-mind.d.ts +1 -1
- package/public-api.d.ts +4 -2
- package/styles/styles.scss +5 -2
- package/transforms/abstract-node.d.ts +1 -1
- package/transforms/emoji.d.ts +6 -0
- package/transforms/index.d.ts +3 -0
- package/transforms/node.d.ts +5 -5
- package/utils/abstract/common.d.ts +19 -4
- package/utils/abstract/resize.d.ts +2 -1
- package/utils/dnd/common.d.ts +7 -0
- package/utils/dnd/detector.d.ts +31 -0
- package/utils/dnd/draw.d.ts +9 -0
- package/utils/index.d.ts +5 -5
- package/utils/mind.d.ts +3 -22
- package/utils/node/adjust-node.d.ts +5 -0
- package/utils/{node.d.ts → node/common.d.ts} +1 -1
- package/utils/node/create-node.d.ts +14 -0
- package/utils/node/index.d.ts +3 -0
- package/utils/point-placement.d.ts +8 -1
- package/utils/position/emoji.d.ts +7 -0
- package/utils/position/index.d.ts +3 -0
- package/utils/position/node.d.ts +12 -0
- package/utils/position/topic.d.ts +16 -0
- package/utils/space/emoji.d.ts +7 -0
- package/{layout-option.d.ts → utils/space/layout-options.d.ts} +1 -1
- package/utils/{node-space.d.ts → space/node-space.d.ts} +4 -4
- package/draw/link.d.ts +0 -3
- package/draw/richtext.d.ts +0 -15
- package/draw/shape.d.ts +0 -3
- package/esm2020/draw/link.mjs +0 -160
- package/esm2020/draw/richtext.mjs +0 -39
- package/esm2020/draw/shape.mjs +0 -18
- package/esm2020/drawer/base/base.mjs +0 -17
- package/esm2020/interfaces/abstract.mjs +0 -12
- package/esm2020/layout-option.mjs +0 -72
- package/esm2020/plugins/emoji/emoji-base.component.mjs +0 -33
- package/esm2020/plugins/emoji/emoji.drawer.mjs +0 -72
- package/esm2020/plugins/emoji/emoji.mjs +0 -47
- package/esm2020/plugins/emoji/index.mjs +0 -3
- package/esm2020/plugins/with-abstract.mjs +0 -106
- package/esm2020/plugins/with-dnd.mjs +0 -179
- package/esm2020/plugins/with-extend-mind.mjs +0 -11
- package/esm2020/utils/direction-corrector.mjs +0 -54
- package/esm2020/utils/direction-detector.mjs +0 -56
- package/esm2020/utils/dnd.mjs +0 -122
- package/esm2020/utils/draw-placeholder.mjs +0 -313
- package/esm2020/utils/drop-target-corrector.mjs +0 -87
- package/esm2020/utils/graph.mjs +0 -24
- package/esm2020/utils/node-space.mjs +0 -77
- package/esm2020/utils/node.mjs +0 -6
- package/plugins/emoji/emoji.d.ts +0 -11
- package/utils/direction-corrector.d.ts +0 -4
- package/utils/direction-detector.d.ts +0 -9
- package/utils/dnd.d.ts +0 -16
- package/utils/draw-placeholder.d.ts +0 -42
- package/utils/drop-target-corrector.d.ts +0 -9
- package/utils/graph.d.ts +0 -5
- /package/plugins/{with-abstract.d.ts → with-abstract-resize.d.ts} +0 -0
- /package/plugins/{with-dnd.d.ts → with-node-dnd.d.ts} +0 -0
package/fesm2015/plait-mind.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
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 {
|
|
5
|
-
import { MindLayoutType, AbstractNode, getAbstractLayout, isIndentedLayout, isStandardLayout,
|
|
6
|
-
import { getSizeByText, ROOT_DEFAULT_HEIGHT, TEXT_DEFAULT_HEIGHT,
|
|
4
|
+
import { PlaitBoard, PlaitNode, NODE_TO_PARENT, Path, distanceBetweenPointAndRectangle, RectangleClient, PlaitElement, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, depthFirstRecursion, drawRoundRectangle, createG, getRectangleByElements, getSelectedElements, drawAbstractRoundRectangle, PlaitPluginElementComponent, PlaitPointerType, NODE_TO_INDEX, createText, IS_TEXT_EDITABLE, MERGING, transformPoint, toPoint, PlaitModule, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, BOARD_TO_HOST, throttleRAF, updateForeignObject as updateForeignObject$1, BoardTransforms, Selection, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
|
|
5
|
+
import { MindLayoutType, AbstractNode, getAbstractLayout, isIndentedLayout, isStandardLayout, isLeftLayout, isRightLayout, getNonAbstractChildren, isTopLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, ConnectingPosition, GlobalLayout } from '@plait/layouts';
|
|
6
|
+
import { getSizeByText, ROOT_DEFAULT_HEIGHT, TEXT_DEFAULT_HEIGHT, updateForeignObject, drawRichtext, 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';
|
|
9
9
|
import { Node, Path as Path$1, Editor, Operation } from 'slate';
|
|
10
10
|
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
11
11
|
import { isKeyHotkey } from 'is-hotkey';
|
|
12
12
|
import * as i1 from '@angular/common';
|
|
13
|
-
import {
|
|
13
|
+
import { CommonModule } from '@angular/common';
|
|
14
14
|
|
|
15
15
|
const ELEMENT_TO_NODE = new WeakMap();
|
|
16
16
|
|
|
@@ -56,27 +56,42 @@ const ABSTRACT_INCLUDED_OUTLINE_OFFSET = 3.5;
|
|
|
56
56
|
const ABSTRACT_HANDLE_LENGTH = 10;
|
|
57
57
|
const ABSTRACT_HANDLE_MASK_WIDTH = 8;
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
function hitMindElement(board, point, element) {
|
|
72
|
-
const node = ELEMENT_TO_NODE.get(element);
|
|
73
|
-
if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
|
|
74
|
-
return true;
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
return false;
|
|
59
|
+
const MindNode = {
|
|
60
|
+
get(root, path) {
|
|
61
|
+
let node = root;
|
|
62
|
+
for (let i = 0; i < path.length; i++) {
|
|
63
|
+
const p = path[i];
|
|
64
|
+
if (!node || !node.children || !node.children[p]) {
|
|
65
|
+
throw new Error(`Cannot find a descendant at path [${path}]`);
|
|
66
|
+
}
|
|
67
|
+
node = node.children[p];
|
|
68
|
+
}
|
|
69
|
+
return node;
|
|
78
70
|
}
|
|
79
|
-
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
var LayoutDirection;
|
|
74
|
+
(function (LayoutDirection) {
|
|
75
|
+
LayoutDirection["top"] = "top";
|
|
76
|
+
LayoutDirection["right"] = "right";
|
|
77
|
+
LayoutDirection["bottom"] = "bottom";
|
|
78
|
+
LayoutDirection["left"] = "left";
|
|
79
|
+
})(LayoutDirection || (LayoutDirection = {}));
|
|
80
|
+
const LayoutDirectionsMap = {
|
|
81
|
+
[MindLayoutType.right]: [LayoutDirection.right],
|
|
82
|
+
[MindLayoutType.left]: [LayoutDirection.left],
|
|
83
|
+
[MindLayoutType.upward]: [LayoutDirection.top],
|
|
84
|
+
[MindLayoutType.downward]: [LayoutDirection.bottom],
|
|
85
|
+
[MindLayoutType.rightBottomIndented]: [LayoutDirection.right, LayoutDirection.bottom],
|
|
86
|
+
[MindLayoutType.rightTopIndented]: [LayoutDirection.right, LayoutDirection.top],
|
|
87
|
+
[MindLayoutType.leftBottomIndented]: [LayoutDirection.left, LayoutDirection.bottom],
|
|
88
|
+
[MindLayoutType.leftTopIndented]: [LayoutDirection.left, LayoutDirection.top]
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
var MindPointerType;
|
|
92
|
+
(function (MindPointerType) {
|
|
93
|
+
MindPointerType["mind"] = "mind";
|
|
94
|
+
})(MindPointerType || (MindPointerType = {}));
|
|
80
95
|
|
|
81
96
|
/**
|
|
82
97
|
* get correctly layout:
|
|
@@ -368,398 +383,172 @@ var MindElementShape;
|
|
|
368
383
|
MindElementShape["underline"] = "underline";
|
|
369
384
|
})(MindElementShape || (MindElementShape = {}));
|
|
370
385
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
386
|
+
function getEmojisWidthHeight(board, element) {
|
|
387
|
+
const options = board.getMindOptions();
|
|
388
|
+
const count = element.data.emojis.length;
|
|
389
|
+
const fontSize = getEmojiFontSize(element);
|
|
390
|
+
return {
|
|
391
|
+
width: fontSize * count + count * 2 * options.emojiPadding + (count - 1) * options.spaceBetweenEmojis,
|
|
392
|
+
height: element.height
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
function getEmojiFontSize(element) {
|
|
396
|
+
if (PlaitMind.isMind(element)) {
|
|
397
|
+
return 18 + 2;
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
return 14 + 2;
|
|
382
401
|
}
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
var LayoutDirection;
|
|
386
|
-
(function (LayoutDirection) {
|
|
387
|
-
LayoutDirection["top"] = "top";
|
|
388
|
-
LayoutDirection["right"] = "right";
|
|
389
|
-
LayoutDirection["bottom"] = "bottom";
|
|
390
|
-
LayoutDirection["left"] = "left";
|
|
391
|
-
})(LayoutDirection || (LayoutDirection = {}));
|
|
392
|
-
const LayoutDirectionsMap = {
|
|
393
|
-
[MindLayoutType.right]: [LayoutDirection.right],
|
|
394
|
-
[MindLayoutType.left]: [LayoutDirection.left],
|
|
395
|
-
[MindLayoutType.upward]: [LayoutDirection.top],
|
|
396
|
-
[MindLayoutType.downward]: [LayoutDirection.bottom],
|
|
397
|
-
[MindLayoutType.rightBottomIndented]: [LayoutDirection.right, LayoutDirection.bottom],
|
|
398
|
-
[MindLayoutType.rightTopIndented]: [LayoutDirection.right, LayoutDirection.top],
|
|
399
|
-
[MindLayoutType.leftBottomIndented]: [LayoutDirection.left, LayoutDirection.bottom],
|
|
400
|
-
[MindLayoutType.leftTopIndented]: [LayoutDirection.left, LayoutDirection.top]
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
var AbstractHandlePosition;
|
|
404
|
-
(function (AbstractHandlePosition) {
|
|
405
|
-
AbstractHandlePosition["start"] = "start";
|
|
406
|
-
AbstractHandlePosition["end"] = "end";
|
|
407
|
-
})(AbstractHandlePosition || (AbstractHandlePosition = {}));
|
|
408
|
-
var AbstractResizeState;
|
|
409
|
-
(function (AbstractResizeState) {
|
|
410
|
-
AbstractResizeState["start"] = "start";
|
|
411
|
-
AbstractResizeState["resizing"] = "resizing";
|
|
412
|
-
AbstractResizeState["end"] = "end";
|
|
413
|
-
})(AbstractResizeState || (AbstractResizeState = {}));
|
|
414
|
-
|
|
415
|
-
function enterNodeEditing(element) {
|
|
416
|
-
const component = ELEMENT_TO_COMPONENT.get(element);
|
|
417
|
-
component.startEditText(false, false);
|
|
418
402
|
}
|
|
419
403
|
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
rightChildren.push(child);
|
|
428
|
-
continue;
|
|
429
|
-
}
|
|
430
|
-
if (AbstractNode.isAbstract(child) && child.start >= rightNodeCount) {
|
|
431
|
-
leftChildren.push(child);
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
if (i < rightNodeCount) {
|
|
435
|
-
rightChildren.push(child);
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
leftChildren.push(child);
|
|
439
|
-
}
|
|
404
|
+
const NodeDefaultSpace = {
|
|
405
|
+
horizontal: {
|
|
406
|
+
nodeAndText: BASE * 3,
|
|
407
|
+
emojiAndText: BASE * 1.5
|
|
408
|
+
},
|
|
409
|
+
vertical: {
|
|
410
|
+
nodeAndText: BASE * 1.5
|
|
440
411
|
}
|
|
441
|
-
return { leftChildren, rightChildren };
|
|
442
412
|
};
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
413
|
+
const RootDefaultSpace = {
|
|
414
|
+
horizontal: {
|
|
415
|
+
nodeAndText: BASE * 4,
|
|
416
|
+
emojiAndText: BASE * 2
|
|
417
|
+
},
|
|
418
|
+
vertical: {
|
|
419
|
+
nodeAndText: BASE * 2
|
|
420
|
+
}
|
|
446
421
|
};
|
|
447
|
-
const
|
|
448
|
-
|
|
422
|
+
const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
|
|
423
|
+
const isMind = PlaitMind.isMind(element);
|
|
424
|
+
const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
|
|
425
|
+
return nodeAndText;
|
|
449
426
|
};
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
return parent.children.find(child => {
|
|
455
|
-
return AbstractNode.isAbstract(child) && elementIndex >= child.start && elementIndex <= child.end;
|
|
456
|
-
});
|
|
427
|
+
const getVerticalSpaceBetweenNodeAndText = (element) => {
|
|
428
|
+
const isMind = PlaitMind.isMind(element);
|
|
429
|
+
const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
|
|
430
|
+
return nodeAndText;
|
|
457
431
|
};
|
|
458
|
-
const
|
|
459
|
-
const
|
|
460
|
-
|
|
432
|
+
const getSpaceEmojiAndText = (element) => {
|
|
433
|
+
const isMind = PlaitMind.isMind(element);
|
|
434
|
+
const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
|
|
435
|
+
return emojiAndText;
|
|
461
436
|
};
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const parent = MindElement.getParent(value);
|
|
472
|
-
const isOverall = parent.children.slice(start, end + 1).every(includedElement => elements.indexOf(includedElement) > -1);
|
|
473
|
-
if (isOverall) {
|
|
474
|
-
overallAbstracts.push(abstract);
|
|
475
|
-
}
|
|
437
|
+
const NodeSpace = {
|
|
438
|
+
getNodeWidth(board, element) {
|
|
439
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
440
|
+
if (MindElement.hasEmojis(element)) {
|
|
441
|
+
return (NodeSpace.getEmojiLeftSpace(board, element) +
|
|
442
|
+
getEmojisWidthHeight(board, element).width +
|
|
443
|
+
getSpaceEmojiAndText(element) +
|
|
444
|
+
element.width +
|
|
445
|
+
nodeAndText);
|
|
476
446
|
}
|
|
477
|
-
|
|
478
|
-
|
|
447
|
+
return nodeAndText + element.width + nodeAndText;
|
|
448
|
+
},
|
|
449
|
+
getNodeHeight(board, element) {
|
|
450
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
451
|
+
return nodeAndText + element.height + nodeAndText;
|
|
452
|
+
},
|
|
453
|
+
getTextLeftSpace(board, element) {
|
|
454
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
455
|
+
if (MindElement.hasEmojis(element)) {
|
|
456
|
+
return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
return nodeAndText;
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
getTextTopSpace(element) {
|
|
463
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
464
|
+
return nodeAndText;
|
|
465
|
+
},
|
|
466
|
+
getEmojiLeftSpace(board, element) {
|
|
467
|
+
const options = board.getMindOptions();
|
|
468
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
469
|
+
return nodeAndText - options.emojiPadding;
|
|
470
|
+
},
|
|
471
|
+
getEmojiTopSpace(element) {
|
|
472
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
473
|
+
return nodeAndText;
|
|
474
|
+
}
|
|
479
475
|
};
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
476
|
+
|
|
477
|
+
function getRectangleByNode(node) {
|
|
478
|
+
const x = node.x + node.hGap;
|
|
479
|
+
let y = node.y + node.vGap;
|
|
480
|
+
const width = node.width - node.hGap * 2;
|
|
481
|
+
const height = node.height - node.vGap * 2;
|
|
482
|
+
return {
|
|
483
|
+
x,
|
|
484
|
+
y,
|
|
485
|
+
width,
|
|
486
|
+
height
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
function getRectangleByElement(board, originPoint, element) {
|
|
490
|
+
const nodeRectangle = {
|
|
491
|
+
x: originPoint[0],
|
|
492
|
+
y: originPoint[1],
|
|
493
|
+
width: NodeSpace.getNodeWidth(board, element),
|
|
494
|
+
height: NodeSpace.getNodeHeight(board, element)
|
|
495
|
+
};
|
|
496
|
+
return nodeRectangle;
|
|
497
|
+
}
|
|
498
|
+
function isHitMindElement(board, point, element) {
|
|
499
|
+
const node = MindElement.getNode(element);
|
|
500
|
+
if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
|
|
501
|
+
return true;
|
|
488
502
|
}
|
|
489
503
|
else {
|
|
490
|
-
|
|
491
|
-
behindAbstracts = getBehindAbstracts(parent, selectedElement);
|
|
492
|
-
}
|
|
493
|
-
if (behindAbstracts.length) {
|
|
494
|
-
behindAbstracts.forEach(abstract => {
|
|
495
|
-
let newProperties = abstractRefs.get(abstract);
|
|
496
|
-
if (!newProperties) {
|
|
497
|
-
newProperties = { start: 0, end: 0 };
|
|
498
|
-
abstractRefs.set(abstract, newProperties);
|
|
499
|
-
}
|
|
500
|
-
newProperties.start = newProperties.start + 1;
|
|
501
|
-
newProperties.end = newProperties.end + 1;
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
if (!hasPreviousNode) {
|
|
505
|
-
return abstractRefs;
|
|
504
|
+
return false;
|
|
506
505
|
}
|
|
507
|
-
|
|
508
|
-
const correspondingAbstract = getCorrespondingAbstract(parent, selectedElement);
|
|
509
|
-
const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
|
|
510
|
-
if (correspondingAbstract && !isDragToLast) {
|
|
511
|
-
let newProperties = abstractRefs.get(correspondingAbstract);
|
|
512
|
-
if (!newProperties) {
|
|
513
|
-
newProperties = { start: 0, end: 0 };
|
|
514
|
-
abstractRefs.set(correspondingAbstract, newProperties);
|
|
515
|
-
}
|
|
516
|
-
newProperties.end = newProperties.end + 1;
|
|
517
|
-
}
|
|
518
|
-
return abstractRefs;
|
|
519
|
-
};
|
|
520
|
-
const deleteElementHandleAbstract = (board, deletableElements, abstractRefs = new Map()) => {
|
|
521
|
-
deletableElements.forEach(node => {
|
|
522
|
-
if (!PlaitMind.isMind(node)) {
|
|
523
|
-
const parent = PlaitNode.parent(board, PlaitBoard.findPath(board, node));
|
|
524
|
-
const behindAbstracts = getBehindAbstracts(parent, node).filter(abstract => !deletableElements.includes(abstract));
|
|
525
|
-
if (behindAbstracts.length) {
|
|
526
|
-
behindAbstracts.forEach(abstract => {
|
|
527
|
-
let newProperties = abstractRefs.get(abstract);
|
|
528
|
-
if (!newProperties) {
|
|
529
|
-
newProperties = { start: 0, end: 0 };
|
|
530
|
-
abstractRefs.set(abstract, newProperties);
|
|
531
|
-
}
|
|
532
|
-
newProperties.start = newProperties.start - 1;
|
|
533
|
-
newProperties.end = newProperties.end - 1;
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
const correspondingAbstract = getCorrespondingAbstract(parent, node);
|
|
537
|
-
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
538
|
-
let newProperties = abstractRefs.get(correspondingAbstract);
|
|
539
|
-
if (!newProperties) {
|
|
540
|
-
newProperties = { start: 0, end: 0 };
|
|
541
|
-
abstractRefs.set(correspondingAbstract, newProperties);
|
|
542
|
-
}
|
|
543
|
-
newProperties.end = newProperties.end - 1;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
});
|
|
547
|
-
return abstractRefs;
|
|
548
|
-
};
|
|
549
|
-
|
|
550
|
-
const setAbstractsByRefs = (board, abstractRefs) => {
|
|
551
|
-
abstractRefs.forEach((newProperty, element) => {
|
|
552
|
-
const start = element.start + newProperty.start;
|
|
553
|
-
const end = element.end + newProperty.end;
|
|
554
|
-
const path = PlaitBoard.findPath(board, element);
|
|
555
|
-
if (start > end) {
|
|
556
|
-
Transforms.removeNode(board, path);
|
|
557
|
-
}
|
|
558
|
-
else {
|
|
559
|
-
Transforms.setNode(board, { start, end }, path);
|
|
560
|
-
}
|
|
561
|
-
});
|
|
562
|
-
};
|
|
563
|
-
const setAbstractByStandardLayout = (board, element) => {
|
|
564
|
-
const rightNodeCount = element.rightNodeCount;
|
|
565
|
-
const abstract = element.children.find(child => {
|
|
566
|
-
return AbstractNode.isAbstract(child) && child.end >= rightNodeCount && child.start < rightNodeCount;
|
|
567
|
-
});
|
|
568
|
-
if (abstract) {
|
|
569
|
-
const path = PlaitBoard.findPath(board, abstract);
|
|
570
|
-
Transforms.setNode(board, { end: rightNodeCount - 1 }, path);
|
|
571
|
-
}
|
|
572
|
-
};
|
|
573
|
-
const insertAbstract = (board, elements) => {
|
|
574
|
-
let elementGroup = getFirstLevelElement(elements);
|
|
575
|
-
const { parentElements, abstractIncludedGroups } = divideElementByParent(elementGroup);
|
|
576
|
-
abstractIncludedGroups.forEach((group, index) => {
|
|
577
|
-
const groupParent = parentElements[index];
|
|
578
|
-
setAbstractByElements(board, groupParent, group);
|
|
579
|
-
});
|
|
580
|
-
};
|
|
581
|
-
const setAbstractByElements = (board, groupParent, group) => {
|
|
582
|
-
const indexArray = group.map(child => groupParent.children.indexOf(child)).sort((a, b) => a - b);
|
|
583
|
-
const rightNodeCount = groupParent === null || groupParent === void 0 ? void 0 : groupParent.rightNodeCount;
|
|
584
|
-
const start = indexArray[0], end = indexArray[indexArray.length - 1];
|
|
585
|
-
if (isStandardLayout(MindQueries.getLayoutByElement(groupParent)) &&
|
|
586
|
-
rightNodeCount &&
|
|
587
|
-
start < rightNodeCount &&
|
|
588
|
-
end >= rightNodeCount) {
|
|
589
|
-
const childrenLength = groupParent.children.length;
|
|
590
|
-
const path = [...PlaitBoard.findPath(board, groupParent), childrenLength];
|
|
591
|
-
const leftChildren = indexArray.filter(index => index >= rightNodeCount);
|
|
592
|
-
const rightChildren = indexArray.filter(index => index < rightNodeCount);
|
|
593
|
-
insertAbstractNode(board, path, rightChildren[0], rightChildren[rightChildren.length - 1]);
|
|
594
|
-
insertAbstractNode(board, Path.next(path), leftChildren[0], leftChildren[leftChildren.length - 1]);
|
|
595
|
-
}
|
|
596
|
-
else {
|
|
597
|
-
const path = [...PlaitBoard.findPath(board, groupParent), groupParent.children.length];
|
|
598
|
-
insertAbstractNode(board, path, start, end);
|
|
599
|
-
}
|
|
600
|
-
};
|
|
601
|
-
const insertAbstractNode = (board, path, start, end) => {
|
|
602
|
-
const mindElement = createMindElement('概要', 28, 20, {
|
|
603
|
-
strokeColor: DefaultAbstractNodeStyle.strokeColor,
|
|
604
|
-
strokeWidth: DefaultAbstractNodeStyle.branchWidth,
|
|
605
|
-
branchColor: DefaultAbstractNodeStyle.branchColor,
|
|
606
|
-
branchWidth: DefaultAbstractNodeStyle.branchWidth
|
|
607
|
-
});
|
|
608
|
-
mindElement.start = start;
|
|
609
|
-
mindElement.end = end;
|
|
610
|
-
Transforms.insertNode(board, mindElement, path);
|
|
611
|
-
};
|
|
612
|
-
|
|
613
|
-
const setLayout = (board, layout, path) => {
|
|
614
|
-
correctLogicLayoutNode(board, layout, path);
|
|
615
|
-
const element = PlaitNode.get(board, path);
|
|
616
|
-
if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
|
|
617
|
-
MindTransforms.setAbstractByStandardLayout(board, element);
|
|
618
|
-
}
|
|
619
|
-
Transforms.setNode(board, { layout }, path);
|
|
620
|
-
};
|
|
621
|
-
const correctLogicLayoutNode = (board, layout, path) => {
|
|
622
|
-
var _a;
|
|
623
|
-
const node = PlaitNode.get(board, path);
|
|
624
|
-
if (node && layout) {
|
|
625
|
-
(_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach((value, index) => {
|
|
626
|
-
var _a;
|
|
627
|
-
if (value.layout) {
|
|
628
|
-
if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
|
|
629
|
-
(isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
|
|
630
|
-
Transforms.setNode(board, { layout: null }, [...path, index]);
|
|
631
|
-
}
|
|
632
|
-
if ((_a = value.children) === null || _a === void 0 ? void 0 : _a.length) {
|
|
633
|
-
correctLogicLayoutNode(board, layout, [...path, index]);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
};
|
|
506
|
+
}
|
|
639
507
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const path = PlaitBoard.findPath(board, element);
|
|
650
|
-
Transforms.setNode(board, newElement, path);
|
|
651
|
-
};
|
|
652
|
-
const setTopicSize = (board, element, width, height) => {
|
|
653
|
-
const newElement = {
|
|
654
|
-
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
655
|
-
height: height / board.viewport.zoom
|
|
656
|
-
};
|
|
657
|
-
const path = PlaitBoard.findPath(board, element);
|
|
658
|
-
Transforms.setNode(board, newElement, path);
|
|
659
|
-
};
|
|
660
|
-
const addEmoji = (board, element, emojiItem) => {
|
|
661
|
-
const emojis = element.data.emojis || [];
|
|
662
|
-
const newEmojis = [...emojis];
|
|
663
|
-
newEmojis.push(emojiItem);
|
|
664
|
-
const newElement = {
|
|
665
|
-
data: { topic: element.data.topic, emojis: newEmojis }
|
|
666
|
-
};
|
|
667
|
-
const path = PlaitBoard.findPath(board, element);
|
|
668
|
-
Transforms.setNode(board, newElement, path);
|
|
669
|
-
};
|
|
670
|
-
const removeEmoji = (board, element, emojiItem) => {
|
|
671
|
-
const emojis = element.data.emojis.filter(value => value !== emojiItem);
|
|
672
|
-
const newElement = {
|
|
673
|
-
data: { topic: element.data.topic }
|
|
508
|
+
function getEmojiRectangle(board, element) {
|
|
509
|
+
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
510
|
+
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
511
|
+
const { width, height } = getEmojisWidthHeight(board, element);
|
|
512
|
+
return {
|
|
513
|
+
x,
|
|
514
|
+
y,
|
|
515
|
+
width,
|
|
516
|
+
height
|
|
674
517
|
};
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
518
|
+
}
|
|
519
|
+
function getEmojiForeignRectangle(board, element) {
|
|
520
|
+
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
521
|
+
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
522
|
+
const { width, height } = getEmojisWidthHeight(board, element);
|
|
523
|
+
return {
|
|
524
|
+
x,
|
|
525
|
+
y,
|
|
526
|
+
width,
|
|
527
|
+
height: height + NodeSpace.getEmojiTopSpace(element) * 2
|
|
684
528
|
};
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
}
|
|
689
|
-
return value;
|
|
690
|
-
});
|
|
691
|
-
newElement.data.emojis = newEmojis;
|
|
692
|
-
const path = PlaitBoard.findPath(board, element);
|
|
693
|
-
Transforms.setNode(board, newElement, path);
|
|
529
|
+
}
|
|
530
|
+
const isHitEmojis = (board, element, point) => {
|
|
531
|
+
return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
|
|
694
532
|
};
|
|
695
533
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
}
|
|
534
|
+
function getTopicRectangleByNode(board, node) {
|
|
535
|
+
let nodeRectangle = getRectangleByNode(node);
|
|
536
|
+
return getTopicRectangleByElement(board, nodeRectangle, node.origin);
|
|
537
|
+
}
|
|
538
|
+
function getTopicRectangleByElement(board, nodeRectangle, element) {
|
|
539
|
+
const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
|
|
540
|
+
const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
|
|
541
|
+
const width = Math.ceil(element.width);
|
|
542
|
+
const height = Math.ceil(element.height);
|
|
543
|
+
return { height, width, x, y };
|
|
544
|
+
}
|
|
707
545
|
|
|
708
|
-
function
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
let parent = MindElement.findParent(element);
|
|
712
|
-
while (parent) {
|
|
713
|
-
branch = root;
|
|
714
|
-
root = parent;
|
|
715
|
-
parent = MindElement.findParent(parent);
|
|
716
|
-
}
|
|
717
|
-
return { root, branch };
|
|
546
|
+
function enterNodeEditing(element) {
|
|
547
|
+
const component = PlaitElement.getComponent(element);
|
|
548
|
+
component.startEditText(false, false);
|
|
718
549
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
return p + getChildrenCount(c);
|
|
722
|
-
}, 0);
|
|
723
|
-
return count + element.children.length;
|
|
724
|
-
};
|
|
725
|
-
const isChildElement = (origin, child) => {
|
|
726
|
-
let parent = MindElement.findParent(child);
|
|
727
|
-
while (parent) {
|
|
728
|
-
if (parent === origin) {
|
|
729
|
-
return true;
|
|
730
|
-
}
|
|
731
|
-
parent = MindElement.findParent(parent);
|
|
732
|
-
}
|
|
733
|
-
return false;
|
|
734
|
-
};
|
|
735
|
-
const getFirstLevelElement = (elements) => {
|
|
736
|
-
let result = [];
|
|
737
|
-
elements.forEach(element => {
|
|
738
|
-
const isChild = elements.some(node => {
|
|
739
|
-
return isChildElement(node, element);
|
|
740
|
-
});
|
|
741
|
-
if (!isChild) {
|
|
742
|
-
result.push(element);
|
|
743
|
-
}
|
|
744
|
-
});
|
|
745
|
-
return result;
|
|
746
|
-
};
|
|
747
|
-
const isChildRight = (node, child) => {
|
|
748
|
-
return node.x < child.x;
|
|
749
|
-
};
|
|
750
|
-
const isChildUp = (node, child) => {
|
|
751
|
-
return node.y > child.y;
|
|
752
|
-
};
|
|
753
|
-
const copyNewNode = (node) => {
|
|
754
|
-
const newNode = Object.assign({}, node);
|
|
755
|
-
newNode.id = idCreator();
|
|
756
|
-
newNode.children = [];
|
|
757
|
-
for (const childNode of node.children) {
|
|
758
|
-
newNode.children.push(copyNewNode(childNode));
|
|
759
|
-
}
|
|
760
|
-
return newNode;
|
|
761
|
-
};
|
|
762
|
-
const transformRootToNode = (board, node) => {
|
|
550
|
+
|
|
551
|
+
const adjustRootToNode = (board, node) => {
|
|
763
552
|
const newNode = Object.assign({}, node);
|
|
764
553
|
delete newNode.isRoot;
|
|
765
554
|
delete newNode.rightNodeCount;
|
|
@@ -773,13 +562,13 @@ const transformRootToNode = (board, node) => {
|
|
|
773
562
|
}
|
|
774
563
|
return newNode;
|
|
775
564
|
};
|
|
776
|
-
const
|
|
565
|
+
const adjustAbstractToNode = (node) => {
|
|
777
566
|
const newNode = Object.assign({}, node);
|
|
778
567
|
delete newNode.start;
|
|
779
568
|
delete newNode.end;
|
|
780
569
|
return newNode;
|
|
781
570
|
};
|
|
782
|
-
const
|
|
571
|
+
const adjustNodeToRoot = (board, node) => {
|
|
783
572
|
var _a;
|
|
784
573
|
const newElement = Object.assign({}, node);
|
|
785
574
|
let text = Node.string(newElement.data.topic);
|
|
@@ -796,40 +585,14 @@ const transformNodeToRoot = (board, node) => {
|
|
|
796
585
|
newElement.height = height;
|
|
797
586
|
return Object.assign(Object.assign({}, newElement), { layout: (_a = newElement.layout) !== null && _a !== void 0 ? _a : MindLayoutType.right, isCollapsed: false, isRoot: true, type: 'mindmap' });
|
|
798
587
|
};
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
return str;
|
|
808
|
-
};
|
|
809
|
-
const changeRightNodeCount = (board, parentPath, changeNumber) => {
|
|
810
|
-
const _rightNodeCount = board.children[parentPath[0]].rightNodeCount;
|
|
811
|
-
Transforms.setNode(board, {
|
|
812
|
-
rightNodeCount: changeNumber >= 0
|
|
813
|
-
? _rightNodeCount + changeNumber
|
|
814
|
-
: _rightNodeCount + changeNumber < 0
|
|
815
|
-
? 0
|
|
816
|
-
: _rightNodeCount + changeNumber
|
|
817
|
-
}, parentPath);
|
|
818
|
-
};
|
|
819
|
-
const shouldChangeRightNodeCount = (selectedElement) => {
|
|
820
|
-
const parentElement = MindElement.findParent(selectedElement);
|
|
821
|
-
if (parentElement) {
|
|
822
|
-
const nodeIndex = parentElement.children.findIndex(item => item.id === selectedElement.id);
|
|
823
|
-
if (parentElement.isRoot &&
|
|
824
|
-
getRootLayout(parentElement) === MindLayoutType.standard &&
|
|
825
|
-
parentElement.rightNodeCount &&
|
|
826
|
-
nodeIndex <= parentElement.rightNodeCount - 1) {
|
|
827
|
-
return true;
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
return false;
|
|
588
|
+
|
|
589
|
+
const createEmptyMind = (board, point) => {
|
|
590
|
+
const element = createMindElement('', 0, 0, { layout: MindLayoutType.right });
|
|
591
|
+
const rootElement = adjustNodeToRoot(board, element);
|
|
592
|
+
rootElement.points = [point];
|
|
593
|
+
return rootElement;
|
|
831
594
|
};
|
|
832
|
-
const
|
|
595
|
+
const createDefaultMind = (point, rightNodeCount, layout) => {
|
|
833
596
|
const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle, layout });
|
|
834
597
|
root.rightNodeCount = rightNodeCount;
|
|
835
598
|
root.isRoot = true;
|
|
@@ -878,6 +641,83 @@ const createMindElement = (text, width, height, options) => {
|
|
|
878
641
|
}
|
|
879
642
|
return newElement;
|
|
880
643
|
};
|
|
644
|
+
|
|
645
|
+
const getChildrenCount = (element) => {
|
|
646
|
+
const count = element.children.reduce((p, c) => {
|
|
647
|
+
return p + getChildrenCount(c);
|
|
648
|
+
}, 0);
|
|
649
|
+
return count + element.children.length;
|
|
650
|
+
};
|
|
651
|
+
const isChildElement = (origin, child) => {
|
|
652
|
+
let parent = MindElement.findParent(child);
|
|
653
|
+
while (parent) {
|
|
654
|
+
if (parent === origin) {
|
|
655
|
+
return true;
|
|
656
|
+
}
|
|
657
|
+
parent = MindElement.findParent(parent);
|
|
658
|
+
}
|
|
659
|
+
return false;
|
|
660
|
+
};
|
|
661
|
+
const getFirstLevelElement = (elements) => {
|
|
662
|
+
let result = [];
|
|
663
|
+
elements.forEach(element => {
|
|
664
|
+
const isChild = elements.some(node => {
|
|
665
|
+
return isChildElement(node, element);
|
|
666
|
+
});
|
|
667
|
+
if (!isChild) {
|
|
668
|
+
result.push(element);
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
return result;
|
|
672
|
+
};
|
|
673
|
+
const isChildRight = (node, child) => {
|
|
674
|
+
return node.x < child.x;
|
|
675
|
+
};
|
|
676
|
+
const isChildUp = (node, child) => {
|
|
677
|
+
return node.y > child.y;
|
|
678
|
+
};
|
|
679
|
+
const copyNewNode = (node) => {
|
|
680
|
+
const newNode = Object.assign({}, node);
|
|
681
|
+
newNode.id = idCreator();
|
|
682
|
+
newNode.children = [];
|
|
683
|
+
for (const childNode of node.children) {
|
|
684
|
+
newNode.children.push(copyNewNode(childNode));
|
|
685
|
+
}
|
|
686
|
+
return newNode;
|
|
687
|
+
};
|
|
688
|
+
const extractNodesText = (node) => {
|
|
689
|
+
let str = '';
|
|
690
|
+
if (node) {
|
|
691
|
+
str += Node.string(node.data.topic.children[0]) + ' ';
|
|
692
|
+
for (const childNode of node.children) {
|
|
693
|
+
str += extractNodesText(childNode);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
return str;
|
|
697
|
+
};
|
|
698
|
+
const changeRightNodeCount = (board, parentPath, changeNumber) => {
|
|
699
|
+
const _rightNodeCount = board.children[parentPath[0]].rightNodeCount;
|
|
700
|
+
Transforms.setNode(board, {
|
|
701
|
+
rightNodeCount: changeNumber >= 0
|
|
702
|
+
? _rightNodeCount + changeNumber
|
|
703
|
+
: _rightNodeCount + changeNumber < 0
|
|
704
|
+
? 0
|
|
705
|
+
: _rightNodeCount + changeNumber
|
|
706
|
+
}, parentPath);
|
|
707
|
+
};
|
|
708
|
+
const isInRightBranchOfStandardLayout = (selectedElement) => {
|
|
709
|
+
const parentElement = MindElement.findParent(selectedElement);
|
|
710
|
+
if (parentElement) {
|
|
711
|
+
const nodeIndex = parentElement.children.findIndex(item => item.id === selectedElement.id);
|
|
712
|
+
if (parentElement.isRoot &&
|
|
713
|
+
getRootLayout(parentElement) === MindLayoutType.standard &&
|
|
714
|
+
parentElement.rightNodeCount &&
|
|
715
|
+
nodeIndex <= parentElement.rightNodeCount - 1) {
|
|
716
|
+
return true;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return false;
|
|
720
|
+
};
|
|
881
721
|
// layoutLevel 用来表示插入兄弟节点还是子节点
|
|
882
722
|
const insertMindElement = (board, inheritNode, path) => {
|
|
883
723
|
let fill, strokeColor, strokeWidth, shape = MindElementShape.roundRectangle;
|
|
@@ -902,25 +742,6 @@ const findLastChild = (child) => {
|
|
|
902
742
|
}
|
|
903
743
|
return result;
|
|
904
744
|
};
|
|
905
|
-
const deleteSelectedELements = (board, selectedElements) => {
|
|
906
|
-
const deletableElements = getFirstLevelElement(selectedElements).reverse();
|
|
907
|
-
const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
|
|
908
|
-
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
909
|
-
//翻转,从下到上修改,防止找不到 path
|
|
910
|
-
deletableElements
|
|
911
|
-
.map(element => {
|
|
912
|
-
const path = PlaitBoard.findPath(board, element);
|
|
913
|
-
return () => {
|
|
914
|
-
if (shouldChangeRightNodeCount(element)) {
|
|
915
|
-
changeRightNodeCount(board, path.slice(0, 1), -1);
|
|
916
|
-
}
|
|
917
|
-
Transforms.removeNode(board, path);
|
|
918
|
-
};
|
|
919
|
-
})
|
|
920
|
-
.forEach(action => {
|
|
921
|
-
action();
|
|
922
|
-
});
|
|
923
|
-
};
|
|
924
745
|
const divideElementByParent = (elements) => {
|
|
925
746
|
const abstractIncludedGroups = [];
|
|
926
747
|
const parentElements = [];
|
|
@@ -1016,467 +837,123 @@ function isVirtualKey(e) {
|
|
|
1016
837
|
return isCapsLock || isMod || isAlt || isArrow || isShift || isTab || isEsc || isF;
|
|
1017
838
|
}
|
|
1018
839
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
if (!isChildRight(node, child)) {
|
|
1025
|
-
beginNode = child;
|
|
1026
|
-
endNode = node;
|
|
1027
|
-
}
|
|
1028
|
-
beginX = beginNode.x + beginNode.width - beginNode.hGap;
|
|
1029
|
-
beginY = beginNode.y + beginNode.height / 2;
|
|
1030
|
-
endX = endNode.x + endNode.hGap;
|
|
1031
|
-
endY = endNode.y + endNode.height / 2;
|
|
1032
|
-
if (node.parent &&
|
|
1033
|
-
isIndentedLayout(MindQueries.getLayoutByElement((_a = node.parent) === null || _a === void 0 ? void 0 : _a.origin)) &&
|
|
1034
|
-
getShapeByElement(board, node.origin) === MindElementShape.underline) {
|
|
1035
|
-
if (isChildRight(node, child)) {
|
|
1036
|
-
beginY = node.y + node.height - node.vGap;
|
|
1037
|
-
}
|
|
1038
|
-
else {
|
|
1039
|
-
endY = node.y + node.height - node.vGap;
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
840
|
+
const IS_DRAGGING = new WeakMap();
|
|
841
|
+
const addActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
842
|
+
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
843
|
+
if (isOrigin) {
|
|
844
|
+
activeComponent.g.classList.add('dragging-origin');
|
|
1042
845
|
}
|
|
1043
846
|
else {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
847
|
+
activeComponent.g.classList.add('dragging-child');
|
|
848
|
+
}
|
|
849
|
+
!activeElement.isCollapsed &&
|
|
850
|
+
activeElement.children.forEach(child => {
|
|
851
|
+
addActiveOnDragOrigin(child, false);
|
|
852
|
+
});
|
|
853
|
+
};
|
|
854
|
+
const removeActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
855
|
+
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
856
|
+
if (isOrigin) {
|
|
857
|
+
activeComponent.g.classList.remove('dragging-origin');
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
activeComponent.g.classList.remove('dragging-child');
|
|
1052
861
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
862
|
+
!activeElement.isCollapsed &&
|
|
863
|
+
activeElement.children.forEach(child => {
|
|
864
|
+
removeActiveOnDragOrigin(child, false);
|
|
865
|
+
});
|
|
866
|
+
};
|
|
867
|
+
const isDragging = (board) => {
|
|
868
|
+
return !!IS_DRAGGING.get(board);
|
|
869
|
+
};
|
|
870
|
+
const setIsDragging = (board, state) => {
|
|
871
|
+
IS_DRAGGING.set(board, state);
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
*
|
|
876
|
+
* @param targetNode
|
|
877
|
+
* @param centerPoint
|
|
878
|
+
* @returns DetectResult[] | null
|
|
879
|
+
*/
|
|
880
|
+
const directionCorrector = (board, node, detectResults) => {
|
|
881
|
+
if (!node.origin.isRoot && !AbstractNode.isAbstract(node.origin)) {
|
|
882
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, node === null || node === void 0 ? void 0 : node.parent.origin);
|
|
883
|
+
if (isStandardLayout(parentLayout)) {
|
|
884
|
+
const idx = node.parent.children.findIndex(x => x === node);
|
|
885
|
+
const isLeft = idx >= (node.parent.origin.rightNodeCount || 0);
|
|
886
|
+
return getAllowedDirection(detectResults, [isLeft ? 'right' : 'left']);
|
|
1058
887
|
}
|
|
1059
|
-
if (
|
|
1060
|
-
|
|
888
|
+
if (isLeftLayout(parentLayout)) {
|
|
889
|
+
return getAllowedDirection(detectResults, ['right']);
|
|
1061
890
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
if (layout === MindLayoutType.right || isStandardLayout(layout)) {
|
|
1065
|
-
beginX += strokeWidth;
|
|
891
|
+
if (isRightLayout(parentLayout)) {
|
|
892
|
+
return getAllowedDirection(detectResults, ['left']);
|
|
1066
893
|
}
|
|
1067
|
-
if (
|
|
1068
|
-
|
|
894
|
+
if (parentLayout === MindLayoutType.upward) {
|
|
895
|
+
return getAllowedDirection(detectResults, ['bottom']);
|
|
1069
896
|
}
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
let curve = [
|
|
1073
|
-
[beginX, beginY],
|
|
1074
|
-
[beginX + (beginNode.hGap + endNode.hGap) / 3, beginY],
|
|
1075
|
-
[endX - (beginNode.hGap + endNode.hGap) / 2, endY],
|
|
1076
|
-
[endX, endY]
|
|
1077
|
-
];
|
|
1078
|
-
const shape = getShapeByElement(board, child.origin);
|
|
1079
|
-
if (!node.origin.isRoot) {
|
|
1080
|
-
if (node.x > child.x) {
|
|
1081
|
-
curve = [
|
|
1082
|
-
[beginX, beginY],
|
|
1083
|
-
[beginX + (beginNode.hGap + endNode.hGap) / 3, beginY],
|
|
1084
|
-
[endX - (beginNode.hGap + endNode.hGap) / 2, endY],
|
|
1085
|
-
[endX - 12, endY]
|
|
1086
|
-
];
|
|
1087
|
-
const line = [
|
|
1088
|
-
[endX - 12, endY],
|
|
1089
|
-
[endX - 12, endY],
|
|
1090
|
-
[endX, endY]
|
|
1091
|
-
];
|
|
1092
|
-
curve = [...curve, ...line];
|
|
1093
|
-
}
|
|
1094
|
-
else {
|
|
1095
|
-
curve = [
|
|
1096
|
-
[beginX + 12, beginY],
|
|
1097
|
-
[beginX + (beginNode.hGap + endNode.hGap) / 2, beginY],
|
|
1098
|
-
[endX - (beginNode.hGap + endNode.hGap) / 3, endY],
|
|
1099
|
-
[endX, endY]
|
|
1100
|
-
];
|
|
1101
|
-
const line = [
|
|
1102
|
-
[beginX, beginY],
|
|
1103
|
-
[beginX + 12, beginY],
|
|
1104
|
-
[beginX + 12, beginY]
|
|
1105
|
-
];
|
|
1106
|
-
curve = [...line, ...curve];
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
if (needDrawUnderline && shape === MindElementShape.underline) {
|
|
1110
|
-
if (child.left) {
|
|
1111
|
-
const underline = [
|
|
1112
|
-
[beginX - (beginNode.width - beginNode.hGap * 2), beginY],
|
|
1113
|
-
[beginX - (beginNode.width - beginNode.hGap * 2), beginY],
|
|
1114
|
-
[beginX - (beginNode.width - beginNode.hGap * 2), beginY]
|
|
1115
|
-
];
|
|
1116
|
-
curve = [...underline, ...curve];
|
|
1117
|
-
}
|
|
1118
|
-
else {
|
|
1119
|
-
const underline = [
|
|
1120
|
-
[endX + (endNode.width - endNode.hGap * 2), endY],
|
|
1121
|
-
[endX + (endNode.width - endNode.hGap * 2), endY],
|
|
1122
|
-
[endX + (endNode.width - endNode.hGap * 2), endY]
|
|
1123
|
-
];
|
|
1124
|
-
curve = [...curve, ...underline];
|
|
1125
|
-
}
|
|
897
|
+
if (parentLayout === MindLayoutType.downward) {
|
|
898
|
+
return getAllowedDirection(detectResults, ['top']);
|
|
1126
899
|
}
|
|
1127
|
-
const points = pointsOnBezierCurves(curve);
|
|
1128
|
-
return PlaitBoard.getRoughSVG(board).curve(points, { stroke, strokeWidth });
|
|
1129
900
|
}
|
|
1130
901
|
else {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
[beginX, beginY + (beginNode.vGap + endNode.vGap) / 2],
|
|
1142
|
-
[endX, endY - (beginNode.vGap + endNode.vGap) / 2],
|
|
1143
|
-
[endX, endY - 12]
|
|
1144
|
-
];
|
|
1145
|
-
const line = [
|
|
1146
|
-
[endX, endY - 12],
|
|
1147
|
-
[endX, endY - 12],
|
|
1148
|
-
[endX, endY]
|
|
1149
|
-
];
|
|
1150
|
-
curve = [...curve, ...line];
|
|
1151
|
-
}
|
|
1152
|
-
else {
|
|
1153
|
-
curve = [
|
|
1154
|
-
[beginX, beginY + 12],
|
|
1155
|
-
[beginX, beginY + (beginNode.vGap + endNode.vGap) / 2],
|
|
1156
|
-
[endX, endY - (beginNode.vGap + endNode.vGap) / 2],
|
|
1157
|
-
[endX, endY]
|
|
1158
|
-
];
|
|
1159
|
-
const line = [
|
|
1160
|
-
[beginX, beginY],
|
|
1161
|
-
[beginX, beginY + 12],
|
|
1162
|
-
[beginX, beginY + 12]
|
|
1163
|
-
];
|
|
1164
|
-
curve = [...line, ...curve];
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
const points = pointsOnBezierCurves(curve);
|
|
1168
|
-
return PlaitBoard.getRoughSVG(board).curve(points, { stroke, strokeWidth });
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
const drawPlaceholderDropNodeG = (board, dropTarget, fakeDropNodeG) => {
|
|
1173
|
-
const targetComponent = PlaitElement.getComponent(dropTarget.target);
|
|
1174
|
-
const targetRect = getRectangleByNode(targetComponent.node);
|
|
1175
|
-
if (dropTarget.detectResult && ['right', 'left'].includes(dropTarget.detectResult)) {
|
|
1176
|
-
drawStraightDropNodeG(board, targetRect, dropTarget.detectResult, targetComponent, fakeDropNodeG);
|
|
1177
|
-
}
|
|
1178
|
-
const targetParent = MindElement.findParent(targetComponent.element);
|
|
1179
|
-
if (targetParent && dropTarget.detectResult && ['top', 'bottom'].includes(dropTarget.detectResult)) {
|
|
1180
|
-
const parentComponent = PlaitElement.getComponent(targetParent);
|
|
1181
|
-
const targetIndex = parentComponent.node.origin.children.indexOf(targetComponent.node.origin);
|
|
1182
|
-
drawCurvePlaceholderDropNodeG(board, targetRect, dropTarget.detectResult, targetIndex, targetComponent, parentComponent, fakeDropNodeG);
|
|
1183
|
-
}
|
|
1184
|
-
};
|
|
1185
|
-
const drawCurvePlaceholderDropNodeG = (board, targetRect, detectResult, targetIndex, targetComponent, parentComponent, fakeDropNodeG) => {
|
|
1186
|
-
const parentNodeLayout = MindQueries.getCorrectLayoutByElement(board, parentComponent.node.origin);
|
|
1187
|
-
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.parent.origin);
|
|
1188
|
-
const strokeWidth = targetComponent.node.origin.branchWidth ? targetComponent.node.origin.branchWidth : STROKE_WIDTH;
|
|
1189
|
-
let fakeX = targetComponent.node.x, fakeY = targetRect.y - 30, fakeRectangleStartX = targetRect.x, fakeRectangleEndX = targetRect.x + 30, fakeRectangleStartY = fakeY, fakeRectangleEndY = fakeRectangleStartY + 12, width = 30;
|
|
1190
|
-
if (isLeftLayout(layout)) {
|
|
1191
|
-
fakeX = targetComponent.node.x + targetComponent.node.width - 30;
|
|
1192
|
-
fakeRectangleStartX = targetRect.x + targetRect.width - 30;
|
|
1193
|
-
fakeRectangleEndX = targetRect.x + targetRect.width;
|
|
1194
|
-
}
|
|
1195
|
-
if (isHorizontalLogicLayout(parentNodeLayout)) {
|
|
1196
|
-
fakeY = getHorizontalFakeY(detectResult, targetIndex, parentComponent.node, targetRect, layout, fakeY);
|
|
1197
|
-
if (isStandardLayout(parentNodeLayout)) {
|
|
1198
|
-
const rightNodeCount = parentComponent.node.origin.rightNodeCount || 0;
|
|
1199
|
-
const idx = parentComponent.node.children.findIndex(x => x === targetComponent.node);
|
|
1200
|
-
const isLeft = idx >= rightNodeCount;
|
|
1201
|
-
// 标准布局的左,需要调整 x
|
|
1202
|
-
if (isLeft) {
|
|
1203
|
-
fakeX = targetComponent.node.x + targetComponent.node.width - 30;
|
|
1204
|
-
fakeRectangleStartX = targetRect.x + targetRect.width - 30;
|
|
1205
|
-
fakeRectangleEndX = targetRect.x + targetRect.width;
|
|
1206
|
-
}
|
|
1207
|
-
const isLeftFirst = idx === rightNodeCount;
|
|
1208
|
-
const isRightLast = idx === rightNodeCount - 1;
|
|
1209
|
-
// 拖拽至左第一个节点的情况
|
|
1210
|
-
if (detectResult === 'top' && isLeftFirst) {
|
|
1211
|
-
fakeY = targetRect.y - targetRect.height;
|
|
1212
|
-
}
|
|
1213
|
-
if (detectResult === 'bottom' && isRightLast) {
|
|
1214
|
-
fakeY = targetRect.y + targetRect.height + 30;
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
fakeRectangleStartY = fakeY;
|
|
1218
|
-
fakeRectangleEndY = fakeRectangleStartY + 12;
|
|
1219
|
-
}
|
|
1220
|
-
if (isVerticalLogicLayout(layout)) {
|
|
1221
|
-
parentComponent = targetComponent;
|
|
1222
|
-
targetComponent = PlaitElement.getComponent(MindElement.getParent(targetComponent.element));
|
|
1223
|
-
fakeX = parentComponent.node.x;
|
|
1224
|
-
width = parentComponent.node.width;
|
|
1225
|
-
const vGap = BASE * 6 + strokeWidth;
|
|
1226
|
-
if (isTopLayout(layout) && detectResult === 'top') {
|
|
1227
|
-
fakeY = targetRect.y - vGap;
|
|
1228
|
-
fakeRectangleStartY = fakeY - vGap + strokeWidth;
|
|
1229
|
-
}
|
|
1230
|
-
if (isBottomLayout(layout) && detectResult === 'bottom') {
|
|
1231
|
-
fakeY = targetRect.y + targetRect.height + vGap;
|
|
1232
|
-
fakeRectangleStartY = fakeY + vGap - strokeWidth;
|
|
1233
|
-
}
|
|
1234
|
-
fakeRectangleStartX = fakeX + Math.ceil(parentComponent.node.width / 2) - parentComponent.node.hGap - Math.ceil(strokeWidth / 2);
|
|
1235
|
-
fakeRectangleEndX = fakeRectangleStartX + 30;
|
|
1236
|
-
fakeRectangleEndY = fakeRectangleStartY + 12;
|
|
1237
|
-
}
|
|
1238
|
-
if (isIndentedLayout(layout)) {
|
|
1239
|
-
// 偏移一个 Gap
|
|
902
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node === null || node === void 0 ? void 0 : node.origin);
|
|
903
|
+
if (isStandardLayout(layout)) {
|
|
904
|
+
return getAllowedDirection(detectResults, ['top', 'bottom']);
|
|
905
|
+
}
|
|
906
|
+
if (layout === MindLayoutType.upward) {
|
|
907
|
+
return getAllowedDirection(detectResults, ['left', 'right', 'bottom']);
|
|
908
|
+
}
|
|
909
|
+
if (layout === MindLayoutType.downward) {
|
|
910
|
+
return getAllowedDirection(detectResults, ['left', 'right', 'top']);
|
|
911
|
+
}
|
|
1240
912
|
if (isLeftLayout(layout)) {
|
|
1241
|
-
|
|
913
|
+
return getAllowedDirection(detectResults, ['right', 'top', 'bottom']);
|
|
1242
914
|
}
|
|
1243
915
|
if (isRightLayout(layout)) {
|
|
1244
|
-
|
|
1245
|
-
}
|
|
1246
|
-
if (isTopLayout(layout)) {
|
|
1247
|
-
if (detectResult === 'top') {
|
|
1248
|
-
const isLastNode = targetIndex === parentComponent.node.origin.children.length - 1;
|
|
1249
|
-
if (isLastNode) {
|
|
1250
|
-
fakeY = targetRect.y - targetRect.height - BASE;
|
|
1251
|
-
}
|
|
1252
|
-
else {
|
|
1253
|
-
const nextComponent = PlaitElement.getComponent(parentComponent.node.origin.children[targetIndex + 1]);
|
|
1254
|
-
const nextRect = getRectangleByNode(nextComponent.node);
|
|
1255
|
-
fakeY = targetRect.y - Math.abs((nextRect.y + nextRect.height - targetRect.y) / 2);
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
if (detectResult === 'bottom') {
|
|
1259
|
-
const isFirstNode = targetIndex === 0;
|
|
1260
|
-
if (isFirstNode) {
|
|
1261
|
-
const parentRect = getRectangleByNode(parentComponent.node);
|
|
1262
|
-
fakeY = parentRect.y - parentRect.height / 2 - BASE;
|
|
1263
|
-
}
|
|
1264
|
-
else {
|
|
1265
|
-
const previousComponent = PlaitElement.getComponent(parentComponent.node.origin.children[targetIndex + 1]);
|
|
1266
|
-
const previousRect = getRectangleByNode(previousComponent.node);
|
|
1267
|
-
fakeY = previousRect.y - Math.abs((targetRect.y + targetRect.height - previousRect.y) / 2);
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
916
|
+
return getAllowedDirection(detectResults, ['left', 'top', 'bottom']);
|
|
1270
917
|
}
|
|
1271
|
-
fakeRectangleStartX = fakeX;
|
|
1272
|
-
fakeRectangleEndX = fakeRectangleStartX + 30;
|
|
1273
|
-
fakeRectangleStartY = fakeY;
|
|
1274
|
-
fakeRectangleEndY = fakeRectangleStartY + 12;
|
|
1275
918
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
fill: PRIMARY_COLOR,
|
|
1286
|
-
fillStyle: 'solid'
|
|
919
|
+
return null;
|
|
920
|
+
};
|
|
921
|
+
const getAllowedDirection = (detectResults, illegalDirections) => {
|
|
922
|
+
const directions = detectResults;
|
|
923
|
+
illegalDirections.forEach(item => {
|
|
924
|
+
const bottomDirectionIndex = directions.findIndex(direction => direction === item);
|
|
925
|
+
if (bottomDirectionIndex !== -1) {
|
|
926
|
+
directions.splice(bottomDirectionIndex, 1);
|
|
927
|
+
}
|
|
1287
928
|
});
|
|
1288
|
-
|
|
1289
|
-
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.appendChild(fakeRectangleG);
|
|
929
|
+
return directions.length ? directions : null;
|
|
1290
930
|
};
|
|
1291
|
-
const
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
let endLinePoint = x + width + lineLength;
|
|
1296
|
-
let startRectanglePointX = x + width + lineLength;
|
|
1297
|
-
let endRectanglePointX = x + lineLength + width + 30;
|
|
1298
|
-
let startRectanglePointY = y + height / 2 - 6;
|
|
1299
|
-
let endRectanglePointY = y + height / 2 - 6 + 12;
|
|
1300
|
-
if (detectResult === 'left') {
|
|
1301
|
-
startLinePoint = x - lineLength;
|
|
1302
|
-
endLinePoint = x;
|
|
1303
|
-
startRectanglePointX = x - lineLength - 30;
|
|
1304
|
-
endRectanglePointX = x - lineLength;
|
|
1305
|
-
}
|
|
1306
|
-
let fakeY = targetComponent.node.y;
|
|
1307
|
-
let fakeX = targetRect.x;
|
|
1308
|
-
const strokeWidth = targetComponent.node.origin.branchWidth ? targetComponent.node.origin.branchWidth : STROKE_WIDTH;
|
|
1309
|
-
const pointOptions = {
|
|
1310
|
-
fakeX,
|
|
1311
|
-
fakeY,
|
|
1312
|
-
x,
|
|
1313
|
-
y,
|
|
1314
|
-
width,
|
|
1315
|
-
height,
|
|
1316
|
-
strokeWidth
|
|
1317
|
-
};
|
|
1318
|
-
const parentLayout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1319
|
-
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1320
|
-
if (!isMixedLayout(parentLayout, layout)) {
|
|
1321
|
-
// 构造一条直线
|
|
1322
|
-
let linePoints = [
|
|
1323
|
-
[startLinePoint, y + height / 2],
|
|
1324
|
-
[endLinePoint, y + height / 2]
|
|
1325
|
-
];
|
|
1326
|
-
if (isIndentedLayout(parentLayout)) {
|
|
1327
|
-
const fakePoint = getIndentedFakePoint(parentLayout, pointOptions);
|
|
1328
|
-
drawIndentNodeG(board, fakeDropNodeG, fakePoint, targetComponent.node);
|
|
931
|
+
const detectDropTarget = (board, detectPoint, dropTarget, activeElements) => {
|
|
932
|
+
let detectResult = null;
|
|
933
|
+
depthFirstRecursion(board, element => {
|
|
934
|
+
if (!MindElement.isMindElement(board, element) || detectResult) {
|
|
1329
935
|
return;
|
|
1330
936
|
}
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
* 1. 移动到左侧:当前节点 startX - 偏移值,偏移值计算如下:
|
|
1336
|
-
* a. 第一个节点: 固定值(来源于 getMainAxle,第二级节点:BASE * 8,其他 BASE * 3 + strokeWidth / 2);
|
|
1337
|
-
* b. 第二个节点到最后一个节点之间:上一个节点到当前节点间距的一半((当前节点 startX - 上一个节点的 endX) / 2),endX = 当前节点的 startX + width;
|
|
1338
|
-
* 2. 移动到右侧:当前节点 x + width + 偏移值,偏移值计算如下:
|
|
1339
|
-
* a. 第二个节点到最后一个节点之间的右侧:当前节点到下一个节点间距的一半((下一个节点 startX - 当前节点的 endX) / 2),endX = 当前节点的 startX + width;
|
|
1340
|
-
* b. 最后一个节点的右侧:固定值(来源于 getMainAxle,第二级节点:BASE * 8,其他 BASE * 3 + strokeWidth / 2);
|
|
1341
|
-
*/
|
|
1342
|
-
fakeY = targetComponent.node.y;
|
|
1343
|
-
const parentComponent = PlaitElement.getComponent(MindElement.getParent(targetComponent.element));
|
|
1344
|
-
const targetIndex = parentComponent.node.origin.children.indexOf(targetComponent.node.origin);
|
|
1345
|
-
if (detectResult === 'left') {
|
|
1346
|
-
let offsetX = 0;
|
|
1347
|
-
const isFirstNode = targetIndex === 0;
|
|
1348
|
-
if (isFirstNode) {
|
|
1349
|
-
offsetX = parentComponent.node.origin.isRoot ? BASE * 8 : BASE * 3 + strokeWidth / 2;
|
|
1350
|
-
}
|
|
1351
|
-
else {
|
|
1352
|
-
const previousComponent = PlaitElement.getComponent(parentComponent.node.origin.children[targetIndex - 1]);
|
|
1353
|
-
const previousRect = getRectangleByNode(previousComponent.node);
|
|
1354
|
-
const space = targetRect.x - (previousRect.x + previousRect.width);
|
|
1355
|
-
offsetX = space / 2;
|
|
1356
|
-
}
|
|
1357
|
-
fakeX = targetRect.x - offsetX - width / 2 - Math.ceil(strokeWidth / 2);
|
|
1358
|
-
}
|
|
1359
|
-
if (detectResult === 'right') {
|
|
1360
|
-
let offsetX = 0;
|
|
1361
|
-
const isLastNode = targetIndex === parentComponent.node.origin.children.length - 1;
|
|
1362
|
-
if (isLastNode) {
|
|
1363
|
-
offsetX = parentComponent.node.origin.isRoot ? BASE * 8 : BASE * 3 + strokeWidth / 2;
|
|
1364
|
-
}
|
|
1365
|
-
else {
|
|
1366
|
-
const nextComponent = PlaitElement.getComponent(parentComponent.node.origin.children[targetIndex + 1]);
|
|
1367
|
-
const nextRect = getRectangleByNode(nextComponent.node);
|
|
1368
|
-
const space = nextRect.x - (targetRect.x + targetRect.width);
|
|
1369
|
-
offsetX = space / 2;
|
|
1370
|
-
}
|
|
1371
|
-
fakeX = targetRect.x + width + offsetX - width / 2 - Math.ceil(strokeWidth / 2);
|
|
1372
|
-
}
|
|
1373
|
-
startRectanglePointX = fakeX;
|
|
1374
|
-
if (isTopLayout(parentLayout)) {
|
|
1375
|
-
// 因为矩形是从左上角为起点向下画的,所以需要向上偏移一个矩形的高度(-12)
|
|
1376
|
-
startRectanglePointY = fakeY + height + targetComponent.node.vGap - 12;
|
|
1377
|
-
}
|
|
1378
|
-
if (isBottomLayout(parentLayout)) {
|
|
1379
|
-
startRectanglePointY = fakeY + targetComponent.node.vGap;
|
|
1380
|
-
}
|
|
1381
|
-
endRectanglePointX = startRectanglePointX + 30;
|
|
1382
|
-
endRectanglePointY = startRectanglePointY + 12;
|
|
1383
|
-
const fakeNode = Object.assign(Object.assign({}, targetComponent.node), { x: fakeX, y: fakeY, width: 30 });
|
|
1384
|
-
const linkSVGG = drawLink(board, parentComponent.node, fakeNode, PRIMARY_COLOR, false, false);
|
|
1385
|
-
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.appendChild(linkSVGG);
|
|
1386
|
-
}
|
|
937
|
+
const node = MindElement.getNode(element);
|
|
938
|
+
const directions = directionDetector(node, detectPoint);
|
|
939
|
+
if (directions) {
|
|
940
|
+
detectResult = directionCorrector(board, node, directions);
|
|
1387
941
|
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
942
|
+
dropTarget = null;
|
|
943
|
+
const isValid = activeElements.every(element => isValidTarget(element, node.origin));
|
|
944
|
+
if (detectResult && isValid) {
|
|
945
|
+
dropTarget = { target: node.origin, detectResult: detectResult[0] };
|
|
1391
946
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
strokeWidth: 2,
|
|
1396
|
-
fill: PRIMARY_COLOR,
|
|
1397
|
-
fillStyle: 'solid'
|
|
1398
|
-
});
|
|
1399
|
-
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.appendChild(fakeRectangleG);
|
|
1400
|
-
}
|
|
1401
|
-
else {
|
|
1402
|
-
// 混合布局画线逻辑
|
|
1403
|
-
if (isHorizontalLogicLayout(parentLayout)) {
|
|
1404
|
-
if (isIndentedLayout(layout)) {
|
|
1405
|
-
const fakePoint = getIndentedFakePoint(layout, pointOptions);
|
|
1406
|
-
drawIndentNodeG(board, fakeDropNodeG, fakePoint, targetComponent.node);
|
|
1407
|
-
return;
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
};
|
|
1412
|
-
const getHorizontalFakeY = (detectResult, targetIndex, parentNode, targetRect, layout, fakeY) => {
|
|
1413
|
-
const childrenLength = getNonAbstractChildren(parentNode).length;
|
|
1414
|
-
if (detectResult === 'top') {
|
|
1415
|
-
if (targetIndex === 0 && isTopLayout(layout)) {
|
|
1416
|
-
fakeY = targetRect.y + targetRect.height;
|
|
1417
|
-
}
|
|
1418
|
-
if (targetIndex > 0) {
|
|
1419
|
-
const previousComponent = PlaitElement.getComponent(parentNode.origin.children[targetIndex - 1]);
|
|
1420
|
-
const previousRect = getRectangleByNode(previousComponent.node);
|
|
1421
|
-
const topY = previousRect.y + previousRect.height;
|
|
1422
|
-
fakeY = topY + (targetRect.y - topY) / 5;
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
if (detectResult === 'bottom') {
|
|
1426
|
-
fakeY = targetRect.y + targetRect.height + 30;
|
|
1427
|
-
if (targetIndex < childrenLength - 1) {
|
|
1428
|
-
const nextComponent = PlaitElement.getComponent(parentNode.origin.children[targetIndex + 1]);
|
|
1429
|
-
const nextRect = getRectangleByNode(nextComponent.node);
|
|
1430
|
-
const topY = targetRect.y + targetRect.height;
|
|
1431
|
-
fakeY = topY + (nextRect.y - topY) / 5;
|
|
947
|
+
}, node => {
|
|
948
|
+
if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
|
|
949
|
+
return true;
|
|
1432
950
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
951
|
+
else {
|
|
952
|
+
return false;
|
|
1435
953
|
}
|
|
1436
|
-
}
|
|
1437
|
-
return fakeY;
|
|
1438
|
-
};
|
|
1439
|
-
const getIndentedFakePoint = (layout, pointOptions) => {
|
|
1440
|
-
let { fakeX, fakeY, x, y, width, height, strokeWidth } = pointOptions;
|
|
1441
|
-
const hGap = BASE * 4;
|
|
1442
|
-
const vGap = BASE * 6;
|
|
1443
|
-
const offsetX = hGap + width / 2 + strokeWidth;
|
|
1444
|
-
const offsetY = vGap + height / 2 + strokeWidth;
|
|
1445
|
-
if (isLeftLayout(layout)) {
|
|
1446
|
-
fakeX = x - offsetX;
|
|
1447
|
-
}
|
|
1448
|
-
if (isRightLayout(layout)) {
|
|
1449
|
-
fakeX = x + offsetX;
|
|
1450
|
-
}
|
|
1451
|
-
if (isTopLayout(layout)) {
|
|
1452
|
-
fakeY = y - offsetY;
|
|
1453
|
-
}
|
|
1454
|
-
if (isBottomLayout(layout)) {
|
|
1455
|
-
fakeY = y + height + offsetY;
|
|
1456
|
-
}
|
|
1457
|
-
return { fakeX, fakeY };
|
|
1458
|
-
};
|
|
1459
|
-
const drawIndentNodeG = (board, fakeDropNodeG, fakePoint, node) => {
|
|
1460
|
-
const { fakeX, fakeY } = fakePoint;
|
|
1461
|
-
const fakeNode = Object.assign(Object.assign({}, node), { x: fakeX, y: fakeY, width: 30, height: 12 });
|
|
1462
|
-
const linkSVGG = drawIndentedLink(board, node, fakeNode, PRIMARY_COLOR, false);
|
|
1463
|
-
const startRectanglePointX = fakeX, startRectanglePointY = fakeY, endRectanglePointX = fakeX + 30, endRectanglePointY = fakeY + 12;
|
|
1464
|
-
const fakeRectangleG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), startRectanglePointX, startRectanglePointY, endRectanglePointX, endRectanglePointY, {
|
|
1465
|
-
stroke: PRIMARY_COLOR,
|
|
1466
|
-
strokeWidth: 2,
|
|
1467
|
-
fill: PRIMARY_COLOR,
|
|
1468
|
-
fillStyle: 'solid'
|
|
1469
954
|
});
|
|
1470
|
-
|
|
1471
|
-
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.appendChild(fakeRectangleG);
|
|
955
|
+
return dropTarget;
|
|
1472
956
|
};
|
|
1473
|
-
|
|
1474
|
-
/**
|
|
1475
|
-
*
|
|
1476
|
-
* @param targetNode
|
|
1477
|
-
* @param centerPoint
|
|
1478
|
-
* @returns DetectResult[] | null
|
|
1479
|
-
*/
|
|
1480
957
|
const directionDetector = (targetNode, centerPoint) => {
|
|
1481
958
|
const { x, y, width, height } = getRectangleByNode(targetNode);
|
|
1482
959
|
const yCenter = y + height / 2;
|
|
@@ -1525,59 +1002,6 @@ const directionDetector = (targetNode, centerPoint) => {
|
|
|
1525
1002
|
}
|
|
1526
1003
|
return null;
|
|
1527
1004
|
};
|
|
1528
|
-
|
|
1529
|
-
const directionCorrector = (board, node, detectResults) => {
|
|
1530
|
-
if (!node.origin.isRoot && !AbstractNode.isAbstract(node.origin)) {
|
|
1531
|
-
const parentLayout = MindQueries.getCorrectLayoutByElement(board, node === null || node === void 0 ? void 0 : node.parent.origin);
|
|
1532
|
-
if (isStandardLayout(parentLayout)) {
|
|
1533
|
-
const idx = node.parent.children.findIndex(x => x === node);
|
|
1534
|
-
const isLeft = idx >= (node.parent.origin.rightNodeCount || 0);
|
|
1535
|
-
return getAllowedDirection(detectResults, [isLeft ? 'right' : 'left']);
|
|
1536
|
-
}
|
|
1537
|
-
if (isLeftLayout(parentLayout)) {
|
|
1538
|
-
return getAllowedDirection(detectResults, ['right']);
|
|
1539
|
-
}
|
|
1540
|
-
if (isRightLayout(parentLayout)) {
|
|
1541
|
-
return getAllowedDirection(detectResults, ['left']);
|
|
1542
|
-
}
|
|
1543
|
-
if (parentLayout === MindLayoutType.upward) {
|
|
1544
|
-
return getAllowedDirection(detectResults, ['bottom']);
|
|
1545
|
-
}
|
|
1546
|
-
if (parentLayout === MindLayoutType.downward) {
|
|
1547
|
-
return getAllowedDirection(detectResults, ['top']);
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
else {
|
|
1551
|
-
const layout = MindQueries.getCorrectLayoutByElement(board, node === null || node === void 0 ? void 0 : node.origin);
|
|
1552
|
-
if (isStandardLayout(layout)) {
|
|
1553
|
-
return getAllowedDirection(detectResults, ['top', 'bottom']);
|
|
1554
|
-
}
|
|
1555
|
-
if (isTopLayout(layout)) {
|
|
1556
|
-
return getAllowedDirection(detectResults, ['left', 'right', 'bottom']);
|
|
1557
|
-
}
|
|
1558
|
-
if (isBottomLayout(layout)) {
|
|
1559
|
-
return getAllowedDirection(detectResults, ['left', 'right', 'top']);
|
|
1560
|
-
}
|
|
1561
|
-
if (layout === MindLayoutType.left) {
|
|
1562
|
-
return getAllowedDirection(detectResults, ['right', 'top', 'bottom']);
|
|
1563
|
-
}
|
|
1564
|
-
if (layout === MindLayoutType.right) {
|
|
1565
|
-
return getAllowedDirection(detectResults, ['left', 'top', 'bottom']);
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
return null;
|
|
1569
|
-
};
|
|
1570
|
-
const getAllowedDirection = (detectResults, illegalDirections) => {
|
|
1571
|
-
const directions = detectResults;
|
|
1572
|
-
illegalDirections.forEach(item => {
|
|
1573
|
-
const bottomDirectionIndex = directions.findIndex(direction => direction === item);
|
|
1574
|
-
if (bottomDirectionIndex !== -1) {
|
|
1575
|
-
directions.splice(bottomDirectionIndex, 1);
|
|
1576
|
-
}
|
|
1577
|
-
});
|
|
1578
|
-
return directions.length ? directions : null;
|
|
1579
|
-
};
|
|
1580
|
-
|
|
1581
1005
|
/* 根据布局调整 target 以及 direction */
|
|
1582
1006
|
const readjustmentDropTarget = (board, dropTarget) => {
|
|
1583
1007
|
const { target, detectResult } = dropTarget;
|
|
@@ -1660,262 +1084,126 @@ const readjustmentDropTarget = (board, dropTarget) => {
|
|
|
1660
1084
|
}
|
|
1661
1085
|
return dropTarget;
|
|
1662
1086
|
};
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1087
|
+
const isValidTarget = (origin, target) => {
|
|
1088
|
+
return origin !== target && !isChildElement(origin, target);
|
|
1089
|
+
};
|
|
1090
|
+
const getPathByDropTarget = (board, dropTarget) => {
|
|
1091
|
+
let targetPath = PlaitBoard.findPath(board, dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target);
|
|
1092
|
+
const layout = PlaitMind.isMind(dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target)
|
|
1093
|
+
? getRootLayout(dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target)
|
|
1094
|
+
: MindQueries.getCorrectLayoutByElement(board, MindElement.getParent(dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target));
|
|
1095
|
+
const children = getNonAbstractChildren(dropTarget.target);
|
|
1096
|
+
// 上下布局:左右是兄弟节点,上下是子节点
|
|
1097
|
+
if (isVerticalLogicLayout(layout)) {
|
|
1098
|
+
if (dropTarget.detectResult === 'top' || dropTarget.detectResult === 'bottom') {
|
|
1099
|
+
targetPath.push(children.length);
|
|
1668
1100
|
}
|
|
1669
|
-
|
|
1670
|
-
|
|
1101
|
+
// 如果是左,位置不变,右则插入到下一个兄弟节点
|
|
1102
|
+
if (dropTarget.detectResult === 'right') {
|
|
1103
|
+
targetPath = Path.next(targetPath);
|
|
1671
1104
|
}
|
|
1672
1105
|
}
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1106
|
+
// 水平布局/标准布局:上下是兄弟节点,左右是子节点
|
|
1107
|
+
if (isHorizontalLogicLayout(layout)) {
|
|
1108
|
+
if (dropTarget.detectResult === 'right' || dropTarget.detectResult === 'left') {
|
|
1109
|
+
targetPath.push(children.length);
|
|
1676
1110
|
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1111
|
+
// 如果是上,位置不变,下插入到下一个兄弟节点
|
|
1112
|
+
if (dropTarget.detectResult === 'bottom') {
|
|
1113
|
+
targetPath = Path.next(targetPath);
|
|
1679
1114
|
}
|
|
1680
1115
|
}
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
const startNode = parentChildren[start];
|
|
1686
|
-
const endNode = parentChildren[end];
|
|
1687
|
-
if (handlePosition === AbstractHandlePosition.start) {
|
|
1688
|
-
const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.end < element.start);
|
|
1689
|
-
let minNode;
|
|
1690
|
-
if (abstractNode.length) {
|
|
1691
|
-
const index = abstractNode
|
|
1692
|
-
.map(node => {
|
|
1693
|
-
const { end } = getCorrectStartEnd(node, parent);
|
|
1694
|
-
return end;
|
|
1695
|
-
})
|
|
1696
|
-
.sort((a, b) => b - a)[0];
|
|
1697
|
-
minNode = parentChildren[index + 1];
|
|
1116
|
+
// 缩进布局:上下是兄弟节点,左右是子节点,但上(左上/右上),探测到上是子节点,下则位置不变,反之同理。
|
|
1117
|
+
if (isIndentedLayout(layout)) {
|
|
1118
|
+
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
1119
|
+
targetPath = Path.next(targetPath);
|
|
1698
1120
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1121
|
+
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
1122
|
+
targetPath = Path.next(targetPath);
|
|
1701
1123
|
}
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
if (isHorizontal) {
|
|
1705
|
-
return {
|
|
1706
|
-
max: endNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1707
|
-
min: minNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1708
|
-
};
|
|
1124
|
+
if (isLeftLayout(layout) && dropTarget.detectResult === 'left') {
|
|
1125
|
+
targetPath.push(children.length);
|
|
1709
1126
|
}
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
max: endNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1713
|
-
min: minNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1714
|
-
};
|
|
1127
|
+
if (isRightLayout(layout) && dropTarget.detectResult === 'right') {
|
|
1128
|
+
targetPath.push(children.length);
|
|
1715
1129
|
}
|
|
1716
1130
|
}
|
|
1131
|
+
return targetPath;
|
|
1132
|
+
};
|
|
1133
|
+
|
|
1134
|
+
function drawRoundRectangleByNode(board, node) {
|
|
1135
|
+
const rectangle = getRectangleByNode(node);
|
|
1136
|
+
return drawRoundRectangleByElement(board, rectangle, node.origin);
|
|
1137
|
+
}
|
|
1138
|
+
function drawRoundRectangleByElement(board, nodeRectangle, element) {
|
|
1139
|
+
const fill = element.fill ? element.fill : element.isRoot ? DefaultRootStyle.fill : DefaultNodeStyle.fill;
|
|
1140
|
+
const stroke = getStrokeByMindElement(board, element);
|
|
1141
|
+
const strokeWidth = element.strokeWidth ? element.strokeWidth : DefaultNodeStyle.strokeWidth;
|
|
1142
|
+
const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), nodeRectangle.x, nodeRectangle.y, nodeRectangle.x + nodeRectangle.width, nodeRectangle.y + nodeRectangle.height, {
|
|
1143
|
+
stroke,
|
|
1144
|
+
strokeWidth,
|
|
1145
|
+
fill,
|
|
1146
|
+
fillStyle: 'solid'
|
|
1147
|
+
});
|
|
1148
|
+
return nodeG;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
var HorizontalPlacement;
|
|
1152
|
+
(function (HorizontalPlacement) {
|
|
1153
|
+
HorizontalPlacement["left"] = "left";
|
|
1154
|
+
HorizontalPlacement["center"] = "center";
|
|
1155
|
+
HorizontalPlacement["right"] = "right";
|
|
1156
|
+
})(HorizontalPlacement || (HorizontalPlacement = {}));
|
|
1157
|
+
var VerticalPlacement;
|
|
1158
|
+
(function (VerticalPlacement) {
|
|
1159
|
+
VerticalPlacement["top"] = "top";
|
|
1160
|
+
VerticalPlacement["middle"] = "middle";
|
|
1161
|
+
VerticalPlacement["bottom"] = "bottom";
|
|
1162
|
+
})(VerticalPlacement || (VerticalPlacement = {}));
|
|
1163
|
+
|
|
1164
|
+
const getPointByPlacement = (client, placement) => {
|
|
1165
|
+
let x = client.x;
|
|
1166
|
+
let y = client.y;
|
|
1167
|
+
if (placement[0] === HorizontalPlacement.center) {
|
|
1168
|
+
x = client.x + client.width / 2;
|
|
1169
|
+
}
|
|
1170
|
+
if (placement[0] === HorizontalPlacement.right) {
|
|
1171
|
+
x = client.x + client.width;
|
|
1172
|
+
}
|
|
1173
|
+
if (placement[1] === VerticalPlacement.middle) {
|
|
1174
|
+
y = client.y + client.height / 2;
|
|
1175
|
+
}
|
|
1176
|
+
if (placement[1] === VerticalPlacement.bottom) {
|
|
1177
|
+
y = client.y + client.height;
|
|
1178
|
+
}
|
|
1179
|
+
return [x, y];
|
|
1180
|
+
};
|
|
1181
|
+
const getXDistanceBetweenPoint = (point1, point2, isHorizontalLayout) => {
|
|
1182
|
+
if (isHorizontalLayout) {
|
|
1183
|
+
return Math.abs(point1[0] - point2[0]);
|
|
1184
|
+
}
|
|
1717
1185
|
else {
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1186
|
+
return Math.abs(point1[1] - point2[1]);
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
const getYDistanceBetweenPoint = (point1, point2, isHorizontalLayout) => {
|
|
1190
|
+
getXDistanceBetweenPoint(point1, point2, !isHorizontalLayout);
|
|
1191
|
+
};
|
|
1192
|
+
const getLayoutDirection = (node, isHorizontal) => {
|
|
1193
|
+
if (isHorizontal) {
|
|
1194
|
+
if (node.left) {
|
|
1195
|
+
return LayoutDirection.left;
|
|
1728
1196
|
}
|
|
1729
1197
|
else {
|
|
1730
|
-
|
|
1731
|
-
maxNode = parentChildren[children.length - 1];
|
|
1198
|
+
return LayoutDirection.right;
|
|
1732
1199
|
}
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
if (
|
|
1736
|
-
return
|
|
1737
|
-
max: maxNodeRectangle.y + maxNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1738
|
-
min: startNodeRectangle.y + startNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1739
|
-
};
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
if (node.up) {
|
|
1203
|
+
return LayoutDirection.top;
|
|
1740
1204
|
}
|
|
1741
1205
|
else {
|
|
1742
|
-
return
|
|
1743
|
-
max: maxNodeRectangle.x + maxNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1744
|
-
min: startNodeRectangle.x + startNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1745
|
-
};
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
};
|
|
1749
|
-
const getHitAbstractHandle = (board, element, point) => {
|
|
1750
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
1751
|
-
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
1752
|
-
const parentElement = MindElement.getParent(element);
|
|
1753
|
-
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
1754
|
-
let abstractRectangle = getRectangleByElements(board, includedElements, true);
|
|
1755
|
-
abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
|
|
1756
|
-
const startHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.start);
|
|
1757
|
-
const endHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.end);
|
|
1758
|
-
const pointRec = RectangleClient.toRectangleClient([point, point]);
|
|
1759
|
-
if (RectangleClient.isHit(pointRec, startHandleRec))
|
|
1760
|
-
return AbstractHandlePosition.start;
|
|
1761
|
-
if (RectangleClient.isHit(pointRec, endHandleRec))
|
|
1762
|
-
return AbstractHandlePosition.end;
|
|
1763
|
-
return undefined;
|
|
1764
|
-
};
|
|
1765
|
-
const getAbstractHandleRectangle = (rectangle, isHorizontal, position) => {
|
|
1766
|
-
let result;
|
|
1767
|
-
if (position === AbstractHandlePosition.start) {
|
|
1768
|
-
const location = isHorizontal ? rectangle.y : rectangle.x;
|
|
1769
|
-
result = getRectangleByResizingLocation(rectangle, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.end, isHorizontal);
|
|
1770
|
-
result = getRectangleByResizingLocation(result, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
|
|
1771
|
-
}
|
|
1772
|
-
else {
|
|
1773
|
-
const location = isHorizontal ? rectangle.y + rectangle.height : rectangle.x + rectangle.width;
|
|
1774
|
-
result = getRectangleByResizingLocation(rectangle, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.start, isHorizontal);
|
|
1775
|
-
result = getRectangleByResizingLocation(result, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
|
|
1776
|
-
}
|
|
1777
|
-
return result;
|
|
1778
|
-
};
|
|
1779
|
-
function findLocationLeftIndex(board, parentChildren, location, isHorizontal) {
|
|
1780
|
-
const children = parentChildren.filter(child => {
|
|
1781
|
-
return !AbstractNode.isAbstract(child);
|
|
1782
|
-
});
|
|
1783
|
-
const recArray = children.map(child => {
|
|
1784
|
-
return getRectangleByElements(board, [child], false);
|
|
1785
|
-
});
|
|
1786
|
-
const firstRec = getRectangleByElements(board, [children[0]], true);
|
|
1787
|
-
const fakeLeftRec = {
|
|
1788
|
-
x: firstRec.x - firstRec.width,
|
|
1789
|
-
y: firstRec.y - firstRec.height,
|
|
1790
|
-
width: firstRec.width,
|
|
1791
|
-
height: firstRec.height
|
|
1792
|
-
};
|
|
1793
|
-
const lastRec = getRectangleByElements(board, [children[children.length - 1]], true);
|
|
1794
|
-
const fakeRightRec = {
|
|
1795
|
-
x: lastRec.x + lastRec.width,
|
|
1796
|
-
y: lastRec.y + lastRec.height,
|
|
1797
|
-
width: lastRec.width,
|
|
1798
|
-
height: lastRec.height
|
|
1799
|
-
};
|
|
1800
|
-
recArray.push(fakeRightRec);
|
|
1801
|
-
recArray.unshift(fakeLeftRec);
|
|
1802
|
-
for (let i = 0; i < recArray.length - 1; i++) {
|
|
1803
|
-
const recXOrY = isHorizontal ? recArray[i].y : recArray[i].x;
|
|
1804
|
-
const recWidthOrHeight = isHorizontal ? recArray[i].height : recArray[i].width;
|
|
1805
|
-
if (location >= recXOrY + recWidthOrHeight / 2 &&
|
|
1806
|
-
location <= recArray[i + 1][isHorizontal ? 'y' : 'x'] + recArray[i + 1][isHorizontal ? 'height' : 'width'] / 2) {
|
|
1807
|
-
return i - 1;
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
return 0;
|
|
1811
|
-
}
|
|
1812
|
-
function handleTouchedAbstract(board, touchedAbstract, endPoint) {
|
|
1813
|
-
let touchedHandle;
|
|
1814
|
-
const abstract = getSelectedElements(board)
|
|
1815
|
-
.filter(element => AbstractNode.isAbstract(element))
|
|
1816
|
-
.find(element => {
|
|
1817
|
-
touchedHandle = getHitAbstractHandle(board, element, endPoint);
|
|
1818
|
-
return touchedHandle;
|
|
1819
|
-
});
|
|
1820
|
-
if (touchedAbstract === abstract) {
|
|
1821
|
-
return touchedAbstract;
|
|
1822
|
-
}
|
|
1823
|
-
if (touchedAbstract) {
|
|
1824
|
-
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1825
|
-
component.updateAbstractIncludedOutline();
|
|
1826
|
-
touchedAbstract = undefined;
|
|
1827
|
-
}
|
|
1828
|
-
if (abstract) {
|
|
1829
|
-
touchedAbstract = abstract;
|
|
1830
|
-
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1831
|
-
component.updateAbstractIncludedOutline(touchedHandle);
|
|
1832
|
-
}
|
|
1833
|
-
return touchedAbstract;
|
|
1834
|
-
}
|
|
1835
|
-
|
|
1836
|
-
function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnderline = true) {
|
|
1837
|
-
const branchWidth = getBranchWidthByMindElement(board, child.origin);
|
|
1838
|
-
const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin);
|
|
1839
|
-
const isUnderlineShape = getShapeByElement(board, child.origin) === MindElementShape.underline;
|
|
1840
|
-
let beginX, beginY, endX, endY, beginNode = node, endNode = child;
|
|
1841
|
-
const beginRectangle = getRectangleByNode(beginNode);
|
|
1842
|
-
const endRectangle = getRectangleByNode(endNode);
|
|
1843
|
-
beginX = beginNode.x + beginNode.width / 2;
|
|
1844
|
-
beginY = isChildUp(node, child) ? beginRectangle.y : beginRectangle.y + beginRectangle.height;
|
|
1845
|
-
endX = node.left ? endNode.x + endNode.hGap + endRectangle.width : endNode.x + endNode.hGap;
|
|
1846
|
-
endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
|
|
1847
|
-
//根据位置,设置正负参数
|
|
1848
|
-
let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
|
|
1849
|
-
const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
|
|
1850
|
-
if (beginNode.origin.isRoot) {
|
|
1851
|
-
if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
|
|
1852
|
-
beginY += branchWidth;
|
|
1853
|
-
}
|
|
1854
|
-
if (layout === MindLayoutType.leftTopIndented || layout === MindLayoutType.rightTopIndented) {
|
|
1855
|
-
beginY -= branchWidth;
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
let curve = [
|
|
1859
|
-
[beginX, beginY],
|
|
1860
|
-
[beginX, beginY],
|
|
1861
|
-
[beginX, beginY],
|
|
1862
|
-
[beginX, endY - (endNode.hGap * 3 * plusMinus[1]) / 5],
|
|
1863
|
-
[beginX, endY - (endNode.hGap * plusMinus[1]) / 5],
|
|
1864
|
-
[beginX + (endNode.hGap * plusMinus[0]) / 4, endY],
|
|
1865
|
-
[beginX + (endNode.hGap * plusMinus[0] * 3) / 5, endY],
|
|
1866
|
-
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1867
|
-
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1868
|
-
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY]
|
|
1869
|
-
];
|
|
1870
|
-
const points = pointsOnBezierCurves(curve);
|
|
1871
|
-
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1872
|
-
}
|
|
1873
|
-
|
|
1874
|
-
var HorizontalPlacement;
|
|
1875
|
-
(function (HorizontalPlacement) {
|
|
1876
|
-
HorizontalPlacement["left"] = "left";
|
|
1877
|
-
HorizontalPlacement["center"] = "center";
|
|
1878
|
-
HorizontalPlacement["right"] = "right";
|
|
1879
|
-
})(HorizontalPlacement || (HorizontalPlacement = {}));
|
|
1880
|
-
var VerticalPlacement;
|
|
1881
|
-
(function (VerticalPlacement) {
|
|
1882
|
-
VerticalPlacement["top"] = "top";
|
|
1883
|
-
VerticalPlacement["middle"] = "middle";
|
|
1884
|
-
VerticalPlacement["bottom"] = "bottom";
|
|
1885
|
-
})(VerticalPlacement || (VerticalPlacement = {}));
|
|
1886
|
-
|
|
1887
|
-
const getPointByPlacement = (client, placement) => {
|
|
1888
|
-
let x = client.x;
|
|
1889
|
-
let y = client.y;
|
|
1890
|
-
if (placement[0] === HorizontalPlacement.center) {
|
|
1891
|
-
x = client.x + client.width / 2;
|
|
1892
|
-
}
|
|
1893
|
-
if (placement[0] === HorizontalPlacement.right) {
|
|
1894
|
-
x = client.x + client.width;
|
|
1895
|
-
}
|
|
1896
|
-
if (placement[1] === VerticalPlacement.middle) {
|
|
1897
|
-
y = client.y + client.height / 2;
|
|
1898
|
-
}
|
|
1899
|
-
if (placement[1] === VerticalPlacement.bottom) {
|
|
1900
|
-
y = client.y + client.height;
|
|
1901
|
-
}
|
|
1902
|
-
return [x, y];
|
|
1903
|
-
};
|
|
1904
|
-
const getLayoutDirection = (node, isHorizontal) => {
|
|
1905
|
-
if (isHorizontal) {
|
|
1906
|
-
if (node.left) {
|
|
1907
|
-
return LayoutDirection.left;
|
|
1908
|
-
}
|
|
1909
|
-
else {
|
|
1910
|
-
return LayoutDirection.right;
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
else {
|
|
1914
|
-
if (node.up) {
|
|
1915
|
-
return LayoutDirection.top;
|
|
1916
|
-
}
|
|
1917
|
-
else {
|
|
1918
|
-
return LayoutDirection.bottom;
|
|
1206
|
+
return LayoutDirection.bottom;
|
|
1919
1207
|
}
|
|
1920
1208
|
}
|
|
1921
1209
|
};
|
|
@@ -1929,7 +1217,7 @@ const getLayoutDirection = (node, isHorizontal) => {
|
|
|
1929
1217
|
// 下 -> 上:
|
|
1930
1218
|
// 1. 终点 -> 起点/终点 -> 起点
|
|
1931
1219
|
// 2. 加 -> 减
|
|
1932
|
-
const
|
|
1220
|
+
const moveXOfPoint = (point, distance, direction = LayoutDirection.right) => {
|
|
1933
1221
|
if (direction === LayoutDirection.left) {
|
|
1934
1222
|
return [point[0] - distance, point[1]];
|
|
1935
1223
|
}
|
|
@@ -1941,6 +1229,15 @@ const movePoint = (point, distance, direction = LayoutDirection.right) => {
|
|
|
1941
1229
|
}
|
|
1942
1230
|
return [point[0] + distance, point[1]];
|
|
1943
1231
|
};
|
|
1232
|
+
const moveYOfPoint = (point, distance, direction = LayoutDirection.right) => {
|
|
1233
|
+
if (direction === LayoutDirection.bottom) {
|
|
1234
|
+
return [point[0] + distance, point[1]];
|
|
1235
|
+
}
|
|
1236
|
+
if (direction === LayoutDirection.top) {
|
|
1237
|
+
return [point[0] + distance, point[1]];
|
|
1238
|
+
}
|
|
1239
|
+
return [point[0], point[1] + distance];
|
|
1240
|
+
};
|
|
1944
1241
|
const transformPlacement = (placement, direction) => {
|
|
1945
1242
|
// to left
|
|
1946
1243
|
if (direction === LayoutDirection.left) {
|
|
@@ -1981,9 +1278,9 @@ const transformPlacement = (placement, direction) => {
|
|
|
1981
1278
|
}
|
|
1982
1279
|
};
|
|
1983
1280
|
|
|
1984
|
-
function drawLogicLink(board, node, parent, isHorizontal) {
|
|
1985
|
-
const branchColor = getBranchColorByMindElement(board, node.origin);
|
|
1986
|
-
const branchWidth = getBranchWidthByMindElement(board, node.origin);
|
|
1281
|
+
function drawLogicLink(board, node, parent, isHorizontal, defaultStroke = null, defaultStrokeWidth) {
|
|
1282
|
+
const branchColor = defaultStroke || getBranchColorByMindElement(board, node.origin);
|
|
1283
|
+
const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, node.origin);
|
|
1987
1284
|
const hasStraightLine = !parent.origin.isRoot;
|
|
1988
1285
|
const parentShape = getShapeByElement(board, parent.origin);
|
|
1989
1286
|
const shape = node.origin.shape ? node.origin.shape : parentShape;
|
|
@@ -2010,159 +1307,566 @@ function drawLogicLink(board, node, parent, isHorizontal) {
|
|
|
2010
1307
|
// ② 确定凸出直线,从起始点开始画一条直线,从直线的结束位置绘制曲线,保证收起图标可以完美覆盖起始连线,根节点不需要这条直线
|
|
2011
1308
|
// 绘制贝塞尔曲线要求,需要增加三个点,正常两个点就可以确定这条直线
|
|
2012
1309
|
const straightLineDistance = 8;
|
|
2013
|
-
const beginPoint2 = hasStraightLine ?
|
|
1310
|
+
const beginPoint2 = hasStraightLine ? moveXOfPoint(beginPoint, straightLineDistance, linkDirection) : beginPoint;
|
|
2014
1311
|
let straightLine = hasStraightLine ? [beginPoint, beginPoint2, beginPoint2] : [];
|
|
2015
1312
|
// ③ 确定曲线
|
|
2016
1313
|
const beginBufferDistance = (parent.hGap + node.hGap) / 3;
|
|
2017
1314
|
const endBufferDistance = -(parent.hGap + node.hGap) / 2.4;
|
|
2018
1315
|
let curve = [
|
|
2019
1316
|
beginPoint2,
|
|
2020
|
-
|
|
2021
|
-
|
|
1317
|
+
moveXOfPoint(beginPoint2, beginBufferDistance, linkDirection),
|
|
1318
|
+
moveXOfPoint(endPoint, endBufferDistance, linkDirection),
|
|
2022
1319
|
endPoint
|
|
2023
1320
|
];
|
|
2024
1321
|
// ④ 下划线绘制,underline shape and horizontal
|
|
2025
|
-
const underlineEnd =
|
|
1322
|
+
const underlineEnd = moveXOfPoint(endPoint, nodeClient.width, linkDirection);
|
|
2026
1323
|
const underline = hasUnderlineShape && isHorizontal ? [underlineEnd, underlineEnd, underlineEnd] : [];
|
|
2027
1324
|
const points = pointsOnBezierCurves([...straightLine, ...curve, ...underline]);
|
|
2028
1325
|
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
2029
1326
|
}
|
|
2030
1327
|
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
const
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
1328
|
+
const drawFakeDragNode = (board, activeComponent, offsetX, offsetY) => {
|
|
1329
|
+
var _a;
|
|
1330
|
+
const dragFakeNodeG = createG();
|
|
1331
|
+
dragFakeNodeG.classList.add('dragging', 'fake-node', 'plait-board-attached');
|
|
1332
|
+
const fakeDraggingNode = Object.assign(Object.assign({}, activeComponent.node), { children: [], x: activeComponent.node.x + offsetX, y: activeComponent.node.y + offsetY });
|
|
1333
|
+
const textRectangle = getTopicRectangleByNode(board, activeComponent.node);
|
|
1334
|
+
const fakeNodeG = drawRoundRectangleByNode(board, fakeDraggingNode);
|
|
1335
|
+
const richtextG = (_a = activeComponent.richtextG) === null || _a === void 0 ? void 0 : _a.cloneNode(true);
|
|
1336
|
+
updateForeignObject(richtextG, textRectangle.width + BASE * 10, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
|
|
1337
|
+
dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(fakeNodeG);
|
|
1338
|
+
dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(richtextG);
|
|
1339
|
+
return dragFakeNodeG;
|
|
1340
|
+
};
|
|
1341
|
+
const drawFakeDropNodeByPath = (board, target, path) => {
|
|
1342
|
+
const fakeDropNodeG = createG();
|
|
1343
|
+
const parent = PlaitNode.get(board, Path.parent(path));
|
|
1344
|
+
const layout = MindQueries.getLayoutByElement(parent);
|
|
1345
|
+
const isHorizontal = isHorizontalLayout(layout);
|
|
1346
|
+
const { hasNextNode, hasPreviousNode } = getPreviousAndNextByPath(parent, target, path);
|
|
1347
|
+
const width = 30;
|
|
1348
|
+
const height = 12;
|
|
1349
|
+
let fakeNode, centerPoint, basicNode, linkDirection;
|
|
1350
|
+
if (!hasPreviousNode && !hasNextNode) {
|
|
1351
|
+
const parentNode = MindElement.getNode(parent);
|
|
1352
|
+
const parentRect = getRectangleByNode(parentNode);
|
|
1353
|
+
linkDirection = getLayoutDirection(parentNode, isHorizontal);
|
|
1354
|
+
basicNode = parentNode;
|
|
1355
|
+
const placement = [HorizontalPlacement.right, VerticalPlacement.middle];
|
|
1356
|
+
transformPlacement(placement, linkDirection);
|
|
1357
|
+
const parentCenterPoint = getPointByPlacement(parentRect, placement);
|
|
1358
|
+
if (isIndentedLayout(layout)) {
|
|
1359
|
+
const placement = [
|
|
1360
|
+
HorizontalPlacement.center,
|
|
1361
|
+
isTopLayout(layout) ? VerticalPlacement.top : VerticalPlacement.bottom
|
|
1362
|
+
];
|
|
1363
|
+
const parentCenterPoint = getPointByPlacement(parentRect, placement);
|
|
1364
|
+
centerPoint = moveXOfPoint(parentCenterPoint, height, linkDirection);
|
|
1365
|
+
centerPoint[1] = isTopLayout(layout) ? centerPoint[1] - height : centerPoint[1] + height;
|
|
1366
|
+
}
|
|
1367
|
+
else {
|
|
1368
|
+
centerPoint = moveXOfPoint(parentCenterPoint, width, linkDirection);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
else if (!hasPreviousNode && hasNextNode) {
|
|
1372
|
+
const nextElement = PlaitNode.get(board, path);
|
|
1373
|
+
basicNode = MindElement.getNode(nextElement);
|
|
1374
|
+
const nextRect = getRectangleByNode(basicNode);
|
|
1375
|
+
linkDirection = getLayoutDirection(basicNode, isHorizontal);
|
|
1376
|
+
const placement = [HorizontalPlacement.left, VerticalPlacement.top];
|
|
1377
|
+
transformPlacement(placement, linkDirection);
|
|
1378
|
+
let offset = -height;
|
|
1379
|
+
if (MindElement.isIndentedLayout(parent)) {
|
|
1380
|
+
offset = isTopLayout(layout) ? offset / 2 + basicNode.height - basicNode.vGap : 0;
|
|
1381
|
+
}
|
|
1382
|
+
centerPoint = getPointByPlacement(nextRect, placement);
|
|
1383
|
+
centerPoint = moveYOfPoint(centerPoint, offset, linkDirection);
|
|
1384
|
+
}
|
|
1385
|
+
else if (hasPreviousNode && !hasNextNode) {
|
|
1386
|
+
const previousElement = PlaitNode.get(board, Path.previous(path));
|
|
1387
|
+
basicNode = MindElement.getNode(previousElement);
|
|
1388
|
+
const previousRect = getRectangleByNode(basicNode);
|
|
1389
|
+
linkDirection = getLayoutDirection(basicNode, isHorizontal);
|
|
1390
|
+
const placement = [HorizontalPlacement.left, VerticalPlacement.bottom];
|
|
1391
|
+
transformPlacement(placement, linkDirection);
|
|
1392
|
+
let offset = height;
|
|
1393
|
+
if (MindElement.isIndentedLayout(parent)) {
|
|
1394
|
+
offset = isTopLayout(layout) ? -offset - (basicNode.height - basicNode.vGap) : offset;
|
|
1395
|
+
}
|
|
1396
|
+
centerPoint = getPointByPlacement(previousRect, placement);
|
|
1397
|
+
centerPoint = moveYOfPoint(centerPoint, offset, linkDirection);
|
|
2043
1398
|
}
|
|
2044
1399
|
else {
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
1400
|
+
const previousElement = PlaitNode.get(board, Path.previous(path));
|
|
1401
|
+
basicNode = MindElement.getNode(previousElement);
|
|
1402
|
+
const previousRect = getRectangleByNode(basicNode);
|
|
1403
|
+
const nextElement = PlaitNode.get(board, path);
|
|
1404
|
+
const nextNode = MindElement.getNode(nextElement);
|
|
1405
|
+
const nextRect = getRectangleByNode(nextNode);
|
|
1406
|
+
const beginPlacement = [HorizontalPlacement.left, VerticalPlacement.bottom];
|
|
1407
|
+
const endPlacement = [HorizontalPlacement.left, VerticalPlacement.top];
|
|
1408
|
+
linkDirection = getLayoutDirection(basicNode, isHorizontal);
|
|
1409
|
+
transformPlacement(beginPlacement, linkDirection);
|
|
1410
|
+
transformPlacement(endPlacement, linkDirection);
|
|
1411
|
+
const previousPoint = getPointByPlacement(previousRect, beginPlacement);
|
|
1412
|
+
const nextPoint = getPointByPlacement(nextRect, endPlacement);
|
|
1413
|
+
centerPoint = [(previousPoint[0] + nextPoint[0]) / 2, (previousPoint[1] + nextPoint[1]) / 2];
|
|
1414
|
+
}
|
|
1415
|
+
let cornerPoint = centerPoint, oppositePoint = centerPoint;
|
|
1416
|
+
const offsetY = isHorizontal ? height : width;
|
|
1417
|
+
const offsetX = isHorizontal ? width : height;
|
|
1418
|
+
cornerPoint = moveYOfPoint(cornerPoint, -offsetY / 2, linkDirection);
|
|
1419
|
+
oppositePoint = moveYOfPoint(oppositePoint, offsetY / 2, linkDirection);
|
|
1420
|
+
oppositePoint = moveXOfPoint(oppositePoint, offsetX, linkDirection);
|
|
1421
|
+
const x = Math.min(cornerPoint[0], oppositePoint[0]);
|
|
1422
|
+
const y = Math.min(cornerPoint[1], oppositePoint[1]);
|
|
1423
|
+
fakeNode = Object.assign(Object.assign({}, basicNode), { x,
|
|
2054
1424
|
y,
|
|
2055
1425
|
width,
|
|
2056
|
-
height
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
1426
|
+
height, hGap: MindElement.isIndentedLayout(parent) ? BASE * 4 + (basicNode.origin.strokeWidth || STROKE_WIDTH) : 0, vGap: MindElement.isIndentedLayout(parent) ? BASE : 0 });
|
|
1427
|
+
const fakeRectangleG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), fakeNode.x, fakeNode.y, fakeNode.x + width, fakeNode.y + height, {
|
|
1428
|
+
stroke: PRIMARY_COLOR,
|
|
1429
|
+
strokeWidth: 2,
|
|
1430
|
+
fill: PRIMARY_COLOR,
|
|
1431
|
+
fillStyle: 'solid'
|
|
1432
|
+
});
|
|
1433
|
+
const link = MindElement.isIndentedLayout(parent)
|
|
1434
|
+
? drawIndentedLink(board, MindElement.getNode(parent), fakeNode, PRIMARY_COLOR, false, STROKE_WIDTH)
|
|
1435
|
+
: drawLogicLink(board, fakeNode, MindElement.getNode(parent), isHorizontal, PRIMARY_COLOR, STROKE_WIDTH);
|
|
1436
|
+
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.appendChild(link);
|
|
1437
|
+
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.appendChild(fakeRectangleG);
|
|
1438
|
+
return fakeDropNodeG;
|
|
1439
|
+
};
|
|
1440
|
+
const getPreviousAndNextByPath = (parent, target, path) => {
|
|
1441
|
+
const children = getNonAbstractChildren(parent);
|
|
1442
|
+
let hasPreviousNode = path[path.length - 1] !== 0;
|
|
1443
|
+
let hasNextNode = path[path.length - 1] !== ((children === null || children === void 0 ? void 0 : children.length) || 0);
|
|
1444
|
+
if (PlaitMind.isMind(parent) && isStandardLayout(getRootLayout(parent))) {
|
|
1445
|
+
const dropStandardRightBottom = target === parent.children[parent.rightNodeCount - 1] && path[path.length - 1] === parent.rightNodeCount;
|
|
1446
|
+
const dropStandardLeftTop = target === parent.children[parent.rightNodeCount] && path[path.length - 1] === parent.rightNodeCount;
|
|
1447
|
+
if (dropStandardRightBottom) {
|
|
1448
|
+
hasPreviousNode = true;
|
|
1449
|
+
hasNextNode = false;
|
|
1450
|
+
}
|
|
1451
|
+
if (dropStandardLeftTop) {
|
|
1452
|
+
hasPreviousNode = false;
|
|
1453
|
+
hasNextNode = true;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
if (parent.isCollapsed) {
|
|
1457
|
+
hasNextNode = false;
|
|
1458
|
+
hasPreviousNode = false;
|
|
1459
|
+
}
|
|
2063
1460
|
return {
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
width,
|
|
2067
|
-
height: height + NodeSpace.getEmojiTopSpace(element) * 2
|
|
1461
|
+
hasPreviousNode,
|
|
1462
|
+
hasNextNode
|
|
2068
1463
|
};
|
|
1464
|
+
};
|
|
1465
|
+
|
|
1466
|
+
const separateChildren = (parentElement) => {
|
|
1467
|
+
const rightNodeCount = parentElement.rightNodeCount;
|
|
1468
|
+
const children = parentElement.children;
|
|
1469
|
+
let rightChildren = [], leftChildren = [];
|
|
1470
|
+
for (let i = 0; i < children.length; i++) {
|
|
1471
|
+
const child = children[i];
|
|
1472
|
+
if (AbstractNode.isAbstract(child) && child.end < rightNodeCount) {
|
|
1473
|
+
rightChildren.push(child);
|
|
1474
|
+
continue;
|
|
1475
|
+
}
|
|
1476
|
+
if (AbstractNode.isAbstract(child) && child.start >= rightNodeCount) {
|
|
1477
|
+
leftChildren.push(child);
|
|
1478
|
+
continue;
|
|
1479
|
+
}
|
|
1480
|
+
if (i < rightNodeCount) {
|
|
1481
|
+
rightChildren.push(child);
|
|
1482
|
+
}
|
|
1483
|
+
else {
|
|
1484
|
+
leftChildren.push(child);
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
return { leftChildren, rightChildren };
|
|
1488
|
+
};
|
|
1489
|
+
const isSetAbstract = (element) => {
|
|
1490
|
+
return !!getCorrespondingAbstract(element);
|
|
1491
|
+
};
|
|
1492
|
+
const canSetAbstract = (element) => {
|
|
1493
|
+
return !PlaitElement.isRootElement(element) && !AbstractNode.isAbstract(element) && !isSetAbstract(element);
|
|
1494
|
+
};
|
|
1495
|
+
const getCorrespondingAbstract = (element) => {
|
|
1496
|
+
const parent = MindElement.findParent(element);
|
|
1497
|
+
if (!parent)
|
|
1498
|
+
return undefined;
|
|
1499
|
+
const elementIndex = parent.children.indexOf(element);
|
|
1500
|
+
return parent.children.find(child => {
|
|
1501
|
+
return AbstractNode.isAbstract(child) && elementIndex >= child.start && elementIndex <= child.end;
|
|
1502
|
+
});
|
|
1503
|
+
};
|
|
1504
|
+
const getBehindAbstracts = (element) => {
|
|
1505
|
+
const parent = MindElement.findParent(element);
|
|
1506
|
+
if (!parent)
|
|
1507
|
+
return [];
|
|
1508
|
+
const index = parent.children.indexOf(element);
|
|
1509
|
+
return parent.children.filter(child => AbstractNode.isAbstract(child) && child.start > index);
|
|
1510
|
+
};
|
|
1511
|
+
/**
|
|
1512
|
+
* return corresponding abstract that is not child of elements
|
|
1513
|
+
*/
|
|
1514
|
+
const getOverallAbstracts = (board, elements) => {
|
|
1515
|
+
const overallAbstracts = [];
|
|
1516
|
+
elements
|
|
1517
|
+
.filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
|
|
1518
|
+
.forEach(value => {
|
|
1519
|
+
const abstract = getCorrespondingAbstract(value);
|
|
1520
|
+
if (abstract && elements.indexOf(abstract) === -1 && overallAbstracts.indexOf(abstract) === -1) {
|
|
1521
|
+
const { start, end } = abstract;
|
|
1522
|
+
const parent = MindElement.getParent(value);
|
|
1523
|
+
const isOverall = parent.children.slice(start, end + 1).every(includedElement => elements.indexOf(includedElement) > -1);
|
|
1524
|
+
if (isOverall) {
|
|
1525
|
+
overallAbstracts.push(abstract);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
});
|
|
1529
|
+
return overallAbstracts;
|
|
1530
|
+
};
|
|
1531
|
+
/**
|
|
1532
|
+
* abstract node is valid when elements contains at least one element it is referenced with
|
|
1533
|
+
*/
|
|
1534
|
+
const getValidAbstractRefs = (board, elements) => {
|
|
1535
|
+
const validAbstractRefs = [];
|
|
1536
|
+
elements
|
|
1537
|
+
.filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
|
|
1538
|
+
.forEach(value => {
|
|
1539
|
+
const abstract = getCorrespondingAbstract(value);
|
|
1540
|
+
if (abstract && elements.indexOf(abstract) > 0) {
|
|
1541
|
+
const index = validAbstractRefs.findIndex(value => value.abstract === abstract);
|
|
1542
|
+
if (index === -1) {
|
|
1543
|
+
validAbstractRefs.push({
|
|
1544
|
+
abstract: abstract,
|
|
1545
|
+
references: [value]
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
else {
|
|
1549
|
+
validAbstractRefs[index].references.push(value);
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
});
|
|
1553
|
+
return validAbstractRefs;
|
|
1554
|
+
};
|
|
1555
|
+
function getRelativeStartEndByAbstractRef(abstractRef, elements) {
|
|
1556
|
+
const start = elements.indexOf(abstractRef.references[0]);
|
|
1557
|
+
const end = elements.indexOf(abstractRef.references[abstractRef.references.length - 1]);
|
|
1558
|
+
return { start, end };
|
|
2069
1559
|
}
|
|
2070
|
-
const
|
|
2071
|
-
|
|
1560
|
+
const insertElementHandleAbstract = (board, path, step = 1,
|
|
1561
|
+
//由此区分拖拽和新增到概要概括最后一个节点
|
|
1562
|
+
isExtendPreviousNode = true, effectedAbstracts = new Map()) => {
|
|
1563
|
+
const parent = PlaitNode.parent(board, path);
|
|
1564
|
+
const hasPreviousNode = path[path.length - 1] !== 0;
|
|
1565
|
+
let behindAbstracts;
|
|
1566
|
+
if (!hasPreviousNode) {
|
|
1567
|
+
behindAbstracts = parent.children.filter(child => AbstractNode.isAbstract(child));
|
|
1568
|
+
}
|
|
1569
|
+
else {
|
|
1570
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
1571
|
+
behindAbstracts = getBehindAbstracts(selectedElement);
|
|
1572
|
+
}
|
|
1573
|
+
if (behindAbstracts.length) {
|
|
1574
|
+
behindAbstracts.forEach(abstract => {
|
|
1575
|
+
let newProperties = effectedAbstracts.get(abstract);
|
|
1576
|
+
if (!newProperties) {
|
|
1577
|
+
newProperties = { start: 0, end: 0 };
|
|
1578
|
+
effectedAbstracts.set(abstract, newProperties);
|
|
1579
|
+
}
|
|
1580
|
+
newProperties.start = newProperties.start + step;
|
|
1581
|
+
newProperties.end = newProperties.end + step;
|
|
1582
|
+
});
|
|
1583
|
+
}
|
|
1584
|
+
if (!hasPreviousNode) {
|
|
1585
|
+
return effectedAbstracts;
|
|
1586
|
+
}
|
|
1587
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
1588
|
+
const correspondingAbstract = getCorrespondingAbstract(selectedElement);
|
|
1589
|
+
const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
|
|
1590
|
+
if (correspondingAbstract && !isDragToLast) {
|
|
1591
|
+
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
1592
|
+
if (!newProperties) {
|
|
1593
|
+
newProperties = { start: 0, end: 0 };
|
|
1594
|
+
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
1595
|
+
}
|
|
1596
|
+
newProperties.end = newProperties.end + step;
|
|
1597
|
+
}
|
|
1598
|
+
return effectedAbstracts;
|
|
1599
|
+
};
|
|
1600
|
+
const deleteElementHandleAbstract = (board, deletableElements, effectedAbstracts = new Map()) => {
|
|
1601
|
+
deletableElements.forEach(node => {
|
|
1602
|
+
if (!PlaitMind.isMind(node)) {
|
|
1603
|
+
const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
|
|
1604
|
+
if (behindAbstracts.length) {
|
|
1605
|
+
behindAbstracts.forEach(abstract => {
|
|
1606
|
+
let newProperties = effectedAbstracts.get(abstract);
|
|
1607
|
+
if (!newProperties) {
|
|
1608
|
+
newProperties = { start: 0, end: 0 };
|
|
1609
|
+
effectedAbstracts.set(abstract, newProperties);
|
|
1610
|
+
}
|
|
1611
|
+
newProperties.start = newProperties.start - 1;
|
|
1612
|
+
newProperties.end = newProperties.end - 1;
|
|
1613
|
+
});
|
|
1614
|
+
}
|
|
1615
|
+
const correspondingAbstract = getCorrespondingAbstract(node);
|
|
1616
|
+
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
1617
|
+
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
1618
|
+
if (!newProperties) {
|
|
1619
|
+
newProperties = { start: 0, end: 0 };
|
|
1620
|
+
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
1621
|
+
}
|
|
1622
|
+
newProperties.end = newProperties.end - 1;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
});
|
|
1626
|
+
return effectedAbstracts;
|
|
2072
1627
|
};
|
|
2073
1628
|
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
1629
|
+
var AbstractHandlePosition;
|
|
1630
|
+
(function (AbstractHandlePosition) {
|
|
1631
|
+
AbstractHandlePosition["start"] = "start";
|
|
1632
|
+
AbstractHandlePosition["end"] = "end";
|
|
1633
|
+
})(AbstractHandlePosition || (AbstractHandlePosition = {}));
|
|
1634
|
+
var AbstractResizeState;
|
|
1635
|
+
(function (AbstractResizeState) {
|
|
1636
|
+
AbstractResizeState["start"] = "start";
|
|
1637
|
+
AbstractResizeState["resizing"] = "resizing";
|
|
1638
|
+
AbstractResizeState["end"] = "end";
|
|
1639
|
+
})(AbstractResizeState || (AbstractResizeState = {}));
|
|
1640
|
+
|
|
1641
|
+
const getRectangleByResizingLocation = (abstractRectangle, location, activeHandlePosition, isHorizontal) => {
|
|
1642
|
+
if (isHorizontal) {
|
|
1643
|
+
if (activeHandlePosition === AbstractHandlePosition.start) {
|
|
1644
|
+
return Object.assign(Object.assign({}, abstractRectangle), { y: location, height: abstractRectangle.height + abstractRectangle.y - location });
|
|
1645
|
+
}
|
|
1646
|
+
else {
|
|
1647
|
+
return Object.assign(Object.assign({}, abstractRectangle), { height: location - abstractRectangle.y });
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
else {
|
|
1651
|
+
if (activeHandlePosition === AbstractHandlePosition.start) {
|
|
1652
|
+
return Object.assign(Object.assign({}, abstractRectangle), { x: location, width: abstractRectangle.width + abstractRectangle.x - location });
|
|
1653
|
+
}
|
|
1654
|
+
else {
|
|
1655
|
+
return Object.assign(Object.assign({}, abstractRectangle), { width: location - abstractRectangle.x });
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
};
|
|
1659
|
+
const getLocationScope = (board, handlePosition, parentChildren, element, parent, isHorizontal) => {
|
|
1660
|
+
const node = MindElement.getNode(element);
|
|
1661
|
+
const { start, end } = getCorrectStartEnd(node.origin, parent);
|
|
1662
|
+
const startNode = parentChildren[start];
|
|
1663
|
+
const endNode = parentChildren[end];
|
|
1664
|
+
if (handlePosition === AbstractHandlePosition.start) {
|
|
1665
|
+
const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.end < element.start);
|
|
1666
|
+
let minNode;
|
|
1667
|
+
if (abstractNode.length) {
|
|
1668
|
+
const index = abstractNode
|
|
1669
|
+
.map(node => {
|
|
1670
|
+
const { end } = getCorrectStartEnd(node, parent);
|
|
1671
|
+
return end;
|
|
1672
|
+
})
|
|
1673
|
+
.sort((a, b) => b - a)[0];
|
|
1674
|
+
minNode = parentChildren[index + 1];
|
|
1675
|
+
}
|
|
1676
|
+
else {
|
|
1677
|
+
minNode = parentChildren[0];
|
|
1678
|
+
}
|
|
1679
|
+
const minNodeRectangle = getRectangleByElements(board, [minNode], true);
|
|
1680
|
+
const endNodeRectangle = getRectangleByElements(board, [endNode], false);
|
|
1681
|
+
if (isHorizontal) {
|
|
1682
|
+
return {
|
|
1683
|
+
max: endNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1684
|
+
min: minNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
else {
|
|
1688
|
+
return {
|
|
1689
|
+
max: endNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1690
|
+
min: minNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1691
|
+
};
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
else {
|
|
1695
|
+
const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.start > element.end);
|
|
1696
|
+
let maxNode;
|
|
1697
|
+
if (abstractNode.length) {
|
|
1698
|
+
const index = abstractNode
|
|
1699
|
+
.map(node => {
|
|
1700
|
+
const { start } = getCorrectStartEnd(node, parent);
|
|
1701
|
+
return start;
|
|
1702
|
+
})
|
|
1703
|
+
.sort((a, b) => a - b)[0];
|
|
1704
|
+
maxNode = parentChildren[index - 1];
|
|
1705
|
+
}
|
|
1706
|
+
else {
|
|
1707
|
+
const children = parentChildren.filter(child => !AbstractNode.isAbstract(child));
|
|
1708
|
+
maxNode = parentChildren[children.length - 1];
|
|
1709
|
+
}
|
|
1710
|
+
const maxNodeRectangle = getRectangleByElements(board, [maxNode], true);
|
|
1711
|
+
const startNodeRectangle = getRectangleByElements(board, [startNode], false);
|
|
1712
|
+
if (isHorizontal) {
|
|
1713
|
+
return {
|
|
1714
|
+
max: maxNodeRectangle.y + maxNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1715
|
+
min: startNodeRectangle.y + startNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
else {
|
|
1719
|
+
return {
|
|
1720
|
+
max: maxNodeRectangle.x + maxNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1721
|
+
min: startNodeRectangle.x + startNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
};
|
|
1726
|
+
const getHitAbstractHandle = (board, element, point) => {
|
|
1727
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
1728
|
+
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
1729
|
+
const parentElement = MindElement.getParent(element);
|
|
1730
|
+
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
1731
|
+
let abstractRectangle = getRectangleByElements(board, includedElements, true);
|
|
1732
|
+
abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
|
|
1733
|
+
const startHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.start);
|
|
1734
|
+
const endHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.end);
|
|
1735
|
+
const pointRec = RectangleClient.toRectangleClient([point, point]);
|
|
1736
|
+
if (RectangleClient.isHit(pointRec, startHandleRec))
|
|
1737
|
+
return AbstractHandlePosition.start;
|
|
1738
|
+
if (RectangleClient.isHit(pointRec, endHandleRec))
|
|
1739
|
+
return AbstractHandlePosition.end;
|
|
1740
|
+
return undefined;
|
|
1741
|
+
};
|
|
1742
|
+
const getAbstractHandleRectangle = (rectangle, isHorizontal, position) => {
|
|
1743
|
+
let result;
|
|
1744
|
+
if (position === AbstractHandlePosition.start) {
|
|
1745
|
+
const location = isHorizontal ? rectangle.y : rectangle.x;
|
|
1746
|
+
result = getRectangleByResizingLocation(rectangle, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.end, isHorizontal);
|
|
1747
|
+
result = getRectangleByResizingLocation(result, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
|
|
1748
|
+
}
|
|
1749
|
+
else {
|
|
1750
|
+
const location = isHorizontal ? rectangle.y + rectangle.height : rectangle.x + rectangle.width;
|
|
1751
|
+
result = getRectangleByResizingLocation(rectangle, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.start, isHorizontal);
|
|
1752
|
+
result = getRectangleByResizingLocation(result, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
|
|
1753
|
+
}
|
|
1754
|
+
return result;
|
|
1755
|
+
};
|
|
1756
|
+
function findLocationLeftIndex(board, parentChildren, location, isHorizontal) {
|
|
1757
|
+
const children = parentChildren.filter(child => {
|
|
1758
|
+
return !AbstractNode.isAbstract(child);
|
|
1759
|
+
});
|
|
1760
|
+
const recArray = children.map(child => {
|
|
1761
|
+
return getRectangleByElements(board, [child], false);
|
|
1762
|
+
});
|
|
1763
|
+
const firstRec = getRectangleByElements(board, [children[0]], true);
|
|
1764
|
+
const fakeLeftRec = {
|
|
1765
|
+
x: firstRec.x - firstRec.width,
|
|
1766
|
+
y: firstRec.y - firstRec.height,
|
|
1767
|
+
width: firstRec.width,
|
|
1768
|
+
height: firstRec.height
|
|
1769
|
+
};
|
|
1770
|
+
const lastRec = getRectangleByElements(board, [children[children.length - 1]], true);
|
|
1771
|
+
const fakeRightRec = {
|
|
1772
|
+
x: lastRec.x + lastRec.width,
|
|
1773
|
+
y: lastRec.y + lastRec.height,
|
|
1774
|
+
width: lastRec.width,
|
|
1775
|
+
height: lastRec.height
|
|
1776
|
+
};
|
|
1777
|
+
recArray.push(fakeRightRec);
|
|
1778
|
+
recArray.unshift(fakeLeftRec);
|
|
1779
|
+
for (let i = 0; i < recArray.length - 1; i++) {
|
|
1780
|
+
const recXOrY = isHorizontal ? recArray[i].y : recArray[i].x;
|
|
1781
|
+
const recWidthOrHeight = isHorizontal ? recArray[i].height : recArray[i].width;
|
|
1782
|
+
if (location >= recXOrY + recWidthOrHeight / 2 &&
|
|
1783
|
+
location <= recArray[i + 1][isHorizontal ? 'y' : 'x'] + recArray[i + 1][isHorizontal ? 'height' : 'width'] / 2) {
|
|
1784
|
+
return i - 1;
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
return 0;
|
|
1788
|
+
}
|
|
1789
|
+
function handleTouchedAbstract(board, touchedAbstract, endPoint) {
|
|
1790
|
+
let touchedHandle;
|
|
1791
|
+
const abstract = getSelectedElements(board)
|
|
1792
|
+
.filter(element => AbstractNode.isAbstract(element))
|
|
1793
|
+
.find(element => {
|
|
1794
|
+
touchedHandle = getHitAbstractHandle(board, element, endPoint);
|
|
1795
|
+
return touchedHandle;
|
|
1796
|
+
});
|
|
1797
|
+
if (touchedAbstract === abstract) {
|
|
1798
|
+
return touchedAbstract;
|
|
2081
1799
|
}
|
|
2082
|
-
|
|
2083
|
-
const
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
emojiAndText: BASE * 2
|
|
2087
|
-
},
|
|
2088
|
-
vertical: {
|
|
2089
|
-
nodeAndText: BASE * 2
|
|
1800
|
+
if (touchedAbstract) {
|
|
1801
|
+
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1802
|
+
component.updateAbstractIncludedOutline();
|
|
1803
|
+
touchedAbstract = undefined;
|
|
2090
1804
|
}
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
const
|
|
2103
|
-
|
|
2104
|
-
const
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
}
|
|
2117
|
-
return nodeAndText + element.width + nodeAndText;
|
|
2118
|
-
},
|
|
2119
|
-
getNodeHeight(element) {
|
|
2120
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
2121
|
-
return nodeAndText + element.height + nodeAndText;
|
|
2122
|
-
},
|
|
2123
|
-
getTextLeftSpace(board, element) {
|
|
2124
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
2125
|
-
if (MindElement.hasEmojis(element)) {
|
|
2126
|
-
return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
|
|
1805
|
+
if (abstract) {
|
|
1806
|
+
touchedAbstract = abstract;
|
|
1807
|
+
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1808
|
+
component.updateAbstractIncludedOutline(touchedHandle);
|
|
1809
|
+
}
|
|
1810
|
+
return touchedAbstract;
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnderline = true, defaultStrokeWidth) {
|
|
1814
|
+
const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, child.origin);
|
|
1815
|
+
const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin);
|
|
1816
|
+
const isUnderlineShape = getShapeByElement(board, child.origin) === MindElementShape.underline;
|
|
1817
|
+
let beginX, beginY, endX, endY, beginNode = node, endNode = child;
|
|
1818
|
+
const beginRectangle = getRectangleByNode(beginNode);
|
|
1819
|
+
const endRectangle = getRectangleByNode(endNode);
|
|
1820
|
+
beginX = beginNode.x + beginNode.width / 2;
|
|
1821
|
+
beginY = isChildUp(node, child) ? beginRectangle.y : beginRectangle.y + beginRectangle.height;
|
|
1822
|
+
endX = node.left ? endNode.x + endNode.hGap + endRectangle.width : endNode.x + endNode.hGap;
|
|
1823
|
+
endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
|
|
1824
|
+
//根据位置,设置正负参数
|
|
1825
|
+
let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
|
|
1826
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
|
|
1827
|
+
if (beginNode.origin.isRoot) {
|
|
1828
|
+
if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
|
|
1829
|
+
beginY += branchWidth;
|
|
2127
1830
|
}
|
|
2128
|
-
|
|
2129
|
-
|
|
1831
|
+
if (layout === MindLayoutType.leftTopIndented || layout === MindLayoutType.rightTopIndented) {
|
|
1832
|
+
beginY -= branchWidth;
|
|
2130
1833
|
}
|
|
2131
|
-
},
|
|
2132
|
-
getTextTopSpace(element) {
|
|
2133
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
2134
|
-
return nodeAndText;
|
|
2135
|
-
},
|
|
2136
|
-
getEmojiLeftSpace(board, element) {
|
|
2137
|
-
const options = board.getMindOptions();
|
|
2138
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
2139
|
-
return nodeAndText - options.emojiPadding;
|
|
2140
|
-
},
|
|
2141
|
-
getEmojiTopSpace(element) {
|
|
2142
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
2143
|
-
return nodeAndText;
|
|
2144
1834
|
}
|
|
2145
|
-
|
|
1835
|
+
let curve = [
|
|
1836
|
+
[beginX, beginY],
|
|
1837
|
+
[beginX, beginY],
|
|
1838
|
+
[beginX, beginY],
|
|
1839
|
+
[beginX, endY - (endNode.hGap * 3 * plusMinus[1]) / 5],
|
|
1840
|
+
[beginX, endY - (endNode.hGap * plusMinus[1]) / 5],
|
|
1841
|
+
[beginX + (endNode.hGap * plusMinus[0]) / 4, endY],
|
|
1842
|
+
[beginX + (endNode.hGap * plusMinus[0] * 3) / 5, endY],
|
|
1843
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1844
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1845
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY]
|
|
1846
|
+
];
|
|
1847
|
+
const points = pointsOnBezierCurves(curve);
|
|
1848
|
+
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1849
|
+
}
|
|
2146
1850
|
|
|
2147
|
-
function
|
|
2148
|
-
|
|
2149
|
-
|
|
1851
|
+
function drawTopicByNode(board, node, viewContainerRef) {
|
|
1852
|
+
const rectangle = getTopicRectangleByNode(board, node);
|
|
1853
|
+
return drawTopicByElement(board, rectangle, node.origin, viewContainerRef);
|
|
1854
|
+
}
|
|
1855
|
+
function drawTopicByElement(board, rectangle, element, viewContainerRef) {
|
|
1856
|
+
const containerRef = viewContainerRef || PlaitBoard.getComponent(board).viewContainerRef;
|
|
2150
1857
|
const classList = [];
|
|
2151
|
-
if (
|
|
1858
|
+
if (element.isRoot) {
|
|
2152
1859
|
classList.push('root-node');
|
|
2153
1860
|
classList.push('font-size-18');
|
|
2154
1861
|
}
|
|
2155
|
-
else if ((_b = (_a = node.parent) === null || _a === void 0 ? void 0 : _a.origin) === null || _b === void 0 ? void 0 : _b.isRoot) {
|
|
2156
|
-
classList.push('root-child-node');
|
|
2157
|
-
}
|
|
2158
1862
|
else {
|
|
2159
1863
|
classList.push('child-node');
|
|
2160
1864
|
}
|
|
2161
1865
|
// COMPAT: last character can not show in safari browser
|
|
2162
|
-
return drawRichtext(x, y, width, height,
|
|
1866
|
+
return drawRichtext(rectangle.x, rectangle.y, rectangle.width, rectangle.height, element.data.topic, containerRef, classList);
|
|
2163
1867
|
}
|
|
2164
1868
|
function updateMindNodeTopicSize(board, node, g, isEditable) {
|
|
2165
|
-
const { x, y, width, height } =
|
|
1869
|
+
const { x, y, width, height } = getTopicRectangleByNode(board, node);
|
|
2166
1870
|
if (isEditable) {
|
|
2167
1871
|
// add 999, avoid changing lines when paste more text
|
|
2168
1872
|
updateForeignObject(g, width + 999, height + 999, x, y);
|
|
@@ -2172,28 +1876,6 @@ function updateMindNodeTopicSize(board, node, g, isEditable) {
|
|
|
2172
1876
|
updateForeignObject(g, width, height, x, y);
|
|
2173
1877
|
}
|
|
2174
1878
|
}
|
|
2175
|
-
function getRichtextRectangleByNode(board, node) {
|
|
2176
|
-
let { x, y } = getRectangleByNode(node);
|
|
2177
|
-
x = x + NodeSpace.getTextLeftSpace(board, node.origin);
|
|
2178
|
-
y = y + NodeSpace.getTextTopSpace(node.origin);
|
|
2179
|
-
const width = Math.ceil(node.origin.width);
|
|
2180
|
-
const height = Math.ceil(node.origin.height);
|
|
2181
|
-
return { height, width, x, y };
|
|
2182
|
-
}
|
|
2183
|
-
|
|
2184
|
-
function drawRectangleNode(board, node) {
|
|
2185
|
-
const { x, y, width, height } = getRectangleByNode(node);
|
|
2186
|
-
const fill = node.origin.fill ? node.origin.fill : node.origin.isRoot ? DefaultRootStyle.fill : DefaultNodeStyle.fill;
|
|
2187
|
-
const stroke = getStrokeByMindElement(board, node.origin);
|
|
2188
|
-
const strokeWidth = node.origin.strokeWidth ? node.origin.strokeWidth : DefaultNodeStyle.strokeWidth;
|
|
2189
|
-
const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), x, y, x + width, y + height, {
|
|
2190
|
-
stroke,
|
|
2191
|
-
strokeWidth,
|
|
2192
|
-
fill,
|
|
2193
|
-
fillStyle: 'solid'
|
|
2194
|
-
});
|
|
2195
|
-
return nodeG;
|
|
2196
|
-
}
|
|
2197
1879
|
|
|
2198
1880
|
function drawAbstractLink(board, node, isHorizontal) {
|
|
2199
1881
|
const linkPadding = 15;
|
|
@@ -2215,18 +1897,12 @@ function drawAbstractLink(board, node, isHorizontal) {
|
|
|
2215
1897
|
let bezierBeginPoint = getPointByPlacement(includedElementsRectangle, bezierBeginPlacement);
|
|
2216
1898
|
let bezierEndPoint = getPointByPlacement(includedElementsRectangle, bezierEndPlacement);
|
|
2217
1899
|
let abstractConnectorPoint = getPointByPlacement(abstractRectangle, abstractConnectorPlacement);
|
|
2218
|
-
let curveDistance =
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
}
|
|
2225
|
-
bezierBeginPoint = movePoint(bezierBeginPoint, linkPadding, linkDirection);
|
|
2226
|
-
let c1 = movePoint(bezierBeginPoint, curveDistance, linkDirection);
|
|
2227
|
-
bezierEndPoint = movePoint(bezierEndPoint, linkPadding, linkDirection);
|
|
2228
|
-
let c2 = movePoint(bezierEndPoint, curveDistance, linkDirection);
|
|
2229
|
-
let bezierConnectorPoint = movePoint(abstractConnectorPoint, -linkPadding, linkDirection);
|
|
1900
|
+
let curveDistance = getXDistanceBetweenPoint(abstractConnectorPoint, bezierBeginPoint, isHorizontal) - linkPadding * 2;
|
|
1901
|
+
bezierBeginPoint = moveXOfPoint(bezierBeginPoint, linkPadding, linkDirection);
|
|
1902
|
+
let c1 = moveXOfPoint(bezierBeginPoint, curveDistance, linkDirection);
|
|
1903
|
+
bezierEndPoint = moveXOfPoint(bezierEndPoint, linkPadding, linkDirection);
|
|
1904
|
+
let c2 = moveXOfPoint(bezierEndPoint, curveDistance, linkDirection);
|
|
1905
|
+
let bezierConnectorPoint = moveXOfPoint(abstractConnectorPoint, -linkPadding, linkDirection);
|
|
2230
1906
|
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]}`, {
|
|
2231
1907
|
stroke: branchColor,
|
|
2232
1908
|
strokeWidth: branchWidth
|
|
@@ -2270,37 +1946,235 @@ class EmojisDrawer {
|
|
|
2270
1946
|
this.viewContainerRef = viewContainerRef;
|
|
2271
1947
|
this.emojiDrawers = [];
|
|
2272
1948
|
}
|
|
2273
|
-
drawEmojis(element) {
|
|
2274
|
-
this.destroy();
|
|
2275
|
-
if (MindElement.hasEmojis(element)) {
|
|
2276
|
-
this.g = createG();
|
|
2277
|
-
this.g.classList.add('emojis');
|
|
2278
|
-
const foreignRectangle = getEmojiForeignRectangle(this.board, element);
|
|
2279
|
-
const foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
|
|
2280
|
-
this.g.append(foreignObject);
|
|
2281
|
-
const container = document.createElement('div');
|
|
2282
|
-
container.classList.add('node-emojis-container');
|
|
2283
|
-
foreignObject.append(container);
|
|
2284
|
-
this.emojiDrawers = element.data.emojis.map(emojiItem => {
|
|
2285
|
-
const drawer = new EmojiDrawer(this.board, this.viewContainerRef);
|
|
2286
|
-
drawer.draw(emojiItem, element);
|
|
2287
|
-
return drawer;
|
|
2288
|
-
});
|
|
2289
|
-
this.emojiDrawers.forEach(drawer => {
|
|
2290
|
-
container.append(drawer.nativeElement);
|
|
2291
|
-
});
|
|
2292
|
-
return this.g;
|
|
1949
|
+
drawEmojis(element) {
|
|
1950
|
+
this.destroy();
|
|
1951
|
+
if (MindElement.hasEmojis(element)) {
|
|
1952
|
+
this.g = createG();
|
|
1953
|
+
this.g.classList.add('emojis');
|
|
1954
|
+
const foreignRectangle = getEmojiForeignRectangle(this.board, element);
|
|
1955
|
+
const foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
|
|
1956
|
+
this.g.append(foreignObject);
|
|
1957
|
+
const container = document.createElement('div');
|
|
1958
|
+
container.classList.add('node-emojis-container');
|
|
1959
|
+
foreignObject.append(container);
|
|
1960
|
+
this.emojiDrawers = element.data.emojis.map(emojiItem => {
|
|
1961
|
+
const drawer = new EmojiDrawer(this.board, this.viewContainerRef);
|
|
1962
|
+
drawer.draw(emojiItem, element);
|
|
1963
|
+
return drawer;
|
|
1964
|
+
});
|
|
1965
|
+
this.emojiDrawers.forEach(drawer => {
|
|
1966
|
+
container.append(drawer.nativeElement);
|
|
1967
|
+
});
|
|
1968
|
+
return this.g;
|
|
1969
|
+
}
|
|
1970
|
+
return undefined;
|
|
1971
|
+
}
|
|
1972
|
+
destroy() {
|
|
1973
|
+
if (this.g) {
|
|
1974
|
+
this.g.remove();
|
|
1975
|
+
}
|
|
1976
|
+
this.emojiDrawers.forEach(drawer => drawer.destroy());
|
|
1977
|
+
this.emojiDrawers = [];
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
const setAbstractsByRefs = (board, abstractRefs) => {
|
|
1982
|
+
abstractRefs.forEach((newProperty, element) => {
|
|
1983
|
+
const start = element.start + newProperty.start;
|
|
1984
|
+
const end = element.end + newProperty.end;
|
|
1985
|
+
const path = PlaitBoard.findPath(board, element);
|
|
1986
|
+
if (start > end) {
|
|
1987
|
+
Transforms.removeNode(board, path);
|
|
1988
|
+
}
|
|
1989
|
+
else {
|
|
1990
|
+
Transforms.setNode(board, { start, end }, path);
|
|
1991
|
+
}
|
|
1992
|
+
});
|
|
1993
|
+
};
|
|
1994
|
+
const setAbstractByStandardLayout = (board, element) => {
|
|
1995
|
+
const rightNodeCount = element.rightNodeCount;
|
|
1996
|
+
const abstract = element.children.find(child => {
|
|
1997
|
+
return AbstractNode.isAbstract(child) && child.end >= rightNodeCount && child.start < rightNodeCount;
|
|
1998
|
+
});
|
|
1999
|
+
if (abstract) {
|
|
2000
|
+
const path = PlaitBoard.findPath(board, abstract);
|
|
2001
|
+
Transforms.setNode(board, { end: rightNodeCount - 1 }, path);
|
|
2002
|
+
}
|
|
2003
|
+
};
|
|
2004
|
+
const insertAbstract = (board, elements) => {
|
|
2005
|
+
let elementGroup = getFirstLevelElement(elements);
|
|
2006
|
+
const { parentElements, abstractIncludedGroups } = divideElementByParent(elementGroup);
|
|
2007
|
+
abstractIncludedGroups.forEach((group, index) => {
|
|
2008
|
+
const groupParent = parentElements[index];
|
|
2009
|
+
setAbstractByElements(board, groupParent, group);
|
|
2010
|
+
});
|
|
2011
|
+
};
|
|
2012
|
+
const setAbstractByElements = (board, groupParent, group) => {
|
|
2013
|
+
const indexArray = group.map(child => groupParent.children.indexOf(child)).sort((a, b) => a - b);
|
|
2014
|
+
const rightNodeCount = groupParent === null || groupParent === void 0 ? void 0 : groupParent.rightNodeCount;
|
|
2015
|
+
const start = indexArray[0], end = indexArray[indexArray.length - 1];
|
|
2016
|
+
if (isStandardLayout(MindQueries.getLayoutByElement(groupParent)) &&
|
|
2017
|
+
rightNodeCount &&
|
|
2018
|
+
start < rightNodeCount &&
|
|
2019
|
+
end >= rightNodeCount) {
|
|
2020
|
+
const childrenLength = groupParent.children.length;
|
|
2021
|
+
const path = [...PlaitBoard.findPath(board, groupParent), childrenLength];
|
|
2022
|
+
const leftChildren = indexArray.filter(index => index >= rightNodeCount);
|
|
2023
|
+
const rightChildren = indexArray.filter(index => index < rightNodeCount);
|
|
2024
|
+
insertAbstractNode(board, path, rightChildren[0], rightChildren[rightChildren.length - 1]);
|
|
2025
|
+
insertAbstractNode(board, Path.next(path), leftChildren[0], leftChildren[leftChildren.length - 1]);
|
|
2026
|
+
}
|
|
2027
|
+
else {
|
|
2028
|
+
const path = [...PlaitBoard.findPath(board, groupParent), groupParent.children.length];
|
|
2029
|
+
insertAbstractNode(board, path, start, end);
|
|
2030
|
+
}
|
|
2031
|
+
};
|
|
2032
|
+
const insertAbstractNode = (board, path, start, end) => {
|
|
2033
|
+
const mindElement = createMindElement('概要', 28, 20, {
|
|
2034
|
+
strokeColor: DefaultAbstractNodeStyle.strokeColor,
|
|
2035
|
+
strokeWidth: DefaultAbstractNodeStyle.branchWidth,
|
|
2036
|
+
branchColor: DefaultAbstractNodeStyle.branchColor,
|
|
2037
|
+
branchWidth: DefaultAbstractNodeStyle.branchWidth
|
|
2038
|
+
});
|
|
2039
|
+
mindElement.start = start;
|
|
2040
|
+
mindElement.end = end;
|
|
2041
|
+
Transforms.insertNode(board, mindElement, path);
|
|
2042
|
+
};
|
|
2043
|
+
|
|
2044
|
+
const setLayout = (board, layout, path) => {
|
|
2045
|
+
correctLogicLayoutNode(board, layout, path);
|
|
2046
|
+
const element = PlaitNode.get(board, path);
|
|
2047
|
+
if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
|
|
2048
|
+
MindTransforms.setAbstractByStandardLayout(board, element);
|
|
2049
|
+
}
|
|
2050
|
+
Transforms.setNode(board, { layout }, path);
|
|
2051
|
+
};
|
|
2052
|
+
const correctLogicLayoutNode = (board, layout, path) => {
|
|
2053
|
+
var _a;
|
|
2054
|
+
const node = PlaitNode.get(board, path);
|
|
2055
|
+
if (node && layout) {
|
|
2056
|
+
(_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach((value, index) => {
|
|
2057
|
+
var _a;
|
|
2058
|
+
if (value.layout) {
|
|
2059
|
+
if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
|
|
2060
|
+
(isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
|
|
2061
|
+
Transforms.setNode(board, { layout: null }, [...path, index]);
|
|
2062
|
+
}
|
|
2063
|
+
if ((_a = value.children) === null || _a === void 0 ? void 0 : _a.length) {
|
|
2064
|
+
correctLogicLayoutNode(board, layout, [...path, index]);
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
};
|
|
2070
|
+
|
|
2071
|
+
const setTopic = (board, element, topic, width, height) => {
|
|
2072
|
+
const newElement = {
|
|
2073
|
+
data: { topic },
|
|
2074
|
+
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
2075
|
+
height: height / board.viewport.zoom
|
|
2076
|
+
};
|
|
2077
|
+
if (MindElement.hasEmojis(element)) {
|
|
2078
|
+
newElement.data.emojis = element.data.emojis;
|
|
2079
|
+
}
|
|
2080
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2081
|
+
Transforms.setNode(board, newElement, path);
|
|
2082
|
+
};
|
|
2083
|
+
const setTopicSize = (board, element, width, height) => {
|
|
2084
|
+
const newElement = {
|
|
2085
|
+
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
2086
|
+
height: height / board.viewport.zoom
|
|
2087
|
+
};
|
|
2088
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2089
|
+
Transforms.setNode(board, newElement, path);
|
|
2090
|
+
};
|
|
2091
|
+
const removeElements = (board, elements) => {
|
|
2092
|
+
const deletableElements = getFirstLevelElement(elements).reverse();
|
|
2093
|
+
//翻转,从下到上修改,防止找不到 path
|
|
2094
|
+
deletableElements
|
|
2095
|
+
.map(element => {
|
|
2096
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2097
|
+
return () => {
|
|
2098
|
+
if (isInRightBranchOfStandardLayout(element)) {
|
|
2099
|
+
changeRightNodeCount(board, path.slice(0, 1), -1);
|
|
2100
|
+
}
|
|
2101
|
+
Transforms.removeNode(board, path);
|
|
2102
|
+
};
|
|
2103
|
+
})
|
|
2104
|
+
.forEach(action => {
|
|
2105
|
+
action();
|
|
2106
|
+
});
|
|
2107
|
+
};
|
|
2108
|
+
const insertNodes = (board, elements, path) => {
|
|
2109
|
+
const pathRef = board.pathRef(path);
|
|
2110
|
+
elements.forEach(element => {
|
|
2111
|
+
if (pathRef.current) {
|
|
2112
|
+
Transforms.insertNode(board, element, pathRef.current);
|
|
2293
2113
|
}
|
|
2294
|
-
|
|
2114
|
+
});
|
|
2115
|
+
pathRef.unref();
|
|
2116
|
+
};
|
|
2117
|
+
const insertAbstractNodes = (board, validAbstractRefs, elements, path) => {
|
|
2118
|
+
var _a;
|
|
2119
|
+
const parent = PlaitNode.get(board, Path$1.parent(path));
|
|
2120
|
+
const abstractPath = [...Path$1.parent(path), (_a = parent.children) === null || _a === void 0 ? void 0 : _a.length];
|
|
2121
|
+
const abstracts = validAbstractRefs.map(refs => {
|
|
2122
|
+
const { start, end } = getRelativeStartEndByAbstractRef(refs, elements);
|
|
2123
|
+
return Object.assign(Object.assign({}, refs.abstract), { start: start + path[path.length - 1], end: end + path[path.length - 1] });
|
|
2124
|
+
});
|
|
2125
|
+
insertNodes(board, abstracts, abstractPath);
|
|
2126
|
+
};
|
|
2127
|
+
|
|
2128
|
+
const addEmoji = (board, element, emojiItem) => {
|
|
2129
|
+
const emojis = element.data.emojis || [];
|
|
2130
|
+
const newEmojis = [...emojis];
|
|
2131
|
+
newEmojis.push(emojiItem);
|
|
2132
|
+
const newElement = {
|
|
2133
|
+
data: { topic: element.data.topic, emojis: newEmojis }
|
|
2134
|
+
};
|
|
2135
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2136
|
+
Transforms.setNode(board, newElement, path);
|
|
2137
|
+
};
|
|
2138
|
+
const removeEmoji = (board, element, emojiItem) => {
|
|
2139
|
+
const emojis = element.data.emojis.filter(value => value !== emojiItem);
|
|
2140
|
+
const newElement = {
|
|
2141
|
+
data: { topic: element.data.topic }
|
|
2142
|
+
};
|
|
2143
|
+
if (emojis.length > 0) {
|
|
2144
|
+
newElement.data.emojis = emojis;
|
|
2295
2145
|
}
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2146
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2147
|
+
Transforms.setNode(board, newElement, path);
|
|
2148
|
+
};
|
|
2149
|
+
const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
2150
|
+
const newElement = {
|
|
2151
|
+
data: { topic: element.data.topic }
|
|
2152
|
+
};
|
|
2153
|
+
const newEmojis = element.data.emojis.map(value => {
|
|
2154
|
+
if (value === oldEmoji) {
|
|
2155
|
+
return newEmoji;
|
|
2299
2156
|
}
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2157
|
+
return value;
|
|
2158
|
+
});
|
|
2159
|
+
newElement.data.emojis = newEmojis;
|
|
2160
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2161
|
+
Transforms.setNode(board, newElement, path);
|
|
2162
|
+
};
|
|
2163
|
+
|
|
2164
|
+
const MindTransforms = {
|
|
2165
|
+
setLayout,
|
|
2166
|
+
setTopic,
|
|
2167
|
+
setTopicSize,
|
|
2168
|
+
addEmoji,
|
|
2169
|
+
removeEmoji,
|
|
2170
|
+
replaceEmoji,
|
|
2171
|
+
insertAbstract,
|
|
2172
|
+
setAbstractsByRefs,
|
|
2173
|
+
setAbstractByStandardLayout,
|
|
2174
|
+
removeElements,
|
|
2175
|
+
insertNodes,
|
|
2176
|
+
insertAbstractNodes
|
|
2177
|
+
};
|
|
2304
2178
|
|
|
2305
2179
|
function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
|
|
2306
2180
|
const abstractIncludedG = createG();
|
|
@@ -2325,10 +2199,10 @@ function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosit
|
|
|
2325
2199
|
transformPlacement(endPlacement, linkDirection);
|
|
2326
2200
|
let startCenterPoint = getPointByPlacement(abstractRectangle, startPlacement);
|
|
2327
2201
|
let endCenterPoint = getPointByPlacement(abstractRectangle, endPlacement);
|
|
2328
|
-
const startPoint1 =
|
|
2329
|
-
const startPoint2 =
|
|
2330
|
-
const endPoint1 =
|
|
2331
|
-
const endPoint2 =
|
|
2202
|
+
const startPoint1 = moveXOfPoint(startCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2203
|
+
const startPoint2 = moveXOfPoint(startCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2204
|
+
const endPoint1 = moveXOfPoint(endCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2205
|
+
const endPoint2 = moveXOfPoint(endCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
|
|
2332
2206
|
const startHandle = roughSVG.line(startPoint1[0], startPoint1[1], startPoint2[0], startPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.start));
|
|
2333
2207
|
const endHandle = roughSVG.line(endPoint1[0], endPoint1[1], endPoint2[0], endPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.end));
|
|
2334
2208
|
changeBoardClass(board, activeHandlePosition, isHorizontal);
|
|
@@ -2681,7 +2555,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2681
2555
|
const shape = getShapeByElement(this.board, this.node.origin);
|
|
2682
2556
|
switch (shape) {
|
|
2683
2557
|
case MindElementShape.roundRectangle:
|
|
2684
|
-
this.shapeG =
|
|
2558
|
+
this.shapeG = drawRoundRectangleByNode(this.board, this.node);
|
|
2685
2559
|
this.g.prepend(this.shapeG);
|
|
2686
2560
|
break;
|
|
2687
2561
|
default:
|
|
@@ -2838,7 +2712,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2838
2712
|
}
|
|
2839
2713
|
}
|
|
2840
2714
|
drawRichtext() {
|
|
2841
|
-
const { richtextG, richtextComponentRef, foreignObject } =
|
|
2715
|
+
const { richtextG, richtextComponentRef, foreignObject } = drawTopicByNode(this.board, this.node, this.viewContainerRef);
|
|
2842
2716
|
this.richtextComponentRef = richtextComponentRef;
|
|
2843
2717
|
this.richtextG = richtextG;
|
|
2844
2718
|
this.foreignObject = foreignObject;
|
|
@@ -2859,7 +2733,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2859
2733
|
}
|
|
2860
2734
|
// interactive
|
|
2861
2735
|
fromEvent(collapseG, 'mouseup')
|
|
2862
|
-
.pipe(filter(() => !this.handActive || this.board
|
|
2736
|
+
.pipe(filter(() => !this.handActive || !PlaitBoard.isReadonly(this.board)), take(1))
|
|
2863
2737
|
.subscribe(() => {
|
|
2864
2738
|
const isCollapsed = !this.node.origin.isCollapsed;
|
|
2865
2739
|
const newElement = { isCollapsed };
|
|
@@ -3041,7 +2915,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
3041
2915
|
});
|
|
3042
2916
|
const mousedown$ = fromEvent(document, 'mousedown').subscribe((event) => {
|
|
3043
2917
|
const point = transformPoint(this.board, toPoint(event.x, event.y, PlaitBoard.getHost(this.board)));
|
|
3044
|
-
const clickInNode =
|
|
2918
|
+
const clickInNode = isHitMindElement(this.board, point, this.element);
|
|
3045
2919
|
if (clickInNode && !hasEditableTarget(richtextInstance.editor, event.target)) {
|
|
3046
2920
|
event.preventDefault();
|
|
3047
2921
|
}
|
|
@@ -3106,6 +2980,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
3106
2980
|
super.ngOnDestroy();
|
|
3107
2981
|
(_a = this.abstractIncludedOutlineG) === null || _a === void 0 ? void 0 : _a.remove();
|
|
3108
2982
|
this.destroyRichtext();
|
|
2983
|
+
this.emojisDrawer.destroy();
|
|
3109
2984
|
this.destroy$.next();
|
|
3110
2985
|
this.destroy$.complete();
|
|
3111
2986
|
if (ELEMENT_TO_NODE.get(this.element) === this.node) {
|
|
@@ -3160,7 +3035,7 @@ const getLayoutOptions = (board) => {
|
|
|
3160
3035
|
}
|
|
3161
3036
|
return {
|
|
3162
3037
|
getHeight(element) {
|
|
3163
|
-
return NodeSpace.getNodeHeight(element);
|
|
3038
|
+
return NodeSpace.getNodeHeight(board, element);
|
|
3164
3039
|
},
|
|
3165
3040
|
getWidth(element) {
|
|
3166
3041
|
return NodeSpace.getNodeWidth(board, element);
|
|
@@ -3251,142 +3126,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3251
3126
|
class MindModule {
|
|
3252
3127
|
}
|
|
3253
3128
|
MindModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3254
|
-
MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [
|
|
3255
|
-
MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [
|
|
3129
|
+
MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [CommonModule, RichtextModule, PlaitModule], exports: [PlaitMindComponent, MindNodeComponent] });
|
|
3130
|
+
MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule, RichtextModule, PlaitModule] });
|
|
3256
3131
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, decorators: [{
|
|
3257
3132
|
type: NgModule,
|
|
3258
3133
|
args: [{
|
|
3259
3134
|
declarations: [PlaitMindComponent, MindNodeComponent],
|
|
3260
|
-
imports: [
|
|
3135
|
+
imports: [CommonModule, RichtextModule, PlaitModule],
|
|
3261
3136
|
exports: [PlaitMindComponent, MindNodeComponent]
|
|
3262
3137
|
}]
|
|
3263
3138
|
}] });
|
|
3264
3139
|
|
|
3265
|
-
const isValidTarget = (origin, target) => {
|
|
3266
|
-
return origin !== target && !isChildElement(origin, target);
|
|
3267
|
-
};
|
|
3268
|
-
const addActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3269
|
-
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3270
|
-
if (isOrigin) {
|
|
3271
|
-
activeComponent.g.classList.add('dragging-origin');
|
|
3272
|
-
}
|
|
3273
|
-
else {
|
|
3274
|
-
activeComponent.g.classList.add('dragging-child');
|
|
3275
|
-
}
|
|
3276
|
-
!activeElement.isCollapsed &&
|
|
3277
|
-
activeElement.children.forEach(child => {
|
|
3278
|
-
addActiveOnDragOrigin(child, false);
|
|
3279
|
-
});
|
|
3280
|
-
};
|
|
3281
|
-
const removeActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3282
|
-
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3283
|
-
if (isOrigin) {
|
|
3284
|
-
activeComponent.g.classList.remove('dragging-origin');
|
|
3285
|
-
}
|
|
3286
|
-
else {
|
|
3287
|
-
activeComponent.g.classList.remove('dragging-child');
|
|
3288
|
-
}
|
|
3289
|
-
!activeElement.isCollapsed &&
|
|
3290
|
-
activeElement.children.forEach(child => {
|
|
3291
|
-
removeActiveOnDragOrigin(child, false);
|
|
3292
|
-
});
|
|
3293
|
-
};
|
|
3294
|
-
const updatePathByLayoutAndDropTarget = (targetPath, layout, dropTarget) => {
|
|
3295
|
-
// 上下布局:左右是兄弟节点,上下是子节点
|
|
3296
|
-
if (isVerticalLogicLayout(layout)) {
|
|
3297
|
-
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3298
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3299
|
-
}
|
|
3300
|
-
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3301
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3302
|
-
}
|
|
3303
|
-
// 如果是左,位置不变,右则插入到下一个兄弟节点
|
|
3304
|
-
if (dropTarget.detectResult === 'right') {
|
|
3305
|
-
targetPath = Path.next(targetPath);
|
|
3306
|
-
}
|
|
3307
|
-
}
|
|
3308
|
-
// 水平布局/标准布局:上下是兄弟节点,左右是子节点
|
|
3309
|
-
if (isHorizontalLogicLayout(layout)) {
|
|
3310
|
-
if (dropTarget.detectResult === 'right') {
|
|
3311
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3312
|
-
}
|
|
3313
|
-
if (dropTarget.detectResult === 'left') {
|
|
3314
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3315
|
-
}
|
|
3316
|
-
// 如果是上,位置不变,下插入到下一个兄弟节点
|
|
3317
|
-
if (dropTarget.detectResult === 'bottom') {
|
|
3318
|
-
targetPath = Path.next(targetPath);
|
|
3319
|
-
}
|
|
3320
|
-
}
|
|
3321
|
-
// 缩进布局:上下是兄弟节点,左右是子节点,但上(左上/右上),探测到上是子节点,下则位置不变,反之同理。
|
|
3322
|
-
if (isIndentedLayout(layout)) {
|
|
3323
|
-
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3324
|
-
targetPath = Path.next(targetPath);
|
|
3325
|
-
}
|
|
3326
|
-
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3327
|
-
targetPath = Path.next(targetPath);
|
|
3328
|
-
}
|
|
3329
|
-
if (isLeftLayout(layout) && dropTarget.detectResult === 'left') {
|
|
3330
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3331
|
-
}
|
|
3332
|
-
if (isRightLayout(layout) && dropTarget.detectResult === 'right') {
|
|
3333
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3334
|
-
}
|
|
3335
|
-
}
|
|
3336
|
-
return targetPath;
|
|
3337
|
-
};
|
|
3338
|
-
const updateRightNodeCount = (board, activeComponent, targetComponent, detectResult) => {
|
|
3339
|
-
var _a;
|
|
3340
|
-
let rightNodeCount;
|
|
3341
|
-
const mindElement = findUpElement(targetComponent.node.origin).root;
|
|
3342
|
-
const mindComponent = ELEMENT_TO_COMPONENT.get(mindElement);
|
|
3343
|
-
const activeIndex = mindComponent === null || mindComponent === void 0 ? void 0 : mindComponent.root.children.indexOf(activeComponent.node);
|
|
3344
|
-
const targetIndex = mindComponent === null || mindComponent === void 0 ? void 0 : mindComponent.root.children.indexOf(targetComponent.node);
|
|
3345
|
-
const activeParent = MindElement.getParent(activeComponent.element);
|
|
3346
|
-
const targetParent = MindElement.findParent(targetComponent.element);
|
|
3347
|
-
const isActiveOnRight = activeIndex !== -1 && activeIndex <= activeParent.rightNodeCount - 1;
|
|
3348
|
-
const isTargetOnRight = targetParent && targetIndex !== -1 && targetIndex <= targetParent.rightNodeCount - 1;
|
|
3349
|
-
const isBothOnRight = isActiveOnRight && isTargetOnRight;
|
|
3350
|
-
const rootChildCount = (_a = mindComponent.root.children) === null || _a === void 0 ? void 0 : _a.length;
|
|
3351
|
-
const rootRightNodeCount = mindComponent === null || mindComponent === void 0 ? void 0 : mindComponent.root.origin.rightNodeCount;
|
|
3352
|
-
if (!isBothOnRight) {
|
|
3353
|
-
if (isActiveOnRight) {
|
|
3354
|
-
rightNodeCount = rootChildCount < rootRightNodeCount ? rootChildCount - 1 : rootRightNodeCount - 1;
|
|
3355
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, activeParent));
|
|
3356
|
-
}
|
|
3357
|
-
if (isTargetOnRight && detectResult !== 'right') {
|
|
3358
|
-
rightNodeCount = rootChildCount < rootRightNodeCount ? rootRightNodeCount : rootRightNodeCount + 1;
|
|
3359
|
-
const parent = MindElement.getParent(targetComponent.element);
|
|
3360
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, parent));
|
|
3361
|
-
}
|
|
3362
|
-
//二级子节点拖动到根节点左侧
|
|
3363
|
-
if (targetComponent.node.origin.isRoot && detectResult === 'left' && activeIndex === -1) {
|
|
3364
|
-
rightNodeCount = rootChildCount;
|
|
3365
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, targetComponent.element));
|
|
3366
|
-
}
|
|
3367
|
-
}
|
|
3368
|
-
};
|
|
3369
|
-
const IS_DRAGGING = new WeakMap();
|
|
3370
|
-
const isDragging = (board) => {
|
|
3371
|
-
return !!IS_DRAGGING.get(board);
|
|
3372
|
-
};
|
|
3373
|
-
const setIsDragging = (board, state) => {
|
|
3374
|
-
IS_DRAGGING.set(board, state);
|
|
3375
|
-
};
|
|
3376
|
-
const updateAbstractInDnd = (board, deletableElements, originPath) => {
|
|
3377
|
-
const refs = insertElementHandleAbstract(board, originPath, false);
|
|
3378
|
-
deleteElementHandleAbstract(board, deletableElements, refs);
|
|
3379
|
-
MindTransforms.setAbstractsByRefs(board, refs);
|
|
3380
|
-
};
|
|
3381
|
-
|
|
3382
3140
|
const DRAG_MOVE_BUFFER = 5;
|
|
3383
3141
|
const withDnd = (board) => {
|
|
3384
|
-
const { mousedown, mousemove, globalMouseup
|
|
3385
|
-
let
|
|
3142
|
+
const { mousedown, mousemove, globalMouseup } = board;
|
|
3143
|
+
let activeElements = [];
|
|
3144
|
+
let correspondingElements = [];
|
|
3386
3145
|
let startPoint;
|
|
3387
|
-
let
|
|
3146
|
+
let dragFakeNodeG;
|
|
3388
3147
|
let fakeDropNodeG;
|
|
3389
3148
|
let dropTarget = null;
|
|
3149
|
+
let targetPath;
|
|
3390
3150
|
board.mousedown = (event) => {
|
|
3391
3151
|
if (board.options.readonly || IS_TEXT_EDITABLE.get(board) || event.button === 2) {
|
|
3392
3152
|
mousedown(event);
|
|
@@ -3395,152 +3155,137 @@ const withDnd = (board) => {
|
|
|
3395
3155
|
// 确认是否 hit 节点
|
|
3396
3156
|
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
3397
3157
|
const selectedElements = getSelectedElements(board);
|
|
3398
|
-
board
|
|
3399
|
-
if (
|
|
3158
|
+
depthFirstRecursion(board, element => {
|
|
3159
|
+
if (activeElements.length || !MindElement.isMindElement(board, element)) {
|
|
3400
3160
|
return;
|
|
3401
3161
|
}
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3162
|
+
const isHitElement = isHitMindElement(board, point, element) && !element.isRoot && !AbstractNode.isAbstract(element);
|
|
3163
|
+
const isAllMindElement = selectedElements.every(element => MindElement.isMindElement(board, element));
|
|
3164
|
+
const isMultiple = isHitElement && selectedElements.length > 1 && selectedElements.includes(element) && isAllMindElement;
|
|
3165
|
+
const isSingle = isHitElement && !(selectedElements.length > 1 && selectedElements.includes(element));
|
|
3166
|
+
if (isSingle) {
|
|
3167
|
+
activeElements = [element];
|
|
3168
|
+
startPoint = point;
|
|
3169
|
+
}
|
|
3170
|
+
else if (isMultiple) {
|
|
3171
|
+
activeElements = getFirstLevelElement(selectedElements);
|
|
3172
|
+
startPoint = point;
|
|
3173
|
+
}
|
|
3174
|
+
}, node => {
|
|
3175
|
+
if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
|
|
3176
|
+
return true;
|
|
3177
|
+
}
|
|
3178
|
+
else {
|
|
3179
|
+
return false;
|
|
3418
3180
|
}
|
|
3419
3181
|
});
|
|
3420
|
-
if (
|
|
3421
|
-
|
|
3182
|
+
if (activeElements.length) {
|
|
3183
|
+
correspondingElements = getOverallAbstracts(board, activeElements);
|
|
3422
3184
|
}
|
|
3423
3185
|
mousedown(event);
|
|
3424
3186
|
};
|
|
3425
3187
|
board.mousemove = (event) => {
|
|
3426
|
-
|
|
3427
|
-
if (!board.options.readonly && activeElement && startPoint) {
|
|
3188
|
+
if (!board.options.readonly && (activeElements === null || activeElements === void 0 ? void 0 : activeElements.length) && startPoint) {
|
|
3428
3189
|
const endPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
3429
3190
|
const distance = distanceBetweenPointAndPoint(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
|
|
3430
3191
|
if (distance < DRAG_MOVE_BUFFER) {
|
|
3431
3192
|
return;
|
|
3432
3193
|
}
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3194
|
+
setIsDragging(board, true);
|
|
3195
|
+
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.remove();
|
|
3196
|
+
const detectPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
3197
|
+
dropTarget = detectDropTarget(board, detectPoint, dropTarget, [...activeElements, ...correspondingElements]);
|
|
3198
|
+
if (dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target) {
|
|
3199
|
+
targetPath = getPathByDropTarget(board, dropTarget);
|
|
3200
|
+
fakeDropNodeG = drawFakeDropNodeByPath(board, dropTarget.target, targetPath);
|
|
3439
3201
|
PlaitBoard.getHost(board).appendChild(fakeDropNodeG);
|
|
3440
|
-
PlaitBoard.getHost(board).appendChild(fakeDragNodeG);
|
|
3441
|
-
}
|
|
3442
|
-
else {
|
|
3443
|
-
if (fakeDragNodeG) {
|
|
3444
|
-
fakeDragNodeG.innerHTML = '';
|
|
3445
|
-
}
|
|
3446
|
-
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.childNodes.forEach(node => {
|
|
3447
|
-
node.remove();
|
|
3448
|
-
});
|
|
3449
3202
|
}
|
|
3450
|
-
// fake dragging origin node
|
|
3451
3203
|
const offsetX = endPoint[0] - startPoint[0];
|
|
3452
3204
|
const offsetY = endPoint[1] - startPoint[1];
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
// draw emojis
|
|
3462
|
-
if (MindElement.hasEmojis(activeElement)) {
|
|
3463
|
-
const fakeEmojisG = activeComponent.emojisDrawer.g.cloneNode(true);
|
|
3464
|
-
const foreignRectangle = getEmojiForeignRectangle(board, activeElement);
|
|
3465
|
-
updateForeignObject$1(fakeEmojisG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
|
|
3466
|
-
fakeDragNodeG === null || fakeDragNodeG === void 0 ? void 0 : fakeDragNodeG.append(fakeEmojisG);
|
|
3467
|
-
}
|
|
3468
|
-
// drop position detect
|
|
3469
|
-
const { x, y } = getRectangleByNode(fakeDraggingNode);
|
|
3470
|
-
const detectCenterPoint = [x + textRectangle.width / 2, y + textRectangle.height / 2];
|
|
3471
|
-
let detectResult = null;
|
|
3472
|
-
board.children.forEach((value) => {
|
|
3473
|
-
if (detectResult) {
|
|
3474
|
-
return;
|
|
3475
|
-
}
|
|
3476
|
-
if (PlaitMind.isMind(value)) {
|
|
3477
|
-
const mindmapComponent = ELEMENT_TO_COMPONENT.get(value);
|
|
3478
|
-
const root = mindmapComponent === null || mindmapComponent === void 0 ? void 0 : mindmapComponent.root;
|
|
3479
|
-
root.eachNode((node) => {
|
|
3480
|
-
if (detectResult) {
|
|
3481
|
-
return;
|
|
3482
|
-
}
|
|
3483
|
-
const directions = directionDetector(node, detectCenterPoint);
|
|
3484
|
-
if (directions) {
|
|
3485
|
-
detectResult = directionCorrector(board, node, directions);
|
|
3486
|
-
}
|
|
3487
|
-
dropTarget = null;
|
|
3488
|
-
if (detectResult && isValidTarget(activeComponent.node.origin, node.origin)) {
|
|
3489
|
-
dropTarget = { target: node.origin, detectResult: detectResult[0] };
|
|
3490
|
-
}
|
|
3491
|
-
});
|
|
3205
|
+
dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.remove();
|
|
3206
|
+
dragFakeNodeG = createG();
|
|
3207
|
+
[...activeElements, ...correspondingElements].forEach(element => {
|
|
3208
|
+
addActiveOnDragOrigin(element);
|
|
3209
|
+
if (activeElements.includes(element)) {
|
|
3210
|
+
const activeComponent = PlaitElement.getComponent(element);
|
|
3211
|
+
const nodeG = drawFakeDragNode(board, activeComponent, offsetX, offsetY);
|
|
3212
|
+
dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.appendChild(nodeG);
|
|
3492
3213
|
}
|
|
3493
3214
|
});
|
|
3494
|
-
|
|
3495
|
-
dropTarget = readjustmentDropTarget(board, dropTarget);
|
|
3496
|
-
drawPlaceholderDropNodeG(board, dropTarget, fakeDropNodeG);
|
|
3497
|
-
}
|
|
3215
|
+
PlaitBoard.getHost(board).appendChild(dragFakeNodeG);
|
|
3498
3216
|
}
|
|
3499
3217
|
mousemove(event);
|
|
3500
3218
|
};
|
|
3501
3219
|
board.globalMouseup = (event) => {
|
|
3502
|
-
if (!board.options.readonly &&
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
const
|
|
3509
|
-
const
|
|
3510
|
-
|
|
3511
|
-
const
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
targetPath = PlaitBoard.findPath(board, targetComponent.element);
|
|
3520
|
-
targetPath.push(0);
|
|
3521
|
-
const rightNodeCount = targetComponent.node.origin.rightNodeCount + 1;
|
|
3522
|
-
newElement = { isCollapsed: false, rightNodeCount };
|
|
3220
|
+
if (!board.options.readonly && (activeElements === null || activeElements === void 0 ? void 0 : activeElements.length)) {
|
|
3221
|
+
const elements = [...activeElements, ...correspondingElements];
|
|
3222
|
+
if (isDragging(board)) {
|
|
3223
|
+
elements.forEach(element => removeActiveOnDragOrigin(element));
|
|
3224
|
+
}
|
|
3225
|
+
if (dropTarget) {
|
|
3226
|
+
const targetPathRef = board.pathRef(targetPath);
|
|
3227
|
+
const targetElementPathRef = board.pathRef(PlaitBoard.findPath(board, dropTarget.target));
|
|
3228
|
+
const abstractRefs = getValidAbstractRefs(board, elements);
|
|
3229
|
+
const normalElements = elements
|
|
3230
|
+
.filter(element => !abstractRefs.some(refs => refs.abstract === element))
|
|
3231
|
+
.map(element => {
|
|
3232
|
+
if (AbstractNode.isAbstract(element)) {
|
|
3233
|
+
return adjustAbstractToNode(element);
|
|
3234
|
+
}
|
|
3235
|
+
if (PlaitMind.isMind(element)) {
|
|
3236
|
+
return adjustRootToNode(board, element);
|
|
3523
3237
|
}
|
|
3524
|
-
|
|
3238
|
+
return element;
|
|
3239
|
+
});
|
|
3240
|
+
const effectedAbstracts = deleteElementHandleAbstract(board, elements);
|
|
3241
|
+
insertElementHandleAbstract(board, targetPath, normalElements.length, false, effectedAbstracts);
|
|
3242
|
+
MindTransforms.setAbstractsByRefs(board, effectedAbstracts);
|
|
3243
|
+
MindTransforms.removeElements(board, elements);
|
|
3244
|
+
let insertPath = targetPathRef.current;
|
|
3245
|
+
const parentPath = Path.parent(targetPathRef.current || targetPath);
|
|
3246
|
+
if (!insertPath) {
|
|
3247
|
+
const parent = PlaitNode.get(board, parentPath);
|
|
3248
|
+
const children = getNonAbstractChildren(parent);
|
|
3249
|
+
insertPath = [...parentPath, children.length || 0];
|
|
3525
3250
|
}
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3251
|
+
MindTransforms.insertNodes(board, normalElements, insertPath);
|
|
3252
|
+
if (abstractRefs.length) {
|
|
3253
|
+
MindTransforms.insertAbstractNodes(board, abstractRefs, normalElements, insertPath);
|
|
3254
|
+
}
|
|
3255
|
+
const shouldChangeRoot = isInRightBranchOfStandardLayout(dropTarget === null || dropTarget === void 0 ? void 0 : dropTarget.target) &&
|
|
3256
|
+
targetElementPathRef.current &&
|
|
3257
|
+
(Path.isSibling(targetPath, targetElementPathRef.current) || Path.equals(targetPath, targetElementPathRef.current));
|
|
3258
|
+
if (shouldChangeRoot && targetElementPathRef.current) {
|
|
3259
|
+
changeRightNodeCount(board, targetElementPathRef.current.slice(0, 1), normalElements.length);
|
|
3260
|
+
}
|
|
3261
|
+
if (targetElementPathRef.current &&
|
|
3262
|
+
targetPathRef.current &&
|
|
3263
|
+
Path.isAncestor(targetElementPathRef.current, targetPathRef.current) &&
|
|
3264
|
+
dropTarget.target.isCollapsed) {
|
|
3265
|
+
Transforms.setNode(board, { isCollapsed: false }, targetElementPathRef.current);
|
|
3266
|
+
}
|
|
3267
|
+
targetElementPathRef.unref();
|
|
3268
|
+
targetPathRef.unref();
|
|
3269
|
+
const selectedElements = getSelectedElements(board);
|
|
3270
|
+
let setActiveElements = [];
|
|
3271
|
+
depthFirstRecursion(board, node => {
|
|
3272
|
+
const isSelected = selectedElements.some(element => element.id === node.id);
|
|
3273
|
+
if (isSelected) {
|
|
3274
|
+
setActiveElements.push(node);
|
|
3275
|
+
}
|
|
3276
|
+
});
|
|
3277
|
+
Transforms.setSelectionWithTemporaryElements(board, setActiveElements);
|
|
3530
3278
|
}
|
|
3531
3279
|
setIsDragging(board, false);
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3280
|
+
activeElements = [];
|
|
3281
|
+
dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.remove();
|
|
3282
|
+
dragFakeNodeG = undefined;
|
|
3535
3283
|
fakeDropNodeG === null || fakeDropNodeG === void 0 ? void 0 : fakeDropNodeG.remove();
|
|
3536
3284
|
fakeDropNodeG = undefined;
|
|
3537
3285
|
dropTarget = null;
|
|
3538
3286
|
}
|
|
3539
3287
|
globalMouseup(event);
|
|
3540
3288
|
};
|
|
3541
|
-
board.keydown = (event) => {
|
|
3542
|
-
keydown(event);
|
|
3543
|
-
};
|
|
3544
3289
|
return board;
|
|
3545
3290
|
};
|
|
3546
3291
|
|
|
@@ -3548,16 +3293,11 @@ const buildClipboardData = (board, selectedElements) => {
|
|
|
3548
3293
|
let result = [];
|
|
3549
3294
|
// get overall abstract
|
|
3550
3295
|
const overallAbstracts = getOverallAbstracts(board, selectedElements);
|
|
3296
|
+
// get valid abstract refs
|
|
3297
|
+
const validAbstractRefs = getValidAbstractRefs(board, [...selectedElements, ...overallAbstracts]);
|
|
3551
3298
|
// keep correct order
|
|
3552
|
-
const newSelectedElements = selectedElements.filter(
|
|
3553
|
-
newSelectedElements.push(...
|
|
3554
|
-
// get correct start and end in selected elements
|
|
3555
|
-
function getCorrectStartEnd(abstract) {
|
|
3556
|
-
const parent = MindElement.getParent(abstract);
|
|
3557
|
-
const startElement = parent.children[abstract.start];
|
|
3558
|
-
const index = selectedElements.indexOf(startElement);
|
|
3559
|
-
return { start: index, end: index + (abstract.end - abstract.start) };
|
|
3560
|
-
}
|
|
3299
|
+
const newSelectedElements = selectedElements.filter(value => !validAbstractRefs.find(ref => ref.abstract === value));
|
|
3300
|
+
newSelectedElements.push(...validAbstractRefs.map(value => value.abstract));
|
|
3561
3301
|
const selectedMindNodes = newSelectedElements.map(value => MindElement.getNode(value));
|
|
3562
3302
|
const nodesRectangle = getRectangleByElements(board, newSelectedElements, true);
|
|
3563
3303
|
newSelectedElements.forEach((element, index) => {
|
|
@@ -3565,8 +3305,9 @@ const buildClipboardData = (board, selectedElements) => {
|
|
|
3565
3305
|
const nodeRectangle = getRectangleByNode(selectedMindNodes[index]);
|
|
3566
3306
|
const points = [[nodeRectangle.x - nodesRectangle.x, nodeRectangle.y - nodesRectangle.y]];
|
|
3567
3307
|
// handle invalid abstract
|
|
3568
|
-
|
|
3569
|
-
|
|
3308
|
+
const abstractRef = validAbstractRefs.find(ref => ref.abstract === element);
|
|
3309
|
+
if (AbstractNode.isAbstract(element) && abstractRef) {
|
|
3310
|
+
const { start, end } = getRelativeStartEndByAbstractRef(abstractRef, newSelectedElements);
|
|
3570
3311
|
result.push(Object.assign(Object.assign({}, element), { points,
|
|
3571
3312
|
start,
|
|
3572
3313
|
end }));
|
|
@@ -3615,7 +3356,7 @@ const insertClipboardData = (board, elements, targetPoint) => {
|
|
|
3615
3356
|
newElement = copyNewNode(item);
|
|
3616
3357
|
if (hasTargetParent) {
|
|
3617
3358
|
if (item.isRoot) {
|
|
3618
|
-
newElement =
|
|
3359
|
+
newElement = adjustRootToNode(board, newElement);
|
|
3619
3360
|
}
|
|
3620
3361
|
// handle abstract start and end
|
|
3621
3362
|
if (AbstractNode.isAbstract(newElement)) {
|
|
@@ -3628,10 +3369,10 @@ const insertClipboardData = (board, elements, targetPoint) => {
|
|
|
3628
3369
|
const point = [targetPoint[0] + item.points[0][0], targetPoint[1] + item.points[0][1]];
|
|
3629
3370
|
newElement.points = [point];
|
|
3630
3371
|
if (AbstractNode.isAbstract(item)) {
|
|
3631
|
-
newElement =
|
|
3372
|
+
newElement = adjustAbstractToNode(newElement);
|
|
3632
3373
|
}
|
|
3633
3374
|
if (!item.isRoot) {
|
|
3634
|
-
newElement =
|
|
3375
|
+
newElement = adjustNodeToRoot(board, newElement);
|
|
3635
3376
|
}
|
|
3636
3377
|
path = [board.children.length];
|
|
3637
3378
|
}
|
|
@@ -3662,8 +3403,8 @@ const withAbstract = (board) => {
|
|
|
3662
3403
|
const point = transformPoint(board, toPoint(event.x, event.y, host));
|
|
3663
3404
|
activeAbstractElement = activeAbstractElements.find(element => {
|
|
3664
3405
|
abstractHandlePosition = getHitAbstractHandle(board, element, point);
|
|
3665
|
-
if (newBoard === null || newBoard === void 0 ? void 0 : newBoard.
|
|
3666
|
-
newBoard.
|
|
3406
|
+
if (newBoard === null || newBoard === void 0 ? void 0 : newBoard.onAbstractResize) {
|
|
3407
|
+
newBoard.onAbstractResize(AbstractResizeState.start);
|
|
3667
3408
|
}
|
|
3668
3409
|
return abstractHandlePosition;
|
|
3669
3410
|
});
|
|
@@ -3697,8 +3438,8 @@ const withAbstract = (board) => {
|
|
|
3697
3438
|
children = leftChildren;
|
|
3698
3439
|
}
|
|
3699
3440
|
}
|
|
3700
|
-
if (newBoard === null || newBoard === void 0 ? void 0 : newBoard.
|
|
3701
|
-
newBoard.
|
|
3441
|
+
if (newBoard === null || newBoard === void 0 ? void 0 : newBoard.onAbstractResize) {
|
|
3442
|
+
newBoard.onAbstractResize(AbstractResizeState.resizing);
|
|
3702
3443
|
}
|
|
3703
3444
|
const resizingLocation = isHorizontal ? endPoint[1] : endPoint[0];
|
|
3704
3445
|
const parent = MindElement.getNode(parentElement);
|
|
@@ -3730,8 +3471,8 @@ const withAbstract = (board) => {
|
|
|
3730
3471
|
startPoint = undefined;
|
|
3731
3472
|
abstractHandlePosition = undefined;
|
|
3732
3473
|
if (activeAbstractElement) {
|
|
3733
|
-
if (newBoard === null || newBoard === void 0 ? void 0 : newBoard.
|
|
3734
|
-
newBoard.
|
|
3474
|
+
if (newBoard === null || newBoard === void 0 ? void 0 : newBoard.onAbstractResize) {
|
|
3475
|
+
newBoard.onAbstractResize(AbstractResizeState.end);
|
|
3735
3476
|
}
|
|
3736
3477
|
if (newProperty) {
|
|
3737
3478
|
const path = PlaitBoard.findPath(board, activeAbstractElement);
|
|
@@ -3748,7 +3489,7 @@ const withAbstract = (board) => {
|
|
|
3748
3489
|
return board;
|
|
3749
3490
|
};
|
|
3750
3491
|
|
|
3751
|
-
const
|
|
3492
|
+
const withMindExtend = (board) => {
|
|
3752
3493
|
const newBoard = board;
|
|
3753
3494
|
newBoard.drawEmoji = (emoji, element) => {
|
|
3754
3495
|
throw new Error('Not implement drawEmoji method error.');
|
|
@@ -3759,6 +3500,85 @@ const withExtendMind = (board) => {
|
|
|
3759
3500
|
return newBoard;
|
|
3760
3501
|
};
|
|
3761
3502
|
|
|
3503
|
+
const DefaultHotkey = 'm';
|
|
3504
|
+
const withCreateMind = (board) => {
|
|
3505
|
+
const newBoard = board;
|
|
3506
|
+
const { keydown, mousemove, mouseup } = board;
|
|
3507
|
+
let fakeCreateNodeRef = null;
|
|
3508
|
+
newBoard.mousemove = (event) => {
|
|
3509
|
+
if (PlaitBoard.isReadonly(board)) {
|
|
3510
|
+
mousemove(event);
|
|
3511
|
+
return;
|
|
3512
|
+
}
|
|
3513
|
+
if (PlaitBoard.isPointer(board, MindPointerType.mind)) {
|
|
3514
|
+
throttleRAF(() => {
|
|
3515
|
+
const movingPoint = PlaitBoard.getMovingPoint(board);
|
|
3516
|
+
if (movingPoint) {
|
|
3517
|
+
const targetPoint = transformPoint(board, toPoint(movingPoint[0], movingPoint[1], PlaitBoard.getHost(board)));
|
|
3518
|
+
const emptyMind = createEmptyMind(board, targetPoint);
|
|
3519
|
+
const nodeRectangle = getRectangleByElement(newBoard, targetPoint, emptyMind);
|
|
3520
|
+
const nodeG = drawRoundRectangleByElement(board, nodeRectangle, emptyMind);
|
|
3521
|
+
const topicRectangle = getTopicRectangleByElement(newBoard, nodeRectangle, emptyMind);
|
|
3522
|
+
if (!fakeCreateNodeRef) {
|
|
3523
|
+
const { richtextComponentRef, richtextG, foreignObject } = drawTopicByElement(newBoard, topicRectangle, emptyMind);
|
|
3524
|
+
fakeCreateNodeRef = {
|
|
3525
|
+
instanceRef: richtextComponentRef,
|
|
3526
|
+
nodeG,
|
|
3527
|
+
foreignObject,
|
|
3528
|
+
topicG: richtextG
|
|
3529
|
+
};
|
|
3530
|
+
richtextComponentRef.changeDetectorRef.detectChanges();
|
|
3531
|
+
PlaitBoard.getHost(board).append(...[fakeCreateNodeRef.nodeG, fakeCreateNodeRef.topicG]);
|
|
3532
|
+
}
|
|
3533
|
+
else {
|
|
3534
|
+
fakeCreateNodeRef.nodeG.remove();
|
|
3535
|
+
fakeCreateNodeRef.nodeG = nodeG;
|
|
3536
|
+
PlaitBoard.getHost(board).append(nodeG);
|
|
3537
|
+
PlaitBoard.getHost(board).append(fakeCreateNodeRef.topicG);
|
|
3538
|
+
updateForeignObject$1(fakeCreateNodeRef.topicG, topicRectangle.width, topicRectangle.height, topicRectangle.x, topicRectangle.y);
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
});
|
|
3542
|
+
}
|
|
3543
|
+
else {
|
|
3544
|
+
destroy();
|
|
3545
|
+
}
|
|
3546
|
+
mousemove(event);
|
|
3547
|
+
};
|
|
3548
|
+
newBoard.mouseup = (event) => {
|
|
3549
|
+
const movingPoint = PlaitBoard.getMovingPoint(board);
|
|
3550
|
+
if (movingPoint && fakeCreateNodeRef && PlaitBoard.isPointer(board, MindPointerType.mind)) {
|
|
3551
|
+
const targetPoint = transformPoint(board, toPoint(movingPoint[0], movingPoint[1], PlaitBoard.getHost(board)));
|
|
3552
|
+
const emptyMind = createEmptyMind(board, targetPoint);
|
|
3553
|
+
Transforms.insertNode(board, emptyMind, [board.children.length]);
|
|
3554
|
+
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
3555
|
+
}
|
|
3556
|
+
destroy();
|
|
3557
|
+
mouseup(event);
|
|
3558
|
+
};
|
|
3559
|
+
board.keydown = (event) => {
|
|
3560
|
+
if (PlaitBoard.isReadonly(board) || getSelectedElements(board).length > 0) {
|
|
3561
|
+
keydown(event);
|
|
3562
|
+
return;
|
|
3563
|
+
}
|
|
3564
|
+
if (event.key === DefaultHotkey && !PlaitBoard.isPointer(board, MindPointerType.mind)) {
|
|
3565
|
+
BoardTransforms.updatePointerType(board, MindPointerType.mind);
|
|
3566
|
+
event.preventDefault();
|
|
3567
|
+
return;
|
|
3568
|
+
}
|
|
3569
|
+
keydown(event);
|
|
3570
|
+
};
|
|
3571
|
+
function destroy() {
|
|
3572
|
+
if (fakeCreateNodeRef) {
|
|
3573
|
+
fakeCreateNodeRef.instanceRef.destroy();
|
|
3574
|
+
fakeCreateNodeRef.nodeG.remove();
|
|
3575
|
+
fakeCreateNodeRef.topicG.remove();
|
|
3576
|
+
fakeCreateNodeRef = null;
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
return newBoard;
|
|
3580
|
+
};
|
|
3581
|
+
|
|
3762
3582
|
const withMind = (board) => {
|
|
3763
3583
|
const { drawElement, dblclick, keydown, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
|
|
3764
3584
|
board.drawElement = (context) => {
|
|
@@ -3800,7 +3620,7 @@ const withMind = (board) => {
|
|
|
3800
3620
|
return isMovable(element);
|
|
3801
3621
|
};
|
|
3802
3622
|
board.keydown = (event) => {
|
|
3803
|
-
if (
|
|
3623
|
+
if (PlaitBoard.isReadonly(board)) {
|
|
3804
3624
|
keydown(event);
|
|
3805
3625
|
return;
|
|
3806
3626
|
}
|
|
@@ -3823,7 +3643,7 @@ const withMind = (board) => {
|
|
|
3823
3643
|
insertMindElement(board, selectedElement, findNewChildNodePath(board, selectedElement));
|
|
3824
3644
|
}
|
|
3825
3645
|
else {
|
|
3826
|
-
if (
|
|
3646
|
+
if (isInRightBranchOfStandardLayout(selectedElement)) {
|
|
3827
3647
|
changeRightNodeCount(board, selectedElementPath.slice(0, 1), 1);
|
|
3828
3648
|
}
|
|
3829
3649
|
const abstractRefs = insertElementHandleAbstract(board, Path.next(selectedElementPath));
|
|
@@ -3834,7 +3654,10 @@ const withMind = (board) => {
|
|
|
3834
3654
|
}
|
|
3835
3655
|
if (hotkeys.isDeleteBackward(event) || hotkeys.isDeleteForward(event)) {
|
|
3836
3656
|
event.preventDefault();
|
|
3837
|
-
|
|
3657
|
+
const deletableElements = getFirstLevelElement(selectedElements).reverse();
|
|
3658
|
+
const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
|
|
3659
|
+
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
3660
|
+
MindTransforms.removeElements(board, selectedElements);
|
|
3838
3661
|
let activeElement;
|
|
3839
3662
|
const firstLevelElements = getFirstLevelElement(selectedElements);
|
|
3840
3663
|
if (AbstractNode.isAbstract(firstLevelElements[0])) {
|
|
@@ -3880,7 +3703,7 @@ const withMind = (board) => {
|
|
|
3880
3703
|
keydown(event);
|
|
3881
3704
|
};
|
|
3882
3705
|
board.dblclick = (event) => {
|
|
3883
|
-
if (
|
|
3706
|
+
if (PlaitBoard.isReadonly(board)) {
|
|
3884
3707
|
dblclick(event);
|
|
3885
3708
|
return;
|
|
3886
3709
|
}
|
|
@@ -3889,9 +3712,16 @@ const withMind = (board) => {
|
|
|
3889
3712
|
.filter(value => PlaitMind.isMind(value))
|
|
3890
3713
|
.forEach(mindMap => {
|
|
3891
3714
|
depthFirstRecursion(mindMap, node => {
|
|
3892
|
-
if (!PlaitBoard.hasBeenTextEditing(board) &&
|
|
3715
|
+
if (!PlaitBoard.hasBeenTextEditing(board) && isHitMindElement(board, point, node)) {
|
|
3893
3716
|
enterNodeEditing(node);
|
|
3894
3717
|
}
|
|
3718
|
+
}, node => {
|
|
3719
|
+
if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
|
|
3720
|
+
return true;
|
|
3721
|
+
}
|
|
3722
|
+
else {
|
|
3723
|
+
return false;
|
|
3724
|
+
}
|
|
3895
3725
|
});
|
|
3896
3726
|
});
|
|
3897
3727
|
if (PlaitBoard.hasBeenTextEditing(board)) {
|
|
@@ -3929,10 +3759,13 @@ const withMind = (board) => {
|
|
|
3929
3759
|
};
|
|
3930
3760
|
board.deleteFragment = (data) => {
|
|
3931
3761
|
const selectedElements = getSelectedElements(board);
|
|
3932
|
-
|
|
3762
|
+
const deletableElements = getFirstLevelElement(selectedElements).reverse();
|
|
3763
|
+
const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
|
|
3764
|
+
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
3765
|
+
MindTransforms.removeElements(board, selectedElements);
|
|
3933
3766
|
deleteFragment(data);
|
|
3934
3767
|
};
|
|
3935
|
-
return
|
|
3768
|
+
return withMindExtend(withCreateMind(withAbstract(withDnd(board))));
|
|
3936
3769
|
};
|
|
3937
3770
|
|
|
3938
3771
|
class MindEmojiBaseComponent {
|
|
@@ -3974,5 +3807,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3974
3807
|
* Generated bundle index. Do not edit.
|
|
3975
3808
|
*/
|
|
3976
3809
|
|
|
3977
|
-
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,
|
|
3810
|
+
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_COLORS, BRANCH_WIDTH, BaseDrawer, DefaultAbstractNodeStyle, DefaultNodeStyle, DefaultRootStyle, ELEMENT_TO_NODE, EXTEND_OFFSET, EXTEND_RADIUS, GRAY_COLOR, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, 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, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, changeRightNodeCount, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNodeByPath, enterNodeEditing, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getPreviousAndNextByPath, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, insertElementHandleAbstract, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isDragging, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, readjustmentDropTarget, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
|
|
3978
3811
|
//# sourceMappingURL=plait-mind.mjs.map
|