]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/adapter/AWTMouseEventAdapter.java
bad131312a337ce33195346fde1d1a6c4888b145
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / events / adapter / AWTMouseEventAdapter.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 /*
13  *
14  * @author Toni Kalajainen
15  */
16 package org.simantics.scenegraph.g2d.events.adapter;
17
18 import java.awt.event.InputEvent;
19 import java.awt.event.MouseEvent;
20 import java.awt.event.MouseListener;
21 import java.awt.event.MouseMotionListener;
22 import java.awt.event.MouseWheelEvent;
23 import java.awt.event.MouseWheelListener;
24 import java.awt.geom.Point2D;
25
26 import org.simantics.scenegraph.g2d.events.EventDebugPolicy;
27 import org.simantics.scenegraph.g2d.events.IEventHandler;
28 import org.simantics.scenegraph.g2d.events.IEventQueue;
29 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
30 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
31 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;
32 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;
33 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;
34 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
35 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent;
36
37
38 /**
39  * Adapts AWT mouse events into G2D events.
40  * 
41  * Sends adapted events to IEventHandler
42  */
43 public class AWTMouseEventAdapter extends AbstractEventAdapter implements MouseListener, MouseMotionListener, MouseWheelListener {
44
45     private final boolean   DEBUG                  = EventDebugPolicy.AWT_MOUSE_EVENT_ADAPTION;
46
47     private final boolean   IGNORE_CONSUMED_EVENTS = false;
48
49     /** Mouse id of the default mouse */
50     public static final int MOUSE_ID = 0;
51
52     private final long [] pressTime = new long[5];
53
54     int buttonStatus = 0;
55
56     /**
57      * create new adapter
58      * @param sender the sender field in the events
59      * @param delegator the target of the adapted events
60      */
61     public AWTMouseEventAdapter(Object sender, IEventHandler delegator) {
62         super(sender, delegator);
63     }
64
65     /**
66      * create new adapter
67      * @param sender the sender field in the events
68      * @param queue
69      */
70     public AWTMouseEventAdapter(Object sender, IEventQueue queue) {
71         super(sender, queue);
72     }
73
74     public static Point2D getControlPosition(MouseEvent e)
75     {
76         return new Point2D.Double(e.getX(), e.getY());
77     }
78
79     public static Point2D getScreenPosition(MouseEvent e)
80     {
81         return e.getLocationOnScreen();
82     }
83
84     public static int getStateMask(MouseEvent e) {
85         int modifiers = e.getModifiersEx();
86         int stateMask = 0;
87         if((modifiers & InputEvent.CTRL_DOWN_MASK) != 0)
88             stateMask |= org.simantics.scenegraph.g2d.events.MouseEvent.CTRL_MASK;
89         if((modifiers & InputEvent.ALT_DOWN_MASK) != 0)
90             stateMask |= org.simantics.scenegraph.g2d.events.MouseEvent.ALT_MASK;
91         if((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0)
92             stateMask |= org.simantics.scenegraph.g2d.events.MouseEvent.ALT_GRAPH_MASK;
93         if((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0)
94             stateMask |= org.simantics.scenegraph.g2d.events.MouseEvent.SHIFT_MASK;
95         return stateMask;
96     }
97
98     public static int getMouseButton(MouseEvent e)
99     {
100         int awtMouseButton = e.getButton();
101         if (awtMouseButton == MouseEvent.BUTTON1)
102             return org.simantics.scenegraph.g2d.events.MouseEvent.LEFT_BUTTON;
103         if (awtMouseButton == MouseEvent.BUTTON2)
104             return org.simantics.scenegraph.g2d.events.MouseEvent.MIDDLE_BUTTON;
105         if (awtMouseButton == MouseEvent.BUTTON3)
106             return org.simantics.scenegraph.g2d.events.MouseEvent.RIGHT_BUTTON;
107         return awtMouseButton;
108     }
109
110     /**
111      * Converts AWT {@link MouseEvent#getModifiersEx()} mouse button status to
112      * G2D mouse button status. Only supports three buttons while AWT supports
113      * plenty more.
114      * 
115      * @param e
116      * @return
117      */
118     public static int getButtonStatus(MouseEvent e) {
119         int modex = e.getModifiersEx();
120         int status = 0;
121         status |= (modex & MouseEvent.BUTTON1_DOWN_MASK) != 0 ? org.simantics.scenegraph.g2d.events.MouseEvent.LEFT_MASK : 0;
122         status |= (modex & MouseEvent.BUTTON2_DOWN_MASK) != 0 ? org.simantics.scenegraph.g2d.events.MouseEvent.MIDDLE_MASK : 0;
123         status |= (modex & MouseEvent.BUTTON3_DOWN_MASK) != 0 ? org.simantics.scenegraph.g2d.events.MouseEvent.RIGHT_MASK : 0;
124         return status;
125     }
126
127     @Override
128     public void mouseEntered(MouseEvent e) {
129         if (IGNORE_CONSUMED_EVENTS) {
130             if (e.isConsumed()) {
131                 if (DEBUG)
132                     System.out.println("AWT mouse entered but already consumed: " + e);
133                 return;
134             }
135         }
136         if (DEBUG)
137             System.out.println("AWT mouse entered: " + e);
138         buttonStatus = getButtonStatus(e);
139         MouseEnterEvent me = new MouseEnterEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e));
140         handleEvent(me);
141     }
142
143     @Override
144     public void mouseExited(MouseEvent e) {
145         if (IGNORE_CONSUMED_EVENTS) {
146             if (e.isConsumed()) {
147                 if (DEBUG)
148                     System.out.println("AWT mouse exited but already consumed: " + e);
149                 return;
150             }
151         }
152         if (DEBUG)
153             System.out.println("AWT mouse exited: " + e);
154
155         MouseExitEvent me = new MouseExitEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e));
156         handleEvent(me);
157     }
158
159     @Override
160     public void mousePressed(MouseEvent e) {
161         if (IGNORE_CONSUMED_EVENTS) {
162             if (e.isConsumed()) {
163                 if (DEBUG)
164                     System.out.println("AWT mouse pressed but already consumed: " + e);
165                 return;
166             }
167         }
168         if (DEBUG)
169             System.out.println("AWT mouse pressed: " + e);
170
171         int mouseButton = getMouseButton(e);
172         if (mouseButton == MouseEvent.NOBUTTON) {
173                 // This is strange, seems to happen on Linux constantly when pressing buttons rapidly.
174                 //System.out.println("NO BUTTON EVENT: " + e);
175                 return;
176         }
177         
178         if (mouseButton<=pressTime.length) pressTime[mouseButton-1] = e.getWhen();
179         buttonStatus |= 1 << (mouseButton-1);
180
181         handleEvent(new MouseButtonPressedEvent(sender, e.getWhen(), MOUSE_ID,
182                 buttonStatus, getStateMask(e), mouseButton, getControlPosition(e), getScreenPosition(e)));
183         if (e.getClickCount() == 2) {
184             handleEvent(new MouseDoubleClickedEvent(sender, e.getWhen(),
185                     MOUSE_ID, buttonStatus, getStateMask(e), mouseButton, getControlPosition(e), getScreenPosition(e)));
186         }
187     }
188
189     @Override
190     public void mouseReleased(MouseEvent e) {
191         if (IGNORE_CONSUMED_EVENTS) {
192             if (e.isConsumed()) {
193                 if (DEBUG)
194                     System.out.println("AWT mouse released but already consumed: " + e);
195                 return;
196             }
197         }
198         if (DEBUG)
199             System.out.println("AWT mouse released: " + e);
200
201         int mouseButton = getMouseButton(e);
202         if (mouseButton == MouseEvent.NOBUTTON) {
203             // This is strange, seems to happen on Linux constantly when pressing buttons rapidly.
204             //System.out.println("NO BUTTON EVENT: " + e);
205             return;
206         }
207
208         long holdTime = Long.MAX_VALUE;
209         if (mouseButton<=pressTime.length)
210             holdTime = e.getWhen() - pressTime[mouseButton-1];
211
212         int stateMask = getStateMask(e);
213
214         // This works around the problem of AWT putting the ALT_DOWN_MASK in the
215         // mouse event extended modifiers when button 2 is pressed.
216         if (mouseButton == org.simantics.scenegraph.g2d.events.MouseEvent.MIDDLE_BUTTON) {
217             stateMask &= ~(org.simantics.scenegraph.g2d.events.MouseEvent.ALT_MASK);
218         }
219
220         buttonStatus &=~ (1<<(mouseButton-1));
221         MouseButtonReleasedEvent me = new MouseButtonReleasedEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, stateMask, mouseButton, holdTime, getControlPosition(e), getScreenPosition(e));
222         handleEvent(me);
223     }
224
225     @Override
226     public void mouseDragged(MouseEvent e) {
227         if (IGNORE_CONSUMED_EVENTS) {
228             if (e.isConsumed()) {
229                 if (DEBUG)
230                     System.out.println("AWT mouse dragged but already consumed: " + e);
231                 return;
232             }
233         }
234         if (DEBUG)
235             System.out.println("AWT mouse dragged: " + e);
236         MouseMovedEvent me = new MouseMovedEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e));
237         handleEvent(me);
238     }
239
240     @Override
241     public void mouseMoved(MouseEvent e) {
242         if (IGNORE_CONSUMED_EVENTS) {
243             if (e.isConsumed()) {
244                 if (DEBUG)
245                     System.out.println("AWT mouse moved but already consumed: " + e);
246                 return;
247             }
248         }
249         if (DEBUG)
250             System.out.println("AWT mouse moved: " + e);
251         MouseMovedEvent me = new MouseMovedEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e));
252         handleEvent(me);
253     }
254
255     @Override
256     public void mouseWheelMoved(MouseWheelEvent e) {
257         if (IGNORE_CONSUMED_EVENTS) {
258             if (e.isConsumed()) {
259                 if (DEBUG)
260                     System.out.println("AWT mouse wheel moved but already consumed: " + e);
261                 return;
262             }
263         }
264         if (DEBUG)
265             System.out.println("AWT mouse wheel moved: " + e);
266         int wheelRotation = 0;
267         if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
268             wheelRotation = -e.getUnitsToScroll();
269         } else {
270             wheelRotation = -e.getWheelRotation();
271         }
272         handleEvent(new MouseWheelMovedEvent(
273                 sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e),
274                 e.getScrollType(), e.getScrollAmount(), wheelRotation
275         ));
276
277     }
278
279     @Override
280     public void mouseClicked(MouseEvent e) {
281         if (IGNORE_CONSUMED_EVENTS) {
282             if (e.isConsumed()) {
283                 if (DEBUG)
284                     System.out.println("AWT mouse clicked but already consumed: " + e);
285                 return;
286             }
287         }
288         if (DEBUG)
289             System.out.println("AWT mouse clicked: " + e);
290     }
291
292 }