/* * TouchGraph Software License * * * Copyright (c) 2001 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The name "TouchGraph" must not be used to endorse or promote * products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of TouchGraph. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ===================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.awt.event.*; /** HVRotateDragUI. A combination of HVScrolling + rotating. * The graph is rotated, but the mouse is always kept on the same point * on the graph. * * @author Alexander Shapiro * @version 1.06 */ public class HVRotateDragUI extends TGAbstractDragUI implements TGPaintListener { HVScroll hvScroll; RotateScroll rotateScroll; Node mouseOverN; Node tempNode; TGPoint2D lastMousePos; double lastAngle; // ............ /** Constructor with TGPanel <tt>tgp</tt>, HVScroll <tt>hvs</tt> * and a RotateScroll <tt>rs</tt>. */ public HVRotateDragUI( TGPanel tgp, HVScroll hvs, RotateScroll rs ) { super(tgp); hvScroll = hvs; rotateScroll = rs; } double graphDist(double x, double y) { double adjx=(x-this.tgPanel.getDrawCenter().x); double adjy=(y-this.tgPanel.getDrawCenter().y); return Math.sqrt(adjx*adjx+adjy*adjy); } double getMouseAngle(double x, double y) { double adjx=(x-this.tgPanel.getDrawCenter().x); double adjy=(y-this.tgPanel.getDrawCenter().y); double ang = Math.atan(adjy/adjx); if (adjx==0) if(adjy>0) ang=Math.PI/2; else ang=-Math.PI/2; if(adjx<0) ang=ang+Math.PI; return ang; } public void preActivate() { tgPanel.addPaintListener(this); } public void preDeactivate() { tgPanel.removePaintListener(this); tgPanel.repaint(); } public void mousePressed(MouseEvent e) { mouseOverN=tgPanel.getMouseOverN(); if (mouseOverN!=null) { lastMousePos = new TGPoint2D(mouseOverN.drawx, mouseOverN.drawy); lastAngle = getMouseAngle(mouseOverN.drawx, mouseOverN.drawy); } else { tempNode=new Node(); //A hack, until lenses are better implemented //One should keep track of a real position on the graph //As opposed to having a temporary node do this task. tempNode.drawx = e.getX(); tempNode.drawy = e.getY(); tgPanel.updatePosFromDraw(tempNode); lastMousePos = new TGPoint2D(tempNode.drawx, tempNode.drawy); lastAngle = getMouseAngle(tempNode.drawx, tempNode.drawy); } } public void mouseReleased( MouseEvent e ) {} public void mouseDragged( MouseEvent e ) { double currX = e.getX(); double currY = e.getY(); double currDist = graphDist(currX,currY); if (mouseOverN!=null) lastAngle = getMouseAngle(mouseOverN.drawx, mouseOverN.drawy); else lastAngle = getMouseAngle(tempNode.drawx, tempNode.drawy); double currentAngle = getMouseAngle(currX, currY); if(lastAngle>currentAngle+Math.PI) currentAngle+=Math.PI*2; //Avoids bug at x==0 else if(currentAngle>lastAngle+Math.PI) lastAngle+=Math.PI*2; if (currDist>60) rotateScroll.incrementRotateAngle((currentAngle-lastAngle)); tgPanel.updateDrawPositions(); //Rotate, but don't redraw tgPanel.updateGraphSize(); //Just in case. Mostly effects H+V Scrollbars if(tempNode!=null) tgPanel.updateDrawPos(tempNode); //The temporary node is not part of the graph, //So it needs to be updated individually TGPoint2D lastMousePos; if(mouseOverN!=null) lastMousePos = new TGPoint2D(mouseOverN.drawx, mouseOverN.drawy); else lastMousePos = new TGPoint2D(tempNode.drawx, tempNode.drawy); TGPoint2D newPos = new TGPoint2D(currX,currY); if (!hvScroll.scrolling) hvScroll.scrollAtoB(lastMousePos, newPos); //Scroll the node to the mouse this.tgPanel.repaintAfterMove(); if(tempNode!=null) tgPanel.updateDrawPos(tempNode); //The temporary node is not part of the graph, //So it needs to be updated individually } public void paintFirst( Graphics g ) { TGPoint2D drawCenter = tgPanel.getDrawCenter(); g.setColor(Color.lightGray); for(int i=0;i<16;i++) { double ang = Math.PI*2*i/16; double rayX = 1000*Math.cos(ang); double rayY = 1000*Math.sin(ang); g.drawLine((int) drawCenter.x, (int) drawCenter.y, (int) (rayX+drawCenter.x),(int) (rayY+drawCenter.y)); g.drawLine((int) drawCenter.x+1, (int) drawCenter.y, (int) (rayX+drawCenter.x+1),(int) (rayY+drawCenter.y)); g.drawLine((int) drawCenter.x, (int) drawCenter.y+1, (int) (rayX+drawCenter.x),(int) (rayY+drawCenter.y+1)); g.drawLine((int) drawCenter.x+1, (int) drawCenter.y+1, (int) (rayX+drawCenter.x+1),(int) (rayY+drawCenter.y+1)); } g.fillOval((int)drawCenter.x-60, (int) drawCenter.y-60, 120,120); g.setColor(tgPanel.BACK_COLOR); g.fillOval((int)drawCenter.x-58, (int) drawCenter.y-58, 116,116); } public void paintLast( Graphics g ) {} public void paintAfterEdges( Graphics g ) {} } // end com.touchgraph.graphlayout.interaction.HVRotateDragUI