View Javadoc

1   /*
2    * TouchGraph Software License
3    *
4    *
5    * Copyright (c) 2001 Alexander Shapiro. All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer.
13   *
14   * 2. Redistributions in binary form must reproduce the above copyright
15   *    notice, this list of conditions and the following disclaimer in
16   *    the documentation and/or other materials provided with the
17   *    distribution.
18   *
19   * 3. The end-user documentation included with the redistribution,
20   *    if any, must include the following acknowledgment:
21   *       "This product includes software developed by
22   *        TouchGraph (http://www.touchgraph.com/)."
23   *    Alternately, this acknowledgment may appear in the software itself,
24   *    if and wherever such third-party acknowledgments normally appear.
25   *
26   * 4. The name "TouchGraph" must not be used to endorse or promote
27   *    products derived from this software without prior written
28   *    permission.  For written permission, please contact
29   *    alex@touchgraph.com
30   *
31   * 5. Products derived from this software may not be called "TouchGraph",
32   *    nor may "TouchGraph" appear in their name, without prior written
33   *    permission of TouchGraph.
34   *
35   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38   * DISCLAIMED.  IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE
39   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
40   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
43   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
44   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
45   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46   * =====================================================================
47   *
48   */
49  
50  package com.touchgraph.graphlayout.interaction;
51  
52  import java.awt.*;
53  import java.awt.event.MouseEvent;
54  
55  import com.touchgraph.graphlayout.*;
56  
57  /*** HVRotateDragUI.  A combination of HVScrolling + rotating.
58    * The graph is rotated, but the mouse is always kept on the same point
59    * on the graph.
60    *
61    * @author   Alexander Shapiro
62    * @version  1.06
63    */
64  public class HVRotateDragUI extends TGAbstractDragUI implements TGPaintListener {
65  
66      HVScroll hvScroll;
67      RotateScroll rotateScroll;
68      Node mouseOverN;
69      Node tempNode;
70  
71      TGPoint2D lastMousePos;
72      double lastAngle;
73  
74    // ............
75  
76     /*** Constructor with TGPanel <tt>tgp</tt>, HVScroll <tt>hvs</tt>
77       * and a RotateScroll <tt>rs</tt>.
78       */
79      public HVRotateDragUI( TGPanel tgp, HVScroll hvs, RotateScroll rs ) {
80          super(tgp);
81          hvScroll = hvs;
82          rotateScroll = rs;
83      }
84  
85      double graphDist(double x, double y) {
86          double adjx=(x-this.tgPanel.getDrawCenter().x);
87          double adjy=(y-this.tgPanel.getDrawCenter().y);
88          return Math.sqrt(adjx*adjx+adjy*adjy);
89      }
90  
91      double getMouseAngle(double x, double y) {
92          double adjx=(x-this.tgPanel.getDrawCenter().x);
93          double adjy=(y-this.tgPanel.getDrawCenter().y);
94          double ang = Math.atan(adjy/adjx);
95          if (adjx==0)
96              if(adjy>0) ang=Math.PI/2;
97              else ang=-Math.PI/2;
98          if(adjx<0) ang=ang+Math.PI;
99          return ang;
100     }
101 
102     public void preActivate() {
103         tgPanel.addPaintListener(this);
104     }
105 
106     public void preDeactivate() {
107         tgPanel.removePaintListener(this);
108         tgPanel.repaint();
109     }
110 
111     public void mousePressed(MouseEvent e) {
112         mouseOverN=tgPanel.getMouseOverN();
113         if (mouseOverN!=null) {
114             lastMousePos = new TGPoint2D(mouseOverN.drawx, mouseOverN.drawy);
115             lastAngle = getMouseAngle(mouseOverN.drawx, mouseOverN.drawy);
116         } else {
117             tempNode=new Node(); //A hack, until lenses are better implemented
118                                  //One should keep track of a real position on the graph
119                                  //As opposed to having a temporary node do this task.
120             tempNode.drawx = e.getX();
121             tempNode.drawy = e.getY();
122             tgPanel.updatePosFromDraw(tempNode);
123             lastMousePos = new TGPoint2D(tempNode.drawx, tempNode.drawy);
124             lastAngle = getMouseAngle(tempNode.drawx, tempNode.drawy);
125         }
126     }
127 
128     public void mouseReleased( MouseEvent e ) {}
129 
130     public void mouseDragged( MouseEvent e ) {
131         double currX = e.getX();
132         double currY = e.getY();
133         double currDist = graphDist(currX,currY);
134 
135         if (mouseOverN!=null)
136             lastAngle = getMouseAngle(mouseOverN.drawx, mouseOverN.drawy);
137         else
138             lastAngle = getMouseAngle(tempNode.drawx, tempNode.drawy);
139 
140         double currentAngle = getMouseAngle(currX, currY);
141         if(lastAngle>currentAngle+Math.PI) currentAngle+=Math.PI*2; //Avoids bug at x==0
142         else if(currentAngle>lastAngle+Math.PI) lastAngle+=Math.PI*2;
143 
144         if (currDist>60) rotateScroll.incrementRotateAngle((currentAngle-lastAngle));
145 
146         tgPanel.updateDrawPositions(); //Rotate, but don't redraw
147         tgPanel.updateGraphSize(); //Just in case.  Mostly effects H+V Scrollbars
148 
149         if(tempNode!=null) tgPanel.updateDrawPos(tempNode); //The temporary node is not part of the graph,
150                                                             //So it needs to be updated individually
151         TGPoint2D lastMousePos;
152         if(mouseOverN!=null)
153             lastMousePos = new TGPoint2D(mouseOverN.drawx, mouseOverN.drawy);
154         else
155             lastMousePos = new TGPoint2D(tempNode.drawx, tempNode.drawy);
156 
157         TGPoint2D newPos = new TGPoint2D(currX,currY);
158 
159         if (!hvScroll.scrolling) hvScroll.scrollAtoB(lastMousePos, newPos); //Scroll the node to the mouse
160 
161         this.tgPanel.repaintAfterMove();
162 
163         if(tempNode!=null) tgPanel.updateDrawPos(tempNode); //The temporary node is not part of the graph,
164                                                             //So it needs to be updated individually
165     }
166 
167     public void paintFirst( Graphics g ) {
168         TGPoint2D drawCenter = tgPanel.getDrawCenter();
169         g.setColor(Color.lightGray);
170         for(int i=0;i<16;i++) {
171             double ang = Math.PI*2*i/16;
172             double rayX = 1000*Math.cos(ang);
173             double rayY = 1000*Math.sin(ang);
174             g.drawLine((int) drawCenter.x, (int) drawCenter.y,
175                        (int) (rayX+drawCenter.x),(int) (rayY+drawCenter.y));
176             g.drawLine((int) drawCenter.x+1, (int) drawCenter.y,
177                        (int) (rayX+drawCenter.x+1),(int) (rayY+drawCenter.y));
178             g.drawLine((int) drawCenter.x, (int) drawCenter.y+1,
179                        (int) (rayX+drawCenter.x),(int) (rayY+drawCenter.y+1));
180             g.drawLine((int) drawCenter.x+1, (int) drawCenter.y+1,
181                        (int) (rayX+drawCenter.x+1),(int) (rayY+drawCenter.y+1));
182         }
183 
184 
185         g.fillOval((int)drawCenter.x-60, (int) drawCenter.y-60, 120,120);
186         g.setColor(TGPanel.BACK_COLOR);
187         g.fillOval((int)drawCenter.x-58, (int) drawCenter.y-58, 116,116);
188 
189     }
190 
191     public void paintLast( Graphics g ) {}
192     public void paintAfterEdges( Graphics g ) {}
193 
194 } // end com.touchgraph.graphlayout.interaction.HVRotateDragUI