android: Clean button overlay

This commit is contained in:
Narr the Reg 2023-02-13 13:11:03 -06:00 committed by bunnei
parent 43e43021a3
commit 1ab269775d
2 changed files with 65 additions and 195 deletions

View file

@ -369,29 +369,10 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener {
} }
for (InputOverlayDrawableButton button : overlayButtons) { for (InputOverlayDrawableButton button : overlayButtons) {
// Determine the button state to apply based on the MotionEvent action flag. if (!button.updateStatus(event)) {
switch (event.getAction() & MotionEvent.ACTION_MASK) { continue;
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
// 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);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
// If a pointer ends, release the button it was pressing.
if (button.getTrackId() == event.getPointerId(pointerIndex)) {
button.setPressedState(false);
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
ButtonState.RELEASED);
}
break;
} }
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), button.getStatus());
} }
for (InputOverlayDrawableDpad dpad : overlayDpads) { for (InputOverlayDrawableDpad dpad : overlayDpads) {
@ -516,136 +497,9 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener {
} }
public boolean onTouchWhileEditing(MotionEvent event) { public boolean onTouchWhileEditing(MotionEvent event) {
int pointerIndex = event.getActionIndex(); // TODO: Reimplement this
int fingerPositionX = (int) event.getX(pointerIndex);
int fingerPositionY = (int) event.getY(pointerIndex);
String orientation =
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ?
"-Portrait" : "";
// Maybe combine Button and Joystick as subclasses of the same parent?
// Or maybe create an interface like IMoveableHUDControl?
for (InputOverlayDrawableButton button : overlayButtons) {
// Determine the button state to apply based on the MotionEvent action flag.
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
// If no button is being moved now, remember the currently touched button to move.
if (mButtonBeingConfigured == null &&
button.getBounds().contains(fingerPositionX, fingerPositionY)) {
mButtonBeingConfigured = button;
mButtonBeingConfigured.onConfigureTouch(event);
}
break;
case MotionEvent.ACTION_MOVE:
if (mButtonBeingConfigured != null) {
mButtonBeingConfigured.onConfigureTouch(event);
invalidate();
return true; return true;
} }
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (mButtonBeingConfigured == button) {
// Persist button position by saving new place.
saveControlPosition(mButtonBeingConfigured.getId(),
mButtonBeingConfigured.getBounds().left,
mButtonBeingConfigured.getBounds().top, orientation);
mButtonBeingConfigured = null;
}
break;
}
}
for (InputOverlayDrawableDpad dpad : overlayDpads) {
// Determine the button state to apply based on the MotionEvent action flag.
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
// If no button is being moved now, remember the currently touched button to move.
if (mButtonBeingConfigured == null &&
dpad.getBounds().contains(fingerPositionX, fingerPositionY)) {
mDpadBeingConfigured = dpad;
mDpadBeingConfigured.onConfigureTouch(event);
}
break;
case MotionEvent.ACTION_MOVE:
if (mDpadBeingConfigured != null) {
mDpadBeingConfigured.onConfigureTouch(event);
invalidate();
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (mDpadBeingConfigured == dpad) {
// Persist button position by saving new place.
saveControlPosition(mDpadBeingConfigured.getId(0),
mDpadBeingConfigured.getBounds().left, mDpadBeingConfigured.getBounds().top,
orientation);
mDpadBeingConfigured = null;
}
break;
}
}
for (InputOverlayDrawableJoystick joystick : overlayJoysticks) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
if (mJoystickBeingConfigured == null &&
joystick.getBounds().contains(fingerPositionX, fingerPositionY)) {
mJoystickBeingConfigured = joystick;
mJoystickBeingConfigured.onConfigureTouch(event);
}
break;
case MotionEvent.ACTION_MOVE:
if (mJoystickBeingConfigured != null) {
mJoystickBeingConfigured.onConfigureTouch(event);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (mJoystickBeingConfigured != null) {
saveControlPosition(mJoystickBeingConfigured.getId(),
mJoystickBeingConfigured.getBounds().left,
mJoystickBeingConfigured.getBounds().top, orientation);
mJoystickBeingConfigured = null;
}
break;
}
}
return true;
}
private void setDpadState(InputOverlayDrawableDpad dpad, boolean up, boolean down, boolean left,
boolean right) {
if (up) {
if (left)
dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP_LEFT);
else if (right)
dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP_RIGHT);
else
dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP);
} else if (down) {
if (left)
dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN_LEFT);
else if (right)
dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN_RIGHT);
else
dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN);
} else if (left) {
dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_LEFT);
} else if (right) {
dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_RIGHT);
}
}
private void addOverlayControls(String orientation) { private void addOverlayControls(String orientation) {
if (mPreferences.getBoolean("buttonToggle0", true)) { if (mPreferences.getBoolean("buttonToggle0", true)) {

View file

@ -13,16 +13,22 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.view.MotionEvent; import android.view.MotionEvent;
import org.yuzu.yuzu_emu.NativeLibrary.ButtonState;
/** /**
* Custom {@link BitmapDrawable} that is capable * Custom {@link BitmapDrawable} that is capable
* of storing it's own ID. * of storing it's own ID.
*/ */
public final class InputOverlayDrawableButton { public final class InputOverlayDrawableButton {
// The ID identifying what type of button this Drawable represents. // The ID value what type of button this Drawable represents.
private int mButtonType; private int mButtonId;
// The ID value what motion event is tracking
private int mTrackId; private int mTrackId;
private int mPreviousTouchX, mPreviousTouchY;
private int mControlPositionX, mControlPositionY; // The drawable position on the screen
private int mButtonPositionX, mButtonPositionY;
private int mWidth; private int mWidth;
private int mHeight; private int mHeight;
private BitmapDrawable mDefaultStateBitmap; private BitmapDrawable mDefaultStateBitmap;
@ -35,60 +41,57 @@ public final class InputOverlayDrawableButton {
* @param res {@link Resources} instance. * @param res {@link Resources} instance.
* @param defaultStateBitmap {@link Bitmap} to use with the default state Drawable. * @param defaultStateBitmap {@link Bitmap} to use with the default state Drawable.
* @param pressedStateBitmap {@link Bitmap} to use with the pressed state Drawable. * @param pressedStateBitmap {@link Bitmap} to use with the pressed state Drawable.
* @param buttonType Identifier for this type of button. * @param buttonId Identifier for this type of button.
*/ */
public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap, public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap,
Bitmap pressedStateBitmap, int buttonType) { Bitmap pressedStateBitmap, int buttonId) {
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap); mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap); mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap);
mButtonType = buttonType; mButtonId = buttonId;
mTrackId = -1;
mWidth = mDefaultStateBitmap.getIntrinsicWidth(); mWidth = mDefaultStateBitmap.getIntrinsicWidth();
mHeight = mDefaultStateBitmap.getIntrinsicHeight(); mHeight = mDefaultStateBitmap.getIntrinsicHeight();
} }
/** /**
* Gets this InputOverlayDrawableButton's button ID. * Updates button status based on the motion event.
* *
* @return this InputOverlayDrawableButton's button ID. * @return true if value was changed
*/ */
public int getId() { public boolean updateStatus(MotionEvent event) {
return mButtonType;
}
public int getTrackId() {
return mTrackId;
}
public void setTrackId(int trackId) {
mTrackId = trackId;
}
public boolean onConfigureTouch(MotionEvent event) {
int pointerIndex = event.getActionIndex(); int pointerIndex = event.getActionIndex();
int fingerPositionX = (int) event.getX(pointerIndex); int xPosition = (int) event.getX(pointerIndex);
int fingerPositionY = (int) event.getY(pointerIndex); int yPosition = (int) event.getY(pointerIndex);
switch (event.getAction()) { int pointerId = event.getPointerId(pointerIndex);
case MotionEvent.ACTION_DOWN: int motion_event = event.getAction() & MotionEvent.ACTION_MASK;
mPreviousTouchX = fingerPositionX; boolean isActionDown = motion_event == MotionEvent.ACTION_DOWN || motion_event == MotionEvent.ACTION_POINTER_DOWN;
mPreviousTouchY = fingerPositionY; boolean isActionUp = motion_event == MotionEvent.ACTION_UP || motion_event == MotionEvent.ACTION_POINTER_UP;
break;
case MotionEvent.ACTION_MOVE:
mControlPositionX += fingerPositionX - mPreviousTouchX;
mControlPositionY += fingerPositionY - mPreviousTouchY;
setBounds(mControlPositionX, mControlPositionY, getWidth() + mControlPositionX,
getHeight() + mControlPositionY);
mPreviousTouchX = fingerPositionX;
mPreviousTouchY = fingerPositionY;
break;
if (isActionDown) {
if (!getBounds().contains(xPosition, yPosition)) {
return false;
} }
mPressedState = true;
mTrackId = pointerId;
return true; return true;
} }
if (isActionUp) {
if (mTrackId != pointerId) {
return false;
}
mPressedState = false;
mTrackId = -1;
return true;
}
return false;
}
public void setPosition(int x, int y) { public void setPosition(int x, int y) {
mControlPositionX = x; mButtonPositionX = x;
mControlPositionY = y; mButtonPositionY = y;
} }
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
@ -104,7 +107,24 @@ public final class InputOverlayDrawableButton {
mPressedStateBitmap.setBounds(left, top, right, bottom); mPressedStateBitmap.setBounds(left, top, right, bottom);
} }
public Rect getBounds() { /**
* Gets this InputOverlayDrawableButton's button ID.
*
* @return this InputOverlayDrawableButton's button ID.
*/
public int getId() {
return mButtonId;
}
public int getTrackId() {
return mTrackId;
}
public int getStatus() {
return mPressedState ? ButtonState.PRESSED : ButtonState.RELEASED;
}
private Rect getBounds() {
return mDefaultStateBitmap.getBounds(); return mDefaultStateBitmap.getBounds();
} }
@ -115,8 +135,4 @@ public final class InputOverlayDrawableButton {
public int getHeight() { public int getHeight() {
return mHeight; return mHeight;
} }
public void setPressedState(boolean isPressed) {
mPressedState = isPressed;
}
} }