@plait/mind 0.82.0-next.0 → 0.82.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/constants/default.d.ts +8 -5
- package/fesm2022/plait-mind.mjs +354 -279
- package/fesm2022/plait-mind.mjs.map +1 -1
- package/generators/node-more.generator.d.ts +30 -0
- package/mind-node.component.d.ts +3 -7
- package/package.json +1 -1
- package/plugins/with-node-more.d.ts +10 -0
- package/styles/styles.scss +16 -56
- package/utils/clipboard.d.ts +1 -1
- package/utils/common.d.ts +1 -1
- package/generators/node-collapse.generator.d.ts +0 -8
- package/generators/node-plus.generator.d.ts +0 -7
- package/plugins/with-node-hover-hit-test.d.ts +0 -2
- package/utils/node-hover/extend.d.ts +0 -9
package/fesm2022/plait-mind.mjs
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { DEFAULT_COLOR, DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, PlaitElement, PlaitNode, Path, isNullOrUndefined, PlaitBoard, getSelectedElements, getI18nValue, idCreator, Transforms, clearSelectedElement, addSelectedElement, distanceBetweenPointAndRectangle, RectangleClient, setDragging, depthFirstRecursion, getIsRecursionFunc, drawRoundRectangle, drawLinearPath, drawBezierPath, setStrokeLinecap, createG, createForeignObject, updateForeignObject, getRectangleByElements, toActiveRectangleFromViewBoxRectangle, ACTIVE_STROKE_WIDTH, SELECTION_RECTANGLE_CLASS_NAME, NODE_TO_PARENT, removeSelectedElement, PlaitHistoryBoard, createText,
|
|
1
|
+
import { DEFAULT_COLOR, DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, rgbaToHEX, PlaitElement, PlaitNode, Path, isNullOrUndefined, PlaitBoard, getSelectedElements, getI18nValue, idCreator, Transforms, clearSelectedElement, addSelectedElement, distanceBetweenPointAndRectangle, RectangleClient, setDragging, depthFirstRecursion, getIsRecursionFunc, drawRoundRectangle, drawLinearPath, drawBezierPath, setStrokeLinecap, createG, createForeignObject, updateForeignObject, getRectangleByElements, toActiveRectangleFromViewBoxRectangle, ACTIVE_STROKE_WIDTH, SELECTION_RECTANGLE_CLASS_NAME, NODE_TO_PARENT, removeSelectedElement, PlaitHistoryBoard, isSelectedElement, createText, isSelectionMoving, isDragging, isMovingElements, NODE_TO_INDEX, PlaitPointerType, isMainPointer, toViewBoxPoint, toHostPoint, getHitElementByPoint, distanceBetweenPointAndPoint, CoreTransforms, toActivePointFromViewBoxPoint, BoardTransforms, throttleRAF, isContextmenu, temporaryDisableSelection, hotkeys, createClipboardContext, WritableClipboardType, Point, ResizeCursorClass, WritableClipboardOperationType, addOrCreateClipboardContext } from '@plait/core';
|
|
2
2
|
import { MindLayoutType, AbstractNode, isIndentedLayout, isHorizontalLogicLayout, ConnectingPosition, isHorizontalLayout, getNonAbstractChildren, isStandardLayout, isLeftLayout, isRightLayout, isVerticalLogicLayout, isTopLayout, isBottomLayout, getCorrectStartEnd, getAbstractLayout, GlobalLayout } from '@plait/layouts';
|
|
3
|
-
import { StrokeStyle, getFirstTextManage, DEFAULT_FONT_FAMILY, measureElement, buildText, getFirstTextEditor, RESIZE_HANDLE_DIAMETER, getRectangleResizeHandleRefs, addElementOfFocusedImage, ImageGenerator, removeElementOfFocusedImage, getStrokeLineDash, Generator, PropertyTransforms, CommonElementFlavour, WithTextPluginKey, TextManage, isDrawingMode, isDndMode, setCreationMode, BoardCreationMode, isExpandHotkey, isTabHotkey, isEnterHotkey, isVirtualKey, isDelete, isSpaceHotkey, getElementOfFocusedImage, acceptImageTypes, buildImage, withResize, getElementsText } from '@plait/common';
|
|
4
|
-
import { TEXT_DEFAULT_HEIGHT, PlaitMarkEditor, MarkTypes, DEFAULT_FONT_SIZE } from '@plait/text-plugins';
|
|
3
|
+
import { StrokeStyle, getFirstTextManage, DEFAULT_FONT_FAMILY, measureElement, buildText, getFirstTextEditor, RESIZE_HANDLE_DIAMETER, getRectangleResizeHandleRefs, addElementOfFocusedImage, ImageGenerator, removeElementOfFocusedImage, getStrokeLineDash, Generator, PropertyTransforms, TRANSPARENT, isResizing, CommonElementFlavour, WithTextPluginKey, TextManage, isDrawingMode, isDndMode, setCreationMode, BoardCreationMode, isExpandHotkey, isTabHotkey, isEnterHotkey, isVirtualKey, isDelete, isSpaceHotkey, getElementOfFocusedImage, acceptImageTypes, buildImage, withResize, getElementsText } from '@plait/common';
|
|
4
|
+
import { TEXT_DEFAULT_HEIGHT, PlaitMarkEditor, MarkTypes, DEFAULT_FONT_SIZE, FontSizes } from '@plait/text-plugins';
|
|
5
5
|
import { Node as Node$1, Path as Path$1 } from 'slate';
|
|
6
6
|
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
7
|
-
import { fromEvent } from 'rxjs';
|
|
8
|
-
import { take, filter } from 'rxjs/operators';
|
|
9
7
|
import { isHotkey } from 'is-hotkey';
|
|
10
8
|
|
|
11
9
|
const ELEMENT_TO_NODE = new WeakMap();
|
|
@@ -180,11 +178,14 @@ const BASE = 4;
|
|
|
180
178
|
const PRIMARY_COLOR = '#6698FF';
|
|
181
179
|
const GRAY_COLOR = '#AAAAAA';
|
|
182
180
|
const STROKE_WIDTH = 3;
|
|
183
|
-
const
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
const
|
|
187
|
-
const
|
|
181
|
+
const RESIZE_HANDLE_BUFFER_DISTANCE = 8;
|
|
182
|
+
const NODE_MORE_LINE_DISTANCE = 10;
|
|
183
|
+
const NODE_MORE_STROKE_WIDTH = 2;
|
|
184
|
+
const NODE_MORE_ICON_DIAMETER = 20;
|
|
185
|
+
const NODE_MORE_BRIDGE_DISTANCE = 10;
|
|
186
|
+
const NODE_ADD_CIRCLE_COLOR = rgbaToHEX('#000000', 0.2);
|
|
187
|
+
const NODE_ADD_HOVER_COLOR = '#6698FF';
|
|
188
|
+
const NODE_ADD_INNER_CROSS_COLOR = 'white';
|
|
188
189
|
const DEFAULT_MIND_IMAGE_WIDTH = 240;
|
|
189
190
|
var MindI18nKey;
|
|
190
191
|
(function (MindI18nKey) {
|
|
@@ -611,9 +612,9 @@ const getLayoutOptions = (board) => {
|
|
|
611
612
|
}
|
|
612
613
|
function getSecondAxle(element, parent) {
|
|
613
614
|
if (element.isRoot) {
|
|
614
|
-
return BASE *
|
|
615
|
+
return BASE * 12;
|
|
615
616
|
}
|
|
616
|
-
return BASE *
|
|
617
|
+
return BASE * 8.5;
|
|
617
618
|
}
|
|
618
619
|
return {
|
|
619
620
|
getHeight(element) {
|
|
@@ -626,7 +627,7 @@ const getLayoutOptions = (board) => {
|
|
|
626
627
|
const _layout = (parent && parent.layout) || getRootLayout(element);
|
|
627
628
|
const isHorizontal = isHorizontalLayout(_layout);
|
|
628
629
|
if (isIndentedLayout(_layout)) {
|
|
629
|
-
return BASE *
|
|
630
|
+
return BASE * 6;
|
|
630
631
|
}
|
|
631
632
|
if (!isHorizontal) {
|
|
632
633
|
return getMainAxle(element, parent);
|
|
@@ -638,7 +639,7 @@ const getLayoutOptions = (board) => {
|
|
|
638
639
|
getVerticalGap(element, parent) {
|
|
639
640
|
const _layout = (parent && parent.layout) || getRootLayout(element);
|
|
640
641
|
if (isIndentedLayout(_layout)) {
|
|
641
|
-
return BASE;
|
|
642
|
+
return BASE * 3.5;
|
|
642
643
|
}
|
|
643
644
|
const isHorizontal = isHorizontalLayout(_layout);
|
|
644
645
|
if (isHorizontal) {
|
|
@@ -655,10 +656,10 @@ const getLayoutOptions = (board) => {
|
|
|
655
656
|
return undefined;
|
|
656
657
|
},
|
|
657
658
|
getExtendHeight(node) {
|
|
658
|
-
return
|
|
659
|
+
return 0;
|
|
659
660
|
},
|
|
660
661
|
getIndentedCrossLevelGap() {
|
|
661
|
-
return BASE *
|
|
662
|
+
return BASE * 1;
|
|
662
663
|
}
|
|
663
664
|
};
|
|
664
665
|
};
|
|
@@ -683,7 +684,7 @@ const getDefaultMindNameText = (board) => {
|
|
|
683
684
|
const getAbstractNodeText = (board) => {
|
|
684
685
|
return getI18nValue(board, MindI18nKey.abstractNodeText, ABSTRACT_NODE_TEXT);
|
|
685
686
|
};
|
|
686
|
-
const getTopicSize = (isRoot, isBranch, topic, manualWidth) => {
|
|
687
|
+
const getTopicSize = (board, isRoot, isBranch, topic, manualWidth) => {
|
|
687
688
|
let fontFamily = DEFAULT_FONT_FAMILY;
|
|
688
689
|
let fontSize = TOPIC_FONT_SIZE;
|
|
689
690
|
if (isRoot) {
|
|
@@ -694,12 +695,12 @@ const getTopicSize = (isRoot, isBranch, topic, manualWidth) => {
|
|
|
694
695
|
fontFamily = DEFAULT_FONT_FAMILY;
|
|
695
696
|
}
|
|
696
697
|
const maxWidth = fontSize * TOPIC_DEFAULT_MAX_WORD_COUNT;
|
|
697
|
-
return measureElement(topic, { fontSize, fontFamily }, manualWidth ? manualWidth : maxWidth);
|
|
698
|
+
return measureElement(board, topic, { fontSize, fontFamily }, manualWidth ? manualWidth : maxWidth);
|
|
698
699
|
};
|
|
699
700
|
|
|
700
701
|
const createEmptyMind = (board, point) => {
|
|
701
702
|
const text = getDefaultMindNameText(board);
|
|
702
|
-
const topicSize = getTopicSize(true, false, buildText(text));
|
|
703
|
+
const topicSize = getTopicSize(board, true, false, buildText(text));
|
|
703
704
|
const element = createMindElement(text, topicSize.width, topicSize.height, { layout: MindLayoutType.right });
|
|
704
705
|
element.isRoot = true;
|
|
705
706
|
element.type = 'mindmap';
|
|
@@ -2514,7 +2515,7 @@ const setAbstractByElements = (board, groupParent, group) => {
|
|
|
2514
2515
|
};
|
|
2515
2516
|
const insertAbstractNode = (board, path, start, end) => {
|
|
2516
2517
|
const abstractNodeText = getAbstractNodeText(board);
|
|
2517
|
-
const { width, height } = getTopicSize(false, false, buildText(abstractNodeText));
|
|
2518
|
+
const { width, height } = getTopicSize(board, false, false, buildText(abstractNodeText));
|
|
2518
2519
|
const mindElement = createMindElement(abstractNodeText, width, height, {
|
|
2519
2520
|
strokeWidth: DefaultAbstractNodeStyle.branch.width,
|
|
2520
2521
|
branchWidth: DefaultAbstractNodeStyle.branch.width
|
|
@@ -2752,201 +2753,202 @@ const MindTransforms = {
|
|
|
2752
2753
|
insertMind
|
|
2753
2754
|
};
|
|
2754
2755
|
|
|
2755
|
-
class
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
return false;
|
|
2759
|
-
}
|
|
2760
|
-
return true;
|
|
2756
|
+
class NodeShapeGenerator extends Generator {
|
|
2757
|
+
constructor(board) {
|
|
2758
|
+
super(board, { prepend: true });
|
|
2761
2759
|
}
|
|
2762
|
-
|
|
2763
|
-
const
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
const layout = MindQueries.getLayoutByElement(element);
|
|
2767
|
-
const isHorizontal = isHorizontalLayout(layout);
|
|
2768
|
-
let linkDirection = getLayoutDirection(node, isHorizontal);
|
|
2769
|
-
if (isIndentedLayout(layout)) {
|
|
2770
|
-
linkDirection = isTopLayout(layout) ? LayoutDirection.top : LayoutDirection.bottom;
|
|
2771
|
-
}
|
|
2772
|
-
const isUnderlineShape = getShapeByElement(this.board, element) === MindElementShape.underline;
|
|
2773
|
-
const nodeClient = getRectangleByNode(node);
|
|
2774
|
-
const branchWidth = getBranchWidthByMindElement(this.board, element);
|
|
2775
|
-
const branchColor = PlaitMind.isMind(element)
|
|
2776
|
-
? getNextBranchColor(this.board, element)
|
|
2777
|
-
: getBranchColorByMindElement(this.board, element);
|
|
2778
|
-
let distance = 8;
|
|
2779
|
-
let placement = [HorizontalPlacement.right, VerticalPlacement.middle];
|
|
2780
|
-
transformPlacement(placement, linkDirection);
|
|
2781
|
-
// underline shape and horizontal
|
|
2782
|
-
if (isHorizontal && isUnderlineShape && !element.isRoot) {
|
|
2783
|
-
placement[1] = VerticalPlacement.bottom;
|
|
2784
|
-
}
|
|
2785
|
-
let beginPoint = getPointByPlacement(nodeClient, placement);
|
|
2786
|
-
if (element.children.length > 0 && !element.isRoot) {
|
|
2787
|
-
beginPoint = moveXOfPoint(beginPoint, EXTEND_DIAMETER + 8, linkDirection);
|
|
2788
|
-
distance = 5;
|
|
2760
|
+
canDraw(element, data) {
|
|
2761
|
+
const shape = getShapeByElement(this.board, element);
|
|
2762
|
+
if (shape === MindElementShape.roundRectangle) {
|
|
2763
|
+
return true;
|
|
2789
2764
|
}
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
});
|
|
2796
|
-
const circle = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
|
|
2797
|
-
fill: QUICK_INSERT_CIRCLE_COLOR,
|
|
2798
|
-
stroke: QUICK_INSERT_CIRCLE_COLOR,
|
|
2799
|
-
fillStyle: 'solid'
|
|
2800
|
-
});
|
|
2801
|
-
const HLineBeginPoint = [circleCenter[0] - 5, circleCenter[1]];
|
|
2802
|
-
const HLineEndPoint = [circleCenter[0] + 5, circleCenter[1]];
|
|
2803
|
-
const VLineBeginPoint = [circleCenter[0], circleCenter[1] - 5];
|
|
2804
|
-
const VLineEndPoint = [circleCenter[0], circleCenter[1] + 5];
|
|
2805
|
-
const innerCrossHLine = PlaitBoard.getRoughSVG(this.board).line(HLineBeginPoint[0], HLineBeginPoint[1], HLineEndPoint[0], HLineEndPoint[1], {
|
|
2806
|
-
stroke: QUICK_INSERT_INNER_CROSS_COLOR,
|
|
2807
|
-
strokeWidth: 2
|
|
2808
|
-
});
|
|
2809
|
-
const innerCrossVLine = PlaitBoard.getRoughSVG(this.board).line(VLineBeginPoint[0], VLineBeginPoint[1], VLineEndPoint[0], VLineEndPoint[1], {
|
|
2810
|
-
stroke: QUICK_INSERT_INNER_CROSS_COLOR,
|
|
2811
|
-
strokeWidth: 2
|
|
2812
|
-
});
|
|
2813
|
-
plusG.appendChild(line);
|
|
2814
|
-
plusG.appendChild(circle);
|
|
2815
|
-
plusG.appendChild(innerCrossHLine);
|
|
2816
|
-
plusG.appendChild(innerCrossVLine);
|
|
2817
|
-
return plusG;
|
|
2818
|
-
}
|
|
2819
|
-
afterDraw(element) {
|
|
2820
|
-
if (!this.g) {
|
|
2821
|
-
throw new Error(`can not find quick insert g`);
|
|
2822
|
-
}
|
|
2823
|
-
fromEvent(this.g, 'pointerdown')
|
|
2824
|
-
.pipe(take(1))
|
|
2825
|
-
.subscribe(e => {
|
|
2826
|
-
e.preventDefault();
|
|
2827
|
-
});
|
|
2828
|
-
fromEvent(this.g, 'pointerup')
|
|
2829
|
-
.pipe(take(1))
|
|
2830
|
-
.subscribe((event) => {
|
|
2831
|
-
// wait the event period end of pointerup to otherwise the pointerup will cause new element lose selected state
|
|
2832
|
-
setTimeout(() => {
|
|
2833
|
-
const path = findNewChildNodePath(this.board, element);
|
|
2834
|
-
insertMindElement(this.board, element, path);
|
|
2835
|
-
}, 0);
|
|
2836
|
-
});
|
|
2765
|
+
return false;
|
|
2766
|
+
}
|
|
2767
|
+
draw(element, data) {
|
|
2768
|
+
const rectangle = getRectangleByNode(data.node);
|
|
2769
|
+
return drawRoundRectangleByElement(this.board, rectangle, data.node.origin);
|
|
2837
2770
|
}
|
|
2838
2771
|
}
|
|
2839
2772
|
|
|
2840
|
-
class
|
|
2841
|
-
|
|
2842
|
-
|
|
2773
|
+
class NodeMoreGenerator extends Generator {
|
|
2774
|
+
static { this.key = 'mind-node-more'; }
|
|
2775
|
+
canDraw(element, extraData) {
|
|
2776
|
+
if (((extraData?.isHovered || extraData?.isHoveredCollapseArea || extraData?.isHoveredAddArea) && canHandleNodeMore(this.board)) ||
|
|
2777
|
+
(extraData?.isSelected && isLastSelectedMindElement(this.board, element) && canHandleNodeMore(this.board)) ||
|
|
2778
|
+
element.isCollapsed) {
|
|
2843
2779
|
return true;
|
|
2844
2780
|
}
|
|
2845
2781
|
return false;
|
|
2846
2782
|
}
|
|
2847
|
-
draw(element) {
|
|
2848
|
-
const
|
|
2849
|
-
collapseG.classList.add('collapse');
|
|
2850
|
-
const node = MindElement.getNode(element);
|
|
2783
|
+
draw(element, extraData) {
|
|
2784
|
+
const moreGContainer = createG();
|
|
2851
2785
|
const stroke = getBranchColorByMindElement(this.board, element);
|
|
2852
|
-
const
|
|
2853
|
-
const
|
|
2854
|
-
const
|
|
2855
|
-
const
|
|
2856
|
-
const
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2786
|
+
const layoutDirection = getNodeMoreLayoutDirection(this.board, element);
|
|
2787
|
+
const moreStartAndEnd = getMoreStartAndEnd(this.board, element, layoutDirection);
|
|
2788
|
+
const collapseOrExpandCenter = moveXOfPoint(moreStartAndEnd[1], NODE_MORE_ICON_DIAMETER / 2, layoutDirection);
|
|
2789
|
+
const hasChildren = element.children.length > 0;
|
|
2790
|
+
const isShowCollapseOrAdd = !element.isCollapsed &&
|
|
2791
|
+
(isSelectedElement(this.board, element) ||
|
|
2792
|
+
!!extraData?.isHovered ||
|
|
2793
|
+
!!extraData?.isHoveredCollapseArea ||
|
|
2794
|
+
!!extraData?.isHoveredAddArea);
|
|
2795
|
+
const isShowCollapse = isShowCollapseOrAdd && hasChildren && !PlaitMind.isMind(element);
|
|
2796
|
+
const isShowAdd = isShowCollapseOrAdd && !PlaitBoard.isReadonly(this.board);
|
|
2797
|
+
const addCenter = (isShowCollapseOrAdd && getAddCenterByCollapseOrExpandCenter(element, collapseOrExpandCenter, layoutDirection)) || null;
|
|
2798
|
+
this.toggleCollapseOrAdd(collapseOrExpandCenter, addCenter, stroke, moreGContainer, isShowCollapse, isShowAdd, !!extraData?.isHoveredAddArea, !!extraData?.isShowCollapseAnimation, !!extraData?.isShowAddAnimation);
|
|
2799
|
+
this.toggleExpandBadge(element, moreStartAndEnd, collapseOrExpandCenter, stroke, moreGContainer, !!element.isCollapsed, !!extraData?.isHoveredExpandArea);
|
|
2800
|
+
return moreGContainer;
|
|
2801
|
+
}
|
|
2802
|
+
toggleCollapseOrAdd(center, addCenter, stroke, parentG, isShowCollapse, isShowAdd, isHoveredAddArea, isShowCollapseAnimation, isShowAddAnimation) {
|
|
2803
|
+
this.collapseOrAddG?.remove();
|
|
2804
|
+
if (!isShowCollapse && !isShowAdd) {
|
|
2805
|
+
return;
|
|
2860
2806
|
}
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2807
|
+
this.collapseOrAddG = createG();
|
|
2808
|
+
if (isShowCollapse) {
|
|
2809
|
+
const collapseG = createG();
|
|
2810
|
+
this.collapseOrAddG.appendChild(collapseG);
|
|
2811
|
+
collapseG.classList.add('collapse-button');
|
|
2812
|
+
if (isShowCollapseAnimation) {
|
|
2813
|
+
collapseG.classList.add('animated');
|
|
2814
|
+
}
|
|
2815
|
+
const collapseCircle = PlaitBoard.getRoughSVG(this.board).circle(center[0], center[1], NODE_MORE_ICON_DIAMETER, {
|
|
2816
|
+
fill: '#fff',
|
|
2817
|
+
stroke,
|
|
2818
|
+
strokeWidth: NODE_MORE_STROKE_WIDTH,
|
|
2819
|
+
fillStyle: 'solid'
|
|
2820
|
+
});
|
|
2821
|
+
const start = moveXOfPoint(center, -NODE_MORE_BRIDGE_DISTANCE / 2);
|
|
2822
|
+
const end = moveXOfPoint(center, NODE_MORE_BRIDGE_DISTANCE / 2);
|
|
2823
|
+
const collapseLine = PlaitBoard.getRoughSVG(this.board).line(start[0], start[1], end[0], end[1], {
|
|
2824
|
+
fill: '#fff',
|
|
2825
|
+
stroke,
|
|
2826
|
+
strokeWidth: NODE_MORE_STROKE_WIDTH,
|
|
2827
|
+
fillStyle: 'solid'
|
|
2828
|
+
});
|
|
2829
|
+
collapseG.appendChild(collapseCircle);
|
|
2830
|
+
collapseG.appendChild(collapseLine);
|
|
2831
|
+
setStrokeLinecap(collapseLine, 'round');
|
|
2832
|
+
}
|
|
2833
|
+
if (isShowAdd && addCenter) {
|
|
2834
|
+
const addG = createG();
|
|
2835
|
+
this.collapseOrAddG.appendChild(addG);
|
|
2836
|
+
addG.classList.add('add-button');
|
|
2837
|
+
if (isShowAddAnimation) {
|
|
2838
|
+
addG.classList.add('animated');
|
|
2839
|
+
}
|
|
2840
|
+
const circle = PlaitBoard.getRoughSVG(this.board).circle(addCenter[0], addCenter[1], NODE_MORE_ICON_DIAMETER + NODE_MORE_STROKE_WIDTH, {
|
|
2841
|
+
fill: isHoveredAddArea ? NODE_ADD_HOVER_COLOR : NODE_ADD_CIRCLE_COLOR,
|
|
2842
|
+
stroke: TRANSPARENT,
|
|
2843
|
+
fillStyle: 'solid'
|
|
2844
|
+
});
|
|
2845
|
+
const hLineBeginPoint = [addCenter[0] - NODE_MORE_BRIDGE_DISTANCE / 2, addCenter[1]];
|
|
2846
|
+
const hLineEndPoint = [addCenter[0] + NODE_MORE_BRIDGE_DISTANCE / 2, addCenter[1]];
|
|
2847
|
+
const vLineBeginPoint = [addCenter[0], addCenter[1] - NODE_MORE_BRIDGE_DISTANCE / 2];
|
|
2848
|
+
const vLineEndPoint = [addCenter[0], addCenter[1] + NODE_MORE_BRIDGE_DISTANCE / 2];
|
|
2849
|
+
const innerCrossHLine = PlaitBoard.getRoughSVG(this.board).line(hLineBeginPoint[0], hLineBeginPoint[1], hLineEndPoint[0], hLineEndPoint[1], {
|
|
2850
|
+
stroke: NODE_ADD_INNER_CROSS_COLOR,
|
|
2851
|
+
strokeWidth: NODE_MORE_STROKE_WIDTH
|
|
2852
|
+
});
|
|
2853
|
+
setStrokeLinecap(innerCrossHLine, 'round');
|
|
2854
|
+
const innerCrossVLine = PlaitBoard.getRoughSVG(this.board).line(vLineBeginPoint[0], vLineBeginPoint[1], vLineEndPoint[0], vLineEndPoint[1], {
|
|
2855
|
+
stroke: NODE_ADD_INNER_CROSS_COLOR,
|
|
2856
|
+
strokeWidth: NODE_MORE_STROKE_WIDTH
|
|
2857
|
+
});
|
|
2858
|
+
setStrokeLinecap(innerCrossVLine, 'round');
|
|
2859
|
+
addG.appendChild(circle);
|
|
2860
|
+
addG.appendChild(innerCrossHLine);
|
|
2861
|
+
addG.appendChild(innerCrossVLine);
|
|
2866
2862
|
}
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
});
|
|
2879
|
-
const badge = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
|
|
2863
|
+
parentG.appendChild(this.collapseOrAddG);
|
|
2864
|
+
}
|
|
2865
|
+
toggleExpandBadge(element, moreStartAndEnd, center, stroke, parentG, isCollapsed, isHoveredExpandIcon) {
|
|
2866
|
+
this.expandG?.remove();
|
|
2867
|
+
if (!isCollapsed) {
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
this.expandG = createG();
|
|
2871
|
+
this.expandG.classList.add('expanded-button');
|
|
2872
|
+
const endWithWidth = moreStartAndEnd[1];
|
|
2873
|
+
const moreLine = PlaitBoard.getRoughSVG(this.board).line(moreStartAndEnd[0][0], moreStartAndEnd[0][1], endWithWidth[0], endWithWidth[1], {
|
|
2880
2874
|
fill: stroke,
|
|
2881
2875
|
stroke,
|
|
2882
|
-
fillStyle: 'solid'
|
|
2876
|
+
fillStyle: 'solid',
|
|
2877
|
+
strokeWidth: NODE_MORE_STROKE_WIDTH
|
|
2883
2878
|
});
|
|
2884
|
-
const
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2879
|
+
const backgroundColor = isHoveredExpandIcon ? rgbaToHEX(stroke, 0.4) : rgbaToHEX(stroke, 0.2);
|
|
2880
|
+
const badgeBackground = PlaitBoard.getRoughSVG(this.board).circle(center[0], center[1], NODE_MORE_ICON_DIAMETER + NODE_MORE_STROKE_WIDTH, {
|
|
2881
|
+
fill: backgroundColor,
|
|
2882
|
+
stroke: TRANSPARENT,
|
|
2888
2883
|
fillStyle: 'solid'
|
|
2889
2884
|
});
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
collapseG.appendChild(badgeText);
|
|
2901
|
-
collapseG.appendChild(extendLine);
|
|
2902
|
-
}
|
|
2903
|
-
else {
|
|
2904
|
-
collapseG.appendChild(hideCircleG);
|
|
2905
|
-
collapseG.appendChild(arrowLine);
|
|
2906
|
-
}
|
|
2907
|
-
collapseG.appendChild(extendLine);
|
|
2908
|
-
return collapseG;
|
|
2909
|
-
}
|
|
2910
|
-
afterDraw(element) {
|
|
2911
|
-
if (!this.g) {
|
|
2912
|
-
throw new Error(`can not find quick insert g`);
|
|
2913
|
-
}
|
|
2914
|
-
fromEvent(this.g, 'pointerdown')
|
|
2915
|
-
.pipe(filter(() => !PlaitBoard.isPointer(this.board, PlaitPointerType.hand) || !!PlaitBoard.isReadonly(this.board)), take(1))
|
|
2916
|
-
.subscribe((event) => {
|
|
2917
|
-
event.preventDefault();
|
|
2918
|
-
const isCollapsed = !element.isCollapsed;
|
|
2919
|
-
const newElement = { isCollapsed };
|
|
2920
|
-
const path = PlaitBoard.findPath(this.board, element);
|
|
2921
|
-
Transforms.setNode(this.board, newElement, path);
|
|
2885
|
+
const childrenCount = getChildrenCount(element);
|
|
2886
|
+
let text = `${childrenCount}`;
|
|
2887
|
+
let y = center[1] + 4.5;
|
|
2888
|
+
if (childrenCount >= 99) {
|
|
2889
|
+
text = '...';
|
|
2890
|
+
y = center[1] + 1;
|
|
2891
|
+
}
|
|
2892
|
+
const { width, height } = measureElement(this.board, buildText(text), {
|
|
2893
|
+
fontSize: Number(FontSizes.fontSize12),
|
|
2894
|
+
fontFamily: DEFAULT_FONT_FAMILY
|
|
2922
2895
|
});
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
arrowBottomPoint = moveYOfPoint(arrowBottomPoint, -4, linkDirection);
|
|
2930
|
-
return [arrowTopPoint, arrowMiddlePoint, arrowBottomPoint];
|
|
2896
|
+
const badgeText = createText(center[0] - width / 2 + 0.5, y, stroke, `${text}`);
|
|
2897
|
+
badgeText.setAttribute('style', `font-size: ${Number(FontSizes.fontSize12)}px;`);
|
|
2898
|
+
this.expandG.appendChild(moreLine);
|
|
2899
|
+
this.expandG.appendChild(badgeBackground);
|
|
2900
|
+
this.expandG.appendChild(badgeText);
|
|
2901
|
+
parentG.appendChild(this.expandG);
|
|
2931
2902
|
}
|
|
2932
2903
|
}
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2904
|
+
const getCollapseAndAddCenterPoint = (board, element) => {
|
|
2905
|
+
const layoutDirection = getNodeMoreLayoutDirection(board, element);
|
|
2906
|
+
const [startPoint, endPoint] = getMoreStartAndEnd(board, element, layoutDirection);
|
|
2907
|
+
const collapseCenter = moveXOfPoint(endPoint, NODE_MORE_ICON_DIAMETER / 2, layoutDirection);
|
|
2908
|
+
const addCenter = getAddCenterByCollapseOrExpandCenter(element, collapseCenter, layoutDirection);
|
|
2909
|
+
return { collapseCenter, addCenter };
|
|
2910
|
+
};
|
|
2911
|
+
const getAddCenterByCollapseOrExpandCenter = (target, collapseOrExpandCenter, layoutDirection) => {
|
|
2912
|
+
let addCenter = collapseOrExpandCenter;
|
|
2913
|
+
if (target.children?.length > 0 && !PlaitMind.isMind(target)) {
|
|
2914
|
+
addCenter = moveXOfPoint(addCenter, NODE_MORE_LINE_DISTANCE + NODE_MORE_ICON_DIAMETER, layoutDirection);
|
|
2937
2915
|
}
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2916
|
+
return addCenter;
|
|
2917
|
+
};
|
|
2918
|
+
const getNodeMoreLayoutDirection = (board, element) => {
|
|
2919
|
+
const node = MindElement.getNode(element);
|
|
2920
|
+
const layout = MindQueries.getLayoutByElement(element);
|
|
2921
|
+
const isHorizontal = isHorizontalLayout(layout);
|
|
2922
|
+
let layoutDirection = getLayoutDirection(node, isHorizontal);
|
|
2923
|
+
if (isIndentedLayout(layout)) {
|
|
2924
|
+
layoutDirection = isTopLayout(layout) ? LayoutDirection.top : LayoutDirection.bottom;
|
|
2944
2925
|
}
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2926
|
+
return layoutDirection;
|
|
2927
|
+
};
|
|
2928
|
+
const getMoreStartAndEnd = (board, element, linkLineDirection) => {
|
|
2929
|
+
const node = MindElement.getNode(element);
|
|
2930
|
+
const isUnderlineShape = getShapeByElement(board, element) === MindElementShape.underline;
|
|
2931
|
+
const nodeClient = getRectangleByNode(node);
|
|
2932
|
+
let placement = [HorizontalPlacement.right, VerticalPlacement.middle];
|
|
2933
|
+
transformPlacement(placement, linkLineDirection);
|
|
2934
|
+
// underline shape and horizontal
|
|
2935
|
+
const layout = MindQueries.getLayoutByElement(element);
|
|
2936
|
+
const isHorizontal = isHorizontalLayout(layout);
|
|
2937
|
+
if (isHorizontal && isUnderlineShape && !element.isRoot) {
|
|
2938
|
+
placement[1] = VerticalPlacement.bottom;
|
|
2948
2939
|
}
|
|
2949
|
-
|
|
2940
|
+
let startPoint = getPointByPlacement(nodeClient, placement);
|
|
2941
|
+
const endPoint = moveXOfPoint(startPoint, NODE_MORE_LINE_DISTANCE, linkLineDirection);
|
|
2942
|
+
return [startPoint, endPoint];
|
|
2943
|
+
};
|
|
2944
|
+
const isLastSelectedMindElement = (board, element) => {
|
|
2945
|
+
const selectedElements = getSelectedElements(board);
|
|
2946
|
+
const selectedMindElements = selectedElements.filter((element) => MindElement.isMindElement(board, element)).reverse();
|
|
2947
|
+
return selectedMindElements[selectedMindElements.length - 1] === element;
|
|
2948
|
+
};
|
|
2949
|
+
const canHandleNodeMore = (board) => {
|
|
2950
|
+
return !isResizing(board) && !isSelectionMoving(board) && !isDragging(board) && !isMovingElements(board);
|
|
2951
|
+
};
|
|
2950
2952
|
|
|
2951
2953
|
class MindNodeComponent extends CommonElementFlavour {
|
|
2952
2954
|
get textManage() {
|
|
@@ -2963,8 +2965,7 @@ class MindNodeComponent extends CommonElementFlavour {
|
|
|
2963
2965
|
this.nodeShapeGenerator = new NodeShapeGenerator(this.board);
|
|
2964
2966
|
this.nodeEmojisGenerator = new NodeEmojisGenerator(this.board);
|
|
2965
2967
|
this.activeGenerator = new NodeActiveGenerator(this.board);
|
|
2966
|
-
this.
|
|
2967
|
-
this.collapseGenerator = new CollapseGenerator(this.board);
|
|
2968
|
+
this.nodeMoreGenerator = new NodeMoreGenerator(this.board);
|
|
2968
2969
|
this.imageGenerator = new ImageGenerator(this.board, {
|
|
2969
2970
|
getRectangle: (element) => {
|
|
2970
2971
|
return getImageForeignRectangle(this.board, element);
|
|
@@ -3002,6 +3003,7 @@ class MindNodeComponent extends CommonElementFlavour {
|
|
|
3002
3003
|
this.getRef().addGenerator(NodeActiveGenerator.key, this.activeGenerator);
|
|
3003
3004
|
this.getRef().addGenerator(NodeEmojisGenerator.key, this.nodeEmojisGenerator);
|
|
3004
3005
|
this.getRef().addGenerator(ImageGenerator.key, this.imageGenerator);
|
|
3006
|
+
this.getRef().addGenerator(NodeMoreGenerator.key, this.nodeMoreGenerator);
|
|
3005
3007
|
this.getRef().initializeTextManage(textManage);
|
|
3006
3008
|
this.getRef().updateActiveSection = () => {
|
|
3007
3009
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
@@ -3021,8 +3023,8 @@ class MindNodeComponent extends CommonElementFlavour {
|
|
|
3021
3023
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
3022
3024
|
selected: this.selected
|
|
3023
3025
|
});
|
|
3026
|
+
this.nodeMoreGenerator.processDrawing(this.element, this.getElementG());
|
|
3024
3027
|
this.drawEmojis();
|
|
3025
|
-
this.drawExtend();
|
|
3026
3028
|
this.imageGenerator.processDrawing(this.element, this.getElementG());
|
|
3027
3029
|
if (PlaitMind.isMind(this.context.parent)) {
|
|
3028
3030
|
this.getElementG().classList.add('branch');
|
|
@@ -3036,10 +3038,10 @@ class MindNodeComponent extends CommonElementFlavour {
|
|
|
3036
3038
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
3037
3039
|
selected: this.selected
|
|
3038
3040
|
});
|
|
3041
|
+
this.nodeMoreGenerator.processDrawing(this.element, this.getElementG(), { isSelected: this.selected });
|
|
3039
3042
|
this.nodeShapeGenerator.processDrawing(this.element, this.getElementG(), { node: this.node });
|
|
3040
3043
|
this.drawLink();
|
|
3041
3044
|
this.drawEmojis();
|
|
3042
|
-
this.drawExtend();
|
|
3043
3045
|
if (!MindElement.hasImage(previous.element) && MindElement.hasImage(this.element)) {
|
|
3044
3046
|
this.imageGenerator.processDrawing(this.element, this.getElementG());
|
|
3045
3047
|
}
|
|
@@ -3058,6 +3060,9 @@ class MindNodeComponent extends CommonElementFlavour {
|
|
|
3058
3060
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
3059
3061
|
selected: this.selected
|
|
3060
3062
|
});
|
|
3063
|
+
this.nodeMoreGenerator.processDrawing(this.element, this.getElementG(), {
|
|
3064
|
+
isSelected: this.selected
|
|
3065
|
+
});
|
|
3061
3066
|
}
|
|
3062
3067
|
if (!hasSameParent) {
|
|
3063
3068
|
this.drawLink();
|
|
@@ -3076,32 +3081,17 @@ class MindNodeComponent extends CommonElementFlavour {
|
|
|
3076
3081
|
}
|
|
3077
3082
|
const parent = MindElement.getParent(this.element);
|
|
3078
3083
|
const parentNode = MindElement.getNode(parent);
|
|
3079
|
-
if (this.
|
|
3080
|
-
this.
|
|
3084
|
+
if (this.linkLineG) {
|
|
3085
|
+
this.linkLineG.remove();
|
|
3081
3086
|
}
|
|
3082
3087
|
const layout = MindQueries.getLayoutByElement(parent);
|
|
3083
3088
|
if (AbstractNode.isAbstract(this.node.origin)) {
|
|
3084
|
-
this.
|
|
3089
|
+
this.linkLineG = drawAbstractLink(this.board, this.node, isHorizontalLayout(layout));
|
|
3085
3090
|
}
|
|
3086
3091
|
else {
|
|
3087
|
-
this.
|
|
3092
|
+
this.linkLineG = drawLink(this.board, parentNode, this.node, isHorizontalLayout(layout));
|
|
3088
3093
|
}
|
|
3089
|
-
this.getElementG().append(this.
|
|
3090
|
-
}
|
|
3091
|
-
drawExtend() {
|
|
3092
|
-
if (!this.extendG) {
|
|
3093
|
-
this.extendG = createG();
|
|
3094
|
-
this.extendG.classList.add('extend');
|
|
3095
|
-
this.getElementG().append(this.extendG);
|
|
3096
|
-
}
|
|
3097
|
-
if (this.element.isCollapsed) {
|
|
3098
|
-
this.getElementG().classList.add('collapsed');
|
|
3099
|
-
}
|
|
3100
|
-
else {
|
|
3101
|
-
this.getElementG().classList.remove('collapsed');
|
|
3102
|
-
}
|
|
3103
|
-
this.nodePlusGenerator.processDrawing(this.element, this.extendG);
|
|
3104
|
-
this.collapseGenerator.processDrawing(this.element, this.extendG);
|
|
3094
|
+
this.getElementG().append(this.linkLineG);
|
|
3105
3095
|
}
|
|
3106
3096
|
drawTopic() {
|
|
3107
3097
|
this.textManage.draw(this.element.data.topic);
|
|
@@ -3580,72 +3570,152 @@ const withMindHotkey = (baseBoard) => {
|
|
|
3580
3570
|
return board;
|
|
3581
3571
|
};
|
|
3582
3572
|
|
|
3583
|
-
const
|
|
3573
|
+
const withNodeMore = (board) => {
|
|
3574
|
+
const { pointerMove, pointerLeave, pointerUp } = board;
|
|
3575
|
+
let nodeMoreRef = null;
|
|
3576
|
+
board.pointerMove = (event) => {
|
|
3577
|
+
if (canHandleNodeMore(board)) {
|
|
3578
|
+
throttleRAF(board, 'with-mind-node-hover-hit-test', () => {
|
|
3579
|
+
// target has been deleted
|
|
3580
|
+
if (nodeMoreRef && !PlaitElement.hasMounted(nodeMoreRef.target)) {
|
|
3581
|
+
nodeMoreRef = null;
|
|
3582
|
+
}
|
|
3583
|
+
const newNodeMoreRef = getNodeMoreRef(board, event.x, event.y);
|
|
3584
|
+
if (nodeMoreRef && newNodeMoreRef && nodeMoreRef.target === newNodeMoreRef.target) {
|
|
3585
|
+
return;
|
|
3586
|
+
}
|
|
3587
|
+
if (nodeMoreRef) {
|
|
3588
|
+
toggleHoveredNodeCallback({
|
|
3589
|
+
target: nodeMoreRef.target,
|
|
3590
|
+
isHovered: false,
|
|
3591
|
+
isHoveredCollapseArea: false,
|
|
3592
|
+
isHoveredExpandArea: false,
|
|
3593
|
+
isHoveredAddArea: false
|
|
3594
|
+
});
|
|
3595
|
+
}
|
|
3596
|
+
if (newNodeMoreRef) {
|
|
3597
|
+
toggleHoveredNodeCallback(newNodeMoreRef);
|
|
3598
|
+
if (nodeMoreRef) {
|
|
3599
|
+
nodeMoreRef.target = newNodeMoreRef.target;
|
|
3600
|
+
}
|
|
3601
|
+
else {
|
|
3602
|
+
nodeMoreRef = newNodeMoreRef;
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3605
|
+
else {
|
|
3606
|
+
nodeMoreRef = null;
|
|
3607
|
+
}
|
|
3608
|
+
});
|
|
3609
|
+
}
|
|
3610
|
+
pointerMove(event);
|
|
3611
|
+
};
|
|
3612
|
+
board.pointerUp = (event) => {
|
|
3613
|
+
if (nodeMoreRef && (nodeMoreRef.isHoveredCollapseArea || nodeMoreRef.isHoveredExpandArea)) {
|
|
3614
|
+
const isCollapsed = !nodeMoreRef.target.isCollapsed;
|
|
3615
|
+
const newElement = { isCollapsed };
|
|
3616
|
+
const path = PlaitBoard.findPath(board, nodeMoreRef.target);
|
|
3617
|
+
Transforms.setNode(board, newElement, path);
|
|
3618
|
+
setTimeout(() => {
|
|
3619
|
+
const newNodeMoreRef = getNodeMoreRef(board, event.x, event.y);
|
|
3620
|
+
if (newNodeMoreRef) {
|
|
3621
|
+
toggleHoveredNodeCallback(newNodeMoreRef);
|
|
3622
|
+
nodeMoreRef = newNodeMoreRef;
|
|
3623
|
+
}
|
|
3624
|
+
else {
|
|
3625
|
+
nodeMoreRef = null;
|
|
3626
|
+
}
|
|
3627
|
+
}, 0);
|
|
3628
|
+
return;
|
|
3629
|
+
}
|
|
3630
|
+
if (nodeMoreRef && nodeMoreRef.isHoveredAddArea && !PlaitBoard.isReadonly(board)) {
|
|
3631
|
+
if (nodeMoreRef) {
|
|
3632
|
+
const path = findNewChildNodePath(board, nodeMoreRef.target);
|
|
3633
|
+
insertMindElement(board, nodeMoreRef.target, path);
|
|
3634
|
+
}
|
|
3635
|
+
return;
|
|
3636
|
+
}
|
|
3637
|
+
pointerUp(event);
|
|
3638
|
+
};
|
|
3639
|
+
const toggleHoveredNodeCallback = (ref) => {
|
|
3640
|
+
const elementRef = PlaitElement.getElementRef(ref.target);
|
|
3641
|
+
const nodeMoreGenerator = elementRef?.getGenerator(NodeMoreGenerator.key);
|
|
3642
|
+
if (nodeMoreGenerator) {
|
|
3643
|
+
const g = PlaitElement.getElementG(ref.target);
|
|
3644
|
+
nodeMoreGenerator.processDrawing(ref.target, g, {
|
|
3645
|
+
isHovered: ref.isHovered,
|
|
3646
|
+
isHoveredCollapseArea: ref.isHoveredCollapseArea,
|
|
3647
|
+
isHoveredExpandArea: ref.isHoveredExpandArea,
|
|
3648
|
+
isSelected: isSelectedElement(board, ref.target),
|
|
3649
|
+
isHoveredAddArea: ref.isHoveredAddArea,
|
|
3650
|
+
isShowCollapseAnimation: (ref.isHovered || ref.isHoveredCollapseArea) && !isSelectedElement(board, ref.target),
|
|
3651
|
+
isShowAddAnimation: (ref.isHovered || ref.isHoveredAddArea) && !isSelectedElement(board, ref.target)
|
|
3652
|
+
});
|
|
3653
|
+
}
|
|
3654
|
+
};
|
|
3655
|
+
board.pointerLeave = (event) => {
|
|
3656
|
+
if (nodeMoreRef) {
|
|
3657
|
+
toggleHoveredNodeCallback({
|
|
3658
|
+
target: nodeMoreRef.target,
|
|
3659
|
+
isHovered: false,
|
|
3660
|
+
isHoveredCollapseArea: false,
|
|
3661
|
+
isHoveredExpandArea: false,
|
|
3662
|
+
isHoveredAddArea: false
|
|
3663
|
+
});
|
|
3664
|
+
}
|
|
3665
|
+
nodeMoreRef = null;
|
|
3666
|
+
pointerLeave(event);
|
|
3667
|
+
};
|
|
3668
|
+
return board;
|
|
3669
|
+
};
|
|
3670
|
+
const getNodeMoreRef = (board, x, y) => {
|
|
3584
3671
|
let target = null;
|
|
3585
|
-
|
|
3586
|
-
|
|
3672
|
+
let isHovered = false;
|
|
3673
|
+
let isHoveredCollapseArea = false;
|
|
3674
|
+
let isHoveredExpandArea = false;
|
|
3675
|
+
let isHoveredAddArea = false;
|
|
3676
|
+
const point = toViewBoxPoint(board, toHostPoint(board, x, y));
|
|
3677
|
+
depthFirstRecursion(board, (element) => {
|
|
3587
3678
|
if (target) {
|
|
3588
3679
|
return;
|
|
3589
3680
|
}
|
|
3590
3681
|
if (!MindElement.isMindElement(board, element)) {
|
|
3591
3682
|
return;
|
|
3592
3683
|
}
|
|
3684
|
+
const isMind = PlaitMind.isMind(element);
|
|
3593
3685
|
const isHitElement = isHitMindElement(board, point, element);
|
|
3594
|
-
|
|
3686
|
+
let isHitCollapseOrExpand = false;
|
|
3687
|
+
let isHitAdd = false;
|
|
3688
|
+
const { collapseCenter, addCenter } = getCollapseAndAddCenterPoint(board, element);
|
|
3689
|
+
const collapseOrExpandIconRectangle = !isMind && RectangleClient.getRectangleByCenterPoint(collapseCenter, NODE_MORE_ICON_DIAMETER, NODE_MORE_ICON_DIAMETER);
|
|
3690
|
+
isHitCollapseOrExpand =
|
|
3691
|
+
collapseOrExpandIconRectangle &&
|
|
3692
|
+
RectangleClient.isHit(RectangleClient.getRectangleByPoints([point, point]), collapseOrExpandIconRectangle);
|
|
3693
|
+
const addIconRectangle = RectangleClient.getRectangleByCenterPoint(addCenter, NODE_MORE_ICON_DIAMETER, NODE_MORE_ICON_DIAMETER);
|
|
3694
|
+
isHitAdd = RectangleClient.isHit(RectangleClient.getRectangleByPoints([point, point]), addIconRectangle);
|
|
3695
|
+
if (isHitElement || isHitCollapseOrExpand || isHitAdd) {
|
|
3696
|
+
isHovered = isHitElement;
|
|
3697
|
+
if (element.children.length > 0) {
|
|
3698
|
+
if (element.isCollapsed) {
|
|
3699
|
+
isHoveredExpandArea = isHitCollapseOrExpand;
|
|
3700
|
+
}
|
|
3701
|
+
else {
|
|
3702
|
+
isHoveredCollapseArea = isHitCollapseOrExpand;
|
|
3703
|
+
}
|
|
3704
|
+
}
|
|
3705
|
+
isHoveredAddArea = isHitAdd;
|
|
3595
3706
|
target = element;
|
|
3596
3707
|
}
|
|
3597
3708
|
}, getIsRecursionFunc(board), true);
|
|
3598
|
-
if (
|
|
3599
|
-
return
|
|
3600
|
-
}
|
|
3601
|
-
if (nodeExtendHoveredRef) {
|
|
3602
|
-
removeHovered(nodeExtendHoveredRef.element);
|
|
3709
|
+
if (!target) {
|
|
3710
|
+
return null;
|
|
3603
3711
|
}
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
nodeExtendHoveredRef = { element: target };
|
|
3611
|
-
}
|
|
3612
|
-
}
|
|
3613
|
-
else {
|
|
3614
|
-
nodeExtendHoveredRef = null;
|
|
3615
|
-
}
|
|
3616
|
-
return nodeExtendHoveredRef;
|
|
3617
|
-
};
|
|
3618
|
-
const pointerLeaveHandle = (board, event, nodeExtendHoveredRef) => {
|
|
3619
|
-
if (nodeExtendHoveredRef) {
|
|
3620
|
-
removeHovered(nodeExtendHoveredRef.element);
|
|
3621
|
-
}
|
|
3622
|
-
};
|
|
3623
|
-
const addHovered = (element) => {
|
|
3624
|
-
PlaitElement.getElementG(element).classList.add('hovered');
|
|
3625
|
-
};
|
|
3626
|
-
const removeHovered = (element) => {
|
|
3627
|
-
PlaitElement.getElementG(element)?.classList?.remove('hovered');
|
|
3628
|
-
};
|
|
3629
|
-
|
|
3630
|
-
const withNodeHoverHitTest = (board) => {
|
|
3631
|
-
const { pointerMove, pointerLeave } = board;
|
|
3632
|
-
let nodeExtendHoveredRef = null;
|
|
3633
|
-
board.pointerMove = (event) => {
|
|
3634
|
-
throttleRAF(board, 'with-mind-node-hover-hit-test', () => {
|
|
3635
|
-
// element has been deleted
|
|
3636
|
-
if (nodeExtendHoveredRef && !PlaitElement.hasMounted(nodeExtendHoveredRef.element)) {
|
|
3637
|
-
nodeExtendHoveredRef = null;
|
|
3638
|
-
}
|
|
3639
|
-
nodeExtendHoveredRef = pointerMoveHandle(board, event, nodeExtendHoveredRef);
|
|
3640
|
-
});
|
|
3641
|
-
pointerMove(event);
|
|
3642
|
-
};
|
|
3643
|
-
board.pointerLeave = (event) => {
|
|
3644
|
-
pointerLeaveHandle(board, event, nodeExtendHoveredRef);
|
|
3645
|
-
nodeExtendHoveredRef = null;
|
|
3646
|
-
pointerLeave(event);
|
|
3712
|
+
return {
|
|
3713
|
+
target,
|
|
3714
|
+
isHovered,
|
|
3715
|
+
isHoveredCollapseArea,
|
|
3716
|
+
isHoveredExpandArea,
|
|
3717
|
+
isHoveredAddArea
|
|
3647
3718
|
};
|
|
3648
|
-
return board;
|
|
3649
3719
|
};
|
|
3650
3720
|
|
|
3651
3721
|
const withNodeImage = (board) => {
|
|
@@ -3800,9 +3870,9 @@ const withNodeResize = (board) => {
|
|
|
3800
3870
|
return board;
|
|
3801
3871
|
};
|
|
3802
3872
|
const getSelectedTarget = (board, point) => {
|
|
3803
|
-
const selectedElements = getSelectedElements(board).filter(value => MindElement.isMindElement(board, value));
|
|
3873
|
+
const selectedElements = getSelectedElements(board).filter((value) => MindElement.isMindElement(board, value));
|
|
3804
3874
|
if (selectedElements.length > 0) {
|
|
3805
|
-
const target = selectedElements.find(value => {
|
|
3875
|
+
const target = selectedElements.find((value) => {
|
|
3806
3876
|
const rectangle = getResizeActiveRectangle(board, value);
|
|
3807
3877
|
return distanceBetweenPointAndRectangle(point[0], point[1], rectangle) <= 0;
|
|
3808
3878
|
});
|
|
@@ -3813,7 +3883,12 @@ const getSelectedTarget = (board, point) => {
|
|
|
3813
3883
|
const getResizeActiveRectangle = (board, element) => {
|
|
3814
3884
|
const node = MindElement.getNode(element);
|
|
3815
3885
|
const rectangle = getRectangleByNode(node);
|
|
3816
|
-
return {
|
|
3886
|
+
return {
|
|
3887
|
+
x: rectangle.x + rectangle.width - RESIZE_HANDLE_BUFFER_DISTANCE,
|
|
3888
|
+
y: rectangle.y,
|
|
3889
|
+
width: RESIZE_HANDLE_BUFFER_DISTANCE * 2,
|
|
3890
|
+
height: rectangle.height
|
|
3891
|
+
};
|
|
3817
3892
|
};
|
|
3818
3893
|
|
|
3819
3894
|
const withNodeImageResize = (board) => {
|
|
@@ -3912,7 +3987,7 @@ const insertClipboardData = (board, elements, targetPoint, operationType) => {
|
|
|
3912
3987
|
if (hasTargetParent && operationType !== WritableClipboardOperationType.duplicate) {
|
|
3913
3988
|
if (item.isRoot) {
|
|
3914
3989
|
newElement = adjustRootToNode(board, newElement);
|
|
3915
|
-
const { width, height } = getTopicSizeByElement(newElement, targetParent);
|
|
3990
|
+
const { width, height } = getTopicSizeByElement(board, newElement, targetParent);
|
|
3916
3991
|
newElement.width = width;
|
|
3917
3992
|
newElement.height = height;
|
|
3918
3993
|
}
|
|
@@ -3931,7 +4006,7 @@ const insertClipboardData = (board, elements, targetPoint, operationType) => {
|
|
|
3931
4006
|
}
|
|
3932
4007
|
if (!item.isRoot) {
|
|
3933
4008
|
newElement = adjustNodeToRoot(board, newElement);
|
|
3934
|
-
const { width, height } = getTopicSizeByElement(newElement);
|
|
4009
|
+
const { width, height } = getTopicSizeByElement(board, newElement);
|
|
3935
4010
|
newElement.width = width;
|
|
3936
4011
|
newElement.height = height;
|
|
3937
4012
|
}
|
|
@@ -3944,13 +4019,13 @@ const insertClipboardData = (board, elements, targetPoint, operationType) => {
|
|
|
3944
4019
|
Transforms.addSelectionWithTemporaryElements(board, newELements);
|
|
3945
4020
|
};
|
|
3946
4021
|
const insertClipboardText = (board, targetParent, text) => {
|
|
3947
|
-
const { width, height } = getTopicSize(false, PlaitMind.isMind(targetParent), buildText(text));
|
|
4022
|
+
const { width, height } = getTopicSize(board, false, PlaitMind.isMind(targetParent), buildText(text));
|
|
3948
4023
|
const newElement = createMindElement(text, Math.max(width, getFontSizeBySlateElement(text)), height, {});
|
|
3949
4024
|
Transforms.insertNode(board, newElement, findNewChildNodePath(board, targetParent));
|
|
3950
4025
|
Transforms.addSelectionWithTemporaryElements(board, [newElement]);
|
|
3951
4026
|
};
|
|
3952
|
-
const getTopicSizeByElement = (element, parentElement) => {
|
|
3953
|
-
return getTopicSize(PlaitMind.isMind(element), (parentElement && PlaitMind.isMind(parentElement)) || false, element.data.topic, element.manualWidth);
|
|
4027
|
+
const getTopicSizeByElement = (board, element, parentElement) => {
|
|
4028
|
+
return getTopicSize(board, PlaitMind.isMind(element), (parentElement && PlaitMind.isMind(parentElement)) || false, element.data.topic, element.manualWidth);
|
|
3954
4029
|
};
|
|
3955
4030
|
|
|
3956
4031
|
const withMindFragment = (baseBoard) => {
|
|
@@ -4218,7 +4293,7 @@ const withMind = (baseBoard) => {
|
|
|
4218
4293
|
}
|
|
4219
4294
|
dblClick(event);
|
|
4220
4295
|
};
|
|
4221
|
-
return withEmoji(withNodeResize(withNodeImageResize(withNodeImage(
|
|
4296
|
+
return withEmoji(withNodeResize(withNodeImageResize(withNodeImage(withNodeMore(withMindFragment(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board)))))))))));
|
|
4222
4297
|
};
|
|
4223
4298
|
|
|
4224
4299
|
class MindEmojiBaseComponent {
|
|
@@ -4235,5 +4310,5 @@ class MindEmojiBaseComponent {
|
|
|
4235
4310
|
* Generated bundle index. Do not edit.
|
|
4236
4311
|
*/
|
|
4237
4312
|
|
|
4238
|
-
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, ABSTRACT_NODE_TEXT, AbstractHandlePosition, AbstractResizeState, BASE, BranchShape, DEFAULT_MIND_IMAGE_WIDTH, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE,
|
|
4313
|
+
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, ABSTRACT_NODE_TEXT, AbstractHandlePosition, AbstractResizeState, BASE, BranchShape, DEFAULT_MIND_IMAGE_WIDTH, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, LayoutDirection, LayoutDirectionsMap, MIND_CENTRAL_TEXT, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindI18nKey, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NODE_ADD_CIRCLE_COLOR, NODE_ADD_HOVER_COLOR, NODE_ADD_INNER_CROSS_COLOR, NODE_MORE_BRIDGE_DISTANCE, NODE_MORE_ICON_DIAMETER, NODE_MORE_LINE_DISTANCE, NODE_MORE_STROKE_WIDTH, NodeSpace, NodeTopicThreshold, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, RESIZE_HANDLE_BUFFER_DISTANCE, ROOT_TOPIC_FONT_SIZE, STROKE_WIDTH, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, WithMindPluginKey, addActiveOnDragOrigin, addImageFocus, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, findLastChild, findLocationLeftIndex, findNewChildNodePath, findNewSiblingNodePath, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAbstractNodeText, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getDefaultMindElementFontSize, getDefaultMindNameText, getEmojiFontSize, getEmojiForeignRectangle, getEmojiRectangle, getEmojisWidthHeight, getFillByElement, getFirstLevelElement, getFontSizeBySlateElement, getHitAbstractHandle, getHitImageResizeHandleDirection, getImageForeignRectangle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutOptions, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNewNodeHeight, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getSelectedMindElements, getShapeByElement, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTopicRectangleByElement, getTopicRectangleByNode, getTopicSize, getValidAbstractRefs, handleTouchedAbstract, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDropStandardRight, isHitEmojis, isHitImage, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, removeActiveOnDragOrigin, removeImageFocus, separateChildren, setMindDragging, withEmoji, withMind, withMindExtend };
|
|
4239
4314
|
//# sourceMappingURL=plait-mind.mjs.map
|