Android: Merge dpad into one button
This commit is contained in:
parent
acff275f6b
commit
17707525dc
|
@ -0,0 +1,166 @@
|
|||
package com.github.stenzek.duckstation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public final class TouchscreenControllerDPadView extends View {
|
||||
private static final int NUM_DIRECTIONS = 4;
|
||||
private static final int NUM_POSITIONS = 8;
|
||||
private static final int DIRECTION_UP = 0;
|
||||
private static final int DIRECTION_RIGHT = 1;
|
||||
private static final int DIRECTION_DOWN = 2;
|
||||
private static final int DIRECTION_LEFT = 3;
|
||||
|
||||
private final Drawable[] mUnpressedDrawables = new Drawable[NUM_DIRECTIONS];
|
||||
private final Drawable[] mPressedDrawables = new Drawable[NUM_DIRECTIONS];
|
||||
private final int[] mDirectionCodes = new int[] { -1, -1, -1, -1 };
|
||||
private final boolean[] mDirectionStates = new boolean[NUM_DIRECTIONS];
|
||||
|
||||
private boolean mPressed = false;
|
||||
private int mPointerId = 0;
|
||||
private int mPointerX = 0;
|
||||
private int mPointerY = 0;
|
||||
|
||||
private String mConfigName;
|
||||
private boolean mDefaultVisibility = true;
|
||||
|
||||
private int mControllerIndex = -1;
|
||||
|
||||
private static final int[][] DRAWABLES = {
|
||||
{R.drawable.ic_controller_up_button,R.drawable.ic_controller_up_button_pressed},
|
||||
{R.drawable.ic_controller_right_button,R.drawable.ic_controller_right_button_pressed},
|
||||
{R.drawable.ic_controller_down_button,R.drawable.ic_controller_down_button_pressed},
|
||||
{R.drawable.ic_controller_left_button,R.drawable.ic_controller_left_button_pressed},
|
||||
};
|
||||
|
||||
|
||||
public TouchscreenControllerDPadView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public TouchscreenControllerDPadView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public TouchscreenControllerDPadView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
for (int i = 0; i < NUM_DIRECTIONS; i++) {
|
||||
mUnpressedDrawables[i] = getContext().getDrawable(DRAWABLES[i][0]);
|
||||
mPressedDrawables[i] = getContext().getDrawable(DRAWABLES[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
public String getConfigName() {
|
||||
return mConfigName;
|
||||
}
|
||||
public void setConfigName(String configName) {
|
||||
mConfigName = configName;
|
||||
}
|
||||
|
||||
public boolean getDefaultVisibility() { return mDefaultVisibility; }
|
||||
public void setDefaultVisibility(boolean visibility) { mDefaultVisibility = visibility; }
|
||||
|
||||
public void setControllerButtons(int controllerIndex, int leftCode, int rightCode, int upCode, int downCode) {
|
||||
mControllerIndex = controllerIndex;
|
||||
mDirectionCodes[DIRECTION_LEFT] = leftCode;
|
||||
mDirectionCodes[DIRECTION_RIGHT] = rightCode;
|
||||
mDirectionCodes[DIRECTION_UP] = upCode;
|
||||
mDirectionCodes[DIRECTION_DOWN] = downCode;
|
||||
}
|
||||
|
||||
public void setUnpressed() {
|
||||
if (!mPressed && mPointerX == 0 && mPointerY == 0)
|
||||
return;
|
||||
|
||||
mPressed = false;
|
||||
mPointerX = 0;
|
||||
mPointerY = 0;
|
||||
updateControllerState();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setPressed(int pointerId, float pointerX, float pointerY) {
|
||||
final int posX = (int)(pointerX - getX());
|
||||
final int posY = (int)(pointerY - getY());
|
||||
|
||||
boolean doUpdate = (pointerId != mPointerId || !mPressed || (posX != mPointerX || posY != mPointerY));
|
||||
mPointerId = pointerId;
|
||||
mPointerX = posX;
|
||||
mPointerY = posY;
|
||||
mPressed = true;
|
||||
|
||||
if (doUpdate) {
|
||||
updateControllerState();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateControllerState() {
|
||||
final int subX = mPointerX / (getWidth() / 3);
|
||||
final int subY = mPointerY / (getWidth() / 3);
|
||||
|
||||
mDirectionStates[DIRECTION_UP] = (mPressed && subY == 0);
|
||||
mDirectionStates[DIRECTION_RIGHT] = (mPressed && subX == 2);
|
||||
mDirectionStates[DIRECTION_DOWN] = (mPressed && subY == 2);
|
||||
mDirectionStates[DIRECTION_LEFT] = (mPressed && subX == 0);
|
||||
|
||||
AndroidHostInterface hostInterface = AndroidHostInterface.getInstance();
|
||||
for (int i = 0; i < NUM_DIRECTIONS; i++) {
|
||||
if (mDirectionCodes[i] >= 0)
|
||||
hostInterface.setControllerButtonState(mControllerIndex, mDirectionCodes[i], mDirectionStates[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawDirection(int direction, int subX, int subY, Canvas canvas, int buttonWidth, int buttonHeight) {
|
||||
final int leftBounds = subX * buttonWidth;
|
||||
final int rightBounds = leftBounds + buttonWidth;
|
||||
final int topBounds = subY * buttonHeight;
|
||||
final int bottomBounds = topBounds + buttonHeight;
|
||||
|
||||
final Drawable drawable = mDirectionStates[direction] ? mPressedDrawables[direction] : mUnpressedDrawables[direction];
|
||||
drawable.setBounds(leftBounds, topBounds, rightBounds, bottomBounds);
|
||||
drawable.draw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
|
||||
// Divide it into thirds - draw between.
|
||||
final int buttonWidth = width / 3;
|
||||
final int buttonHeight = height / 3;
|
||||
|
||||
drawDirection(DIRECTION_UP, 1, 0, canvas, buttonWidth, buttonHeight);
|
||||
drawDirection(DIRECTION_RIGHT, 2, 1, canvas, buttonWidth, buttonHeight);
|
||||
drawDirection(DIRECTION_DOWN, 1, 2, canvas, buttonWidth, buttonHeight);
|
||||
drawDirection(DIRECTION_LEFT, 0, 1, canvas, buttonWidth, buttonHeight);
|
||||
}
|
||||
|
||||
public boolean isPressed() {
|
||||
return mPressed;
|
||||
}
|
||||
|
||||
public boolean hasPointerId() {
|
||||
return mPointerId >= 0;
|
||||
}
|
||||
|
||||
public int getPointerId() {
|
||||
return mPointerId;
|
||||
}
|
||||
|
||||
public void setPointerId(int mPointerId) {
|
||||
this.mPointerId = mPointerId;
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
private View mMainView;
|
||||
private ArrayList<TouchscreenControllerButtonView> mButtonViews = new ArrayList<>();
|
||||
private ArrayList<TouchscreenControllerAxisView> mAxisViews = new ArrayList<>();
|
||||
private TouchscreenControllerDPadView mDPadView = null;
|
||||
private boolean mHapticFeedback;
|
||||
private String mLayoutOrientation;
|
||||
private boolean mEditingLayout = false;
|
||||
|
@ -105,6 +106,13 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
axisView.setTranslationY(0.0f);
|
||||
}
|
||||
|
||||
if (mDPadView != null) {
|
||||
editor.remove(getConfigKeyForXTranslation(mDPadView.getConfigName()));
|
||||
editor.remove(getConfigKeyForYTranslation(mDPadView.getConfigName()));
|
||||
mDPadView.setTranslationX(0.0f);
|
||||
mDPadView.setTranslationY(0.0f);
|
||||
}
|
||||
|
||||
editor.commit();
|
||||
requestLayout();
|
||||
}
|
||||
|
@ -137,6 +145,18 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
if (mDPadView != null) {
|
||||
try {
|
||||
mDPadView.setTranslationX(prefs.getFloat(getConfigKeyForXTranslation(mDPadView.getConfigName()), 0.0f));
|
||||
mDPadView.setTranslationY(prefs.getFloat(getConfigKeyForYTranslation(mDPadView.getConfigName()), 0.0f));
|
||||
|
||||
final boolean visible = prefs.getBoolean(getConfigKeyForVisibility(mDPadView.getConfigName()), mDPadView.getDefaultVisibility());
|
||||
mDPadView.setVisibility(visible ? VISIBLE : INVISIBLE);
|
||||
} catch (ClassCastException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setOpacity(int opacity) {
|
||||
|
@ -160,6 +180,8 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
for (TouchscreenControllerAxisView axisView : mAxisViews) {
|
||||
axisView.setAlpha(alpha);
|
||||
}
|
||||
if (mDPadView != null)
|
||||
mDPadView.setAlpha(alpha);
|
||||
}
|
||||
|
||||
private String getOrientationString() {
|
||||
|
@ -232,10 +254,7 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
|
||||
linkButton(mMainView, R.id.controller_button_up, "UpButton", "Up", true, false);
|
||||
linkButton(mMainView, R.id.controller_button_right, "RightButton", "Right", true, false);
|
||||
linkButton(mMainView, R.id.controller_button_down, "DownButton", "Down", true, false);
|
||||
linkButton(mMainView, R.id.controller_button_left, "LeftButton", "Left", true, false);
|
||||
linkDPadToButtons(mMainView, R.id.controller_dpad, "DPad", "", true);
|
||||
linkButton(mMainView, R.id.controller_button_l1, "L1Button", "L1", true, gliding);
|
||||
linkButton(mMainView, R.id.controller_button_l2, "L2Button", "L2", true, gliding);
|
||||
linkButton(mMainView, R.id.controller_button_select, "SelectButton", "Select", true, gliding);
|
||||
|
@ -320,6 +339,27 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean linkDPadToButtons(View view, int id, String configName, String buttonPrefix, boolean defaultVisibility) {
|
||||
TouchscreenControllerDPadView dpadView = (TouchscreenControllerDPadView) view.findViewById(id);
|
||||
if (dpadView == null)
|
||||
return false;
|
||||
|
||||
dpadView.setConfigName(configName);
|
||||
dpadView.setDefaultVisibility(defaultVisibility);
|
||||
mDPadView = dpadView;
|
||||
|
||||
int leftCode = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonPrefix + "Left");
|
||||
int rightCode = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonPrefix + "Right");
|
||||
int upCode = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonPrefix + "Up");
|
||||
int downCode = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonPrefix + "Down");
|
||||
Log.i("TouchscreenController", String.format("%s(DPad) -> %d,%d,%d,%d", buttonPrefix, leftCode, rightCode, upCode, downCode));
|
||||
if (leftCode < 0 && rightCode < 0 && upCode < 0 && downCode < 0)
|
||||
return false;
|
||||
|
||||
dpadView.setControllerButtons(mControllerIndex, leftCode, rightCode, upCode, downCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void linkHotkeyButton(View view, int id, String configName, TouchscreenControllerButtonView.Hotkey hotkey, boolean defaultVisibility) {
|
||||
TouchscreenControllerButtonView buttonView = (TouchscreenControllerButtonView) view.findViewById(id);
|
||||
if (buttonView == null)
|
||||
|
@ -410,6 +450,17 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
}
|
||||
}
|
||||
|
||||
if (mDPadView != null) {
|
||||
mDPadView.getHitRect(rect);
|
||||
if (rect.contains((int) x, (int) y)) {
|
||||
mMovingView = mDPadView;
|
||||
mMovingName = mDPadView.getConfigName();
|
||||
mMovingLastX = x;
|
||||
mMovingLastY = y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// nothing..
|
||||
return true;
|
||||
}
|
||||
|
@ -502,6 +553,23 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
axisView.setUnpressed();
|
||||
}
|
||||
|
||||
if (mDPadView != null && mDPadView.getVisibility() == VISIBLE) {
|
||||
mDPadView.getHitRect(rect);
|
||||
|
||||
boolean pressed = false;
|
||||
for (int i = 0; i < pointerCount; i++) {
|
||||
final int x = (int) event.getX(i);
|
||||
final int y = (int) event.getY(i);
|
||||
if (rect.contains(x, y)) {
|
||||
mDPadView.setPressed(event.getPointerId(i), x, y);
|
||||
pressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pressed)
|
||||
mDPadView.setUnpressed();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -521,6 +589,9 @@ public class TouchscreenControllerView extends FrameLayout {
|
|||
axisView.setUnpressed();
|
||||
}
|
||||
|
||||
if (mDPadView != null)
|
||||
mDPadView.setUnpressed();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,57 +147,14 @@
|
|||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_left"
|
||||
android:layout_width="50dp"
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerDPadView
|
||||
android:id="@+id/controller_dpad"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="150dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginBottom="300dp"
|
||||
android:paddingTop="50dp"
|
||||
android:paddingBottom="50dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_left_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_left_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_down"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginBottom="300dp"
|
||||
android:paddingStart="50dp"
|
||||
android:paddingEnd="50dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_down_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_down_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_right"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="150dp"
|
||||
android:layout_marginStart="120dp"
|
||||
android:layout_marginBottom="300dp"
|
||||
android:paddingTop="50dp"
|
||||
android:paddingBottom="50dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_right_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_right_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_up"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginBottom="400dp"
|
||||
android:paddingStart="50dp"
|
||||
android:paddingEnd="50dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_up_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_up_button" />
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_fast_forward"
|
||||
|
|
|
@ -29,31 +29,14 @@
|
|||
app:pressedDrawable="@drawable/ic_controller_r1_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_r1_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_right"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="150dp"
|
||||
android:layout_marginStart="120dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:paddingTop="50dp"
|
||||
android:paddingBottom="50dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_right_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_right_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_up"
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerDPadView
|
||||
android:id="@+id/controller_dpad"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_height="150dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginBottom="130dp"
|
||||
android:paddingStart="50dp"
|
||||
android:paddingEnd="50dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_up_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_up_button" />
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_l1"
|
||||
|
@ -77,32 +60,6 @@
|
|||
app:pressedDrawable="@drawable/ic_controller_l2_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_l2_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_left"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="150dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:paddingTop="50dp"
|
||||
android:paddingBottom="50dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_left_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_left_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_down"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:paddingStart="50dp"
|
||||
android:paddingEnd="50dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:pressedDrawable="@drawable/ic_controller_down_button_pressed"
|
||||
app:unpressedDrawable="@drawable/ic_controller_down_button" />
|
||||
|
||||
<com.github.stenzek.duckstation.TouchscreenControllerButtonView
|
||||
android:id="@+id/controller_button_start"
|
||||
android:layout_width="40dp"
|
||||
|
|
Loading…
Reference in New Issue