/*
* Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.eclipse.flow.common.editor.editpart;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.drools.eclipse.flow.common.editor.editpart.figure.ElementFigure;
import org.eclipse.draw2d.AbsoluteBendpoint;
import org.eclipse.draw2d.Bendpoint;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.graph.DirectedGraph;
import org.eclipse.draw2d.graph.DirectedGraphLayout;
import org.eclipse.draw2d.graph.Edge;
import org.eclipse.draw2d.graph.Node;
import org.eclipse.draw2d.graph.NodeList;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
public class DirectedGraphLayoutVisitor {
private Map<AbstractGraphicalEditPart, Object> partToNodesMap;
private DirectedGraph graph;
public void layoutDiagram(ProcessEditPart diagram) {
partToNodesMap = new HashMap<AbstractGraphicalEditPart, Object>();
graph = new DirectedGraph();
addNodes(diagram);
if (graph.nodes.size() > 0) {
addEdges(diagram);
new DirectedGraphLayout().visit(graph);
applyResults(diagram);
}
}
protected void addNodes(ProcessEditPart diagram) {
for (int i = 0; i < diagram.getChildren().size(); i++) {
ElementEditPart elementEditPart = (ElementEditPart) diagram.getChildren().get(i);
addNodes(elementEditPart);
}
}
@SuppressWarnings("unchecked")
protected void addNodes(ElementEditPart elementEditPart) {
Node n = new Node(elementEditPart);
n.width = elementEditPart.getFigure().getPreferredSize(400, 300).width;
n.height = elementEditPart.getFigure().getPreferredSize(400, 300).height;
n.setPadding(new Insets(10, 8, 10, 12));
partToNodesMap.put(elementEditPart, n);
graph.nodes.add(n);
}
protected void addEdges(ProcessEditPart diagram) {
for (int i = 0; i < diagram.getChildren().size(); i++) {
ElementEditPart elementEditPart = (ElementEditPart) diagram.getChildren().get(i);
addEdges(elementEditPart);
}
}
protected void addEdges(ElementEditPart elementEditPart) {
@SuppressWarnings("unchecked")
List<ElementConnectionEditPart> outgoing = elementEditPart.getSourceConnections();
for (int i = 0; i < outgoing.size(); i++) {
ElementConnectionEditPart connectionPart = outgoing.get(i);
addEdges(connectionPart);
}
}
@SuppressWarnings("unchecked")
protected void addEdges(ElementConnectionEditPart connectionPart) {
Node source = (Node) partToNodesMap.get(connectionPart.getSource());
Node target = (Node) partToNodesMap.get(connectionPart.getTarget());
Edge e = new Edge(connectionPart, source, target);
e.weight = 2;
graph.edges.add(e);
partToNodesMap.put(connectionPart, e);
}
protected void applyResults(ProcessEditPart diagram) {
applyChildrenResults(diagram);
}
protected void applyChildrenResults(ProcessEditPart diagram) {
for (int i = 0; i < diagram.getChildren().size(); i++) {
ElementEditPart elementEditPart = (ElementEditPart) diagram.getChildren().get(i);
applyResults(elementEditPart);
}
}
protected void applyOwnResults(ProcessEditPart diagram) {
}
public void applyResults(ElementEditPart elementEditPart) {
Node n = (Node) partToNodesMap.get(elementEditPart);
ElementFigure elementFigure = (ElementFigure) elementEditPart.getFigure();
Rectangle bounds = new Rectangle(n.x, n.y, elementFigure.getPreferredSize().width,
elementFigure.getPreferredSize().height);
elementFigure.setBounds(bounds);
for (int i = 0; i < elementEditPart.getSourceConnections().size(); i++) {
ElementConnectionEditPart connectionPart = (ElementConnectionEditPart) elementEditPart.getSourceConnections().get(i);
applyResults(connectionPart);
}
}
protected void applyResults(ElementConnectionEditPart connectionPart) {
Edge e = (Edge) partToNodesMap.get(connectionPart);
NodeList nodes = e.vNodes;
PolylineConnection conn = (PolylineConnection) connectionPart.getConnectionFigure();
conn.setTargetDecoration(new PolygonDecoration());
if (nodes != null) {
List<Bendpoint> bends = new ArrayList<Bendpoint>();
for (int i = 0; i < nodes.size(); i++) {
Node vn = nodes.getNode(i);
int x = vn.x;
int y = vn.y;
if (e.isFeedback()) {
bends.add(new AbsoluteBendpoint(x, y + vn.height));
bends.add(new AbsoluteBendpoint(x, y));
} else {
bends.add(new AbsoluteBendpoint(x, y));
bends.add(new AbsoluteBendpoint(x, y + vn.height));
}
}
conn.setRoutingConstraint(bends);
} else {
conn.setRoutingConstraint(Collections.EMPTY_LIST);
}
}
}