1   /****************************************************************************
2    * This demo file is part of yFiles for Java 2.14.
3    * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28,
4    * 72070 Tuebingen, Germany. All rights reserved.
5    * 
6    * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution
7    * of demo files in source code or binary form, with or without
8    * modification, is not permitted.
9    * 
10   * Owners of a valid software license for a yFiles for Java version that this
11   * demo is shipped with are allowed to use the demo source code as basis
12   * for their own yFiles for Java powered applications. Use of such programs is
13   * governed by the rights and conditions as set out in the yFiles for Java
14   * license agreement.
15   * 
16   * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED
17   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19   * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21   * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   *
27   ***************************************************************************/
28  package demo.layout.organic;
29  
30  import y.base.Node;
31  import y.base.NodeCursor;
32  import y.view.Graph2DView;
33  import y.view.MoveSelectionMode;
34  import y.view.NodeRealizer;
35  import y.layout.organic.InteractiveOrganicLayouter;
36  
37  /**
38   * This moveSelection mode allows the user to easily drag nodes around.
39   */
40  public class InteractiveMoveSelectionMode extends MoveSelectionMode {
41    private InteractiveOrganicLayouter layouter;
42  
43    public InteractiveMoveSelectionMode( InteractiveOrganicLayouter layouter ) {
44      if ( layouter == null ) throw new IllegalArgumentException( "layouter must not be null" );
45      this.layouter = layouter;
46    }
47  
48    /**
49     * Called when the dragging has started.
50     * The node is locked and the position is updated.
51     */
52    protected void selectionMoveStarted( double x, double y ) {
53      view.setDrawingMode( Graph2DView.NORMAL_MODE );
54  
55      for ( NodeCursor nodeCursor = getGraph2D().selectedNodes(); nodeCursor.ok(); nodeCursor.next() ) {
56        Node node = nodeCursor.node();
57        NodeRealizer realizer = getGraph2D().getRealizer( node );
58        layouter.setCenter( node, realizer.getCenterX(), realizer.getCenterY() );
59  
60        layouter.setInertia( node, 1 );
61        increaseNeighborsHeat( node );
62      }
63      layouter.wakeUp();
64    }
65  
66    /**
67     * Called while the node is dragged.
68     */
69    protected void selectionOnMove( double dx, double dy, double x, double y ) {
70      for ( NodeCursor nodeCursor = getGraph2D().selectedNodes(); nodeCursor.ok(); nodeCursor.next() ) {
71        Node node = nodeCursor.node();
72        NodeRealizer realizer = getGraph2D().getRealizer( node );
73        layouter.setCenter( node, realizer.getCenterX(), realizer.getCenterY() );
74        increaseNeighborsHeat( node );
75      }
76      layouter.wakeUp();
77    }
78  
79    /**
80     * When the dragging ends.
81     * The lock on the node is removed
82     */
83    protected void selectionMovedAction( double dx, double dy, double x, double y ) {
84      for ( NodeCursor nodeCursor = getGraph2D().selectedNodes(); nodeCursor.ok(); nodeCursor.next() ) {
85        Node node = nodeCursor.node();
86        NodeRealizer realizer = getGraph2D().getRealizer( node );
87        layouter.setCenter( node, realizer.getCenterX(), realizer.getCenterY() );
88  
89        layouter.setInertia( node, 0 );
90        increaseNeighborsHeat( node );
91      }
92      layouter.wakeUp();
93    }
94  
95    /**
96     * Increases the neighbors heat
97     * @param originalNode
98     */
99    protected void increaseNeighborsHeat( Node originalNode ) {
100     //Increase Heat of neighbors
101     for ( NodeCursor cursor = originalNode.neighbors(); cursor.ok(); cursor.next() ) {
102       Node neighbor = cursor.node();
103 
104       double oldStress = layouter.getStress( neighbor );
105       layouter.setStress( neighbor, Math.min( 1, oldStress + 0.5 ) );
106     }
107   }
108 }
109