Author: Christian Lopes
Date: 2010-09-02 14:48:03 -0700 (Thu, 02 Sep 2010)
New Revision: 21671

Modified:
   cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js
   cytoscapeweb/trunk/cytoscapeweb/html-template/sample.html
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DrawGraphCommand.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/ConfigProxy.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/data/ConfigVO.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/Layouts.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ApplicationMediator.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/GraphMediator.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/PanZoomMediator.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphVis.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/controls/EnclosingSelectionControl.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/controls/EventDragControl.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/layout/ForceDirectedLayout.as
Log:
Fixed bug #2329: Grabber hand cursor gets stuck: Removed Ctrl-key shortcut and 
added an experimental mousedown timer that will automatically change Cytoscape 
Web to grab-to-pan mode when user clicks and holds for a while.
Some other edge-weighted force directed layout changes.

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js    
2010-09-02 21:46:06 UTC (rev 21670)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js    
2010-09-02 21:48:03 UTC (rev 21671)
@@ -112,6 +112,15 @@
      *                                              by a number, so if the 
application has two instances of the Visualization in the same page,
      *                                              their id's will be 
"cytoscapeWeb1" and "cytoscapeWeb2".
      *                                              This token does not 
usually need to be changed.</li>
+     *                    <li><code>mouseDownToDragDelay</code>: If the user 
clicks (mouse-down) the background and hold if for a while,
+     *                                                           Cytoscape Web 
temporarily changes to grab-to-pan mode, so the user can drag the whole network.
+     *                                                           If the user 
do the same over a node, the grab-to-pan mode can be activated as well,
+     *                                                           but dragging 
the node will drag the node's disconnected component only,
+     *                                                           not 
necessarily the whole network--if there are other disconnected parts, they will 
not be dragged.
+     *                                                           This 
parameter lets you set the time (in milliseconds) Cytoscape Web should wait 
before changing modes.
+     *                                                           The default 
value is <code>400</code>.
+     *                                                           If this 
parameter is set to <code>-1</code>, Cytoscape Web will never activate the 
grab-to-pan mode
+     *                                                           
automatically, but users can still use the grab-to-pan option from the pan-zoom 
control.</li>
      *                </ul>
      * @return {org.cytoscapeweb.Visualization} The Visualization instance.
      * @see org.cytoscapeweb.Visualization#draw
@@ -2249,10 +2258,16 @@
      *                                                   look worse than 
expected, or if the layout is taking too long to execute.</li>
      *         <li><code>weightAttr</code> {String}: The name of the edge 
attribute that contains the weights.
      *                                               The default value is 
<code>null</code>, which means that the layout is unweighted.
-     *                                               If you want to generate 
an edge-weighted layout, you just need to specify the attribute name.
+     *                                               If you want to generate 
an edge-weighted layout, you just need to provide the name of the data 
attribute that should be used as weight.</li>
      *         <li><code>weightNorm</code> {String}: The normalization method 
that is applied to the weight values when using a weighted layout.
      *                                               Possible values are: 
<code>"linear"</code>, <code>"inverselinear"</code> and <code>"log"</code>.
-     *                                               The default value is 
<code>"linear"</code>.
+     *                                               The default value is 
<code>"linear"</code>.</li>
+     *         <li><code>minWeight</code> {Number}: The minimum edge weight to 
consider, if the layout is set to be weighted.
+     *                                              Do not specify any value 
if you want the layout to get the minimum weight from the rendered edges data 
(filtered-out edges are ignored).
+     *                                              Any edge with a weight 
bellow the minimum will be considered to have the minimum weight.</li>
+     *         <li><code>maxWeight</code> {Number}: The maximum edge weight to 
consider, if the layout is set to be weighted.
+     *                                              Do not specify any value 
if you want the layout to get the maximum weight from the rendered edges data 
(filtered-out edges are ignored).
+     *                                              Any edge with a weight 
above the maximum will be considered to have the maximum weight.</li>
      *     </ul>
      * <li><b>Circle:</b></li>
      *     <ul class="options">

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/sample.html
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/sample.html   2010-09-02 
21:46:06 UTC (rev 21670)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/sample.html   2010-09-02 
21:48:03 UTC (rev 21671)
@@ -20,6 +20,7 @@
                 edgeTooltipsEnabled: true,
                 nodeTooltipsEnabled: true,
                 edgesMerged: false,
+                //mouseDownToDragDelay: -1,
                 visualStyle: {
                     global: {
                         backgroundColor: "#fefefe",

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DrawGraphCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DrawGraphCommand.as
 2010-09-02 21:46:06 UTC (rev 21670)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DrawGraphCommand.as
 2010-09-02 21:48:03 UTC (rev 21671)
@@ -58,6 +58,8 @@
                     configProxy.edgeLabelsVisible = options.edgeLabelsVisible;
                 if (options.panZoomControlVisible != null)
                     configProxy.panZoomControlVisible = 
options.panZoomControlVisible;
+                if (options.mouseDownToDragDelay != null)
+                    configProxy.mouseDownToDragDelay = 
options.mouseDownToDragDelay;
                 
                 graphProxy.loadGraph(options.network, 
configProxy.currentLayout);
                 

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/ConfigProxy.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/ConfigProxy.as   
2010-09-02 21:46:06 UTC (rev 21670)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/ConfigProxy.as   
2010-09-02 21:48:03 UTC (rev 21671)
@@ -192,6 +192,14 @@
         public function set maxZoom(value:Number):void {
             config.maxZoom = value;
         }
+        
+        public function get mouseDownToDragDelay():Number {
+            return config.mouseDownToDragDelay;
+        }
+        
+        public function set mouseDownToDragDelay(value:Number):void {
+            config.mouseDownToDragDelay = value;
+        }
 
         // ========[ CONSTRUCTOR 
]==================================================================
 

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/data/ConfigVO.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/data/ConfigVO.as 
2010-09-02 21:46:06 UTC (rev 21670)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/data/ConfigVO.as 
2010-09-02 21:48:03 UTC (rev 21671)
@@ -53,6 +53,7 @@
         public var currentLayout:Object;
         public var minZoom:Number = 0.002;
         public var maxZoom:Number = 3;
+        public var mouseDownToDragDelay:Number = 400;
         
         // ========[ CONSTRUCTOR 
]==================================================================
         

Modified: cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/Layouts.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/Layouts.as        
2010-09-02 21:46:06 UTC (rev 21670)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/Layouts.as        
2010-09-02 21:48:03 UTC (rev 21671)
@@ -68,11 +68,13 @@
                 maxDistance: 10000,
                 mass:        3,
                 tension:     0.1,
-                restLength: "auto",
-                weightAttr: null,
-                weightNorm: ForceDirectedLayout.NORMALIZED_WEIGHT,
-                iterations: 400,
-                maxTime:    30000, // milliseconds
+                restLength:  "auto",
+                weightAttr:  null,
+                weightNorm:  ForceDirectedLayout.NORMALIZED_WEIGHT,
+                minWeight:   undefined,
+                maxWeight:   undefined,
+                iterations:  400,
+                maxTime:     30000, // milliseconds
                 autoStabilize: true
             },
             Preset: {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ApplicationMediator.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ApplicationMediator.as
    2010-09-02 21:46:06 UTC (rev 21670)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ApplicationMediator.as
    2010-09-02 21:48:03 UTC (rev 21671)
@@ -372,7 +372,7 @@
             // roll out the Flash player area and then over again.
             // That happens when the plus cursor is being displayed.
             if (!_isCustomCursor) Mouse.show();
-            // The user might have pressed or released a SHIFT or CTRL key 
while the mouse
+            // The user might have pressed or released the SHIFT key while the 
mouse
             // was out of the application area:
             updateCursor(_cursorOptions);
             sendNotification(ApplicationFacade.ROLLOVER_EVENT);
@@ -469,16 +469,15 @@
             if (options == null) options = {};
             if (!_overApp || options.selecting) return;
             
-            if (options.draggingGraph) {
+            if (options.draggingGraph || options.draggingComponent) {
                 showClosedHandCursor();
                 _isCustomCursor = true;
             } else {
                 hideClosedHandCursor();
 
                 if ( !_overPanZoom &&
-                     (options.ctrlDown || (configProxy.grabToPanEnabled && 
-                                           graphProxy.rolledOverNode == null 
&& 
-                                           graphProxy.rolledOverEdge == null)) 
) {
+                     configProxy.grabToPanEnabled && 
+                     graphProxy.rolledOverNode == null && 
graphProxy.rolledOverEdge == null ) {
                     showOpenedHandCursor();
                     _isCustomCursor = true;
                 } else {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/GraphMediator.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/GraphMediator.as  
2010-09-02 21:46:06 UTC (rev 21670)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/GraphMediator.as  
2010-09-02 21:48:03 UTC (rev 21671)
@@ -41,7 +41,9 @@
     import flash.display.DisplayObject;
     import flash.events.KeyboardEvent;
     import flash.events.MouseEvent;
+    import flash.events.TimerEvent;
     import flash.ui.Keyboard;
+    import flash.utils.Timer;
     
     import org.cytoscapeweb.ApplicationFacade;
     import org.cytoscapeweb.events.DragEvent;
@@ -73,9 +75,10 @@
         private var _isMouseOverView:Boolean;
         private var _draggingNode:Boolean;
         private var _draggingGraph:Boolean;
+        private var _draggingComponent:Boolean;
         private var _selecting:Boolean;
-        private var _ctrlDown:Boolean;
         private var _shiftDown:Boolean;
+        private var _dragAllTimer:Timer;
         
         private var _dragControl:EventDragControl;
         
@@ -102,7 +105,8 @@
                 setStyleToSelectionControl(configProxy.visualStyle);
                 // It is important to attach it here, or the first attempt to 
use the
                 // drag-selection will not work:
-                selectionControl.attach(graphView);
+                _selectionControl.attach(graphView);
+                _selectionControl.enabled = false;
             }
             
             return _selectionControl;
@@ -111,6 +115,10 @@
         private function get _graphScale():Number {
             return vis.scaleX;
         }
+        
+        private function get dragging():Boolean {
+            return _draggingGraph || _draggingComponent || _draggingNode;
+        }
    
         // ========[ PUBLIC PROPERTIES 
]============================================================
    
@@ -141,9 +149,7 @@
         
         /** @inheritDoc */
         override public function listNotificationInterests():Array {
-            return [ApplicationFacade.ACTIVATE_EVENT,
-                    ApplicationFacade.DEACTIVATE_EVENT,
-                    ApplicationFacade.PAN_GRAPH,
+            return [ApplicationFacade.PAN_GRAPH,
                     ApplicationFacade.ENABLE_GRAB_TO_PAN,
                     ApplicationFacade.CENTER_GRAPH];
         }
@@ -151,10 +157,6 @@
         /** @inheritDoc */
         override public function handleNotification(note:INotification):void {
             switch (note.getName()) {
-                case ApplicationFacade.DEACTIVATE_EVENT:
-                    if (_ctrlDown)
-                        graphView.stage.dispatchEvent(new 
KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, Keyboard.CONTROL));
-                    break;
                 case ApplicationFacade.ENABLE_GRAB_TO_PAN:
                     updateCursor();
                     break;
@@ -341,7 +343,7 @@
             graphView.stage.addEventListener(KeyboardEvent.KEY_DOWN, 
onKeyDown, false, 0, true);
             graphView.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp, 
false, 0, true);
             // 2. DRAG the whole graph:
-            graphView.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownView, 
false, 0, true);
+            graphView.stage.addEventListener(MouseEvent.MOUSE_DOWN, 
onMouseDownView, false, 0, true);
             // 3. 2-Click:
             graphView.addEventListener(MouseEvent.DOUBLE_CLICK, 
onDoubleClickView, false, 0, true);
             
@@ -396,27 +398,15 @@
         // VIEW listener functions:
         // 
-----------------------------------------------------------------------------------------
         private function onKeyDown(evt:KeyboardEvent):void { trace("* Key DOWN 
:: " + evt.keyCode + "/" + evt.charCode);
-            var dirty:Boolean = _isMouseOverView || _selecting || 
_draggingGraph;
-            
-            if (evt.keyCode === Keyboard.CONTROL) {
-                _ctrlDown = true;
-                
-                if (dirty)
-                    updateCursor();
-                if (graphProxy.rolledOverNode != null)
-                    vis.showDragRectangle(graphProxy.rolledOverNode);
-            } else if (evt.keyCode === Keyboard.SHIFT) {
+            if (evt.keyCode === Keyboard.SHIFT) {
                 _shiftDown = true;
-                if (!_ctrlDown && dirty) updateCursor();
+                var dirty:Boolean = _isMouseOverView || _selecting || dragging;
+                if (dirty) updateCursor();
             }
         }
         
         private function onKeyUp(evt:KeyboardEvent):void { trace("* Key UP :: 
" + evt.keyCode + "/" + evt.charCode);
-            if (evt.keyCode === Keyboard.CONTROL) {
-                _ctrlDown = false;
-                if (_isMouseOverView) updateCursor();
-                vis.hideDragRectangle();
-            } else if (evt.keyCode === Keyboard.SHIFT) {
+            if (evt.keyCode === Keyboard.SHIFT) {
                 _shiftDown = false;
                 if (_isMouseOverView) updateCursor();
             }
@@ -429,27 +419,32 @@
         
         private function onRollOutView(evt:MouseEvent):void { trace(">>>> Roll 
OUT [View]");
             _isMouseOverView = false;
-            if (!_selecting && !_draggingNode && !_draggingGraph)
+            if (!_selecting && !dragging)
                 sendNotification(ApplicationFacade.UPDATE_CURSOR);
         }
         
         private function onMouseDownView(evt:MouseEvent):void { trace("* Mouse 
DOWN [View]");
-            if (_ctrlDown || (configProxy.grabToPanEnabled && 
graphProxy.rolledOverEdge == null)) {
-                // PANNING the whole graph...
-                _draggingGraph = true;
-                updateCursor();
-
-                // Remove other actions that should not occur when panning:
-                selectionControl.detach();
+            if (configProxy.grabToPanEnabled && graphProxy.rolledOverEdge == 
null) {
+                // DRAGGING the whole graph...
+                startDragGraph();
+            } else if (!configProxy.grabToPanEnabled) {
+                if (configProxy.mouseDownToDragDelay >= 0) {
+                    _dragAllTimer = new 
Timer(configProxy.mouseDownToDragDelay, 1);
+                    _dragAllTimer.addEventListener(TimerEvent.TIMER, 
function(te:TimerEvent):void {
+                       if (!_selecting) { trace("* Hold Mouse DOWN - will 
drag...");
+                           
graphView.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpToDeselect);
+                           
graphView.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpToClick);
+                           
graphView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
+                           startDragGraph();
+                       }
+                    });
+                    _dragAllTimer.start();
+                }
                 
-                vis.startDrag();
-                graphView.addEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToStopPanning, false, 0, true);
-            } else if (!configProxy.grabToPanEnabled) {
                 // DRAG-SELECTION...
                 updateCursor();
                // Add the SELECTION CONTROL again:
-                selectionControl.detach();
-                selectionControl.attach(vis);
+                selectionControl.enabled = !dragging;
        
                if (_shiftDown) {
                        // If SHIFT is pressed, add selected nodes to the 
selection group, thus
@@ -459,31 +454,32 @@
                            // TODO: filter edges OR nodes based on config param
                                return d is DataSprite && 
!DataSprite(d).props.$selected;
                        }
-               } else if (graphProxy.rolledOverEdge == null) {
+               } else if (!dragging && graphProxy.rolledOverEdge == null) {
                        // TODO: edges OR nodes based on config param
                        selectionControl.filter = DataSprite;
-                       graphView.addEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToDeselect, false, 0, true);
+                       graphView.stage.addEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToDeselect, false, 0, true);
                }
 
-                graphView.addEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToClick, false, 0, true);
-                graphView.addEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart, false, 0, true);
+                graphView.stage.addEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToClick, false, 0, true);
+                graphView.stage.addEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart, false, 0, true);
             }
         }
         
         private function onMouseUpToClick(evt:MouseEvent):void { trace("* 
Mouse UP / CLICK [View]");
             evt.currentTarget.removeEventListener(evt.type, arguments.callee);
+            if (_dragAllTimer != null && _dragAllTimer.running) 
_dragAllTimer.stop();
+            graphView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
             sendNotification(ApplicationFacade.CLICK_EVENT, { mouseX: 
evt.stageX, mouseY: evt.stageY });
         }
         
         private function onMouseUpToDeselect(evt:MouseEvent):void { trace("* 
Mouse UP / Deselect all [View]");
             evt.currentTarget.removeEventListener(evt.type, arguments.callee);
-            graphView.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
             sendNotification(ApplicationFacade.DESELECT_ALL, Groups.NONE);
         }
         
         private function onMouseUpToStopPanning(evt:MouseEvent):void { 
trace("* Mouse UP / STOP PANNING [View]");
             evt.currentTarget.removeEventListener(evt.type, arguments.callee);
-            graphView.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
+            graphView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
             vis.stopDrag();
             _draggingGraph = false;
             if (_isMouseOverView) updateCursor();
@@ -500,9 +496,10 @@
         
         private function onDragSelectionStart(evt:MouseEvent):void { trace("* 
Drag Selection START [View]");
             evt.currentTarget.removeEventListener(evt.type, arguments.callee);
-            graphView.addEventListener(MouseEvent.MOUSE_UP, 
onDragSelectionEnd, false, 0, true);
-            graphView.removeEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToDeselect);
-            graphView.removeEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToClick);
+            if (_dragAllTimer != null && _dragAllTimer.running) 
_dragAllTimer.stop();
+            graphView.stage.addEventListener(MouseEvent.MOUSE_UP, 
onDragSelectionEnd, false, 0, true);
+            graphView.stage.removeEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToDeselect);
+            graphView.stage.removeEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToClick);
 
             // If SHIFT key is pressed, keep the previously selected elements.
             // Otherwise, deselect everything first:
@@ -520,7 +517,7 @@
         // NODE listener functions:
         // 
-----------------------------------------------------------------------------------------
         private function onRollOverNode(evt:MouseEvent):void {
-            if (_draggingNode || _draggingGraph || _selecting) return;
+            if (_draggingNode || dragging || _selecting) return;
 
             var n:NodeSprite = evt.target as NodeSprite;
             n.addEventListener(MouseEvent.ROLL_OUT, onRollOutNode, false, 0, 
true);
@@ -530,12 +527,10 @@
             
             // When zoom < 100%, increase the label size to make it readable:
             if (_graphScale < 1) rescaleNodeLabel(n);
-            
-            if (_ctrlDown) vis.showDragRectangle(n);
         }
         
         private function onRollOutNode(evt:MouseEvent):void {
-            if (_draggingNode || _draggingGraph || _selecting) return;
+            if (dragging || _selecting) return;
 
             var n:NodeSprite = evt.target as NodeSprite;
             sendNotification(ApplicationFacade.ROLLOUT_EVENT, n);
@@ -545,26 +540,31 @@
             evt.stopImmediatePropagation();
 
             rescaleNodeLabel(n, true);
-            vis.hideDragRectangle();
         }
         
         private function onMouseDownNode(evt:MouseEvent):void { trace("** 
Mouse DOWN [node]");
             var n:NodeSprite = evt.target as NodeSprite;
+            
+            if (configProxy.mouseDownToDragDelay >= 0) {
+                _dragAllTimer = new Timer(configProxy.mouseDownToDragDelay, 1);
+                _dragAllTimer.addEventListener(TimerEvent.TIMER, 
function(te:TimerEvent):void {
+                   trace("* Hold Mouse DOWN - will drag part...");
+                    _draggingComponent = true;
+                    updateCursor();
+                    vis.showDragRectangle(n);
+                    var data:Data = vis.getDisconnectedData(n);
+                    graphView.bringAllToFront(data.nodes);
+                    graphView.bringToFront(n);
+                });
+                _dragAllTimer.start();
+            }
+            
             n.addEventListener(MouseEvent.MOUSE_UP, onMouseUpNode, false, 0, 
true);
             n.addEventListener(MouseEvent.CLICK, onClickNode, false, 0, true);
             // Remove the SELECTION CONTROL:
-            selectionControl.detach();
+            selectionControl.enabled = false;
             // To avoid clicking the background:
-            graphView.removeEventListener(MouseEvent.MOUSE_DOWN, 
onMouseDownView);
-  
-            // Dragging a disconnected component?
-            if (_ctrlDown) {
-                _draggingGraph = true;
-                updateCursor();
-                vis.showDragRectangle(n);
-                var data:Data = vis.getDisconnectedData(n);
-                graphView.bringAllToFront(data.nodes);
-            }
+            graphView.stage.removeEventListener(MouseEvent.MOUSE_DOWN, 
onMouseDownView);
             // Bring the target and the node to front:
             graphView.bringToFront(n);
         }
@@ -572,20 +572,19 @@
         private function onMouseUpNode(evt:MouseEvent):void { trace("** Mouse 
UP [node]");
             evt.currentTarget.removeEventListener(evt.type, arguments.callee);
             var n:NodeSprite = evt.target as NodeSprite;
-            
             _draggingGraph = false;
             updateCursor();
-            if (_ctrlDown) vis.showDragRectangle(n);
-            
             // Return the MOUSE DOWN to the View, so panning is possible again:
-            graphView.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownView, 
false, 0, true);
+            graphView.stage.addEventListener(MouseEvent.MOUSE_DOWN, 
onMouseDownView, false, 0, true);
         }
         
         private function onClickNode(evt:MouseEvent):void { trace("** CLICK 
[node]");
             evt.currentTarget.removeEventListener(evt.type, arguments.callee);
             evt.stopImmediatePropagation();
             
-            if (!_draggingGraph && !evt.ctrlKey) {
+            if (!dragging) {
+                if (_dragAllTimer != null && _dragAllTimer.running) 
_dragAllTimer.stop();
+                
                 var n:NodeSprite = evt.target as NodeSprite;
                 sendNotification(ApplicationFacade.CLICK_EVENT,
                                  { target: n, mouseX: evt.stageX, mouseY: 
evt.stageY });
@@ -606,25 +605,25 @@
         }
         
         private function onDoubleClickNode(evt:MouseEvent):void { trace("** 
2-CLICK [node]");
-            if (!_ctrlDown) {
-                var n:NodeSprite = evt.target as NodeSprite;
-                sendNotification(ApplicationFacade.DOUBLE_CLICK_EVENT,
-                                 { target: n, mouseX: evt.stageX, mouseY: 
evt.stageY });
-            }
+            var n:NodeSprite = evt.target as NodeSprite;
+            sendNotification(ApplicationFacade.DOUBLE_CLICK_EVENT,
+                             { target: n, mouseX: evt.stageX, mouseY: 
evt.stageY });
             evt.stopImmediatePropagation();
         }
         
         private function onDragNodeStart(evt:DragEvent):void { trace("== START 
Drag Node");
-            _draggingNode = true;
-            updateCursor();
+            if (!_draggingComponent) {
+                if (_dragAllTimer != null && _dragAllTimer.running) 
_dragAllTimer.stop();
+                _draggingNode = true;
+                updateCursor();
+            }
             evt.node.removeEventListener(MouseEvent.CLICK, onClickNode);
         }
         
         private function onDragNodeEnd(evt:DragEvent):void { trace("== END 
Drag Node");
+            if (_draggingComponent) vis.hideDragRectangle();
             _draggingNode = false;
-            _draggingGraph = false;
-            if (!_ctrlDown || graphProxy.rolledOverNode == null)
-                vis.hideDragRectangle();
+            _draggingComponent = false;
             updateCursor();
             
             // Fix a bug on Safari when mouse-up occurs out of the Flash area, 
which ends the
@@ -638,8 +637,7 @@
             var target:NodeSprite = evt.node;
             var nodes:*;
 
-            if (_ctrlDown) {
-                _draggingGraph = true;
+            if (_draggingComponent) {
                 var data:Data = vis.getDisconnectedData(target);
                 nodes = data.nodes;
             } else if (target.props.$selected) {
@@ -674,7 +672,7 @@
                 if (configProxy.edgeLabelsVisible) 
graphView.updateLabels(Groups.EDGES);
             }
             
-            vis.updateDragRectangle(amountX, amountY);
+            if (_draggingComponent) vis.updateDragRectangle(amountX, amountY);
         }
         
         private function onSelect(evt:SelectionEvent):void {
@@ -704,18 +702,18 @@
         }
         
         private function onMouseDownEdge(evt:MouseEvent):void { trace("** 
Mouse DOWN [edge]");
-            if (!_draggingGraph && !_ctrlDown) {
+            if (!_draggingGraph) {
                 var e:EdgeSprite = evt.target as EdgeSprite;
                 e.addEventListener(MouseEvent.CLICK, onClickEdge, false, 0, 
true);
                 // Remove the SELECTION CONTROL:
-                selectionControl.detach();
+                selectionControl.enabled = false;
             }
         }
         
         private function onClickEdge(evt:MouseEvent):void { trace("** Click 
[edge]");
             evt.currentTarget.removeEventListener(evt.type, arguments.callee);
             
-            if (!_draggingGraph && !_ctrlDown) {
+            if (!_draggingGraph) {
                 var edge:EdgeSprite = evt.target as EdgeSprite;
                 if (edge == null) return;
                 
@@ -737,23 +735,29 @@
                 }
             }
             
-            graphView.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
+            graphView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
             evt.stopImmediatePropagation();
         }
         
         private function onDoubleClickEdge(evt:MouseEvent):void { trace("** 
2-CLICK [edge] : " + evt.target);
-            if (!_ctrlDown) {
-                var e:EdgeSprite = evt.target as EdgeSprite;
-                sendNotification(ApplicationFacade.DOUBLE_CLICK_EVENT,
-                                 { target: e, mouseX: evt.stageX, mouseY: 
evt.stageY });
-            }
-            graphView.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
+            var e:EdgeSprite = evt.target as EdgeSprite;
+            sendNotification(ApplicationFacade.DOUBLE_CLICK_EVENT,
+                             { target: e, mouseX: evt.stageX, mouseY: 
evt.stageY });
+            graphView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, 
onDragSelectionStart);
             evt.stopImmediatePropagation();
         }
         
         // OTHER functions:
         // 
-----------------------------------------------------------------------------------------
         
+        private function startDragGraph():void {
+            _draggingGraph = true;
+            updateCursor();
+            selectionControl.enabled = false;
+            vis.startDrag();
+            graphView.stage.addEventListener(MouseEvent.MOUSE_UP, 
onMouseUpToStopPanning, false, 0, true);
+        }
+        
         private function rescaleNodeLabel(n:NodeSprite, 
reset:Boolean=false):void {
             if (n != null && configProxy.config.nodeLabelsVisible) {
                 var label:TextSprite = n.props.label as TextSprite;
@@ -827,8 +831,8 @@
             sendNotification(ApplicationFacade.UPDATE_CURSOR, { selecting: 
_selecting,
                                                                 draggingNode: 
_draggingNode,
                                                                 draggingGraph: 
_draggingGraph,
-                                                                shiftDown: 
_shiftDown,
-                                                                ctrlDown: 
_ctrlDown });
+                                                                
draggingComponent: _draggingComponent,
+                                                                shiftDown: 
_shiftDown });
         }
     }
 }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/PanZoomMediator.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/PanZoomMediator.as    
    2010-09-02 21:46:06 UTC (rev 21670)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/PanZoomMediator.as    
    2010-09-02 21:48:03 UTC (rev 21671)
@@ -138,30 +138,13 @@
         // ========[ PRIVATE METHODS 
]==============================================================
 
         private function onComplete(evt:Event):void {
-            panZoomBox.stage.addEventListener(KeyboardEvent.KEY_DOWN, 
onKeyDown, false, 0, true);
-            panZoomBox.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp, 
false, 0, true);
+            // Initialization stuff here...
         }
 
-        private function onKeyDown(evt:KeyboardEvent):void {
-            if (evt.keyCode === Keyboard.CONTROL)
-                panZoomBox.panButton.selected = true;
-        }
-        
-        private function onKeyUp(evt:KeyboardEvent):void {
-            if (!configProxy.grabToPanEnabled && evt.keyCode === 
Keyboard.CONTROL)
-                panZoomBox.panButton.selected = false;
-        }
-
            private function onPanToggleClick(e:MouseEvent):void {
             e.stopImmediatePropagation();
             var bt:Button = e.target as Button;
-            
-               if (!e.ctrlKey) {
-                sendNotification(ApplicationFacade.ENABLE_GRAB_TO_PAN, 
bt.selected);
-            } else {
-                // Just keep the correct button state...
-                bt.selected = configProxy.grabToPanEnabled || !bt.selected;
-            }
+            sendNotification(ApplicationFacade.ENABLE_GRAB_TO_PAN, 
bt.selected);
            }
            
            private function onPanMouseDown(e:Event):void {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphVis.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphVis.as
    2010-09-02 21:46:06 UTC (rev 21670)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphVis.as
    2010-09-02 21:48:03 UTC (rev 21671)
@@ -390,7 +390,7 @@
             return bounds;
         }
         
-        public function updateDragRectangle(...delta):void {
+               public function updateDragRectangle(...delta):void {
             if (_dragRect != null) {
                 var b:Rectangle = _dragRect;
                 if (delta.length > 1) {
@@ -426,7 +426,7 @@
                 graphics.clear();
             }
         }
-        
+
         // ========[ PRIVATE METHODS 
]==============================================================
         
         /**
@@ -461,6 +461,8 @@
                 fdl.simulation.nbodyForce.maxDistance = options.maxDistance;
                 fdl.defaultParticleMass = options.mass;
                 fdl.defaultSpringTension = options.tension;
+                fdl.minWeight = options.minWeight;
+                fdl.maxWeight = options.maxWeight;
 
                 var length:Number = options.restLength;
                 var el:uint = data.edges.length;

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/controls/EnclosingSelectionControl.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/controls/EnclosingSelectionControl.as
     2010-09-02 21:46:06 UTC (rev 21670)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/controls/EnclosingSelectionControl.as
     2010-09-02 21:48:03 UTC (rev 21671)
@@ -58,6 +58,7 @@
         
         private var _r:Rectangle = new Rectangle();
         private var _drag:Boolean = false;
+        private var _enabled:Boolean = true;
         private var _shape:Shape = new Shape();
         private var _hit:InteractiveObject;
         private var _stage:Stage;
@@ -88,6 +89,14 @@
          */
         public var fireImmediately:Boolean = true;
         
+        public function get enabled():Boolean {
+            return _enabled;
+        }
+        public function set enabled(val:Boolean):void {
+            _enabled = val;
+            if (!_enabled) stopSelection();
+        }
+        
         /** Line color of the selection region border. */
         public var lineColor:uint = 0x8888FF;
         /** Line alpha of the selection region border. */
@@ -168,8 +177,9 @@
         }
         
         private function onRemove(evt:Event=null):void {
-            if (_hit)
+            if (_hit) {
                 _hit.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
+            }
         }
                 
         private function mouseDown(evt:MouseEvent):void {
@@ -185,18 +195,21 @@
             
             DisplayObjectContainer(_object).addChild(_shape);
             renderShape(_shape.graphics);
-            if (fireImmediately) {
-                selectionTest(evt);
-            } else if (!evt.shiftKey) {
-                // ALTERED: if SHIFT key is not pressed, it should reset 
everything first:
-                _rem = _add = null;
-                _rem0 = _add0 = null;
-                _sel = new Dictionary();
+            
+            if (_enabled) {
+                if (fireImmediately) {
+                    selectionTest(evt);
+                } else if (!evt.shiftKey) {
+                    // ALTERED: if SHIFT key is not pressed, it should reset 
everything first:
+                    _rem = _add = null;
+                    _rem0 = _add0 = null;
+                    _sel = new Dictionary();
+                }
             }
         }
         
         private function mouseMove(evt:MouseEvent):void {
-            if (!_drag) return;
+            if (!enabled || !_drag || _object == null) return;
             _r.width = _object.mouseX - _r.x;
             _r.height = _object.mouseY - _r.y;
             
@@ -207,20 +220,31 @@
         }
         
         private function mouseUp(evt:MouseEvent):void {
+            if (!enabled) return;
             if (!fireImmediately)
                 selectionTest(evt);
+            stopSelection();
+        }
+        
+        private function stopSelection():void {
+            if (_drag) {
+                DisplayObjectContainer(_object).removeChild(_shape);
+            }
+            if (_stage != null) {
+                _stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
+                _stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
+            }
             _drag = false;
-            DisplayObjectContainer(_object).removeChild(_shape);
-            _stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
-            _stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
         }
         
         private function renderShape(g:Graphics):void {
             g.clear();
-            g.beginFill(fillColor, fillAlpha);
-            g.lineStyle(lineWidth, lineColor, lineAlpha, true, "none");
-            g.drawRect(_r.x, _r.y, _r.width, _r.height);
-            g.endFill();
+            if (_enabled) {
+                g.beginFill(fillColor, fillAlpha);
+                g.lineStyle(lineWidth, lineColor, lineAlpha, true, "none");
+                g.drawRect(_r.x, _r.y, _r.width, _r.height);
+                g.endFill();
+            }
         }
         
         private function selectionTest(evt:MouseEvent):void {           

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/controls/EventDragControl.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/controls/EventDragControl.as
      2010-09-02 21:46:06 UTC (rev 21670)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/controls/EventDragControl.as
      2010-09-02 21:48:03 UTC (rev 21671)
@@ -122,7 +122,6 @@
                    event.stopPropagation();
                    
                }
-               
            }
            
            private function _onDrag(event:Event) : void {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/layout/ForceDirectedLayout.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/layout/ForceDirectedLayout.as
     2010-09-02 21:46:06 UTC (rev 21670)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/layout/ForceDirectedLayout.as
     2010-09-02 21:48:03 UTC (rev 21671)
@@ -63,7 +63,7 @@
         public static const LOG_WEIGHT:String = "log";
         
         protected static const MIN_SPRING_WEIGHT:Number = 0.1;
-        protected static const MAX_SPRING_WEIGHT:Number = 1.1;
+        protected static const MAX_SPRING_WEIGHT:Number = 0.9;
         
         // ========[ PRIVATE PROPERTIES 
]===========================================================
 
@@ -74,6 +74,8 @@
         private var _weightAttr:String;
         private var _weightNormalization:String;
         private var _weighted:Boolean;
+        private var _minWeight:Number;
+        private var _maxWeight:Number;
         
         private var _eLengths:/*edge_id->length*/Object;
 
@@ -87,8 +89,16 @@
         /** The name of the edge attribute that contains the weights. */
         public function get weightAttr():String { return _weightAttr; }
         public function get weightNormalization():String { return 
_weightNormalization; }
-        public function get weighted():Boolean { return _weighted }
+        public function get weighted():Boolean { return _weighted; }
         
+        /** The minimum edge weight to consider, if the layout is set to be 
weighted. */
+        public function get minWeight():Number { return _minWeight; }
+        public function set minWeight(min:Number):void { _minWeight = min; }
+        
+        /** The maximum edge weight to consider, if the layout is set to be 
weighted */
+        public function get maxWeight():Number { return _maxWeight; }
+        public function set maxWeight(max:Number):void { _maxWeight = max; }
+        
         public function get edges():DataList { return 
visualization.data.group(Groups.MERGED_EDGES); }
 
         // ========[ CONSTRUCTOR 
]==================================================================
@@ -119,14 +129,16 @@
             
             this.restLength = function(e:EdgeSprite):Number {
                 var rl:Number = defaultSpringLength;
-                if (weighted && !isNaN(e.props.springWeight)) {
+                var sw:Number = e.props.springWeight;
+                
+                if (weighted && !isNaN(sw)) {
                     switch (edgeWeightNormalization) {
                         case INV_NORMALIZED_WEIGHT:
-                            rl /= (MIN_SPRING_WEIGHT + MAX_SPRING_WEIGHT - 
e.props.springWeight); break;
+                            rl /= (MIN_SPRING_WEIGHT + MAX_SPRING_WEIGHT - 
sw); break;
                         case LOG_WEIGHT:
                             // TODO...
                         default: // normalized...
-                            rl /= e.props.springWeight;
+                            if (sw !== 0) rl /= sw;
                     }
                 }
                 return Math.max(1, rl);
@@ -283,8 +295,11 @@
             });
             
             // Minimum and maximum weight values for the current edges set:
-            var minW:Number = Number.POSITIVE_INFINITY;
-            var maxW:Number = Number.NEGATIVE_INFINITY;
+            var computeMin:Boolean = isNaN(minWeight); // User didn't set the 
min weight
+            var computeMax:Boolean = isNaN(maxWeight);
+            
+            if (computeMin) minWeight = Number.POSITIVE_INFINITY;
+            if (computeMax) maxWeight = Number.NEGATIVE_INFINITY;
             var ew:Number;
             
             $each(edges, function(i:uint, e:EdgeSprite):void {
@@ -299,12 +314,11 @@
 
                 s.tag = _gen;
                 
-                
                 if (weighted && !GraphUtils.isFilteredOut(e)) {
                     // Get min and max weights - filtered-in edges only!
                     ew = e.data[weightAttr];
-                    minW = Math.min(ew, minW);
-                    maxW = Math.max(ew, maxW);
+                    if (computeMin) minWeight = Math.min(ew, minWeight);
+                    if (computeMax) maxWeight = Math.max(ew, maxWeight);
                 }
             });
             
@@ -318,15 +332,30 @@
                 });
             }
 
+            var mediumSpringWeight:Number = (MAX_SPRING_WEIGHT - 
MIN_SPRING_WEIGHT) / 2;
+
             $each(edges, function(i:uint, e:EdgeSprite):void {
                 s = e.props.spring;
-              
+                var sw:Number;
+                
                 if (weighted) {
+                    ew = e.data[weightAttr];
+
                     // Normalize min and max weights for better visual results 
(always between 0 and 1):
-                    var f:Number = Maths.invLinearInterp(e.data[weightAttr], 
minW, maxW);
-                    e.props.springWeight  = Maths.linearInterp(f, 
MIN_SPRING_WEIGHT, MAX_SPRING_WEIGHT);
+                    if (minWeight === maxWeight) {
+                        sw = mediumSpringWeight;
+                    } else if (ew < minWeight) {
+                        sw = MIN_SPRING_WEIGHT;
+                    } else if (ew > maxWeight) {
+                        sw = MAX_SPRING_WEIGHT;
+                    } else {
+                        var f:Number = Maths.invLinearInterp(ew, minWeight, 
maxWeight);
+                        sw = Maths.linearInterp(f, MIN_SPRING_WEIGHT, 
MAX_SPRING_WEIGHT);
+                    }
                 }
                 
+                e.props.springWeight = sw;
+                
                 if (restLength != null)
                     s.restLength = restLength(e);
                 if (tension != null)

-- 
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