From b7b756bb057477bca8f6e0e4a1161e47f6b150b8 Mon Sep 17 00:00:00 2001 From: Lye Hongtao Date: Wed, 24 Apr 2024 13:59:54 +0800 Subject: [PATCH] fix(edgeless): mindmap refine (#6824) --- .../root-block/edgeless/edgeless-keyboard.ts | 45 +++++++++++++++++- .../element-toolbar/change-mindmap-button.ts | 10 ++-- .../surface-block/element-model/mindmap.ts | 46 +++++++++++++++++++ .../src/surface-block/utils/math-utils.ts | 2 +- 4 files changed, 95 insertions(+), 8 deletions(-) diff --git a/packages/blocks/src/root-block/edgeless/edgeless-keyboard.ts b/packages/blocks/src/root-block/edgeless/edgeless-keyboard.ts index 429b451dcbcb..a22f94fcd1b3 100644 --- a/packages/blocks/src/root-block/edgeless/edgeless-keyboard.ts +++ b/packages/blocks/src/root-block/edgeless/edgeless-keyboard.ts @@ -2,8 +2,11 @@ import { IS_MAC } from '@blocksuite/global/env'; import { type EdgelessTool, LassoMode } from '../../_common/types.js'; import { matchFlavours } from '../../_common/utils/model.js'; -import type { MindmapElementModel } from '../../surface-block/element-model/mindmap.js'; -import type { ShapeElementModel } from '../../surface-block/index.js'; +import { MindmapElementModel } from '../../surface-block/element-model/mindmap.js'; +import type { + ElementModel, + ShapeElementModel, +} from '../../surface-block/index.js'; import { Bound, ConnectorElementModel, @@ -471,6 +474,44 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager { const { elements } = edgeless.service.selection; const inc = shift ? 10 : 1; + const mindmapNodes = elements.filter( + el => el.group instanceof MindmapElementModel + ); + + if (mindmapNodes.length > 0) { + const node = mindmapNodes[0]; + const mindmap = node.group as MindmapElementModel; + let targetNode: ElementModel | null = null; + + switch (key) { + case 'ArrowUp': + case 'ArrowDown': + targetNode = mindmap.getSiblingNode( + node.id, + key === 'ArrowDown' ? 'next' : 'prev' + ); + break; + case 'ArrowLeft': + targetNode = mindmap.getParentNode(node.id); + break; + case 'ArrowRight': + { + const children = mindmap.getChildNodes(node.id); + + targetNode = children[0] ?? null; + } + break; + } + + if (targetNode) { + edgeless.service.selection.set({ + elements: [targetNode.id], + editing: false, + }); + } + + return; + } elements.forEach(element => { const bound = Bound.deserialize(element.xywh).clone(); diff --git a/packages/blocks/src/root-block/widgets/element-toolbar/change-mindmap-button.ts b/packages/blocks/src/root-block/widgets/element-toolbar/change-mindmap-button.ts index 6fbd539326ee..1e6697428731 100644 --- a/packages/blocks/src/root-block/widgets/element-toolbar/change-mindmap-button.ts +++ b/packages/blocks/src/root-block/widgets/element-toolbar/change-mindmap-button.ts @@ -126,7 +126,7 @@ export class EdgelessChangeMindmapButton extends WithDisposable(LitElement) { return html`
{ @@ -153,7 +153,7 @@ export class EdgelessChangeMindmapButton extends WithDisposable(LitElement) { { @@ -276,9 +276,9 @@ class EdgelessChangeMindmapLayoutPanel extends LitElement { `; static mindmapLayouts = [ - [LayoutType.LEFT, MindmapLeftLayoutIcon, 'Left layout'], - [LayoutType.RIGHT, MindmapRightLayoutIcon, 'Right layout'], - [LayoutType.BALANCE, MindmapBalanceLayoutIcon, 'Balance layout'], + [LayoutType.LEFT, MindmapLeftLayoutIcon, 'Left'], + [LayoutType.RIGHT, MindmapRightLayoutIcon, 'Right'], + [LayoutType.BALANCE, MindmapBalanceLayoutIcon, 'Radial'], ]; @property({ attribute: false }) diff --git a/packages/blocks/src/surface-block/element-model/mindmap.ts b/packages/blocks/src/surface-block/element-model/mindmap.ts index b46f13e1a1cd..8772efd950f6 100644 --- a/packages/blocks/src/surface-block/element-model/mindmap.ts +++ b/packages/blocks/src/surface-block/element-model/mindmap.ts @@ -261,6 +261,18 @@ export class MindmapElementModel extends GroupLikeModel { return node?.parent ? this.surface.getElementById(node.parent) : null; } + /** + * Path is an array of indexes that represent the path from the root node to the target node. + * The first element of the array is always 0, which represents the root node. + * @param element + * @returns + * + * @example + * ```ts + * const path = mindmap.getPath('nodeId'); + * // [0, 1, 2] + * ``` + */ getPath(element: string | MindmapNode) { let node = this._nodeMap.get( typeof element === 'string' ? element : element.id @@ -563,4 +575,38 @@ export class MindmapElementModel extends GroupLikeModel { }); }); } + + getSiblingNode(id: string, direction: 'prev' | 'next' = 'next') { + const node = this._nodeMap.get(id); + + if (!node) { + return null; + } + + const parent = this._nodeMap.get(node.detail.parent!); + + if (!parent) { + return null; + } + + const idx = parent.children.indexOf(node); + if (idx === -1) { + return null; + } + + return ( + parent?.children[direction === 'next' ? idx + 1 : idx - 1]?.element ?? + null + ); + } + + getChildNodes(id: string) { + const node = this._nodeMap.get(id); + + if (!node) { + return []; + } + + return node.children.map(child => child.element); + } } diff --git a/packages/blocks/src/surface-block/utils/math-utils.ts b/packages/blocks/src/surface-block/utils/math-utils.ts index e3a1db73657f..daf1c7408361 100644 --- a/packages/blocks/src/surface-block/utils/math-utils.ts +++ b/packages/blocks/src/surface-block/utils/math-utils.ts @@ -148,7 +148,7 @@ export function getBoundsFromPoints(points: IVec[], rotation = 0): TLBounds { let maxX = -Infinity; let maxY = -Infinity; - if (points.length < 2) { + if (points.length < 1) { minX = 0; minY = 0; maxX = 1;