From 1ab269775ddd3860976323c7bf55548adc75e133 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Mon, 13 Feb 2023 13:11:03 -0600 Subject: [PATCH] android: Clean button overlay --- .../yuzu/yuzu_emu/overlay/InputOverlay.java | 154 +----------------- .../overlay/InputOverlayDrawableButton.java | 106 +++++++----- 2 files changed, 65 insertions(+), 195 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java index 686c656a89..96868f9657 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java @@ -369,29 +369,10 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { } 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 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; + if (!button.updateStatus(event)) { + continue; } + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), button.getStatus()); } for (InputOverlayDrawableDpad dpad : overlayDpads) { @@ -516,137 +497,10 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { } public boolean onTouchWhileEditing(MotionEvent event) { - int pointerIndex = event.getActionIndex(); - 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; - } - 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; - } - } - + // TODO: Reimplement this 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) { if (mPreferences.getBoolean("buttonToggle0", true)) { overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.button_a, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableButton.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableButton.java index fe523c6c4d..15da42f3d6 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableButton.java +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableButton.java @@ -13,16 +13,22 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.view.MotionEvent; +import org.yuzu.yuzu_emu.NativeLibrary.ButtonState; + + /** * Custom {@link BitmapDrawable} that is capable * of storing it's own ID. */ public final class InputOverlayDrawableButton { - // The ID identifying what type of button this Drawable represents. - private int mButtonType; + // The ID value what type of button this Drawable represents. + private int mButtonId; + + // The ID value what motion event is tracking 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 mHeight; private BitmapDrawable mDefaultStateBitmap; @@ -35,60 +41,57 @@ public final class InputOverlayDrawableButton { * @param res {@link Resources} instance. * @param defaultStateBitmap {@link Bitmap} to use with the default 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, - Bitmap pressedStateBitmap, int buttonType) { + Bitmap pressedStateBitmap, int buttonId) { mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap); mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap); - mButtonType = buttonType; + mButtonId = buttonId; + mTrackId = -1; mWidth = mDefaultStateBitmap.getIntrinsicWidth(); 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() { - return mButtonType; - } - - public int getTrackId() { - return mTrackId; - } - - public void setTrackId(int trackId) { - mTrackId = trackId; - } - - public boolean onConfigureTouch(MotionEvent event) { + public boolean updateStatus(MotionEvent event) { int pointerIndex = event.getActionIndex(); - int fingerPositionX = (int) event.getX(pointerIndex); - int fingerPositionY = (int) event.getY(pointerIndex); - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mPreviousTouchX = fingerPositionX; - mPreviousTouchY = fingerPositionY; - break; - case MotionEvent.ACTION_MOVE: - mControlPositionX += fingerPositionX - mPreviousTouchX; - mControlPositionY += fingerPositionY - mPreviousTouchY; - setBounds(mControlPositionX, mControlPositionY, getWidth() + mControlPositionX, - getHeight() + mControlPositionY); - mPreviousTouchX = fingerPositionX; - mPreviousTouchY = fingerPositionY; - break; + int xPosition = (int) event.getX(pointerIndex); + int yPosition = (int) event.getY(pointerIndex); + int pointerId = event.getPointerId(pointerIndex); + int motion_event = event.getAction() & MotionEvent.ACTION_MASK; + boolean isActionDown = motion_event == MotionEvent.ACTION_DOWN || motion_event == MotionEvent.ACTION_POINTER_DOWN; + boolean isActionUp = motion_event == MotionEvent.ACTION_UP || motion_event == MotionEvent.ACTION_POINTER_UP; + 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) { - mControlPositionX = x; - mControlPositionY = y; + mButtonPositionX = x; + mButtonPositionY = y; } public void draw(Canvas canvas) { @@ -104,7 +107,24 @@ public final class InputOverlayDrawableButton { 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(); } @@ -115,8 +135,4 @@ public final class InputOverlayDrawableButton { public int getHeight() { return mHeight; } - - public void setPressedState(boolean isPressed) { - mPressedState = isPressed; - } }