diff options
| author | 2023-02-13 13:11:03 -0600 | |
|---|---|---|
| committer | 2023-06-03 00:05:30 -0700 | |
| commit | 1ab269775ddd3860976323c7bf55548adc75e133 (patch) | |
| tree | e2d49ed8fbd73e45f385680fc2530c2d177af6ba | |
| parent | android: Add all buttons to screen controller (diff) | |
| download | yuzu-1ab269775ddd3860976323c7bf55548adc75e133.tar.gz yuzu-1ab269775ddd3860976323c7bf55548adc75e133.tar.xz yuzu-1ab269775ddd3860976323c7bf55548adc75e133.zip | |
android: Clean button overlay
| -rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java | 154 | ||||
| -rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/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 686c656a8..96868f965 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 { | |||
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | for (InputOverlayDrawableButton button : overlayButtons) { | 371 | for (InputOverlayDrawableButton button : overlayButtons) { |
| 372 | // Determine the button state to apply based on the MotionEvent action flag. | 372 | if (!button.updateStatus(event)) { |
| 373 | switch (event.getAction() & MotionEvent.ACTION_MASK) { | 373 | continue; |
| 374 | case MotionEvent.ACTION_DOWN: | ||
| 375 | case MotionEvent.ACTION_POINTER_DOWN: | ||
| 376 | // If a pointer enters the bounds of a button, press that button. | ||
| 377 | if (button.getBounds() | ||
| 378 | .contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex))) { | ||
| 379 | button.setPressedState(true); | ||
| 380 | button.setTrackId(event.getPointerId(pointerIndex)); | ||
| 381 | NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), | ||
| 382 | ButtonState.PRESSED); | ||
| 383 | } | ||
| 384 | break; | ||
| 385 | case MotionEvent.ACTION_UP: | ||
| 386 | case MotionEvent.ACTION_POINTER_UP: | ||
| 387 | // If a pointer ends, release the button it was pressing. | ||
| 388 | if (button.getTrackId() == event.getPointerId(pointerIndex)) { | ||
| 389 | button.setPressedState(false); | ||
| 390 | NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), | ||
| 391 | ButtonState.RELEASED); | ||
| 392 | } | ||
| 393 | break; | ||
| 394 | } | 374 | } |
| 375 | NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(), button.getStatus()); | ||
| 395 | } | 376 | } |
| 396 | 377 | ||
| 397 | for (InputOverlayDrawableDpad dpad : overlayDpads) { | 378 | for (InputOverlayDrawableDpad dpad : overlayDpads) { |
| @@ -516,137 +497,10 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { | |||
| 516 | } | 497 | } |
| 517 | 498 | ||
| 518 | public boolean onTouchWhileEditing(MotionEvent event) { | 499 | public boolean onTouchWhileEditing(MotionEvent event) { |
| 519 | int pointerIndex = event.getActionIndex(); | 500 | // TODO: Reimplement this |
| 520 | int fingerPositionX = (int) event.getX(pointerIndex); | ||
| 521 | int fingerPositionY = (int) event.getY(pointerIndex); | ||
| 522 | |||
| 523 | String orientation = | ||
| 524 | getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? | ||
| 525 | "-Portrait" : ""; | ||
| 526 | |||
| 527 | // Maybe combine Button and Joystick as subclasses of the same parent? | ||
| 528 | // Or maybe create an interface like IMoveableHUDControl? | ||
| 529 | |||
| 530 | for (InputOverlayDrawableButton button : overlayButtons) { | ||
| 531 | // Determine the button state to apply based on the MotionEvent action flag. | ||
| 532 | switch (event.getAction() & MotionEvent.ACTION_MASK) { | ||
| 533 | case MotionEvent.ACTION_DOWN: | ||
| 534 | case MotionEvent.ACTION_POINTER_DOWN: | ||
| 535 | // If no button is being moved now, remember the currently touched button to move. | ||
| 536 | if (mButtonBeingConfigured == null && | ||
| 537 | button.getBounds().contains(fingerPositionX, fingerPositionY)) { | ||
| 538 | mButtonBeingConfigured = button; | ||
| 539 | mButtonBeingConfigured.onConfigureTouch(event); | ||
| 540 | } | ||
| 541 | break; | ||
| 542 | case MotionEvent.ACTION_MOVE: | ||
| 543 | if (mButtonBeingConfigured != null) { | ||
| 544 | mButtonBeingConfigured.onConfigureTouch(event); | ||
| 545 | invalidate(); | ||
| 546 | return true; | ||
| 547 | } | ||
| 548 | break; | ||
| 549 | |||
| 550 | case MotionEvent.ACTION_UP: | ||
| 551 | case MotionEvent.ACTION_POINTER_UP: | ||
| 552 | if (mButtonBeingConfigured == button) { | ||
| 553 | // Persist button position by saving new place. | ||
| 554 | saveControlPosition(mButtonBeingConfigured.getId(), | ||
| 555 | mButtonBeingConfigured.getBounds().left, | ||
| 556 | mButtonBeingConfigured.getBounds().top, orientation); | ||
| 557 | mButtonBeingConfigured = null; | ||
| 558 | } | ||
| 559 | break; | ||
| 560 | } | ||
| 561 | } | ||
| 562 | |||
| 563 | for (InputOverlayDrawableDpad dpad : overlayDpads) { | ||
| 564 | // Determine the button state to apply based on the MotionEvent action flag. | ||
| 565 | switch (event.getAction() & MotionEvent.ACTION_MASK) { | ||
| 566 | case MotionEvent.ACTION_DOWN: | ||
| 567 | case MotionEvent.ACTION_POINTER_DOWN: | ||
| 568 | // If no button is being moved now, remember the currently touched button to move. | ||
| 569 | if (mButtonBeingConfigured == null && | ||
| 570 | dpad.getBounds().contains(fingerPositionX, fingerPositionY)) { | ||
| 571 | mDpadBeingConfigured = dpad; | ||
| 572 | mDpadBeingConfigured.onConfigureTouch(event); | ||
| 573 | } | ||
| 574 | break; | ||
| 575 | case MotionEvent.ACTION_MOVE: | ||
| 576 | if (mDpadBeingConfigured != null) { | ||
| 577 | mDpadBeingConfigured.onConfigureTouch(event); | ||
| 578 | invalidate(); | ||
| 579 | return true; | ||
| 580 | } | ||
| 581 | break; | ||
| 582 | |||
| 583 | case MotionEvent.ACTION_UP: | ||
| 584 | case MotionEvent.ACTION_POINTER_UP: | ||
| 585 | if (mDpadBeingConfigured == dpad) { | ||
| 586 | // Persist button position by saving new place. | ||
| 587 | saveControlPosition(mDpadBeingConfigured.getId(0), | ||
| 588 | mDpadBeingConfigured.getBounds().left, mDpadBeingConfigured.getBounds().top, | ||
| 589 | orientation); | ||
| 590 | mDpadBeingConfigured = null; | ||
| 591 | } | ||
| 592 | break; | ||
| 593 | } | ||
| 594 | } | ||
| 595 | |||
| 596 | for (InputOverlayDrawableJoystick joystick : overlayJoysticks) { | ||
| 597 | switch (event.getAction()) { | ||
| 598 | case MotionEvent.ACTION_DOWN: | ||
| 599 | case MotionEvent.ACTION_POINTER_DOWN: | ||
| 600 | if (mJoystickBeingConfigured == null && | ||
| 601 | joystick.getBounds().contains(fingerPositionX, fingerPositionY)) { | ||
| 602 | mJoystickBeingConfigured = joystick; | ||
| 603 | mJoystickBeingConfigured.onConfigureTouch(event); | ||
| 604 | } | ||
| 605 | break; | ||
| 606 | case MotionEvent.ACTION_MOVE: | ||
| 607 | if (mJoystickBeingConfigured != null) { | ||
| 608 | mJoystickBeingConfigured.onConfigureTouch(event); | ||
| 609 | invalidate(); | ||
| 610 | } | ||
| 611 | break; | ||
| 612 | case MotionEvent.ACTION_UP: | ||
| 613 | case MotionEvent.ACTION_POINTER_UP: | ||
| 614 | if (mJoystickBeingConfigured != null) { | ||
| 615 | saveControlPosition(mJoystickBeingConfigured.getId(), | ||
| 616 | mJoystickBeingConfigured.getBounds().left, | ||
| 617 | mJoystickBeingConfigured.getBounds().top, orientation); | ||
| 618 | mJoystickBeingConfigured = null; | ||
| 619 | } | ||
| 620 | break; | ||
| 621 | } | ||
| 622 | } | ||
| 623 | |||
| 624 | return true; | 501 | return true; |
| 625 | } | 502 | } |
| 626 | 503 | ||
| 627 | private void setDpadState(InputOverlayDrawableDpad dpad, boolean up, boolean down, boolean left, | ||
| 628 | boolean right) { | ||
| 629 | if (up) { | ||
| 630 | if (left) | ||
| 631 | dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP_LEFT); | ||
| 632 | else if (right) | ||
| 633 | dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP_RIGHT); | ||
| 634 | else | ||
| 635 | dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_UP); | ||
| 636 | } else if (down) { | ||
| 637 | if (left) | ||
| 638 | dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN_LEFT); | ||
| 639 | else if (right) | ||
| 640 | dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN_RIGHT); | ||
| 641 | else | ||
| 642 | dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_DOWN); | ||
| 643 | } else if (left) { | ||
| 644 | dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_LEFT); | ||
| 645 | } else if (right) { | ||
| 646 | dpad.setState(InputOverlayDrawableDpad.STATE_PRESSED_RIGHT); | ||
| 647 | } | ||
| 648 | } | ||
| 649 | |||
| 650 | private void addOverlayControls(String orientation) { | 504 | private void addOverlayControls(String orientation) { |
| 651 | if (mPreferences.getBoolean("buttonToggle0", true)) { | 505 | if (mPreferences.getBoolean("buttonToggle0", true)) { |
| 652 | overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.button_a, | 506 | 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 fe523c6c4..15da42f3d 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; | |||
| 13 | import android.graphics.drawable.BitmapDrawable; | 13 | import android.graphics.drawable.BitmapDrawable; |
| 14 | import android.view.MotionEvent; | 14 | import android.view.MotionEvent; |
| 15 | 15 | ||
| 16 | import org.yuzu.yuzu_emu.NativeLibrary.ButtonState; | ||
| 17 | |||
| 18 | |||
| 16 | /** | 19 | /** |
| 17 | * Custom {@link BitmapDrawable} that is capable | 20 | * Custom {@link BitmapDrawable} that is capable |
| 18 | * of storing it's own ID. | 21 | * of storing it's own ID. |
| 19 | */ | 22 | */ |
| 20 | public final class InputOverlayDrawableButton { | 23 | public final class InputOverlayDrawableButton { |
| 21 | // The ID identifying what type of button this Drawable represents. | 24 | // The ID value what type of button this Drawable represents. |
| 22 | private int mButtonType; | 25 | private int mButtonId; |
| 26 | |||
| 27 | // The ID value what motion event is tracking | ||
| 23 | private int mTrackId; | 28 | private int mTrackId; |
| 24 | private int mPreviousTouchX, mPreviousTouchY; | 29 | |
| 25 | private int mControlPositionX, mControlPositionY; | 30 | // The drawable position on the screen |
| 31 | private int mButtonPositionX, mButtonPositionY; | ||
| 26 | private int mWidth; | 32 | private int mWidth; |
| 27 | private int mHeight; | 33 | private int mHeight; |
| 28 | private BitmapDrawable mDefaultStateBitmap; | 34 | private BitmapDrawable mDefaultStateBitmap; |
| @@ -35,60 +41,57 @@ public final class InputOverlayDrawableButton { | |||
| 35 | * @param res {@link Resources} instance. | 41 | * @param res {@link Resources} instance. |
| 36 | * @param defaultStateBitmap {@link Bitmap} to use with the default state Drawable. | 42 | * @param defaultStateBitmap {@link Bitmap} to use with the default state Drawable. |
| 37 | * @param pressedStateBitmap {@link Bitmap} to use with the pressed state Drawable. | 43 | * @param pressedStateBitmap {@link Bitmap} to use with the pressed state Drawable. |
| 38 | * @param buttonType Identifier for this type of button. | 44 | * @param buttonId Identifier for this type of button. |
| 39 | */ | 45 | */ |
| 40 | public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap, | 46 | public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap, |
| 41 | Bitmap pressedStateBitmap, int buttonType) { | 47 | Bitmap pressedStateBitmap, int buttonId) { |
| 42 | mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap); | 48 | mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap); |
| 43 | mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap); | 49 | mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap); |
| 44 | mButtonType = buttonType; | 50 | mButtonId = buttonId; |
| 51 | mTrackId = -1; | ||
| 45 | 52 | ||
| 46 | mWidth = mDefaultStateBitmap.getIntrinsicWidth(); | 53 | mWidth = mDefaultStateBitmap.getIntrinsicWidth(); |
| 47 | mHeight = mDefaultStateBitmap.getIntrinsicHeight(); | 54 | mHeight = mDefaultStateBitmap.getIntrinsicHeight(); |
| 48 | } | 55 | } |
| 49 | 56 | ||
| 50 | /** | 57 | /** |
| 51 | * Gets this InputOverlayDrawableButton's button ID. | 58 | * Updates button status based on the motion event. |
| 52 | * | 59 | * |
| 53 | * @return this InputOverlayDrawableButton's button ID. | 60 | * @return true if value was changed |
| 54 | */ | 61 | */ |
| 55 | public int getId() { | 62 | public boolean updateStatus(MotionEvent event) { |
| 56 | return mButtonType; | ||
| 57 | } | ||
| 58 | |||
| 59 | public int getTrackId() { | ||
| 60 | return mTrackId; | ||
| 61 | } | ||
| 62 | |||
| 63 | public void setTrackId(int trackId) { | ||
| 64 | mTrackId = trackId; | ||
| 65 | } | ||
| 66 | |||
| 67 | public boolean onConfigureTouch(MotionEvent event) { | ||
| 68 | int pointerIndex = event.getActionIndex(); | 63 | int pointerIndex = event.getActionIndex(); |
| 69 | int fingerPositionX = (int) event.getX(pointerIndex); | 64 | int xPosition = (int) event.getX(pointerIndex); |
| 70 | int fingerPositionY = (int) event.getY(pointerIndex); | 65 | int yPosition = (int) event.getY(pointerIndex); |
| 71 | switch (event.getAction()) { | 66 | int pointerId = event.getPointerId(pointerIndex); |
| 72 | case MotionEvent.ACTION_DOWN: | 67 | int motion_event = event.getAction() & MotionEvent.ACTION_MASK; |
| 73 | mPreviousTouchX = fingerPositionX; | 68 | boolean isActionDown = motion_event == MotionEvent.ACTION_DOWN || motion_event == MotionEvent.ACTION_POINTER_DOWN; |
| 74 | mPreviousTouchY = fingerPositionY; | 69 | boolean isActionUp = motion_event == MotionEvent.ACTION_UP || motion_event == MotionEvent.ACTION_POINTER_UP; |
| 75 | break; | 70 | |
| 76 | case MotionEvent.ACTION_MOVE: | 71 | if (isActionDown) { |
| 77 | mControlPositionX += fingerPositionX - mPreviousTouchX; | 72 | if (!getBounds().contains(xPosition, yPosition)) { |
| 78 | mControlPositionY += fingerPositionY - mPreviousTouchY; | 73 | return false; |
| 79 | setBounds(mControlPositionX, mControlPositionY, getWidth() + mControlPositionX, | 74 | } |
| 80 | getHeight() + mControlPositionY); | 75 | mPressedState = true; |
| 81 | mPreviousTouchX = fingerPositionX; | 76 | mTrackId = pointerId; |
| 82 | mPreviousTouchY = fingerPositionY; | 77 | return true; |
| 83 | break; | 78 | } |
| 84 | 79 | ||
| 80 | if (isActionUp) { | ||
| 81 | if (mTrackId != pointerId) { | ||
| 82 | return false; | ||
| 83 | } | ||
| 84 | mPressedState = false; | ||
| 85 | mTrackId = -1; | ||
| 86 | return true; | ||
| 85 | } | 87 | } |
| 86 | return true; | 88 | |
| 89 | return false; | ||
| 87 | } | 90 | } |
| 88 | 91 | ||
| 89 | public void setPosition(int x, int y) { | 92 | public void setPosition(int x, int y) { |
| 90 | mControlPositionX = x; | 93 | mButtonPositionX = x; |
| 91 | mControlPositionY = y; | 94 | mButtonPositionY = y; |
| 92 | } | 95 | } |
| 93 | 96 | ||
| 94 | public void draw(Canvas canvas) { | 97 | public void draw(Canvas canvas) { |
| @@ -104,7 +107,24 @@ public final class InputOverlayDrawableButton { | |||
| 104 | mPressedStateBitmap.setBounds(left, top, right, bottom); | 107 | mPressedStateBitmap.setBounds(left, top, right, bottom); |
| 105 | } | 108 | } |
| 106 | 109 | ||
| 107 | public Rect getBounds() { | 110 | /** |
| 111 | * Gets this InputOverlayDrawableButton's button ID. | ||
| 112 | * | ||
| 113 | * @return this InputOverlayDrawableButton's button ID. | ||
| 114 | */ | ||
| 115 | public int getId() { | ||
| 116 | return mButtonId; | ||
| 117 | } | ||
| 118 | |||
| 119 | public int getTrackId() { | ||
| 120 | return mTrackId; | ||
| 121 | } | ||
| 122 | |||
| 123 | public int getStatus() { | ||
| 124 | return mPressedState ? ButtonState.PRESSED : ButtonState.RELEASED; | ||
| 125 | } | ||
| 126 | |||
| 127 | private Rect getBounds() { | ||
| 108 | return mDefaultStateBitmap.getBounds(); | 128 | return mDefaultStateBitmap.getBounds(); |
| 109 | } | 129 | } |
| 110 | 130 | ||
| @@ -115,8 +135,4 @@ public final class InputOverlayDrawableButton { | |||
| 115 | public int getHeight() { | 135 | public int getHeight() { |
| 116 | return mHeight; | 136 | return mHeight; |
| 117 | } | 137 | } |
| 118 | |||
| 119 | public void setPressedState(boolean isPressed) { | ||
| 120 | mPressedState = isPressed; | ||
| 121 | } | ||
| 122 | } | 138 | } |