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