/******************************************************************************* * Copyright 2012 Geoscience Australia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package au.gov.ga.earthsci.newt.awt; import gov.nasa.worldwind.awt.AWTInputHandler; import java.awt.Component; import java.awt.Window; import javax.swing.SwingUtilities; import jogamp.newt.awt.event.AWTNewtEventFactory; import com.jogamp.common.util.IntIntHashMap; import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.event.NEWTEvent; import com.jogamp.newt.event.WindowEvent; /** * Helper class used to convert NEWT events to corresponding AWT events. Similar * to {@link AWTNewtEventFactory}, but converts in the opposite direction. * * @author Michael de Hoog (michael.dehoog@ga.gov.au) */ public class NewtEventConverterAWT { protected static final int KEY_NOT_FOUND_VALUE = 0xFFFFFFFF; protected static final IntIntHashMap eventTypeAWT2NEWT; static { // @formatter:off IntIntHashMap map = new IntIntHashMap(); map.setKeyNotFoundValue(KEY_NOT_FOUND_VALUE); // n/a map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_OPENED, java.awt.event.WindowEvent.WINDOW_OPENED); map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY, java.awt.event.WindowEvent.WINDOW_CLOSING); map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROYED, java.awt.event.WindowEvent.WINDOW_CLOSED); // n/a map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_ICONIFIED, java.awt.event.WindowEvent.WINDOW_ICONIFIED); // n/a map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DEICONIFIED, java.awt.event.WindowEvent.WINDOW_DEICONIFIED); //map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS, java.awt.event.WindowEvent.WINDOW_ACTIVATED); //map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS, java.awt.event.WindowEvent.WINDOW_GAINED_FOCUS); map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS, java.awt.event.FocusEvent.FOCUS_GAINED); //map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS, java.awt.event.WindowEvent.WINDOW_DEACTIVATED); //map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS, java.awt.event.WindowEvent.WINDOW_LOST_FOCUS); map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS, java.awt.event.FocusEvent.FOCUS_LOST); // n/a map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_STATE_CHANGED, java.awt.event.WindowEvent.WINDOW_STATE_CHANGED); map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_MOVED, java.awt.event.ComponentEvent.COMPONENT_MOVED); map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_RESIZED, java.awt.event.ComponentEvent.COMPONENT_RESIZED); // n/a map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_SHOWN, java.awt.event.ComponentEvent.COMPONENT_SHOWN); // n/a map.put(com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_HIDDEN, java.awt.event.ComponentEvent.COMPONENT_HIDDEN); map.put(com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED, java.awt.event.MouseEvent.MOUSE_CLICKED); map.put(com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED, java.awt.event.MouseEvent.MOUSE_PRESSED); map.put(com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED, java.awt.event.MouseEvent.MOUSE_RELEASED); map.put(com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED, java.awt.event.MouseEvent.MOUSE_MOVED); map.put(com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_ENTERED, java.awt.event.MouseEvent.MOUSE_ENTERED); map.put(com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_EXITED, java.awt.event.MouseEvent.MOUSE_EXITED); map.put(com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED, java.awt.event.MouseEvent.MOUSE_DRAGGED); map.put(com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED, java.awt.event.MouseEvent.MOUSE_WHEEL); map.put(com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED, java.awt.event.KeyEvent.KEY_PRESSED); map.put(com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED, java.awt.event.KeyEvent.KEY_RELEASED); eventTypeAWT2NEWT = map; // @formatter:on } /** * Convert a NEWT modifiers mask int to an AWT mask. * * @param newtMods * NEWT modifiers mask * @return Corresponding AWT modifiers mask */ protected static final int newtModifiers2Awt(int newtMods) { int awtMods = 0; if ((newtMods & com.jogamp.newt.event.InputEvent.SHIFT_MASK) != 0) { awtMods |= java.awt.event.InputEvent.SHIFT_DOWN_MASK; } if ((newtMods & com.jogamp.newt.event.InputEvent.CTRL_MASK) != 0) { awtMods |= java.awt.event.InputEvent.CTRL_DOWN_MASK; } if ((newtMods & com.jogamp.newt.event.InputEvent.META_MASK) != 0) { awtMods |= java.awt.event.InputEvent.META_DOWN_MASK; } if ((newtMods & com.jogamp.newt.event.InputEvent.ALT_MASK) != 0) { awtMods |= java.awt.event.InputEvent.ALT_DOWN_MASK; } if ((newtMods & com.jogamp.newt.event.InputEvent.ALT_GRAPH_MASK) != 0) { awtMods |= java.awt.event.InputEvent.ALT_GRAPH_MASK; } if ((newtMods & com.jogamp.newt.event.InputEvent.BUTTON1_MASK) != 0) { awtMods |= java.awt.event.InputEvent.BUTTON1_DOWN_MASK; } if ((newtMods & com.jogamp.newt.event.InputEvent.BUTTON2_MASK) != 0) { awtMods |= java.awt.event.InputEvent.BUTTON2_DOWN_MASK; } if ((newtMods & com.jogamp.newt.event.InputEvent.BUTTON3_MASK) != 0) { awtMods |= java.awt.event.InputEvent.BUTTON3_DOWN_MASK; } return awtMods; } /** * Convert a NEWT button int to an AWT button int. * * @param newtButton * NEWT button * @return Corresponding AWT button */ protected static final int newtButton2Awt(int newtButton) { switch (newtButton) { case com.jogamp.newt.event.MouseEvent.BUTTON1: return java.awt.event.MouseEvent.BUTTON1; case com.jogamp.newt.event.MouseEvent.BUTTON2: return java.awt.event.MouseEvent.BUTTON2; case com.jogamp.newt.event.MouseEvent.BUTTON3: return java.awt.event.MouseEvent.BUTTON3; } return 0; } /** * Create an {@link java.awt.AWTEvent} from the given * com.jogamp.newt.event.NEWTEvent. * * @param event * NEWT event to convert * @param awtSourceComponent * Component to set as the AWT event source * @return AWT event corresponding to the given NEWT event */ public static final java.awt.AWTEvent createEvent(com.jogamp.newt.event.NEWTEvent event, java.awt.Component awtSourceComponent) { if (event instanceof KeyEvent) { return createKeyEvent((KeyEvent) event, awtSourceComponent); } else if (event instanceof MouseEvent) { return createMouseEvent((MouseEvent) event, awtSourceComponent); } else if (event instanceof WindowEvent) { return createComponentEvent((WindowEvent) event, awtSourceComponent); } return null; } /** * Create an AWT {@link java.awt.event.ComponentEvent} from the given NEWT * {@link com.jogamp.newt.event.WindowEvent}. Return object type may be a * {@link java.awt.event.ComponentEvent}, or one of its subclasses * {@link java.awt.event.WindowEvent} or {@link java.awt.event.FocusEvent}, * according to the NEWT event type. Return value implements * {@link AWTEventFromNewt}. * * @param event * NEWT event to convert * @param awtSource * Component to set as the AWT event source * @return AWT event corresponding to the given NEWT event */ public static final java.awt.event.ComponentEvent createComponentEvent(com.jogamp.newt.event.WindowEvent event, java.awt.Component awtSource) { int id = eventTypeAWT2NEWT.get(event.getEventType()); if (id != KEY_NOT_FOUND_VALUE) { switch (id) { case java.awt.event.FocusEvent.FOCUS_GAINED: case java.awt.event.FocusEvent.FOCUS_LOST: return new FocusEventFromNewt(event, awtSource, id); case java.awt.event.ComponentEvent.COMPONENT_MOVED: case java.awt.event.ComponentEvent.COMPONENT_RESIZED: return new ComponentEventFromNewt(event, awtSource, id); default: return new WindowEventFromNewt(event, getWindowAncestor(awtSource), id); } } return null; } private static Window getWindowAncestor(Component c) { if (c instanceof Window) { return (Window) c; } return SwingUtilities.getWindowAncestor(c); } /** * Create an AWT {@link java.awt.event.MouseEvent} from the given NEWT * {@link com.jogamp.newt.event.MouseEvent}. Return object type may be a * {@link java.awt.event.MouseEvent}, or a * {@link java.awt.event.MouseWheelEvent} if the NEWT event is a mouse wheel * event. Return value implements {@link AWTEventFromNewt}. * * @param event * NEWT event to convert * @param awtSource * Component to set as the AWT event source * @return AWT event corresponding to the given NEWT event */ public static final java.awt.event.MouseEvent createMouseEvent(com.jogamp.newt.event.MouseEvent event, java.awt.Component awtSource) { int id = eventTypeAWT2NEWT.get(event.getEventType()); if (id != KEY_NOT_FOUND_VALUE) { // AWT/NEWT rotation is reversed - AWT +1 is down, NEWT +1 is up. int rotation = Math.round(-event.getRotation()[1]); int mods = newtModifiers2Awt(event.getModifiers()); int button = newtButton2Awt(event.getButton()); switch (id) { case java.awt.event.MouseEvent.MOUSE_WHEEL: return new MouseWheelEventFromNewt(event, awtSource, id, event.getWhen(), mods, event.getX(), event.getY(), event.getClickCount(), false, java.awt.event.MouseWheelEvent.WHEEL_UNIT_SCROLL, rotation, rotation); default: return new MouseEventFromNewt(event, awtSource, id, event.getWhen(), mods, event.getX(), event.getY(), event.getClickCount(), false, button); } } return null; // no mapping .. } /** * Create an AWT {@link java.awt.event.KeyEvent} from the given NEWT * {@link com.jogamp.newt.event.KeyEvent}. Return value implements * {@link AWTEventFromNewt}. * * @param event * NEWT event to convert * @param awtSource * Component to set as the AWT event source * @return AWT event corresponding to the given NEWT event */ public static final java.awt.event.KeyEvent createKeyEvent(com.jogamp.newt.event.KeyEvent event, java.awt.Component awtSource) { int id = eventTypeAWT2NEWT.get(event.getEventType()); if (id != KEY_NOT_FOUND_VALUE) { if ((event.getModifiers() & InputEvent.AUTOREPEAT_MASK) != 0) { //don't forward autorepeat events return null; } //can never be java.awt.event.KeyEvent.VK_UNDEFINED or java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN, //because id will never be java.awt.event.KeyEvent.KEY_TYPED (doesn't exist in map) int code = AWTNewtEventFactory.newtKeyCode2AWTKeyCode(event.getKeyCode()); int location = java.awt.event.KeyEvent.KEY_LOCATION_STANDARD; try { return new KeyEventFromNewt(event, awtSource, id, event.getWhen(), newtModifiers2Awt(event.getModifiers()), code, event.getKeyChar(), location); } catch (IllegalArgumentException e) { //ignore - sometimes can raise an: java.lang.IllegalArgumentException: invalid keyChar } } return null; // no mapping .. } ///////////////////////////////////// // AWTEvent subclasses used above: // ///////////////////////////////////// /** * Interface which all AWT events created by the * {@link NewtEventConverterAWT} implement. Provides access to the original * NEWT event from which the AWT event was created. */ public interface AWTEventFromNewt { /** * @return The original NEWT event from which this AWT event was * created. */ NEWTEvent getOriginalEvent(); /** * Forward this event to the given {@link AWTInputHandler} * * @param inputHandler */ void forward(AWTInputHandler inputHandler); } /** * {@link java.awt.event.ComponentEvent} subclass that implements * {@link AWTEventFromNewt}. */ public static class ComponentEventFromNewt extends java.awt.event.ComponentEvent implements AWTEventFromNewt { private final NEWTEvent originalEvent; public ComponentEventFromNewt(NEWTEvent originalEvent, Component source, int id) { super(source, id); this.originalEvent = originalEvent; } @Override public NEWTEvent getOriginalEvent() { return originalEvent; } @Override public void forward(AWTInputHandler inputHandler) { } } /** * {@link java.awt.event.FocusEvent} subclass that implements * {@link AWTEventFromNewt}. */ public static class FocusEventFromNewt extends java.awt.event.FocusEvent implements AWTEventFromNewt { private final NEWTEvent originalEvent; public FocusEventFromNewt(NEWTEvent originalEvent, Component source, int id, boolean temporary, Component opposite) { super(source, id, temporary, opposite); this.originalEvent = originalEvent; } public FocusEventFromNewt(NEWTEvent originalEvent, Component source, int id, boolean temporary) { super(source, id, temporary); this.originalEvent = originalEvent; } public FocusEventFromNewt(NEWTEvent originalEvent, Component source, int id) { super(source, id); this.originalEvent = originalEvent; } @Override public NEWTEvent getOriginalEvent() { return originalEvent; } @Override public void forward(AWTInputHandler inputHandler) { switch (getID()) { case java.awt.event.FocusEvent.FOCUS_GAINED: inputHandler.focusGained(this); break; case java.awt.event.FocusEvent.FOCUS_LOST: inputHandler.focusLost(this); break; } } } /** * {@link java.awt.event.KeyEvent} subclass that implements * {@link AWTEventFromNewt}. */ public static class KeyEventFromNewt extends java.awt.event.KeyEvent implements AWTEventFromNewt { private final NEWTEvent originalEvent; public KeyEventFromNewt(NEWTEvent originalEvent, Component source, int id, long when, int modifiers, int keyCode, char keyChar, int keyLocation) { super(source, id, when, modifiers, keyCode, keyChar, keyLocation); this.originalEvent = originalEvent; } public KeyEventFromNewt(NEWTEvent originalEvent, Component source, int id, long when, int modifiers, int keyCode, char keyChar) { super(source, id, when, modifiers, keyCode, keyChar); this.originalEvent = originalEvent; } @Override public NEWTEvent getOriginalEvent() { return originalEvent; } @Override public void forward(AWTInputHandler inputHandler) { switch (getID()) { case java.awt.event.KeyEvent.KEY_PRESSED: inputHandler.keyPressed(this); break; case java.awt.event.KeyEvent.KEY_RELEASED: inputHandler.keyReleased(this); break; case java.awt.event.KeyEvent.KEY_TYPED: inputHandler.keyTyped(this); break; } } } /** * {@link java.awt.event.MouseEvent} subclass that implements * {@link AWTEventFromNewt}. */ public static class MouseEventFromNewt extends java.awt.event.MouseEvent implements AWTEventFromNewt { private final NEWTEvent originalEvent; public MouseEventFromNewt(NEWTEvent originalEvent, Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger, int button) { super(source, id, when, modifiers, x, y, clickCount, popupTrigger, button); this.originalEvent = originalEvent; } public MouseEventFromNewt(NEWTEvent originalEvent, Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger) { super(source, id, when, modifiers, x, y, clickCount, popupTrigger); this.originalEvent = originalEvent; } public MouseEventFromNewt(NEWTEvent originalEvent, Component source, int id, long when, int modifiers, int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger, int button) { super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger, button); this.originalEvent = originalEvent; } @Override public NEWTEvent getOriginalEvent() { return originalEvent; } @Override public void forward(AWTInputHandler inputHandler) { switch (getID()) { case java.awt.event.MouseEvent.MOUSE_CLICKED: inputHandler.mouseClicked(this); break; case java.awt.event.MouseEvent.MOUSE_PRESSED: inputHandler.mousePressed(this); break; case java.awt.event.MouseEvent.MOUSE_RELEASED: inputHandler.mouseReleased(this); break; case java.awt.event.MouseEvent.MOUSE_MOVED: inputHandler.mouseMoved(this); break; case java.awt.event.MouseEvent.MOUSE_ENTERED: inputHandler.mouseEntered(this); break; case java.awt.event.MouseEvent.MOUSE_EXITED: inputHandler.mouseExited(this); break; case java.awt.event.MouseEvent.MOUSE_DRAGGED: inputHandler.mouseDragged(this); break; } } } /** * {@link java.awt.event.MouseWheelEvent} subclass that implements * {@link AWTEventFromNewt}. */ public static class MouseWheelEventFromNewt extends java.awt.event.MouseWheelEvent implements AWTEventFromNewt { private final NEWTEvent originalEvent; public MouseWheelEventFromNewt(NEWTEvent originalEvent, Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger, int scrollType, int scrollAmount, int wheelRotation) { super(source, id, when, modifiers, x, y, clickCount, popupTrigger, scrollType, scrollAmount, wheelRotation); this.originalEvent = originalEvent; } public MouseWheelEventFromNewt(NEWTEvent originalEvent, Component source, int id, long when, int modifiers, int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger, int scrollType, int scrollAmount, int wheelRotation) { super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger, scrollType, scrollAmount, wheelRotation); this.originalEvent = originalEvent; } @Override public NEWTEvent getOriginalEvent() { return originalEvent; } @Override public void forward(AWTInputHandler inputHandler) { switch (getID()) { case java.awt.event.MouseEvent.MOUSE_WHEEL: inputHandler.mouseWheelMoved(this); break; } } } /** * {@link java.awt.event.WindowEvent} subclass that implements * {@link AWTEventFromNewt}. */ public static class WindowEventFromNewt extends java.awt.event.WindowEvent implements AWTEventFromNewt { private final NEWTEvent originalEvent; public WindowEventFromNewt(NEWTEvent originalEvent, Window source, int id, int oldState, int newState) { super(source, id, oldState, newState); this.originalEvent = originalEvent; } public WindowEventFromNewt(NEWTEvent originalEvent, Window source, int id, Window opposite, int oldState, int newState) { super(source, id, opposite, oldState, newState); this.originalEvent = originalEvent; } public WindowEventFromNewt(NEWTEvent originalEvent, Window source, int id, Window opposite) { super(source, id, opposite); this.originalEvent = originalEvent; } public WindowEventFromNewt(NEWTEvent originalEvent, Window source, int id) { super(source, id); this.originalEvent = originalEvent; } @Override public NEWTEvent getOriginalEvent() { return originalEvent; } @Override public void forward(AWTInputHandler inputHandler) { } } }