Skip to content

Commit

Permalink
[2689] Fix the borderNode moves that is no longer anchored to its parent
Browse files Browse the repository at this point in the history
Bug: #2689
Signed-off-by: Florian ROUËNÉ <florian.rouene@obeosoft.com>
  • Loading branch information
frouene committed Dec 4, 2023
1 parent 3909203 commit a178446
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ The only way to export diagram as SVG image is to use the ReactFlow toolbar loca
- https://github.com/eclipse-sirius/sirius-web/issues/2698[#2698] [diagram] Fix an issue that prevents _imageNode_ to be resizable.
- https://github.com/eclipse-sirius/sirius-web/issues/2684[#2684] [diagram] Fix an issue where the edges' arrows where not exported during the SVG export.
- https://github.com/eclipse-sirius/sirius-web/issues/2726[#2726] [diagram] Fix an issue that prevents last tool used in a tool section to be added to another palette.
- https://github.com/eclipse-sirius/sirius-web/issues/2689[#2689] [diagram] Fix the borderNode moves that is no longer anchored to its parent.

=== New Features

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { IconLabelNodeConverterHandler } from './IconLabelNodeConverterHandler';
import { ImageNodeConverterHandler } from './ImageNodeConverterHandler';
import { ListNodeConverterHandler } from './ListNodeConverterHandler';
import { RectangleNodeConverterHandler } from './RectangleNodeConverterHandler';
import { computeBorderNodeExtents, computeBorderNodePositions } from '../renderer/layout/layoutBorderNodes';

const nodeDepth = (nodeId2node: Map<string, Node>, nodeId: string): number => {
const node = nodeId2node.get(nodeId);
Expand Down Expand Up @@ -218,6 +219,8 @@ export const convertDiagram = (
edges,
};
layoutHandles(rawDiagram);
computeBorderNodeExtents(rawDiagram.nodes);
computeBorderNodePositions(rawDiagram.nodes);

return {
metadata: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
*******************************************************************************/
import { useCallback } from 'react';
import { Node, NodeChange, useReactFlow, XYPosition } from 'reactflow';
import { BorderNodePositon, EdgeData, NodeData } from '../DiagramRenderer.types';
import { EdgeData, NodeData } from '../DiagramRenderer.types';
import { borderNodeOffset } from '../layout/layoutParams';
import { UseBorderChangeValue } from './useBorderChange.types';
import { findBorderNodePosition } from '../layout/layoutBorderNodes';

const isNewPositionInsideIsParent = (newNodePosition: XYPosition, movedNode: Node, parentNode: Node): boolean => {
if (movedNode.width && movedNode.height && parentNode?.positionAbsolute && parentNode.width && parentNode.height) {
Expand All @@ -28,40 +29,6 @@ const isNewPositionInsideIsParent = (newNodePosition: XYPosition, movedNode: Nod
return false;
};

const computeNewBorderPosition = (
newNodePosition: XYPosition,
movedNode: Node,
parentNode: Node | undefined
): BorderNodePositon | null => {
if (movedNode.width && movedNode.height && parentNode?.positionAbsolute && parentNode.width && parentNode.height) {
if (
Math.trunc(newNodePosition.x + movedNode.width) - borderNodeOffset ===
Math.trunc(parentNode.positionAbsolute.x)
) {
return BorderNodePositon.WEST;
}
if (
Math.trunc(newNodePosition.x) + borderNodeOffset ===
Math.trunc(parentNode.positionAbsolute.x + parentNode.width)
) {
return BorderNodePositon.EAST;
}
if (
Math.trunc(newNodePosition.y + movedNode.height) - borderNodeOffset ===
Math.trunc(parentNode.positionAbsolute.y)
) {
return BorderNodePositon.NORTH;
}
if (
Math.trunc(newNodePosition.y) + borderNodeOffset ===
Math.trunc(parentNode.positionAbsolute.y + parentNode.height)
) {
return BorderNodePositon.SOUTH;
}
}
return null;
};

export const useBorderChange = (): UseBorderChangeValue => {
const { getNodes } = useReactFlow<NodeData, EdgeData>();

Expand All @@ -76,11 +43,7 @@ export const useBorderChange = (): UseBorderChangeValue => {
change.position = movedNode.position;
change.positionAbsolute = movedNode.positionAbsolute;
} else {
movedNode.data.borderNodePosition = computeNewBorderPosition(
change.positionAbsolute,
movedNode,
parentNode
);
movedNode.data.borderNodePosition = findBorderNodePosition(change.position, movedNode, parentNode);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { CoordinateExtent, Node } from 'reactflow';
import { CoordinateExtent, Node, XYPosition } from 'reactflow';
import { BorderNodePositon, NodeData } from '../DiagramRenderer.types';
import { borderNodeOffset } from './layoutParams';
import { DiagramNodeType } from '../node/NodeTypes.types';

export const isEastBorderNode = (borderNode: Node<NodeData>): boolean => {
return borderNode.data.isBorderNode && borderNode.data.borderNodePosition === BorderNodePositon.EAST;
Expand All @@ -28,15 +29,60 @@ export const isSouthBorderNode = (borderNode: Node<NodeData>): boolean => {
};

export const getBorderNodeExtent = (
nodeParent: Node<NodeData>,
borderNorde: Node<NodeData>
parentNode: Node<NodeData>,
borderNode: Node<NodeData>
): CoordinateExtent | 'parent' => {
let coordinateExtent: CoordinateExtent | 'parent' = 'parent';
if (nodeParent.width && nodeParent.height && borderNorde.height && borderNorde.width) {
if (parentNode.width && parentNode.height && borderNode.height && borderNode.width) {
coordinateExtent = [
[0 - borderNorde.width + borderNodeOffset, 0 - borderNorde.height + borderNodeOffset],
[nodeParent.width - borderNodeOffset, nodeParent.height - borderNodeOffset],
[0 - borderNode.width + borderNodeOffset, 0 - borderNode.height + borderNodeOffset],
[parentNode.width - borderNodeOffset, parentNode.height - borderNodeOffset],
];
}
return coordinateExtent;
};

export const computeBorderNodeExtents = (nodes: Node<NodeData, DiagramNodeType>[]): void => {
nodes
.filter((node) => node.data.isBorderNode)
.forEach((borderNode) => {
const parentNode = nodes.find((node) => node.id === borderNode.parentNode);
if (parentNode) {
borderNode.extent = getBorderNodeExtent(parentNode, borderNode);
}
});
};

export const computeBorderNodePositions = (nodes: Node<NodeData, DiagramNodeType>[]): void => {
nodes
.filter((node) => node.data.isBorderNode)
.forEach((borderNode) => {
const parentNode = nodes.find((node) => node.id === borderNode.parentNode);
if (parentNode) {
const newPosition = findBorderNodePosition(borderNode.position, borderNode, parentNode);
borderNode.data.borderNodePosition = newPosition ?? BorderNodePositon.EAST;
}
});
};

export const findBorderNodePosition = (
borderNodePosition: XYPosition | undefined,
borderNode: Node,
parentNode: Node | undefined
): BorderNodePositon | null => {
if (borderNodePosition && borderNode.width && borderNode.height && parentNode?.width && parentNode.height) {
if (Math.trunc(borderNodePosition.x + borderNode.width) - borderNodeOffset === 0) {
return BorderNodePositon.WEST;
}
if (Math.trunc(borderNodePosition.x) + borderNodeOffset === Math.trunc(parentNode.width)) {
return BorderNodePositon.EAST;
}
if (Math.trunc(borderNodePosition.y + borderNode.height) - borderNodeOffset === 0) {
return BorderNodePositon.NORTH;
}
if (Math.trunc(borderNodePosition.y) + borderNodeOffset === Math.trunc(parentNode.height)) {
return BorderNodePositon.SOUTH;
}
}
return null;
};

0 comments on commit a178446

Please sign in to comment.