1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g2d.participant;
\r
14 import java.awt.geom.AffineTransform;
\r
15 import java.awt.geom.Point2D;
\r
17 import org.simantics.g2d.canvas.Hints;
\r
18 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
\r
19 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
\r
20 import org.simantics.g2d.participant.CanvasGrab.PointerInfo;
\r
21 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
\r
22 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
\r
23 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
\r
24 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;
\r
25 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
\r
28 * @author Toni Kalajainen
\r
30 public class MultitouchPanZoomRotateInteractor extends AbstractCanvasParticipant {
\r
32 @Dependency TransformUtil util;
\r
33 @Dependency CanvasGrab grab;
\r
35 // Pointer grabbing button
\r
36 public static final int BUTTON_ID = 1;
\r
38 @EventHandler(priority = Integer.MAX_VALUE - 2000)
\r
39 public boolean handleEvent(MouseButtonPressedEvent e) {
\r
40 // ignore normal mouse
\r
41 if (getHint(Hints.KEY_TOOL) != Hints.PANTOOL) return false;
\r
42 if (e.mouseId==0) return false;
\r
43 if (e.button != BUTTON_ID) return false;
\r
44 assertDependencies();
\r
45 //System.out.println(e.mouseId+" down");
\r
46 Point2D controlPos = e.controlPosition;
\r
47 Point2D canvasPos = util.controlToCanvas(controlPos, null);
\r
48 grab.grabCanvas(e.mouseId, canvasPos);
\r
52 @EventHandler(priority = Integer.MAX_VALUE - 2000)
\r
53 public boolean handleEvent(MouseButtonReleasedEvent e) {
\r
54 // ignore normal mouse
\r
55 if (getHint(Hints.KEY_TOOL) != Hints.PANTOOL) return false;
\r
56 if (e.mouseId==0) return false;
\r
57 if (e.button != BUTTON_ID) return false;
\r
58 assertDependencies();
\r
59 //System.out.println(e.mouseId+" up");
\r
60 grab.grabInfo.remove(e.mouseId);
\r
65 @EventHandler(priority = Integer.MAX_VALUE - 2000)
\r
66 public boolean handleEvent(MouseExitEvent e) {
\r
67 // ignore normal mouse
\r
68 if (getHint(Hints.KEY_TOOL) != Hints.PANTOOL) return false;
\r
69 if (e.mouseId==0) return false;
\r
70 assertDependencies();
\r
71 //System.out.println(e.mouseId+" exit");
\r
72 grab.grabInfo.remove(e.mouseId);
\r
76 @EventHandler(priority = Integer.MAX_VALUE - 2000)
\r
77 public boolean handleEvent(MouseMovedEvent e) {
\r
78 if (e.context instanceof MouseUtil) return false;
\r
79 if (getHint(Hints.KEY_TOOL) != Hints.PANTOOL) return false;
\r
80 assertDependencies();
\r
81 PointerInfo ai = grab.grabInfo.get(e.mouseId);
\r
82 if (ai==null) return false;
\r
83 if (grab.grabInfo.size() == 1) {
\r
84 PointerInfo pi = grab.grabInfo.values().iterator().next();
\r
86 Point2D pt = util.controlToCanvas(e.controlPosition, null);
\r
88 double a1_x = pi.anchorPos.getX();
\r
89 double a1_y = pi.anchorPos.getY();
\r
90 double b1_x = pt.getX();
\r
91 double b1_y = pt.getY();
\r
93 AffineTransform gat = util.getTransform();
\r
94 gat.translate(b1_x-a1_x, b1_y-a1_y);
\r
95 util.setTransform(gat);
\r
97 return true; // TODO Do panning;
\r
99 if (grab.grabInfo.size()!=2) return false;
\r
101 double EPSILON = 3;
\r
103 PointerInfo[] pi = grab.grabInfo.values().toArray(new PointerInfo[2]);
\r
105 for (PointerInfo p : pi)
\r
106 if (p.mouseId == e.mouseId)
\r
107 p.currentPos = util.controlToCanvas(e.controlPosition, null);
\r
109 double a1_x = pi[0].anchorPos.getX();
\r
110 double a1_y = pi[0].anchorPos.getY();
\r
111 double b1_x = pi[0].currentPos.getX();
\r
112 double b1_y = pi[0].currentPos.getY();
\r
114 double a2_x = pi[1].anchorPos.getX();
\r
115 double a2_y = pi[1].anchorPos.getY();
\r
116 double b2_x = pi[1].currentPos.getX();
\r
117 double b2_y = pi[1].currentPos.getY();
\r
119 for (PointerInfo p : pi)
\r
120 if (p.mouseId != e.mouseId)
\r
121 p.currentPos = p.anchorPos;
\r
123 double da_x = a1_x - a2_x;
\r
124 double da_y = a1_y - a2_y;
\r
125 double da_lensq = da_x*da_x + da_y*da_y;
\r
126 if(da_lensq < EPSILON) {
\r
127 System.err.println("a1 ja a2 ovat liian lähellä toisiaan");
\r
131 double db_x = b1_x - b2_x;
\r
132 double db_y = b1_y - b2_y;
\r
134 double s_x = (db_x * da_x + db_y * da_y) / da_lensq;
\r
135 double s_y = (-db_x * da_y + db_y * da_x) / da_lensq;
\r
137 double t_x = b1_x - s_x * a1_x + s_y * a1_y;
\r
138 double t_y = b1_y - s_x * a1_y - s_y * a1_x;
\r
140 double mat[] = new double[] {s_x, s_y, -s_y, s_x, t_x, t_y};
\r
141 AffineTransform at = new AffineTransform(mat);
\r
144 AffineTransform gat = util.getTransform();
\r
145 gat.concatenate(at);
\r
146 util.setTransform(gat);
\r