From f83cf18bf1a023934526bcfb99172cc3948c8e81 Mon Sep 17 00:00:00 2001 From: Laurent Redor Date: Thu, 25 Jul 2024 13:52:49 +0200 Subject: [PATCH] [426] Handle horizontal stack container Before this commit, this kind of container was not correctly handled. Bug: https://github.com/eclipse-sirius/sirius-desktop/issues/426 --- .../ui/business/api/query/ViewQuery.java | 46 +++- .../ui/internal/refresh/GMFHelper.java | 234 +++++++++--------- 2 files changed, 162 insertions(+), 118 deletions(-) diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/ViewQuery.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/ViewQuery.java index 3c9d3ec99b..4bb609ab7a 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/ViewQuery.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/business/api/query/ViewQuery.java @@ -420,7 +420,7 @@ public boolean isRegion() { } /** - * Return if this GMF node is contained in an vertical stack layout container. + * Return if this GMF node is contained in a vertical stack layout container. */ public boolean isVerticalRegion() { return view.eContainer() instanceof View container && new ViewQuery(container).isVerticalRegionContainerCompartment(); @@ -445,7 +445,7 @@ public boolean isVerticalRegionContainer() { } /** - * Return if this GMF node is a compartment of a container having horizontal stack layout. + * Return if this GMF node is a compartment of a container having vertical stack layout. */ public boolean isVerticalRegionContainerCompartment() { if (isFreeFormCompartment()) { @@ -458,6 +458,48 @@ public boolean isVerticalRegionContainerCompartment() { } + /** + * Return if this GMF node is contained in an horizontal stack layout container. + */ + public boolean isHorizontalRegion() { + return view.eContainer() instanceof View container && new ViewQuery(container).isHorizontalRegionContainerCompartment(); + } + + /** + * Return if this GMF node have horizontal stack layout. + */ + public boolean isHorizontalRegionContainer() { + return this.view.getElement() instanceof DDiagramElement element // + && element.getDiagramElementMapping() instanceof ContainerMapping mapping // + && new ContainerMappingQuery(mapping).isHorizontalStackContainer(); + } + + /** + * Return if this GMF node is a compartment of a container having horizontal stack layout. + */ + public boolean isHorizontalRegionContainerCompartment() { + if (isFreeFormCompartment()) { + if (view.eContainer() instanceof Node container) { + return new ViewQuery(container).isHorizontalRegionContainer(); + } + + } + return false; + } + + /** + * Return if this GMF node is a compartment of a container having an horizontal or a vertical stack layout. + */ + public boolean isRegionContainerCompartment() { + if (isFreeFormCompartment()) { + if (view.eContainer() instanceof Node container) { + return new ViewQuery(container).isRegionContainer(); + } + + } + return false; + } + /** * Return if this GMF node is associated to DNode Sirius diagram element. */ 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 fcf9a7a7ef..0cd8afa2a7 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 @@ -77,6 +77,7 @@ import org.eclipse.sirius.diagram.ui.business.internal.query.DNodeContainerQuery; import org.eclipse.sirius.diagram.ui.business.internal.query.DNodeQuery; import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramElementContainerEditPart; +import org.eclipse.sirius.diagram.ui.edit.api.part.IDiagramNameEditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeContainerCompartmentEditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeContainer2EditPart; import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeList2EditPart; @@ -157,19 +158,102 @@ 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, insetsAware); // TODO: Location of title "DNode*NameEditPart", x coordinate, can be wrong according to label alignment. This // problem is not yet handled. - // if (currentNode.eContainer() instanceof Node) { - // currentNode = (Node) currentNode.eContainer(); - // Point parentNodeLocation = getAbsoluteLocation(currentNode, insetsAware); - // absoluteNodeLocation.translate(parentNodeLocation); - // if (insetsAware) { - // translateWithInsets(absoluteNodeLocation, node); - // } - // } - return absoluteNodeLocation; + + Point location = new Point(0, 0); + LayoutConstraint layoutConstraint = node.getLayoutConstraint(); + if (layoutConstraint instanceof Bounds && !(new ViewQuery(node).isRegion())) { + // The bounds is computed for horizontal or vertical regions, even if it is stored in GMF data + 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 (new ViewQuery(node).isListCompartment()) { + // Translate the compartment to be just below the the title, the x coordinate is also the same (same parent + // insets) + Rectangle titleBounds = getAbsoluteBounds(getPreviousChild(node), true); + location.translate(titleBounds.preciseX(), titleBounds.preciseY() + titleBounds.preciseHeight()); + // Translate from the spacing (5 pixels) + location.translate(0, IContainerLabelOffsets.LABEL_OFFSET); + } else if (new ViewQuery(node).isRegionContainerCompartment()) { + // Translate the compartment to be just below the the title, the x coordinate is also the same (same parent + // insets) + Rectangle titleBounds = getAbsoluteBounds(getPreviousChild(node), true); + location.translate(titleBounds.preciseX(), titleBounds.preciseY() + titleBounds.preciseHeight()); + // Translate from the spacing (5 pixels) + location.translate(0, IContainerLabelOffsets.LABEL_OFFSET); + } else if (new ViewQuery(node).isListItem()) { + if (node.eContainer() instanceof Node container) { + if (container.getChildren().get(0) == node) { + Point parentNodeLocation = getAbsoluteLocation(container, insetsAware); + location.translate(parentNodeLocation); + if (insetsAware) { + translateWithInsets(location, node); + } + + // This is the first list item, add a one margin border over it. + // location.translate(0, 1); TODO: Here or in parent insets ? + } else { + // Translate from the previous children + Rectangle previousChildBounds = getAbsoluteBounds(getPreviousChild(node), true); + location.translate(previousChildBounds.preciseX(), previousChildBounds.preciseY() + previousChildBounds.preciseHeight()); + } + } + } else if (new ViewQuery(node).isVerticalRegion()) { + if (node.eContainer() instanceof Node container) { + if (container.getChildren().get(0) == node) { + Point parentNodeLocation = getAbsoluteLocation(container, insetsAware); + location.translate(parentNodeLocation); + if (insetsAware) { + translateWithInsets(location, node); + } + } else { + // Translate from the previous children + Rectangle previousChildBounds = getAbsoluteBounds(getPreviousChild(node), true); + location.translate(previousChildBounds.preciseX(), previousChildBounds.preciseY() + previousChildBounds.preciseHeight()); + } + } + } else if (new ViewQuery(node).isHorizontalRegion()) { + if (node.eContainer() instanceof Node container) { + if (container.getChildren().get(0) == node) { + Point parentNodeLocation = getAbsoluteLocation(container, insetsAware); + location.translate(parentNodeLocation); + if (insetsAware) { + translateWithInsets(location, node); + } + } else { + // Translate from the previous children + Rectangle previousChildBounds = getAbsoluteBounds(getPreviousChild(node), true); + location.translate(previousChildBounds.preciseX() + previousChildBounds.preciseWidth(), previousChildBounds.preciseY()); + } + } + } else { + if (node.eContainer() instanceof Node container) { + Point parentNodeLocation = getAbsoluteLocation(container, insetsAware); + location.translate(parentNodeLocation); + if (insetsAware) { + translateWithInsets(location, node); + } + } + + } + return location; } /** @@ -217,10 +301,11 @@ public static Dimension getTopLeftInsets(Node container) { // org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeListCompartmentEditPart.createFigure() result.setWidth(4); result.setHeight(1); - } else if (nodeQuery.isVerticalRegionContainerCompartment()) { - // Add the corresponding margin of {1, 0, 0, 0} of + } else if (nodeQuery.isRegionContainerCompartment()) { + // Add the corresponding OneLineMarginBorder of {1, 0, 0, 0} corresponding to // org.eclipse.sirius.diagram.ui.edit.internal.part.DiagramContainerEditPartOperation.refreshBorder(AbstractDiagramElementContainerEditPart, // ViewNodeContainerFigureDesc, ContainerStyle) + // TODO : 1 should be replace by borderSize (style.getBorderSize().intValue()) result.setWidth(0); result.setHeight(1); } @@ -244,7 +329,7 @@ public static Dimension getContainerTopLeftInsets(Node node, boolean searchFirst if (nodeContainer instanceof Node) { Node parentNode = (Node) nodeContainer; NodeQuery nodeQuery = new NodeQuery(parentNode); - if (nodeQuery.isContainer() || nodeQuery.isListCompartment() || nodeQuery.isVerticalRegionContainerCompartment()) { + if (nodeQuery.isContainer() || nodeQuery.isListCompartment() || nodeQuery.isRegionContainerCompartment()) { result = getTopLeftInsets(parentNode); } else if (searchFirstParentContainer) { result = getContainerTopLeftInsets(parentNode, searchFirstParentContainer); @@ -278,7 +363,18 @@ public static Dimension getBottomRightInsets(Node container) { result.setWidth(result.width() + borderSize.width()); result.setHeight(result.height() + borderSize.height()); } else if (new DDiagramElementContainerExperimentalQuery(ddec).isRegion()) { - // No margin + // if (new DDiagramElementContainerExperimentalQuery(ddec).isRegionInHorizontalStack() && + // isFirstRegion(container)) { + // // Correspond to + // // + // org.eclipse.sirius.diagram.ui.edit.internal.part.DiagramContainerEditPartOperation.configureBorder(AbstractDiagramElementContainerEditPart, + // // IFigure, boolean) + // result.setWidth(1); + // } + // No margin otherwise + Dimension borderSize = getBorderSize(ddec); + result.setWidth(result.width() + borderSize.width()); + result.setHeight(result.height() + borderSize.height()); } else { if (hasFullLabelBorder(ddec)) { // TODO : Not sure about that, to verify @@ -363,7 +459,7 @@ public static Dimension getBorderSize(DDiagramElementContainer ddec) { result.setWidth(isFirstRegion(ddec) ? 0 : borderSize); result.setHeight(1); } else if (regionQuery.isRegionInVerticalStack()) { - result.setWidth(1); + result.setWidth(0); result.setHeight(isFirstRegion(ddec) ? 1 : borderSize); } else { result.setWidth(borderSize); @@ -431,100 +527,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, boolean insetsAware) { - Point location = new Point(0, 0); - LayoutConstraint layoutConstraint = node.getLayoutConstraint(); - if (layoutConstraint instanceof Bounds && !(new ViewQuery(node).isVerticalRegion())) { - // The bounds is computed for vertical region, even if it is stored in GMF data - 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 (new ViewQuery(node).isListCompartment()) { - // Translate the compartment to be just below the the title, the x coordinate is also the same (same parent - // insets) - Rectangle titleBounds = getAbsoluteBounds(getPreviousChild(node), true); - location.translate(titleBounds.preciseX(), titleBounds.preciseY() + titleBounds.preciseHeight()); - // Translate from the spacing (5 pixels) - location.translate(0, IContainerLabelOffsets.LABEL_OFFSET); - } else if (new ViewQuery(node).isVerticalRegionContainerCompartment()) { - // Translate the compartment to be just below the the title, the x coordinate is also the same (same parent - // insets) - Rectangle titleBounds = getAbsoluteBounds(getPreviousChild(node), true); - location.translate(titleBounds.preciseX(), titleBounds.preciseY() + titleBounds.preciseHeight()); - // Translate from the spacing (5 pixels) - location.translate(0, IContainerLabelOffsets.LABEL_OFFSET); - } else if (new ViewQuery(node).isListItem()) { - if (node.eContainer() instanceof Node container) { - if (container.getChildren().get(0) == node) { - Point parentNodeLocation = getAbsoluteLocation(container, insetsAware); - location.translate(parentNodeLocation); - if (insetsAware) { - translateWithInsets(location, node); - } - - // This is the first list item, add a one margin border over it. - // location.translate(0, 1); TODO: Here or in parent insets ? - } else { - // Translate from the previous children - Rectangle previousChildBounds = getAbsoluteBounds(getPreviousChild(node), true); - location.translate(previousChildBounds.preciseX(), previousChildBounds.preciseY() + previousChildBounds.preciseHeight()); - } - } - } else if (new ViewQuery(node).isVerticalRegion()) { - if (node.eContainer() instanceof Node container) { - if (container.getChildren().get(0) == node) { - Point parentNodeLocation = getAbsoluteLocation(container, insetsAware); - location.translate(parentNodeLocation); - if (insetsAware) { - translateWithInsets(location, node); - } - } else { - // Translate from the previous children - Rectangle previousChildBounds = getAbsoluteBounds(getPreviousChild(node), true); - location.translate(previousChildBounds.preciseX(), previousChildBounds.preciseY() + previousChildBounds.preciseHeight()); - } - } - } else { - if (node.eContainer() instanceof Node container) { - Point parentNodeLocation = getAbsoluteLocation(container, insetsAware); - location.translate(parentNodeLocation); - if (insetsAware) { - translateWithInsets(location, node); - } - } - - } - // if (new ViewQuery(node).isVerticalRegion()) { - // if (node.eContainer() instanceof Node container) { - // if (container.getChildren().get(0) == node) { - // // This is the first vertical region. - // // location.translate(0, 1); TODO: Here or in parent insets ? - // } else { - // // Replace location by the the previous children bottom corner - // // location = new PrecisionPoint(0, getBottomRight(container, node, false).preciseY()); - // // location = new PrecisionPoint(0, getAbsoluteBounds(getPreviousChild(node), - // // true).getBottomRight().preciseY()); - // } - // } - // } - return location; + return getAbsoluteLocation(node, insetsAware); } private static Node getPreviousChild(Node node) { @@ -906,8 +913,8 @@ private static void replaceAutoSize(Node node, PrecisionRectangle bounds, boolea ViewQuery nodeQuery = new ViewQuery(node); if (nodeQuery.isFreeFormCompartment() || nodeQuery.isListCompartment()) { defaultSize = new Dimension(ResizableCompartmentFigure.MIN_CLIENT_DP, ResizableCompartmentFigure.MIN_CLIENT_DP); - if (nodeQuery.isVerticalRegionContainerCompartment() || nodeQuery.isListCompartment()) { - if (node.getChildren().isEmpty()) { + if (node.getChildren().isEmpty()) { + if (nodeQuery.isVerticalRegionContainerCompartment() || nodeQuery.isHorizontalRegionContainerCompartment() || nodeQuery.isListCompartment()) { // Add one margin border (even if empty) defaultSize.expand(0, 1); } @@ -1060,12 +1067,7 @@ public static Rectangle getChildrenBounds(Node container, boolean considerBorder ViewQuery containerViewQuery = new ViewQuery(container); Rectangle result = null; if (container.getChildren().isEmpty()) { - if (containerViewQuery.isListCompartment() || containerViewQuery.isVerticalRegionContainerCompartment()) { - // Add one vertical margin border (even if empty) - result = new PrecisionRectangle(0, 0, 0, 1); - } else { - result = new PrecisionRectangle(); - } + result = new PrecisionRectangle(); } if (containerViewQuery.isListContainer() || containerViewQuery.isVerticalRegionContainerCompartment() || containerViewQuery.isListCompartment()) { if (!container.getChildren().isEmpty()) {