mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-10 09:56:20 +00:00
feat: support drill down logic
This commit is contained in:
parent
74a75c976f
commit
f9d4ff61af
@ -76,6 +76,26 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
|
|||||||
if (!current || host.viewport.scrolling || host.liveEditing.editing) {
|
if (!current || host.viewport.scrolling || host.liveEditing.editing) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rootNode, hover whole viewport
|
||||||
|
const focusNode = current.document.focusNode;
|
||||||
|
|
||||||
|
if (current.contains(focusNode)) {
|
||||||
|
const bounds = host.viewport.bounds;
|
||||||
|
return (
|
||||||
|
<BorderDetectingInstance
|
||||||
|
key="line-root"
|
||||||
|
title={current.title}
|
||||||
|
scale={this.scale}
|
||||||
|
scrollX={host.viewport.scrollX}
|
||||||
|
scrollY={host.viewport.scrollY}
|
||||||
|
rect={new DOMRect(0, 0, bounds.width, bounds.height)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else if (!focusNode.contains(current)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const instances = host.getComponentInstances(current);
|
const instances = host.getComponentInstances(current);
|
||||||
if (!instances || instances.length < 1) {
|
if (!instances || instances.length < 1) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -326,7 +326,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
(downEvent.target as HTMLElement).removeAttribute('for');
|
(downEvent.target as HTMLElement).removeAttribute('for');
|
||||||
|
|
||||||
const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
|
const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
|
||||||
const node = nodeInst?.node || documentModel?.rootNode;
|
const focusNode = documentModel.focusNode;
|
||||||
|
const node = nodeInst?.node || focusNode;
|
||||||
// if (!node?.isValidComponent()) {
|
// if (!node?.isValidComponent()) {
|
||||||
// // 对于未注册组件直接返回
|
// // 对于未注册组件直接返回
|
||||||
// return;
|
// return;
|
||||||
@ -338,7 +339,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
if (!isShaken(downEvent, e)) {
|
if (!isShaken(downEvent, e)) {
|
||||||
let id = node.id;
|
let id = node.id;
|
||||||
designer.activeTracker.track({ node, instance: nodeInst?.instance });
|
designer.activeTracker.track({ node, instance: nodeInst?.instance });
|
||||||
if (isMulti && !isRootNode(node) && selection.has(id)) {
|
if (isMulti && !node.contains(focusNode) && selection.has(id)) {
|
||||||
selection.remove(id);
|
selection.remove(id);
|
||||||
} else {
|
} else {
|
||||||
// TODO: 避免选中 Page 组件,默认选中第一个子节点;新增规则 或 判断 Live 模式
|
// TODO: 避免选中 Page 组件,默认选中第一个子节点;新增规则 或 判断 Live 模式
|
||||||
@ -349,7 +350,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
?.getId();
|
?.getId();
|
||||||
if (firstChildId) id = firstChildId;
|
if (firstChildId) id = firstChildId;
|
||||||
}
|
}
|
||||||
selection.select(id);
|
selection.select(node.contains(focusNode) ? focusNode.id : id);
|
||||||
|
|
||||||
// dirty code should refector
|
// dirty code should refector
|
||||||
const editor = this.designer?.editor;
|
const editor = this.designer?.editor;
|
||||||
@ -365,7 +366,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isLeftButton && !isRootNode(node)) {
|
if (isLeftButton && !node.contains(focusNode)) {
|
||||||
let nodes: Node[] = [node];
|
let nodes: Node[] = [node];
|
||||||
let ignoreUpSelected = false;
|
let ignoreUpSelected = false;
|
||||||
if (isMulti) {
|
if (isMulti) {
|
||||||
@ -375,7 +376,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
selection.add(node.id);
|
selection.add(node.id);
|
||||||
ignoreUpSelected = true;
|
ignoreUpSelected = true;
|
||||||
}
|
}
|
||||||
selection.remove(documentModel.rootNode.id);
|
selection.remove(focusNode.id);
|
||||||
// 获得顶层 nodes
|
// 获得顶层 nodes
|
||||||
nodes = selection.getTopNodes();
|
nodes = selection.getTopNodes();
|
||||||
} else if (selection.containsNode(node, true)) {
|
} else if (selection.containsNode(node, true)) {
|
||||||
@ -456,7 +457,16 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const nodeInst = this.getNodeInstanceFromElement(e.target as Element);
|
const nodeInst = this.getNodeInstanceFromElement(e.target as Element);
|
||||||
detecting.capture(nodeInst?.node || null);
|
if (nodeInst?.node) {
|
||||||
|
let node = nodeInst.node;
|
||||||
|
const focusNode = node.document.focusNode;
|
||||||
|
if (node.contains(focusNode)) {
|
||||||
|
node = focusNode;
|
||||||
|
}
|
||||||
|
detecting.capture(node);
|
||||||
|
} else {
|
||||||
|
detecting.capture(null);
|
||||||
|
}
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
};
|
};
|
||||||
const leave = () => detecting.leave(this.project.currentDocument);
|
const leave = () => detecting.leave(this.project.currentDocument);
|
||||||
@ -497,7 +507,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
if (!nodeInst) {
|
if (!nodeInst) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const node = nodeInst.node || this.project.currentDocument?.rootNode;
|
const focusNode = this.project.currentDocument!.focusNode;
|
||||||
|
const node = nodeInst.node || focusNode;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -551,7 +562,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
if (!nodeInst) {
|
if (!nodeInst) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const node = nodeInst.node || this.project.currentDocument?.rootNode;
|
const node = nodeInst.node || this.project.currentDocument?.focusNode;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -983,7 +994,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
e.dragObject.nodes[0].componentMeta.isModal
|
e.dragObject.nodes[0].componentMeta.isModal
|
||||||
) {
|
) {
|
||||||
return this.designer.createLocation({
|
return this.designer.createLocation({
|
||||||
target: document.rootNode,
|
target: document.focusNode,
|
||||||
detail,
|
detail,
|
||||||
source: 'simulator' + document.id,
|
source: 'simulator' + document.id,
|
||||||
event: e,
|
event: e,
|
||||||
@ -1132,7 +1143,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p !== container) {
|
if (p !== container) {
|
||||||
container = p || document.rootNode;
|
container = p || document.focusNode;
|
||||||
drillDownExcludes.add(container);
|
drillDownExcludes.add(container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1218,8 +1229,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
handleAccept({ container, instance }: DropContainer, e: LocateEvent): boolean {
|
handleAccept({ container, instance }: DropContainer, e: LocateEvent): boolean {
|
||||||
const { dragObject } = e;
|
const { dragObject } = e;
|
||||||
const document = this.currentDocument!;
|
const document = this.currentDocument!;
|
||||||
if (isRootNode(container)) {
|
const focusNode = document.focusNode;
|
||||||
return document.checkDropTarget(container, dragObject as any);
|
if (isRootNode(container) || container.contains(focusNode)) {
|
||||||
|
return document.checkDropTarget(focusNode, dragObject as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
const meta = (container as Node).componentMeta;
|
const meta = (container as Node).componentMeta;
|
||||||
|
|||||||
@ -31,7 +31,13 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
|||||||
|
|
||||||
// 获取节点的父级节点(最多获取5层)
|
// 获取节点的父级节点(最多获取5层)
|
||||||
getParentNodes = (node: Node) => {
|
getParentNodes = (node: Node) => {
|
||||||
const parentNodes = [];
|
const parentNodes: any[] = [];
|
||||||
|
const focusNode = node.document.focusNode;
|
||||||
|
|
||||||
|
if (node.contains(focusNode) || !focusNode.contains(node)) {
|
||||||
|
return parentNodes;
|
||||||
|
}
|
||||||
|
|
||||||
let currentNode: UnionNode = node;
|
let currentNode: UnionNode = node;
|
||||||
|
|
||||||
while (currentNode && parentNodes.length < 5) {
|
while (currentNode && parentNodes.length < 5) {
|
||||||
@ -39,6 +45,9 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
|||||||
if (currentNode) {
|
if (currentNode) {
|
||||||
parentNodes.push(currentNode);
|
parentNodes.push(currentNode);
|
||||||
}
|
}
|
||||||
|
if (currentNode === focusNode) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return parentNodes;
|
return parentNodes;
|
||||||
};
|
};
|
||||||
@ -72,7 +81,10 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderNodes = (/* node: Node */) => {
|
renderNodes = (/* node: Node */) => {
|
||||||
const nodes = this.state.parentNodes || [];
|
const nodes = this.state.parentNodes;
|
||||||
|
if (!nodes || nodes.length < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const children = nodes.map((node, key) => {
|
const children = nodes.map((node, key) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import {
|
|||||||
NodeSchema,
|
NodeSchema,
|
||||||
} from '@ali/lowcode-types';
|
} from '@ali/lowcode-types';
|
||||||
import { Project } from '../project';
|
import { Project } from '../project';
|
||||||
import { Node, DocumentModel, insertChildren, isRootNode, ParentalNode, TransformStage } from '../document';
|
import { Node, DocumentModel, insertChildren, ParentalNode, TransformStage } from '../document';
|
||||||
import { ComponentMeta } from '../component-meta';
|
import { ComponentMeta } from '../component-meta';
|
||||||
import { INodeSelector, Component } from '../simulator';
|
import { INodeSelector, Component } from '../simulator';
|
||||||
import { Scroller, IScrollable } from './scroller';
|
import { Scroller, IScrollable } from './scroller';
|
||||||
@ -36,6 +36,7 @@ export interface DesignerProps {
|
|||||||
suspensed?: boolean;
|
suspensed?: boolean;
|
||||||
componentMetadatas?: ComponentMetadata[];
|
componentMetadatas?: ComponentMetadata[];
|
||||||
globalComponentActions?: ComponentAction[];
|
globalComponentActions?: ComponentAction[];
|
||||||
|
focusNodeSelector?: (rootNode: Node) => Node;
|
||||||
onMount?: (designer: Designer) => void;
|
onMount?: (designer: Designer) => void;
|
||||||
onDragstart?: (e: LocateEvent) => void;
|
onDragstart?: (e: LocateEvent) => void;
|
||||||
onDrag?: (e: LocateEvent) => void;
|
onDrag?: (e: LocateEvent) => void;
|
||||||
@ -209,6 +210,7 @@ export class Designer {
|
|||||||
}
|
}
|
||||||
const currentSelection = this.currentSelection;
|
const currentSelection = this.currentSelection;
|
||||||
// TODO: 避免选中 Page 组件,默认选中第一个子节点;新增规则 或 判断 Live 模式
|
// TODO: 避免选中 Page 组件,默认选中第一个子节点;新增规则 或 判断 Live 模式
|
||||||
|
// dirty code, should remove
|
||||||
if (currentSelection && currentSelection.selected.length === 0 && this.simulatorProps?.designMode === 'live') {
|
if (currentSelection && currentSelection.selected.length === 0 && this.simulatorProps?.designMode === 'live') {
|
||||||
const rootNodeChildrens = this.currentDocument.getRoot().getChildren().children;
|
const rootNodeChildrens = this.currentDocument.getRoot().getChildren().children;
|
||||||
if (rootNodeChildrens.length > 0) {
|
if (rootNodeChildrens.length > 0) {
|
||||||
@ -300,19 +302,20 @@ export class Designer {
|
|||||||
if (!activedDoc) {
|
if (!activedDoc) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
const focusNode = activedDoc.focusNode;
|
||||||
const nodes = activedDoc.selection.getNodes();
|
const nodes = activedDoc.selection.getNodes();
|
||||||
|
const refNode = nodes.find(item => focusNode.contains(item));
|
||||||
let target;
|
let target;
|
||||||
let index: number | undefined;
|
let index: number | undefined;
|
||||||
if (!nodes || nodes.length < 1) {
|
if (!refNode || refNode === focusNode) {
|
||||||
target = activedDoc.rootNode;
|
target = focusNode;
|
||||||
} else {
|
} else {
|
||||||
const node = nodes[0];
|
if (refNode.componentMeta.isContainer) {
|
||||||
if (isRootNode(node) || node.componentMeta.isContainer) {
|
target = refNode;
|
||||||
target = node;
|
|
||||||
} else {
|
} else {
|
||||||
// FIXME!!, parent maybe null
|
// FIXME!!, parent maybe null
|
||||||
target = node.parent!;
|
target = refNode.parent!;
|
||||||
index = node.index + 1;
|
index = refNode.index + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -105,7 +105,8 @@ export class OffsetObserver {
|
|||||||
this.node = node;
|
this.node = node;
|
||||||
const doc = node.document;
|
const doc = node.document;
|
||||||
const host = doc.simulator!;
|
const host = doc.simulator!;
|
||||||
this.isRoot = isRootNode(node);
|
const focusNode = doc.focusNode;
|
||||||
|
this.isRoot = node.contains(focusNode);
|
||||||
this.viewport = host.viewport;
|
this.viewport = host.viewport;
|
||||||
if (this.isRoot) {
|
if (this.isRoot) {
|
||||||
this.hasOffset = true;
|
this.hasOffset = true;
|
||||||
|
|||||||
@ -94,6 +94,23 @@ export class DocumentModel {
|
|||||||
this.rootNode?.getExtraProp('fileName', true)?.setValue(fileName);
|
this.rootNode?.getExtraProp('fileName', true)?.setValue(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@computed get focusNode() {
|
||||||
|
if (this._drillDownNode) {
|
||||||
|
return this._drillDownNode;
|
||||||
|
}
|
||||||
|
const selector = this.designer.get('focusNodeSelector');
|
||||||
|
if (typeof selector === 'function') {
|
||||||
|
return selector(this.rootNode);
|
||||||
|
}
|
||||||
|
return this.rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@obx.ref private _drillDownNode: Node | null = null;
|
||||||
|
|
||||||
|
drillDown(node: Node | null) {
|
||||||
|
this._drillDownNode = node;
|
||||||
|
}
|
||||||
|
|
||||||
private _modalNode?: ParentalNode;
|
private _modalNode?: ParentalNode;
|
||||||
|
|
||||||
private _blank?: boolean;
|
private _blank?: boolean;
|
||||||
@ -143,7 +160,7 @@ export class DocumentModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get currentRoot() {
|
get currentRoot() {
|
||||||
return this.modalNode || this.rootNode;
|
return this.modalNode || this.focusNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
addWillPurge(node: Node) {
|
addWillPurge(node: Node) {
|
||||||
@ -338,6 +355,7 @@ export class DocumentModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
import(schema: RootSchema, checkId = false) {
|
import(schema: RootSchema, checkId = false) {
|
||||||
|
const drillDownNodeId = this._drillDownNode?.id;
|
||||||
// TODO: 暂时用饱和式删除,原因是 Slot 节点并不是树节点,无法正常递归删除
|
// TODO: 暂时用饱和式删除,原因是 Slot 节点并不是树节点,无法正常递归删除
|
||||||
this.nodes.forEach(node => {
|
this.nodes.forEach(node => {
|
||||||
this.internalRemoveAndPurgeNode(node, true);
|
this.internalRemoveAndPurgeNode(node, true);
|
||||||
@ -347,6 +365,9 @@ export class DocumentModel {
|
|||||||
// });
|
// });
|
||||||
this.rootNode?.import(schema as any, checkId);
|
this.rootNode?.import(schema as any, checkId);
|
||||||
// todo: select added and active track added
|
// todo: select added and active track added
|
||||||
|
if (drillDownNodeId) {
|
||||||
|
this.drillDown(this.getNode(drillDownNodeId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export(stage: TransformStage = TransformStage.Serilize) {
|
export(stage: TransformStage = TransformStage.Serilize) {
|
||||||
|
|||||||
@ -102,7 +102,7 @@ export class Selection {
|
|||||||
containsNode(node: Node, excludeRoot = false) {
|
containsNode(node: Node, excludeRoot = false) {
|
||||||
for (const id of this._selected) {
|
for (const id of this._selected) {
|
||||||
const parent = this.doc.getNode(id);
|
const parent = this.doc.getNode(id);
|
||||||
if (excludeRoot && parent === this.doc.rootNode) {
|
if (excludeRoot && parent?.contains(this.doc.focusNode)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (parent?.contains(node)) {
|
if (parent?.contains(node)) {
|
||||||
@ -134,7 +134,7 @@ export class Selection {
|
|||||||
for (const id of this._selected) {
|
for (const id of this._selected) {
|
||||||
const node = this.doc.getNode(id);
|
const node = this.doc.getNode(id);
|
||||||
// 排除根节点
|
// 排除根节点
|
||||||
if (!node || (!includeRoot && node === this.doc.rootNode)) {
|
if (!node || (!includeRoot && node.contains(this.doc.focusNode))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let i = nodes.length;
|
let i = nodes.length;
|
||||||
|
|||||||
@ -58,13 +58,18 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
|
|||||||
const designer = editor.get(Designer);
|
const designer = editor.get(Designer);
|
||||||
const current = designer?.currentSelection?.getNodes()?.[0];
|
const current = designer?.currentSelection?.getNodes()?.[0];
|
||||||
let node: Node | null = settings.first;
|
let node: Node | null = settings.first;
|
||||||
|
const focusNode = node.document.focusNode;
|
||||||
|
|
||||||
const items = [];
|
const items = [];
|
||||||
let l = 3;
|
let l = 3;
|
||||||
while (l-- > 0 && node) {
|
while (l-- > 0 && node) {
|
||||||
const _node = node;
|
const _node = node;
|
||||||
|
// dirty code: should remove
|
||||||
if (shouldIgnoreRoot && node.isRoot()) {
|
if (shouldIgnoreRoot && node.isRoot()) {
|
||||||
node = null;
|
break;
|
||||||
continue;
|
}
|
||||||
|
if (node.contains(focusNode)) {
|
||||||
|
l = 0;
|
||||||
}
|
}
|
||||||
const props =
|
const props =
|
||||||
l === 2
|
l === 2
|
||||||
|
|||||||
@ -161,7 +161,7 @@ export class OutlineMain implements ISensor, ITreeBoard, IScrollable {
|
|||||||
const componentMeta = e.dragObject.nodes ? e.dragObject.nodes[0].componentMeta : null;
|
const componentMeta = e.dragObject.nodes ? e.dragObject.nodes[0].componentMeta : null;
|
||||||
if (e.dragObject.type === 'node' && componentMeta && componentMeta.isModal) {
|
if (e.dragObject.type === 'node' && componentMeta && componentMeta.isModal) {
|
||||||
return designer.createLocation({
|
return designer.createLocation({
|
||||||
target: document.rootNode,
|
target: document.focusNode,
|
||||||
detail: {
|
detail: {
|
||||||
type: LocationDetailType.Children,
|
type: LocationDetailType.Children,
|
||||||
index: 0,
|
index: 0,
|
||||||
@ -226,7 +226,7 @@ export class OutlineMain implements ISensor, ITreeBoard, IScrollable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p !== node) {
|
if (p !== node) {
|
||||||
node = p || document.rootNode;
|
node = p || document.focusNode;
|
||||||
treeNode = tree.getTreeNode(node);
|
treeNode = tree.getTreeNode(node);
|
||||||
focusSlots = false;
|
focusSlots = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,17 @@
|
|||||||
import { DocumentModel, Node } from '@ali/lowcode-designer';
|
import { DocumentModel, Node } from '@ali/lowcode-designer';
|
||||||
|
import { computed } from '@ali/lowcode-editor-core';
|
||||||
import TreeNode from './tree-node';
|
import TreeNode from './tree-node';
|
||||||
|
|
||||||
export class Tree {
|
export class Tree {
|
||||||
private treeNodesMap = new Map<string, TreeNode>();
|
private treeNodesMap = new Map<string, TreeNode>();
|
||||||
|
|
||||||
readonly root: TreeNode;
|
|
||||||
|
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
|
|
||||||
readonly document: DocumentModel;
|
@computed get root(): TreeNode {
|
||||||
|
return this.getTreeNode(this.document.focusNode);
|
||||||
|
}
|
||||||
|
|
||||||
constructor(document: DocumentModel) {
|
constructor(readonly document: DocumentModel) {
|
||||||
this.document = document;
|
|
||||||
this.root = this.getTreeNode(document.rootNode);
|
|
||||||
this.id = document.id;
|
this.id = document.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,11 +51,11 @@ export default class TreeView extends Component<{ tree: Tree }> {
|
|||||||
const { node } = treeNode;
|
const { node } = treeNode;
|
||||||
const { designer } = treeNode;
|
const { designer } = treeNode;
|
||||||
const doc = node.document;
|
const doc = node.document;
|
||||||
const { selection } = doc;
|
const { selection, focusNode } = doc;
|
||||||
const { id } = node;
|
const { id } = node;
|
||||||
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
|
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
|
||||||
designer.activeTracker.track(node);
|
designer.activeTracker.track(node);
|
||||||
if (isMulti && !isRootNode(node) && selection.has(id)) {
|
if (isMulti && !node.contains(focusNode) && selection.has(id)) {
|
||||||
if (!isFormEvent(e.nativeEvent)) {
|
if (!isFormEvent(e.nativeEvent)) {
|
||||||
selection.remove(id);
|
selection.remove(id);
|
||||||
}
|
}
|
||||||
@ -107,13 +107,13 @@ export default class TreeView extends Component<{ tree: Tree }> {
|
|||||||
const { node } = treeNode;
|
const { node } = treeNode;
|
||||||
const { designer } = treeNode;
|
const { designer } = treeNode;
|
||||||
const doc = node.document;
|
const doc = node.document;
|
||||||
const { selection } = doc;
|
const { selection, focusNode } = doc;
|
||||||
|
|
||||||
// TODO: shift selection
|
// TODO: shift selection
|
||||||
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
|
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
|
||||||
const isLeftButton = e.button === 0;
|
const isLeftButton = e.button === 0;
|
||||||
|
|
||||||
if (isLeftButton && !isRootNode(node)) {
|
if (isLeftButton && !node.contains(focusNode)) {
|
||||||
let nodes: Node[] = [node];
|
let nodes: Node[] = [node];
|
||||||
this.ignoreUpSelected = false;
|
this.ignoreUpSelected = false;
|
||||||
if (isMulti) {
|
if (isMulti) {
|
||||||
@ -123,7 +123,8 @@ export default class TreeView extends Component<{ tree: Tree }> {
|
|||||||
selection.add(node.id);
|
selection.add(node.id);
|
||||||
this.ignoreUpSelected = true;
|
this.ignoreUpSelected = true;
|
||||||
}
|
}
|
||||||
selection.remove(doc.rootNode.id);
|
// todo: remove rootNodes id
|
||||||
|
selection.remove(focusNode.id);
|
||||||
// 获得顶层 nodes
|
// 获得顶层 nodes
|
||||||
nodes = selection.getTopNodes();
|
nodes = selection.getTopNodes();
|
||||||
} else if (selection.has(node.id)) {
|
} else if (selection.has(node.id)) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user