diff options
author | Sven Gothel <[email protected]> | 2013-10-17 07:56:20 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-10-17 07:56:20 +0200 |
commit | a90bf31f8747dd38c61d518f8af4d4d4a64a8e90 (patch) | |
tree | b99e97fe8644080418e86f1e9da17b01755cfc02 | |
parent | 40863632d1428de015099b5967e5136425e99f25 (diff) |
NEWT PointerEvent: Unify event processing in new doPointerEvent(..) and consumePointerEvent(..) - Unifies native mouse and Android's pointer event, ready for Win7 touch
Unify event processing in new doPointerEvent(..), which is also invoked from doMouseEvent(..),
and consumePointerEvent().
doPointerEvent(..): Validates and modifies event data and finally creates the event,
where consumePointerEvent(..) calls gesture handlers and may synthesize events.
Unifies native mouse and Android's pointer event, ready for Win7 touch.
AndroidNewtEventFactory calls doPointerEvent(..) directly.
Removed lots of duplicated pointer event handling code.
-rwxr-xr-x | make/scripts/tests-win.bat | 4 | ||||
-rwxr-xr-x | make/scripts/tests-x64-dbg.bat | 4 | ||||
-rw-r--r-- | make/scripts/tests.sh | 4 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/event/MouseEvent.java | 98 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 409 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java | 64 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java | 14 |
7 files changed, 303 insertions, 294 deletions
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat index b3029f94c..099768f7c 100755 --- a/make/scripts/tests-win.bat +++ b/make/scripts/tests-win.bat @@ -58,14 +58,14 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestRandomTiledR REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestRandomTiledRendering3GL2AWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT %* -scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT2 %* +REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT2 %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsNewtAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingNIOImageSwingAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %* -REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* +scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 40000 -width 100 -height 100 -screen 0 %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT -time 5000 diff --git a/make/scripts/tests-x64-dbg.bat b/make/scripts/tests-x64-dbg.bat index c1a14c1a2..bab911e37 100755 --- a/make/scripts/tests-x64-dbg.bat +++ b/make/scripts/tests-x64-dbg.bat @@ -49,9 +49,9 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLC REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer" "-Djogl.debug.TileRenderer.PNG"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer"
-set D_ARGS="-Dnewt.debug.Window"
+REM set D_ARGS="-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
-REM set D_ARGS="-Dnewt.debug.Window.MouseEvent"
+set D_ARGS="-Dnewt.debug.Window.MouseEvent"
REM set D_ARGS="-Dnewt.debug.Window.MouseEvent" "-Dnewt.debug.Window.KeyEvent"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
REM set D_ARGS="-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index a302666f7..129b0deab 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -301,7 +301,7 @@ function testawtswt() { #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NEWT $* #testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $* @@ -333,7 +333,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.tile.TestRandomTiledRendering2GL2NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.tile.TestRandomTiledRendering3GL2AWT $* #testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsAWT $* -testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT $* +#testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT $* #testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT2 $* #testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsNewtAWT $* #testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingNIOImageSwingAWT $* diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java index fd5e27bdd..cb9e7a290 100644 --- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java @@ -145,9 +145,17 @@ public class MouseEvent extends InputEvent super(eventType, source, when, modifiers); this.x = new int[]{x}; this.y = new int[]{y}; - this.pressure = constMousePressure; + switch(eventType) { + case EVENT_MOUSE_CLICKED: + case EVENT_MOUSE_PRESSED: + case EVENT_MOUSE_DRAGGED: + this.pressure = constMousePressure1; + break; + default: + this.pressure = constMousePressure0; + } this.maxPressure= 1.0f; - this.pointerID = constMousePointerIDs; + this.pointerID = new short[] { (short)(button - 1) }; this.clickCount=clickCount; this.button=button; this.rotationXYZ = rotationXYZ; @@ -213,70 +221,6 @@ public class MouseEvent extends InputEvent } /** - * Factory for a multiple-pointer event. - * <p> - * The index for the multiple-pointer fields representing the triggering pointer is passed via <i>actionIdx</i>. - * If <i>actionIdx</i> is not <code>0</code>, all multiple-pointer fields values of index <code>0</code> - * and <i>actionIdx</i> are swapped so that the pointer-index 0 will represent the triggering pointer. - * </p> - * <p> - * See details for <a href="#multiPtrEvent">multiple-pointer events</a>. - * </p> - * - * @param eventType - * @param source - * @param when - * @param modifiers - * @param actionIdx index of multiple-pointer arrays representing the pointer which triggered the event - * @param pointerType PointerType for each pointer (multiple pointer) - * @param pointerID Pointer ID for each pointer (multiple pointer). IDs start w/ 0 and are consecutive numbers. - * @param x X-axis for each pointer (multiple pointer) - * @param y Y-axis for each pointer (multiple pointer) - * @param pressure Pressure for each pointer (multiple pointer) - * @param maxPressure Maximum pointer pressure for all pointer - * @param button Corresponding mouse-button - * @param clickCount Mouse-button click-count - * @param rotationXYZ Rotation of all axis - * @param rotationScale Rotation scale - */ - public static MouseEvent create(short eventType, Object source, long when, int modifiers, - int actionIdx, PointerType pointerType[], short[] pointerID, - int[] x, int[] y, float[] pressure, float maxPressure, - short button, short clickCount, float[] rotationXYZ, float rotationScale) { - if( 0 <= actionIdx && actionIdx < pointerType.length) { - if( 0 < actionIdx ) { - { - final PointerType aType = pointerType[actionIdx]; - pointerType[actionIdx] = pointerType[0]; - pointerType[0] = aType; - } - { - final short s = pointerID[actionIdx]; - pointerID[actionIdx] = pointerID[0]; - pointerID[0] = s; - } - { - int s = x[actionIdx]; - x[actionIdx] = x[0]; - x[0] = s; - s = y[actionIdx]; - y[actionIdx] = y[0]; - y[0] = s; - } - { - final float aPress = pressure[actionIdx]; - pressure[actionIdx] = pressure[0]; - pressure[0] = aPress; - } - } - return new MouseEvent(eventType, source, when, modifiers, - pointerType, pointerID, x, y, pressure, maxPressure, - button, clickCount, rotationXYZ, rotationScale); - } - throw new IllegalArgumentException("actionIdx out of bounds [0.."+(pointerType.length-1)+"]"); - } - - /** * @return the count of pointers involved in this event */ public final int getPointerCount() { @@ -528,15 +472,15 @@ public class MouseEvent extends InputEvent public static String getEventTypeString(short type) { switch(type) { - case EVENT_MOUSE_CLICKED: return "EVENT_MOUSE_CLICKED"; - case EVENT_MOUSE_ENTERED: return "EVENT_MOUSE_ENTERED"; - case EVENT_MOUSE_EXITED: return "EVENT_MOUSE_EXITED"; - case EVENT_MOUSE_PRESSED: return "EVENT_MOUSE_PRESSED"; - case EVENT_MOUSE_RELEASED: return "EVENT_MOUSE_RELEASED"; - case EVENT_MOUSE_MOVED: return "EVENT_MOUSE_MOVED"; - case EVENT_MOUSE_DRAGGED: return "EVENT_MOUSE_DRAGGED"; - case EVENT_MOUSE_WHEEL_MOVED: return "EVENT_MOUSE_WHEEL_MOVED"; - default: return "unknown (" + type + ")"; + case EVENT_MOUSE_CLICKED: return "EVENT_MOUSE_CLICKED"; + case EVENT_MOUSE_ENTERED: return "EVENT_MOUSE_ENTERED"; + case EVENT_MOUSE_EXITED: return "EVENT_MOUSE_EXITED"; + case EVENT_MOUSE_PRESSED: return "EVENT_MOUSE_PRESSED"; + case EVENT_MOUSE_RELEASED: return "EVENT_MOUSE_RELEASED"; + case EVENT_MOUSE_MOVED: return "EVENT_MOUSE_MOVED"; + case EVENT_MOUSE_DRAGGED: return "EVENT_MOUSE_DRAGGED"; + case EVENT_MOUSE_WHEEL_MOVED: return "EVENT_MOUSE_WHEEL_MOVED"; + default: return "unknown (" + type + ")"; } } @@ -558,8 +502,8 @@ public class MouseEvent extends InputEvent private final float rotationScale; private final float maxPressure; - private static final float[] constMousePressure = new float[]{0f}; - private static final short[] constMousePointerIDs = new short[]{0}; + private static final float[] constMousePressure0 = new float[]{0f}; + private static final float[] constMousePressure1 = new float[]{1f}; private static final PointerType[] constMousePointerTypes = new PointerType[] { PointerType.Mouse }; public static final short EVENT_MOUSE_CLICKED = 200; diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 66ce46ed0..b0df2d894 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -135,6 +135,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer /** Timeout of queued events (repaint and resize) */ static final long QUEUED_EVENT_TO = 1200; // ms + private static final int[] constMousePointerTypes = new int[] { PointerType.Mouse.ordinal() }; + // // Volatile: Multithread Mutable Access // @@ -181,34 +183,50 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private ArrayList<MouseListener> mouseListeners = new ArrayList<MouseListener>(); + /** from event passing: {@link WindowImpl#consumePointerEvent(MouseEvent)}. */ private static class PointerState0 { - /** current pressed mouse button number */ - private short buttonPressed = (short)0; - /** current pressed mouse button modifier mask */ - private int buttonModMask = 0; - /** last time when a mouse button was pressed */ - private long lastButtonPressTime = 0; - /** last mouse button click count */ - private short lastButtonClickCount = (short)0; /** mouse entered window - is inside the window (may be synthetic) */ - private boolean insideWindow = false; - /** last mouse-move position */ - private Point lastMovePosition = new Point(); - } - private static class PointerState1 { - /** current pressed mouse button number */ - private short buttonPressed = (short)0; + boolean insideWindow = false; + /** last time when a mouse button was pressed */ - private long lastButtonPressTime = 0; - /** mouse entered window - is inside the window (may be synthetic) */ - private boolean insideWindow = false; - /** last mouse-move position */ - private Point lastMovePosition = new Point(); + long lastButtonPressTime = 0; + + void clearButton() { + lastButtonPressTime = 0; + } } - /** doMouseEvent */ private PointerState0 pState0 = new PointerState0(); - /** consumeMouseEvent */ + + /** from direct input: {@link WindowImpl#doPointerEvent(boolean, boolean, int[], short, int, int, short[], int[], int[], float[], float, float[], float)}. */ + private static class PointerState1 extends PointerState0 { + /** current pressed mouse button number */ + short buttonPressed = (short)0; + /** current pressed mouse button modifier mask */ + int buttonPressedMask = 0; + /** last mouse button click count */ + short lastButtonClickCount = (short)0; + + final void clearButton() { + super.clearButton(); + lastButtonPressTime = 0; + lastButtonClickCount = (short)0; + buttonPressed = 0; + buttonPressedMask = 0; + } + + /** last pointer-move position for 8 touch-down pointers */ + final Point[] movePositions = new Point[] { + new Point(), new Point(), new Point(), new Point(), + new Point(), new Point(), new Point(), new Point() }; + final Point getMovePosition(int id) { + if( 0 <= id && id < movePositions.length ) { + return movePositions[id]; + } + return null; + } + } private PointerState1 pState1 = new PointerState1(); + private boolean defaultGestureHandlerEnabled = true; private DoubleTapScrollGesture gesture2PtrTouchScroll = null; private ArrayList<GestureHandler> pointerGestureHandler = new ArrayList<GestureHandler>(); @@ -2247,7 +2265,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } @Override - public boolean consumeEvent(NEWTEvent e) { + public final boolean consumeEvent(NEWTEvent e) { switch(e.getEventType()) { // special repaint treatment case WindowEvent.EVENT_WINDOW_REPAINT: @@ -2288,7 +2306,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } else if(e instanceof KeyEvent) { consumeKeyEvent((KeyEvent)e); } else if(e instanceof MouseEvent) { - consumeMouseEvent((MouseEvent)e); + consumePointerEvent((MouseEvent)e); } else { throw new NativeWindowException("Unexpected NEWTEvent type " + e); } @@ -2347,21 +2365,115 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer int x, int y, short button, float[] rotationXYZ, float rotationScale) { doMouseEvent(true, wait, eventType, modifiers, x, y, button, rotationXYZ, rotationScale); } */ + + /** + * Send mouse event (one-pointer) either to be directly consumed or to be enqueued + * + * @param enqueue if true, event will be {@link #enqueueEvent(boolean, NEWTEvent) enqueued}, + * otherwise {@link #consumeEvent(NEWTEvent) consumed} directly. + * @param wait if true wait until {@link #consumeEvent(NEWTEvent) consumed}. + */ protected void doMouseEvent(boolean enqueue, boolean wait, short eventType, int modifiers, int x, int y, short button, float[] rotationXYZ, float rotationScale) { - if( 0 > button || button > MouseEvent.BUTTON_NUMBER ) { + if( 0 > button || button > MouseEvent.BUTTON_COUNT ) { throw new NativeWindowException("Invalid mouse button number" + button); + } else if( 0 == button ) { + button = 1; + } + doPointerEvent(enqueue, wait, constMousePointerTypes, eventType, modifiers, + 0 /*actionIdx*/, new short[] { (short)(button-1) }, + new int[]{x}, new int[]{y}, new float[]{0f} /*pressure*/, 1f /*maxPressure*/, + rotationXYZ, rotationScale); + } + + /** + * Send multiple-pointer event either to be directly consumed or to be enqueued + * <p> + * The index for the element of multiple-pointer arrays represents the pointer which triggered the event + * is passed via <i>actionIdx</i>. + * </p> + * + * @param enqueue if true, event will be {@link #enqueueEvent(boolean, NEWTEvent) enqueued}, + * otherwise {@link #consumeEvent(NEWTEvent) consumed} directly. + * @param wait if true wait until {@link #consumeEvent(NEWTEvent) consumed}. + * @param pTypesOrdinal {@link MouseEvent.PointerType#ordinal()} for each pointer (multiple pointer) + * @param eventType + * @param modifiers + * @param actionIdx index of multiple-pointer arrays representing the pointer which triggered the event + * @param pID Pointer ID for each pointer (multiple pointer), we assume pointerID's starts w/ 0 + * @param pX X-axis for each pointer (multiple pointer) + * @param pY Y-axis for each pointer (multiple pointer) + * @param pPressure Pressure for each pointer (multiple pointer) + * @param maxPressure Maximum pointer pressure for all pointer + */ + public void doPointerEvent(boolean enqueue, boolean wait, + int[] pTypesOrdinal, short eventType, int modifiers, + int actionIdx, short[] pID, + int[] pX, int[] pY, float[] pPressure, float maxPressure, + float[] rotationXYZ, float rotationScale) { + final long when = System.currentTimeMillis(); + final int pointerCount = pTypesOrdinal.length; + + if( 0 > actionIdx || actionIdx >= pointerCount) { + throw new IllegalArgumentException("actionIdx out of bounds [0.."+(pointerCount-1)+"]"); + } + if( 0 < actionIdx ) { + // swap values to make idx 0 the triggering pointer + { + final int aType = pTypesOrdinal[actionIdx]; + pTypesOrdinal[actionIdx] = pTypesOrdinal[0]; + pTypesOrdinal[0] = aType; + } + { + final short s = pID[actionIdx]; + pID[actionIdx] = pID[0]; + pID[0] = s; + } + { + int s = pX[actionIdx]; + pX[actionIdx] = pX[0]; + pX[0] = s; + s = pY[actionIdx]; + pY[actionIdx] = pY[0]; + pY[0] = s; + } + { + final float aPress = pPressure[actionIdx]; + pPressure[actionIdx] = pPressure[0]; + pPressure[0] = aPress; + } + } + final PointerType[] pointerType = new PointerType[pointerCount]; + for(int i=pointerCount-1; i>=0; i--) { + pointerType[i] = PointerType.valueOf(pTypesOrdinal[i]); + } + final short id = pID[0]; + final short button; + { + final int b = id + 1; + if( com.jogamp.newt.event.MouseEvent.BUTTON1 <= b && b <= com.jogamp.newt.event.MouseEvent.BUTTON_COUNT ) { + button = (short)b; + } else { + button = com.jogamp.newt.event.MouseEvent.BUTTON1; + } } // - // Remove redundant events, determine ENTERED state and reset states if applicable + // - Determine ENTERED/EXITED state + // - Remove redundant move/drag events + // - Reset states if applicable // - final long when = System.currentTimeMillis(); + int x = pX[0]; + int y = pY[0]; + final Point movePositionP0 = pState1.getMovePosition(id); switch( eventType ) { case MouseEvent.EVENT_MOUSE_EXITED: - if( x==-1 && y==-1 ) { - x = pState0.lastMovePosition.getX(); - y = pState0.lastMovePosition.getY(); + if( null != movePositionP0 ) { + if( x==-1 && y==-1 ) { + x = movePositionP0.getX(); + y = movePositionP0.getY(); + } + movePositionP0.set(0, 0); } // Fall through intended! @@ -2369,54 +2481,46 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // clip coordinates to window dimension x = Math.min(Math.max(x, 0), getWidth()-1); y = Math.min(Math.max(y, 0), getHeight()-1); - pState0.insideWindow = eventType == MouseEvent.EVENT_MOUSE_ENTERED; - // clear states - pState0.lastButtonPressTime = 0; - pState0.lastButtonClickCount = (short)0; - pState0.buttonPressed = 0; - pState0.buttonModMask = 0; + pState1.insideWindow = eventType == MouseEvent.EVENT_MOUSE_ENTERED; + pState1.clearButton(); break; case MouseEvent.EVENT_MOUSE_MOVED: case MouseEvent.EVENT_MOUSE_DRAGGED: - if( pState0.insideWindow && pState0.lastMovePosition.getX() == x && pState0.lastMovePosition.getY() == y ) { - if(DEBUG_MOUSE_EVENT) { - System.err.println("doMouseEvent: skip EVENT_MOUSE_MOVED w/ same position: "+pState0.lastMovePosition); + if( null != movePositionP0 ) { + if( pState1.insideWindow && movePositionP0.getX() == x && movePositionP0.getY() == y ) { + if(DEBUG_MOUSE_EVENT) { + System.err.println("doMouseEvent: skip "+MouseEvent.getEventTypeString(eventType)+" w/ same position: "+movePositionP0); + } + return; // skip same position } - return; // skip same position + movePositionP0.set(x, y); } - pState0.lastMovePosition.setX(x); - pState0.lastMovePosition.setY(y); // Fall through intended ! default: - if(!pState0.insideWindow) { - pState0.insideWindow = true; - - // clear states - pState0.lastButtonPressTime = 0; - pState0.lastButtonClickCount = (short)0; - pState0.buttonPressed = 0; - pState0.buttonModMask = 0; + if(!pState1.insideWindow) { + pState1.insideWindow = true; + pState1.clearButton(); } } if( x < 0 || y < 0 || x >= getWidth() || y >= getHeight() ) { if(DEBUG_MOUSE_EVENT) { System.err.println("doMouseEvent: drop: "+MouseEvent.getEventTypeString(eventType)+ - ", mod "+modifiers+", pos "+x+"/"+y+", button "+button+", lastMousePosition: "+pState0.lastMovePosition); + ", mod "+modifiers+", pos "+x+"/"+y+", button "+button+", lastMousePosition: "+movePositionP0); } return; // .. invalid .. } if(DEBUG_MOUSE_EVENT) { System.err.println("doMouseEvent: enqueue "+enqueue+", wait "+wait+", "+MouseEvent.getEventTypeString(eventType)+ - ", mod "+modifiers+", pos "+x+"/"+y+", button "+button+", lastMousePosition: "+pState0.lastMovePosition); + ", mod "+modifiers+", pos "+x+"/"+y+", button "+button+", lastMousePosition: "+movePositionP0); } - - modifiers |= InputEvent.getButtonMask(button); // Always add current button to modifier mask (Bug 571) - modifiers |= pState0.buttonModMask; // Always add currently pressed mouse buttons to modifier mask + modifiers |= InputEvent.getButtonMask(button); // Always add current button to modifier mask (Bug 571) + modifiers |= pState1.buttonPressedMask; // Always add currently pressed mouse buttons to modifier mask + if( isPointerConfined() ) { modifiers |= InputEvent.CONFINED_MASK; } @@ -2424,78 +2528,79 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer modifiers |= InputEvent.INVISIBLE_MASK; } - final MouseEvent e; - + pX[0] = x; + pY[0] = y; + + // + // - Determine CLICK COUNT + // - Ignore sent CLICKED + // - Track buttonPressed incl. buttonPressedMask + // - Fix MOVED/DRAGGED event + // + final MouseEvent e; switch( eventType ) { + case MouseEvent.EVENT_MOUSE_CLICKED: + e = null; + break; + case MouseEvent.EVENT_MOUSE_PRESSED: - if( when - pState0.lastButtonPressTime < MouseEvent.getClickTimeout() ) { - pState0.lastButtonClickCount++; + if( 0 >= pPressure[0] ) { + pPressure[0] = maxPressure; + } + pState1.buttonPressedMask |= InputEvent.getButtonMask(button); + if( 1 == pointerCount ) { + if( when - pState1.lastButtonPressTime < MouseEvent.getClickTimeout() ) { + pState1.lastButtonClickCount++; + } else { + pState1.lastButtonClickCount=(short)1; + } + pState1.lastButtonPressTime = when; + pState1.buttonPressed = button; + e = new MouseEvent(eventType, this, when, modifiers, pointerType, pID, + pX, pY, pPressure, maxPressure, button, pState1.lastButtonClickCount, rotationXYZ, rotationScale); } else { - pState0.lastButtonClickCount=(short)1; + e = new MouseEvent(eventType, this, when, modifiers, pointerType, pID, + pX, pY, pPressure, maxPressure, button, (short)1, rotationXYZ, rotationScale); } - pState0.lastButtonPressTime = when; - pState0.buttonPressed = button; - pState0.buttonModMask |= MouseEvent.getButtonMask(button); - e = new MouseEvent(eventType, this, when, - modifiers, x, y, pState0.lastButtonClickCount, button, rotationXYZ, rotationScale); break; case MouseEvent.EVENT_MOUSE_RELEASED: - e = new MouseEvent(eventType, this, when, - modifiers, x, y, pState0.lastButtonClickCount, button, rotationXYZ, rotationScale); - if( when - pState0.lastButtonPressTime >= MouseEvent.getClickTimeout() ) { - pState0.lastButtonClickCount = (short)0; - pState0.lastButtonPressTime = 0; - } - pState0.buttonPressed = 0; - pState0.buttonModMask &= ~MouseEvent.getButtonMask(button); + if( 1 == pointerCount ) { + e = new MouseEvent(eventType, this, when, modifiers, pointerType, pID, + pX, pY, pPressure, maxPressure, button, pState1.lastButtonClickCount, rotationXYZ, rotationScale); + if( when - pState1.lastButtonPressTime >= MouseEvent.getClickTimeout() ) { + pState1.lastButtonClickCount = (short)0; + pState1.lastButtonPressTime = 0; + } + pState1.buttonPressed = 0; + } else { + e = new MouseEvent(eventType, this, when, modifiers, pointerType, pID, + pX, pY, pPressure, maxPressure, button, (short)1, rotationXYZ, rotationScale); + } + pState1.buttonPressedMask &= ~InputEvent.getButtonMask(button); + if( null != movePositionP0 ) { + movePositionP0.set(0, 0); + } break; case MouseEvent.EVENT_MOUSE_MOVED: - if ( pState0.buttonPressed > 0 ) { - e = new MouseEvent(MouseEvent.EVENT_MOUSE_DRAGGED, this, when, - modifiers, x, y, (short)1, pState0.buttonPressed, rotationXYZ, rotationScale); + if ( 0 != pState1.buttonPressedMask ) { // any button or pointer move -> drag + e = new MouseEvent(MouseEvent.EVENT_MOUSE_DRAGGED, this, when, modifiers, pointerType, pID, + pX, pY, pPressure, maxPressure, pState1.buttonPressed, (short)1, rotationXYZ, rotationScale); } else { - e = new MouseEvent(eventType, this, when, - modifiers, x, y, (short)0, button, rotationXYZ, rotationScale); + e = new MouseEvent(eventType, this, when, modifiers, pointerType, pID, + pX, pY, pPressure, maxPressure, button, (short)0, rotationXYZ, rotationScale); } break; + case MouseEvent.EVENT_MOUSE_DRAGGED: + if( 0 >= pPressure[0] ) { + pPressure[0] = maxPressure; + } + // Fall through intended! default: - e = new MouseEvent(eventType, this, when, modifiers, x, y, (short)0, button, rotationXYZ, rotationScale); + e = new MouseEvent(eventType, this, when, modifiers, pointerType, pID, + pX, pY, pPressure, maxPressure, button, (short)0, rotationXYZ, rotationScale); } doEvent(enqueue, wait, e); // actual mouse event } - - /** - * Send multiple-pointer event directly to be consumed - * <p> - * The index for the element of multiple-pointer arrays represents the pointer which triggered the event - * is passed via <i>actionIdx</i>. - * </p> - * - * @param eventType - * @param source - * @param when - * @param modifiers - * @param actionIdx index of multiple-pointer arrays representing the pointer which triggered the event - * @param pointerType PointerType for each pointer (multiple pointer) - * @param pointerID Pointer ID for each pointer (multiple pointer) - * @param x X-axis for each pointer (multiple pointer) - * @param y Y-axis for each pointer (multiple pointer) - * @param pressure Pressure for each pointer (multiple pointer) - * @param maxPressure Maximum pointer pressure for all pointer - * @param button Corresponding mouse-button - * @param clickCount Mouse-button click-count - * @param rotationXYZ Rotation of all axis - * @param rotationScale Rotation scale - */ - public void sendMouseEvent(short eventType, Object source, long when, int modifiers, - int actionIdx, PointerType pointerType[], short[] pointerID, - int[] x, int[] y, float[] pressure, float maxPressure, - short button, short clickCount, float[] rotationXYZ, float rotationScale) { - final MouseEvent pe = MouseEvent.create(eventType, source, when, modifiers, actionIdx, - pointerType, pointerID, x, y, pressure, maxPressure, button, clickCount, - rotationXYZ, rotationScale); - consumeMouseEvent(pe); - } @Override public final void addMouseListener(MouseListener l) { @@ -2619,25 +2724,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer * - dispatch event to listener * </pre> */ - protected void consumeMouseEvent(MouseEvent pe) { - final int x = pe.getX(); - final int y = pe.getY(); + private final void consumePointerEvent(MouseEvent pe) { + int x = pe.getX(); + int y = pe.getY(); - if( x < 0 || y < 0 || x >= getWidth() || y >= getHeight() ) { - if(DEBUG_MOUSE_EVENT) { - System.err.println("consumeMouseEvent.drop: "+pe); - } - return; // .. invalid .. - } if(DEBUG_MOUSE_EVENT) { System.err.println("consumeMouseEvent.in: "+pe); } // - // - Remove redundant events // - Determine ENTERED/EXITED state - // - synthesize ENTERED event - // - fix MOVED/DRAGGED event + // - Synthesize ENTERED event // - Reset states if applicable // final long when = pe.getWhen(); @@ -2646,36 +2743,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer switch( eventType ) { case MouseEvent.EVENT_MOUSE_EXITED: case MouseEvent.EVENT_MOUSE_ENTERED: - pState1.insideWindow = eventType == MouseEvent.EVENT_MOUSE_ENTERED; - // clear states - pState1.lastButtonPressTime = 0; - pState1.buttonPressed = 0; + // clip coordinates to window dimension + x = Math.min(Math.max(x, 0), getWidth()-1); + y = Math.min(Math.max(y, 0), getHeight()-1); + pState0.insideWindow = eventType == MouseEvent.EVENT_MOUSE_ENTERED; + pState0.clearButton(); eEntered = null; break; - case MouseEvent.EVENT_MOUSE_MOVED: - if ( pState1.buttonPressed > 0 ) { - pe = pe.createVariant(MouseEvent.EVENT_MOUSE_DRAGGED); - eventType = pe.getEventType(); - } - // Fall through intended ! - case MouseEvent.EVENT_MOUSE_DRAGGED: - if( pState1.insideWindow && pState1.lastMovePosition.getX() == x && pState1.lastMovePosition.getY() == y ) { - if(DEBUG_MOUSE_EVENT) { - System.err.println("consumeMouseEvent: skip EVENT_MOUSE_MOVED w/ same position: "+pState1.lastMovePosition); - } - return; // skip same position - } - pState1.lastMovePosition.setX(x); - pState1.lastMovePosition.setY(y); - // Fall through intended ! default: - if(!pState1.insideWindow) { - pState1.insideWindow = true; + if(!pState0.insideWindow) { + pState0.insideWindow = true; + pState0.clearButton(); eEntered = pe.createVariant(MouseEvent.EVENT_MOUSE_ENTERED); - // clear states - pState1.lastButtonPressTime = 0; - pState1.buttonPressed = 0; } else { eEntered = null; } @@ -2685,6 +2765,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println("consumeMouseEvent.send.0: "+eEntered); } dispatchMouseEvent(eEntered); + } else if( x < 0 || y < 0 || x >= getWidth() || y >= getHeight() ) { + if(DEBUG_MOUSE_EVENT) { + System.err.println("consumeMouseEvent.drop: "+pe); + } + return; // .. invalid .. } // @@ -2758,25 +2843,24 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } // - // Synthesize mouse click - // + // - Synthesize mouse CLICKED + // - Ignore sent CLICKED + // final MouseEvent eClicked; switch( eventType ) { case MouseEvent.EVENT_MOUSE_PRESSED: if( 1 == pe.getPointerCount() ) { - pState1.lastButtonPressTime = when; + pState0.lastButtonPressTime = when; } - pState1.buttonPressed = pe.getButton(); eClicked = null; break; case MouseEvent.EVENT_MOUSE_RELEASED: - if( 1 == pe.getPointerCount() && when - pState1.lastButtonPressTime < MouseEvent.getClickTimeout() ) { + if( 1 == pe.getPointerCount() && when - pState0.lastButtonPressTime < MouseEvent.getClickTimeout() ) { eClicked = pe.createVariant(MouseEvent.EVENT_MOUSE_CLICKED); } else { eClicked = null; - pState1.lastButtonPressTime = 0; + pState0.lastButtonPressTime = 0; } - pState1.buttonPressed = 0; break; case MouseEvent.EVENT_MOUSE_CLICKED: // ignore - synthesized here .. @@ -2874,12 +2958,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) { // Always add currently pressed mouse buttons to modifier mask - consumeKeyEvent( KeyEvent.create(eventType, this, System.currentTimeMillis(), modifiers | pState0.buttonModMask, keyCode, keySym, keyChar) ); + consumeKeyEvent( KeyEvent.create(eventType, this, System.currentTimeMillis(), modifiers | pState1.buttonPressedMask, keyCode, keySym, keyChar) ); } public void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short keyCode, short keySym, char keyChar) { // Always add currently pressed mouse buttons to modifier mask - enqueueEvent(wait, KeyEvent.create(eventType, this, System.currentTimeMillis(), modifiers | pState0.buttonModMask, keyCode, keySym, keyChar) ); + enqueueEvent(wait, KeyEvent.create(eventType, this, System.currentTimeMillis(), modifiers | pState1.buttonPressedMask, keyCode, keySym, keyChar) ); } @Override @@ -2980,7 +3064,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return e.isConsumed(); } - protected void consumeKeyEvent(KeyEvent e) { + private final void consumeKeyEvent(KeyEvent e) { boolean consumedE = false; if( null != keyboardFocusHandler && !e.isAutoRepeat() ) { consumedE = propagateKeyEvent(e, keyboardFocusHandler); @@ -3059,7 +3143,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return windowListeners.toArray(new WindowListener[windowListeners.size()]); } - protected void consumeWindowEvent(WindowEvent e) { + private final void consumeWindowEvent(WindowEvent e) { if(DEBUG_IMPLEMENTATION) { System.err.println("consumeWindowEvent: "+e+", visible "+isVisible()+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); } @@ -3266,10 +3350,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } else if ( (left != insets.getLeftWidth() || right != insets.getRightWidth() || top != insets.getTopHeight() || bottom != insets.getBottomHeight() ) ) { - insets.setLeftWidth(left); - insets.setRightWidth(right); - insets.setTopHeight(top); - insets.setBottomHeight(bottom); + insets.set(left, right, top, bottom); if(DEBUG_IMPLEMENTATION) { System.err.println("Window.insetsChanged: (defer: "+defer+") "+insets); } diff --git a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java index 0e76db374..23c32993f 100644 --- a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java +++ b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java @@ -252,22 +252,22 @@ public class AndroidNewtEventFactory { } } - private static void collectPointerData(MotionEvent e, int eIdx, int dIdx, final int[] x, final int[] y, final float[] pressure, short[] pointerIds, final com.jogamp.newt.event.MouseEvent.PointerType[] pointerTypes) { - x[dIdx] = (int)e.getX(eIdx); - y[dIdx] = (int)e.getY(eIdx); - pressure[dIdx] = e.getPressure(eIdx); - pointerIds[dIdx] = (short)e.getPointerId(eIdx); - if( pressure[dIdx] > maxPressure ) { - maxPressure = pressure[dIdx]; + private static void collectPointerData(MotionEvent e, int idx, final int[] x, final int[] y, final float[] pressure, short[] pointerIds, final int[] pointerTypes) { + x[idx] = (int)e.getX(idx); + y[idx] = (int)e.getY(idx); + pressure[idx] = e.getPressure(idx); + pointerIds[idx] = (short)e.getPointerId(idx); + if( pressure[idx] > maxPressure ) { + maxPressure = pressure[idx]; } - pointerTypes[dIdx] = aToolType2PointerType( e.getToolType(eIdx) ); + pointerTypes[idx] = aToolType2PointerType( e.getToolType(idx) ).ordinal(); if(DEBUG_MOUSE_EVENT) { - System.err.println("createMouseEvent: ptr-data["+eIdx+" -> "+dIdx+"] "+x[dIdx]+"/"+y[dIdx]+", pressure "+pressure[dIdx]+", id "+pointerIds[dIdx]+", type "+pointerTypes[dIdx]); + System.err.println("createMouseEvent: ptr-data["+idx+"] "+x[idx]+"/"+y[idx]+", pressure "+pressure[idx]+", id "+pointerIds[idx]+", type "+pointerTypes[idx]); } } - public com.jogamp.newt.event.MouseEvent createMouseEvents(boolean isOnTouchEvent, - android.view.MotionEvent event, com.jogamp.newt.Window newtSource) { + public boolean sendPointerEvent(boolean enqueue, boolean wait, boolean setFocusOnDown, boolean isOnTouchEvent, + android.view.MotionEvent event, jogamp.newt.driver.android.WindowDriver newtSource) { if(DEBUG_MOUSE_EVENT) { System.err.println("createMouseEvent: isOnTouchEvent "+isOnTouchEvent+", "+event); } @@ -285,7 +285,6 @@ public class AndroidNewtEventFactory { final float[] rotationXYZ = new float[] { 0f, 0f, 0f }; if( (short)0 != nType ) { - final short clickCount = 1; int modifiers = 0; // @@ -298,7 +297,7 @@ public class AndroidNewtEventFactory { case android.view.MotionEvent.ACTION_POINTER_UP: { pIndex = event.getActionIndex(); final int b = event.getPointerId(pIndex) + 1; // FIXME: Assumption that Pointer-ID starts w/ 0 ! - if( com.jogamp.newt.event.MouseEvent.BUTTON1 <= b && b <= com.jogamp.newt.event.MouseEvent.BUTTON_NUMBER ) { + if( com.jogamp.newt.event.MouseEvent.BUTTON1 <= b && b <= com.jogamp.newt.event.MouseEvent.BUTTON_COUNT ) { button = (short)b; } else { button = com.jogamp.newt.event.MouseEvent.BUTTON1; @@ -328,6 +327,15 @@ public class AndroidNewtEventFactory { } final int pCount = event.getPointerCount(); // all + switch( aType ) { + case android.view.MotionEvent.ACTION_DOWN: + case android.view.MotionEvent.ACTION_POINTER_DOWN: + modifiers |= InputEvent.getButtonMask(button); + if( setFocusOnDown ) { + newtSource.focusChanged(false, true); + } + } + // // Collect common data // @@ -335,38 +343,20 @@ public class AndroidNewtEventFactory { final int[] y = new int[pCount]; final float[] pressure = new float[pCount]; final short[] pointerIds = new short[pCount]; - final com.jogamp.newt.event.MouseEvent.PointerType[] pointerTypes = new com.jogamp.newt.event.MouseEvent.PointerType[pCount]; + final int[] pointerTypes = new int[pCount]; if( 0 < pCount ) { if(DEBUG_MOUSE_EVENT) { System.err.println("createMouseEvent: collect ptr-data [0.."+(pCount-1)+", count "+pCount+", action "+pIndex+"], aType "+aType+", button "+button); } - int j = 0; - // Always put action-pointer data at index 0 - collectPointerData(event, pIndex, j++, x, y, pressure, pointerIds, pointerTypes); for(int i=0; i < pCount; i++) { - if( pIndex != i ) { - collectPointerData(event, i, j++, x, y, pressure, pointerIds, pointerTypes); - } + collectPointerData(event, i, x, y, pressure, pointerIds, pointerTypes); } } - - if(null!=newtSource) { - if(newtSource.isPointerConfined()) { - modifiers |= InputEvent.CONFINED_MASK; - } - if(!newtSource.isPointerVisible()) { - modifiers |= InputEvent.INVISIBLE_MASK; - } - } - - final Object src = (null==newtSource)?null:(Object)newtSource; - final long unixTime = System.currentTimeMillis() + ( event.getEventTime() - android.os.SystemClock.uptimeMillis() ); - - return new com.jogamp.newt.event.MouseEvent(nType, src, unixTime, - modifiers, pointerTypes, pointerIds, x, y, pressure, maxPressure, - button, clickCount, rotationXYZ, rotationScale); + newtSource.doPointerEvent(enqueue, wait, pointerTypes, nType, modifiers, + pIndex, pointerIds, x, y, pressure, maxPressure, rotationXYZ, rotationScale); + return true; } - return null; // no mapping .. + return false; // no mapping .. } } diff --git a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java index df52208df..5a4743f73 100644 --- a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java +++ b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java @@ -13,16 +13,10 @@ public class AndroidNewtEventTranslator implements View.OnKeyListener, View.OnTo } private final boolean processTouchMotionEvents(View v, android.view.MotionEvent event, boolean isOnTouchEvent) { - final com.jogamp.newt.event.MouseEvent newtEvent = factory.createMouseEvents(isOnTouchEvent, event, newtWindow); - if(null != newtEvent) { - switch( event.getActionMasked() ) { - case android.view.MotionEvent.ACTION_DOWN: - case android.view.MotionEvent.ACTION_POINTER_DOWN: - newtWindow.focusChanged(false, true); - break; - } - newtWindow.enqueueEvent(false, newtEvent); - try { Thread.sleep((long) (100.0F/3.0F)); } // 33 ms + final boolean eventSent = factory.sendPointerEvent(true /*enqueue*/, false /*wait*/, true /*setFocusOnDown*/, + isOnTouchEvent, event, newtWindow); + if( eventSent ) { + try { Thread.sleep((long) (100.0F/3.0F)); } // 33 ms - FIXME ?? catch(InterruptedException e) { } return true; // consumed/handled, further interest in events } |