diff options
Diffstat (limited to 'plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice')
6 files changed, 594 insertions, 97 deletions
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java index 63329e1b2..1bb0d2958 100644 --- a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java +++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java @@ -23,10 +23,7 @@ import org.eclipse.graphiti.mm.pictograms.Shape; import org.eclipse.graphiti.ui.internal.parts.IPictogramElementEditPart; import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.kiml.LayoutContext; -import de.cau.cs.kieler.kiml.config.VolatileLayoutConfig; import de.cau.cs.kieler.kiml.graphiti.KimlGraphitiUtil; -import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.ui.diagram.LayoutMapping; import de.cau.cs.kieler.kiml.util.KimlUtil; @@ -79,16 +76,42 @@ public class BehaviorDiagramLayoutManager extends ETriceDiagramLayoutManager { } - /** the fixed minimal height of nodes. */ - public static final float MIN_HEIGHT = StateSupport.DEFAULT_SIZE_Y; - /** the fixed minimal width of shapes. */ - public static final float MIN_WIDHT = StateSupport.DEFAULT_SIZE_X; + @Override + protected Size getDefaultSize(Shape shape) { + Size defaultSize = new Size(); + + // This code sets same minimal default size for both State Graph and + // State + defaultSize.setHeight(StateSupport.MIN_SIZE_Y); + defaultSize.setWidth(StateSupport.MIN_SIZE_X); + + /* + * This code sets default size differently for Actor Class and Actor Container + * Refs. This keeps the top-level container quite large on layout, which + * might not seem so pleasant, but is more closer to the model. + */ + /* + EObject modelObject = shape.getLink().getBusinessObjects().get(0); + if (modelObject instanceof StateGraph) { + defaultSize.setHeight(StateGraphSupport.DEFAULT_SIZE_Y); + defaultSize.setWidth(StateGraphSupport.DEFAULT_SIZE_X); + } else if (modelObject instanceof State) { + defaultSize.setHeight(StateSupport.MIN_SIZE_Y); + defaultSize.setWidth(StateSupport.MIN_SIZE_X); + } else { + defaultSize.setHeight(MIN_HEIGHT); + defaultSize.setWidth(MIN_WIDHT); + }*/ + + return defaultSize; + } /** * {@inheritDoc} * * @author jayant */ + @Override protected KNode createNode(final LayoutMapping<PictogramElement> mapping, final KNode parentNode, final Shape shape) { KNode node = KimlUtil.createInitializedNode(); @@ -96,15 +119,6 @@ public class BehaviorDiagramLayoutManager extends ETriceDiagramLayoutManager { setCurrentPositionAndSize(mapping, parentNode, node, shape); - VolatileLayoutConfig staticConfig = mapping - .getProperty(KimlGraphitiUtil.STATIC_CONFIG); - // FIXME find a way to specify the minimal size dynamically - - staticConfig.setValue(LayoutOptions.MIN_WIDTH, node, - LayoutContext.GRAPH_ELEM, MIN_WIDHT); - staticConfig.setValue(LayoutOptions.MIN_HEIGHT, node, - LayoutContext.GRAPH_ELEM, MIN_HEIGHT); - mapping.getGraphMap().put(node, shape); // gather all connections directly connected to the Node (not the @@ -118,33 +132,45 @@ public class BehaviorDiagramLayoutManager extends ETriceDiagramLayoutManager { return node; } - - /** * {@inheritDoc} * * @author jayant */ @Override - protected boolean isPort(Shape shape) { + public boolean isBoundaryPort(Shape shape) { EObject modelObject = shape.getLink().getBusinessObjects().get(0); if (modelObject instanceof TrPoint) return true; - + return false; } + /** * {@inheritDoc} * * @author jayant */ @Override - protected boolean isTopLevelBoundingBox(Shape shape) { + public boolean isInternalPort(Shape shape) { + //No shape is an internal port (i.e. All ports are external only) + return false; + } + + /** + * {@inheritDoc} + * + * @author jayant + */ + @Override + public boolean isTopLevelBoundingBox(Shape shape) { EObject modelObject = shape.getLink().getBusinessObjects().get(0); if (modelObject instanceof StateGraph) return true; - + return false; } + + } diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorLayoutCommand.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorLayoutCommand.java new file mode 100644 index 000000000..26ee58162 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorLayoutCommand.java @@ -0,0 +1,128 @@ +package org.eclipse.etrice.ui.layout; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.etrice.core.room.State; +import org.eclipse.etrice.ui.behavior.support.TrPointSupport; +import org.eclipse.graphiti.features.IFeatureProvider; +import org.eclipse.graphiti.features.context.impl.LayoutContext; +import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; +import org.eclipse.graphiti.mm.algorithms.Text; +import org.eclipse.graphiti.mm.algorithms.styles.Orientation; +import org.eclipse.graphiti.mm.pictograms.Anchor; +import org.eclipse.graphiti.mm.pictograms.ContainerShape; +import org.eclipse.graphiti.mm.pictograms.PictogramElement; +import org.eclipse.graphiti.services.Graphiti; +import org.eclipse.graphiti.services.IGaService; + +import de.cau.cs.kieler.core.kgraph.KNode; +import de.cau.cs.kieler.core.kgraph.KPort; + +public class BehaviorLayoutCommand extends ETriceLayoutCommand { + + public BehaviorLayoutCommand(TransactionalEditingDomain domain, + IFeatureProvider thefeatureProvider) { + super(domain, thefeatureProvider); + // TODO Auto-generated constructor stub + } + + /** + * {@inheritDoc} + * + * @author jayant + */ + @Override + protected void applyNodeLayout(KNode knode, PictogramElement pelem) { + setCalculatedPositionAndSize(knode, knode.getParent(), + (ContainerShape) pelem); + + getFeatureProvider().layoutIfPossible(new LayoutContext(pelem)); + + }; + + /** + * {@inheritDoc} + * + * @author jayant + */ + @Override + protected void applyPortLayout(KPort kport, PictogramElement pelem) { + + ContainerShape shape = (ContainerShape) ((Anchor) pelem).getParent(); + + setCalculatedPositionAndSize(kport, kport.getNode(), shape); + + GraphicsAlgorithm ga = shape.getGraphicsAlgorithm(); + EObject bo = shape.getContainer().getLink().getBusinessObjects().get(0); + + // margin and size for bounding box (State Graph) + int margin = TrPointSupport.MARGIN; + int size = TrPointSupport.ITEM_SIZE; + + if (bo instanceof State) { + // margin and size for a State + margin = TrPointSupport.MARGIN_SMALL; + size = TrPointSupport.ITEM_SIZE_SMALL; + } + + Text label = (Text) (shape.getChildren().get(0).getGraphicsAlgorithm()); + + adjustLabel(label, ga.getX(), ga.getY(), ga.getWidth(), margin, size); + + getFeatureProvider().layoutIfPossible(new LayoutContext(shape)); + + } + + /** + * Sets correct port label position depending on the corresponding port + * position. + * + * @param label + * Text Graphics Algorithm to be placed + * @param x + * The x coordinate of the containing shape + * @param y + * The y coordinate of the containing shape + * @param width + * The width of the containing shape + * @param margin + * The margin of the containing shape + * @param size + * The size(length/width) of the port's visible graphics + * algorithm + * + */ + /* + * This method has been copied from TrPointSuppot.FeatureProvider class + * since its visibility is not public there + */ + private static void adjustLabel(Text label, int x, int y, int width, + int margin, int size) { + Orientation halign = Orientation.ALIGNMENT_CENTER; + Orientation valign = Orientation.ALIGNMENT_CENTER; + + int pos = 0; + + if (x <= margin) + halign = Orientation.ALIGNMENT_LEFT; + else if ((width - margin) <= x) + halign = Orientation.ALIGNMENT_RIGHT; + if (y <= margin) { + pos = 0; + valign = Orientation.ALIGNMENT_BOTTOM; + } else { + pos = 5 * margin / 4; + valign = Orientation.ALIGNMENT_TOP; + } + + label.setHorizontalAlignment(halign); + label.setVerticalAlignment(valign); + + if (pos != label.getY()) { + IGaService gaService = Graphiti.getGaService(); + gaService.setLocationAndSize(label, 0, pos, 2 * margin, + 3 * margin / 4); + } + } + +} diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java index a5a83b706..9cf2a5f91 100644 --- a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java +++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java @@ -18,6 +18,7 @@ import java.util.Map.Entry; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.etrice.ui.behavior.editor.BehaviorEditor; import org.eclipse.etrice.ui.common.editor.RoomDiagramEditor; import org.eclipse.gef.EditPart; import org.eclipse.graphiti.mm.algorithms.AbstractText; @@ -50,6 +51,7 @@ import de.cau.cs.kieler.kiml.graphiti.KimlGraphitiUtil; import de.cau.cs.kieler.kiml.klayoutdata.KInsets; import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; import de.cau.cs.kieler.kiml.klayoutdata.impl.KShapeLayoutImpl; +import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.ui.diagram.LayoutMapping; import de.cau.cs.kieler.kiml.util.KimlUtil; @@ -153,9 +155,19 @@ public abstract class ETriceDiagramLayoutManager extends protected void transferLayout(final LayoutMapping<PictogramElement> mapping) { DiagramEditor diagramEditor = mapping .getProperty(KimlGraphitiUtil.DIAGRAM_EDITOR); - ETriceLayoutCommand command = new ETriceLayoutCommand( - diagramEditor.getEditingDomain(), diagramEditor - .getDiagramTypeProvider().getFeatureProvider()); + + ETriceLayoutCommand command = null; + + if (diagramEditor instanceof BehaviorEditor) { + command = new BehaviorLayoutCommand( + diagramEditor.getEditingDomain(), diagramEditor + .getDiagramTypeProvider().getFeatureProvider()); + } else { + command = new StructureLayoutCommand( + diagramEditor.getEditingDomain(), diagramEditor + .getDiagramTypeProvider().getFeatureProvider()); + } + for (Entry<KGraphElement, PictogramElement> entry : mapping .getGraphMap().entrySet()) { command.add(entry.getKey(), entry.getValue()); @@ -231,15 +243,17 @@ public abstract class ETriceDiagramLayoutManager extends } else if (element instanceof Shape) { - if ( isTopLevelBoundingBox( (Shape)element) ) { + if (isTopLevelBoundingBox((Shape) element)) { // The selected Element is the Top Level Top Level Bounding Box mapping.setLayoutGraph((KNode) buildAllLevels(mapping, (Shape) element, null)); } else { + KGraphElement internalKGraphElement = createKGaphElementFromShape( mapping, null, (Shape) element); - if (internalKGraphElement instanceof KNode) { + if (internalKGraphElement instanceof KNode + && !isInternalPort((Shape) element)) { // The selected Element is a Node. for (Shape childShape : ((ContainerShape) element) .getChildren()) { @@ -247,15 +261,16 @@ public abstract class ETriceDiagramLayoutManager extends createKGaphElementFromShape(mapping, internalKGraphElement, childShape); } - + mapping.setLayoutGraph((KNode) internalKGraphElement); - + } else { - // The selected Element is a Port or an Edge Label. + // The selected Element is a Port(Boundary or Internal) or an Edge Label. // Giving the user a SWT dialog indicating that this Shape // cannot be lay-outed. - Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + Shell shell = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(); MessageBox dialog = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK | SWT.CANCEL); dialog.setText("Invalid Layout Call"); @@ -266,7 +281,8 @@ public abstract class ETriceDiagramLayoutManager extends } } else if (element instanceof FreeFormConnection) { - // This gives the user a SWT dialog indicating this is a connection and + // This gives the user a SWT dialog indicating this is a connection + // and // cannot be lay-outed. Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getShell(); @@ -340,9 +356,19 @@ public abstract class ETriceDiagramLayoutManager extends createKGaphElementFromShape(mapping, secondLevelKGraphElement, thirdLevelShape); } + + if (!isInternalPort(secondtLevelShape)) { + // For KNodes which are not internal ports. + setNodeLayoutOptions(mapping, + (KNode) secondLevelKGraphElement, secondtLevelShape); + } + } } + setNodeLayoutOptions(mapping, topLevelBoundingBoxNode, + topLevelBoundingBox); + return topLevelBoundingBoxNode; } @@ -382,12 +408,13 @@ public abstract class ETriceDiagramLayoutManager extends else if (shape instanceof ContainerShape) { - // Checking whether this shape is a Port - if (isPort(shape)) + // Checking whether this shape is a boundary port + if (isBoundaryPort(shape)) return createPort(mapping, (KNode) parent, shape); else - // This shape is a node + // This shape is considered to be a node (includes internal + // Ports) return createNode(mapping, (KNode) parent, shape); } else @@ -395,9 +422,15 @@ public abstract class ETriceDiagramLayoutManager extends } /** - * {@inheritDoc} + * Create a node for the layout graph. * - * @author jayant + * @param mapping + * the mapping of pictogram elements to graph elements + * @param parentNode + * the parent node + * @param shape + * the shape for a new node + * @return a new layout node */ protected abstract KNode createNode( final LayoutMapping<PictogramElement> mapping, @@ -504,23 +537,131 @@ public abstract class ETriceDiagramLayoutManager extends } /** - * Determines whether the given shape is a port. + * Sets the heuristic layout options for nodes (like minimal width and + * minimal height) + * + * @param mapping + * the mapping of pictogram elements to graph elements + * @param node + * the node for which layout options need to be set + * @param shape + * TODO + * @author jayant + */ + /* This is fairly general for both the eTrice editors */ + protected void setNodeLayoutOptions( + final LayoutMapping<PictogramElement> mapping, final KNode node, + Shape shape) { + + // get label width and height for the node + float labelWidth = 0.0f; + float labelHeight = 0.0f; + + if (!node.getLabels().isEmpty()) { + KShapeLayout labelLayout = node.getLabels().get(0) + .getData(KShapeLayout.class); + labelWidth = labelLayout.getWidth(); + labelHeight = labelLayout.getHeight(); + } + + VolatileLayoutConfig staticConfig = mapping + .getProperty(KimlGraphitiUtil.STATIC_CONFIG); + + Size defaultSize = getDefaultSize(shape); + staticConfig.setValue(LayoutOptions.MIN_WIDTH, node, + LayoutContext.GRAPH_ELEM, defaultSize.getWidth() + labelWidth); + staticConfig + .setValue(LayoutOptions.MIN_HEIGHT, node, + LayoutContext.GRAPH_ELEM, defaultSize.getHeight() + + labelHeight); + } + + public static class Size { + private float width = 0; + private float height = 0; + + /** + * Getter for width + * + * @return the width + */ + public float getWidth() { + return width; + } + + /** + * Setter for width + * + * @param width + * the width to set + */ + public void setWidth(float width) { + this.width = width; + } + + /** + * Getter for height + * + * @return the height + */ + public float getHeight() { + return height; + } + + /** + * Setter for height + * + * @param height + * the height to set + */ + public void setHeight(float height) { + this.height = height; + } + } + + /** + * Determines whether the given shape is a boundary port or not. * - * @param shape the shape to be investigated + * @param shape + * the shape to be investigated * @return true if the {@code shape} is a port else false * * @author jayant */ - protected abstract boolean isPort(Shape shape); + public abstract boolean isBoundaryPort(Shape shape); + + /** + * Determines whether the given shape is an internal port or not. + * + * @param shape + * the shape to be investigated + * @return true if the {@code shape} is a port else false + * + * @author jayant + */ + public abstract boolean isInternalPort(Shape shape); /** * Determines whether the given shape is a Top Level Bounding Box or not. * - * @param shape the shape to be investigated + * @param shape + * the shape to be investigated * @return true if the {@code shape} is the Top Level Bounding Box * * @author jayant */ - protected abstract boolean isTopLevelBoundingBox(Shape shape); + public abstract boolean isTopLevelBoundingBox(Shape shape); + + /** + * Gets the Default Minimal Width for a node + * + * @param shape + * TODO + * + * @return the defaults minimal width a node + * + * @author jayant + */ + protected abstract Size getDefaultSize(Shape shape); } diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java index c09dabf46..5d33d8a2c 100644 --- a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java +++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java @@ -15,14 +15,13 @@ import java.util.List; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.graphiti.features.IFeatureProvider; -import org.eclipse.graphiti.features.context.impl.LayoutContext; import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; import org.eclipse.graphiti.mm.algorithms.styles.Point; -import org.eclipse.graphiti.mm.pictograms.Anchor; import org.eclipse.graphiti.mm.pictograms.ContainerShape; import org.eclipse.graphiti.mm.pictograms.FreeFormConnection; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.services.Graphiti; +import org.eclipse.graphiti.services.IGaService; import de.cau.cs.kieler.core.kgraph.KEdge; import de.cau.cs.kieler.core.kgraph.KGraphElement; @@ -40,7 +39,7 @@ import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout; * * @author jayant */ -public class ETriceLayoutCommand extends GraphitiLayoutCommand { +public abstract class ETriceLayoutCommand extends GraphitiLayoutCommand { public ETriceLayoutCommand(TransactionalEditingDomain domain, IFeatureProvider thefeatureProvider) { @@ -48,30 +47,21 @@ public class ETriceLayoutCommand extends GraphitiLayoutCommand { } /** - * {@inheritDoc} + * {@inheritDoc} Also responsible for the layout of internal ports in eTrice + * (which are considered as KNodes) * * @author jayant */ @Override - protected void applyPortLayout(KPort kport, PictogramElement pelem) { - - ContainerShape shape = (ContainerShape) ((Anchor) pelem).getParent(); - - setCalculatedPositionAndSize(kport, kport.getNode(), shape); - }; + protected abstract void applyNodeLayout(KNode knode, PictogramElement pelem); /** - * {@inheritDoc} + * {@inheritDoc} Only Boundary Ports are lay-outed by this method * * @author jayant */ @Override - protected void applyNodeLayout(KNode knode, PictogramElement pelem) { - - setCalculatedPositionAndSize(knode, knode.getParent(), - (ContainerShape) pelem); - - }; + protected abstract void applyPortLayout(KPort kport, PictogramElement pelem); /** * {@inheritDoc} @@ -112,8 +102,8 @@ public class ETriceLayoutCommand extends GraphitiLayoutCommand { } /** - * Sets the calculated position and size from a KGraph Model-Element (Node or - * Port) back to the corresponding diagram shape. + * Sets the calculated position and size from a KGraph Model-Element (Node + * or Port) back to the corresponding diagram shape. * * @param kelem * the KGraph Model Element (Node/Port) @@ -124,11 +114,7 @@ public class ETriceLayoutCommand extends GraphitiLayoutCommand { * * @author jayant */ - /* - * This function derives its code majorly from - * GraphitilayoutCommand.applyNodeLayout() method - */ - private void setCalculatedPositionAndSize(final KGraphElement kelem, + public static void setCalculatedPositionAndSize(final KGraphElement kelem, KNode parentNode, final ContainerShape shape) { KShapeLayout shapeLayout = kelem.getData(KShapeLayout.class); @@ -147,21 +133,20 @@ public class ETriceLayoutCommand extends GraphitiLayoutCommand { float width = shapeLayout.getWidth(); float height = shapeLayout.getHeight(); - KInsets nodeInsets = shapeLayout.getProperty(INVIS_INSETS); - if (nodeInsets != null) { - xpos -= nodeInsets.getLeft(); - ypos -= nodeInsets.getTop(); - width += nodeInsets.getLeft() + nodeInsets.getRight(); - height += nodeInsets.getTop() + nodeInsets.getBottom(); + KInsets shapeInsets = shapeLayout.getProperty(INVIS_INSETS); + if (shapeInsets != null) { + xpos -= shapeInsets.getLeft(); + ypos -= shapeInsets.getTop(); + width += shapeInsets.getLeft() + shapeInsets.getRight(); + height += shapeInsets.getTop() + shapeInsets.getBottom(); } GraphicsAlgorithm ga = shape.getGraphicsAlgorithm(); - ga.setX(Math.round(xpos)); - ga.setY(Math.round(ypos)); - ga.setWidth(Math.round(width)); - ga.setHeight(Math.round(height)); + IGaService gaService = Graphiti.getGaService(); + gaService.setLocationAndSize(ga, Math.round(xpos), Math.round(ypos), + Math.round(width), Math.round(height)); - featureProvider.layoutIfPossible(new LayoutContext(shape)); } + } diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java index 5dd544f9d..63a1976bf 100644 --- a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java +++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java @@ -12,21 +12,22 @@ package org.eclipse.etrice.ui.layout; import org.eclipse.emf.ecore.EObject; import org.eclipse.etrice.core.room.ActorClass; +import org.eclipse.etrice.core.room.ActorContainerClass; import org.eclipse.etrice.core.room.InterfaceItem; +import org.eclipse.etrice.core.room.Port; import org.eclipse.etrice.core.room.SAPoint; +import org.eclipse.etrice.core.room.SPPRef; import org.eclipse.etrice.core.room.SPPoint; import org.eclipse.etrice.ui.structure.editor.StructureEditor; import org.eclipse.etrice.ui.structure.support.ActorContainerRefSupport; +import org.eclipse.graphiti.mm.pictograms.Anchor; 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.ui.internal.parts.IPictogramElementEditPart; import de.cau.cs.kieler.core.kgraph.KNode; -import de.cau.cs.kieler.kiml.LayoutContext; -import de.cau.cs.kieler.kiml.config.VolatileLayoutConfig; import de.cau.cs.kieler.kiml.graphiti.KimlGraphitiUtil; -import de.cau.cs.kieler.kiml.options.LayoutOptions; import de.cau.cs.kieler.kiml.ui.diagram.LayoutMapping; import de.cau.cs.kieler.kiml.util.KimlUtil; @@ -70,16 +71,43 @@ public class StructureDiagramLayoutmanager extends ETriceDiagramLayoutManager { } } - /** the fixed minimal height of nodes. */ - public static final float MIN_HEIGHT = ActorContainerRefSupport.DEFAULT_SIZE_Y; - /** the fixed minimal width of shapes. */ - public static final float MIN_WIDHT = ActorContainerRefSupport.DEFAULT_SIZE_X; + @Override + protected Size getDefaultSize(Shape shape) { + Size defaultSize = new Size(); + + // This code sets same minimal default size for both Actor Class and + // Actor Container Ref + defaultSize.setHeight(ActorContainerRefSupport.MIN_SIZE_Y); + defaultSize.setWidth(ActorContainerRefSupport.MIN_SIZE_X); + + + /* + * This code sets default size differently for Actor Class and Actor Container + * Refs. This keeps the top-level container quite large on layout, which + * might not seem so pleasant, but is more closer to the model. + */ + /* + EObject modelObject = shape.getLink().getBusinessObjects().get(0); + if (modelObject instanceof ActorClass) { + defaultSize.setHeight(StructureClassSupport.DEFAULT_SIZE_Y); + defaultSize.setWidth(StructureClassSupport.DEFAULT_SIZE_X); + } else if (modelObject instanceof ActorContainerRef) { + defaultSize.setHeight(ActorContainerRefSupport.MIN_SIZE_Y); + defaultSize.setWidth(ActorContainerRefSupport.MIN_SIZE_X); + } else { + defaultSize.setHeight(MIN_HEIGHT); + defaultSize.setWidth(MIN_WIDHT); + }*/ + + return defaultSize; + } /** * {@inheritDoc} * * @author jayant */ + @Override protected KNode createNode(final LayoutMapping<PictogramElement> mapping, final KNode parentNode, final Shape shape) { KNode node = KimlUtil.createInitializedNode(); @@ -87,17 +115,16 @@ public class StructureDiagramLayoutmanager extends ETriceDiagramLayoutManager { setCurrentPositionAndSize(mapping, parentNode, node, shape); - VolatileLayoutConfig staticConfig = mapping - .getProperty(KimlGraphitiUtil.STATIC_CONFIG); - // FIXME find a way to specify the minimal size dynamically - - staticConfig.setValue(LayoutOptions.MIN_WIDTH, node, - LayoutContext.GRAPH_ELEM, MIN_WIDHT); - staticConfig.setValue(LayoutOptions.MIN_HEIGHT, node, - LayoutContext.GRAPH_ELEM, MIN_HEIGHT); - mapping.getGraphMap().put(node, shape); + // gather all connections connected to Internal ports in the diagram. + // It is of no use to ActorRefs as they do-not possess direct + // connection(They have all connections via port). + for (Anchor anchor : shape.getAnchors()) { + mapping.getProperty(KimlGraphitiUtil.CONNECTIONS).addAll( + anchor.getOutgoingConnections()); + } + return node; } @@ -107,11 +134,11 @@ public class StructureDiagramLayoutmanager extends ETriceDiagramLayoutManager { * @author jayant */ @Override - protected boolean isPort(Shape shape) { + public boolean isBoundaryPort(Shape shape) { EObject modelObject = shape.getLink().getBusinessObjects().get(0); - if (modelObject instanceof InterfaceItem + if ((modelObject instanceof InterfaceItem && !isInternal((InterfaceItem) modelObject)) || modelObject instanceof SPPoint - || modelObject instanceof SAPoint) + || modelObject instanceof SAPoint) return true; return false; @@ -123,7 +150,47 @@ public class StructureDiagramLayoutmanager extends ETriceDiagramLayoutManager { * @author jayant */ @Override - protected boolean isTopLevelBoundingBox(Shape shape) { + public boolean isInternalPort(Shape shape) { + EObject modelObject = shape.getLink().getBusinessObjects().get(0); + + if ((modelObject instanceof InterfaceItem && isInternal((InterfaceItem) modelObject))) + return true; + + return false; + } + + /* + * This method has been derived from + * org.eclipse.eTrice.ui.structure.InterfaceItem.FeatureProvider + */ + private static boolean isInternal(InterfaceItem item) { + if (item instanceof Port) { + Port port = (Port) item; + + // NB: the port's container might be a base class of the depicted + // actor class + ActorContainerClass acc = (ActorContainerClass) port.eContainer(); + if (acc instanceof ActorClass) { + ActorClass ac = (ActorClass) acc; + if (ac.getIntPorts().contains(port)) + return true; + } + } else if (item instanceof SPPRef) { + return false; + } else { + assert (false) : "unexpected sub type"; + } + + return false; + } + + /** + * {@inheritDoc} + * + * @author jayant + */ + @Override + public boolean isTopLevelBoundingBox(Shape shape) { EObject modelObject = shape.getLink().getBusinessObjects().get(0); if (modelObject instanceof ActorClass) return true; diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureLayoutCommand.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureLayoutCommand.java new file mode 100644 index 000000000..f3f4dde40 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureLayoutCommand.java @@ -0,0 +1,150 @@ +package org.eclipse.etrice.ui.layout; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.etrice.core.room.ActorContainerRef; +import org.eclipse.etrice.core.room.InterfaceItem; +import org.eclipse.etrice.ui.structure.support.InterfaceItemSupport; +import org.eclipse.graphiti.features.IFeatureProvider; +import org.eclipse.graphiti.features.context.impl.LayoutContext; +import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; +import org.eclipse.graphiti.mm.algorithms.Text; +import org.eclipse.graphiti.mm.algorithms.styles.Orientation; +import org.eclipse.graphiti.mm.pictograms.Anchor; +import org.eclipse.graphiti.mm.pictograms.ContainerShape; +import org.eclipse.graphiti.mm.pictograms.PictogramElement; +import org.eclipse.graphiti.services.Graphiti; +import org.eclipse.graphiti.services.IGaService; + +import de.cau.cs.kieler.core.kgraph.KNode; +import de.cau.cs.kieler.core.kgraph.KPort; + +public class StructureLayoutCommand extends ETriceLayoutCommand { + + public StructureLayoutCommand(TransactionalEditingDomain domain, + IFeatureProvider thefeatureProvider) { + super(domain, thefeatureProvider); + } + + /** + * {@inheritDoc} + * + * @author jayant + */ + @Override + protected void applyNodeLayout(KNode knode, PictogramElement pelem) { + + setCalculatedPositionAndSize(knode, knode.getParent(), + (ContainerShape) pelem); + + // Checking whether this node corresponds to an internal port or + // ActorContainerRef + EObject modelObject = pelem.getLink().getBusinessObjects().get(0); + if (modelObject instanceof InterfaceItem) { + // adjust label for internal port + adjustLabelForPort((ContainerShape) pelem); + } + + getFeatureProvider().layoutIfPossible(new LayoutContext(pelem)); + + }; + + /** + * {@inheritDoc} + * + * @author jayant + */ + @Override + protected void applyPortLayout(KPort kport, PictogramElement pelem) { + + ContainerShape shape = (ContainerShape) ((Anchor) pelem).getParent(); + + setCalculatedPositionAndSize(kport, kport.getNode(), shape); + + // adjust label for this (boundary)port + adjustLabelForPort(shape); + + getFeatureProvider().layoutIfPossible(new LayoutContext(shape)); + } + + /** + * Extracts relevant information and delegates it to + * {@link #adjustLabel(Text, int, int, int, int, int)} for proper adjustment + * of port label + * + * @param shape + * the Shape for the port + * + * @author jayant + */ + private static void adjustLabelForPort(ContainerShape shape) { + GraphicsAlgorithm ga = shape.getGraphicsAlgorithm(); + EObject boContainer = shape.getContainer().getLink().getBusinessObjects().get(0); + + // First make sure that the shape corresponds to a Port + EObject bo = shape.getLink().getBusinessObjects().get(0); + if ( bo instanceof InterfaceItem) { + // margin and size for bounding box (ActorClass ) + int margin = InterfaceItemSupport.MARGIN; + int size = InterfaceItemSupport.ITEM_SIZE; + + if (boContainer instanceof ActorContainerRef) { + // margin and size for ActorContainerRef + margin = InterfaceItemSupport.MARGIN_SMALL; + size = InterfaceItemSupport.ITEM_SIZE_SMALL; + } + + Text label = (Text) (shape.getChildren().get(0) + .getGraphicsAlgorithm()); + + adjustLabel(label, ga.getX(), ga.getY(), ga.getWidth(), margin, + size); + } + }; + + /** + * Sets correct port label position depending on the corresponding port + * position. + * + * @param label + * Text Graphics Algorithm to be placed + * @param x + * The x coordinate of the containing shape + * @param y + * The y coordinate of the containing shape + * @param width + * The width of the containing shape + * @param margin + * The margin of the containing shape + * @param size + * The size(length/width) of the port's visible graphics + * algorithm + * + */ + /* + * This method has been copied from InterfaceItemSuppot.FeatureProvider + * class since its visibility is not public there + */ + private static void adjustLabel(Text label, int x, int y, int width, + int margin, int size) { + Orientation align = Orientation.ALIGNMENT_CENTER; + label.setHorizontalAlignment(align); + + int pos = margin + size / 2; + + if (x <= margin) + align = Orientation.ALIGNMENT_LEFT; + else if ((width - margin) <= x) + align = Orientation.ALIGNMENT_RIGHT; + if (y <= margin) + pos = (margin - size) / 2; + + if (align != label.getHorizontalAlignment()) { + label.setHorizontalAlignment(align); + } + if (pos != label.getY()) { + IGaService gaService = Graphiti.getGaService(); + gaService.setLocationAndSize(label, 0, pos, 2 * margin, margin / 2); + } + } +} |