001 // GraphLab Project: http://graphlab.sharif.edu 002 // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology 003 // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ 004 package graphlab.plugins.main.core.actions.edge; 005 006 import graphlab.graph.GraphUtils; 007 import graphlab.graph.atributeset.GraphAttrSet; 008 import graphlab.graph.event.GraphEvent; 009 import graphlab.graph.event.VertexEvent; 010 import graphlab.graph.graph.*; 011 import graphlab.graph.old.AcceleratedRenderer; 012 import graphlab.graph.old.GStroke; 013 import graphlab.library.util.Pair; 014 import graphlab.platform.core.AbstractAction; 015 import graphlab.platform.core.BlackBoard; 016 import graphlab.plugins.commonplugin.undo.Undoable; 017 import graphlab.plugins.commonplugin.undo.UndoableActionOccuredData; 018 import graphlab.plugins.main.select.Select; 019 import graphlab.plugins.main.select.SelectPluginMethods; 020 021 import java.awt.*; 022 import java.awt.event.MouseEvent; 023 024 /** 025 * @author azin azadi 026 */ 027 028 public class AddEdge extends AbstractAction implements PaintHandler, Undoable { 029 // private double lasty; 030 // private double lastx; 031 private GraphPoint lastPos; 032 private SelectPluginMethods selMethods; 033 034 /** 035 * constructor 036 * 037 * @param bb the blackboard of the action 038 */ 039 public AddEdge(BlackBoard bb) { 040 super(bb); 041 selMethods = new SelectPluginMethods(bb); 042 listen4Event(VertexEvent.EVENT_KEY); 043 // listen4Event(GraphEvent.name); 044 // listen4Event(VertexDropData.event); 045 // listen4Event(VertexSelectData.name); 046 } 047 048 protected VertexModel v1, vc1; 049 protected GraphModel g; 050 protected AbstractGraphRenderer gv; 051 protected boolean isClick = false; 052 protected boolean isDrag = false; 053 054 public void performAction(String eventName, Object value) { 055 // our old lovely Add Edge 056 // if (name == VertexSelectData.name) { 057 // VertexSelectData vsd = blackboard.getLog(VertexSelectData.name).getLast(); 058 // if (!isClick) { 059 // vc1 = vsd.v; 060 // v1=vc1; 061 // startPainting(); 062 // } else { 063 // Vertex v2=vsd.v; 064 // Edge e = doJob(v2.g, v2, vc1); 065 // addUndoData(e); 066 // stopPainting(); 067 // } 068 // isClick=true; 069 // isDrag=false; 070 // } 071 VertexEvent ve = blackboard.getData(VertexEvent.EVENT_KEY); 072 073 if ((ve.modifiers & MouseEvent.SHIFT_DOWN_MASK) == MouseEvent.SHIFT_DOWN_MASK) 074 return; 075 076 SubGraph sd = Select.getSelection(blackboard); 077 g = blackboard.getData(GraphAttrSet.name); 078 gv = blackboard.getData(AbstractGraphRenderer.EVENT_KEY); 079 080 081 if (eventName == VertexEvent.EVENT_KEY) { 082 if (ve.eventType == VertexEvent.DRAGGING_STARTED) { 083 if (!sd.vertices.contains(ve.v)) { //start if the vertex is not selected 084 // VertexDragData vdrag = blackboard.get(VertexDragData.name); 085 v1 = ve.v; 086 startPainting(); 087 // if (!selMethods.getSelectedVertices().contains(v1)) { 088 // //the vertex doesn't selected 089 // } else 090 // v1 = null; 091 } 092 } 093 if (ve.eventType == VertexEvent.DROPPED) { 094 if (v1 != null) { 095 VertexModel v2 = ve.v; 096 if (v2 != null && isDrag) //!it was released on empty space 097 if (!v1.equals(v2)) { 098 EdgeModel e = doJob(g, v1, v2); 099 addUndoData(e, g); 100 } 101 // unListenEvent(VertexMouseDraggingData.event); 102 } 103 stopPainting(); 104 v1 = null; 105 } 106 107 if (ve.eventType == VertexEvent.DRAGGING) { 108 lastPos = ve.mousePos; 109 GraphPoint absPosOnGraph = GraphUtils.createGraphPoint(g, x1, y1); 110 absPosOnGraph.add(lastPos); 111 if (g.getVerticesCount() < 300) { 112 Pair<VertexModel, Double> p = GraphControl.mindistv(g, absPosOnGraph); 113 if (p.first != null) 114 curVertexUnderMouse = GraphControl.isPointOnVertex(g, p.first, absPosOnGraph) ? p.first : null; 115 } 116 if (!(gv instanceof AcceleratedRenderer)) 117 gv.repaint(); 118 119 isDrag = true; 120 isClick = false; 121 } 122 123 if (ve.eventType == VertexEvent.DOUBLECLICKED) { 124 VertexModel v = ve.v; 125 if (v != null) { 126 EdgeModel e = doJob(g, v, v); 127 addUndoData(e, g); 128 } 129 } 130 if (ve.eventType == VertexEvent.RELEASED) { //mouse released on a blank area of graph 131 v1 = null; 132 stopPainting(); 133 } 134 } else if (eventName == GraphEvent.EVENT_KEY) { 135 // if (ge.eventType == GraphEvent.) { 136 // stopPainting(); 137 // } 138 } 139 } 140 141 protected void stopPainting() { 142 gv.removePaintHandler(this); 143 // g.view.repaint(); 144 } 145 146 protected void addUndoData(EdgeModel e, GraphModel g) { 147 UndoableActionOccuredData uaod = new UndoableActionOccuredData(this); 148 uaod.properties.put("AddedEdge", e); 149 uaod.properties.put("Graph", g); 150 blackboard.setData(UndoableActionOccuredData.EVENT_KEY, uaod); 151 } 152 153 protected void startPainting() { 154 GraphPoint location = v1.getLocation(); 155 Point viewPoint = GraphUtils.createViewPoint(g, location); 156 cx = v1.getCenter().x / 2; 157 x1 = viewPoint.x; 158 cy = v1.getCenter().y / 2; 159 y1 = viewPoint.y; 160 // listen4Event(VertexMouseDraggingData.event); 161 gv.addPostPaintHandler(this); 162 } 163 164 public static EdgeModel doJob(GraphModel g, VertexModel v1, VertexModel v2) { 165 EdgeModel e = new EdgeModel(v1, v2); 166 g.insertEdge(e); 167 return e; 168 } 169 170 protected int x1; 171 protected int y1; 172 protected int cx; 173 protected int cy; 174 175 protected VertexModel curVertexUnderMouse = null; 176 177 public void paint(Graphics g, Object component, Boolean drawExtras) { 178 if (!drawExtras) 179 return; 180 Graphics2D gg = (Graphics2D) g; 181 gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 182 Stroke stroke = gg.getStroke(); 183 gg.setStroke(GStroke.dashed.stroke); 184 if (lastPos != null) { 185 Point viewPoint = GraphUtils.createViewPoint(this.g, lastPos); 186 gg.setColor(Color.DARK_GRAY); 187 if (curVertexUnderMouse == null) 188 gg.drawLine(x1, y1, x1 + viewPoint.x, y1 + viewPoint.y); 189 else { 190 gg.setStroke(GStroke.strong.stroke); 191 GraphPoint loc = curVertexUnderMouse.getLocation(); 192 viewPoint = GraphUtils.createViewPoint(this.g, loc); 193 gg.drawLine(x1, y1, viewPoint.x, viewPoint.y); 194 } 195 } 196 // } 197 gg.setStroke(stroke); 198 } 199 200 public void undo(UndoableActionOccuredData uaod) { 201 EdgeModel e = (EdgeModel) uaod.properties.get("AddedEdge"); 202 GraphModel g = (GraphModel) uaod.properties.get("Graph"); 203 g.removeEdge(e); 204 205 } 206 207 public void redo(UndoableActionOccuredData uaod) { 208 EdgeModel e = (EdgeModel) uaod.properties.get("AddedEdge"); 209 GraphModel g = (GraphModel) uaod.properties.get("Graph"); 210 g.insertEdge(e); 211 } 212 }