001: /*
002: * $RCSfile: MouseTranslate.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.4 $
041: * $Date: 2007/02/09 17:20:13 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.utils.behaviors.mouse;
046:
047: import java.awt.*;
048: import java.awt.event.*;
049: import java.util.*;
050: import javax.media.j3d.*;
051: import javax.vecmath.*;
052:
053: /**
054: * MouseTranslate is a Java3D behavior object that lets users control the
055: * translation (X, Y) of an object via a mouse drag motion with the third
056: * mouse button (alt-click on PC). See MouseRotate for similar usage info.
057: */
058:
059: public class MouseTranslate extends MouseBehavior {
060:
061: double x_factor = .02;
062: double y_factor = .02;
063: Vector3d translation = new Vector3d();
064:
065: private MouseBehaviorCallback callback = null;
066:
067: /**
068: * Creates a mouse translate behavior given the transform group.
069: * @param transformGroup The transformGroup to operate on.
070: */
071: public MouseTranslate(TransformGroup transformGroup) {
072: super (transformGroup);
073: }
074:
075: /**
076: * Creates a default translate behavior.
077: */
078: public MouseTranslate() {
079: super (0);
080: }
081:
082: /**
083: * Creates a translate behavior.
084: * Note that this behavior still needs a transform
085: * group to work on (use setTransformGroup(tg)) and
086: * the transform group must add this behavior.
087: * @param flags
088: */
089: public MouseTranslate(int flags) {
090: super (flags);
091: }
092:
093: /**
094: * Creates a translate behavior that uses AWT listeners and behavior
095: * posts rather than WakeupOnAWTEvent. The behavior is added to the
096: * specified Component. A null component can be passed to specify
097: * the behavior should use listeners. Components can then be added
098: * to the behavior with the addListener(Component c) method.
099: * @param c The Component to add the MouseListener
100: * and MouseMotionListener to.
101: * @since Java 3D 1.2.1
102: */
103: public MouseTranslate(Component c) {
104: super (c, 0);
105: }
106:
107: /**
108: * Creates a translate behavior that uses AWT listeners and behavior
109: * posts rather than WakeupOnAWTEvent. The behaviors is added to
110: * the specified Component and works on the given TransformGroup.
111: * A null component can be passed to specify the behavior should use
112: * listeners. Components can then be added to the behavior with the
113: * addListener(Component c) method.
114: * @param c The Component to add the MouseListener and
115: * MouseMotionListener to.
116: * @param transformGroup The TransformGroup to operate on.
117: * @since Java 3D 1.2.1
118: */
119: public MouseTranslate(Component c, TransformGroup transformGroup) {
120: super (c, transformGroup);
121: }
122:
123: /**
124: * Creates a translate behavior that uses AWT listeners and behavior
125: * posts rather than WakeupOnAWTEvent. The behavior is added to the
126: * specified Component. A null component can be passed to specify
127: * the behavior should use listeners. Components can then be added to
128: * the behavior with the addListener(Component c) method.
129: * Note that this behavior still needs a transform
130: * group to work on (use setTransformGroup(tg)) and the transform
131: * group must add this behavior.
132: * @param flags interesting flags (wakeup conditions).
133: * @since Java 3D 1.2.1
134: */
135: public MouseTranslate(Component c, int flags) {
136: super (c, flags);
137: }
138:
139: public void initialize() {
140: super .initialize();
141: if ((flags & INVERT_INPUT) == INVERT_INPUT) {
142: invert = true;
143: x_factor *= -1;
144: y_factor *= -1;
145: }
146: }
147:
148: /**
149: * Return the x-axis movement multipler.
150: **/
151: public double getXFactor() {
152: return x_factor;
153: }
154:
155: /**
156: * Return the y-axis movement multipler.
157: **/
158: public double getYFactor() {
159: return y_factor;
160: }
161:
162: /**
163: * Set the x-axis amd y-axis movement multipler with factor.
164: **/
165: public void setFactor(double factor) {
166: x_factor = y_factor = factor;
167: }
168:
169: /**
170: * Set the x-axis amd y-axis movement multipler with xFactor and yFactor
171: * respectively.
172: **/
173: public void setFactor(double xFactor, double yFactor) {
174: x_factor = xFactor;
175: y_factor = yFactor;
176: }
177:
178: public void processStimulus(Enumeration criteria) {
179: WakeupCriterion wakeup;
180: AWTEvent[] events;
181: MouseEvent evt;
182: // int id;
183: // int dx, dy;
184:
185: while (criteria.hasMoreElements()) {
186: wakeup = (WakeupCriterion) criteria.nextElement();
187:
188: if (wakeup instanceof WakeupOnAWTEvent) {
189: events = ((WakeupOnAWTEvent) wakeup).getAWTEvent();
190: if (events.length > 0) {
191: evt = (MouseEvent) events[events.length - 1];
192: doProcess(evt);
193: }
194: }
195:
196: else if (wakeup instanceof WakeupOnBehaviorPost) {
197: while (true) {
198: // access to the queue must be synchronized
199: synchronized (mouseq) {
200: if (mouseq.isEmpty())
201: break;
202: evt = (MouseEvent) mouseq.remove(0);
203: // consolodate MOUSE_DRAG events
204: while ((evt.getID() == MouseEvent.MOUSE_DRAGGED)
205: && !mouseq.isEmpty()
206: && (((MouseEvent) mouseq.get(0))
207: .getID() == MouseEvent.MOUSE_DRAGGED)) {
208: evt = (MouseEvent) mouseq.remove(0);
209: }
210: }
211: doProcess(evt);
212: }
213: }
214:
215: }
216: wakeupOn(mouseCriterion);
217: }
218:
219: void doProcess(MouseEvent evt) {
220: int id;
221: int dx, dy;
222:
223: processMouseEvent(evt);
224:
225: if (((buttonPress) && ((flags & MANUAL_WAKEUP) == 0))
226: || ((wakeUp) && ((flags & MANUAL_WAKEUP) != 0))) {
227: id = evt.getID();
228: if ((id == MouseEvent.MOUSE_DRAGGED) && !evt.isAltDown()
229: && evt.isMetaDown()) {
230:
231: x = evt.getX();
232: y = evt.getY();
233:
234: dx = x - x_last;
235: dy = y - y_last;
236:
237: if ((!reset)
238: && ((Math.abs(dy) < 50) && (Math.abs(dx) < 50))) {
239: //System.out.println("dx " + dx + " dy " + dy);
240: transformGroup.getTransform(currXform);
241:
242: translation.x = dx * x_factor;
243: translation.y = -dy * y_factor;
244:
245: transformX.set(translation);
246:
247: if (invert) {
248: currXform.mul(currXform, transformX);
249: } else {
250: currXform.mul(transformX, currXform);
251: }
252:
253: transformGroup.setTransform(currXform);
254:
255: transformChanged(currXform);
256:
257: if (callback != null)
258: callback.transformChanged(
259: MouseBehaviorCallback.TRANSLATE,
260: currXform);
261:
262: } else {
263: reset = false;
264: }
265: x_last = x;
266: y_last = y;
267: } else if (id == MouseEvent.MOUSE_PRESSED) {
268: x_last = evt.getX();
269: y_last = evt.getY();
270: }
271: }
272: }
273:
274: /**
275: * Users can overload this method which is called every time
276: * the Behavior updates the transform
277: *
278: * Default implementation does nothing
279: */
280: public void transformChanged(Transform3D transform) {
281: }
282:
283: /**
284: * The transformChanged method in the callback class will
285: * be called every time the transform is updated
286: */
287: public void setupCallback(MouseBehaviorCallback callback) {
288: this.callback = callback;
289: }
290: }
|