Merge pull request #5423 from SeannyM/misc-touch

Android: Various touch control improvements
This commit is contained in:
Markus Wick 2017-05-17 11:05:33 +02:00 committed by GitHub
commit 392936a5e5
10 changed files with 134 additions and 77 deletions

View File

@ -133,25 +133,22 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_MOVE:
// If a pointer enters the bounds of a button, press that button.
if (button.getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex)))
{
button.setPressedState(true);
button.setTrackId(event.getPointerId(pointerIndex));
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), ButtonState.PRESSED);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
// If a pointer ends, release the button it was pressing.
if (button.getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex)))
if (button.getTrackId() == event.getPointerId(pointerIndex))
{
button.setPressedState(false);
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), ButtonState.RELEASED);
}
button.setPressedState(false);
invalidate();
break;
}
}
@ -163,7 +160,6 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_MOVE:
// If a pointer enters the bounds of a button, press that button.
if (dpad.getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex)))
{
@ -193,21 +189,20 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
setDpadState(dpad, up, down, left, right);
invalidate();
dpad.setTrackId(event.getPointerId(pointerIndex));
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
// If a pointer ends, release the buttons.
if (dpad.getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex)))
if (dpad.getTrackId() == event.getPointerId(pointerIndex))
{
for(int i = 0; i < 4; i++)
{
dpad.setState(InputOverlayDrawableDpad.STATE_DEFAULT);
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i), ButtonState.RELEASED);
}
}
dpad.setState(InputOverlayDrawableDpad.STATE_DEFAULT);
invalidate();
break;
}
}
@ -224,6 +219,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
}
invalidate();
return true;
}
@ -333,11 +330,9 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
mJoystickBeingConfigured = null;
}
break;
}
}
return true;
}
@ -414,15 +409,13 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
if (mPreferences.getBoolean("buttonToggleGc9", true))
{
overlayJoysticks.add(initializeOverlayJoystick(getContext(),
R.drawable.gcwii_joystick_range, R.drawable.gcwii_joystick,
ButtonType.STICK_MAIN));
overlayJoysticks.add(initializeOverlayJoystick(getContext(), R.drawable.gcwii_joystick_range,
R.drawable.gcwii_joystick, R.drawable.gcwii_joystick_pressed, ButtonType.STICK_MAIN));
}
if (mPreferences.getBoolean("buttonToggleGc10", true))
{
overlayJoysticks.add(initializeOverlayJoystick(getContext(),
R.drawable.gcwii_joystick_range, R.drawable.gcpad_c,
ButtonType.STICK_C));
overlayJoysticks.add(initializeOverlayJoystick(getContext(), R.drawable.gcwii_joystick_range,
R.drawable.gcpad_c, R.drawable.gcpad_c_pressed, ButtonType.STICK_C));
}
}
@ -487,9 +480,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
if (mPreferences.getBoolean("buttonToggleWii10", true))
{
overlayJoysticks.add(initializeOverlayJoystick(getContext(),
R.drawable.gcwii_joystick_range, R.drawable.gcwii_joystick,
ButtonType.NUNCHUK_STICK));
overlayJoysticks.add(initializeOverlayJoystick(getContext(), R.drawable.gcwii_joystick_range,
R.drawable.gcwii_joystick, R.drawable.gcwii_joystick_pressed, ButtonType.NUNCHUK_STICK));
}
}
@ -548,15 +540,13 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
if (mPreferences.getBoolean("buttonToggleClassic12", true))
{
overlayJoysticks.add(initializeOverlayJoystick(getContext(),
R.drawable.gcwii_joystick_range, R.drawable.gcwii_joystick,
ButtonType.CLASSIC_STICK_LEFT));
overlayJoysticks.add(initializeOverlayJoystick(getContext(), R.drawable.gcwii_joystick_range,
R.drawable.gcwii_joystick, R.drawable.gcwii_joystick_pressed, ButtonType.CLASSIC_STICK_LEFT));
}
if (mPreferences.getBoolean("buttonToggleClassic13", true))
{
overlayJoysticks.add(initializeOverlayJoystick(getContext(),
R.drawable.gcwii_joystick_range, R.drawable.gcwii_joystick,
ButtonType.CLASSIC_STICK_RIGHT));
overlayJoysticks.add(initializeOverlayJoystick(getContext(), R.drawable.gcwii_joystick_range,
R.drawable.gcwii_joystick, R.drawable.gcwii_joystick_pressed, ButtonType.CLASSIC_STICK_RIGHT));
}
}
@ -785,14 +775,15 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
/**
* Initializes an {@link InputOverlayDrawableJoystick}
*
* @param context The current {@link Context}
* @param resOuter Resource ID for the outer image of the joystick (the static image that shows the circular bounds).
* @param resInner Resource ID for the inner image of the joystick (the one you actually move around).
* @param joystick Identifier for which joystick this is.
* @param context The current {@link Context}
* @param resOuter Resource ID for the outer image of the joystick (the static image that shows the circular bounds).
* @param defaultResInner Resource ID for the default inner image of the joystick (the one you actually move around).
* @param pressedResInner Resource ID for the pressed inner image of the joystick.
* @param joystick Identifier for which joystick this is.
*
* @return the initialized {@link InputOverlayDrawableJoystick}.
*/
private static InputOverlayDrawableJoystick initializeOverlayJoystick(Context context, int resOuter, int resInner, int joystick)
private static InputOverlayDrawableJoystick initializeOverlayJoystick(Context context, int resOuter, int defaultResInner, int pressedResInner, int joystick)
{
// Resources handle for fetching the initial Drawable resource.
final Resources res = context.getResources();
@ -807,7 +798,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
// Initialize the InputOverlayDrawableJoystick.
final Bitmap bitmapOuter = resizeBitmap(context, BitmapFactory.decodeResource(res, resOuter), scale);
final Bitmap bitmapInner = BitmapFactory.decodeResource(res, resInner);
final Bitmap bitmapInnerDefault = BitmapFactory.decodeResource(res, defaultResInner);
final Bitmap bitmapInnerPressed = BitmapFactory.decodeResource(res, pressedResInner);
// The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay.
// These were set in the input overlay configuration menu.
@ -835,10 +827,9 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
// Send the drawableId to the joystick so it can be referenced when saving control position.
final InputOverlayDrawableJoystick overlayDrawable
= new InputOverlayDrawableJoystick(res,
bitmapOuter, bitmapInner,
outerRect, innerRect,
joystick);
= new InputOverlayDrawableJoystick(res, bitmapOuter,
bitmapInnerDefault, bitmapInnerPressed,
outerRect, innerRect, joystick);
// Need to set the image's position
overlayDrawable.setPosition(drawableX, drawableY);

View File

@ -21,6 +21,7 @@ public final class InputOverlayDrawableButton
{
// The ID identifying what type of button this Drawable represents.
private int mButtonType;
private int mTrackId;
private int mPreviousTouchX, mPreviousTouchY;
private int mControlPositionX, mControlPositionY;
private int mWidth;
@ -57,6 +58,16 @@ public final class InputOverlayDrawableButton
return mButtonType;
}
public void setTrackId(int trackId)
{
mTrackId = trackId;
}
public int getTrackId()
{
return mTrackId;
}
public boolean onConfigureTouch(MotionEvent event)
{
int pointerIndex = event.getActionIndex();

View File

@ -21,6 +21,7 @@ public final class InputOverlayDrawableDpad
{
// The ID identifying what type of button this Drawable represents.
private int[] mButtonType = new int[4];
private int mTrackId;
private int mPreviousTouchX, mPreviousTouchY;
private int mControlPositionX, mControlPositionY;
private int mWidth;
@ -135,6 +136,16 @@ public final class InputOverlayDrawableDpad
return mButtonType[direction];
}
public void setTrackId(int trackId)
{
mTrackId = trackId;
}
public int getTrackId()
{
return mTrackId;
}
public boolean onConfigureTouch(MotionEvent event)
{
int pointerIndex = event.getActionIndex();

View File

@ -18,42 +18,52 @@ import android.view.View;
* Custom {@link BitmapDrawable} that is capable
* of storing it's own ID.
*/
public final class InputOverlayDrawableJoystick extends BitmapDrawable
public final class InputOverlayDrawableJoystick
{
private final int[] axisIDs = {0, 0, 0, 0};
private final float[] axises = {0f, 0f};
private final BitmapDrawable ringInner;
private int trackId = -1;
private int mJoystickType;
private int mControlPositionX, mControlPositionY;
private int mControlPositionX, mControlPositionY;
private int mPreviousTouchX, mPreviousTouchY;
private int mWidth;
private int mHeight;
private BitmapDrawable mOuterBitmap;
private BitmapDrawable mDefaultStateInnerBitmap;
private BitmapDrawable mPressedStateInnerBitmap;
private boolean mPressedState = false;
/**
* Constructor
*
* @param res {@link Resources} instance.
* @param bitmapOuter {@link Bitmap} which represents the outer non-movable part of the joystick.
* @param bitmapInner {@link Bitmap} which represents the inner movable part of the joystick.
* @param rectOuter {@link Rect} which represents the outer joystick bounds.
* @param rectInner {@link Rect} which represents the inner joystick bounds.
* @param joystick Identifier for which joystick this is.
* @param res {@link Resources} instance.
* @param bitmapOuter {@link Bitmap} which represents the outer non-movable part of the joystick.
* @param bitmapInnerDefault {@link Bitmap} which represents the default inner movable part of the joystick.
* @param bitmapInnerPressed {@link Bitmap} which represents the pressed inner movable part of the joystick.
* @param rectOuter {@link Rect} which represents the outer joystick bounds.
* @param rectInner {@link Rect} which represents the inner joystick bounds.
* @param joystick Identifier for which joystick this is.
*/
public InputOverlayDrawableJoystick(Resources res,
Bitmap bitmapOuter, Bitmap bitmapInner,
Rect rectOuter, Rect rectInner,
int joystick)
public InputOverlayDrawableJoystick(Resources res, Bitmap bitmapOuter,
Bitmap bitmapInnerDefault, Bitmap bitmapInnerPressed,
Rect rectOuter, Rect rectInner, int joystick)
{
super(res, bitmapOuter);
this.setBounds(rectOuter);
this.ringInner = new BitmapDrawable(res, bitmapInner);
this.ringInner.setBounds(rectInner);
SetInnerBounds();
this.axisIDs[0] = joystick + 1;
this.axisIDs[1] = joystick + 2;
this.axisIDs[2] = joystick + 3;
this.axisIDs[3] = joystick + 4;
axisIDs[0] = joystick + 1;
axisIDs[1] = joystick + 2;
axisIDs[2] = joystick + 3;
axisIDs[3] = joystick + 4;
mJoystickType = joystick;
mOuterBitmap = new BitmapDrawable(res, bitmapOuter);
mDefaultStateInnerBitmap = new BitmapDrawable(res, bitmapInnerDefault);
mPressedStateInnerBitmap = new BitmapDrawable(res, bitmapInnerPressed);
mWidth = bitmapOuter.getWidth();
mHeight = bitmapOuter.getHeight();
setBounds(rectOuter);
mDefaultStateInnerBitmap.setBounds(rectInner);
mPressedStateInnerBitmap.setBounds(rectInner);
SetInnerBounds();
}
/**
@ -66,11 +76,10 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
return mJoystickType;
}
@Override
public void draw(Canvas canvas)
{
super.draw(canvas);
ringInner.draw(canvas);
mOuterBitmap.draw(canvas);
getCurrentStateBitmapDrawable().draw(canvas);
}
public void TrackEvent(MotionEvent event)
@ -82,12 +91,16 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
if (getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex)))
{
mPressedState = true;
trackId = event.getPointerId(pointerIndex);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (trackId == event.getPointerId(pointerIndex))
{
mPressedState = false;
axises[0] = axises[1] = 0.0f;
SetInnerBounds();
trackId = -1;
@ -136,12 +149,13 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
int deltaY = fingerPositionY - mPreviousTouchY;
mControlPositionX += deltaX;
mControlPositionY += deltaY;
setBounds(new Rect(mControlPositionX, mControlPositionY, getBitmap().getWidth() + mControlPositionX, getBitmap().getHeight() + mControlPositionY));
setBounds(new Rect(mControlPositionX, mControlPositionY,
mOuterBitmap.getIntrinsicWidth() + mControlPositionX,
mOuterBitmap.getIntrinsicHeight() + mControlPositionY));
SetInnerBounds();
mPreviousTouchX = fingerPositionX;
mPreviousTouchY = fingerPositionY;
break;
}
return true;
}
@ -164,17 +178,22 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
private void SetInnerBounds()
{
float floatX = this.getBounds().centerX();
float floatY = this.getBounds().centerY();
floatY += axises[0] * (this.getBounds().height() / 2);
floatX += axises[1] * (this.getBounds().width() / 2);
int X = (int)(floatX);
int Y = (int)(floatY);
int width = this.ringInner.getBounds().width() / 2;
int height = this.ringInner.getBounds().height() / 2;
this.ringInner.setBounds(X - width, Y - height,
X + width, Y + height);
ringInner.invalidateSelf();
int X = getBounds().centerX() + (int)((axises[1]) * (getBounds().width() / 2));
int Y = getBounds().centerY() + (int)((axises[0]) * (getBounds().height() / 2));
if (X > getBounds().centerX() + (getBounds().width() / 2))
X = getBounds().centerX() + (getBounds().width() / 2);
if (X < getBounds().centerX() - (getBounds().width() / 2))
X = getBounds().centerX() - (getBounds().width() / 2);
if (Y > getBounds().centerY() + (getBounds().height() / 2))
Y = getBounds().centerY() + (getBounds().height() / 2);
if (Y < getBounds().centerY() - (getBounds().height() / 2))
Y = getBounds().centerY() - (getBounds().height() / 2);
int width = mPressedStateInnerBitmap.getBounds().width() / 2;
int height = mPressedStateInnerBitmap.getBounds().height() / 2;
mDefaultStateInnerBitmap.setBounds(X - width, Y - height, X + width, Y + height);
mPressedStateInnerBitmap.setBounds(mDefaultStateInnerBitmap.getBounds());
}
public void setPosition(int x, int y)
@ -182,4 +201,29 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
mControlPositionX = x;
mControlPositionY = y;
}
private BitmapDrawable getCurrentStateBitmapDrawable()
{
return mPressedState ? mPressedStateInnerBitmap : mDefaultStateInnerBitmap;
}
public void setBounds(Rect bounds)
{
mOuterBitmap.setBounds(bounds);
}
public Rect getBounds()
{
return mOuterBitmap.getBounds();
}
public int getWidth()
{
return mWidth;
}
public int getHeight()
{
return mHeight;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB