/* This file is part of Green. * * Copyright (C) 2005 The Research Foundation of State University of New York * All Rights Under Copyright Reserved, The Research Foundation of S.U.N.Y. * * Green is free software, licensed under the terms of the Eclipse * Public License, version 1.0. The license is available at * http://www.eclipse.org/legal/epl-v10.html */ /** * */ package edu.buffalo.cse.green.editor.model.commands; import java.util.List; import java.util.Vector; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.gef.commands.Command; import ccvisu.CCVisu; import ccvisu.GraphData; import ccvisu.GraphEdgeInt; import ccvisu.GraphVertex; import ccvisu.Minimizer; import edu.buffalo.cse.green.editor.DiagramEditor; import edu.buffalo.cse.green.editor.controller.AbstractPart; import edu.buffalo.cse.green.editor.model.AbstractModel; import edu.buffalo.cse.green.editor.model.RelationshipModel; import edu.buffalo.cse.green.editor.model.RootModel; import edu.buffalo.cse.green.editor.model.TypeModel; /** * @author zgwang * */ public class AutoArrangeCommand extends Command { private int[][] opos; private int[][] npos; private Vector<TypeModel> _m; /** * */ public AutoArrangeCommand() { _m = new Vector<TypeModel>(); } public void undo() { for( int i=0; i<_m.size(); i++) _m.get(i).setLocation(opos[i][0], opos[i][1]); } public void redo() { for( int i=0; i<_m.size(); i++) _m.get(i).setLocation(npos[i][0], npos[i][1]); } public void execute() { DiagramEditor editor = DiagramEditor.getActiveEditor(); RootModel root = editor.getRootModel(); // List<AbstractModel> allModels = root.getChildren(); List<RelationshipModel> rels = root.getRelationships(); /* * Dimension dim = m.getSize(); if(dim.height == -1 && dim.width == -1) { //Box is default size, need to get real size instead. dim = f.getLayoutManager().getPreferredSize(f.getParent(), -1, -1); } * for(AbstractModel m : allModels) { IFigure f = activeEditor.getRootPart().getPartFromModel(m).getFigure(); * */ /*for(RelationshipModel relModel : rels) { String[] interfaces = relModel.getSourceType().getSuperInterfaceNames(); IType source = relModel.getSourceType(); IType target = relModel.getTargetType(); TypeModel sModel = root.getModelFromType(source); TypeModel tModel = root.getModelFromType(target); System.out.println(sModel.getLocation()); System.out.println(tModel.getLocation()); for(int a = 0; a < interfaces.length; a++) { if(interfaces[a].equals(target.getElementName())) { IFigure sFig = editor.getRootPart().getPartFromModel(sModel).getFigure(); IFigure tFig = editor.getRootPart().getPartFromModel(tModel).getFigure(); sFig.setLocation(new Point(50, 50)); tFig.setLocation(new Point(50, 50)); Dimension sDim = getRealSize(sFig); Dimension tDim = getRealSize(tFig); int horizCenter = tModel.getLocation().x + (tDim.width / 2); sModel.setLocation(horizCenter - (sDim.width / 2), tModel.getLocation().y + tDim.height + 50); } } }*/ List<AbstractModel> mods = root.getChildren(); //List<Map.Entry<Integer, TypeModel>> l = new LinkedList<Map.Entry<Integer, TypeModel>>(); GraphData gd = new GraphData(); for(AbstractModel m : mods) { //TODO Insert heuristic layout algorithm here. //new org.eclipse.zest.layouts.algorithms.SpringLayoutAlgorithm(); /*System.out.println(models.getBounds() + "; " + models.getDrawnSize() + "; " + models.getSize());*/ //models.setLocation(new Point(60, 60)); if(m instanceof TypeModel) { final TypeModel n = (TypeModel)m; GraphVertex me = new GraphVertex(); me.me = n; me.id = gd.vertices.size(); me.name = "" + me.id; Dimension size = editor.getRootPart().getPartFromModel(n).getFigure().getSize(); me.degree = n.getIncomingEdges().size() + n.getOutgoingEdges().size() + (size.height * size.width /20000.0f); //System.out.println("1: " + size.height + ", 2: " + size.width); me.isSource = me.degree > 0; if( !gd.vertices.contains(me) ) { gd.vertices.add(me); _m.add(n); } else me = gd.vertices.get( gd.vertices.indexOf(me) ); /*int card = 0, i=0; card += n.getIncomingEdges().size(); card += n.getOutgoingEdges().size(); for(Map.Entry<Integer, TypeModel> o : l) { if( o.getKey() <= card ) break; i++; } final int c = card; l.add(i, new Map.Entry<Integer, TypeModel>() { private Integer _k; private TypeModel _v; { _k = c; _v = n; } public Integer getKey() { return _k; } public TypeModel getValue() { return _v; } public TypeModel setValue(TypeModel value) { return _v = value; } @Override public boolean equals(Object o) { return ((Map.Entry<Integer, TypeModel>)o).getValue() == this.getValue(); } });*/ for(RelationshipModel e : n.getOutgoingEdges()) { TypeModel y = e.getTargetModel(); GraphVertex you = new GraphVertex(); you.me = y; you.id = gd.vertices.size(); you.name = "" + you.id; you.degree = y.getIncomingEdges().size() + y.getOutgoingEdges().size() /*(y.getSize().height + y.getSize().width)*/; you.isSource = you.degree > 0; if( !gd.vertices.contains(you) ) { gd.vertices.add(you); _m.add(y); } else you = gd.vertices.get( gd.vertices.indexOf(you) ); // have me, you // create edge GraphEdgeInt ed = new GraphEdgeInt(); ed.x = me.id; ed.y = you.id; ed.w = 1.0f; gd.edges.add(ed); } } } //final GraphData fn = gd; //CCVisu.initializeLayout(gd, 2, null); gd.pos = new float[gd.vertices.size()][3]; for( int i=0; i<gd.vertices.size(); i++) { gd.pos[i][0] = gd.vertices.get(i).me.getLocation().x/200.0f; gd.pos[i][1] = gd.vertices.get(i).me.getLocation().y/200.0f; } Minimizer me = CCVisu.computeLayout(gd, 1000, 3, 1, false, false, 2.001f, null, false/*, new GraphEventListener() { public void onGraphEvent(GraphEvent evt) { for( int i=0; i<fn.vertices.size(); i++ ) { System.out.println("putting vertex " + i + " to (" + fn.pos[i][0] + ", " + fn.pos[i][1] + ")."); fn.vertices.get(i).me.setLocation((int)(fn.pos[i][0]*1000), (int)(fn.pos[i][1]*1000)); } try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }*/); me.minimizeEnergy(15); //System.out.println("computed " + gd.vertices.size() + " vertices."); // normalize float lx = 999, ly = 999; for( float[] e : gd.pos ) { if( e[0] < lx ) lx = e[0]; if( e[1] < ly ) ly = e[1]; } for( float[] e : gd.pos ) { e[0] -= lx; e[1] -= ly; } opos = new int[_m.size()][2]; npos = new int[_m.size()][2]; for( int i=0; i<gd.vertices.size(); i++ ) { //System.out.println("putting vertex " + i + " to (" + gd.pos[i][0] + ", " + gd.pos[i][1] + ")."); opos[i][0] = _m.get(i).getLocation().x; opos[i][1] = _m.get(i).getLocation().y; gd.vertices.get(i).me.setLocation((int)(gd.pos[i][0]*200), (int)(gd.pos[i][1]*200)); npos[i][0] = gd.vertices.get(i).me.getLocation().x; npos[i][1] = gd.vertices.get(i).me.getLocation().y; } /*class noode { public List<noode> childs; public TypeModel me; public noode(TypeModel m) { me = m; childs = new ArrayList<noode>(); } }; noode dad = new Object() { private List<Map.Entry<Integer, TypeModel>> l; public noode go(List<Map.Entry<Integer, TypeModel>> li) { l = li; noode r = new noode(null); while(!l.isEmpty()) { noode me = new noode(l.get(0).getValue()); r.childs.add(me); l.remove(me); recursive(me); } return r; } private void recursive(noode r) { } }.go( l ); for(Map.Entry<Integer, TypeModel> e : l) { //e.getValue().setLocation(60, 60); }*/ editor.checkDirty(); } }