/** * Process an edge and its labels. * * @param edge an edge * @param edgeRouting the global edge routing setting */ private KVector processEdge(final KEdge edge, final EdgeRouting edgeRouting) { KEdgeLayout edgeLayout = edge.getData(KEdgeLayout.class); boolean sameHierarchy = edge.getSource().getParent() == edge.getTarget().getParent(); KVector maxv = new KVector(); KVectorChain bendPoints = edgeLayout.getProperty(LayoutOptions.BEND_POINTS); // we need at least two bend points, since the source point and target point must be included if (bendPoints != null && bendPoints.size() >= 2) { edgeLayout.applyVectorChain(bendPoints); } // determine maximal coordinates if (sameHierarchy) { for (KPoint point : edgeLayout.getBendPoints()) { maxv.x = Math.max(maxv.x, point.getX()); maxv.y = Math.max(maxv.y, point.getY()); } } // set the fixed position of the edge labels, or leave them as they are for (KLabel label : edge.getLabels()) { KShapeLayout labelLayout = label.getData(KShapeLayout.class); KVector pos = labelLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { labelLayout.applyVector(pos); } if (sameHierarchy) { maxv.x = Math.max(maxv.x, labelLayout.getXpos() + labelLayout.getWidth()); maxv.y = Math.max(maxv.y, labelLayout.getYpos() + labelLayout.getHeight()); } } return maxv; }
/** {@inheritDoc} */ @Override public void doLayout(final KNode layoutNode, final IKielerProgressMonitor progressMonitor) { progressMonitor.begin("Fixed Layout", 1); KShapeLayout parentLayout = layoutNode.getData(KShapeLayout.class); EdgeRouting edgeRouting = parentLayout.getProperty(LayoutOptions.EDGE_ROUTING); float maxx = 0, maxy = 0; for (KNode node : layoutNode.getChildren()) { KShapeLayout nodeLayout = node.getData(KShapeLayout.class); // set the fixed position of the node, or leave it as it is KVector pos = nodeLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { nodeLayout.applyVector(pos); // set the fixed size of the node // TODO Think about whether this makes sense with the new size constraint options. if (nodeLayout .getProperty(LayoutOptions.SIZE_CONSTRAINT) .contains(SizeConstraint.MINIMUM_SIZE)) { float width = nodeLayout.getProperty(LayoutOptions.MIN_WIDTH); float height = nodeLayout.getProperty(LayoutOptions.MIN_HEIGHT); if (width > 0 && height > 0) { KimlUtil.resizeNode(node, width, height, true, true); } } } maxx = Math.max(maxx, nodeLayout.getXpos() + nodeLayout.getWidth()); maxy = Math.max(maxy, nodeLayout.getYpos() + nodeLayout.getHeight()); // set the fixed position of the node labels, or leave them as they are for (KLabel label : node.getLabels()) { KShapeLayout labelLayout = label.getData(KShapeLayout.class); pos = labelLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { labelLayout.applyVector(pos); } maxx = Math.max(maxx, nodeLayout.getXpos() + labelLayout.getXpos() + labelLayout.getWidth()); maxy = Math.max(maxy, nodeLayout.getYpos() + labelLayout.getYpos() + labelLayout.getHeight()); } // set the fixed position of the ports, or leave them as they are for (KPort port : node.getPorts()) { KShapeLayout portLayout = port.getData(KShapeLayout.class); pos = portLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { portLayout.applyVector(pos); } float portx = nodeLayout.getXpos() + portLayout.getXpos(); float porty = nodeLayout.getYpos() + portLayout.getYpos(); maxx = Math.max(maxx, portx + portLayout.getWidth()); maxy = Math.max(maxy, porty + portLayout.getHeight()); // set the fixed position of the port labels, or leave them as they are for (KLabel label : port.getLabels()) { KShapeLayout labelLayout = label.getData(KShapeLayout.class); pos = labelLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { labelLayout.applyVector(pos); } maxx = Math.max(maxx, portx + labelLayout.getXpos() + labelLayout.getWidth()); maxy = Math.max(maxy, porty + labelLayout.getYpos() + labelLayout.getHeight()); } } // set fixed routing for the connected edges, or leave them as they are for (KEdge edge : node.getOutgoingEdges()) { KVector maxv = processEdge(edge, edgeRouting); maxx = Math.max(maxx, (float) maxv.x); maxy = Math.max(maxy, (float) maxv.y); } for (KEdge edge : node.getIncomingEdges()) { if (edge.getSource().getParent() != layoutNode) { KVector maxv = processEdge(edge, edgeRouting); maxx = Math.max(maxx, (float) maxv.x); maxy = Math.max(maxy, (float) maxv.y); } } } // if orthogonal routing is selected, determine the junction points if (edgeRouting == EdgeRouting.ORTHOGONAL) { for (KNode node : layoutNode.getChildren()) { for (KEdge edge : node.getOutgoingEdges()) { generateJunctionPoints(edge); } } } // set size of the parent node float borderSpacing = parentLayout.getProperty(LayoutOptions.BORDER_SPACING); if (borderSpacing < 0) { borderSpacing = DEF_BORDER_SPACING; } KInsets insets = parentLayout.getInsets(); float newWidth = maxx + borderSpacing + insets.getLeft() + insets.getRight(); float newHeight = maxy + borderSpacing + insets.getTop() + insets.getBottom(); KimlUtil.resizeNode(layoutNode, newWidth, newHeight, true, true); progressMonitor.done(); }