Commit 9c396c46 authored by Christian Hilden's avatar Christian Hilden
Browse files

Merge branch '29-inherited-structure-diagram-layout' into 'master'

[ui.structure] Simplify inheriting actor positioning

Closes #29

See merge request !12
parents 71d9b289 153d905c
Pipeline #4466 passed with stage
in 0 seconds
......@@ -36,25 +36,32 @@ import org.eclipse.etrice.ui.structure.support.SPPSupport;
import org.eclipse.etrice.ui.structure.support.StructureClassSupport;
import org.eclipse.etrice.ui.structure.support.provider.DecorationProvider;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IAddBendpointFeature;
import org.eclipse.graphiti.features.IAddFeature;
import org.eclipse.graphiti.features.ICreateConnectionFeature;
import org.eclipse.graphiti.features.ICreateFeature;
import org.eclipse.graphiti.features.IDeleteFeature;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.ILayoutFeature;
import org.eclipse.graphiti.features.IMoveBendpointFeature;
import org.eclipse.graphiti.features.IMoveShapeFeature;
import org.eclipse.graphiti.features.IReconnectionFeature;
import org.eclipse.graphiti.features.IRemoveBendpointFeature;
import org.eclipse.graphiti.features.IRemoveFeature;
import org.eclipse.graphiti.features.IResizeShapeFeature;
import org.eclipse.graphiti.features.IUpdateFeature;
import org.eclipse.graphiti.features.context.IAddBendpointContext;
import org.eclipse.graphiti.features.context.IAddContext;
import org.eclipse.graphiti.features.context.IBendpointContext;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.context.IDeleteContext;
import org.eclipse.graphiti.features.context.IDoubleClickContext;
import org.eclipse.graphiti.features.context.ILayoutContext;
import org.eclipse.graphiti.features.context.IMoveBendpointContext;
import org.eclipse.graphiti.features.context.IMoveShapeContext;
import org.eclipse.graphiti.features.context.IPictogramElementContext;
import org.eclipse.graphiti.features.context.IReconnectionContext;
import org.eclipse.graphiti.features.context.IRemoveBendpointContext;
import org.eclipse.graphiti.features.context.IRemoveContext;
import org.eclipse.graphiti.features.context.IResizeShapeContext;
import org.eclipse.graphiti.features.context.IUpdateContext;
......@@ -304,6 +311,33 @@ public class ProviderDispatcher {
return super.getRemoveFeature(context);
}
@Override
public IMoveBendpointFeature getMoveBendpointFeature(IMoveBendpointContext context) {
IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
if (fp!=null)
return fp.getMoveBendpointFeature(context);
else
return super.getMoveBendpointFeature(context);
}
@Override
public IAddBendpointFeature getAddBendpointFeature(IAddBendpointContext context) {
IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
if (fp!=null)
return fp.getAddBendpointFeature(context);
else
return super.getAddBendpointFeature(context);
}
@Override
public IRemoveBendpointFeature getRemoveBendpointFeature(IRemoveBendpointContext context) {
IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
if (fp!=null)
return fp.getRemoveBendpointFeature(context);
else
return super.getRemoveBendpointFeature(context);
}
@Override
public ICustomFeature[] getCustomFeatures(ICustomContext context) {
ArrayList<ICustomFeature> result = new ArrayList<ICustomFeature>();
......@@ -338,6 +372,12 @@ public class ProviderDispatcher {
return bo;
}
private EObject getBusinessObject(IBendpointContext context) {
PictogramElement pictogramElement = context.getConnection();
EObject bo = (EObject) getBusinessObjectForPictogramElement(pictogramElement);
return bo;
}
private EObject getBusinessObject(ICustomContext context) {
PictogramElement[] pes = context.getPictogramElements();
if (pes.length>0) {
......
......@@ -52,7 +52,6 @@ import org.eclipse.etrice.ui.structure.support.context.PositionUpdateContext;
import org.eclipse.etrice.ui.structure.support.feature.ShapeUpdateFeature;
import org.eclipse.etrice.ui.structure.support.provider.DefaultPositionProvider;
import org.eclipse.etrice.ui.structure.support.provider.IPositionProvider;
import org.eclipse.etrice.ui.structure.support.provider.IPositionProvider.PosAndSize;
import org.eclipse.etrice.ui.structure.support.provider.SuperDiagramPositionProvider;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IAddFeature;
......@@ -886,8 +885,7 @@ public class ActorContainerRefSupport {
if(context instanceof PositionUpdateContext)
setPosition(acr, containerShape, (PositionUpdateContext) context);
EObject parent = (EObject) getBusinessObjectForPictogramElement(containerShape.getContainer());
updateRefFigure(acr, containerShape, isInherited(acr, parent), getDiagram());
layoutPictogramElement(containerShape);
GraphicsAlgorithm mainBorder = new ActorRefGraphicsAccess(containerShape, getDiagram()).getMainBorder();
IPositionProvider positionProvider = null;
......@@ -977,23 +975,39 @@ public class ActorContainerRefSupport {
@Override
public boolean canMoveShape(IMoveShapeContext context) {
boolean canMove = super.canMoveShape(context);
if (canMove) {
Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
if (bo instanceof ActorContainerRef) {
ActorContainerRef ar = (ActorContainerRef) bo;
ContainerShape acShape = context.getTargetContainer();
EObject parent = acShape.getLink().getBusinessObjects().get(0);
// TODOHRR: also check coordinates (no overlap with actor boundaries)
return !isInherited(ar, parent);
}
}
if (!super.canMoveShape(context))
return false;
Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
if (!(bo instanceof ActorContainerRef))
return false;
ActorContainerRef ar = (ActorContainerRef) bo;
ContainerShape acShape = context.getTargetContainer();
EObject parent = acShape.getLink().getBusinessObjects().get(0);
return canMove;
// TODOHRR: also check coordinates (no overlap with actor boundaries)
if (isInherited(ar, parent))
return false;
PosAndSize parentExtent = DiagramUtil.getVisibleExtent(acShape);
PosAndSize childExtent = DiagramUtil.getVisibleExtent(context.getPictogramElement());
if (parentExtent == null || childExtent == null)
return false;
int destX = context.getDeltaX()+childExtent.getX();
int destY = context.getDeltaY()+childExtent.getY();
if (destX < parentExtent.getX())
return false;
if (destY < parentExtent.getY())
return false;
if (destX+childExtent.getW() > parentExtent.getX()+parentExtent.getW())
return false;
if (destY+childExtent.getH() > parentExtent.getY()+parentExtent.getH())
return false;
return true;
}
}
......@@ -1007,6 +1021,18 @@ public class ActorContainerRefSupport {
public boolean canResizeShape(IResizeShapeContext context) {
if (!super.canResizeShape(context))
return false;
if (!(context.getPictogramElement() instanceof ContainerShape))
return false;
Object bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(context.getPictogramElement());
if (!(bo instanceof ActorContainerRef))
return false;
// If inherited, do not allow resize
StructureClass sc = SupportUtil.getInstance().getParent((ContainerShape)context.getPictogramElement(), getFeatureProvider());
if (isInherited((ActorContainerRef)bo, sc))
return false;
int width = context.getWidth()-MARGIN;
int height = context.getHeight()-MARGIN;
......
......@@ -33,24 +33,33 @@ import org.eclipse.etrice.ui.structure.support.feature.ConnectionUpdateFeature;
import org.eclipse.etrice.ui.structure.support.provider.ConnectionProvider;
import org.eclipse.etrice.ui.structure.support.provider.DecorationProvider;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IAddBendpointFeature;
import org.eclipse.graphiti.features.IAddFeature;
import org.eclipse.graphiti.features.ICreateConnectionFeature;
import org.eclipse.graphiti.features.IDeleteFeature;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.IMoveBendpointFeature;
import org.eclipse.graphiti.features.IReconnectionFeature;
import org.eclipse.graphiti.features.IRemoveBendpointFeature;
import org.eclipse.graphiti.features.IRemoveFeature;
import org.eclipse.graphiti.features.IUpdateFeature;
import org.eclipse.graphiti.features.context.IAddBendpointContext;
import org.eclipse.graphiti.features.context.IAddConnectionContext;
import org.eclipse.graphiti.features.context.IAddContext;
import org.eclipse.graphiti.features.context.ICreateConnectionContext;
import org.eclipse.graphiti.features.context.IDeleteContext;
import org.eclipse.graphiti.features.context.IMoveBendpointContext;
import org.eclipse.graphiti.features.context.IReconnectionContext;
import org.eclipse.graphiti.features.context.IRemoveBendpointContext;
import org.eclipse.graphiti.features.context.IRemoveContext;
import org.eclipse.graphiti.features.context.IUpdateContext;
import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
import org.eclipse.graphiti.features.context.impl.ReconnectionContext;
import org.eclipse.graphiti.features.impl.AbstractAddFeature;
import org.eclipse.graphiti.features.impl.DefaultAddBendpointFeature;
import org.eclipse.graphiti.features.impl.DefaultMoveBendpointFeature;
import org.eclipse.graphiti.features.impl.DefaultReconnectionFeature;
import org.eclipse.graphiti.features.impl.DefaultRemoveBendpointFeature;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.Polyline;
import org.eclipse.graphiti.mm.pictograms.Anchor;
......@@ -395,8 +404,64 @@ public class BindingSupport {
return true;
}
}
private class MoveBendpointFeature extends DefaultMoveBendpointFeature {
public MoveBendpointFeature(IFeatureProvider fp) {
super(fp);
}
@Override
public boolean canMoveBendpoint(IMoveBendpointContext context) {
EObject bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(context.getConnection());
if (bo instanceof Binding) {
Binding b = (Binding) bo;
if (!isInherited(getDiagram(), b)) {
return true;
}
}
return false;
}
}
private class AddBendpointFeature extends DefaultAddBendpointFeature {
public AddBendpointFeature(IFeatureProvider fp) {
super(fp);
}
@Override
public boolean canAddBendpoint(IAddBendpointContext context) {
EObject bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(context.getConnection());
if (bo instanceof Binding) {
Binding b = (Binding) bo;
if (!isInherited(getDiagram(), b)) {
return true;
}
}
return false;
}
}
private class RemoveBendpointFeature extends DefaultRemoveBendpointFeature {
public RemoveBendpointFeature(IFeatureProvider fp) {
super(fp);
}
@Override
public boolean canRemoveBendpoint(IRemoveBendpointContext context) {
EObject bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(context.getConnection());
if (bo instanceof Binding) {
Binding b = (Binding) bo;
if (!isInherited(getDiagram(), b)) {
return true;
}
}
return false;
}
}
private IFeatureProvider fp;
public FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) {
......@@ -438,6 +503,24 @@ public class BindingSupport {
public IDeleteFeature getDeleteFeature(IDeleteContext context) {
return new DeleteFeature(fp);
}
@Override
public IMoveBendpointFeature getMoveBendpointFeature(IMoveBendpointContext context) {
IMoveBendpointFeature ret = new MoveBendpointFeature(fp);
return ret;
}
@Override
public IAddBendpointFeature getAddBendpointFeature(IAddBendpointContext context) {
IAddBendpointFeature ret = new AddBendpointFeature(fp);
return ret;
}
@Override
public IRemoveBendpointFeature getRemoveBendpointFeature(IRemoveBendpointContext context) {
IRemoveBendpointFeature ret = new RemoveBendpointFeature(fp);
return ret;
}
}
class BehaviorProvider extends BaseToolBehaviorProvider {
......
......@@ -23,7 +23,6 @@ import org.eclipse.etrice.ui.structure.DiagramAccess;
import org.eclipse.etrice.ui.structure.support.context.DeleteContext;
import org.eclipse.etrice.ui.structure.support.context.PositionUpdateContext;
import org.eclipse.etrice.ui.structure.support.provider.IPositionProvider;
import org.eclipse.etrice.ui.structure.support.provider.IPositionProvider.PosAndSize;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.IReason;
import org.eclipse.graphiti.features.IUpdateFeature;
......@@ -212,25 +211,27 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature {
}
private ContainerShape createStructureClass(StructureClass sc, IPositionProvider positionProvider){
PosAndSize pos = positionProvider == null ? null : positionProvider.getDiagramPosition();
AddContext addContext = new AddContext();
addContext.setNewObject(sc);
addContext.setTargetContainer(getDiagram());
addContext.setX(StructureClassSupport.MARGIN);
addContext.setY(StructureClassSupport.MARGIN);
if (pos != null) {
addContext.setWidth(pos.getW()-2*StructureClassSupport.MARGIN);
addContext.setHeight(pos.getH()-2*StructureClassSupport.MARGIN);
}
ContainerShape scShape = (ContainerShape) getFeatureProvider().addIfPossible(addContext);
if(positionProvider != null){
PosAndSize pos = positionProvider.getDiagramPosition();
if(pos != null){
GraphicsAlgorithm ga = scShape.getGraphicsAlgorithm();
if(pos != null){
ga.setX(pos.getX());
ga.setY(pos.getY());
if(pos.getW() > 0)
ga.setWidth(pos.getW());
if(pos.getH() > 0)
ga.setHeight(pos.getH());
}
ga.setX(pos.getX());
ga.setY(pos.getY());
if(pos.getW() > 0)
ga.setWidth(pos.getW());
if(pos.getH() > 0)
ga.setHeight(pos.getH());
}
return scShape;
......
......@@ -22,11 +22,12 @@ import org.eclipse.etrice.core.room.Binding;
import org.eclipse.etrice.core.room.InterfaceItem;
import org.eclipse.etrice.core.room.LayerConnection;
import org.eclipse.etrice.core.room.StructureClass;
import org.eclipse.etrice.ui.structure.support.provider.IPositionProvider.PosAndSize;
import org.eclipse.etrice.core.room.util.RoomSwitch;
import org.eclipse.graphiti.mm.PropertyContainer;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.services.ILinkService;
......@@ -34,6 +35,14 @@ import org.eclipse.graphiti.services.IPeService;
public class DiagramUtil {
public static enum Border {
NONE,
TOP,
BOTTOM,
LEFT,
RIGHT
}
public static boolean isSupported(Object obj){
return obj instanceof StructureClass
|| obj instanceof ActorContainerRef
......@@ -75,4 +84,141 @@ public class DiagramUtil {
return null;
}
/**
* Given an element and its container, calculates the nearest border relative to the element's boundaries.
*/
public static Border getNearestBorder(PosAndSize element, PosAndSize container) {
int left = Math.abs(element.getX());
int right = Math.abs(container.getW() - element.getX());
int top = Math.abs(element.getY());
int bottom = Math.abs(container.getH() - element.getY());
int min = left;
Border border = Border.LEFT;
if (right < min) {
border = Border.RIGHT;
min = right;
}
if (top < min) {
border = Border.TOP;
min = top;
}
if (bottom < min) {
border = Border.BOTTOM;
}
return border;
}
/**
* Given an element and its container, calculates the nearest border relative to the element's boundaries.
* Takes the position and size values from the GraphicsAlgorithm objects.
*/
public static Border getNearestBorder(GraphicsAlgorithm element, GraphicsAlgorithm container) {
PosAndSize posContainer = getPosAndSize(container);
PosAndSize pos = getPosAndSize(element);
return getNearestBorder(pos, posContainer);
}
private static class VisibleExtentSwitch extends RoomSwitch<PosAndSize> {
private PictogramElement pe;
public VisibleExtentSwitch(PictogramElement pe) {
this.pe = pe;
}
@Override
public PosAndSize caseStructureClass(StructureClass object) {
if (pe.getGraphicsAlgorithm() == null)
return null;
if (pe.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().size() < 2) {
return null;
}
GraphicsAlgorithm visibleGa = pe.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0);
return getPosAndSize(visibleGa);
}
@Override
public PosAndSize caseInterfaceItem(InterfaceItem object) {
if (pe.getGraphicsAlgorithm() == null)
return null;
if (pe.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().size() < 1) {
return null;
}
GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
GraphicsAlgorithm visible = pe.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0);
return new PosAndSize(
visible.getX() + invisible.getX(),
visible.getY() + invisible.getY(),
visible.getWidth(),
visible.getHeight()
);
}
@Override
public PosAndSize caseActorContainerRef(ActorContainerRef object) {
if (pe.getGraphicsAlgorithm() == null)
return null;
if (pe.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().size() < 2) {
return null;
}
IPeService peService = Graphiti.getPeService();
GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
GraphicsAlgorithm main = null;
GraphicsAlgorithm repl = null;
boolean isReplVisible = false;
for (GraphicsAlgorithm ga : invisible.getGraphicsAlgorithmChildren()) {
String value = peService.getPropertyValue(ga, ActorContainerRefSupport.GRAPHIC_ITEM_KEY);
if (ActorContainerRefSupport.MAIN_BORDER.equals(value)) {
main = ga;
} else if (ActorContainerRefSupport.REPL_BORDER.equals(value)) {
repl = ga;
isReplVisible = ga.getLineVisible();
}
}
if (main == null || repl == null)
return null;
if (isReplVisible) {
int x = Math.min(main.getX(), repl.getX());
int y = Math.min(main.getY(), repl.getY());
int wTotalMain = main.getX()+main.getWidth();
int wTotalRepl = repl.getX()+repl.getWidth();
int hTotalMain = main.getY()+main.getHeight();
int hTotalRepl = repl.getY()+repl.getHeight();
return new PosAndSize(
x+invisible.getX(),
y+invisible.getY(),
wTotalMain > wTotalRepl ? wTotalMain - x : wTotalRepl - x,
hTotalMain > hTotalRepl ? hTotalMain - y : hTotalRepl - y);
} else {
return new PosAndSize(
main.getX()+invisible.getX(),
main.getY()+invisible.getY(),
main.getWidth(), main.getHeight());
}
}
@Override
public PosAndSize defaultCase(EObject object) {
return getPosAndSize(pe.getGraphicsAlgorithm());
}
}
/**
* Gets the position and size of the visible bounding box of the given PictogramElement. The
* bounds will be calculated based on the GraphicsAlgorithms of the PictogramElement and the
* type of business object it is associated with.
*
* @return the visible bounds of the PictogramElement, or null if the PictogramElement was malformed
* or the corresponding business object was invalid
*/
public static PosAndSize getVisibleExtent(PictogramElement pe) {
Object bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(pe);
if (!EObject.class.isInstance(bo))
return null;
return new VisibleExtentSwitch(pe).doSwitch((EObject)bo);
}
}
......@@ -23,6 +23,7 @@ import org.eclipse.etrice.core.room.ActorRef;
import org.eclipse.etrice.core.room.InterfaceItem;
import org.eclipse.etrice.core.room.Port;
import org.eclipse.etrice.core.room.ProtocolClass;
import org.eclipse.etrice.core.room.RoomPackage;
import org.eclipse.etrice.core.room.SPP;
import org.eclipse.etrice.core.room.SubSystemRef;
import org.eclipse.etrice.ui.commands.RoomOpeningHelper;
......@@ -234,13 +235,13 @@ public class InterfaceItemSupport {
ContainerShape acShape = context.getTargetContainer();
Object parentBO = getBusinessObjectForPictogramElement(acShape);
if (isInherited(item, parentBO, acShape))
return false;
boolean refport = (parentBO instanceof ActorContainerRef);
if (refport)
return true;
if (isInherited(item, parentBO, acShape))
return false;
int margin = refport?ActorContainerRefSupport.MARGIN:StructureClassSupport.MARGIN;
return isValidPosition(context, context, isInternal(item), margin);
}
......@@ -379,6 +380,14 @@ public class InterfaceItemSupport {
if(context instanceof PositionUpdateContext)
setPosition(port, containerShape, (PositionUpdateContext) context);
GraphicsAlgorithm invGa = containerShape.getGraphicsAlgorithm();
GraphicsAlgorithm textGa = containerShape.getChildren().get(0).getGraphicsAlgorithm();
boolean refport = RoomPackage.eINSTANCE.getActorContainerRef().isInstance(parentShapeBo);
int margin = refport?MARGIN_SMALL:MARGIN;
int size = refport?ITEM_SIZE_SMALL:ITEM_SIZE;
if (textGa instanceof Text)
adjustLabel((Text)textGa, invGa.getX(), invGa.getY(), containerShape.getContainer().getGraphicsAlgorithm().getWidth(), margin, size);
return true;