Author: mes
Date: 2010-12-07 14:28:49 -0800 (Tue, 07 Dec 2010)
New Revision: 23117

Added:
   
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeNodeViewTaskFactoryImpl.java
   
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeStateMonitor.java
   
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeTask.java
Modified:
   
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/InnerCanvas.java
   
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/PopupMenuHelper.java
   
core3/ding-presentation-impl/trunk/src/main/resources/META-INF/spring/bundle-context-osgi.xml
   
core3/ding-presentation-impl/trunk/src/main/resources/META-INF/spring/bundle-context.xml
Log:
added support for drop edge creation

Added: 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeNodeViewTaskFactoryImpl.java
===================================================================
--- 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeNodeViewTaskFactoryImpl.java
                                (rev 0)
+++ 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeNodeViewTaskFactoryImpl.java
        2010-12-07 22:28:49 UTC (rev 23117)
@@ -0,0 +1,50 @@
+package org.cytoscape.ding.impl; 
+
+
+import java.awt.geom.Point2D;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.DataFlavor;
+
+import org.cytoscape.dnd.DropNodeViewTaskFactory;
+import org.cytoscape.view.model.CyNetworkView;
+import org.cytoscape.view.model.View;
+import org.cytoscape.model.CyNode;
+import org.cytoscape.model.CyNetworkManager;
+import org.cytoscape.work.TaskIterator;
+import org.cytoscape.work.TaskMonitor;
+import org.cytoscape.work.AbstractTask;
+
+
+
+public class AddEdgeNodeViewTaskFactoryImpl implements DropNodeViewTaskFactory 
{
+       private View<CyNode> nv;
+       private CyNetworkView view;
+       private Point2D xformPt;
+       private Point2D javaPt;
+
+       private final CyNetworkManager netMgr;
+
+       public AddEdgeNodeViewTaskFactoryImpl(CyNetworkManager netMgr) {
+               this.netMgr = netMgr;
+       }
+
+       public void setNodeView(View<CyNode> nv, CyNetworkView view) {
+               this.view = view;
+               this.nv = nv;
+       }
+
+       public void setDropInformation(Transferable t, Point2D javaPt, Point2D 
xformPt) {
+               this.javaPt = javaPt;
+               this.xformPt = xformPt;
+
+               AddEdgeStateMonitor.setSourcePoint(view,javaPt);
+
+               // Because the transferable may be null, we leave that
+               // tracking to the AddEdgeStateMonitor.
+               AddEdgeStateMonitor.setTransferable(view,t);
+       }
+
+       public TaskIterator getTaskIterator() {
+               return new TaskIterator(new AddEdgeTask(nv, view, 
AddEdgeStateMonitor.getTransferable(view)));
+       }
+}

Added: 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeStateMonitor.java
===================================================================
--- 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeStateMonitor.java
                           (rev 0)
+++ 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeStateMonitor.java
   2010-12-07 22:28:49 UTC (rev 23117)
@@ -0,0 +1,202 @@
+/*
+ Copyright (c) 2006, 2007, 2010, The Cytoscape Consortium (www.cytoscape.org)
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  The software and
+ documentation provided hereunder is on an "as is" basis, and the
+ Institute for Systems Biology and the Whitehead Institute
+ have no obligations to provide maintenance, support,
+ updates, enhancements or modifications.  In no event shall the
+ Institute for Systems Biology and the Whitehead Institute
+ be liable to any party for direct, indirect, special,
+ incidental or consequential damages, including lost profits, arising
+ out of the use of this software and its documentation, even if the
+ Institute for Systems Biology and the Whitehead Institute
+ have been advised of the possibility of such damage.  See
+ the GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+package org.cytoscape.ding.impl;
+
+
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetListener;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.swing.JComponent;
+import javax.swing.TransferHandler;
+
+import org.cytoscape.ding.EdgeView;
+import org.cytoscape.ding.GraphViewChangeListener;
+import org.cytoscape.ding.NodeView;
+import org.cytoscape.ding.ViewChangeEdit;
+import org.cytoscape.graph.render.export.ImageImposter;
+import org.cytoscape.graph.render.immed.EdgeAnchors;
+import org.cytoscape.graph.render.immed.GraphGraphics;
+import org.cytoscape.graph.render.stateful.GraphLOD;
+import org.cytoscape.graph.render.stateful.GraphRenderer;
+import org.cytoscape.model.CyEdge;
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.model.CyNode;
+import org.cytoscape.view.model.CyNetworkView;
+import org.cytoscape.util.intr.IntEnumerator;
+import org.cytoscape.util.intr.IntHash;
+import org.cytoscape.util.intr.IntStack;
+import org.cytoscape.work.undo.UndoSupport;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * This class is designed to keep track of the state of AddEdgeTasks 
throughout ding.
+ * An instance of this class is used by InnerCanvas to keep track of the state 
of adding 
+ * edges for that particular view.  This class also maintains several static 
maps that
+ * keep track of the values needed to add edges for individual network views, 
which are
+ * queried by the AddEdgeTask and TaskFactory.
+ */
+class AddEdgeStateMonitor {
+
+       // for drawing the rubber band when dropping
+       private Point2D nextPoint;
+       private double saveX1;
+       private double saveX2;
+       private double saveY1;
+       private double saveY2;
+
+       private final InnerCanvas canvas;
+       private final DGraphView m_view;
+
+       private static Map<CyNetworkView,CyNode> sourceNodes = new 
HashMap<CyNetworkView,CyNode>();
+       private static Map<CyNetworkView,Point2D> sourcePoints = new 
HashMap<CyNetworkView,Point2D>();
+       private static Map<CyNetworkView,Transferable> transfers = new 
HashMap<CyNetworkView,Transferable>();
+
+       AddEdgeStateMonitor(InnerCanvas canvas, DGraphView m_view) {
+               this.canvas = canvas;
+               this.m_view = m_view;
+       }
+
+       boolean addingEdge() {
+               return sourceNodes.containsKey(m_view.cyNetworkView);
+       }
+
+       static CyNode getSourceNode(CyNetworkView view) {
+               return sourceNodes.get(view);
+       }
+
+       static void setSourceNode(CyNetworkView view, CyNode n) {
+               if ( n == null )
+                       sourceNodes.remove(view);
+               else
+                       sourceNodes.put(view,n);
+       }
+
+       static Point2D getSourcePoint(CyNetworkView view) {
+               return sourcePoints.get(view);
+       }
+
+       static void setSourcePoint(CyNetworkView view, Point2D p) {
+               if ( p == null )
+                       sourcePoints.remove(view);
+               else
+                       sourcePoints.put(view,p);
+       }
+
+       static Transferable getTransferable(CyNetworkView view) {
+               return transfers.get(view);
+       }
+
+       static void reset(CyNetworkView view) {
+               setSourceNode(view,null);
+               setSourcePoint(view,null);
+               transfers.remove(view);
+       }
+
+       static void setTransferable(CyNetworkView view, Transferable t) {
+               // Only update the transferable if it's a new one, 
+               // otherwise use the old one.
+               if ( t != null )
+                       transfers.put(view,t);
+       }
+
+       void drawRubberBand(MouseEvent e) {
+               nextPoint = e.getPoint();
+
+               Point2D startPoint = getSourcePoint(m_view.cyNetworkView);
+               if ( startPoint == null )
+                       return;
+
+        if (nextPoint == null) 
+               nextPoint = startPoint; 
+
+        double x1 = startPoint.getX();
+        double y1 = startPoint.getY();
+        double x2 = nextPoint.getX();
+        double y2 = nextPoint.getY();
+        double lineLen = Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 
- y1)));
+        double offset = 5;
+
+        if (lineLen == 0) {
+            lineLen = 1;
+        }
+
+        y2 = y2 + (((y1 - y2) / lineLen) * offset);
+        x2 = x2 + (((x1 - x2) / lineLen) * offset);
+
+        Graphics g = canvas.getGraphics();
+
+        Color saveColor = g.getColor();
+
+        if (saveX1 != Double.MIN_VALUE) {
+            DingCanvas backgroundCanvas = 
m_view.getCanvas(DGraphView.Canvas.BACKGROUND_CANVAS);
+            g.setColor(backgroundCanvas.getBackground());
+            g.drawLine(((int) saveX1) - 1, ((int) saveY1) - 1, ((int) saveX2) 
+ 1,
+                   ((int) saveY2) + 1);
+        }
+
+        canvas.update(g);
+        g.setColor(Color.BLACK);
+        g.drawLine(((int) x1) - 1, ((int) y1) - 1, ((int) x2) + 1, ((int) y2) 
+ 1);
+        g.setColor(saveColor);
+
+        saveX1 = x1;
+        saveX2 = x2;
+        saveY1 = y1;
+        saveY2 = y2;
+       }
+}

Added: 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeTask.java
===================================================================
--- 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeTask.java
                           (rev 0)
+++ 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/AddEdgeTask.java
   2010-12-07 22:28:49 UTC (rev 23117)
@@ -0,0 +1,47 @@
+
+package org.cytoscape.ding.impl; 
+
+import org.cytoscape.task.AbstractNodeViewTask;
+import org.cytoscape.view.model.CyNetworkView;
+import org.cytoscape.view.model.View;
+import org.cytoscape.model.CyNode;
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.work.TaskMonitor;
+import org.cytoscape.dnd.DropUtil;
+
+import java.awt.datatransfer.Transferable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class AddEdgeTask extends AbstractNodeViewTask {
+
+       private final Transferable t;
+
+       private static final Logger logger = 
LoggerFactory.getLogger(AddEdgeTask.class);
+
+       public AddEdgeTask(View<CyNode> nv, CyNetworkView view, Transferable t) 
{
+               super(nv,view);
+               this.t = t;
+       }
+
+       @Override
+       public void run(TaskMonitor tm) throws Exception {
+               if ( !DropUtil.transferableMatches(t,"Edge") ) {
+                       logger.warn("Transferable object does not match 
expected type (Edge) for task.");
+                       return;
+               }
+
+               CyNode sourceNode = AddEdgeStateMonitor.getSourceNode(netView);
+               if ( sourceNode == null ) {
+                       
AddEdgeStateMonitor.setSourceNode(netView,nodeView.getModel());
+               } else {
+                       CyNetwork net = netView.getModel();
+                       CyNode targetNode = nodeView.getModel();
+                       net.addEdge(sourceNode,targetNode,true);
+                       netView.updateView();
+                       AddEdgeStateMonitor.setSourceNode(netView,null);
+               }
+       }
+}

Modified: 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/InnerCanvas.java
===================================================================
--- 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/InnerCanvas.java
   2010-12-07 22:28:17 UTC (rev 23116)
+++ 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/InnerCanvas.java
   2010-12-07 22:28:49 UTC (rev 23117)
@@ -36,6 +36,7 @@
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.DataFlavor;
 import java.awt.dnd.DnDConstants;
 import java.awt.dnd.DropTarget;
 import java.awt.dnd.DropTargetListener;
@@ -77,6 +78,7 @@
 import org.cytoscape.util.intr.IntHash;
 import org.cytoscape.util.intr.IntStack;
 import org.cytoscape.work.undo.UndoSupport;
+import org.cytoscape.dnd.DropUtil;
 
 /**
  *
@@ -126,7 +128,6 @@
        static final String MAC_OS_ID = "mac";
 
        private DropTarget dropTarget;
-       private String CANVAS_DROP = "CanvasDrop";
 
        //  for turning selection rectangle on and off
        private boolean selecting = true;
@@ -141,7 +142,10 @@
        private final MousePressedDelegator mousePressedDelegator;
        private final MouseReleasedDelegator mouseReleasedDelegator;
        private final MouseDraggedDelegator mouseDraggedDelegator;
+       private final AddEdgeMousePressedDelegator addEdgeMousePressedDelegator;
 
+       private final AddEdgeStateMonitor addEdgeMode;
+
        InnerCanvas(Object lock, DGraphView view, UndoSupport undo) {
                super();
                m_lock = lock;
@@ -166,6 +170,9 @@
                mousePressedDelegator = new MousePressedDelegator();
                mouseReleasedDelegator = new MouseReleasedDelegator();
                mouseDraggedDelegator = new MouseDraggedDelegator();
+               addEdgeMousePressedDelegator = new 
AddEdgeMousePressedDelegator();
+
+               addEdgeMode = new AddEdgeStateMonitor(this,m_view);
        }
 
        /**
@@ -268,7 +275,6 @@
                renderGraph(new GraphGraphics(
                                new ImageImposter(g, getWidth(), getHeight()), 
false), 
                                /* setLastRenderDetail = */ false, 
m_view.m_printLOD);
-               // g.drawImage(img, 0, 0, null);
                isPrinting = false;
        }
 
@@ -281,7 +287,6 @@
                isPrinting = true;
                final Image img = new BufferedImage(getWidth(), getHeight(), 
BufferedImage.TYPE_INT_ARGB);
                renderGraph(new GraphGraphics(img, false), /* 
setLastRenderDetail = */ false, m_view.m_printLOD);
-               // g.drawImage(img, 0, 0, null);
                isPrinting = false;
        }
 
@@ -310,7 +315,10 @@
        }
 
        public void mouseMoved(MouseEvent e) {
-               setToolTipText( getToolTipText( e.getPoint() ) );
+               if ( addEdgeMode.addingEdge() )
+                       addEdgeMode.drawRubberBand(e);
+               else
+                       setToolTipText( getToolTipText( e.getPoint() ) );
        }
 
        //
@@ -328,7 +336,10 @@
        }
 
        public void mousePressed(MouseEvent e) {
-               mousePressedDelegator.delegateMouseEvent(e);
+               if ( addEdgeMode.addingEdge() )
+                       addEdgeMousePressedDelegator.delegateMouseEvent(e);
+               else
+                       mousePressedDelegator.delegateMouseEvent(e);
                requestFocusInWindow();
        }
 
@@ -346,6 +357,8 @@
                if ( (code == KeyEvent.VK_UP) || (code == KeyEvent.VK_DOWN) || 
                     (code == KeyEvent.VK_LEFT) || (code == KeyEvent.VK_RIGHT)) 
{
                        handleArrowKeys(k);
+               } else if ( code == KeyEvent.VK_ESCAPE ) {
+                       handleEscapeKey();
                }
        }
 
@@ -839,9 +852,11 @@
         * default drop handler.  
         */
        public void drop(DropTargetDropEvent dte) {
+               requestFocusInWindow();
                dte.acceptDrop(DnDConstants.ACTION_COPY);
 
                Transferable t = dte.getTransferable();
+               String action = getPreferredDropAction(t);
 
                Point rawPt = dte.getLocation();
                double[] loc = new double[2];
@@ -852,14 +867,21 @@
                xformPt.setLocation(loc[0],loc[1]); 
 
                NodeView nview = m_view.getPickedNodeView(rawPt);
-               if ( nview != null )
-                       popup.createDropNodeViewMenu(nview,rawPt,xformPt,t);
-               else 
+               if ( nview != null ) 
+                       
popup.createDropNodeViewMenu(nview,rawPt,xformPt,t,action);
+               else
                        popup.createDropEmptySpaceMenu(rawPt,xformPt,t); 
 
                dte.dropComplete(true);
        }
 
+       private String getPreferredDropAction(Transferable t) {
+               String[] actions = DropUtil.getTransferableDataStrings(t);
+               if (actions.length > 0)
+                       return actions[0];
+               else
+                       return null;
+       }
 
        private void adjustZoom(int notches) {
         double factor; 
@@ -955,6 +977,11 @@
                }
        }
 
+       private void handleEscapeKey() {
+               AddEdgeStateMonitor.reset(m_view.cyNetworkView);
+               repaint();
+       }
+
        private void handleArrowKeys(KeyEvent k) {
                final int code = k.getKeyCode();
                double move = 1.0;
@@ -1011,6 +1038,23 @@
                }
        }
 
+       private class AddEdgeMousePressedDelegator extends ButtonDelegator {
+               @Override
+               void singleLeftClick(MouseEvent e) {
+                       Point rawPt = e.getPoint();
+                       double[] loc = new double[2];
+                       loc[0] = rawPt.getX();
+                       loc[1] = rawPt.getY();
+                       m_view.xformComponentToNodeCoords(loc);
+                       Point xformPt = new Point();
+                       xformPt.setLocation(loc[0],loc[1]); 
+                       String action = "Edge";
+                       NodeView nview = m_view.getPickedNodeView(rawPt);
+                       if ( nview != null ) 
+                               
popup.createDropNodeViewMenu(nview,rawPt,xformPt,null,action);
+               }
+       }
+
        private class MousePressedDelegator extends ButtonDelegator {
 
                @Override

Modified: 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/PopupMenuHelper.java
===================================================================
--- 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/PopupMenuHelper.java
       2010-12-07 22:28:17 UTC (rev 23116)
+++ 
core3/ding-presentation-impl/trunk/src/main/java/org/cytoscape/ding/impl/PopupMenuHelper.java
       2010-12-07 22:28:49 UTC (rev 23117)
@@ -113,9 +113,9 @@
        /**
         * Creates a menu based on a drop event on a NodeView.
         */
-       void createDropNodeViewMenu(NodeView nview, Point rawPt, Point xformPt, 
Transferable t) {
+       void createDropNodeViewMenu(NodeView nview, Point rawPt, Point xformPt, 
Transferable t, String action) {
                if (nview != null ) {
-                       Collection<DropNodeViewTaskFactory> usableTFs = 
getPreferredActions(m_view.dropNodeViewTFs,null);
+                       Collection<DropNodeViewTaskFactory> usableTFs = 
getPreferredActions(m_view.dropNodeViewTFs,action);
                        View<CyNode> nv = nview.getNodeViewModel();
 
                        // build a menu of actions if more than factory exists

Modified: 
core3/ding-presentation-impl/trunk/src/main/resources/META-INF/spring/bundle-context-osgi.xml
===================================================================
--- 
core3/ding-presentation-impl/trunk/src/main/resources/META-INF/spring/bundle-context-osgi.xml
       2010-12-07 22:28:17 UTC (rev 23116)
+++ 
core3/ding-presentation-impl/trunk/src/main/resources/META-INF/spring/bundle-context-osgi.xml
       2010-12-07 22:28:49 UTC (rev 23117)
@@ -36,6 +36,11 @@
                interface="org.cytoscape.model.CyTableManager">
        </osgi:reference>
 
+       <osgi:reference id="cyNetworkManagerServiceRef"
+               interface="org.cytoscape.model.CyNetworkManager">
+       </osgi:reference>
+
+
        <osgi:reference id="cyEventHelperServiceRef"
                interface="org.cytoscape.event.CyEventHelper">
        </osgi:reference>
@@ -63,6 +68,13 @@
                </osgi:service-properties>
        </osgi:service>
 
+       <osgi:service id="addEdgeNodeViewTaskFactoryService" 
ref="addEdgeNodeViewTaskFactory"
+               interface="org.cytoscape.dnd.DropNodeViewTaskFactory">
+               <osgi:service-properties>
+                       <entry key="title" value="Create Edge" />
+                       <entry key="preferredAction" value="Edge" />
+               </osgi:service-properties>
+       </osgi:service>
 
        <!-- Visual Lexicon for Ding -->
        <osgi:service id="dVisualLexiconService" ref="dVisualLexicon"

Modified: 
core3/ding-presentation-impl/trunk/src/main/resources/META-INF/spring/bundle-context.xml
===================================================================
--- 
core3/ding-presentation-impl/trunk/src/main/resources/META-INF/spring/bundle-context.xml
    2010-12-07 22:28:17 UTC (rev 23116)
+++ 
core3/ding-presentation-impl/trunk/src/main/resources/META-INF/spring/bundle-context.xml
    2010-12-07 22:28:49 UTC (rev 23117)
@@ -45,4 +45,9 @@
                <constructor-arg ref="cyTableManagerServiceRef" />
                <constructor-arg ref="renderingEngineManagerServiceRef" />
        </bean>
+
+       <bean id="addEdgeNodeViewTaskFactory" 
+             class="org.cytoscape.ding.impl.AddEdgeNodeViewTaskFactoryImpl">
+               <constructor-arg ref="cyNetworkManagerServiceRef" />
+       </bean>
 </beans>

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to