1 /*
2 * $RCSfile: MouseZoom.java,v $ Copyright (c) 2006 Sun Microsystems, Inc. All
3 * rights reserved. Redistribution and use in source and binary forms, with or
4 * without modification, are permitted provided that the following conditions
5 * are met: - Redistribution of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer. -
7 * Redistribution in binary form must reproduce the above copyright notice, this
8 * list of conditions and the following disclaimer in the documentation and/or
9 * other materials provided with the distribution. Neither the name of Sun
10 * Microsystems, Inc. or the names of contributors may be used to endorse or
11 * promote products derived from this software without specific prior written
12 * permission. This software is provided "AS IS," without a warranty of any
13 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
14 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
15 * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC.
16 * ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
17 * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
18 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
19 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
20 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
21 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
22 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. You
23 * acknowledge that this software is not designed, licensed or intended for use
24 * in the design, construction, operation or maintenance of any nuclear
25 * facility. $Revision: 1.1 $ $Date: 2009/04/08 06:31:15 $ $State: Exp $
26 */
27
28 package edu.uci.ics.jung.visualization3d.control;
29
30 import java.awt.*;
31 import java.awt.event.*;
32 import java.util.*;
33 import javax.media.j3d.*;
34 import javax.vecmath.*;
35
36 import com.sun.j3d.utils.behaviors.mouse.MouseBehavior;
37 import com.sun.j3d.utils.behaviors.mouse.MouseBehaviorCallback;
38
39 /**
40 * MouseZoom is a Java3D behavior object that lets users control the Z axis
41 * translation of an object via a mouse drag motion with the second mouse
42 * button. See MouseRotate for similar usage info.
43 */
44
45 public class MouseZoom extends MouseBehavior
46 {
47
48 double z_factor = .04;
49 Vector3d translation = new Vector3d();
50
51 private MouseBehaviorCallback callback = null;
52
53 /**
54 * Creates a zoom behavior given the transform group.
55 *
56 * @param transformGroup
57 * The transformGroup to operate on.
58 */
59 public MouseZoom(TransformGroup transformGroup)
60 {
61 super(transformGroup);
62 }
63
64 /**
65 * Creates a default mouse zoom behavior.
66 */
67 public MouseZoom()
68 {
69 super(0);
70 }
71
72 /**
73 * Creates a zoom behavior. Note that this behavior still needs a transform
74 * group to work on (use setTransformGroup(tg)) and the transform group must
75 * add this behavior.
76 *
77 * @param flags
78 */
79 public MouseZoom(int flags)
80 {
81 super(flags);
82 }
83
84 /**
85 * Creates a zoom behavior that uses AWT listeners and behavior posts rather
86 * than WakeupOnAWTEvent. The behavior is added to the specified Component.
87 * A null component can be passed to specify the behavior should use
88 * listeners. Components can then be added to the behavior with the
89 * addListener(Component c) method.
90 *
91 * @param c
92 * The Component to add the MouseListener and MouseMotionListener
93 * to.
94 * @since Java 3D 1.2.1
95 */
96 public MouseZoom(Component c)
97 {
98 super(c, 0);
99 }
100
101 /**
102 * Creates a zoom behavior that uses AWT listeners and behavior posts rather
103 * than WakeupOnAWTEvent. The behaviors is added to the specified Component
104 * and works on the given TransformGroup.
105 *
106 * @param c
107 * The Component to add the MouseListener and MouseMotionListener
108 * to. A null component can be passed to specify the behavior
109 * should use listeners. Components can then be added to the
110 * behavior with the addListener(Component c) method.
111 * @param transformGroup
112 * The TransformGroup to operate on.
113 * @since Java 3D 1.2.1
114 */
115 public MouseZoom(Component c, TransformGroup transformGroup)
116 {
117 super(c, transformGroup);
118 }
119
120 /**
121 * Creates a zoom behavior that uses AWT listeners and behavior posts rather
122 * than WakeupOnAWTEvent. The behavior is added to the specified Component.
123 * A null component can be passed to specify the behavior should use
124 * listeners. Components can then be added to the behavior with the
125 * addListener(Component c) method. Note that this behavior still needs a
126 * transform group to work on (use setTransformGroup(tg)) and the transform
127 * group must add this behavior.
128 *
129 * @param flags
130 * interesting flags (wakeup conditions).
131 * @since Java 3D 1.2.1
132 */
133 public MouseZoom(Component c, int flags)
134 {
135 super(c, flags);
136 }
137
138 @Override
139 public void initialize()
140 {
141 super.initialize();
142 if ((flags & INVERT_INPUT) == INVERT_INPUT)
143 {
144 z_factor *= -1;
145 invert = true;
146 }
147 }
148
149 /**
150 * Return the y-axis movement multipler.
151 */
152 public double getFactor()
153 {
154 return z_factor;
155 }
156
157 /**
158 * Set the y-axis movement multipler with factor.
159 */
160 public void setFactor(double factor)
161 {
162 z_factor = factor;
163 }
164
165 public void processStimulus(Enumeration criteria)
166 {
167 WakeupCriterion wakeup;
168 AWTEvent[] events;
169 MouseEvent evt;
170 // int id;
171 // int dx, dy;
172
173 while (criteria.hasMoreElements())
174 {
175 wakeup = (WakeupCriterion) criteria.nextElement();
176 if (wakeup instanceof WakeupOnAWTEvent)
177 {
178 events = ((WakeupOnAWTEvent) wakeup).getAWTEvent();
179 if (events.length > 0)
180 {
181 evt = (MouseEvent) events[events.length - 1];
182 doProcess(evt);
183 }
184 }
185
186 else if (wakeup instanceof WakeupOnBehaviorPost)
187 {
188 while (true)
189 {
190 synchronized (mouseq)
191 {
192 if (mouseq.isEmpty())
193 break;
194 evt = (MouseEvent) mouseq.remove(0);
195 // consolodate MOUSE_DRAG events
196 while ((evt.getID() == MouseEvent.MOUSE_DRAGGED)
197 && !mouseq.isEmpty()
198 && (((MouseEvent) mouseq.get(0)).getID() == MouseEvent.MOUSE_DRAGGED))
199 {
200 evt = (MouseEvent) mouseq.remove(0);
201 }
202 }
203 doProcess(evt);
204 }
205 }
206
207 }
208 wakeupOn(mouseCriterion);
209 }
210
211 void doProcess(MouseEvent evt)
212 {
213 int id;
214 int dx, dy;
215
216 processMouseEvent(evt);
217
218 if (((buttonPress) && ((flags & MANUAL_WAKEUP) == 0))
219 || ((wakeUp) && ((flags & MANUAL_WAKEUP) != 0)))
220 {
221 id = evt.getID();
222 if ((id == MouseEvent.MOUSE_DRAGGED) && evt.isAltDown()
223 && !evt.isMetaDown())
224 {
225
226 x = evt.getX();
227 y = evt.getY();
228
229 dx = x - x_last;
230 dy = y - y_last;
231
232 if (!reset)
233 {
234 transformGroup.getTransform(currXform);
235 translation.z = dy * z_factor;
236 transformX.set(translation);
237
238 if (invert)
239 {
240 currXform.mul(currXform, transformX);
241 }
242 else
243 {
244 currXform.mul(transformX, currXform);
245 }
246
247 transformGroup.setTransform(currXform);
248
249 transformChanged(currXform);
250
251 if (callback != null)
252 callback.transformChanged(MouseBehaviorCallback.ZOOM,
253 currXform);
254 }
255 else
256 {
257 reset = false;
258 }
259
260 x_last = x;
261 y_last = y;
262 }
263 else if (id == MouseEvent.MOUSE_PRESSED)
264 {
265 x_last = evt.getX();
266 y_last = evt.getY();
267 }
268 }
269 }
270
271 /**
272 * Users can overload this method which is called every time
273 * the Behavior updates the transform
274 *
275 * Default implementation does nothing
276 */
277 public void transformChanged(Transform3D transform)
278 {
279 }
280
281 /**
282 * The transformChanged method in the callback class will
283 * be called every time the transform is updated.
284 */
285 public void setupCallback(MouseBehaviorCallback callback)
286 {
287 this.callback = callback;
288 }
289 }