diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java new file mode 100644 index 0000000..db8bb5d --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java @@ -0,0 +1,17 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; +import graphicalrefactor.editor.Editor; + +public class DAGLayoutAction extends AbstractEditorAction { + + public DAGLayoutAction(Editor editor) { + super("DAG Layout", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + editor.setDAGLayout(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java index 4d51c71..0a0e3a1 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -15,14 +16,17 @@ import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGeometry; import com.mxgraph.model.mxGraphModel; +import com.mxgraph.model.mxIGraphModel; import com.mxgraph.util.mxConstants; import com.mxgraph.util.mxPoint; +import com.mxgraph.util.mxRectangle; import com.mxgraph.view.mxGraph; import algorithms.NecessityOfStoringResourceStates; import algorithms.SelectableDataTransfers; import algorithms.UpdateConflictCheck; import code.ast.CompilationUnit; +import graphicalrefactor.layouts.*; import models.Edge; import models.Node; import models.dataConstraintModel.ChannelGenerator; @@ -242,6 +246,17 @@ return graph; } + + public void setDAGLayout() { + Object parent = graph.getDefaultParent(); + graph.getModel().beginUpdate(); + try { + DAGLayout ctl = new DAGLayout(graph); + ctl.execute(parent); + } finally { + graph.getModel().endUpdate(); + } + } public void setTreeLayout() { Object parent = graph.getDefaultParent(); diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/layouts/DAGLayout.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/layouts/DAGLayout.java new file mode 100644 index 0000000..c09178c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/layouts/DAGLayout.java @@ -0,0 +1,148 @@ +package graphicalrefactor.layouts; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.mxgraph.layout.mxGraphLayout; +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGeometry; +import com.mxgraph.model.mxICell; +import com.mxgraph.model.mxIGraphModel; +import com.mxgraph.util.mxRectangle; +import com.mxgraph.view.mxCellState; +import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; + +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.IdentifierTemplate; + +public class DAGLayout extends mxGraphLayout { + + public DAGLayout(mxGraph arg0) { + super(arg0); + } + + public void execute(Object parent) { + mxIGraphModel model = graph.getModel(); + + model.beginUpdate(); + try { + List> map = new ArrayList>(); + List moved = new ArrayList<>(); + + for (int i = 0; i < model.getChildCount(parent); i++) { + + mxCell cell = (mxCell) model.getChildAt(parent, i); + + if (model.isVertex(cell)) { + mxGraphView view = graph.getView(); + mxCellState state = view.getState(cell); + + if (!"ellipse".equals(state.getStyle().get("shape")) && (cell.getEdgeCount() == 1)) { + List newline = new ArrayList(); + map.add(newline); + lines(map, cell); + } + } + } + + // ���בւ� + sort(map, 0, false); + + // layout + int count; + int skip = 0; + mxGraphView view = graph.getView(); + for (int i = 0; i < map.size(); i++) { + count = 0; + for (int j = 0; j < map.get(i).size(); j++) { + mxGeometry geom = (mxGeometry) map.get(i).get(j).getGeometry().clone(); + mxCellState state = view.getState(map.get(i).get(j)); + if (checkmoved(moved, map.get(i).get(j))) { + if ("ellipse".equals(state.getStyle().get("shape"))){ + geom.setX(50 + j*200); + } else { + geom.setX(100 + j*200); + } + geom.setY(100 + (i-skip)*100); + model.setGeometry(map.get(i).get(j), geom); + moved.add(map.get(i).get(j).getId()); + } else if (geom.getX() < 100 + j*150) { + if ("ellipse".equals(state.getStyle().get("shape"))){ + geom.setX(50 + j*200); + } else { + geom.setX(100 + j*200); + } + geom.setY(100 + (i-skip)*100); + model.setGeometry(map.get(i).get(j), geom); + } else { + count++; + } + } + if (count >= map.get(i).size())skip++; + } + + } finally { + model.endUpdate(); + } + } + + + public void lines(List> mapping, mxCell next) { + mapping.get(mapping.size()-1).add(next); + int tagcount = 0; + mxCell edge; + for (int i = 0; i < next.getEdgeCount(); i++) { + edge = (mxCell) next.getEdgeAt(i); + if (next != (mxCell) edge.getTarget() && ((mxCell) edge.getTarget() != null)) { + tagcount++; + if (tagcount > 1) { + List newline = new ArrayList(mapping.get(mapping.size()-1)); + while (newline.get(newline.size()-1).getId() != next.getId()) { + newline.remove(newline.size()-1); + } + mapping.add(newline); + lines(mapping, (mxCell) edge.getTarget()); + + } else { + lines(mapping, (mxCell) edge.getTarget()); + } + } + } + } + + public boolean checkmoved(List list, mxCell cell) { + for (int i = 0; i < list.size(); i++) { + if (list.get(i).equals(cell.getId()))return false; + } + return true; + } + + public void sort(List> map, int n, boolean check) { + int msize = -1; + int mnum = -1; + if (check) { + for (int i = n; i < map.size(); i++) { + if (map.get(i).size() > msize && (map.get(n-1).get(0).getId().equals(map.get(i).get(0).getId()))) { + mnum = i; + } + } + } else { + for (int i = n; i < map.size(); i++) { + if (map.get(i).size() > msize) { + mnum = i; + } + } + } + if (mnum >= 0) { + Collections.swap(map, n, mnum); + sort(map, n+1, true); + } else if(n < map.size()) { + sort(map, n+1, false); + } + } + + +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java index 1584119..e678111 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java @@ -7,6 +7,7 @@ import graphicalrefactor.actions.AbstractEditorAction; import graphicalrefactor.actions.CircleLayoutAction; +import graphicalrefactor.actions.DAGLayoutAction; import graphicalrefactor.actions.ExitAction; import graphicalrefactor.actions.OpenAction; import graphicalrefactor.actions.JavaPrototypeGenerateAction; @@ -24,6 +25,7 @@ private OpenAction openAction = null; private JavaPrototypeGenerateAction javaPrototypeGenerateAction = null; private JerseyPrototypeGenerateAction jerseyPrototypeGenerateAction = null; + private DAGLayoutAction dagLayoutAction = null; private TreeLayoutAction treeLayoutAction = null; private CircleLayoutAction circleLayoutAction = null; @@ -38,6 +40,7 @@ menu.add(new ExitAction()); menu = add(new JMenu("Layout")); + menu.add(dagLayoutAction = new DAGLayoutAction(graphicalModelRefactor.getEditor())); menu.add(treeLayoutAction = new TreeLayoutAction(graphicalModelRefactor.getEditor())); menu.add(circleLayoutAction = new CircleLayoutAction(graphicalModelRefactor.getEditor()));