001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.swing.gvt;
020:
021: import java.awt.Dimension;
022: import java.awt.event.InputEvent;
023: import java.awt.event.MouseEvent;
024: import java.awt.geom.AffineTransform;
025:
026: /**
027: * This class represents a rotate interactor.
028: * To use it, just redefine the {@link
029: * InteractorAdapter#startInteraction(InputEvent)} method.
030: *
031: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
032: * @version $Id: AbstractRotateInteractor.java 475477 2006-11-15 22:44:28Z cam $
033: */
034: public class AbstractRotateInteractor extends InteractorAdapter {
035:
036: /**
037: * Whether the interactor has finished.
038: */
039: protected boolean finished;
040:
041: /**
042: * The initial rotation angle.
043: */
044: protected double initialRotation;
045:
046: /**
047: * Tells whether the interactor has finished.
048: */
049: public boolean endInteraction() {
050: return finished;
051: }
052:
053: // MouseListener ///////////////////////////////////////////////////////
054:
055: /**
056: * Invoked when a mouse button has been pressed on a component.
057: */
058: public void mousePressed(MouseEvent e) {
059: finished = false;
060: JGVTComponent c = (JGVTComponent) e.getSource();
061:
062: Dimension d = c.getSize();
063: double dx = e.getX() - d.width / 2;
064: double dy = e.getY() - d.height / 2;
065: double cos = -dy / Math.sqrt(dx * dx + dy * dy);
066: initialRotation = (dx > 0) ? Math.acos(cos) : -Math.acos(cos);
067: }
068:
069: /**
070: * Invoked when a mouse button has been released on a component.
071: */
072: public void mouseReleased(MouseEvent e) {
073: finished = true;
074: JGVTComponent c = (JGVTComponent) e.getSource();
075:
076: AffineTransform at = rotateTransform(c.getSize(), e.getX(), e
077: .getY());
078: at.concatenate(c.getRenderingTransform());
079: c.setRenderingTransform(at);
080: }
081:
082: /**
083: * Invoked when the mouse exits a component.
084: */
085: public void mouseExited(MouseEvent e) {
086: finished = true;
087: JGVTComponent c = (JGVTComponent) e.getSource();
088: c.setPaintingTransform(null);
089: }
090:
091: // MouseMotionListener /////////////////////////////////////////////////
092:
093: /**
094: * Invoked when a mouse button is pressed on a component and then
095: * dragged. Mouse drag events will continue to be delivered to
096: * the component where the first originated until the mouse button is
097: * released (regardless of whether the mouse position is within the
098: * bounds of the component).
099: */
100: public void mouseDragged(MouseEvent e) {
101: JGVTComponent c = (JGVTComponent) e.getSource();
102:
103: c.setPaintingTransform(rotateTransform(c.getSize(), e.getX(), e
104: .getY()));
105: }
106:
107: /**
108: * Returns the rotate transform.
109: */
110: protected AffineTransform rotateTransform(Dimension d, int x, int y) {
111: double dx = x - d.width / 2;
112: double dy = y - d.height / 2;
113: double cos = -dy / Math.sqrt(dx * dx + dy * dy);
114: double angle = (dx > 0) ? Math.acos(cos) : -Math.acos(cos);
115:
116: angle -= initialRotation;
117:
118: return AffineTransform.getRotateInstance(angle, d.width / 2,
119: d.height / 2);
120: }
121: }
|