Skip to content

Commit

Permalink
[396] Adapt NodeCreationEditPolicy to compute the target location
Browse files Browse the repository at this point in the history
- Constructors of CreationUtil have been improved to directly have
LayoutData as parameter instead of location and size. Indeed, the
location is relative to the parent edit part and for border nodes, the
parent edit part is not systematically the "host" of the called policy.
- In NodeCreationEditPolicy, in case of border nodes, the "host edit
part" is not systematically considered (to compute the RootLayoutData
for example). The correct edit part, a parent of the host, is computed
according to the mapping defined in the used tool.

Bug: #396
  • Loading branch information
lredor committed Sep 12, 2024
1 parent 13e0458 commit 745f51e
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2021 THALES GLOBAL SERVICES and others.
* Copyright (c) 2010, 2024 THALES GLOBAL SERVICES and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -101,7 +101,7 @@ protected Command getCreateNodeOnDiagramCommand(CreateRequest request, NodeCreat
finishingEndEndPredecessor = SequenceGraphicalHelper.getEndBefore(diag, location.y + size.height);
}

CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(startingEndPredecessor, finishingEndEndPredecessor, location), getRealLocation(request), request.getSize(),
CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(startingEndPredecessor, finishingEndEndPredecessor, location), getRealLocation(request), request.getSize(),
getHost());
result = creationUtil.getNodeCreationCommand(diagram, tool);
} else if (tool instanceof InstanceRoleCreationTool && diagram instanceof SequenceDDiagram) {
Expand All @@ -110,7 +110,7 @@ protected Command getCreateNodeOnDiagramCommand(CreateRequest request, NodeCreat
GraphicalHelper.screen2logical(location, (IGraphicalEditPart) getHost());

EObject predecessor = SequenceGraphicalHelper.getInstanceRoleBefore(diag, location.x);
CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(predecessor, location), getRealLocation(request), request.getSize(), getHost());
CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(predecessor, location), getRealLocation(request), request.getSize(), getHost());
result = creationUtil.getNodeCreationCommand(diagram, tool);
} else {
result = super.getCreateNodeOnDiagramCommand(request, tool, diagram);
Expand Down Expand Up @@ -140,7 +140,7 @@ protected Command getCreateContainerOnDiagramCommand(CreateRequest request, Cont
List<EObject> coverage = creationValidator.getCoverage();
Range expansionZone = creationValidator.getExpansionZone();

CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(startingEndPredecessor, finishingEndPredecessor, coverage, getCreationRange(request)),
CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(startingEndPredecessor, finishingEndPredecessor, coverage, getCreationRange(request)),
getRealLocation(request), getRealSize(ccdTool, request), getHost());
result = creationUtil.getContainerCreationDescription(diagram, ccdTool);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2013 THALES GLOBAL SERVICES.
* Copyright (c) 2010, 2024 THALES GLOBAL SERVICES.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -148,7 +148,7 @@ public void eraseTargetFeedback(Request request) {
* {@inheritDoc}
*/
@Override
protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreationDescription tool, DNode viewnode) {
protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreationDescription tool, DNode viewnode, EditPart parentEditPartToUse) {
if (tool instanceof ExecutionCreationTool || tool instanceof StateCreationTool || tool instanceof ObservationPointCreationTool) {
SequenceDiagram sequenceDiagram = EditPartsHelper.getSequenceDiagram(getHost());
SequenceDDiagram diagram = sequenceDiagram.getSequenceDDiagram();
Expand All @@ -163,11 +163,11 @@ protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreation
GraphicalHelper.logical2screen(bottomRight, (IGraphicalEditPart) getHost());
request.setSize(new Dimension(LayoutConstants.DEFAULT_EXECUTION_WIDTH, LayoutConstants.DEFAULT_EXECUTION_HEIGHT));
}
CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(startingEndPredecessor, startingEndPredecessor, location), getRealLocation(request), request.getSize(),
CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(startingEndPredecessor, startingEndPredecessor, location), getRealLocation(request), request.getSize(),
getHost());
return creationUtil.getNodeCreationCommand(viewnode, tool);
} else {
return super.getCreateNodeOnNodeCommand(request, tool, viewnode);
return super.getCreateNodeOnNodeCommand(request, tool, viewnode, parentEditPartToUse);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,13 @@
*/
public class CreationUtil {

/** The location of the clicked point. */
private final Point realLocation;

/** The computed size of the element to create. */
private final Dimension realSize;
/** The location of the clicked point, the size and the parent edit part of the element to create. */
private final RootLayoutData rootLayoutData;

/** The EMF Command Factory. */
private final IDiagramCommandFactory emfCommandFactory;

/** The request. */
private final CreateRequest request;

/** The edit part. */
/** The edit part on which the calling policy is installed. */
private final EditPart editPart;

/**
Expand All @@ -91,33 +85,45 @@ public class CreationUtil {
* @param realLocation
* the location of the clicked point.
* @param editPart
* the edit part
* the edit part on which the calling policy is installed.
* @since 0.9.0
*/
public CreationUtil(final CreateRequest request, final IDiagramCommandFactory commandFactory, final Point realLocation, final EditPart editPart) {
this(request, commandFactory, realLocation, null, editPart);
// The size of the request take into account the zoom (got the size in 100%)
this(commandFactory, new RootLayoutData(editPart, realLocation.getCopy(), CreationUtil.adaptRequestSizeToZoomFactor(request, editPart)), editPart);
}

/**
* Creates a new <code>CreationUtil</code> with the specified request and location.
*
* @param request
* the request.
* @param commandFactory
* the emf command factory.
* @param realLocation
* the location of the clicked point.
* @param realSize
* the computed size of the element to create, null if the default size must be used
* @param editPart
* the edit part
* the edit part on which the calling policy is installed.
* @since 0.9.0
*/
public CreationUtil(final CreateRequest request, final IDiagramCommandFactory commandFactory, final Point realLocation, final Dimension realSize, final EditPart editPart) {
this.realLocation = realLocation;
this.realSize = realSize;
this.request = request;
public CreationUtil(final IDiagramCommandFactory commandFactory, final Point realLocation, final Dimension realSize, final EditPart editPart) {
this(commandFactory, new RootLayoutData(editPart, realLocation.getCopy(), realSize.getCopy()), editPart);
}

/**
* Creates a new <code>CreationUtil</code> with the specified request and location.
*
* @param commandFactory
* the emf command factory.
* @param rootLayoutData
* the layout data for the created element (clicked point, size and parent edit part).
* @param editPart
* the edit part on which the calling policy is installed.
* @since 0.9.0
*/
public CreationUtil(final IDiagramCommandFactory commandFactory, final RootLayoutData rootLayoutData, final EditPart editPart) {
this.emfCommandFactory = commandFactory;
this.rootLayoutData = rootLayoutData;
this.editPart = editPart;
}

Expand Down Expand Up @@ -314,15 +320,7 @@ private Command createLayoutDataCommand() {
return new Command() {
@Override
public void execute() {
// The size of the request take into account the zoom (got
// the size in 100%)
Dimension size = null;
if (realSize != null) {
size = realSize.getCopy();
} else {
size = adaptRequestSizeToZoomFactor();
}
SiriusLayoutDataManager.INSTANCE.addData(new RootLayoutData(editPart, realLocation.getCopy(), size));
SiriusLayoutDataManager.INSTANCE.addData(rootLayoutData);
}
};
}
Expand All @@ -332,7 +330,7 @@ public void execute() {
*
* @return A new dimension
*/
private Dimension adaptRequestSizeToZoomFactor() {
public static Dimension adaptRequestSizeToZoomFactor(CreateRequest request, EditPart editPart) {
if (request.getSize() == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2009 THALES GLOBAL SERVICES.
* Copyright (c) 2007, 2024 THALES GLOBAL SERVICES.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand All @@ -12,23 +12,32 @@
*******************************************************************************/
package org.eclipse.sirius.diagram.ui.graphical.edit.policies;

import java.util.Optional;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.figures.ResizableCompartmentFigure;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.sirius.diagram.AbstractDNode;
import org.eclipse.sirius.diagram.DDiagramElementContainer;
import org.eclipse.sirius.diagram.DNode;
import org.eclipse.sirius.diagram.description.NodeMapping;
import org.eclipse.sirius.diagram.description.tool.ContainerCreationDescription;
import org.eclipse.sirius.diagram.description.tool.NodeCreationDescription;
import org.eclipse.sirius.diagram.tools.api.command.IDiagramCommandFactory;
import org.eclipse.sirius.diagram.tools.api.command.IDiagramCommandFactoryProvider;
import org.eclipse.sirius.diagram.ui.business.internal.query.RequestQuery;
import org.eclipse.sirius.diagram.ui.business.internal.view.RootLayoutData;
import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramContainerEditPart;
import org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeListCompartmentEditPart;
import org.eclipse.sirius.diagram.ui.tools.api.draw2d.ui.figures.FigureUtilities;
import org.eclipse.sirius.diagram.ui.tools.api.editor.DDiagramEditor;
import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription;
Expand All @@ -44,12 +53,25 @@ public class NodeCreationEditPolicy extends SiriusContainerEditPolicy {
*/
@Override
protected Command getCreateCommand(CreateRequest request) {
if (!(getHost().getModel() instanceof Node)) {

AbstractToolDescription tool = getTool(request);
GraphicalEditPart hostEditPartToUse = (GraphicalEditPart) getHost();
if (getHost() instanceof GraphicalEditPart) {
boolean isBorderNodeCreationRequest = new RequestQuery(request).isDropOrCreationOfBorderNode();
if (tool instanceof NodeCreationDescription nodeCreationDescriptionTool && isBorderNodeCreationRequest) {
// Search the correct edit part for this tool. It can be different than the host in case of "extra
// mappings" defined in the tool.
Optional<GraphicalEditPart> optionalEditPartToUse = getParentEditPartWithExpectedMapping((GraphicalEditPart) getHost(), nodeCreationDescriptionTool.getNodeMappings());
if (optionalEditPartToUse.isPresent()) {
hostEditPartToUse = optionalEditPartToUse.get();
}
}
}
if (!(hostEditPartToUse.getModel() instanceof Node)) {
return null;
}
EObject containerElement = ((Node) hostEditPartToUse.getModel()).getElement();

EObject containerElement = ((Node) getHost().getModel()).getElement();
AbstractToolDescription tool = getTool(request);
/*
* Dispatch to the appropriate specialized command depending on the type
* of the container element and the nature of the tool.
Expand All @@ -58,14 +80,14 @@ protected Command getCreateCommand(CreateRequest request) {
if (containerElement instanceof DDiagramElementContainer) {
DDiagramElementContainer viewNodeContainer = (DDiagramElementContainer) containerElement;
if (tool instanceof NodeCreationDescription) {
result = getCreateNodeInContainerCommand(request, (NodeCreationDescription) tool, viewNodeContainer);
result = getCreateNodeInContainerCommand(request, (NodeCreationDescription) tool, viewNodeContainer, hostEditPartToUse);
} else if (tool instanceof ContainerCreationDescription) {
result = getCreateContainerInContainerCommand(request, (ContainerCreationDescription) tool, viewNodeContainer);
}
} else if (containerElement instanceof DNode) {
DNode viewNode = (DNode) containerElement;
if (tool instanceof NodeCreationDescription) {
result = getCreateNodeOnNodeCommand(request, (NodeCreationDescription) tool, viewNode);
result = getCreateNodeOnNodeCommand(request, (NodeCreationDescription) tool, viewNode, hostEditPartToUse);
}
}
return result;
Expand All @@ -82,8 +104,8 @@ protected Command getCreateCommand(CreateRequest request) {
* the node on which to create the new (bordered) node.
* @return a command to create the new node.
*/
protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreationDescription tool, DNode viewnode) {
CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(), getRealLocation(request), getHost());
protected Command getCreateNodeOnNodeCommand(CreateRequest request, NodeCreationDescription tool, DNode viewnode, EditPart parentEditPartToUse) {
CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(), getRealLayoutData(request, parentEditPartToUse), parentEditPartToUse);
return creationUtil.getNodeCreationCommand(viewnode, tool);
}

Expand Down Expand Up @@ -114,8 +136,8 @@ protected Command getCreateContainerInContainerCommand(CreateRequest request, Co
* the container on which to create the new (bordered) node.
* @return a command to create the new node.
*/
protected Command getCreateNodeInContainerCommand(CreateRequest request, NodeCreationDescription tool, DDiagramElementContainer viewNodeContainer) {
CreationUtil creationUtil = new CreationUtil(request, getDiagramCommandFactory(), getRealLocation(request), getHost());
protected Command getCreateNodeInContainerCommand(CreateRequest request, NodeCreationDescription tool, DDiagramElementContainer viewNodeContainer, EditPart parentEditPartToUse) {
CreationUtil creationUtil = new CreationUtil(getDiagramCommandFactory(), getRealLayoutData(request, parentEditPartToUse), parentEditPartToUse);
return creationUtil.getNodeCreationCommand(viewNodeContainer, tool);
}

Expand Down Expand Up @@ -143,10 +165,21 @@ protected AbstractToolDescription getTool(CreateRequest request) {
* @return the real location where the element must be created.
*/
protected Point getRealLocation(final CreateRequest request) {
return getRealLayoutData(request, null).getLocation();
}

/**
* Computes the real location where the element must be created from the raw information passed in the request.
*
* @param request
* the creation request.
* @return the real location where the element must be created.
*/
protected RootLayoutData getRealLayoutData(final CreateRequest request, EditPart parentEditPartToUse) {
Point location = request.getLocation().getCopy();
final Point realLocation;
if (location != null && getHost() instanceof GraphicalEditPart) {
final IFigure fig = ((GraphicalEditPart) getHost()).getFigure();
if (location != null && parentEditPartToUse instanceof GraphicalEditPart graphicalParentEditPart) {
final IFigure fig = graphicalParentEditPart.getFigure();
fig.translateToRelative(location);
final Point containerLocation = fig.getBounds().getLocation();
location = new Point(location.x - containerLocation.x, location.y - containerLocation.y);
Expand All @@ -160,7 +193,7 @@ protected Point getRealLocation(final CreateRequest request) {
} else {
scrollOffset = ((ResizableCompartmentFigure) fig).getScrollPane().getViewport().getViewLocation();
}
final Point shiftFromMarginOffset = FigureUtilities.getShiftFromMarginOffset((ResizableCompartmentFigure) fig, isBorderNodeCreationRequest, getHost());
final Point shiftFromMarginOffset = FigureUtilities.getShiftFromMarginOffset((ResizableCompartmentFigure) fig, isBorderNodeCreationRequest, parentEditPartToUse);
realLocation = new Point(location.x + scrollOffset.x - shiftFromMarginOffset.x, location.y + scrollOffset.y - shiftFromMarginOffset.y);

} else {
Expand All @@ -169,7 +202,30 @@ protected Point getRealLocation(final CreateRequest request) {
} else {
realLocation = location;
}
return realLocation;
return new RootLayoutData(parentEditPartToUse, realLocation.getCopy(), CreationUtil.adaptRequestSizeToZoomFactor(request, parentEditPartToUse));
}

private Optional<GraphicalEditPart> getParentEditPartWithExpectedMapping(GraphicalEditPart editPart, EList<NodeMapping> nodeMappings) {
Optional<GraphicalEditPart> result = Optional.empty();
if (editPart instanceof AbstractDNodeListCompartmentEditPart) {
result = getParentEditPartWithExpectedMapping((GraphicalEditPart) editPart.getParent(), nodeMappings);
} else if (editPart.getParent() instanceof AbstractDiagramContainerEditPart && ((AbstractDiagramContainerEditPart) editPart.getParent()).isRegionContainer()) {
result = getParentEditPartWithExpectedMapping((AbstractDiagramContainerEditPart) editPart.getParent(), nodeMappings);
} else {
for (NodeMapping nodeMapping : nodeMappings) {
if (editPart != null && editPart.getModel() instanceof Node && ((Node) editPart.getModel()).getElement() instanceof AbstractDNode) {
AbstractDNode abstractDNode = (AbstractDNode) ((Node) editPart.getModel()).getElement();
if (abstractDNode.getMapping().equals(nodeMapping.eContainer())) {
result = Optional.of(editPart);
break;
}
}
}
}
if (result.isEmpty() && editPart.getParent() instanceof GraphicalEditPart) {
result = getParentEditPartWithExpectedMapping((GraphicalEditPart) editPart.getParent(), nodeMappings);
}
return result;
}

/**
Expand Down

0 comments on commit 745f51e

Please sign in to comment.