-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
04bc508
commit 16effa4
Showing
10 changed files
with
214 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import { Engine, TreeNode } from '../models'; | ||
import { DragMoveEvent, DragStartEvent, DragStopEvent } from '../events/cursor'; | ||
import { CursorDragType, CursorType } from '../models/cursor'; | ||
import { ClosestPosition } from '../models/move-helper'; | ||
import { Point } from '../../shared/coordinate'; | ||
import { ViewportScrollEvent } from '../events/viewport'; | ||
|
||
export const useDragDropEffect = (engine: Engine) => { | ||
engine.subscribeTo(DragStartEvent, event => { | ||
if (engine.cursor.type !== CursorType.Normal) return; | ||
const target = event.data.target as HTMLElement; | ||
const el = target?.closest(` | ||
*[${engine.props.nodeIdAttrName}], | ||
*[${engine.props.sourceIdAttrName}], | ||
*[${engine.props.outlineNodeIdAttrName}] | ||
`); | ||
const handler = target?.closest(`*[${engine.props.nodeDragHandlerAttrName}]`); | ||
const helper = handler?.closest(`*[${engine.props.nodeSelectionIdAttrName}]`); | ||
if (!el?.getAttribute && !handler) return; | ||
const sourceId = el?.getAttribute(engine.props.sourceIdAttrName); | ||
const outlineId = el?.getAttribute(engine.props.outlineNodeIdAttrName); | ||
const handlerId = helper?.getAttribute(engine.props.nodeSelectionIdAttrName); | ||
const nodeId = el?.getAttribute(engine.props.nodeIdAttrName); | ||
engine.workbench.eachWorkspace(currentWorkspace => { | ||
const operation = currentWorkspace.operation; | ||
const moveHelper = operation.moveHelper; | ||
if (nodeId || outlineId || handlerId) { | ||
const node = engine.findNodeById(outlineId || nodeId || handlerId); | ||
if (node) { | ||
if (!node.allowDrag()) return; | ||
if (node === node.root) return; | ||
const validSelected = engine.getAllSelectedNodes().filter(node => node.allowDrag()); | ||
if (validSelected.some(selectNode => selectNode === node)) { | ||
moveHelper.dragStart({ dragNodes: TreeNode.sort(validSelected) }); | ||
} else { | ||
moveHelper.dragStart({ dragNodes: [node] }); | ||
} | ||
} | ||
} else if (sourceId) { | ||
const sourceNode = engine.findNodeById(sourceId); | ||
if (sourceNode) { | ||
moveHelper.dragStart({ dragNodes: [sourceNode] }); | ||
} | ||
} | ||
}); | ||
engine.cursor.setStyle('move'); | ||
}); | ||
|
||
engine.subscribeTo(DragMoveEvent, event => { | ||
if (engine.cursor.type !== CursorType.Normal) return; | ||
if (engine.cursor.dragType !== CursorDragType.Move) return; | ||
const target = event.data.target as HTMLElement; | ||
const el = target?.closest(` | ||
*[${engine.props.nodeIdAttrName}], | ||
*[${engine.props.outlineNodeIdAttrName}] | ||
`); | ||
const point = new Point(event.data.topClientX, event.data.topClientY); | ||
const nodeId = el?.getAttribute(engine.props.nodeIdAttrName); | ||
const outlineId = el?.getAttribute(engine.props.outlineNodeIdAttrName); | ||
engine.workbench.eachWorkspace(currentWorkspace => { | ||
const operation = currentWorkspace.operation; | ||
const moveHelper = operation.moveHelper; | ||
const dragNodes = moveHelper.dragNodes; | ||
const tree = operation.tree; | ||
if (!dragNodes.length) return; | ||
const touchNode = tree.findById(outlineId || nodeId); | ||
moveHelper.dragMove({ | ||
point, | ||
touchNode | ||
}); | ||
}); | ||
}); | ||
|
||
engine.subscribeTo(ViewportScrollEvent, event => { | ||
if (engine.cursor.type !== CursorType.Normal) return; | ||
if (engine.cursor.dragType !== CursorDragType.Move) return; | ||
const point = new Point(engine.cursor.position.topClientX, engine.cursor.position.topClientY); | ||
const currentWorkspace = event?.context?.workspace ?? engine.workbench.activeWorkspace; | ||
if (!currentWorkspace) return; | ||
const operation = currentWorkspace.operation; | ||
const moveHelper = operation.moveHelper; | ||
if (!moveHelper.dragNodes.length) return; | ||
const tree = operation.tree; | ||
const viewport = currentWorkspace.viewport; | ||
const outline = currentWorkspace.outline; | ||
const viewportTarget = viewport.elementFromPoint(point); | ||
const outlineTarget = outline.elementFromPoint(point); | ||
const viewportNodeElement = viewportTarget?.closest(` | ||
*[${engine.props.nodeIdAttrName}], | ||
*[${engine.props.outlineNodeIdAttrName}] | ||
`); | ||
const outlineNodeElement = outlineTarget?.closest(` | ||
*[${engine.props.nodeIdAttrName}], | ||
*[${engine.props.outlineNodeIdAttrName}] | ||
`); | ||
const nodeId = viewportNodeElement?.getAttribute(engine.props.nodeIdAttrName); | ||
const outlineNodeId = outlineNodeElement?.getAttribute(engine.props.outlineNodeIdAttrName); | ||
const touchNode = tree.findById(outlineNodeId || nodeId); | ||
moveHelper.dragMove({ point, touchNode }); | ||
}); | ||
|
||
engine.subscribeTo(DragStopEvent, () => { | ||
if (engine.cursor.type !== CursorType.Normal) return; | ||
if (engine.cursor.dragType !== CursorDragType.Move) return; | ||
engine.workbench.eachWorkspace(currentWorkspace => { | ||
const operation = currentWorkspace.operation; | ||
const moveHelper = operation.moveHelper; | ||
const dragNodes = moveHelper.dragNodes; | ||
const closestNode = moveHelper.closestNode; | ||
const closestDirection = moveHelper.closestDirection; | ||
const selection = operation.selection; | ||
if (!dragNodes.length) return; | ||
if (dragNodes.length && closestNode && closestDirection) { | ||
if (closestDirection === ClosestPosition.After || closestDirection === ClosestPosition.Under) { | ||
if (closestNode.allowSibling(dragNodes)) { | ||
selection.batchSafeSelect( | ||
closestNode.insertAfter(...TreeNode.filterDroppable(dragNodes, closestNode.parent)) | ||
); | ||
} | ||
} else if (closestDirection === ClosestPosition.Before || closestDirection === ClosestPosition.Upper) { | ||
if (closestNode.allowSibling(dragNodes)) { | ||
selection.batchSafeSelect( | ||
closestNode.insertBefore(...TreeNode.filterDroppable(dragNodes, closestNode.parent)) | ||
); | ||
} | ||
} else if (closestDirection === ClosestPosition.Inner || closestDirection === ClosestPosition.InnerAfter) { | ||
if (closestNode.allowAppend(dragNodes)) { | ||
selection.batchSafeSelect(closestNode.append(...TreeNode.filterDroppable(dragNodes, closestNode))); | ||
moveHelper.dragDrop({ dropNode: closestNode }); | ||
} | ||
} else if (closestDirection === ClosestPosition.InnerBefore) { | ||
if (closestNode.allowAppend(dragNodes)) { | ||
selection.batchSafeSelect(closestNode.prepend(...TreeNode.filterDroppable(dragNodes, closestNode))); | ||
moveHelper.dragDrop({ dropNode: closestNode }); | ||
} | ||
} | ||
} | ||
moveHelper.dragEnd(); | ||
}); | ||
engine.cursor.setStyle(''); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { IEngineContext } from '../../types'; | ||
import { globalThisPolyfill } from '../../../shared/globalThisPolyfill'; | ||
|
||
export interface IViewportEventData { | ||
scrollX: number; | ||
scrollY: number; | ||
width: number; | ||
height: number; | ||
view: Window; | ||
innerWidth: number; | ||
innerHeight: number; | ||
target: EventTarget; | ||
} | ||
|
||
export class AbstractViewportEvent { | ||
data: IViewportEventData; | ||
context: IEngineContext; | ||
constructor(data: IViewportEventData) { | ||
this.data = data || { | ||
scrollX: globalThisPolyfill.scrollX, | ||
scrollY: globalThisPolyfill.scrollY, | ||
width: globalThisPolyfill.innerWidth, | ||
height: globalThisPolyfill.innerHeight, | ||
innerWidth: globalThisPolyfill.innerWidth, | ||
innerHeight: globalThisPolyfill.innerHeight, | ||
view: globalThisPolyfill, | ||
target: globalThisPolyfill | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { AbstractViewportEvent } from './AbstractViewportEvent'; | ||
import { ICustomEvent } from '../../../shared/event'; | ||
|
||
export class ViewportResizeEvent extends AbstractViewportEvent implements ICustomEvent { | ||
type = 'viewport:resize'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { ICustomEvent } from '../../../shared/event'; | ||
import { AbstractViewportEvent } from './AbstractViewportEvent'; | ||
|
||
export class ViewportScrollEvent extends AbstractViewportEvent implements ICustomEvent { | ||
type = 'viewport:scroll'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './ViewportResizeEvent' | ||
export * from './ViewportScrollEvent' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { useDragDropEffect } from './effects/useDragDropEffect'; | ||
|
||
export const DEFAULT_EFFECTS = [useDragDropEffect]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters