diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/auto/KielerAutoLayouter.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/auto/KielerAutoLayouter.java index 742a6dc7a1a62f9d44a0d07cf688b0cba512990c..27ffc2619d979cf37697cb49874dcd1c869f0305 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/auto/KielerAutoLayouter.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/auto/KielerAutoLayouter.java @@ -82,7 +82,7 @@ import de.cau.cs.kieler.klay.layered.properties.Properties; * @author offtermatt, barner * @author $Author$ * @version $Rev$ - * @ConQAT.Rating YELLOW Hash: 8BE55A0C36B936EF103CD3350B857042 + * @ConQAT.Rating YELLOW Hash: 36F683174E3AD8ADC2DDDC27D7C75183 */ public class KielerAutoLayouter implements IAutoLayouter { @@ -113,38 +113,40 @@ public class KielerAutoLayouter implements IAutoLayouter { boolean avUpdateEnabled = AnnotationViewPartBase.isUpdateEnabled(); AnnotationViewPartBase.setUpdateEnabled(false); - KNode parentNode = createKIELERGraph(hierarchicElement); + KNode rootNode = createKIELERGraph(hierarchicElement); - KShapeLayout par = parentNode.getData(KShapeLayout.class); - par.setProperty(LayoutOptions.DIRECTION, Direction.RIGHT); - par.setProperty(LayoutOptions.INTERACTIVE, true); - par.setProperty(Properties.FEEDBACK_EDGES, true); - par.setProperty(Properties.INTERACTIVE_REFERENCE_POINT, InteractiveReferencePoint.TOP_LEFT); + KShapeLayout rootNodeLayout = rootNode.getData(KShapeLayout.class); + rootNodeLayout.setProperty(LayoutOptions.DIRECTION, Direction.RIGHT); + rootNodeLayout.setProperty(LayoutOptions.INTERACTIVE, true); + rootNodeLayout.setProperty(Properties.FEEDBACK_EDGES, true); + rootNodeLayout.setProperty(Properties.INTERACTIVE_REFERENCE_POINT, + InteractiveReferencePoint.TOP_LEFT); AbstractLayoutProvider layoutProvider = new LayeredLayoutProvider(); IKielerProgressMonitor progressMonitor = new BasicProgressMonitor(); - layoutProvider.doLayout(parentNode, progressMonitor); + layoutProvider.doLayout(rootNode, progressMonitor); - applyLayout(parentNode, hierarchicElement); + applyLayout(rootNode, hierarchicElement); AnnotationViewPartBase.setUpdateEnabled(avUpdateEnabled); } /** - * Rounds a given {@code float} value and decreases the value until it is a multiple of the grid + * Truncates a given {@code float} value and decreases the value until it is a multiple of the + * grid * size. * * @param f * {@code float} to process * - * @return Given float value, rounded and aligned to the underlying grid. + * @return Given float value, truncated and aligned to the underlying grid. */ - private int roundSnap2Grid(float f) { - return roundSnap2Grid(f, false); + private int truncateSnap2Grid(float f) { + return truncateSnap2Grid(f, false); } /** - * Rounds a given {@code float} value and aligns it the grid size. + * Truncates a given {@code float} value and aligns it the grid size. * * @param f * {@code float} to process @@ -152,9 +154,9 @@ public class KielerAutoLayouter implements IAutoLayouter { * @param enlarge * Whether to enlarge the given value while aligning to the grid. * - * @return Given float value, rounded and aligned to the underlying grid. + * @return Given float value, truncated and aligned to the underlying grid. */ - private int roundSnap2Grid(float f, boolean enlarge) { + private int truncateSnap2Grid(float f, boolean enlarge) { int rval = (int)f; final int deviationFromGrid = rval % DEFAULT_GRID_SIZE; @@ -181,30 +183,30 @@ public class KielerAutoLayouter implements IAutoLayouter { topLevelElement.runAsCommand(() -> { filterBendPoints(hierarchicElement); - for(IHierarchicElement curElement : hierarchicElement.getContainedElements()) { - KNode curNode = modelElementsToKNodes.get(curElement); - KShapeLayout curLayout = curNode.getData(KShapeLayout.class); - LayoutDataUtils.setNodeLayoutData((ILayoutedModelElement)curElement, - roundSnap2Grid(curLayout.getXpos()), roundSnap2Grid(curLayout.getYpos()), - roundSnap2Grid(curLayout.getWidth(), true), - roundSnap2Grid(curLayout.getHeight(), true)); + for(IHierarchicElement element : hierarchicElement.getContainedElements()) { + KNode kNode = modelElementsToKNodes.get(element); + KShapeLayout kNodeLayout = kNode.getData(KShapeLayout.class); + LayoutDataUtils.setNodeLayoutData((ILayoutedModelElement)element, + truncateSnap2Grid(kNodeLayout.getXpos()), + truncateSnap2Grid(kNodeLayout.getYpos()), + truncateSnap2Grid(kNodeLayout.getWidth(), true), + truncateSnap2Grid(kNodeLayout.getHeight(), true)); } - for(Entry<IConnection, KEdge> curEntry : connectionsToKEdges) { - KEdge curEdge = curEntry.getValue(); - IConnection curConnection = curEntry.getKey(); - KEdgeLayout curLayout = curEdge.getData(KEdgeLayout.class); - for(KPoint k : curLayout.getBendPoints()) { - LayoutDataUIUtils.addBendPointToConnection( - (ILayoutedModelElement)curConnection, roundSnap2Grid(k.getX()), - roundSnap2Grid(k.getY())); + for(Entry<IConnection, KEdge> entry : connectionsToKEdges) { + KEdge kEdge = entry.getValue(); + IConnection connection = entry.getKey(); + KEdgeLayout kEdgeLayout = kEdge.getData(KEdgeLayout.class); + for(KPoint kPoint : kEdgeLayout.getBendPoints()) { + LayoutDataUIUtils.addBendPointToConnection((ILayoutedModelElement)connection, + truncateSnap2Grid(kPoint.getX()), truncateSnap2Grid(kPoint.getY())); } } - setPositionsForPorts(outboundConnectorsToKPorts); - setPositionsForPorts(inboundConnectorsToKPorts); - setPositionsForGlobalPorts(globalInboundConnectorsToKPorts); - setPositionsForGlobalPorts(globalOutboundConnectorsToKPorts); + setPositionsForConnectors(outboundConnectorsToKPorts); + setPositionsForConnectors(inboundConnectorsToKPorts); + setPositionsForGlobalConnectors(globalInboundConnectorsToKPorts); + setPositionsForGlobalConnectors(globalOutboundConnectorsToKPorts); }); } @@ -213,17 +215,17 @@ public class KielerAutoLayouter implements IAutoLayouter { * {@link IConnector}s. Global means in this case that the {@link IConnector}s do not have a * corresponding node, i.e. because they contain connections to a higher-level model. * - * @param globalPorts + * @param globalConnectors * A bijection from {@link IConnector}s to {@link KPort}s */ - private void setPositionsForGlobalPorts(EMap<IConnector, KPort> globalPorts) { - for(Entry<IConnector, KPort> i : globalPorts) { - IConnector port = i.getKey(); - KPort p = i.getValue(); - KNode temp = p.getNode(); - KShapeLayout lay = temp.getData(KShapeLayout.class); - setNodePosition((ILayoutedModelElement)port, roundSnap2Grid(lay.getXpos()), - roundSnap2Grid(lay.getYpos())); + private void setPositionsForGlobalConnectors(EMap<IConnector, KPort> globalConnectors) { + for(Entry<IConnector, KPort> entry : globalConnectors) { + IConnector connector = entry.getKey(); + KPort kPort = entry.getValue(); + KNode tempNode = kPort.getNode(); + KShapeLayout kLayout = tempNode.getData(KShapeLayout.class); + setNodePosition((ILayoutedModelElement)connector, truncateSnap2Grid(kLayout.getXpos()), + truncateSnap2Grid(kLayout.getYpos())); } } @@ -232,15 +234,15 @@ public class KielerAutoLayouter implements IAutoLayouter { * {@link IConnector}s must have corresponding nodes, i.e. they can not contain an * {@link IConnection} to a higher-level model. * - * @param ports + * @param connectors * A bijection from {@link IConnector}s to {@link KPort}s. */ - private void setPositionsForPorts(EMap<IConnector, KPort> ports) { - for(Entry<IConnector, KPort> ic : ports) { - KPort kp = ic.getValue(); - IConnector port = ic.getKey(); - KShapeLayout portLayout = kp.getData(KShapeLayout.class); - PortSide side = portLayout.getProperty(LayoutOptions.PORT_SIDE); + private void setPositionsForConnectors(EMap<IConnector, KPort> connectors) { + for(Entry<IConnector, KPort> entry : connectors) { + KPort kPort = entry.getValue(); + IConnector connector = entry.getKey(); + KShapeLayout kLayout = kPort.getData(KShapeLayout.class); + PortSide side = kLayout.getProperty(LayoutOptions.PORT_SIDE); EOrientation orientation = null; switch(side) { case NORTH: @@ -257,8 +259,8 @@ public class KielerAutoLayouter implements IAutoLayouter { break; } - setStickyConnectorLayoutData((ILayoutedModelElement)port, orientation, - roundSnap2Grid((portLayout.getYpos()))); + setStickyConnectorLayoutData((ILayoutedModelElement)connector, orientation, + truncateSnap2Grid((kLayout.getYpos()))); } } @@ -268,12 +270,10 @@ public class KielerAutoLayouter implements IAutoLayouter { * @param hierarchicElement */ private void filterBendPoints(IHierarchicElement hierarchicElement) { - EList<IConnection> clears = hierarchicElement.getConnections(); - for(IConnection c : clears) { - EList<ILayoutData> l = ((ILayoutedModelElement)c).getLayoutData(); - for(ILayoutData i : l) { - if(i instanceof Points || i instanceof PointsImpl) { - ((Points)i).getPoints().clear(); + for(IConnection connection : hierarchicElement.getConnections()) { + for(ILayoutData layoutData : ((ILayoutedModelElement)connection).getLayoutData()) { + if(layoutData instanceof Points || layoutData instanceof PointsImpl) { + ((Points)layoutData).getPoints().clear(); } } } @@ -291,7 +291,7 @@ public class KielerAutoLayouter implements IAutoLayouter { */ private KNode createKIELERGraph(IHierarchicElement hierarchicElement) { - KNode parentNode = KimlUtil.createInitializedNode(); + KNode rootNode = KimlUtil.createInitializedNode(); modelElementsToKNodes = new BasicEMap<IHierarchicElement, KNode>(); outboundConnectorsToKPorts = new BasicEMap<IConnector, KPort>(); @@ -299,98 +299,97 @@ public class KielerAutoLayouter implements IAutoLayouter { connectionsToKEdges = new BasicEMap<IConnection, KEdge>(); undirectedConnectorsToKPorts = new BasicEMap<IConnector, KPort>(); - // create nodes - for(IHierarchicElement curElement : hierarchicElement.getContainedElements()) { + // Create nodes + for(IHierarchicElement currentChild : hierarchicElement.getContainedElements()) { - if(!(curElement instanceof ILayoutedModelElement)) { + if(!(currentChild instanceof ILayoutedModelElement)) { continue; } - KNode curKNode = KimlUtil.createInitializedNode(); + KNode kNode = KimlUtil.createInitializedNode(); - KShapeLayout curLayout = curKNode.getData(KShapeLayout.class); + KShapeLayout kNodeLayout = kNode.getData(KShapeLayout.class); - EList<IConnector> inputPorts = new BasicEList<IConnector>(); - EList<IConnector> outputPorts = new BasicEList<IConnector>(); - EList<IConnector> genericPorts = new BasicEList<IConnector>(); + EList<IConnector> inputConnectors = new BasicEList<IConnector>(); + EList<IConnector> outputConnectors = new BasicEList<IConnector>(); + EList<IConnector> undirectedConnectors = new BasicEList<IConnector>(); - EList<IConnector> ports = curElement.getConnectors(); - for(IConnector curConnector : ports) { - if(curConnector instanceof EntryConnectorBase) { - inputPorts.add(curConnector); - } else if(curConnector instanceof ExitConnectorBase) { - outputPorts.add(curConnector); + for(IConnector connector : currentChild.getConnectors()) { + if(connector instanceof EntryConnectorBase) { + inputConnectors.add(connector); + } else if(connector instanceof ExitConnectorBase) { + outputConnectors.add(connector); } else { - outputPorts.add(curConnector); - genericPorts.add(curConnector); + outputConnectors.add(connector); + undirectedConnectors.add(connector); } } - Dimension dimension = getNodeSize((ILayoutedModelElement)curElement); - - int portNmbr = Math.max(inputPorts.size(), outputPorts.size()); - curLayout.setHeight(Math.max((1 + 2 * portNmbr) * DEFAULT_CONNECTOR_SIZE, - roundSnap2Grid(dimension.getHeight(), true))); - curLayout.setWidth(Math.max(DEFAULT_SHAPE_MINIMUM_HEIGHT, - roundSnap2Grid(dimension.getWidth(), true))); - - curKNode.setParent(parentNode); - modelElementsToKNodes.put(curElement, curKNode); - for(IConnector curPort : outputPorts) { - KPort k = createKPortFromIConnector(curPort, curKNode, outboundConnectorsToKPorts); - if(genericPorts.contains(curPort)) { - undirectedConnectorsToKPorts.put(curPort, k); + // Adjust size of node to number of connectors + Dimension dimension = getNodeSize((ILayoutedModelElement)currentChild); + int numConnectors = Math.max(inputConnectors.size(), outputConnectors.size()); + kNodeLayout.setHeight(Math.max((1 + 2 * numConnectors) * DEFAULT_CONNECTOR_SIZE, + truncateSnap2Grid(dimension.getHeight(), true))); + kNodeLayout.setWidth(Math.max(DEFAULT_SHAPE_MINIMUM_HEIGHT, + truncateSnap2Grid(dimension.getWidth(), true))); + + kNode.setParent(rootNode); + modelElementsToKNodes.put(currentChild, kNode); + for(IConnector connector : outputConnectors) { + KPort k = createKPortFromIConnector(connector, kNode, outboundConnectorsToKPorts); + if(undirectedConnectors.contains(connector)) { + undirectedConnectorsToKPorts.put(connector, k); } } - for(IConnector curPort : inputPorts) { - createKPortFromIConnector(curPort, curKNode, inboundConnectorsToKPorts); + for(IConnector connector : inputConnectors) { + createKPortFromIConnector(connector, kNode, inboundConnectorsToKPorts); } } - // create virtual nodes for global ports + // Create virtual nodes for global ports globalInboundConnectorsToKPorts = new BasicEMap<IConnector, KPort>(); globalOutboundConnectorsToKPorts = new BasicEMap<IConnector, KPort>(); - for(IConnector curPort : hierarchicElement.getConnectors()) { - KNode virtual = KimlUtil.createInitializedNode(); - KShapeLayout virtualLayout = virtual.getData(KShapeLayout.class); - virtualLayout.setHeight(DEFAULT_CONNECTOR_SIZE); - virtualLayout.setWidth(2 * DEFAULT_CONNECTOR_SIZE); - virtual.setParent(parentNode); - - KPort k = KimlUtil.createInitializedPort(); - k.setNode(virtual); - if(curPort instanceof ExitConnectorBase) { - globalOutboundConnectorsToKPorts.put(curPort, k); + for(IConnector connector : hierarchicElement.getConnectors()) { + KNode kNodeVirtual = KimlUtil.createInitializedNode(); + KShapeLayout kNodeVirtualLayout = kNodeVirtual.getData(KShapeLayout.class); + kNodeVirtualLayout.setHeight(DEFAULT_CONNECTOR_SIZE); + kNodeVirtualLayout.setWidth(2 * DEFAULT_CONNECTOR_SIZE); + kNodeVirtual.setParent(rootNode); + + KPort kPort = KimlUtil.createInitializedPort(); + kPort.setNode(kNodeVirtual); + if(connector instanceof ExitConnectorBase) { + globalOutboundConnectorsToKPorts.put(connector, kPort); } else { - globalInboundConnectorsToKPorts.put(curPort, k); - outboundConnectorsToKPorts.put(curPort, k); + globalInboundConnectorsToKPorts.put(connector, kPort); + outboundConnectorsToKPorts.put(connector, kPort); } } - // create edges - for(Entry<IConnector, KPort> out : outboundConnectorsToKPorts) { - for(IConnection ic : out.getKey().getOutgoing()) { - KEdge curEdge = KimlUtil.createInitializedEdge(); - KPort sourceport = out.getValue(); - - curEdge.setSource(sourceport.getNode()); - curEdge.setSourcePort(sourceport); - sourceport.getEdges().add(curEdge); - KPort targetport = inboundConnectorsToKPorts.get(ic.getTarget()); - if(targetport == null) { - targetport = globalOutboundConnectorsToKPorts.get(ic.getTarget()); + // Create edges + for(Entry<IConnector, KPort> entry : outboundConnectorsToKPorts) { + for(IConnection connection : entry.getKey().getOutgoing()) { + KEdge kEdge = KimlUtil.createInitializedEdge(); + KPort kSourcePort = entry.getValue(); + + kEdge.setSource(kSourcePort.getNode()); + kEdge.setSourcePort(kSourcePort); + kSourcePort.getEdges().add(kEdge); + KPort kTargetPort = inboundConnectorsToKPorts.get(connection.getTarget()); + if(kTargetPort == null) { + kTargetPort = globalOutboundConnectorsToKPorts.get(connection.getTarget()); } - if(targetport == null) { - targetport = undirectedConnectorsToKPorts.get(ic.getTarget()); + if(kTargetPort == null) { + kTargetPort = undirectedConnectorsToKPorts.get(connection.getTarget()); } - curEdge.setTargetPort(targetport); - curEdge.setTarget(targetport.getNode()); - targetport.getEdges().add(curEdge); - connectionsToKEdges.put(ic, curEdge); + kEdge.setTargetPort(kTargetPort); + kEdge.setTarget(kTargetPort.getNode()); + kTargetPort.getEdges().add(kEdge); + connectionsToKEdges.put(connection, kEdge); } } - return parentNode; + return rootNode; } /** @@ -400,21 +399,21 @@ public class KielerAutoLayouter implements IAutoLayouter { * * @param connector * {@link IConnector} to be converted to {@link KPort} - * @param knode + * @param kNode * {@link KNode} that will contain the newly created {@link KPort} * @param connectorsToKPorts * Map between {@link IConnector}s and {@link KPort}s. * - * @return {@link KNode} represeting the given {@link IConnector}. + * @return {@link KNode} representing the given {@link IConnector}. */ - private KPort createKPortFromIConnector(IConnector connector, KNode knode, + private KPort createKPortFromIConnector(IConnector connector, KNode kNode, EMap<IConnector, KPort> connectorsToKPorts) { - KPort k = KimlUtil.createInitializedPort(); - k.setNode(knode); - KShapeLayout portLayout = k.getData(KShapeLayout.class); - portLayout.setHeight(DEFAULT_CONNECTOR_SIZE); + KPort kPort = KimlUtil.createInitializedPort(); + kPort.setNode(kNode); + KShapeLayout kPortLayout = kPort.getData(KShapeLayout.class); + kPortLayout.setHeight(DEFAULT_CONNECTOR_SIZE); - connectorsToKPorts.put(connector, k); - return k; + connectorsToKPorts.put(connector, kPort); + return kPort; } }