001: package org.drools.eclipse.editors.rete;
002:
003: import java.util.HashSet;
004: import java.util.Iterator;
005: import java.util.List;
006: import java.util.Set;
007:
008: import org.drools.eclipse.editors.rete.model.Connection;
009: import org.drools.eclipse.editors.rete.model.ReteGraph;
010: import org.drools.reteoo.BaseVertex;
011: import org.eclipse.draw2d.geometry.Point;
012:
013: /**
014: * Factory methods for calculating and layouting reteoo graph
015: *
016: */
017: public class ReteooLayoutFactory {
018:
019: /**
020: * Calculates layouting for provided graph.
021: *
022: * @param root graph root vertex
023: *
024: * @return Optimally layouted rows from provided graph
025: */
026: public static RowList calculateReteRows(BaseVertex root) {
027: RowList rowList;
028: rowList = new RowList();
029:
030: rowList.add(0, root);
031:
032: int curRow = 0;
033:
034: final Set seenVertices = new HashSet();
035: seenVertices.add(root);
036:
037: while (curRow < rowList.getDepth()) {
038: final List rowVertices = rowList.get(curRow).getVertices();
039:
040: for (final Iterator rowNodeIter = rowVertices.iterator(); rowNodeIter
041: .hasNext();) {
042: final BaseVertex rowNode = (BaseVertex) rowNodeIter
043: .next();
044:
045: final List edges = rowNode.getSourceConnections();
046:
047: for (final Iterator edgeIter = edges.iterator(); edgeIter
048: .hasNext();) {
049:
050: final Connection edge = (Connection) edgeIter
051: .next();
052: final BaseVertex destNode = edge
053: .getOpposite(rowNode);
054:
055: if (!seenVertices.contains(destNode)) {
056: rowList.add(curRow + 1, destNode);
057: seenVertices.add(destNode);
058: }
059: }
060:
061: seenVertices.add(rowNode);
062: }
063:
064: ++curRow;
065: }
066:
067: rowList.optimize();
068:
069: return rowList;
070: }
071:
072: /**
073: * Adds all vertices from rowList to the graph.
074: *
075: * @param graph
076: * @param rowList
077: */
078: public static void layoutRowList(ReteGraph graph, RowList rowList) {
079: new LayoutCalculator(graph, rowList);
080: }
081:
082: private static class LayoutCalculator {
083:
084: public final static String COORDS = "drools.LayoutCalculator.coords";
085:
086: private static final int COLUMN_SPACE = 40;
087: private static final int ROW_HEIGHT_MULTIPLIER = 6;
088:
089: private RowList rowList;
090:
091: private int columnWidth;
092: private int rowHeight;
093:
094: private ReteGraph graph;
095:
096: private LayoutCalculator(final ReteGraph graph,
097: final RowList rowList) {
098: this .graph = graph;
099: this .rowList = rowList;
100: computeSize();
101:
102: List vertices = getGraph().getChildren();
103: Iterator iter = vertices.iterator();
104: while (iter.hasNext()) {
105: BaseVertex v = (BaseVertex) iter.next();
106: initialize_local_vertex(v);
107: }
108:
109: }
110:
111: private void computeSize() {
112: final List vertices = getGraph().getChildren();
113:
114: for (final Iterator vertexIter = vertices.iterator(); vertexIter
115: .hasNext();) {
116: final BaseVertex vertex = (BaseVertex) vertexIter
117: .next();
118:
119: final int width = vertex.getSize().width;
120: final int height = vertex.getSize().height;
121:
122: if (width > this .columnWidth) {
123: this .columnWidth = width;
124: }
125:
126: if (height > this .rowHeight) {
127: this .rowHeight = height;
128: }
129: }
130:
131: this .columnWidth = this .columnWidth
132: + LayoutCalculator.COLUMN_SPACE;
133: }
134:
135: private void initialize_local_vertex(final BaseVertex vertex) {
136: final int row = this .rowList.getRow(vertex);
137: final int col = this .rowList.getColumn(vertex);
138:
139: final int rowWidth = this .rowList.getWidth(row);
140:
141: final int columnWidthPx = columnWidth;
142: final int rowHeightPx = rowHeight;
143:
144: double x = (col * columnWidthPx);
145: double y = (row * (rowHeightPx * LayoutCalculator.ROW_HEIGHT_MULTIPLIER));
146:
147: x = x + (columnWidthPx / 2)
148: - ((rowWidth - 1) * (columnWidthPx / 2));
149: y = y + (rowHeightPx / 2) + 3;
150:
151: vertex.setLocation(new Point(x, y));
152: }
153:
154: private ReteGraph getGraph() {
155: return graph;
156: }
157: }
158:
159: }
|