diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/GMFHelper.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/GMFHelper.java
index dd34ec9baf..69c31540a0 100644
--- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/GMFHelper.java
+++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/GMFHelper.java
@@ -155,17 +155,40 @@ public static Point getAbsoluteLocation(Node node) {
* @return the absolute location of the node relative to the origin (Diagram)
*/
public static Point getAbsoluteLocation(Node node, boolean insetsAware) {
- Node currentNode = node;
- Point absoluteNodeLocation = getLocation(currentNode);
- if (currentNode.eContainer() instanceof Node) {
- currentNode = (Node) currentNode.eContainer();
- Point parentNodeLocation = getAbsoluteLocation(currentNode, insetsAware);
- absoluteNodeLocation.translate(parentNodeLocation);
+ // TODO: Location of title "DNode*NameEditPart", x coordinate, can be wrong according to label alignment. This
+ // problem is not yet handled.
+
+ Point location = new Point(0, 0);
+ LayoutConstraint layoutConstraint = node.getLayoutConstraint();
+ if (layoutConstraint instanceof Bounds) {
+ Bounds gmfBounds = (Bounds) layoutConstraint;
+ location.setX(gmfBounds.getX());
+ location.setY(gmfBounds.getY());
+ // manage location of bordered node with closest side
+ if (node.getElement() instanceof DNode && node.getElement().eContainer() instanceof AbstractDNode) {
+ DNode dNode = (DNode) node.getElement();
+ AbstractDNode parentAbstractDNode = (AbstractDNode) dNode.eContainer();
+ if (parentAbstractDNode.getOwnedBorderedNodes().contains(dNode)) {
+ Node parentNode = (Node) node.eContainer();
+ LayoutConstraint parentLayoutConstraint = parentNode.getLayoutConstraint();
+ if (parentLayoutConstraint instanceof Bounds) {
+ Bounds parentBounds = (Bounds) parentLayoutConstraint;
+ int position = CanonicalDBorderItemLocator.findClosestSideOfParent(new Rectangle(gmfBounds.getX(), gmfBounds.getY(), gmfBounds.getWidth(), gmfBounds.getHeight()),
+ new Rectangle(parentBounds.getX(), parentBounds.getY(), parentBounds.getWidth(), parentBounds.getHeight()));
+ updateLocation(location, position, parentBounds, gmfBounds);
+ }
+ }
+ }
+ }
+
+ if (node.eContainer() instanceof Node container) {
+ Point parentNodeLocation = getAbsoluteLocation(container, insetsAware);
+ location.translate(parentNodeLocation);
if (insetsAware) {
- translateWithInsets(absoluteNodeLocation, node);
+ translateWithInsets(location, node);
}
}
- return absoluteNodeLocation;
+ return location;
}
/**
@@ -201,7 +224,8 @@ public static Dimension getTopLeftInsets(Node container) {
}
/**
- * Return the top-left insets of the container of this node
. The insets also considers its border.
+ * Return the top-left insets of the container of this node
. The insets also considers its border (the
+ * size of the border).
*
* @param node
* The current node
@@ -371,31 +395,11 @@ private static void translateWithInsets(Rectangle boundsToTranslate, Node curren
* @param node
* the node whose location to compute.
* @return the location of the node.
+ * @deprecated Use getAbsoluteLocation instead. This method will be removed in future.
*/
+ @Deprecated
public static Point getLocation(Node node) {
- Point location = new Point(0, 0);
- LayoutConstraint layoutConstraint = node.getLayoutConstraint();
- if (layoutConstraint instanceof Bounds) {
- Bounds gmfBounds = (Bounds) layoutConstraint;
- location.setX(gmfBounds.getX());
- location.setY(gmfBounds.getY());
- // manage location of bordered node with closest side
- if (node.getElement() instanceof DNode && node.getElement().eContainer() instanceof AbstractDNode) {
- DNode dNode = (DNode) node.getElement();
- AbstractDNode parentAbstractDNode = (AbstractDNode) dNode.eContainer();
- if (parentAbstractDNode.getOwnedBorderedNodes().contains(dNode)) {
- Node parentNode = (Node) node.eContainer();
- LayoutConstraint parentLayoutConstraint = parentNode.getLayoutConstraint();
- if (parentLayoutConstraint instanceof Bounds) {
- Bounds parentBounds = (Bounds) parentLayoutConstraint;
- int position = CanonicalDBorderItemLocator.findClosestSideOfParent(new Rectangle(gmfBounds.getX(), gmfBounds.getY(), gmfBounds.getWidth(), gmfBounds.getHeight()),
- new Rectangle(parentBounds.getX(), parentBounds.getY(), parentBounds.getWidth(), parentBounds.getHeight()));
- updateLocation(location, position, parentBounds, gmfBounds);
- }
- }
- }
- }
- return location;
+ return getAbsoluteLocation(node, true);
}
private static void updateLocation(Point location, int position, Bounds parentBounds, Bounds gmfBounds) {
@@ -426,7 +430,7 @@ private static void updateLocation(Point location, int position, Bounds parentBo
* @return the absolute bounds of the node relative to the origin (Diagram)
*/
public static Rectangle getAbsoluteBounds(Node node) {
- return getAbsoluteBounds(node, false, false);
+ return getAbsoluteBounds(node, false);
}
/**
@@ -441,7 +445,7 @@ public static Rectangle getAbsoluteBounds(Node node) {
* @return the absolute bounds of the node relative to the origin (Diagram)
*/
public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware) {
- return getAbsoluteBounds(node, insetsAware, false);
+ return getAbsoluteBounds(node, insetsAware, false, false);
}
/**
@@ -458,17 +462,28 @@ public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware) {
* @return the absolute bounds of the node relative to the origin (Diagram)
*/
public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware, boolean boxForConnection) {
- Node currentNode = node;
- Rectangle absoluteNodeBounds = getBounds(currentNode, false, false, boxForConnection, false);
- if (currentNode.eContainer() instanceof Node) {
- currentNode = (Node) currentNode.eContainer();
- Point parentNodeLocation = getAbsoluteLocation(currentNode, insetsAware);
- absoluteNodeBounds = absoluteNodeBounds.getTranslated(parentNodeLocation);
- if (insetsAware) {
- translateWithInsets(absoluteNodeBounds, node);
- }
- }
- return absoluteNodeBounds;
+ return getAbsoluteBounds(node, insetsAware, boxForConnection, false);
+ }
+
+ /**
+ * Get the absolute bounds relative to the origin (Diagram).
+ *
+ * @param node
+ * the GMF Node
+ * @param insetsAware
+ * true to consider the draw2D figures insets. Warning: Those insets are based on the
+ * current Sirius editParts and could become wrong if a developer customizes them.
+ * @param boxForConnection
+ * true if we want to have the bounds used to compute connection anchor from source or target, false
+ * otherwise
+ * @param recursiveGetBounds
+ * true if this method is called from a parent "getBounds" call, false otherwise.
+ * @return the absolute bounds of the node relative to the origin (Diagram)
+ */
+ public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware, boolean boxForConnection, boolean recursiveGetBounds) {
+ Point location = getAbsoluteLocation(node, insetsAware);
+ Rectangle bounds = getBounds(node, false, false, boxForConnection, recursiveGetBounds, location);
+ return new PrecisionRectangle(location.preciseX(), location.preciseY(), bounds.preciseWidth(), bounds.preciseHeight());
}
/**
@@ -551,7 +566,7 @@ public static Option getAbsoluteBounds(View view, boolean insetsAware
public static Option getAbsoluteBounds(View view, boolean insetsAware, boolean boxForConnection) {
Option result = Options.newNone();
if (view instanceof Node) {
- result = Options.newSome(getAbsoluteBounds((Node) view, insetsAware, boxForConnection));
+ result = Options.newSome(getAbsoluteBounds((Node) view, insetsAware, boxForConnection, false));
} else if (view instanceof Edge) {
result = getAbsoluteBounds((Edge) view, insetsAware, boxForConnection);
}
@@ -595,7 +610,7 @@ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstra
* @return the bounds of the node.
*/
public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint, boolean forceFigureAutoSize) {
- return getBounds(node, useFigureForAutoSizeConstraint, forceFigureAutoSize, false, false);
+ return getBounds(node, useFigureForAutoSizeConstraint, forceFigureAutoSize, false, false, new Point());
}
/**
@@ -612,20 +627,19 @@ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstra
* true if we want to have the bounds used to compute connection anchor from source or target, false
* otherwise
* @param recursiveGetBounds
- * true if this method is called from a parent "getBounds" call, false otherwise.
+ * true if this method is called from a parent "getBounds" call, false otherwise
+ * @param computedAbsoluteLocation
+ * The absolute location of the node
*
* @return the bounds of the node.
*/
- public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint, boolean forceFigureAutoSize, boolean boxForConnection, boolean recursiveGetBounds) {
- PrecisionRectangle bounds = new PrecisionRectangle(0, 0, 0, 0);
+ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint, boolean forceFigureAutoSize, boolean boxForConnection, boolean recursiveGetBounds,
+ Point computedAbsoluteLocation) {
+ PrecisionRectangle bounds = new PrecisionRectangle(computedAbsoluteLocation.preciseX(), computedAbsoluteLocation.preciseY(), 0, 0);
LayoutConstraint layoutConstraint = node.getLayoutConstraint();
EObject element = node.getElement();
if (element instanceof AbstractDNode) {
AbstractDNode abstractDNode = (AbstractDNode) element;
- if (layoutConstraint instanceof Location) {
- bounds.setX(((Location) layoutConstraint).getX());
- bounds.setY(((Location) layoutConstraint).getY());
- }
if (layoutConstraint instanceof Size) {
bounds.setWidth(((Size) layoutConstraint).getWidth());
bounds.setHeight(((Size) layoutConstraint).getHeight());
@@ -658,8 +672,8 @@ public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstra
// This insets corresponds to insets of {@link
// org.eclipse.sirius.diagram.ui.tools.api.figure.AlphaDropShadowBorder#getTransparentInsets()}.
double shadowBorderSize = getShadowBorderSize(node);
- bounds.setWidth(bounds.width - shadowBorderSize);
- bounds.setHeight(bounds.height - shadowBorderSize);
+ bounds.setPreciseWidth(bounds.preciseWidth() - shadowBorderSize);
+ bounds.setPreciseHeight(bounds.preciseHeight() - shadowBorderSize);
}
}
return bounds;
@@ -688,7 +702,7 @@ public static double getShadowBorderSize(Node node) {
*
* @return false for regions and workspace images, true otherwise.
*/
- public static boolean isShadowBorderNeeded(Node node) {
+ private static boolean isShadowBorderNeeded(Node node) {
boolean needShadowBorder = false;
EObject element = node.getElement();
if (element instanceof DDiagramElementContainer) {
@@ -713,7 +727,7 @@ public static boolean isShadowBorderNeeded(Node node) {
* @param recursive
* true if this method is called from a "parent" call, false otherwise.
*/
- private static void replaceAutoSize(Node node, Rectangle bounds, boolean useFigureForAutoSizeConstraint, Dimension providedDefaultSize, boolean recursive) {
+ private static void replaceAutoSize(Node node, PrecisionRectangle bounds, boolean useFigureForAutoSizeConstraint, Dimension providedDefaultSize, boolean recursive) {
if (bounds.width == -1 || bounds.height == -1) {
Dimension defaultSize = providedDefaultSize;
if (providedDefaultSize == null) {
@@ -756,26 +770,29 @@ private static void replaceAutoSize(Node node, Rectangle bounds, boolean useFigu
// Compute the bounds of all children and use the lowest
// one (y+height) for height and the rightmost one
// (x+width) for width plus the margin.
- Point bottomRight = getBottomRight(node, recursive);
+ Rectangle childrenBounds = getChildrenBounds(node, recursive);
+ // Add the potential shadow border size and the bottom right insets of the node (i.e. container)
double shadowBorderSize = getShadowBorderSize(node);
- Dimension topLeftInsets = getTopLeftInsets(node);
Dimension bottomRightInsets = getBottomRightInsets(node);
- if (!recursive) {
- bottomRight.setX(bottomRight.x + Double.valueOf(shadowBorderSize).intValue() + topLeftInsets.width() + bottomRightInsets.width());
- bottomRight.setY(bottomRight.y + Double.valueOf(shadowBorderSize).intValue() + topLeftInsets.height() + bottomRightInsets.height());
- }
+ // Do not add bottom right insets and shadow if there is at least one border node on the corresponding
+ // side
+ int borderNodesSides = getBorderNodesSides(node, childrenBounds);
+ boolean isBorderNodeOnRightSide = recursive && (PositionConstants.RIGHT & borderNodesSides) == PositionConstants.RIGHT;
+ boolean isBorderNodeOnBottomSide = recursive && (PositionConstants.BOTTOM & borderNodesSides) == PositionConstants.BOTTOM;
+ childrenBounds.resize(isBorderNodeOnRightSide ? 0 : bottomRightInsets.width() + shadowBorderSize, isBorderNodeOnBottomSide ? 0 : bottomRightInsets.height() + shadowBorderSize);
+ // Replace -1 by the new computed values
if (bounds.width == -1) {
- if (bottomRight.x > defaultSize.width) {
- bounds.setWidth(bottomRight.x);
- } else {
- bounds.setWidth(defaultSize.width);
+ bounds.setPreciseWidth(defaultSize.preciseWidth());
+ double deltaWidth = childrenBounds.getRight().preciseX() - bounds.getRight().preciseX();
+ if (deltaWidth > 0) {
+ bounds.resize(deltaWidth, 0);
}
}
if (bounds.height == -1) {
- if (bottomRight.y > defaultSize.height) {
- bounds.setHeight(bottomRight.y);
- } else {
- bounds.setHeight(defaultSize.height);
+ bounds.setPreciseHeight(defaultSize.preciseHeight());
+ double deltaHeight = childrenBounds.getBottom().preciseY() - bounds.getBottom().preciseY();
+ if (deltaHeight > 0) {
+ bounds.resize(0, deltaHeight);
}
}
}
@@ -789,6 +806,29 @@ private static void replaceAutoSize(Node node, Rectangle bounds, boolean useFigu
}
}
+ private static int getBorderNodesSides(Node container, Rectangle containerChildrenBounds) {
+ int result = PositionConstants.NONE;
+ for (Iterator children = Iterators.filter(container.getChildren().iterator(), Node.class); children.hasNext(); /* */) {
+ Node child = children.next();
+ if (new NodeQuery(child).isBorderedNode()) {
+ Rectangle borderNodeBounds = getAbsoluteBounds(child, true);
+ if (borderNodeBounds.preciseX() == containerChildrenBounds.preciseX()) {
+ result = result | PositionConstants.LEFT;
+ }
+ if (borderNodeBounds.preciseY() == containerChildrenBounds.preciseY()) {
+ result = result | PositionConstants.TOP;
+ }
+ if (borderNodeBounds.preciseX() + borderNodeBounds.preciseWidth() == containerChildrenBounds.preciseX() + containerChildrenBounds.preciseWidth()) {
+ result = result | PositionConstants.RIGHT;
+ }
+ if (borderNodeBounds.preciseY() + borderNodeBounds.preciseHeight() == containerChildrenBounds.preciseY() + containerChildrenBounds.preciseHeight()) {
+ result = result | PositionConstants.BOTTOM;
+ }
+ }
+ }
+ return result;
+ }
+
private static void lookForNextRegionLocation(Rectangle bounds, Node node) {
EObject element = node.getElement();
if (element instanceof DDiagramElementContainer && node.eContainer() instanceof Node) {
@@ -831,32 +871,33 @@ private static void lookForNextRegionLocation(Rectangle bounds, Node node) {
* Returns a new Point representing the bottom right point of all bounds of children of this Node. Useful for Node
* with size of -1x-1 to be more accurate (but it is still not necessarily the same size that draw2d).
*
- * @param node
+ * @param container
* the node whose bottom right corner is to compute.
* @param considerBorderNode
* true to consider border nodes when computing the bottom right corner point, false otherwise.
*
* @return Point at the bottom right of the rectangle
*/
- private static Point getBottomRight(Node node, boolean considerBorderNodes) {
- int right = 0;
- int bottom = 0;
- for (Iterator children = Iterators.filter(node.getChildren().iterator(), Node.class); children.hasNext(); /* */) {
+ private static Rectangle getChildrenBounds(Node container, boolean considerBorderNodes) {
+ Rectangle result = null;
+ if (container.getChildren().isEmpty()) {
+ result = new PrecisionRectangle();
+ }
+ for (Iterator children = Iterators.filter(container.getChildren().iterator(), Node.class); children.hasNext(); /* */) {
Node child = children.next();
// The border nodes are ignored, except if it is expected to consider it (auto-size of a container with
// children having border nodes)
if (considerBorderNodes || !(new NodeQuery(child).isBorderedNode())) {
- Rectangle bounds = getBounds(child, false, false, false, true);
- Point bottomRight = bounds.getBottomRight();
- if (bottomRight.x > right) {
- right = bottomRight.x;
- }
- if (bottomRight.y > bottom) {
- bottom = bottomRight.y;
+ Rectangle childAbsoluteBounds = getAbsoluteBounds(child, true, false, true);
+ if (result == null) {
+ result = childAbsoluteBounds.getCopy();
+ } else {
+ // Make union of the child bounds and its parent bounds
+ result.union(childAbsoluteBounds);
}
}
}
- return new Point(right, bottom);
+ return result;
}
private static Dimension getDefaultSize(AbstractDNode abstractDNode) {