Added improved mouse pointer capture under API 26. (Thanks Rachel!)
authorSam Lantinga <slouken@libsdl.org>
Tue, 05 Jun 2018 14:08:39 -0700
changeset 120095b41aa10b12f
parent 12008 91f9b8f22b17
child 12010 6d44d9a589e1
Added improved mouse pointer capture under API 26. (Thanks Rachel!)
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
     1.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Tue Jun 05 12:46:13 2018 -0700
     1.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Tue Jun 05 14:08:39 2018 -0700
     1.3 @@ -87,6 +87,9 @@
     1.4  
     1.5      protected static SDLGenericMotionListener_API12 getMotionListener() {
     1.6          if (mMotionListener == null) {
     1.7 +            if (Build.VERSION.SDK_INT >= 26) {
     1.8 +                mMotionListener = new SDLGenericMotionListener_API26();
     1.9 +            } else 
    1.10              if (Build.VERSION.SDK_INT >= 24) {
    1.11                  mMotionListener = new SDLGenericMotionListener_API24();
    1.12              } else {
    1.13 @@ -301,6 +304,7 @@
    1.14          SDLActivity.mHasFocus = hasFocus;
    1.15          if (hasFocus) {
    1.16             mNextNativeState = NativeState.RESUMED;
    1.17 +           SDLActivity.getMotionListener().reclaimRelativeMouseModeIfNeeded();
    1.18          } else {
    1.19             mNextNativeState = NativeState.PAUSED;
    1.20          }
    1.21 @@ -635,7 +639,6 @@
    1.22          }
    1.23      }
    1.24  
    1.25 -
    1.26      /**
    1.27       * This method is called by SDL using JNI.
    1.28       */
    1.29 @@ -736,6 +739,12 @@
    1.30          return false;
    1.31      }
    1.32  
    1.33 +    // This method is called by SDLControllerManager's API 26 Generic Motion Handler.
    1.34 +    public static View getContentView() 
    1.35 +    {
    1.36 +        return mSingleton.mLayout;
    1.37 +    }
    1.38 +
    1.39      static class ShowTextInputTask implements Runnable {
    1.40          /*
    1.41           * This is used to regulate the pan&scan method to have some offset from
    1.42 @@ -1270,6 +1279,10 @@
    1.43              setOnGenericMotionListener(SDLActivity.getMotionListener());
    1.44          }
    1.45  
    1.46 +        if (Build.VERSION.SDK_INT >= 26) {
    1.47 +            setOnCapturedPointerListener(new SDLCapturedPointerListener_API26());
    1.48 +        }
    1.49 +
    1.50          // Some arbitrary defaults to avoid a potential division by zero
    1.51          mWidth = 1.0f;
    1.52          mHeight = 1.0f;
     2.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java	Tue Jun 05 12:46:13 2018 -0700
     2.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java	Tue Jun 05 14:08:39 2018 -0700
     2.3 @@ -569,6 +569,11 @@
     2.4          return false;
     2.5      }
     2.6  
     2.7 +    public void reclaimRelativeMouseModeIfNeeded()
     2.8 +    {
     2.9 +
    2.10 +    }
    2.11 +
    2.12      public float getEventX(MotionEvent event) {
    2.13          return event.getX(0);
    2.14      }
    2.15 @@ -633,19 +638,23 @@
    2.16          return false;
    2.17      }
    2.18  
    2.19 +    @Override
    2.20      public boolean supportsRelativeMouse() {
    2.21          return true;
    2.22      }
    2.23  
    2.24 +    @Override
    2.25      public boolean inRelativeMode() {
    2.26          return mRelativeModeEnabled;
    2.27      }
    2.28  
    2.29 +    @Override
    2.30      public boolean setRelativeMouseEnabled(boolean enabled) {
    2.31          mRelativeModeEnabled = enabled;
    2.32          return true;
    2.33      }
    2.34  
    2.35 +    @Override
    2.36      public float getEventX(MotionEvent event) {
    2.37          if (mRelativeModeEnabled) {
    2.38              return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
    2.39 @@ -655,6 +664,7 @@
    2.40          }
    2.41      }
    2.42  
    2.43 +    @Override
    2.44      public float getEventY(MotionEvent event) {
    2.45          if (mRelativeModeEnabled) {
    2.46              return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
    2.47 @@ -665,3 +675,163 @@
    2.48      }
    2.49  }
    2.50  
    2.51 +
    2.52 +class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
    2.53 +    // Generic Motion (mouse hover, joystick...) events go here
    2.54 +    private boolean mRelativeModeEnabled;
    2.55 +
    2.56 +    @Override
    2.57 +    public boolean onGenericMotion(View v, MotionEvent event) {
    2.58 +        float x, y;
    2.59 +        int action;
    2.60 +
    2.61 +        switch ( event.getSource() ) {
    2.62 +            case InputDevice.SOURCE_JOYSTICK:
    2.63 +            case InputDevice.SOURCE_GAMEPAD:
    2.64 +            case InputDevice.SOURCE_DPAD:
    2.65 +                return SDLControllerManager.handleJoystickMotionEvent(event);
    2.66 +                
    2.67 +            case InputDevice.SOURCE_MOUSE:
    2.68 +                if (!SDLActivity.mSeparateMouseAndTouch) {
    2.69 +                    break;
    2.70 +                }
    2.71 +
    2.72 +                action = event.getActionMasked();
    2.73 +                switch (action) {
    2.74 +                    case MotionEvent.ACTION_SCROLL:
    2.75 +                        x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
    2.76 +                        y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
    2.77 +                        SDLActivity.onNativeMouse(0, action, x, y, false);
    2.78 +                        return true;
    2.79 +
    2.80 +                    case MotionEvent.ACTION_HOVER_MOVE:
    2.81 +                        x = event.getX(0);
    2.82 +                        y = event.getY(0);
    2.83 +                        SDLActivity.onNativeMouse(0, action, x, y, false);
    2.84 +                        return true;
    2.85 +
    2.86 +                    default:
    2.87 +                        break;
    2.88 +                }
    2.89 +                break;
    2.90 +
    2.91 +            case InputDevice.SOURCE_MOUSE_RELATIVE:
    2.92 +                if (!SDLActivity.mSeparateMouseAndTouch) {
    2.93 +                    break;
    2.94 +                }
    2.95 +                action = event.getActionMasked();
    2.96 +                switch (action) {
    2.97 +                    case MotionEvent.ACTION_SCROLL:
    2.98 +                        x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
    2.99 +                        y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
   2.100 +                        SDLActivity.onNativeMouse(0, action, x, y, false);
   2.101 +                        return true;
   2.102 +
   2.103 +                    case MotionEvent.ACTION_HOVER_MOVE:
   2.104 +                        x = event.getX(0);
   2.105 +                        y = event.getY(0);
   2.106 +                        SDLActivity.onNativeMouse(0, action, x, y, true);
   2.107 +                        return true;
   2.108 +
   2.109 +                    default:
   2.110 +                        break;
   2.111 +                }
   2.112 +                break;
   2.113 +
   2.114 +            default:
   2.115 +                break;
   2.116 +        }
   2.117 +
   2.118 +        // Event was not managed
   2.119 +        return false;
   2.120 +    }
   2.121 +
   2.122 +    @Override
   2.123 +    public boolean supportsRelativeMouse() {
   2.124 +        return true;
   2.125 +    }
   2.126 +
   2.127 +    @Override
   2.128 +    public boolean inRelativeMode() {
   2.129 +        return mRelativeModeEnabled;
   2.130 +    }
   2.131 +
   2.132 +    @Override
   2.133 +    public boolean setRelativeMouseEnabled(boolean enabled) {
   2.134 +        if (enabled) {
   2.135 +            SDLActivity.getContentView().requestPointerCapture();
   2.136 +        }
   2.137 +        else {
   2.138 +            SDLActivity.getContentView().releasePointerCapture();            
   2.139 +        }
   2.140 +        mRelativeModeEnabled = enabled;
   2.141 +        return true;
   2.142 +    }
   2.143 +
   2.144 +    @Override
   2.145 +    public void reclaimRelativeMouseModeIfNeeded()
   2.146 +    {
   2.147 +        if (mRelativeModeEnabled) {
   2.148 +            SDLActivity.getContentView().requestPointerCapture();
   2.149 +        }
   2.150 +    }
   2.151 +
   2.152 +    @Override
   2.153 +    public float getEventX(MotionEvent event) {
   2.154 +        // Relative mouse in capture mode will only have relative for X/Y
   2.155 +        return event.getX(0);
   2.156 +    }
   2.157 +
   2.158 +    @Override
   2.159 +    public float getEventY(MotionEvent event) {
   2.160 +        // Relative mouse in capture mode will only have relative for X/Y
   2.161 +        return event.getY(0);
   2.162 +    }
   2.163 +}
   2.164 +
   2.165 +class SDLCapturedPointerListener_API26 implements View.OnCapturedPointerListener
   2.166 +{
   2.167 +    @Override
   2.168 +    public boolean onCapturedPointer(View view, MotionEvent event)
   2.169 +    {
   2.170 +        int action = event.getActionMasked();
   2.171 +
   2.172 +        float x, y;
   2.173 +        switch (action) {
   2.174 +            case MotionEvent.ACTION_SCROLL:
   2.175 +                x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
   2.176 +                y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
   2.177 +                SDLActivity.onNativeMouse(0, action, x, y, false);
   2.178 +                return true;
   2.179 +
   2.180 +            case MotionEvent.ACTION_HOVER_MOVE:
   2.181 +            case MotionEvent.ACTION_MOVE:
   2.182 +                x = event.getX(0);
   2.183 +                y = event.getY(0);
   2.184 +                SDLActivity.onNativeMouse(0, action, x, y, true);
   2.185 +                return true;
   2.186 +
   2.187 +            case MotionEvent.ACTION_BUTTON_PRESS:
   2.188 +            case MotionEvent.ACTION_BUTTON_RELEASE:
   2.189 +
   2.190 +                // Change our action value to what SDL's code expects.
   2.191 +                if (action == MotionEvent.ACTION_BUTTON_PRESS) {
   2.192 +                    action = MotionEvent.ACTION_DOWN;
   2.193 +                }
   2.194 +                else if (action == MotionEvent.ACTION_BUTTON_RELEASE) {
   2.195 +                    action = MotionEvent.ACTION_UP;
   2.196 +                }
   2.197 +
   2.198 +                x = event.getX(0);
   2.199 +                y = event.getY(0);
   2.200 +                int button = event.getButtonState();
   2.201 +
   2.202 +                SDLActivity.onNativeMouse(button, action, x, y, true);
   2.203 +                return true;
   2.204 +
   2.205 +        }
   2.206 +
   2.207 +        return false;
   2.208 +    }
   2.209 +}
   2.210 +