summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayant Gupta2012-07-22 20:40:07 -0400
committerJayant Gupta2012-08-20 14:49:22 -0400
commit9c4538525d003463a4cf00c8e32f6d9d324ce047 (patch)
treefa81eb2d1d139f3fa618bafc7bc83e13f81cd2de
parentaab0e7dbfa4dc0c0c071673686a94b5cc279ab63 (diff)
downloadorg.eclipse.etrice-9c4538525d003463a4cf00c8e32f6d9d324ce047.zip
org.eclipse.etrice-9c4538525d003463a4cf00c8e32f6d9d324ce047.tar.gz
org.eclipse.etrice-9c4538525d003463a4cf00c8e32f6d9d324ce047.tar.xz
Rebuild on Juno and solved some layout issues
1. Port labels corrected. 2. Heuristic for node sizes developed. 3. Context sensitive layout provided. 4. Internal Port Layout improved. 5. Default Layout options set. Change-Id: I1c2eb4bbc39f79d81c39c65c220ac2bc2015cd8d
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/plugin.xml23
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java70
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorLayoutCommand.java128
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java181
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java55
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java107
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureLayoutCommand.java150
7 files changed, 617 insertions, 97 deletions
diff --git a/plugins/org.eclipse.etrice.ui.layout/plugin.xml b/plugins/org.eclipse.etrice.ui.layout/plugin.xml
index 58435d8..8528c91 100644
--- a/plugins/org.eclipse.etrice.ui.layout/plugin.xml
+++ b/plugins/org.eclipse.etrice.ui.layout/plugin.xml
@@ -12,5 +12,28 @@
priority="1">
</manager>
</extension>
+ <extension
+ point="de.cau.cs.kieler.kiml.layoutInfo">
+ <option
+ class="org.eclipse.etrice.core.room.ActorClass"
+ option="de.cau.cs.kieler.borderSpacing"
+ value="50">
+ </option>
+ <option
+ class="org.eclipse.etrice.core.room.ActorClass"
+ option="de.cau.cs.kieler.spacing"
+ value="50">
+ </option>
+ <option
+ class="org.eclipse.etrice.core.room.StateGraph"
+ option="de.cau.cs.kieler.borderSpacing"
+ value="30">
+ </option>
+ <option
+ class="org.eclipse.etrice.core.room.StateGraph"
+ option="de.cau.cs.kieler.spacing"
+ value="50">
+ </option>
+ </extension>
</plugin>
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 63329e1..1bb0d29 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 0000000..26ee581
--- /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 a5a83b7..9cf2a5f 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 c09dabf..5d33d8a 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 5dd544f..63a1976 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 0000000..f3f4dde
--- /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);
+ }
+ }
+}