--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+/*\r
+ *\r
+ * @author Toni Kalajainen\r
+ */\r
+package org.simantics.scenegraph.g2d.events.adapter;\r
+\r
+import java.awt.event.InputEvent;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.event.MouseListener;\r
+import java.awt.event.MouseMotionListener;\r
+import java.awt.event.MouseWheelEvent;\r
+import java.awt.event.MouseWheelListener;\r
+import java.awt.geom.Point2D;\r
+\r
+import org.simantics.scenegraph.g2d.events.EventDebugPolicy;\r
+import org.simantics.scenegraph.g2d.events.IEventHandler;\r
+import org.simantics.scenegraph.g2d.events.IEventQueue;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent;\r
+\r
+\r
+/**\r
+ * Adapts AWT mouse events into G2D events.\r
+ * \r
+ * Sends adapted events to IEventHandler\r
+ */\r
+public class AWTMouseEventAdapter extends AbstractEventAdapter implements MouseListener, MouseMotionListener, MouseWheelListener {\r
+\r
+ private final boolean DEBUG = EventDebugPolicy.AWT_MOUSE_EVENT_ADAPTION;\r
+\r
+ private final boolean IGNORE_CONSUMED_EVENTS = false;\r
+\r
+ /** Mouse id of the default mouse */\r
+ public static final int MOUSE_ID = 0;\r
+\r
+ private final long [] pressTime = new long[5];\r
+\r
+ int buttonStatus = 0;\r
+\r
+ /**\r
+ * create new adapter\r
+ * @param sender the sender field in the events\r
+ * @param delegator the target of the adapted events\r
+ */\r
+ public AWTMouseEventAdapter(Object sender, IEventHandler delegator) {\r
+ super(sender, delegator);\r
+ }\r
+\r
+ /**\r
+ * create new adapter\r
+ * @param sender the sender field in the events\r
+ * @param queue\r
+ */\r
+ public AWTMouseEventAdapter(Object sender, IEventQueue queue) {\r
+ super(sender, queue);\r
+ }\r
+\r
+ private Point2D getControlPosition(MouseEvent e)\r
+ {\r
+ return new Point2D.Double(e.getX(), e.getY());\r
+ }\r
+\r
+ private Point2D getScreenPosition(MouseEvent e)\r
+ {\r
+ return e.getLocationOnScreen();\r
+ }\r
+\r
+ private static int getStateMask(MouseEvent e) {\r
+ int modifiers = e.getModifiersEx();\r
+ int stateMask = 0;\r
+ if((modifiers & InputEvent.CTRL_DOWN_MASK) != 0)\r
+ stateMask |= org.simantics.scenegraph.g2d.events.MouseEvent.CTRL_MASK;\r
+ if((modifiers & InputEvent.ALT_DOWN_MASK) != 0)\r
+ stateMask |= org.simantics.scenegraph.g2d.events.MouseEvent.ALT_MASK;\r
+ if((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0)\r
+ stateMask |= org.simantics.scenegraph.g2d.events.MouseEvent.ALT_GRAPH_MASK;\r
+ if((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0)\r
+ stateMask |= org.simantics.scenegraph.g2d.events.MouseEvent.SHIFT_MASK;\r
+ return stateMask;\r
+ }\r
+\r
+ private int getMouseButton(MouseEvent e)\r
+ {\r
+ int awtMouseButton = e.getButton();\r
+ if (awtMouseButton == MouseEvent.BUTTON1)\r
+ return org.simantics.scenegraph.g2d.events.MouseEvent.LEFT_BUTTON;\r
+ if (awtMouseButton == MouseEvent.BUTTON2)\r
+ return org.simantics.scenegraph.g2d.events.MouseEvent.MIDDLE_BUTTON;\r
+ if (awtMouseButton == MouseEvent.BUTTON3)\r
+ return org.simantics.scenegraph.g2d.events.MouseEvent.RIGHT_BUTTON;\r
+ return awtMouseButton;\r
+ }\r
+\r
+ /**\r
+ * Converts AWT {@link MouseEvent#getModifiersEx()} mouse button status to\r
+ * G2D mouse button status. Only supports three buttons while AWT supports\r
+ * plenty more.\r
+ * \r
+ * @param e\r
+ * @return\r
+ */\r
+ private int getButtonStatus(MouseEvent e) {\r
+ int modex = e.getModifiersEx();\r
+ int status = 0;\r
+ status |= (modex & MouseEvent.BUTTON1_DOWN_MASK) != 0 ? org.simantics.scenegraph.g2d.events.MouseEvent.LEFT_MASK : 0;\r
+ status |= (modex & MouseEvent.BUTTON2_DOWN_MASK) != 0 ? org.simantics.scenegraph.g2d.events.MouseEvent.MIDDLE_MASK : 0;\r
+ status |= (modex & MouseEvent.BUTTON3_DOWN_MASK) != 0 ? org.simantics.scenegraph.g2d.events.MouseEvent.RIGHT_MASK : 0;\r
+ return status;\r
+ }\r
+\r
+ @Override\r
+ public void mouseEntered(MouseEvent e) {\r
+ if (IGNORE_CONSUMED_EVENTS) {\r
+ if (e.isConsumed()) {\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse entered but already consumed: " + e);\r
+ return;\r
+ }\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse entered: " + e);\r
+ buttonStatus = getButtonStatus(e);\r
+ MouseEnterEvent me = new MouseEnterEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e));\r
+ handleEvent(me);\r
+ }\r
+\r
+ @Override\r
+ public void mouseExited(MouseEvent e) {\r
+ if (IGNORE_CONSUMED_EVENTS) {\r
+ if (e.isConsumed()) {\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse exited but already consumed: " + e);\r
+ return;\r
+ }\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse exited: " + e);\r
+\r
+ MouseExitEvent me = new MouseExitEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e));\r
+ handleEvent(me);\r
+ }\r
+\r
+ @Override\r
+ public void mousePressed(MouseEvent e) {\r
+ if (IGNORE_CONSUMED_EVENTS) {\r
+ if (e.isConsumed()) {\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse pressed but already consumed: " + e);\r
+ return;\r
+ }\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse pressed: " + e);\r
+\r
+ int mouseButton = getMouseButton(e);\r
+ if (mouseButton == MouseEvent.NOBUTTON) {\r
+ // This is strange, seems to happen on Linux constantly when pressing buttons rapidly.\r
+ //System.out.println("NO BUTTON EVENT: " + e);\r
+ return;\r
+ }\r
+ \r
+ if (mouseButton<=pressTime.length) pressTime[mouseButton-1] = e.getWhen();\r
+ buttonStatus |= 1 << (mouseButton-1);\r
+\r
+ handleEvent(new MouseButtonPressedEvent(sender, e.getWhen(), MOUSE_ID,\r
+ buttonStatus, getStateMask(e), mouseButton, getControlPosition(e), getScreenPosition(e)));\r
+ if (e.getClickCount() == 2) {\r
+ handleEvent(new MouseDoubleClickedEvent(sender, e.getWhen(),\r
+ MOUSE_ID, buttonStatus, getStateMask(e), mouseButton, getControlPosition(e), getScreenPosition(e)));\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void mouseReleased(MouseEvent e) {\r
+ if (IGNORE_CONSUMED_EVENTS) {\r
+ if (e.isConsumed()) {\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse released but already consumed: " + e);\r
+ return;\r
+ }\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse released: " + e);\r
+\r
+ int mouseButton = getMouseButton(e);\r
+ if (mouseButton == MouseEvent.NOBUTTON) {\r
+ // This is strange, seems to happen on Linux constantly when pressing buttons rapidly.\r
+ //System.out.println("NO BUTTON EVENT: " + e);\r
+ return;\r
+ }\r
+\r
+ long holdTime = Long.MAX_VALUE;\r
+ if (mouseButton<=pressTime.length)\r
+ holdTime = e.getWhen() - pressTime[mouseButton-1];\r
+\r
+ int stateMask = getStateMask(e);\r
+\r
+ // This works around the problem of AWT putting the ALT_DOWN_MASK in the\r
+ // mouse event extended modifiers when button 2 is pressed.\r
+ if (mouseButton == org.simantics.scenegraph.g2d.events.MouseEvent.MIDDLE_BUTTON) {\r
+ stateMask &= ~(org.simantics.scenegraph.g2d.events.MouseEvent.ALT_MASK);\r
+ }\r
+\r
+ buttonStatus &=~ (1<<(mouseButton-1));\r
+ MouseButtonReleasedEvent me = new MouseButtonReleasedEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, stateMask, mouseButton, holdTime, getControlPosition(e), getScreenPosition(e));\r
+ handleEvent(me);\r
+ }\r
+\r
+ @Override\r
+ public void mouseDragged(MouseEvent e) {\r
+ if (IGNORE_CONSUMED_EVENTS) {\r
+ if (e.isConsumed()) {\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse dragged but already consumed: " + e);\r
+ return;\r
+ }\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse dragged: " + e);\r
+ MouseMovedEvent me = new MouseMovedEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e));\r
+ handleEvent(me);\r
+ }\r
+\r
+ @Override\r
+ public void mouseMoved(MouseEvent e) {\r
+ if (IGNORE_CONSUMED_EVENTS) {\r
+ if (e.isConsumed()) {\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse moved but already consumed: " + e);\r
+ return;\r
+ }\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse moved: " + e);\r
+ MouseMovedEvent me = new MouseMovedEvent(sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e));\r
+ handleEvent(me);\r
+ }\r
+\r
+ @Override\r
+ public void mouseWheelMoved(MouseWheelEvent e) {\r
+ if (IGNORE_CONSUMED_EVENTS) {\r
+ if (e.isConsumed()) {\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse wheel moved but already consumed: " + e);\r
+ return;\r
+ }\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse wheel moved: " + e);\r
+ int wheelRotation = 0;\r
+ if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {\r
+ wheelRotation = -e.getUnitsToScroll();\r
+ } else {\r
+ wheelRotation = -e.getWheelRotation();\r
+ }\r
+ handleEvent(new MouseWheelMovedEvent(\r
+ sender, e.getWhen(), MOUSE_ID, buttonStatus, getStateMask(e), getControlPosition(e), getScreenPosition(e),\r
+ e.getScrollType(), e.getScrollAmount(), wheelRotation\r
+ ));\r
+\r
+ }\r
+\r
+ @Override\r
+ public void mouseClicked(MouseEvent e) {\r
+ if (IGNORE_CONSUMED_EVENTS) {\r
+ if (e.isConsumed()) {\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse clicked but already consumed: " + e);\r
+ return;\r
+ }\r
+ }\r
+ if (DEBUG)\r
+ System.out.println("AWT mouse clicked: " + e);\r
+ }\r
+\r
+}\r