import { injectable, inject } from 'inversify'; import { IDropable, IDragable } from '../dnd'; import { OperatePositionEnum, OperateTypeEnum } from './types'; import { LinkedTree, LinkedTreeNode, IDisposable } from 'ts-toolset'; /** 树形拖拽接口 */ export interface ITreeDnd extends IDragable, IDropable, IDisposable { readonly operatePosition?: OperatePositionEnum; readonly operateType?: OperateTypeEnum; readonly selectedTarget?: LinkedTreeNode; readonly hoverTarget?: LinkedTreeNode; readonly dragTarget?: LinkedTreeNode; readonly dropTarget?: LinkedTreeNode; onSelectNode: (node: LinkedTreeNode) => void; onOverNode: (node: LinkedTreeNode) => void; onClearSelected: () => void; onClearDrop: () => void; onClearOver: () => void; } /** 属性拖拽 */ @injectable() export abstract class TreeDnd implements ITreeDnd { protected _operatePosition?: OperatePositionEnum; protected _operateType?: OperateTypeEnum; protected _selectedNode?: LinkedTreeNode; protected _overNode?: LinkedTreeNode; protected _contextMenuNode?: LinkedTreeNode; protected _dragNode?: LinkedTreeNode; protected _dropNode?: LinkedTreeNode; get operatePosition() { return this._operatePosition; } get operateType() { return this._operateType; } get selectedNode() { return this._selectedNode; } get overNode() { return this._overNode; } get contextMenuNode() { return this._contextMenuNode; } get dragNode() { return this._dragNode; } get dropNode() { return this._dropNode; } //constructor(private _linkedTree: LinkedTree) { } onOverNode(overNode: LinkedTreeNode) { let isOver = !this._overNode || (this._overNode && this._overNode !== overNode); isOver && (this._overNode = overNode); this.abstractOnOverNode(overNode, isOver); } protected abstract abstractOnOverNode(overNode: LinkedTreeNode, isOver: boolean): void; onSelectNode(selectNode: LinkedTreeNode) { this._selectedNode = selectNode; this.abstractOnSelectNode(selectNode); } protected abstract abstractOnSelectNode(selectNode: LinkedTreeNode): void; onContextMenu(node: LinkedTreeNode) { this._contextMenuNode = node; this.abstractOnContextMenu(node); } protected abstract abstractOnContextMenu(node: LinkedTreeNode): void; canDrop(overNode: LinkedTreeNode) { return !!(this._dragNode && this._dragNode !== this._overNode && !overNode.hasAncestor(this._dragNode)) && this.abstractCanDrop(overNode); } protected abstract abstractCanDrop(overNode: LinkedTreeNode): boolean; dragStart(dragNode: LinkedTreeNode) { this._dragNode = dragNode; this._operateType = OperateTypeEnum.move; this.abstractDragStart(dragNode); } protected abstract abstractDragStart(dragNode: LinkedTreeNode): void; dragOver(overNode: LinkedTreeNode) { let canDrop = this.canDrop(overNode); this._dropNode = canDrop ? overNode : undefined; this.abstractDragOver(this._dropNode, canDrop); this._overNode = undefined; } protected abstract abstractDragOver(overNode: LinkedTreeNode | undefined, canDrop: boolean): void; drop(dropNode: LinkedTreeNode) { this._dropNode = dropNode; this.abstractDrop(dropNode); } protected abstract abstractDrop(dropNode: LinkedTreeNode): void; dragEnd() { this._dragNode = undefined; this._dropNode = undefined; this._operatePosition = undefined; this._operateType = undefined; this.abstractDragEnd(); } protected abstract abstractDragEnd(): void; onClearOver() { this._overNode = undefined; this.abstractOnClearOver(); } protected abstract abstractOnClearOver(): void; onClearSelected() { this._selectedNode = undefined; this._contextMenuNode = undefined; this.abstractOnClearSelected(); } protected abstract abstractOnClearSelected(): void; onClearDrop() { this._dropNode = undefined; this._overNode = undefined; this.abstractOnClearDrop(); } protected abstract abstractOnClearDrop(): void; abstract dispose(): void; }