Android: Convert InputOverlayDrawableJoystick to Kotlin
This commit is contained in:
parent
fb60b708f5
commit
ddb0de0410
|
@ -1,318 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2013 Dolphin Emulator Project
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.overlay;
|
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.features.input.model.InputOverrider;
|
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom {@link BitmapDrawable} that is capable
|
|
||||||
* of storing it's own ID.
|
|
||||||
*/
|
|
||||||
public final class InputOverlayDrawableJoystick
|
|
||||||
{
|
|
||||||
private float mCurrentX = 0.0f;
|
|
||||||
private float mCurrentY = 0.0f;
|
|
||||||
private int trackId = -1;
|
|
||||||
private final int mJoystickLegacyId;
|
|
||||||
private final int mJoystickXControl;
|
|
||||||
private final int mJoystickYControl;
|
|
||||||
private int mControlPositionX, mControlPositionY;
|
|
||||||
private int mPreviousTouchX, mPreviousTouchY;
|
|
||||||
private final int mWidth;
|
|
||||||
private final int mHeight;
|
|
||||||
private final int mControllerIndex;
|
|
||||||
private Rect mVirtBounds;
|
|
||||||
private Rect mOrigBounds;
|
|
||||||
private int mOpacity;
|
|
||||||
private final BitmapDrawable mOuterBitmap;
|
|
||||||
private final BitmapDrawable mDefaultStateInnerBitmap;
|
|
||||||
private final BitmapDrawable mPressedStateInnerBitmap;
|
|
||||||
private final BitmapDrawable mBoundsBoxBitmap;
|
|
||||||
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 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 legacyId Legacy identifier (ButtonType) for which joystick this is.
|
|
||||||
* @param xControl The control which the x value of the joystick will be written to.
|
|
||||||
* @param yControl The control which the y value of the joystick will be written to.
|
|
||||||
*/
|
|
||||||
public InputOverlayDrawableJoystick(Resources res, Bitmap bitmapOuter, Bitmap bitmapInnerDefault,
|
|
||||||
Bitmap bitmapInnerPressed, Rect rectOuter, Rect rectInner, int legacyId, int xControl,
|
|
||||||
int yControl, int controllerIndex)
|
|
||||||
{
|
|
||||||
mJoystickLegacyId = legacyId;
|
|
||||||
mJoystickXControl = xControl;
|
|
||||||
mJoystickYControl = yControl;
|
|
||||||
|
|
||||||
mOuterBitmap = new BitmapDrawable(res, bitmapOuter);
|
|
||||||
mDefaultStateInnerBitmap = new BitmapDrawable(res, bitmapInnerDefault);
|
|
||||||
mPressedStateInnerBitmap = new BitmapDrawable(res, bitmapInnerPressed);
|
|
||||||
mBoundsBoxBitmap = new BitmapDrawable(res, bitmapOuter);
|
|
||||||
mWidth = bitmapOuter.getWidth();
|
|
||||||
mHeight = bitmapOuter.getHeight();
|
|
||||||
|
|
||||||
if (controllerIndex < 0 || controllerIndex >= 4)
|
|
||||||
throw new IllegalArgumentException("controllerIndex must be 0-3");
|
|
||||||
mControllerIndex = controllerIndex;
|
|
||||||
|
|
||||||
setBounds(rectOuter);
|
|
||||||
mDefaultStateInnerBitmap.setBounds(rectInner);
|
|
||||||
mPressedStateInnerBitmap.setBounds(rectInner);
|
|
||||||
mVirtBounds = getBounds();
|
|
||||||
mOrigBounds = mOuterBitmap.copyBounds();
|
|
||||||
mBoundsBoxBitmap.setAlpha(0);
|
|
||||||
mBoundsBoxBitmap.setBounds(getVirtBounds());
|
|
||||||
SetInnerBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets this InputOverlayDrawableJoystick's legacy ID.
|
|
||||||
*
|
|
||||||
* @return this InputOverlayDrawableJoystick's legacy ID.
|
|
||||||
*/
|
|
||||||
public int getLegacyId()
|
|
||||||
{
|
|
||||||
return mJoystickLegacyId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(Canvas canvas)
|
|
||||||
{
|
|
||||||
mOuterBitmap.draw(canvas);
|
|
||||||
getCurrentStateBitmapDrawable().draw(canvas);
|
|
||||||
mBoundsBoxBitmap.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean TrackEvent(MotionEvent event)
|
|
||||||
{
|
|
||||||
boolean reCenter = BooleanSetting.MAIN_JOYSTICK_REL_CENTER.getBoolean();
|
|
||||||
int action = event.getActionMasked();
|
|
||||||
boolean firstPointer = action != MotionEvent.ACTION_POINTER_DOWN &&
|
|
||||||
action != MotionEvent.ACTION_POINTER_UP;
|
|
||||||
int pointerIndex = firstPointer ? 0 : event.getActionIndex();
|
|
||||||
boolean pressed = false;
|
|
||||||
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
|
||||||
case MotionEvent.ACTION_POINTER_DOWN:
|
|
||||||
if (getBounds().contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
|
|
||||||
{
|
|
||||||
mPressedState = pressed = true;
|
|
||||||
mOuterBitmap.setAlpha(0);
|
|
||||||
mBoundsBoxBitmap.setAlpha(mOpacity);
|
|
||||||
if (reCenter)
|
|
||||||
{
|
|
||||||
getVirtBounds().offset((int) event.getX(pointerIndex) - getVirtBounds().centerX(),
|
|
||||||
(int) event.getY(pointerIndex) - getVirtBounds().centerY());
|
|
||||||
}
|
|
||||||
mBoundsBoxBitmap.setBounds(getVirtBounds());
|
|
||||||
trackId = event.getPointerId(pointerIndex);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
case MotionEvent.ACTION_POINTER_UP:
|
|
||||||
if (trackId == event.getPointerId(pointerIndex))
|
|
||||||
{
|
|
||||||
pressed = true;
|
|
||||||
mPressedState = false;
|
|
||||||
mCurrentX = mCurrentY = 0.0f;
|
|
||||||
mOuterBitmap.setAlpha(mOpacity);
|
|
||||||
mBoundsBoxBitmap.setAlpha(0);
|
|
||||||
setVirtBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right,
|
|
||||||
mOrigBounds.bottom));
|
|
||||||
setBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right,
|
|
||||||
mOrigBounds.bottom));
|
|
||||||
SetInnerBounds();
|
|
||||||
trackId = -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackId == -1)
|
|
||||||
return pressed;
|
|
||||||
|
|
||||||
for (int i = 0; i < event.getPointerCount(); i++)
|
|
||||||
{
|
|
||||||
if (trackId == event.getPointerId(i))
|
|
||||||
{
|
|
||||||
float touchX = event.getX(i);
|
|
||||||
float touchY = event.getY(i);
|
|
||||||
float maxY = getVirtBounds().bottom;
|
|
||||||
float maxX = getVirtBounds().right;
|
|
||||||
touchX -= getVirtBounds().centerX();
|
|
||||||
maxX -= getVirtBounds().centerX();
|
|
||||||
touchY -= getVirtBounds().centerY();
|
|
||||||
maxY -= getVirtBounds().centerY();
|
|
||||||
mCurrentX = touchX / maxX;
|
|
||||||
mCurrentY = touchY / maxY;
|
|
||||||
|
|
||||||
SetInnerBounds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onConfigureTouch(MotionEvent event)
|
|
||||||
{
|
|
||||||
switch (event.getAction())
|
|
||||||
{
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
|
||||||
mPreviousTouchX = (int) event.getX();
|
|
||||||
mPreviousTouchY = (int) event.getY();
|
|
||||||
break;
|
|
||||||
case MotionEvent.ACTION_MOVE:
|
|
||||||
int deltaX = (int) event.getX() - mPreviousTouchX;
|
|
||||||
int deltaY = (int) event.getY() - mPreviousTouchY;
|
|
||||||
mControlPositionX += deltaX;
|
|
||||||
mControlPositionY += deltaY;
|
|
||||||
setBounds(new Rect(mControlPositionX, mControlPositionY,
|
|
||||||
mOuterBitmap.getIntrinsicWidth() + mControlPositionX,
|
|
||||||
mOuterBitmap.getIntrinsicHeight() + mControlPositionY));
|
|
||||||
setVirtBounds(new Rect(mControlPositionX, mControlPositionY,
|
|
||||||
mOuterBitmap.getIntrinsicWidth() + mControlPositionX,
|
|
||||||
mOuterBitmap.getIntrinsicHeight() + mControlPositionY));
|
|
||||||
SetInnerBounds();
|
|
||||||
setOrigBounds(new Rect(new Rect(mControlPositionX, mControlPositionY,
|
|
||||||
mOuterBitmap.getIntrinsicWidth() + mControlPositionX,
|
|
||||||
mOuterBitmap.getIntrinsicHeight() + mControlPositionY)));
|
|
||||||
mPreviousTouchX = (int) event.getX();
|
|
||||||
mPreviousTouchY = (int) event.getY();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getX()
|
|
||||||
{
|
|
||||||
return mCurrentX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getY()
|
|
||||||
{
|
|
||||||
return mCurrentY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getXControl()
|
|
||||||
{
|
|
||||||
return mJoystickXControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getYControl()
|
|
||||||
{
|
|
||||||
return mJoystickYControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetInnerBounds()
|
|
||||||
{
|
|
||||||
double x = mCurrentX;
|
|
||||||
double y = mCurrentY;
|
|
||||||
|
|
||||||
double angle = Math.atan2(y, x) + Math.PI + Math.PI;
|
|
||||||
double radius = Math.hypot(y, x);
|
|
||||||
double maxRadius = InputOverrider.getGateRadiusAtAngle(mControllerIndex, mJoystickXControl,
|
|
||||||
angle);
|
|
||||||
if (radius > maxRadius)
|
|
||||||
{
|
|
||||||
y = maxRadius * Math.sin(angle);
|
|
||||||
x = maxRadius * Math.cos(angle);
|
|
||||||
mCurrentY = (float) y;
|
|
||||||
mCurrentX = (float) x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pixelX = getVirtBounds().centerX() + (int) (x * (getVirtBounds().width() / 2));
|
|
||||||
int pixelY = getVirtBounds().centerY() + (int) (y * (getVirtBounds().height() / 2));
|
|
||||||
|
|
||||||
int width = mPressedStateInnerBitmap.getBounds().width() / 2;
|
|
||||||
int height = mPressedStateInnerBitmap.getBounds().height() / 2;
|
|
||||||
mDefaultStateInnerBitmap.setBounds(pixelX - width, pixelY - height, pixelX + width,
|
|
||||||
pixelY + height);
|
|
||||||
mPressedStateInnerBitmap.setBounds(mDefaultStateInnerBitmap.getBounds());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPosition(int x, int y)
|
|
||||||
{
|
|
||||||
mControlPositionX = x;
|
|
||||||
mControlPositionY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BitmapDrawable getCurrentStateBitmapDrawable()
|
|
||||||
{
|
|
||||||
return mPressedState ? mPressedStateInnerBitmap : mDefaultStateInnerBitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBounds(Rect bounds)
|
|
||||||
{
|
|
||||||
mOuterBitmap.setBounds(bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOpacity(int value)
|
|
||||||
{
|
|
||||||
mOpacity = value;
|
|
||||||
|
|
||||||
mDefaultStateInnerBitmap.setAlpha(value);
|
|
||||||
mPressedStateInnerBitmap.setAlpha(value);
|
|
||||||
|
|
||||||
if (trackId == -1)
|
|
||||||
{
|
|
||||||
mOuterBitmap.setAlpha(value);
|
|
||||||
mBoundsBoxBitmap.setAlpha(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mOuterBitmap.setAlpha(0);
|
|
||||||
mBoundsBoxBitmap.setAlpha(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Rect getBounds()
|
|
||||||
{
|
|
||||||
return mOuterBitmap.getBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setVirtBounds(Rect bounds)
|
|
||||||
{
|
|
||||||
mVirtBounds = bounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setOrigBounds(Rect bounds)
|
|
||||||
{
|
|
||||||
mOrigBounds = bounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rect getVirtBounds()
|
|
||||||
{
|
|
||||||
return mVirtBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth()
|
|
||||||
{
|
|
||||||
return mWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeight()
|
|
||||||
{
|
|
||||||
return mHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTrackId()
|
|
||||||
{
|
|
||||||
return trackId;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,258 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.overlay
|
||||||
|
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import org.dolphinemu.dolphinemu.features.input.model.InputOverrider
|
||||||
|
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting
|
||||||
|
import kotlin.math.atan2
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.hypot
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom [BitmapDrawable] that is capable
|
||||||
|
* of storing it's own ID.
|
||||||
|
*
|
||||||
|
* @param res [Resources] instance.
|
||||||
|
* @param bitmapOuter [Bitmap] which represents the outer non-movable part of the joystick.
|
||||||
|
* @param bitmapInnerDefault [Bitmap] which represents the default inner movable part of the joystick.
|
||||||
|
* @param bitmapInnerPressed [Bitmap] which represents the pressed inner movable part of the joystick.
|
||||||
|
* @param rectOuter [Rect] which represents the outer joystick bounds.
|
||||||
|
* @param rectInner [Rect] which represents the inner joystick bounds.
|
||||||
|
* @param legacyId Legacy identifier (ButtonType) for which joystick this is.
|
||||||
|
* @param xControl The control which the x value of the joystick will be written to.
|
||||||
|
* @param yControl The control which the y value of the joystick will be written to.
|
||||||
|
*/
|
||||||
|
class InputOverlayDrawableJoystick(
|
||||||
|
res: Resources,
|
||||||
|
bitmapOuter: Bitmap,
|
||||||
|
bitmapInnerDefault: Bitmap,
|
||||||
|
bitmapInnerPressed: Bitmap,
|
||||||
|
rectOuter: Rect,
|
||||||
|
rectInner: Rect,
|
||||||
|
val legacyId: Int,
|
||||||
|
val xControl: Int,
|
||||||
|
val yControl: Int,
|
||||||
|
private val controllerIndex: Int
|
||||||
|
) {
|
||||||
|
var x = 0.0f
|
||||||
|
private set
|
||||||
|
var y = 0.0f
|
||||||
|
private set
|
||||||
|
var trackId = -1
|
||||||
|
private set
|
||||||
|
private var controlPositionX = 0
|
||||||
|
private var controlPositionY = 0
|
||||||
|
private var previousTouchX = 0
|
||||||
|
private var previousTouchY = 0
|
||||||
|
val width: Int
|
||||||
|
val height: Int
|
||||||
|
private var virtBounds: Rect
|
||||||
|
private var origBounds: Rect
|
||||||
|
private var opacity = 0
|
||||||
|
private val outerBitmap: BitmapDrawable
|
||||||
|
private val defaultStateInnerBitmap: BitmapDrawable
|
||||||
|
private val pressedStateInnerBitmap: BitmapDrawable
|
||||||
|
private val boundsBoxBitmap: BitmapDrawable
|
||||||
|
private var pressedState = false
|
||||||
|
|
||||||
|
var bounds: Rect
|
||||||
|
get() = outerBitmap.bounds
|
||||||
|
set(bounds) {
|
||||||
|
outerBitmap.bounds = bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
outerBitmap = BitmapDrawable(res, bitmapOuter)
|
||||||
|
defaultStateInnerBitmap = BitmapDrawable(res, bitmapInnerDefault)
|
||||||
|
pressedStateInnerBitmap = BitmapDrawable(res, bitmapInnerPressed)
|
||||||
|
boundsBoxBitmap = BitmapDrawable(res, bitmapOuter)
|
||||||
|
width = bitmapOuter.width
|
||||||
|
height = bitmapOuter.height
|
||||||
|
|
||||||
|
require(!(controllerIndex < 0 || controllerIndex >= 4)) { "controllerIndex must be 0-3" }
|
||||||
|
|
||||||
|
bounds = rectOuter
|
||||||
|
defaultStateInnerBitmap.bounds = rectInner
|
||||||
|
pressedStateInnerBitmap.bounds = rectInner
|
||||||
|
virtBounds = bounds
|
||||||
|
origBounds = outerBitmap.copyBounds()
|
||||||
|
boundsBoxBitmap.alpha = 0
|
||||||
|
boundsBoxBitmap.bounds = virtBounds
|
||||||
|
setInnerBounds()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw(canvas: Canvas) {
|
||||||
|
outerBitmap.draw(canvas)
|
||||||
|
currentStateBitmapDrawable.draw(canvas)
|
||||||
|
boundsBoxBitmap.draw(canvas)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun trackEvent(event: MotionEvent): Boolean {
|
||||||
|
val reCenter = BooleanSetting.MAIN_JOYSTICK_REL_CENTER.boolean
|
||||||
|
val action = event.actionMasked
|
||||||
|
val firstPointer = action != MotionEvent.ACTION_POINTER_DOWN &&
|
||||||
|
action != MotionEvent.ACTION_POINTER_UP
|
||||||
|
val pointerIndex = if (firstPointer) 0 else event.actionIndex
|
||||||
|
var pressed = false
|
||||||
|
|
||||||
|
when (action) {
|
||||||
|
MotionEvent.ACTION_DOWN,
|
||||||
|
MotionEvent.ACTION_POINTER_DOWN -> {
|
||||||
|
if (bounds.contains(
|
||||||
|
event.getX(pointerIndex).toInt(),
|
||||||
|
event.getY(pointerIndex).toInt()
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
pressed = true
|
||||||
|
pressedState = true
|
||||||
|
outerBitmap.alpha = 0
|
||||||
|
boundsBoxBitmap.alpha = opacity
|
||||||
|
if (reCenter) {
|
||||||
|
virtBounds.offset(
|
||||||
|
event.getX(pointerIndex).toInt() - virtBounds.centerX(),
|
||||||
|
event.getY(pointerIndex).toInt() - virtBounds.centerY()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
boundsBoxBitmap.bounds = virtBounds
|
||||||
|
trackId = event.getPointerId(pointerIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MotionEvent.ACTION_UP,
|
||||||
|
MotionEvent.ACTION_POINTER_UP -> {
|
||||||
|
if (trackId == event.getPointerId(pointerIndex)) {
|
||||||
|
pressed = true
|
||||||
|
pressedState = false
|
||||||
|
y = 0f
|
||||||
|
x = y
|
||||||
|
outerBitmap.alpha = opacity
|
||||||
|
boundsBoxBitmap.alpha = 0
|
||||||
|
virtBounds =
|
||||||
|
Rect(origBounds.left, origBounds.top, origBounds.right, origBounds.bottom)
|
||||||
|
bounds =
|
||||||
|
Rect(origBounds.left, origBounds.top, origBounds.right, origBounds.bottom)
|
||||||
|
setInnerBounds()
|
||||||
|
trackId = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackId == -1)
|
||||||
|
return pressed
|
||||||
|
|
||||||
|
for (i in 0 until event.pointerCount) {
|
||||||
|
if (trackId == event.getPointerId(i)) {
|
||||||
|
var touchX = event.getX(i)
|
||||||
|
var touchY = event.getY(i)
|
||||||
|
var maxY = virtBounds.bottom.toFloat()
|
||||||
|
var maxX = virtBounds.right.toFloat()
|
||||||
|
touchX -= virtBounds.centerX().toFloat()
|
||||||
|
maxX -= virtBounds.centerX().toFloat()
|
||||||
|
touchY -= virtBounds.centerY().toFloat()
|
||||||
|
maxY -= virtBounds.centerY().toFloat()
|
||||||
|
x = touchX / maxX
|
||||||
|
y = touchY / maxY
|
||||||
|
|
||||||
|
setInnerBounds()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pressed
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onConfigureTouch(event: MotionEvent) {
|
||||||
|
when (event.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
previousTouchX = event.x.toInt()
|
||||||
|
previousTouchY = event.y.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
val deltaX = event.x.toInt() - previousTouchX
|
||||||
|
val deltaY = event.y.toInt() - previousTouchY
|
||||||
|
controlPositionX += deltaX
|
||||||
|
controlPositionY += deltaY
|
||||||
|
bounds = Rect(
|
||||||
|
controlPositionX,
|
||||||
|
controlPositionY,
|
||||||
|
outerBitmap.intrinsicWidth + controlPositionX,
|
||||||
|
outerBitmap.intrinsicHeight + controlPositionY
|
||||||
|
)
|
||||||
|
virtBounds = Rect(
|
||||||
|
controlPositionX,
|
||||||
|
controlPositionY,
|
||||||
|
outerBitmap.intrinsicWidth + controlPositionX,
|
||||||
|
outerBitmap.intrinsicHeight + controlPositionY
|
||||||
|
)
|
||||||
|
setInnerBounds()
|
||||||
|
origBounds = Rect(
|
||||||
|
Rect(
|
||||||
|
controlPositionX,
|
||||||
|
controlPositionY,
|
||||||
|
outerBitmap.intrinsicWidth + controlPositionX,
|
||||||
|
outerBitmap.intrinsicHeight + controlPositionY
|
||||||
|
)
|
||||||
|
)
|
||||||
|
previousTouchX = event.x.toInt()
|
||||||
|
previousTouchY = event.y.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setInnerBounds() {
|
||||||
|
var x = x.toDouble()
|
||||||
|
var y = y.toDouble()
|
||||||
|
|
||||||
|
val angle = atan2(y, x) + Math.PI + Math.PI
|
||||||
|
val radius = hypot(y, x)
|
||||||
|
val maxRadius = InputOverrider.getGateRadiusAtAngle(controllerIndex, xControl, angle)
|
||||||
|
if (radius > maxRadius) {
|
||||||
|
x = maxRadius * cos(angle)
|
||||||
|
y = maxRadius * sin(angle)
|
||||||
|
this.x = x.toFloat()
|
||||||
|
this.y = y.toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
val pixelX = virtBounds.centerX() + (x * (virtBounds.width() / 2)).toInt()
|
||||||
|
val pixelY = virtBounds.centerY() + (y * (virtBounds.height() / 2)).toInt()
|
||||||
|
|
||||||
|
val width = pressedStateInnerBitmap.bounds.width() / 2
|
||||||
|
val height = pressedStateInnerBitmap.bounds.height() / 2
|
||||||
|
defaultStateInnerBitmap.setBounds(
|
||||||
|
pixelX - width,
|
||||||
|
pixelY - height,
|
||||||
|
pixelX + width,
|
||||||
|
pixelY + height
|
||||||
|
)
|
||||||
|
pressedStateInnerBitmap.bounds = defaultStateInnerBitmap.bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPosition(x: Int, y: Int) {
|
||||||
|
controlPositionX = x
|
||||||
|
controlPositionY = y
|
||||||
|
}
|
||||||
|
|
||||||
|
private val currentStateBitmapDrawable: BitmapDrawable
|
||||||
|
get() = if (pressedState) pressedStateInnerBitmap else defaultStateInnerBitmap
|
||||||
|
|
||||||
|
fun setOpacity(value: Int) {
|
||||||
|
opacity = value
|
||||||
|
|
||||||
|
defaultStateInnerBitmap.alpha = value
|
||||||
|
pressedStateInnerBitmap.alpha = value
|
||||||
|
|
||||||
|
if (trackId == -1) {
|
||||||
|
outerBitmap.alpha = value
|
||||||
|
boundsBoxBitmap.alpha = 0
|
||||||
|
} else {
|
||||||
|
outerBitmap.alpha = 0
|
||||||
|
boundsBoxBitmap.alpha = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue