001: /*
002: * $RCSfile: MouseZoom.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: * MouseZoom is a Java3D behavior object that lets users control the
055: * Z axis translation of an object via a mouse drag motion with the second
056: * mouse button. See MouseRotate for similar usage info.
057: */
058:
059: public class MouseZoom extends MouseBehavior {
060:
061: double z_factor = .04;
062: Vector3d translation = new Vector3d();
063:
064: private MouseBehaviorCallback callback = null;
065:
066: /**
067: * Creates a zoom behavior given the transform group.
068: * @param transformGroup The transformGroup to operate on.
069: */
070: public MouseZoom(TransformGroup transformGroup) {
071: super (transformGroup);
072: }
073:
074: /**
075: * Creates a default mouse zoom behavior.
076: **/
077: public MouseZoom() {
078: super (0);
079: }
080:
081: /**
082: * Creates a zoom behavior.
083: * Note that this behavior still needs a transform
084: * group to work on (use setTransformGroup(tg)) and
085: * the transform group must add this behavior.
086: * @param flags
087: */
088: public MouseZoom(int flags) {
089: super (flags);
090: }
091:
092: /**
093: * Creates a zoom behavior that uses AWT listeners and behavior
094: * posts rather than WakeupOnAWTEvent. The behavior is added to the
095: * specified Component. A null component can be passed to specify
096: * the behavior should use listeners. Components can then be added
097: * to the behavior with the addListener(Component c) method.
098: * @param c The Component to add the MouseListener
099: * and MouseMotionListener to.
100: * @since Java 3D 1.2.1
101: */
102: public MouseZoom(Component c) {
103: super (c, 0);
104: }
105:
106: /**
107: * Creates a zoom behavior that uses AWT listeners and behavior
108: * posts rather than WakeupOnAWTEvent. The behaviors is added to
109: * the specified Component and works on the given TransformGroup.
110: * @param c The Component to add the MouseListener and
111: * MouseMotionListener to. A null component can be passed to specify
112: * the behavior should use listeners. Components can then be added
113: * to the behavior with the addListener(Component c) method.
114: * @param transformGroup The TransformGroup to operate on.
115: * @since Java 3D 1.2.1
116: */
117: public MouseZoom(Component c, TransformGroup transformGroup) {
118: super (c, transformGroup);
119: }
120:
121: /**
122: * Creates a zoom behavior that uses AWT listeners and behavior
123: * posts rather than WakeupOnAWTEvent. The behavior is added to the
124: * specified Component. A null component can be passed to specify
125: * the behavior should use listeners. Components can then be added
126: * to the behavior with the addListener(Component c) method.
127: * Note that this behavior still needs a transform
128: * group to work on (use setTransformGroup(tg)) and the transform
129: * group must add this behavior.
130: * @param flags interesting flags (wakeup conditions).
131: * @since Java 3D 1.2.1
132: */
133: public MouseZoom(Component c, int flags) {
134: super (c, flags);
135: }
136:
137: public void initialize() {
138: super .initialize();
139: if ((flags & INVERT_INPUT) == INVERT_INPUT) {
140: z_factor *= -1;
141: invert = true;
142: }
143: }
144:
145: /**
146: * Return the y-axis movement multipler.
147: **/
148: public double getFactor() {
149: return z_factor;
150: }
151:
152: /**
153: * Set the y-axis movement multipler with factor.
154: **/
155: public void setFactor(double factor) {
156: z_factor = factor;
157: }
158:
159: public void processStimulus(Enumeration criteria) {
160: WakeupCriterion wakeup;
161: AWTEvent[] events;
162: MouseEvent evt;
163: // int id;
164: // int dx, dy;
165:
166: while (criteria.hasMoreElements()) {
167: wakeup = (WakeupCriterion) criteria.nextElement();
168: if (wakeup instanceof WakeupOnAWTEvent) {
169: events = ((WakeupOnAWTEvent) wakeup).getAWTEvent();
170: if (events.length > 0) {
171: evt = (MouseEvent) events[events.length - 1];
172: doProcess(evt);
173: }
174: }
175:
176: else if (wakeup instanceof WakeupOnBehaviorPost) {
177: while (true) {
178: synchronized (mouseq) {
179: if (mouseq.isEmpty())
180: break;
181: evt = (MouseEvent) mouseq.remove(0);
182: // consolodate MOUSE_DRAG events
183: while ((evt.getID() == MouseEvent.MOUSE_DRAGGED)
184: && !mouseq.isEmpty()
185: && (((MouseEvent) mouseq.get(0))
186: .getID() == MouseEvent.MOUSE_DRAGGED)) {
187: evt = (MouseEvent) mouseq.remove(0);
188: }
189: }
190: doProcess(evt);
191: }
192: }
193:
194: }
195: wakeupOn(mouseCriterion);
196: }
197:
198: void doProcess(MouseEvent evt) {
199: int id;
200: int dx, dy;
201:
202: processMouseEvent(evt);
203:
204: if (((buttonPress) && ((flags & MANUAL_WAKEUP) == 0))
205: || ((wakeUp) && ((flags & MANUAL_WAKEUP) != 0))) {
206: id = evt.getID();
207: if ((id == MouseEvent.MOUSE_DRAGGED) && evt.isAltDown()
208: && !evt.isMetaDown()) {
209:
210: x = evt.getX();
211: y = evt.getY();
212:
213: dx = x - x_last;
214: dy = y - y_last;
215:
216: if (!reset) {
217: transformGroup.getTransform(currXform);
218:
219: translation.z = dy * z_factor;
220:
221: transformX.set(translation);
222:
223: if (invert) {
224: currXform.mul(currXform, transformX);
225: } else {
226: currXform.mul(transformX, currXform);
227: }
228:
229: transformGroup.setTransform(currXform);
230:
231: transformChanged(currXform);
232:
233: if (callback != null)
234: callback.transformChanged(
235: MouseBehaviorCallback.ZOOM, currXform);
236:
237: } else {
238: reset = false;
239: }
240:
241: x_last = x;
242: y_last = y;
243: } else if (id == MouseEvent.MOUSE_PRESSED) {
244: x_last = evt.getX();
245: y_last = evt.getY();
246: }
247: }
248: }
249:
250: /**
251: * Users can overload this method which is called every time
252: * the Behavior updates the transform
253: *
254: * Default implementation does nothing
255: */
256: public void transformChanged(Transform3D transform) {
257: }
258:
259: /**
260: * The transformChanged method in the callback class will
261: * be called every time the transform is updated
262: */
263: public void setupCallback(MouseBehaviorCallback callback) {
264: this.callback = callback;
265: }
266: }
|