diff options
| author | 2023-03-11 00:34:09 -0500 | |
|---|---|---|
| committer | 2023-06-03 00:05:39 -0700 | |
| commit | 42b3e72e9608584d873b78defc63bc61218efd5b (patch) | |
| tree | 218d6115fc1e814676b5761520d75300cc290a3a /src/android/app | |
| parent | android: Convert MainActivity to Kotlin (diff) | |
| download | yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.tar.gz yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.tar.xz yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.zip | |
android: Convert InputOverlayDrawableJoystick to Kotlin
Diffstat (limited to 'src/android/app')
2 files changed, 205 insertions, 243 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java deleted file mode 100644 index f7919e483..000000000 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java +++ /dev/null | |||
| @@ -1,243 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * Copyright 2013 Dolphin Emulator Project | ||
| 3 | * Licensed under GPLv2+ | ||
| 4 | * Refer to the license.txt file included. | ||
| 5 | */ | ||
| 6 | |||
| 7 | package org.yuzu.yuzu_emu.overlay; | ||
| 8 | |||
| 9 | import android.content.res.Resources; | ||
| 10 | import android.graphics.Bitmap; | ||
| 11 | import android.graphics.Canvas; | ||
| 12 | import android.graphics.Rect; | ||
| 13 | import android.graphics.drawable.BitmapDrawable; | ||
| 14 | import android.view.MotionEvent; | ||
| 15 | |||
| 16 | import org.yuzu.yuzu_emu.NativeLibrary; | ||
| 17 | import org.yuzu.yuzu_emu.NativeLibrary.ButtonType; | ||
| 18 | import org.yuzu.yuzu_emu.utils.EmulationMenuSettings; | ||
| 19 | |||
| 20 | /** | ||
| 21 | * Custom {@link BitmapDrawable} that is capable | ||
| 22 | * of storing it's own ID. | ||
| 23 | */ | ||
| 24 | public final class InputOverlayDrawableJoystick { | ||
| 25 | // The ID value what type of joystick this Drawable represents. | ||
| 26 | private int mJoystickId; | ||
| 27 | // The ID value what type of button this Drawable represents. | ||
| 28 | private int mButtonId; | ||
| 29 | // The ID value what motion event is tracking | ||
| 30 | private int mTrackId = -1; | ||
| 31 | private float mXAxis; | ||
| 32 | private float mYAxis; | ||
| 33 | private int mControlPositionX, mControlPositionY; | ||
| 34 | private int mWidth; | ||
| 35 | private int mHeight; | ||
| 36 | private Rect mVirtBounds; | ||
| 37 | private Rect mOrigBounds; | ||
| 38 | private BitmapDrawable mOuterBitmap; | ||
| 39 | private BitmapDrawable mDefaultStateInnerBitmap; | ||
| 40 | private BitmapDrawable mPressedStateInnerBitmap; | ||
| 41 | private BitmapDrawable mBoundsBoxBitmap; | ||
| 42 | private boolean mPressedState = false; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Constructor | ||
| 46 | * | ||
| 47 | * @param res {@link Resources} instance. | ||
| 48 | * @param bitmapOuter {@link Bitmap} which represents the outer non-movable part of the joystick. | ||
| 49 | * @param bitmapInnerDefault {@link Bitmap} which represents the default inner movable part of the joystick. | ||
| 50 | * @param bitmapInnerPressed {@link Bitmap} which represents the pressed inner movable part of the joystick. | ||
| 51 | * @param rectOuter {@link Rect} which represents the outer joystick bounds. | ||
| 52 | * @param rectInner {@link Rect} which represents the inner joystick bounds. | ||
| 53 | * @param joystick Identifier for which joystick this is. | ||
| 54 | */ | ||
| 55 | public InputOverlayDrawableJoystick(Resources res, Bitmap bitmapOuter, | ||
| 56 | Bitmap bitmapInnerDefault, Bitmap bitmapInnerPressed, | ||
| 57 | Rect rectOuter, Rect rectInner, int joystick, int button) { | ||
| 58 | mJoystickId = joystick; | ||
| 59 | mButtonId = button; | ||
| 60 | |||
| 61 | mOuterBitmap = new BitmapDrawable(res, bitmapOuter); | ||
| 62 | mDefaultStateInnerBitmap = new BitmapDrawable(res, bitmapInnerDefault); | ||
| 63 | mPressedStateInnerBitmap = new BitmapDrawable(res, bitmapInnerPressed); | ||
| 64 | mBoundsBoxBitmap = new BitmapDrawable(res, bitmapOuter); | ||
| 65 | mWidth = bitmapOuter.getWidth(); | ||
| 66 | mHeight = bitmapOuter.getHeight(); | ||
| 67 | |||
| 68 | setBounds(rectOuter); | ||
| 69 | mDefaultStateInnerBitmap.setBounds(rectInner); | ||
| 70 | mPressedStateInnerBitmap.setBounds(rectInner); | ||
| 71 | mVirtBounds = getBounds(); | ||
| 72 | mOrigBounds = mOuterBitmap.copyBounds(); | ||
| 73 | mBoundsBoxBitmap.setAlpha(0); | ||
| 74 | mBoundsBoxBitmap.setBounds(getVirtBounds()); | ||
| 75 | SetInnerBounds(); | ||
| 76 | } | ||
| 77 | |||
| 78 | public void draw(Canvas canvas) { | ||
| 79 | mOuterBitmap.draw(canvas); | ||
| 80 | getCurrentStateBitmapDrawable().draw(canvas); | ||
| 81 | mBoundsBoxBitmap.draw(canvas); | ||
| 82 | } | ||
| 83 | |||
| 84 | public boolean updateStatus(MotionEvent event) { | ||
| 85 | int pointerIndex = event.getActionIndex(); | ||
| 86 | int xPosition = (int) event.getX(pointerIndex); | ||
| 87 | int yPosition = (int) event.getY(pointerIndex); | ||
| 88 | int pointerId = event.getPointerId(pointerIndex); | ||
| 89 | int motion_event = event.getAction() & MotionEvent.ACTION_MASK; | ||
| 90 | boolean isActionDown = motion_event == MotionEvent.ACTION_DOWN || motion_event == MotionEvent.ACTION_POINTER_DOWN; | ||
| 91 | boolean isActionUp = motion_event == MotionEvent.ACTION_UP || motion_event == MotionEvent.ACTION_POINTER_UP; | ||
| 92 | |||
| 93 | if (isActionDown) { | ||
| 94 | if (!getBounds().contains(xPosition, yPosition)) { | ||
| 95 | return false; | ||
| 96 | } | ||
| 97 | mPressedState = true; | ||
| 98 | mOuterBitmap.setAlpha(0); | ||
| 99 | mBoundsBoxBitmap.setAlpha(255); | ||
| 100 | if (EmulationMenuSettings.getJoystickRelCenter()) { | ||
| 101 | getVirtBounds().offset(xPosition - getVirtBounds().centerX(), | ||
| 102 | yPosition - getVirtBounds().centerY()); | ||
| 103 | } | ||
| 104 | mBoundsBoxBitmap.setBounds(getVirtBounds()); | ||
| 105 | mTrackId = pointerId; | ||
| 106 | } | ||
| 107 | |||
| 108 | if (isActionUp) { | ||
| 109 | if (mTrackId != pointerId) { | ||
| 110 | return false; | ||
| 111 | } | ||
| 112 | mPressedState = false; | ||
| 113 | mXAxis = 0.0f; | ||
| 114 | mYAxis = 0.0f; | ||
| 115 | mOuterBitmap.setAlpha(255); | ||
| 116 | mBoundsBoxBitmap.setAlpha(0); | ||
| 117 | setVirtBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right, | ||
| 118 | mOrigBounds.bottom)); | ||
| 119 | setBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right, | ||
| 120 | mOrigBounds.bottom)); | ||
| 121 | SetInnerBounds(); | ||
| 122 | mTrackId = -1; | ||
| 123 | return true; | ||
| 124 | } | ||
| 125 | |||
| 126 | if (mTrackId == -1) | ||
| 127 | return false; | ||
| 128 | |||
| 129 | for (int i = 0; i < event.getPointerCount(); i++) { | ||
| 130 | if (mTrackId != event.getPointerId(i)) { | ||
| 131 | continue; | ||
| 132 | } | ||
| 133 | float touchX = event.getX(i); | ||
| 134 | float touchY = event.getY(i); | ||
| 135 | float maxY = getVirtBounds().bottom; | ||
| 136 | float maxX = getVirtBounds().right; | ||
| 137 | touchX -= getVirtBounds().centerX(); | ||
| 138 | maxX -= getVirtBounds().centerX(); | ||
| 139 | touchY -= getVirtBounds().centerY(); | ||
| 140 | maxY -= getVirtBounds().centerY(); | ||
| 141 | final float AxisX = touchX / maxX; | ||
| 142 | final float AxisY = touchY / maxY; | ||
| 143 | final float oldXAxis = mXAxis; | ||
| 144 | final float oldYAxis = mYAxis; | ||
| 145 | |||
| 146 | // Clamp the circle pad input to a circle | ||
| 147 | final float angle = (float) Math.atan2(AxisY, AxisX); | ||
| 148 | float radius = (float) Math.sqrt(AxisX * AxisX + AxisY * AxisY); | ||
| 149 | if (radius > 1.0f) { | ||
| 150 | radius = 1.0f; | ||
| 151 | } | ||
| 152 | mXAxis = ((float) Math.cos(angle) * radius); | ||
| 153 | mYAxis = ((float) Math.sin(angle) * radius); | ||
| 154 | SetInnerBounds(); | ||
| 155 | return oldXAxis != mXAxis && oldYAxis != mYAxis; | ||
| 156 | } | ||
| 157 | |||
| 158 | return false; | ||
| 159 | } | ||
| 160 | |||
| 161 | private void SetInnerBounds() { | ||
| 162 | int X = getVirtBounds().centerX() + (int) ((mXAxis) * (getVirtBounds().width() / 2)); | ||
| 163 | int Y = getVirtBounds().centerY() + (int) ((mYAxis) * (getVirtBounds().height() / 2)); | ||
| 164 | |||
| 165 | if (X > getVirtBounds().centerX() + (getVirtBounds().width() / 2)) | ||
| 166 | X = getVirtBounds().centerX() + (getVirtBounds().width() / 2); | ||
| 167 | if (X < getVirtBounds().centerX() - (getVirtBounds().width() / 2)) | ||
| 168 | X = getVirtBounds().centerX() - (getVirtBounds().width() / 2); | ||
| 169 | if (Y > getVirtBounds().centerY() + (getVirtBounds().height() / 2)) | ||
| 170 | Y = getVirtBounds().centerY() + (getVirtBounds().height() / 2); | ||
| 171 | if (Y < getVirtBounds().centerY() - (getVirtBounds().height() / 2)) | ||
| 172 | Y = getVirtBounds().centerY() - (getVirtBounds().height() / 2); | ||
| 173 | |||
| 174 | int width = mPressedStateInnerBitmap.getBounds().width() / 2; | ||
| 175 | int height = mPressedStateInnerBitmap.getBounds().height() / 2; | ||
| 176 | mDefaultStateInnerBitmap.setBounds(X - width, Y - height, X + width, Y + height); | ||
| 177 | mPressedStateInnerBitmap.setBounds(mDefaultStateInnerBitmap.getBounds()); | ||
| 178 | } | ||
| 179 | |||
| 180 | public void setPosition(int x, int y) { | ||
| 181 | mControlPositionX = x; | ||
| 182 | mControlPositionY = y; | ||
| 183 | } | ||
| 184 | |||
| 185 | private BitmapDrawable getCurrentStateBitmapDrawable() { | ||
| 186 | return mPressedState ? mPressedStateInnerBitmap : mDefaultStateInnerBitmap; | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * Gets this InputOverlayDrawableJoystick's button ID. | ||
| 191 | * | ||
| 192 | * @return this InputOverlayDrawableJoystick's button ID. | ||
| 193 | */ | ||
| 194 | public int getJoystickId() { | ||
| 195 | return mJoystickId; | ||
| 196 | } | ||
| 197 | |||
| 198 | public float getXAxis() { | ||
| 199 | return mXAxis; | ||
| 200 | } | ||
| 201 | |||
| 202 | public float getYAxis() { | ||
| 203 | // Nintendo joysticks have y axis inverted | ||
| 204 | return -mYAxis; | ||
| 205 | } | ||
| 206 | |||
| 207 | public int getButtonId() { | ||
| 208 | return mButtonId; | ||
| 209 | } | ||
| 210 | |||
| 211 | public int getTrackId() { | ||
| 212 | return mTrackId; | ||
| 213 | } | ||
| 214 | |||
| 215 | public int getButtonStatus() { | ||
| 216 | // TODO: Add button support | ||
| 217 | return NativeLibrary.ButtonState.RELEASED; | ||
| 218 | } | ||
| 219 | |||
| 220 | public Rect getBounds() { | ||
| 221 | return mOuterBitmap.getBounds(); | ||
| 222 | } | ||
| 223 | |||
| 224 | public void setBounds(Rect bounds) { | ||
| 225 | mOuterBitmap.setBounds(bounds); | ||
| 226 | } | ||
| 227 | |||
| 228 | private Rect getVirtBounds() { | ||
| 229 | return mVirtBounds; | ||
| 230 | } | ||
| 231 | |||
| 232 | private void setVirtBounds(Rect bounds) { | ||
| 233 | mVirtBounds = bounds; | ||
| 234 | } | ||
| 235 | |||
| 236 | public int getWidth() { | ||
| 237 | return mWidth; | ||
| 238 | } | ||
| 239 | |||
| 240 | public int getHeight() { | ||
| 241 | return mHeight; | ||
| 242 | } | ||
| 243 | } | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt new file mode 100644 index 000000000..84a3ea40b --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt | |||
| @@ -0,0 +1,205 @@ | |||
| 1 | package org.yuzu.yuzu_emu.overlay | ||
| 2 | |||
| 3 | import android.content.res.Resources | ||
| 4 | import android.graphics.Bitmap | ||
| 5 | import android.graphics.Canvas | ||
| 6 | import android.graphics.Rect | ||
| 7 | import android.graphics.drawable.BitmapDrawable | ||
| 8 | import android.view.MotionEvent | ||
| 9 | import org.yuzu.yuzu_emu.NativeLibrary | ||
| 10 | import org.yuzu.yuzu_emu.utils.EmulationMenuSettings | ||
| 11 | import kotlin.math.atan2 | ||
| 12 | import kotlin.math.cos | ||
| 13 | import kotlin.math.sin | ||
| 14 | import kotlin.math.sqrt | ||
| 15 | |||
| 16 | /** | ||
| 17 | * Custom [BitmapDrawable] that is capable | ||
| 18 | * of storing it's own ID. | ||
| 19 | * | ||
| 20 | * @param res [Resources] instance. | ||
| 21 | * @param bitmapOuter [Bitmap] which represents the outer non-movable part of the joystick. | ||
| 22 | * @param bitmapInnerDefault [Bitmap] which represents the default inner movable part of the joystick. | ||
| 23 | * @param bitmapInnerPressed [Bitmap] which represents the pressed inner movable part of the joystick. | ||
| 24 | * @param rectOuter [Rect] which represents the outer joystick bounds. | ||
| 25 | * @param rectInner [Rect] which represents the inner joystick bounds. | ||
| 26 | * @param joystickId The ID value what type of joystick this Drawable represents. | ||
| 27 | * @param buttonId The ID value what type of button this Drawable represents. | ||
| 28 | */ | ||
| 29 | class InputOverlayDrawableJoystick( | ||
| 30 | res: Resources, | ||
| 31 | bitmapOuter: Bitmap, | ||
| 32 | bitmapInnerDefault: Bitmap, | ||
| 33 | bitmapInnerPressed: Bitmap, | ||
| 34 | rectOuter: Rect, | ||
| 35 | rectInner: Rect, | ||
| 36 | val joystickId: Int, | ||
| 37 | val buttonId: Int | ||
| 38 | ) { | ||
| 39 | |||
| 40 | // The ID value what motion event is tracking | ||
| 41 | var trackId = -1 | ||
| 42 | var xAxis = 0f | ||
| 43 | private var yAxis = 0f | ||
| 44 | private var controlPositionX = 0 | ||
| 45 | private var controlPositionY = 0 | ||
| 46 | val width: Int | ||
| 47 | val height: Int | ||
| 48 | private var virtBounds: Rect | ||
| 49 | private val origBounds: Rect | ||
| 50 | private val outerBitmap: BitmapDrawable | ||
| 51 | private val defaultStateInnerBitmap: BitmapDrawable | ||
| 52 | private val pressedStateInnerBitmap: BitmapDrawable | ||
| 53 | private val boundsBoxBitmap: BitmapDrawable | ||
| 54 | private var pressedState = false | ||
| 55 | |||
| 56 | // TODO: Add button support | ||
| 57 | val buttonStatus: Int | ||
| 58 | get() = | ||
| 59 | NativeLibrary.ButtonState.RELEASED | ||
| 60 | var bounds: Rect? | ||
| 61 | get() = outerBitmap.bounds | ||
| 62 | set(bounds) { | ||
| 63 | outerBitmap.bounds = bounds!! | ||
| 64 | } | ||
| 65 | |||
| 66 | // Nintendo joysticks have y axis inverted | ||
| 67 | val realYAxis: Float | ||
| 68 | get() = -yAxis | ||
| 69 | |||
| 70 | private val currentStateBitmapDrawable: BitmapDrawable | ||
| 71 | get() = if (pressedState) pressedStateInnerBitmap else defaultStateInnerBitmap | ||
| 72 | |||
| 73 | init { | ||
| 74 | outerBitmap = BitmapDrawable(res, bitmapOuter) | ||
| 75 | defaultStateInnerBitmap = BitmapDrawable(res, bitmapInnerDefault) | ||
| 76 | pressedStateInnerBitmap = BitmapDrawable(res, bitmapInnerPressed) | ||
| 77 | boundsBoxBitmap = BitmapDrawable(res, bitmapOuter) | ||
| 78 | width = bitmapOuter.width | ||
| 79 | height = bitmapOuter.height | ||
| 80 | bounds = rectOuter | ||
| 81 | defaultStateInnerBitmap.bounds = rectInner | ||
| 82 | pressedStateInnerBitmap.bounds = rectInner | ||
| 83 | virtBounds = bounds!! | ||
| 84 | origBounds = outerBitmap.copyBounds() | ||
| 85 | boundsBoxBitmap.alpha = 0 | ||
| 86 | boundsBoxBitmap.bounds = virtBounds | ||
| 87 | setInnerBounds() | ||
| 88 | } | ||
| 89 | |||
| 90 | fun draw(canvas: Canvas?) { | ||
| 91 | outerBitmap.draw(canvas!!) | ||
| 92 | currentStateBitmapDrawable.draw(canvas) | ||
| 93 | boundsBoxBitmap.draw(canvas) | ||
| 94 | } | ||
| 95 | |||
| 96 | fun updateStatus(event: MotionEvent): Boolean { | ||
| 97 | val pointerIndex = event.actionIndex | ||
| 98 | val xPosition = event.getX(pointerIndex).toInt() | ||
| 99 | val yPosition = event.getY(pointerIndex).toInt() | ||
| 100 | val pointerId = event.getPointerId(pointerIndex) | ||
| 101 | val motionEvent = event.action and MotionEvent.ACTION_MASK | ||
| 102 | val isActionDown = | ||
| 103 | motionEvent == MotionEvent.ACTION_DOWN || motionEvent == MotionEvent.ACTION_POINTER_DOWN | ||
| 104 | val isActionUp = | ||
| 105 | motionEvent == MotionEvent.ACTION_UP || motionEvent == MotionEvent.ACTION_POINTER_UP | ||
| 106 | if (isActionDown) { | ||
| 107 | if (!bounds!!.contains(xPosition, yPosition)) { | ||
| 108 | return false | ||
| 109 | } | ||
| 110 | pressedState = true | ||
| 111 | outerBitmap.alpha = 0 | ||
| 112 | boundsBoxBitmap.alpha = 255 | ||
| 113 | if (EmulationMenuSettings.joystickRelCenter) { | ||
| 114 | virtBounds.offset( | ||
| 115 | xPosition - virtBounds.centerX(), | ||
| 116 | yPosition - virtBounds.centerY() | ||
| 117 | ) | ||
| 118 | } | ||
| 119 | boundsBoxBitmap.bounds = virtBounds | ||
| 120 | trackId = pointerId | ||
| 121 | } | ||
| 122 | if (isActionUp) { | ||
| 123 | if (trackId != pointerId) { | ||
| 124 | return false | ||
| 125 | } | ||
| 126 | pressedState = false | ||
| 127 | xAxis = 0.0f | ||
| 128 | yAxis = 0.0f | ||
| 129 | outerBitmap.alpha = 255 | ||
| 130 | boundsBoxBitmap.alpha = 0 | ||
| 131 | virtBounds = Rect( | ||
| 132 | origBounds.left, | ||
| 133 | origBounds.top, | ||
| 134 | origBounds.right, | ||
| 135 | origBounds.bottom | ||
| 136 | ) | ||
| 137 | bounds = Rect( | ||
| 138 | origBounds.left, | ||
| 139 | origBounds.top, | ||
| 140 | origBounds.right, | ||
| 141 | origBounds.bottom | ||
| 142 | ) | ||
| 143 | setInnerBounds() | ||
| 144 | trackId = -1 | ||
| 145 | return true | ||
| 146 | } | ||
| 147 | if (trackId == -1) return false | ||
| 148 | for (i in 0 until event.pointerCount) { | ||
| 149 | if (trackId != event.getPointerId(i)) { | ||
| 150 | continue | ||
| 151 | } | ||
| 152 | var touchX = event.getX(i) | ||
| 153 | var touchY = event.getY(i) | ||
| 154 | var maxY = virtBounds.bottom.toFloat() | ||
| 155 | var maxX = virtBounds.right.toFloat() | ||
| 156 | touchX -= virtBounds.centerX().toFloat() | ||
| 157 | maxX -= virtBounds.centerX().toFloat() | ||
| 158 | touchY -= virtBounds.centerY().toFloat() | ||
| 159 | maxY -= virtBounds.centerY().toFloat() | ||
| 160 | val axisX = touchX / maxX | ||
| 161 | val axisY = touchY / maxY | ||
| 162 | val oldXAxis = xAxis | ||
| 163 | val oldYAxis = yAxis | ||
| 164 | |||
| 165 | // Clamp the circle pad input to a circle | ||
| 166 | val angle = atan2(axisY.toDouble(), axisX.toDouble()).toFloat() | ||
| 167 | var radius = sqrt((axisX * axisX + axisY * axisY).toDouble()).toFloat() | ||
| 168 | if (radius > 1.0f) { | ||
| 169 | radius = 1.0f | ||
| 170 | } | ||
| 171 | xAxis = cos(angle.toDouble()).toFloat() * radius | ||
| 172 | yAxis = sin(angle.toDouble()).toFloat() * radius | ||
| 173 | setInnerBounds() | ||
| 174 | return oldXAxis != xAxis && oldYAxis != yAxis | ||
| 175 | } | ||
| 176 | return false | ||
| 177 | } | ||
| 178 | |||
| 179 | private fun setInnerBounds() { | ||
| 180 | var x = virtBounds.centerX() + (xAxis * (virtBounds.width() / 2)).toInt() | ||
| 181 | var y = virtBounds.centerY() + (yAxis * (virtBounds.height() / 2)).toInt() | ||
| 182 | if (x > virtBounds.centerX() + virtBounds.width() / 2) x = | ||
| 183 | virtBounds.centerX() + virtBounds.width() / 2 | ||
| 184 | if (x < virtBounds.centerX() - virtBounds.width() / 2) x = | ||
| 185 | virtBounds.centerX() - virtBounds.width() / 2 | ||
| 186 | if (y > virtBounds.centerY() + virtBounds.height() / 2) y = | ||
| 187 | virtBounds.centerY() + virtBounds.height() / 2 | ||
| 188 | if (y < virtBounds.centerY() - virtBounds.height() / 2) y = | ||
| 189 | virtBounds.centerY() - virtBounds.height() / 2 | ||
| 190 | val width = pressedStateInnerBitmap.bounds.width() / 2 | ||
| 191 | val height = pressedStateInnerBitmap.bounds.height() / 2 | ||
| 192 | defaultStateInnerBitmap.setBounds( | ||
| 193 | x - width, | ||
| 194 | y - height, | ||
| 195 | x + width, | ||
| 196 | y + height | ||
| 197 | ) | ||
| 198 | pressedStateInnerBitmap.bounds = defaultStateInnerBitmap.bounds | ||
| 199 | } | ||
| 200 | |||
| 201 | fun setPosition(x: Int, y: Int) { | ||
| 202 | controlPositionX = x | ||
| 203 | controlPositionY = y | ||
| 204 | } | ||
| 205 | } | ||