Skip to content

Commit

Permalink
[781] Fix incremental layout when there are border nodes
Browse files Browse the repository at this point in the history
Bug: #781
Signed-off-by: Laurent Fasani <[email protected]>
  • Loading branch information
lfasani committed Mar 8, 2022
1 parent 647aafb commit ad373c4
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,20 +152,21 @@ private void layoutNode(Optional<IDiagramEvent> optionalDiagramElementEvent, Nod

// update the border node once the current node bounds are updated
Bounds newBounds = Bounds.newBounds().position(node.getPosition()).size(node.getSize()).build();
this.layoutBorderNodes(optionalDiagramElementEvent, node.getBorderNodes(), initialNodeBounds, newBounds, layoutConfigurator);
List<BorderNodesOnSide> borderNodesOnSide = this.layoutBorderNodes(optionalDiagramElementEvent, node.getBorderNodes(), initialNodeBounds, newBounds, layoutConfigurator);

// recompute the label
if (node.getLabel() != null) {
node.getLabel().setPosition(this.nodeLabelPositionProvider.getPosition(node, node.getLabel()));
node.getLabel().setPosition(this.nodeLabelPositionProvider.getPosition(node, node.getLabel(), borderNodesOnSide));
}
}

/**
* Update the border nodes position according to the side length change where it is located.<br>
* The aim is to keep the positioning ratio of the border node on its side.
*/
private void layoutBorderNodes(Optional<IDiagramEvent> optionalDiagramElementEvent, List<NodeLayoutData> borderNodesLayoutData, Bounds initialNodeBounds, Bounds newNodeBounds,
private List<BorderNodesOnSide> layoutBorderNodes(Optional<IDiagramEvent> optionalDiagramElementEvent, List<NodeLayoutData> borderNodesLayoutData, Bounds initialNodeBounds, Bounds newNodeBounds,
ISiriusWebLayoutConfigurator layoutConfigurator) {
List<BorderNodesOnSide> borderNodesPerSide = new ArrayList<>();
if (!borderNodesLayoutData.isEmpty()) {
for (NodeLayoutData nodeLayoutData : borderNodesLayoutData) {
// 1- update the position of the border node if it has been explicitly moved
Expand All @@ -179,14 +180,15 @@ private void layoutBorderNodes(Optional<IDiagramEvent> optionalDiagramElementEve
}

// 2- recompute the border node
List<BorderNodesOnSide> borderNodesPerSide = this.snapBorderNodes(borderNodesLayoutData, initialNodeBounds.getSize(), layoutConfigurator);
borderNodesPerSide = this.snapBorderNodes(borderNodesLayoutData, initialNodeBounds.getSize(), layoutConfigurator);

// 3 - move the border node along the side according to the side change
this.updateBorderNodeAccordingParentResize(optionalDiagramElementEvent, initialNodeBounds, newNodeBounds, borderNodesPerSide, borderNodesLayoutData.get(0).getParent().getId());

// 4- set the label position if the border is newly created
this.updateBorderNodeLabel(optionalDiagramElementEvent, borderNodesPerSide);
}
return borderNodesPerSide;
}

private void updateBorderNodeLabel(Optional<IDiagramEvent> optionalDiagramElementEvent, List<BorderNodesOnSide> borderNodesPerSideList) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.eclipse.sirius.components.diagrams.layout.incremental.provider;

import java.util.EnumSet;
import java.util.List;
import java.util.Objects;

import org.eclipse.elk.core.math.ElkPadding;
Expand All @@ -21,8 +22,10 @@
import org.eclipse.sirius.components.diagrams.NodeType;
import org.eclipse.sirius.components.diagrams.Position;
import org.eclipse.sirius.components.diagrams.layout.ISiriusWebLayoutConfigurator;
import org.eclipse.sirius.components.diagrams.layout.incremental.BorderNodesOnSide;
import org.eclipse.sirius.components.diagrams.layout.incremental.data.LabelLayoutData;
import org.eclipse.sirius.components.diagrams.layout.incremental.data.NodeLayoutData;
import org.eclipse.sirius.components.diagrams.layout.incremental.utils.RectangleSide;

/**
* Provides the position to apply to a Node Label.
Expand All @@ -37,7 +40,7 @@ public NodeLabelPositionProvider(ISiriusWebLayoutConfigurator layoutConfigurator
this.layoutConfigurator = Objects.requireNonNull(layoutConfigurator);
}

public Position getPosition(NodeLayoutData node, LabelLayoutData label) {
public Position getPosition(NodeLayoutData node, LabelLayoutData label, List<BorderNodesOnSide> borderNodesOnSide) {
double x = 0d;
double y = 0d;

Expand All @@ -49,15 +52,15 @@ public Position getPosition(NodeLayoutData node, LabelLayoutData label) {
}
break;
default:
x = this.getHorizontalPosition(node, label);
x = this.getHorizontalPosition(node, label, borderNodesOnSide);
y = this.getVerticalPosition(node, label);
break;
}

return Position.at(x, y);
}

private double getHorizontalPosition(NodeLayoutData node, LabelLayoutData label) {
private double getHorizontalPosition(NodeLayoutData node, LabelLayoutData label, List<BorderNodesOnSide> borderNodesOnSides) {
double x = 0d;
EnumSet<NodeLabelPlacement> nodeLabelPlacementSet = this.layoutConfigurator.configureByType(node.getNodeType()).getProperty(CoreOptions.NODE_LABELS_PLACEMENT);
ElkPadding nodeLabelsPadding = this.layoutConfigurator.configureByType(node.getNodeType()).getProperty(CoreOptions.NODE_LABELS_PADDING);
Expand All @@ -81,7 +84,19 @@ private double getHorizontalPosition(NodeLayoutData node, LabelLayoutData label)
case H_CENTER:
// The label is positioned at the center of the node and the front-end will apply a "'text-anchor':
// 'middle'" property.
x = node.getSize().getWidth() / 2;
int shiftToEast = 0;
int shiftToWest = 0;
for (BorderNodesOnSide borderNodesOnSide : borderNodesOnSides) {
if (RectangleSide.WEST.equals(borderNodesOnSide.getSide())) {
shiftToEast = 1;
} else if (RectangleSide.EAST.equals(borderNodesOnSide.getSide())) {
shiftToWest = 1;
}
}
double portOffset = this.layoutConfigurator.configureByType(node.getNodeType()).getProperty(CoreOptions.PORT_BORDER_OFFSET).doubleValue();
double offSetAccordingToBorderNodes = -portOffset / 2 * (shiftToEast - shiftToWest);

x = node.getSize().getWidth() / 2 + offSetAccordingToBorderNodes;
break;
case H_RIGHT:
if (outside) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021 THALES GLOBAL SERVICES.
* Copyright (c) 2021, 2022 THALES GLOBAL SERVICES.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -14,6 +14,7 @@

import static org.assertj.core.api.Assertions.assertThat;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

Expand Down Expand Up @@ -61,7 +62,7 @@ public void testNodeImageLabelBoundsPosition() {
NodeLabelPositionProvider labelBoundsProvider = new NodeLabelPositionProvider(new LayoutConfiguratorRegistry(List.of()).getDefaultLayoutConfigurator());
LabelLayoutData labelLayoutData = this.createLabelLayoutData();

Position position = labelBoundsProvider.getPosition(nodeLayoutData, labelLayoutData);
Position position = labelBoundsProvider.getPosition(nodeLayoutData, labelLayoutData, new ArrayList<>());
assertThat(position).extracting(Position::getX).isEqualTo(Double.valueOf(DEFAULT_NODE_SIZE.getWidth() / 2));
assertThat(position).extracting(Position::getY).isEqualTo(Double.valueOf(-23.3984375));
}
Expand All @@ -72,7 +73,7 @@ public void testNodeRectangleLabelBoundsPosition() {
NodeLayoutData nodeLayoutData = this.createNodeLayoutData(Position.at(0, 0), DEFAULT_NODE_SIZE, createDiagramLayoutData, NodeType.NODE_RECTANGLE);
NodeLabelPositionProvider labelBoundsProvider = new NodeLabelPositionProvider(new LayoutConfiguratorRegistry(List.of()).getDefaultLayoutConfigurator());
LabelLayoutData labelLayoutData = this.createLabelLayoutData();
Position position = labelBoundsProvider.getPosition(nodeLayoutData, labelLayoutData);
Position position = labelBoundsProvider.getPosition(nodeLayoutData, labelLayoutData, new ArrayList<>());
assertThat(position).extracting(Position::getX).isEqualTo(Double.valueOf(DEFAULT_NODE_SIZE.getWidth() / 2));
assertThat(position).extracting(Position::getY).isEqualTo(Double.valueOf(5));
}
Expand Down

0 comments on commit ad373c4

Please sign in to comment.