mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
Add Swap Node functionality (#56)
Adds the ability to swap nodes by dragging to the center of a tile. Also fixes a bug where moving a node to a new lesser index under the same parent would produce a no-op.
This commit is contained in:
parent
b71ae8e6e8
commit
48d4611a05
@ -29,6 +29,7 @@ import {
|
|||||||
LayoutTreeDeleteNodeAction,
|
LayoutTreeDeleteNodeAction,
|
||||||
LayoutTreeMoveNodeAction,
|
LayoutTreeMoveNodeAction,
|
||||||
LayoutTreeState,
|
LayoutTreeState,
|
||||||
|
LayoutTreeSwapNodeAction,
|
||||||
PreviewRenderer,
|
PreviewRenderer,
|
||||||
WritableLayoutTreeStateAtom,
|
WritableLayoutTreeStateAtom,
|
||||||
} from "./model";
|
} from "./model";
|
||||||
@ -518,7 +519,9 @@ const Placeholder = <T,>({ layoutTreeState, overlayContainerRef, nodeRefs, style
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let newPlaceholderOverlay: ReactNode;
|
let newPlaceholderOverlay: ReactNode;
|
||||||
if (layoutTreeState?.pendingAction?.type === LayoutTreeActionType.Move && overlayContainerRef?.current) {
|
if (overlayContainerRef?.current) {
|
||||||
|
switch (layoutTreeState?.pendingAction?.type) {
|
||||||
|
case LayoutTreeActionType.Move: {
|
||||||
const action = layoutTreeState.pendingAction as LayoutTreeMoveNodeAction<T>;
|
const action = layoutTreeState.pendingAction as LayoutTreeMoveNodeAction<T>;
|
||||||
let parentId: string;
|
let parentId: string;
|
||||||
if (action.insertAtRoot) {
|
if (action.insertAtRoot) {
|
||||||
@ -564,7 +567,8 @@ const Placeholder = <T,>({ layoutTreeState, overlayContainerRef, nodeRefs, style
|
|||||||
if (action.index >= (parentNode.children?.length ?? 1)) {
|
if (action.index >= (parentNode.children?.length ?? 1)) {
|
||||||
// If there are no more nodes after the specified index, place the placeholder in the second half of the target node (either right or bottom).
|
// If there are no more nodes after the specified index, place the placeholder in the second half of the target node (either right or bottom).
|
||||||
placeholderDimensions.top +=
|
placeholderDimensions.top +=
|
||||||
parentNode.flexDirection === FlexDirection.Column && targetBoundingRect.height / 2;
|
parentNode.flexDirection === FlexDirection.Column &&
|
||||||
|
targetBoundingRect.height / 2;
|
||||||
placeholderDimensions.left +=
|
placeholderDimensions.left +=
|
||||||
parentNode.flexDirection === FlexDirection.Row && targetBoundingRect.width / 2;
|
parentNode.flexDirection === FlexDirection.Row && targetBoundingRect.width / 2;
|
||||||
} else {
|
} else {
|
||||||
@ -573,14 +577,41 @@ const Placeholder = <T,>({ layoutTreeState, overlayContainerRef, nodeRefs, style
|
|||||||
parentNode.flexDirection === FlexDirection.Column &&
|
parentNode.flexDirection === FlexDirection.Column &&
|
||||||
(3 * targetBoundingRect.height) / 4;
|
(3 * targetBoundingRect.height) / 4;
|
||||||
placeholderDimensions.left +=
|
placeholderDimensions.left +=
|
||||||
parentNode.flexDirection === FlexDirection.Row && (3 * targetBoundingRect.width) / 4;
|
parentNode.flexDirection === FlexDirection.Row &&
|
||||||
|
(3 * targetBoundingRect.width) / 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const placeholderTransform = createTransform(placeholderDimensions);
|
|
||||||
|
|
||||||
|
const placeholderTransform = createTransform(placeholderDimensions);
|
||||||
newPlaceholderOverlay = <div className="placeholder" style={{ ...placeholderTransform }} />;
|
newPlaceholderOverlay = <div className="placeholder" style={{ ...placeholderTransform }} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LayoutTreeActionType.Swap: {
|
||||||
|
const action = layoutTreeState.pendingAction as LayoutTreeSwapNodeAction<T>;
|
||||||
|
console.log("placeholder for swap", action);
|
||||||
|
const targetNode = action.node1;
|
||||||
|
const targetRef = nodeRefs.get(targetNode?.id);
|
||||||
|
if (targetRef?.current) {
|
||||||
|
const overlayBoundingRect = overlayContainerRef.current.getBoundingClientRect();
|
||||||
|
const targetBoundingRect = targetRef.current.getBoundingClientRect();
|
||||||
|
const placeholderDimensions: Dimensions = {
|
||||||
|
top: targetBoundingRect.top - overlayBoundingRect.top,
|
||||||
|
left: targetBoundingRect.left - overlayBoundingRect.left,
|
||||||
|
height: targetBoundingRect.height,
|
||||||
|
width: targetBoundingRect.width,
|
||||||
|
};
|
||||||
|
|
||||||
|
const placeholderTransform = createTransform(placeholderDimensions);
|
||||||
|
newPlaceholderOverlay = <div className="placeholder" style={{ ...placeholderTransform }} />;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// No-op
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setPlaceholderOverlay(newPlaceholderOverlay);
|
setPlaceholderOverlay(newPlaceholderOverlay);
|
||||||
}, [layoutTreeState, nodeRefs, overlayContainerRef]);
|
}, [layoutTreeState, nodeRefs, overlayContainerRef]);
|
||||||
|
@ -99,12 +99,13 @@ export function addIntermediateNode<T>(node: LayoutNode<T>): LayoutNode<T> {
|
|||||||
* Attempts to remove the specified node from its parent.
|
* Attempts to remove the specified node from its parent.
|
||||||
* @param parent The parent node.
|
* @param parent The parent node.
|
||||||
* @param childToRemove The node to remove.
|
* @param childToRemove The node to remove.
|
||||||
|
* @param startingIndex The index in children to start the search from.
|
||||||
* @template T The type of data associated with the node.
|
* @template T The type of data associated with the node.
|
||||||
* @returns The updated parent node, or undefined if the node was not found.
|
* @returns The updated parent node, or undefined if the node was not found.
|
||||||
*/
|
*/
|
||||||
export function removeChild<T>(parent: LayoutNode<T>, childToRemove: LayoutNode<T>) {
|
export function removeChild<T>(parent: LayoutNode<T>, childToRemove: LayoutNode<T>, startingIndex: number = 0) {
|
||||||
if (!parent.children) return;
|
if (!parent.children) return;
|
||||||
const idx = parent.children.indexOf(childToRemove);
|
const idx = parent.children.indexOf(childToRemove, startingIndex);
|
||||||
if (idx === -1) return;
|
if (idx === -1) return;
|
||||||
parent.children?.splice(idx, 1);
|
parent.children?.splice(idx, 1);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import {
|
|||||||
LayoutTreeInsertNodeAction,
|
LayoutTreeInsertNodeAction,
|
||||||
LayoutTreeMoveNodeAction,
|
LayoutTreeMoveNodeAction,
|
||||||
LayoutTreeState,
|
LayoutTreeState,
|
||||||
|
LayoutTreeSwapNodeAction,
|
||||||
MoveOperation,
|
MoveOperation,
|
||||||
} from "./model";
|
} from "./model";
|
||||||
import { DropDirection, FlexDirection, lazy } from "./utils";
|
import { DropDirection, FlexDirection, lazy } from "./utils";
|
||||||
@ -88,6 +89,10 @@ function layoutTreeStateReducerInner<T>(layoutTreeState: LayoutTreeState<T>, act
|
|||||||
deleteNode(layoutTreeState, action as LayoutTreeDeleteNodeAction);
|
deleteNode(layoutTreeState, action as LayoutTreeDeleteNodeAction);
|
||||||
layoutTreeState.generation++;
|
layoutTreeState.generation++;
|
||||||
break;
|
break;
|
||||||
|
case LayoutTreeActionType.Swap:
|
||||||
|
swapNode(layoutTreeState, action as LayoutTreeSwapNodeAction<T>);
|
||||||
|
layoutTreeState.generation++;
|
||||||
|
break;
|
||||||
default: {
|
default: {
|
||||||
console.error("Invalid reducer action", layoutTreeState, action);
|
console.error("Invalid reducer action", layoutTreeState, action);
|
||||||
}
|
}
|
||||||
@ -114,7 +119,12 @@ function computeMoveNode<T>(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newOperation: MoveOperation<T>;
|
if (node.id === nodeToMove.id) {
|
||||||
|
console.warn("Cannot compute move node action since both nodes are equal");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let newMoveOperation: MoveOperation<T>;
|
||||||
const parent = lazy(() => findParent(rootNode, node.id));
|
const parent = lazy(() => findParent(rootNode, node.id));
|
||||||
const grandparent = lazy(() => findParent(rootNode, parent().id));
|
const grandparent = lazy(() => findParent(rootNode, parent().id));
|
||||||
const indexInParent = lazy(() => parent()?.children.findIndex((child) => node.id === child.id));
|
const indexInParent = lazy(() => parent()?.children.findIndex((child) => node.id === child.id));
|
||||||
@ -129,7 +139,7 @@ function computeMoveNode<T>(
|
|||||||
if (grandparentNode) {
|
if (grandparentNode) {
|
||||||
console.log("has grandparent", grandparentNode);
|
console.log("has grandparent", grandparentNode);
|
||||||
const index = indexInGrandparent();
|
const index = indexInGrandparent();
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
parentId: grandparentNode.id,
|
parentId: grandparentNode.id,
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
index,
|
index,
|
||||||
@ -139,10 +149,10 @@ function computeMoveNode<T>(
|
|||||||
}
|
}
|
||||||
case DropDirection.Top:
|
case DropDirection.Top:
|
||||||
if (node.flexDirection === FlexDirection.Column) {
|
if (node.flexDirection === FlexDirection.Column) {
|
||||||
newOperation = { parentId: node.id, index: 0, node: nodeToMove };
|
newMoveOperation = { parentId: node.id, index: 0, node: nodeToMove };
|
||||||
} else {
|
} else {
|
||||||
if (isRoot)
|
if (isRoot)
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
index: 0,
|
index: 0,
|
||||||
insertAtRoot: true,
|
insertAtRoot: true,
|
||||||
@ -150,7 +160,7 @@ function computeMoveNode<T>(
|
|||||||
|
|
||||||
const parentNode = parent();
|
const parentNode = parent();
|
||||||
if (parentNode)
|
if (parentNode)
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
parentId: parentNode.id,
|
parentId: parentNode.id,
|
||||||
index: indexInParent() ?? 0,
|
index: indexInParent() ?? 0,
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
@ -164,7 +174,7 @@ function computeMoveNode<T>(
|
|||||||
if (grandparentNode) {
|
if (grandparentNode) {
|
||||||
console.log("has grandparent", grandparentNode);
|
console.log("has grandparent", grandparentNode);
|
||||||
const index = indexInGrandparent() + 1;
|
const index = indexInGrandparent() + 1;
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
parentId: grandparentNode.id,
|
parentId: grandparentNode.id,
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
index,
|
index,
|
||||||
@ -174,10 +184,10 @@ function computeMoveNode<T>(
|
|||||||
}
|
}
|
||||||
case DropDirection.Bottom:
|
case DropDirection.Bottom:
|
||||||
if (node.flexDirection === FlexDirection.Column) {
|
if (node.flexDirection === FlexDirection.Column) {
|
||||||
newOperation = { parentId: node.id, index: 1, node: nodeToMove };
|
newMoveOperation = { parentId: node.id, index: 1, node: nodeToMove };
|
||||||
} else {
|
} else {
|
||||||
if (isRoot)
|
if (isRoot)
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
index: 1,
|
index: 1,
|
||||||
insertAtRoot: true,
|
insertAtRoot: true,
|
||||||
@ -185,7 +195,7 @@ function computeMoveNode<T>(
|
|||||||
|
|
||||||
const parentNode = parent();
|
const parentNode = parent();
|
||||||
if (parentNode)
|
if (parentNode)
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
parentId: parentNode.id,
|
parentId: parentNode.id,
|
||||||
index: indexInParent() + 1,
|
index: indexInParent() + 1,
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
@ -199,7 +209,7 @@ function computeMoveNode<T>(
|
|||||||
if (grandparentNode) {
|
if (grandparentNode) {
|
||||||
console.log("has grandparent", grandparentNode);
|
console.log("has grandparent", grandparentNode);
|
||||||
const index = indexInGrandparent();
|
const index = indexInGrandparent();
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
parentId: grandparentNode.id,
|
parentId: grandparentNode.id,
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
index,
|
index,
|
||||||
@ -209,11 +219,11 @@ function computeMoveNode<T>(
|
|||||||
}
|
}
|
||||||
case DropDirection.Left:
|
case DropDirection.Left:
|
||||||
if (node.flexDirection === FlexDirection.Row) {
|
if (node.flexDirection === FlexDirection.Row) {
|
||||||
newOperation = { parentId: node.id, index: 0, node: nodeToMove };
|
newMoveOperation = { parentId: node.id, index: 0, node: nodeToMove };
|
||||||
} else {
|
} else {
|
||||||
const parentNode = parent();
|
const parentNode = parent();
|
||||||
if (parentNode)
|
if (parentNode)
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
parentId: parentNode.id,
|
parentId: parentNode.id,
|
||||||
index: indexInParent(),
|
index: indexInParent(),
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
@ -227,7 +237,7 @@ function computeMoveNode<T>(
|
|||||||
if (grandparentNode) {
|
if (grandparentNode) {
|
||||||
console.log("has grandparent", grandparentNode);
|
console.log("has grandparent", grandparentNode);
|
||||||
const index = indexInGrandparent() + 1;
|
const index = indexInGrandparent() + 1;
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
parentId: grandparentNode.id,
|
parentId: grandparentNode.id,
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
index,
|
index,
|
||||||
@ -237,11 +247,11 @@ function computeMoveNode<T>(
|
|||||||
}
|
}
|
||||||
case DropDirection.Right:
|
case DropDirection.Right:
|
||||||
if (node.flexDirection === FlexDirection.Row) {
|
if (node.flexDirection === FlexDirection.Row) {
|
||||||
newOperation = { parentId: node.id, index: 1, node: nodeToMove };
|
newMoveOperation = { parentId: node.id, index: 1, node: nodeToMove };
|
||||||
} else {
|
} else {
|
||||||
const parentNode = parent();
|
const parentNode = parent();
|
||||||
if (parentNode)
|
if (parentNode)
|
||||||
newOperation = {
|
newMoveOperation = {
|
||||||
parentId: parentNode.id,
|
parentId: parentNode.id,
|
||||||
index: indexInParent() + 1,
|
index: indexInParent() + 1,
|
||||||
node: nodeToMove,
|
node: nodeToMove,
|
||||||
@ -249,14 +259,28 @@ function computeMoveNode<T>(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DropDirection.Center:
|
case DropDirection.Center:
|
||||||
// TODO: handle center drop
|
console.log("center drop", rootNode, node, nodeToMove);
|
||||||
console.log("center drop");
|
if (node.id !== rootNode.id && nodeToMove.id !== rootNode.id) {
|
||||||
|
const swapAction: LayoutTreeSwapNodeAction<T> = {
|
||||||
|
type: LayoutTreeActionType.Swap,
|
||||||
|
node1: node,
|
||||||
|
node2: nodeToMove,
|
||||||
|
};
|
||||||
|
console.log("swapAction", swapAction);
|
||||||
|
layoutTreeState.pendingAction = swapAction;
|
||||||
|
} else {
|
||||||
|
console.warn("cannot swap");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid direction: ${direction}`);
|
throw new Error(`Invalid direction: ${direction}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newOperation) layoutTreeState.pendingAction = { type: LayoutTreeActionType.Move, ...newOperation };
|
if (newMoveOperation)
|
||||||
|
layoutTreeState.pendingAction = {
|
||||||
|
type: LayoutTreeActionType.Move,
|
||||||
|
...newMoveOperation,
|
||||||
|
} as LayoutTreeMoveNodeAction<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveNode<T>(layoutTreeState: LayoutTreeState<T>, action: LayoutTreeMoveNodeAction<T>) {
|
function moveNode<T>(layoutTreeState: LayoutTreeState<T>, action: LayoutTreeMoveNodeAction<T>) {
|
||||||
@ -271,12 +295,23 @@ function moveNode<T>(layoutTreeState: LayoutTreeState<T>, action: LayoutTreeMove
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = findNode(rootNode, action.node.id) ?? action.node;
|
const node = findNode(rootNode, action.node.id) ?? action.node;
|
||||||
let parent = findNode(rootNode, action.parentId);
|
const parent = findNode(rootNode, action.parentId);
|
||||||
let oldParent = findParent(rootNode, action.node.id);
|
const oldParent = findParent(rootNode, action.node.id);
|
||||||
|
|
||||||
console.log(node, parent, oldParent);
|
console.log(node, parent, oldParent);
|
||||||
|
|
||||||
|
let startingIndex = 0;
|
||||||
|
|
||||||
|
// If moving under the same parent, we need to make sure that we are removing the child from its old position, not its new one.
|
||||||
|
// If the new index is before the old index, we need to start our search for the node to delete after the new index position.
|
||||||
|
if (oldParent?.id === parent.id) {
|
||||||
|
const curIndexInParent = parent.children!.indexOf(node);
|
||||||
|
if (curIndexInParent >= action.index) {
|
||||||
|
startingIndex = action.index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!parent && action.insertAtRoot) {
|
if (!parent && action.insertAtRoot) {
|
||||||
if (!rootNode.children) {
|
if (!rootNode.children) {
|
||||||
addIntermediateNode(rootNode);
|
addIntermediateNode(rootNode);
|
||||||
@ -290,7 +325,7 @@ function moveNode<T>(layoutTreeState: LayoutTreeState<T>, action: LayoutTreeMove
|
|||||||
|
|
||||||
// Remove nodeToInsert from its old parent
|
// Remove nodeToInsert from its old parent
|
||||||
if (oldParent) {
|
if (oldParent) {
|
||||||
removeChild(oldParent, node);
|
removeChild(oldParent, node, startingIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { node: newRootNode, leafs } = balanceNode(layoutTreeState.rootNode);
|
const { node: newRootNode, leafs } = balanceNode(layoutTreeState.rootNode);
|
||||||
@ -317,6 +352,34 @@ function insertNode<T>(layoutTreeState: LayoutTreeState<T>, action: LayoutTreeIn
|
|||||||
layoutTreeState.leafs = leafs;
|
layoutTreeState.leafs = leafs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function swapNode<T>(layoutTreeState: LayoutTreeState<T>, action: LayoutTreeSwapNodeAction<T>) {
|
||||||
|
console.log("swapNode", layoutTreeState, action);
|
||||||
|
if (!action.node1 || !action.node2) {
|
||||||
|
console.error("invalid swapNode action, both node1 and node2 must be defined");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (action.node1.id === layoutTreeState.rootNode.id || action.node2.id === layoutTreeState.rootNode.id) {
|
||||||
|
console.error("invalid swapNode action, the root node cannot be swapped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (action.node1.id === action.node2.id) {
|
||||||
|
console.error("invalid swapNode action, node1 and node2 are equal");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentNode1 = findParent(layoutTreeState.rootNode, action.node1.id);
|
||||||
|
const parentNode2 = findParent(layoutTreeState.rootNode, action.node2.id);
|
||||||
|
const parentNode1Index = parentNode1.children!.findIndex((child) => child.id === action.node1.id);
|
||||||
|
const parentNode2Index = parentNode2.children!.findIndex((child) => child.id === action.node2.id);
|
||||||
|
|
||||||
|
parentNode1.children[parentNode1Index] = action.node2;
|
||||||
|
parentNode2.children[parentNode2Index] = action.node1;
|
||||||
|
|
||||||
|
const { node: newRootNode, leafs } = balanceNode(layoutTreeState.rootNode);
|
||||||
|
layoutTreeState.rootNode = newRootNode;
|
||||||
|
layoutTreeState.leafs = leafs;
|
||||||
|
}
|
||||||
|
|
||||||
function deleteNode<T>(layoutTreeState: LayoutTreeState<T>, action: LayoutTreeDeleteNodeAction) {
|
function deleteNode<T>(layoutTreeState: LayoutTreeState<T>, action: LayoutTreeDeleteNodeAction) {
|
||||||
console.log("deleteNode", layoutTreeState, action);
|
console.log("deleteNode", layoutTreeState, action);
|
||||||
if (!action?.nodeId) {
|
if (!action?.nodeId) {
|
||||||
|
@ -35,6 +35,7 @@ export type MoveOperation<T> = {
|
|||||||
export enum LayoutTreeActionType {
|
export enum LayoutTreeActionType {
|
||||||
ComputeMove = "computeMove",
|
ComputeMove = "computeMove",
|
||||||
Move = "move",
|
Move = "move",
|
||||||
|
Swap = "swap",
|
||||||
CommitPendingAction = "commit",
|
CommitPendingAction = "commit",
|
||||||
ResizeNode = "resize",
|
ResizeNode = "resize",
|
||||||
InsertNode = "insert",
|
InsertNode = "insert",
|
||||||
@ -72,6 +73,13 @@ export interface LayoutTreeMoveNodeAction<T> extends LayoutTreeAction, MoveOpera
|
|||||||
type: LayoutTreeActionType.Move;
|
type: LayoutTreeActionType.Move;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LayoutTreeSwapNodeAction<T> extends LayoutTreeAction {
|
||||||
|
type: LayoutTreeActionType.Swap;
|
||||||
|
|
||||||
|
node1: LayoutNode<T>;
|
||||||
|
node2: LayoutNode<T>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for committing a pending action to the layout tree.
|
* Action for committing a pending action to the layout tree.
|
||||||
*/
|
*/
|
||||||
|
@ -43,14 +43,13 @@ export function determineDropDirection(dimensions?: Dimensions, offset?: XYCoord
|
|||||||
// Lies outside of the box
|
// Lies outside of the box
|
||||||
if (y < 0 || y > height || x < 0 || x > width) return undefined;
|
if (y < 0 || y > height || x < 0 || x > width) return undefined;
|
||||||
|
|
||||||
// TODO: uncomment once center drop is supported
|
// Determines if a drop point falls within the center fifth of the box, meaning we should return Center.
|
||||||
// // Determines if a drop point falls within the center fifth of the box, meaning we should return Center.
|
const centerX1 = (2 * width) / 5;
|
||||||
// const centerX1 = (2 * width) / 5;
|
const centerX2 = (3 * width) / 5;
|
||||||
// const centerX2 = (3 * width) / 5;
|
const centerY1 = (2 * height) / 5;
|
||||||
// const centerY1 = (2 * height) / 5;
|
const centerY2 = (3 * height) / 5;
|
||||||
// const centerY2 = (3 * width) / 5;
|
|
||||||
|
|
||||||
// if (x > centerX1 && x < centerX2 && y > centerY1 && y < centerY2) return DropDirection.Center;
|
if (x > centerX1 && x < centerX2 && y > centerY1 && y < centerY2) return DropDirection.Center;
|
||||||
|
|
||||||
const diagonal1 = y * width - x * height;
|
const diagonal1 = y * width - x * height;
|
||||||
const diagonal2 = y * width + x * height - height * width;
|
const diagonal2 = y * width + x * height - height * width;
|
||||||
|
@ -82,14 +82,21 @@ test("determineDropDirection", () => {
|
|||||||
DropDirection.OuterLeft
|
DropDirection.OuterLeft
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: uncomment once center direction is supported
|
assert.equal(
|
||||||
// assert.equal(
|
determineDropDirection(dimensions, {
|
||||||
// determineDropDirection(dimensions, {
|
x: 2.5,
|
||||||
// x: 2.5,
|
y: 2.5,
|
||||||
// y: 2.5,
|
}),
|
||||||
// }),
|
DropDirection.Center
|
||||||
// DropDirection.Center
|
);
|
||||||
// );
|
|
||||||
|
assert.equal(
|
||||||
|
determineDropDirection(dimensions, {
|
||||||
|
x: 2.51,
|
||||||
|
y: 2.51,
|
||||||
|
}),
|
||||||
|
DropDirection.Center
|
||||||
|
);
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
determineDropDirection(dimensions, {
|
determineDropDirection(dimensions, {
|
||||||
|
Loading…
Reference in New Issue
Block a user