M android/app/src/main/java/com/metallic/chiaki/touchcontrols/ButtonView.kt => android/app/src/main/java/com/metallic/chiaki/touchcontrols/ButtonView.kt +25 -2
@@ 8,6 8,8 @@ import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
+import android.view.ViewGroup
+import androidx.core.view.children
import com.metallic.chiaki.R
class ButtonView @JvmOverloads constructor(
@@ 46,15 48,36 @@ class ButtonView @JvmOverloads constructor(
{
super.onDraw(canvas)
val drawable = if(buttonPressed) drawablePressed else drawableIdle
- drawable?.setBounds(0, 0, width, height)
+ drawable?.setBounds(paddingLeft, paddingTop, width - paddingRight, height - paddingBottom)
drawable?.draw(canvas)
}
+ /**
+ * If this button overlaps with others in the same layout,
+ * let the one whose center is closest to the touch handle it.
+ */
+ private fun bestFittingTouchView(x: Float, y: Float): View
+ {
+ val loc = locationOnScreen + Vector(x, y)
+ return (parent as? ViewGroup)?.children?.filter {
+ it is ButtonView
+ }?.filter {
+ val pos = it.locationOnScreen
+ loc.x >= pos.x && loc.x < pos.x + it.width && loc.y >= pos.y && loc.y < pos.y + it.height
+ }?.sortedBy {
+ (loc - (it.locationOnScreen + Vector(it.width.toFloat(), it.height.toFloat()) * 0.5f)).lengthSq
+ }?.firstOrNull() ?: this
+ }
+
override fun onTouchEvent(event: MotionEvent): Boolean
{
when(event.action)
{
- MotionEvent.ACTION_DOWN -> buttonPressed = true
+ MotionEvent.ACTION_DOWN -> {
+ if(bestFittingTouchView(event.x, event.y) != this)
+ return false
+ buttonPressed = true
+ }
MotionEvent.ACTION_UP -> buttonPressed = false
}
return true
M android/app/src/main/java/com/metallic/chiaki/touchcontrols/Vector.kt => android/app/src/main/java/com/metallic/chiaki/touchcontrols/Vector.kt +7 -0
@@ 2,6 2,7 @@
package com.metallic.chiaki.touchcontrols
+import android.view.View
import kotlin.math.sqrt
data class Vector(val x: Float, val y: Float)
@@ 18,4 19,10 @@ data class Vector(val x: Float, val y: Float)
val lengthSq get() = x*x + y*y
val length get() = sqrt(lengthSq)
val normalized get() = this / length
+}
+
+val View.locationOnScreen: Vector get() {
+ val v = intArrayOf(0, 0)
+ this.getLocationOnScreen(v)
+ return Vector(v[0].toFloat(), v[1].toFloat())
}=
\ No newline at end of file
M android/app/src/main/res/layout/fragment_controls.xml => android/app/src/main/res/layout/fragment_controls.xml +30 -26
@@ 1,10 1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:clipChildren="false">
+ android:clipChildren="false"
+ tools:ignore="RtlHardcoded,RtlSymmetry">
<com.metallic.chiaki.touchcontrols.ControlsBackgroundView
android:layout_width="match_parent"
@@ 57,8 59,8 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/faceButtonsLayout"
- android:layout_width="144dp"
- android:layout_height="144dp"
+ android:layout_width="@dimen/control_face_button_size_full"
+ android:layout_height="@dimen/control_face_button_size_full"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
@@ 67,9 69,12 @@
<com.metallic.chiaki.touchcontrols.ButtonView
android:id="@+id/crossButtonView"
- android:layout_width="@dimen/control_face_button_size"
- android:layout_height="@dimen/control_face_button_size"
- android:padding="8dp"
+ android:layout_width="@dimen/control_face_button_size_full"
+ android:layout_height="@dimen/control_face_button_size_half"
+ android:paddingLeft="@dimen/control_face_button_padding_to_full"
+ android:paddingRight="@dimen/control_face_button_padding_to_full"
+ android:paddingTop="@dimen/control_face_button_padding_to_center"
+ android:paddingBottom="@dimen/control_face_button_padding_to_outside"
app:drawableIdle="@drawable/control_button_cross"
app:drawablePressed="@drawable/control_button_cross_pressed"
app:layout_constraintLeft_toLeftOf="parent"
@@ 78,9 83,12 @@
<com.metallic.chiaki.touchcontrols.ButtonView
android:id="@+id/moonButtonView"
- android:layout_width="@dimen/control_face_button_size"
- android:layout_height="@dimen/control_face_button_size"
- android:padding="8dp"
+ android:layout_width="@dimen/control_face_button_size_half"
+ android:layout_height="@dimen/control_face_button_size_full"
+ android:paddingTop="@dimen/control_face_button_padding_to_full"
+ android:paddingBottom="@dimen/control_face_button_padding_to_full"
+ android:paddingLeft="@dimen/control_face_button_padding_to_center"
+ android:paddingRight="@dimen/control_face_button_padding_to_outside"
app:drawableIdle="@drawable/control_button_moon"
app:drawablePressed="@drawable/control_button_moon_pressed"
app:layout_constraintRight_toRightOf="parent"
@@ 89,9 97,12 @@
<com.metallic.chiaki.touchcontrols.ButtonView
android:id="@+id/pyramidButtonView"
- android:layout_width="@dimen/control_face_button_size"
- android:layout_height="@dimen/control_face_button_size"
- android:padding="8dp"
+ android:layout_width="@dimen/control_face_button_size_full"
+ android:layout_height="@dimen/control_face_button_size_half"
+ android:paddingLeft="@dimen/control_face_button_padding_to_full"
+ android:paddingRight="@dimen/control_face_button_padding_to_full"
+ android:paddingBottom="@dimen/control_face_button_padding_to_center"
+ android:paddingTop="@dimen/control_face_button_padding_to_outside"
app:drawableIdle="@drawable/control_button_pyramid"
app:drawablePressed="@drawable/control_button_pyramid_pressed"
app:layout_constraintLeft_toLeftOf="parent"
@@ 100,14 111,17 @@
<com.metallic.chiaki.touchcontrols.ButtonView
android:id="@+id/boxButtonView"
- android:layout_width="@dimen/control_face_button_size"
- android:layout_height="@dimen/control_face_button_size"
- android:padding="8dp"
+ android:layout_width="@dimen/control_face_button_size_half"
+ android:layout_height="@dimen/control_face_button_size_full"
+ android:paddingTop="@dimen/control_face_button_padding_to_full"
+ android:paddingBottom="@dimen/control_face_button_padding_to_full"
+ android:paddingRight="@dimen/control_face_button_padding_to_center"
+ android:paddingLeft="@dimen/control_face_button_padding_to_outside"
app:drawableIdle="@drawable/control_button_box"
app:drawablePressed="@drawable/control_button_box_pressed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"/>
+ app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ 116,7 130,6 @@
android:id="@+id/l3ButtonView"
android:layout_width="64dp"
android:layout_height="64dp"
- android:padding="8dp"
app:drawableIdle="@drawable/control_button_l3"
app:drawablePressed="@drawable/control_button_l3_pressed"
app:layout_constraintLeft_toLeftOf="parent"
@@ 126,7 139,6 @@
android:id="@+id/r3ButtonView"
android:layout_width="64dp"
android:layout_height="64dp"
- android:padding="8dp"
app:drawableIdle="@drawable/control_button_r3"
app:drawablePressed="@drawable/control_button_r3_pressed"
app:layout_constraintRight_toRightOf="parent"
@@ 137,7 149,6 @@
android:id="@+id/psButtonView"
android:layout_width="32dp"
android:layout_height="32dp"
- android:padding="8dp"
android:layout_marginBottom="8dp"
app:drawableIdle="@drawable/control_button_home"
app:drawablePressed="@drawable/control_button_home_pressed"
@@ 150,7 161,6 @@
android:id="@+id/touchpadButtonView"
android:layout_width="32dp"
android:layout_height="32dp"
- android:padding="8dp"
android:layout_marginTop="8dp"
app:drawableIdle="@drawable/control_button_touchpad"
app:drawablePressed="@drawable/control_button_touchpad_pressed"
@@ 162,7 172,6 @@
android:id="@+id/l2ButtonView"
android:layout_width="64dp"
android:layout_height="32dp"
- android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
app:drawableIdle="@drawable/control_button_l2"
@@ 174,7 183,6 @@
android:id="@+id/l1ButtonView"
android:layout_width="64dp"
android:layout_height="32dp"
- android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
app:drawableIdle="@drawable/control_button_l1"
@@ 186,7 194,6 @@
android:id="@+id/shareButtonView"
android:layout_width="32dp"
android:layout_height="32dp"
- android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
app:drawableIdle="@drawable/control_button_share"
@@ 198,7 205,6 @@
android:id="@+id/r2ButtonView"
android:layout_width="64dp"
android:layout_height="32dp"
- android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
app:drawableIdle="@drawable/control_button_r2"
@@ 210,7 216,6 @@
android:id="@+id/r1ButtonView"
android:layout_width="64dp"
android:layout_height="32dp"
- android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
app:drawableIdle="@drawable/control_button_r1"
@@ 222,7 227,6 @@
android:id="@+id/optionsButtonView"
android:layout_width="32dp"
android:layout_height="32dp"
- android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
app:drawableIdle="@drawable/control_button_options"
M android/app/src/main/res/values/dimens.xml => android/app/src/main/res/values/dimens.xml +5 -1
@@ 1,6 1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <dimen name="control_face_button_size">48dp</dimen>
+ <dimen name="control_face_button_size_half">88dp</dimen>
+ <dimen name="control_face_button_size_full">176dp</dimen>
+ <dimen name="control_face_button_padding_to_center">24dp</dimen>
+ <dimen name="control_face_button_padding_to_outside">16dp</dimen>
+ <dimen name="control_face_button_padding_to_full">64dp</dimen>
<dimen name="control_analog_stick_radius">48dp</dimen>
<dimen name="control_analog_stick_handle_radius">32dp</dimen>
<dimen name="floating_action_button_speed_dial_anim_offset">48dp</dimen>