1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.ui;
39
40 import ffx.potential.MolecularAssembly;
41 import ffx.potential.bonded.Atom;
42 import ffx.ui.GraphicsCanvas.LeftButtonMode;
43 import ffx.ui.behaviors.GlobalBehavior;
44 import ffx.ui.behaviors.MouseRotate;
45 import ffx.ui.behaviors.MouseTranslate;
46 import ffx.ui.behaviors.MouseZoom;
47 import java.awt.AWTEvent;
48 import java.awt.event.MouseEvent;
49 import java.util.Iterator;
50 import org.jogamp.java3d.Behavior;
51 import org.jogamp.java3d.Bounds;
52 import org.jogamp.java3d.BranchGroup;
53 import org.jogamp.java3d.Node;
54 import org.jogamp.java3d.SceneGraphPath;
55 import org.jogamp.java3d.Shape3D;
56 import org.jogamp.java3d.TransformGroup;
57 import org.jogamp.java3d.WakeupCriterion;
58 import org.jogamp.java3d.WakeupOnAWTEvent;
59 import org.jogamp.java3d.WakeupOnBehaviorPost;
60 import org.jogamp.java3d.WakeupOr;
61 import org.jogamp.java3d.utils.picking.PickCanvas;
62 import org.jogamp.java3d.utils.picking.PickIntersection;
63 import org.jogamp.java3d.utils.picking.PickResult;
64 import org.jogamp.java3d.utils.universe.SimpleUniverse;
65 import org.jogamp.vecmath.Point3d;
66
67
68
69
70
71
72
73 public class GraphicsEvents extends Behavior {
74
75
76
77 private static int ROTATEPOST = 1;
78
79 private static int TRANSLATEPOST = 2;
80
81 private static int ZOOMPOST = 3;
82
83 private static int BEHAVIORDONEPOST = 4;
84
85
86 private MainPanel mainPanel;
87 private GraphicsCanvas graphicsCanvas;
88
89 private WakeupOr mouseCriterion;
90 private WakeupOr postCriterion;
91
92 private boolean buttonPress;
93 private boolean leftButton;
94 private boolean rightButton;
95 private boolean middleButton;
96 private PickCanvas pickCanvas;
97 private PickResult pickResult;
98 private Atom atom;
99 private boolean axisSelected;
100
101 private MouseRotate systemRotate;
102 private MouseTranslate systemTranslate;
103 private MouseZoom globalZoom;
104 private GlobalBehavior viewOrbitBehavior;
105
106
107
108
109
110
111
112
113
114
115
116
117 public GraphicsEvents(
118 MainPanel mainPanel,
119 GraphicsCanvas graphicsCanvas,
120 GraphicsAxis graphicsAxis,
121 SimpleUniverse simpleUniverse,
122 Bounds bounds,
123 BranchGroup root,
124 TransformGroup transformGroup) {
125 this.mainPanel = mainPanel;
126 this.graphicsCanvas = graphicsCanvas;
127
128 TransformGroup viewTransformGroup =
129 simpleUniverse.getViewingPlatform().getViewPlatformTransform();
130 setSchedulingBounds(bounds);
131
132 systemRotate =
133 new MouseRotate(
134 MouseRotate.MANUAL_WAKEUP, viewTransformGroup, this, ROTATEPOST, BEHAVIORDONEPOST);
135 systemRotate.setFactor(0.025);
136 systemRotate.setSchedulingBounds(bounds);
137 root.addChild(systemRotate);
138
139 systemTranslate =
140 new MouseTranslate(
141 MouseTranslate.MANUAL_WAKEUP,
142 viewTransformGroup,
143 this,
144 TRANSLATEPOST,
145 BEHAVIORDONEPOST);
146 systemTranslate.setFactor(0.5);
147 systemTranslate.setSchedulingBounds(bounds);
148 root.addChild(systemTranslate);
149
150 globalZoom =
151 new MouseZoom(
152 MouseZoom.MANUAL_WAKEUP, viewTransformGroup, this, ZOOMPOST, BEHAVIORDONEPOST);
153 globalZoom.setFactor(0.0005);
154 globalZoom.setSchedulingBounds(bounds);
155 globalZoom.setTransformGroup(transformGroup);
156 root.addChild(globalZoom);
157
158 viewOrbitBehavior = new GlobalBehavior(this.graphicsCanvas);
159 viewOrbitBehavior.setUpCallback(graphicsAxis);
160 viewOrbitBehavior.setSchedulingBounds(bounds);
161 simpleUniverse.getViewingPlatform().setViewPlatformBehavior(viewOrbitBehavior);
162
163 pickCanvas = new PickCanvas(this.graphicsCanvas, simpleUniverse.getLocale());
164 pickCanvas.setMode(PickCanvas.GEOMETRY);
165 pickCanvas.setTolerance(20.0f);
166 }
167
168
169 public void initialize() {
170 WakeupCriterion[] behaviorPost = new WakeupCriterion[3];
171 behaviorPost[0] = new WakeupOnBehaviorPost(systemRotate, BEHAVIORDONEPOST);
172 behaviorPost[1] = new WakeupOnBehaviorPost(systemTranslate, BEHAVIORDONEPOST);
173 behaviorPost[2] = new WakeupOnBehaviorPost(globalZoom, BEHAVIORDONEPOST);
174 postCriterion = new WakeupOr(behaviorPost);
175 WakeupCriterion[] awtCriterion = new WakeupCriterion[1];
176 awtCriterion[0] = new WakeupOnAWTEvent(java.awt.AWTEvent.MOUSE_EVENT_MASK);
177 mouseCriterion = new WakeupOr(awtCriterion);
178 wakeupOn(mouseCriterion);
179 }
180
181
182
183
184
185
186 @Override
187 public void processStimulus(Iterator<WakeupCriterion> criteria) {
188 viewOrbitBehavior.setEnable(false);
189 while (criteria.hasNext()) {
190 WakeupCriterion wakeup = criteria.next();
191 if (wakeup instanceof WakeupOnAWTEvent) {
192 AWTEvent[] awtEvents = ((WakeupOnAWTEvent) wakeup).getAWTEvent();
193 if (awtEvents == null) {
194 continue;
195 }
196 for (AWTEvent awtEvent : awtEvents) {
197 MouseEvent mouseEvent;
198 if (awtEvent instanceof MouseEvent) {
199 mouseEvent = (MouseEvent) awtEvent;
200 processMouseEvent(mouseEvent);
201 } else {
202 continue;
203 }
204 if (!axisSelected) {
205
206 if (rightButton && buttonPress) {
207 systemTranslate.setMouseButton(MouseEvent.BUTTON3_DOWN_MASK);
208 if (systemTranslate()) {
209 wakeupOn(postCriterion);
210 return;
211 }
212 }
213
214 if (leftButton && buttonPress) {
215 LeftButtonMode leftButtonMode = graphicsCanvas.getLeftButtonMode();
216 switch (leftButtonMode) {
217 case ROTATE:
218 if (systemRotate()) {
219 wakeupOn(postCriterion);
220 return;
221 }
222 break;
223 case TRANSLATE:
224 systemTranslate.setMouseButton(MouseEvent.BUTTON1_DOWN_MASK);
225 if (systemTranslate()) {
226 wakeupOn(postCriterion);
227 return;
228 }
229 break;
230 case ZOOM:
231 globalZoom.setMouseButton(MouseEvent.BUTTON1_DOWN_MASK);
232 if (globalZoom()) {
233 wakeupOn(postCriterion);
234 return;
235 }
236 }
237 }
238
239 if (middleButton && buttonPress) {
240 globalZoom.setMouseButton(MouseEvent.BUTTON2_DOWN_MASK);
241 if (globalZoom()) {
242 wakeupOn(postCriterion);
243 return;
244 }
245 }
246 } else {
247 viewOrbitBehavior.setEnable(true);
248 wakeupOn(mouseCriterion);
249 return;
250 }
251 }
252 }
253 }
254 wakeupOn(mouseCriterion);
255 }
256
257
258
259
260
261
262 public void setGlobalCenter(double[] d) {
263 Point3d point = new Point3d(d);
264 viewOrbitBehavior.setRotationCenter(point);
265 }
266
267
268
269
270
271
272
273
274 void centerView(boolean resetRotation, boolean resetTranslation, boolean resetZoom) {
275 viewOrbitBehavior.centerView(resetRotation, resetTranslation);
276 }
277
278 private boolean globalZoom() {
279 postId(ZOOMPOST);
280 return true;
281 }
282
283
284
285
286
287
288 private void processMouseEvent(MouseEvent evt) {
289 buttonPress = false;
290 leftButton = false;
291 middleButton = false;
292 rightButton = false;
293 int mod = evt.getModifiersEx();
294 if (evt.getID() == MouseEvent.MOUSE_PRESSED) {
295 buttonPress = true;
296 }
297
298 if ((mod & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK) {
299 leftButton = true;
300 }
301
302 if ((mod & MouseEvent.BUTTON2_DOWN_MASK) == MouseEvent.BUTTON2_DOWN_MASK) {
303 middleButton = true;
304 }
305
306 if ((mod & MouseEvent.ALT_DOWN_MASK) == MouseEvent.ALT_DOWN_MASK) {
307 if (leftButton) {
308 middleButton = true;
309 leftButton = false;
310 }
311 }
312
313 if ((mod & MouseEvent.BUTTON3_DOWN_MASK) == MouseEvent.BUTTON3_DOWN_MASK) {
314 rightButton = true;
315 }
316
317 if ((mod & MouseEvent.SHIFT_DOWN_MASK) == MouseEvent.SHIFT_DOWN_MASK) {
318 if (leftButton) {
319 rightButton = true;
320 leftButton = false;
321 }
322 }
323 int x = evt.getX();
324 int y = evt.getY();
325 atom = null;
326 axisSelected = false;
327 if (buttonPress) {
328
329 pickCanvas.setShapeLocation(x, y);
330
331
332
333 try {
334 pickResult = pickCanvas.pickClosest();
335 } catch (Exception e) {
336 pickResult = null;
337 }
338 if (pickResult != null) {
339 SceneGraphPath sgp = pickResult.getSceneGraphPath();
340 Node node = sgp.getObject();
341 if (node instanceof Shape3D) {
342 Shape3D s = (Shape3D) node;
343 Object o = s.getUserData();
344 if (o instanceof MolecularAssembly) {
345 MolecularAssembly sys = (MolecularAssembly) o;
346 if (pickResult.numIntersections() > 0) {
347 PickIntersection pi = pickResult.getIntersection(0);
348 int[] coords = pi.getPrimitiveCoordinateIndices();
349 atom = sys.getAtomFromWireVertex(coords[0]);
350 }
351 } else if (o instanceof Atom) {
352 atom = (Atom) o;
353 } else if (o instanceof GraphicsAxis) {
354 axisSelected = true;
355 }
356 }
357 }
358 }
359 }
360
361 private boolean systemRotate() {
362 TransformGroup transformGroup = getTransformGroup();
363 if (transformGroup != null) {
364 systemRotate.setTransformGroup(transformGroup);
365 postId(ROTATEPOST);
366 return true;
367 }
368 return false;
369 }
370
371 private boolean systemTranslate() {
372 TransformGroup transformGroup = getTransformGroup();
373 if (transformGroup != null) {
374 systemTranslate.setTransformGroup(transformGroup);
375 postId(TRANSLATEPOST);
376 return true;
377 }
378 return false;
379 }
380
381 private TransformGroup getTransformGroup() {
382 TransformGroup transformGroup = null;
383 GraphicsCanvas.MouseMode mouseMode = graphicsCanvas.getMouseMode();
384 if ((mouseMode == GraphicsCanvas.MouseMode.SYSTEMBELOWMOUSE) && atom != null) {
385 transformGroup = (TransformGroup) pickResult.getNode(PickResult.TRANSFORM_GROUP);
386 } else if (mouseMode == GraphicsCanvas.MouseMode.ACTIVESYSTEM) {
387 if (mainPanel.getHierarchy().getActive() != null) {
388 transformGroup = mainPanel.getHierarchy().getActive().getTransformGroup();
389 }
390 }
391 if (transformGroup != null) {
392
393 if (!transformGroup.getCapability(TransformGroup.ALLOW_TRANSFORM_READ)
394 || !transformGroup.getCapability(TransformGroup.ALLOW_TRANSFORM_WRITE)) {
395 transformGroup = null;
396 }
397 }
398 return transformGroup;
399 }
400 }