summaryrefslogtreecommitdiff
path: root/Source/Android/app/src
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2025-05-14 18:14:38 +0200
committerJosJuice <josjuice@gmail.com>2025-06-07 10:20:20 +0200
commit1002f296918153c55dca674b3d70a54485f00306 (patch)
treee3ab47ee263fb29c865c74c6f97ba164b0dd0351 /Source/Android/app/src
parent0dd601577d20140b78fe2fddf0382d91ec97eeff (diff)
Android: Show input indicators in controller settings
Diffstat (limited to 'Source/Android/app/src')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingControlViewHolder.kt29
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarHorizontal.kt25
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarImpl.kt28
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarVertical.kt30
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/viewholder/InputMappingControlSettingViewHolder.kt22
-rw-r--r--Source/Android/app/src/main/res/layout-ldrtl/list_item_mapping.xml15
-rw-r--r--Source/Android/app/src/main/res/layout/list_item_advanced_mapping_control.xml39
-rw-r--r--Source/Android/app/src/main/res/layout/list_item_mapping.xml15
-rw-r--r--Source/Android/app/src/main/res/layout/view_control_state_bar_horizontal.xml20
-rw-r--r--Source/Android/app/src/main/res/layout/view_control_state_bar_vertical.xml20
10 files changed, 218 insertions, 25 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingControlViewHolder.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingControlViewHolder.kt
index 80771a6f4b..017bc1e642 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingControlViewHolder.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/AdvancedMappingControlViewHolder.kt
@@ -2,13 +2,15 @@
package org.dolphinemu.dolphinemu.features.input.ui
+import android.view.View
import androidx.lifecycle.Lifecycle
import org.dolphinemu.dolphinemu.databinding.ListItemAdvancedMappingControlBinding
import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface
import org.dolphinemu.dolphinemu.features.input.model.CoreDevice
import org.dolphinemu.dolphinemu.utils.LifecycleViewHolder
-import org.dolphinemu.dolphinemu.utils.Log
+import java.text.DecimalFormat
import java.util.function.Consumer
+import kotlin.math.abs
class AdvancedMappingControlViewHolder(
private val binding: ListItemAdvancedMappingControlBinding,
@@ -19,12 +21,16 @@ class AdvancedMappingControlViewHolder(
private lateinit var control: CoreDevice.Control
+ private var previousState = Float.POSITIVE_INFINITY
+
init {
binding.root.setOnClickListener { onClickCallback.accept(control.getName()) }
if (isInput) {
ControllerInterface.inputStateChanged.observe(this) {
updateInputValue()
}
+ } else {
+ binding.layoutState.visibility = View.GONE
}
}
@@ -41,8 +47,23 @@ class AdvancedMappingControlViewHolder(
throw IllegalStateException("AdvancedMappingControlViewHolder leak")
}
- // TODO
- Log.info("AdvancedMappingControlViewHolder: Value of " + control.getName() + " is " +
- control.getState())
+ var state = control.getState().toFloat()
+ if (abs(state - previousState) >= stateUpdateThreshold) {
+ previousState = state
+
+ // Don't print a minus sign for signed zeroes
+ if (state == -0.0f)
+ state = 0.0f
+
+ binding.textState.setText(stateFormat.format(state))
+ binding.controlStateBar.state = state
+ }
+ }
+
+ companion object {
+ private val stateFormat = DecimalFormat("#.####")
+
+ // For performance, require state to change by a certain threshold before we update the UI
+ private val stateUpdateThreshold = 0.00005f
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarHorizontal.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarHorizontal.kt
new file mode 100644
index 0000000000..a7a02921e8
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarHorizontal.kt
@@ -0,0 +1,25 @@
+package org.dolphinemu.dolphinemu.features.input.ui
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.widget.LinearLayout
+import org.dolphinemu.dolphinemu.databinding.ViewControlStateBarHorizontalBinding
+
+class ControlStateBarHorizontal @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : LinearLayout(context, attrs, defStyleAttr) {
+
+ private val binding =
+ ViewControlStateBarHorizontalBinding.inflate(LayoutInflater.from(context), this)
+
+ private val impl = ControlStateBarImpl(binding.viewFilled, binding.viewUnfilled)
+
+ var state: Float
+ get() = impl.state
+ set(value) {
+ impl.state = value
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarImpl.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarImpl.kt
new file mode 100644
index 0000000000..027448b0e3
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarImpl.kt
@@ -0,0 +1,28 @@
+package org.dolphinemu.dolphinemu.features.input.ui
+
+import android.view.View
+import android.widget.LinearLayout
+import androidx.core.math.MathUtils
+
+class ControlStateBarImpl(private val filledView: View, private val unfilledView: View) {
+ private var _state = 0.0f
+
+ var state: Float
+ get() = _state
+ set(value) {
+ val clampedState = MathUtils.clamp(value, 0.0f, 1.0f)
+ if (clampedState != _state) {
+ setLinearLayoutWeight(filledView, clampedState)
+ setLinearLayoutWeight(unfilledView, 1.0f - clampedState)
+ }
+ _state = clampedState
+ }
+
+ companion object {
+ private fun setLinearLayoutWeight(view: View, weight: Float) {
+ val layoutParams = view.layoutParams as LinearLayout.LayoutParams
+ layoutParams.weight = weight
+ view.layoutParams = layoutParams
+ }
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarVertical.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarVertical.kt
new file mode 100644
index 0000000000..cb7c37ad70
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ControlStateBarVertical.kt
@@ -0,0 +1,30 @@
+package org.dolphinemu.dolphinemu.features.input.ui
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.widget.LinearLayout
+import org.dolphinemu.dolphinemu.databinding.ViewControlStateBarVerticalBinding
+
+class ControlStateBarVertical @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : LinearLayout(context, attrs, defStyleAttr) {
+
+ init {
+ // Setting this in the XML file has no effect for some reason
+ orientation = VERTICAL
+ }
+
+ private val binding =
+ ViewControlStateBarVerticalBinding.inflate(LayoutInflater.from(context), this)
+
+ private val impl = ControlStateBarImpl(binding.viewFilled, binding.viewUnfilled)
+
+ var state: Float
+ get() = impl.state
+ set(value) {
+ impl.state = value
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/viewholder/InputMappingControlSettingViewHolder.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/viewholder/InputMappingControlSettingViewHolder.kt
index b6b30da53d..312fc9f6a5 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/viewholder/InputMappingControlSettingViewHolder.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/viewholder/InputMappingControlSettingViewHolder.kt
@@ -10,14 +10,17 @@ import org.dolphinemu.dolphinemu.features.input.model.view.InputMappingControlSe
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SettingViewHolder
-import org.dolphinemu.dolphinemu.utils.Log
+import kotlin.math.abs
class InputMappingControlSettingViewHolder(
private val binding: ListItemMappingBinding,
adapter: SettingsAdapter
) : SettingViewHolder(binding.getRoot(), adapter) {
+
lateinit var setting: InputMappingControlSetting
+ private var previousState = Float.POSITIVE_INFINITY
+
init {
ControllerInterface.inputStateChanged.observe(this) {
updateInputValue()
@@ -34,6 +37,10 @@ class InputMappingControlSettingViewHolder(
binding.textSettingDescription.text = setting.value
binding.buttonAdvancedSettings.setOnClickListener { clicked: View -> onLongClick(clicked) }
+ if (!setting.isInput) {
+ binding.controlStateBar.visibility = View.INVISIBLE
+ }
+
setStyle(binding.textSettingName, setting)
updateInputValue()
}
@@ -69,9 +76,16 @@ class InputMappingControlSettingViewHolder(
}
if (setting.isInput) {
- // TODO
- Log.info("InputMappingControlSettingViewHolder: Value of " + setting.name + " is " +
- setting.state)
+ val state = setting.state.toFloat()
+ if (abs(state - previousState) >= stateUpdateThreshold) {
+ previousState = state
+ binding.controlStateBar.state = state
+ }
}
}
+
+ companion object {
+ // For performance, require state to change by a certain threshold before we update the UI
+ private val stateUpdateThreshold = 0.01f
+ }
}
diff --git a/Source/Android/app/src/main/res/layout-ldrtl/list_item_mapping.xml b/Source/Android/app/src/main/res/layout-ldrtl/list_item_mapping.xml
index 94f219b4c1..e1a2118b36 100644
--- a/Source/Android/app/src/main/res/layout-ldrtl/list_item_mapping.xml
+++ b/Source/Android/app/src/main/res/layout-ldrtl/list_item_mapping.xml
@@ -22,7 +22,7 @@
android:layout_marginTop="@dimen/spacing_large"
android:textSize="16sp"
android:textAlignment="viewStart"
- android:layout_toStartOf="@+id/button_advanced_settings"
+ android:layout_toStartOf="@id/control_state_bar"
tools:text="Setting Name" />
<TextView
@@ -30,16 +30,23 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
- android:layout_alignStart="@+id/text_setting_name"
- android:layout_below="@+id/text_setting_name"
+ android:layout_alignStart="@id/text_setting_name"
+ android:layout_below="@id/text_setting_name"
android:layout_marginBottom="@dimen/spacing_large"
android:layout_marginEnd="@dimen/spacing_large"
android:layout_marginStart="@dimen/spacing_large"
android:layout_marginTop="@dimen/spacing_small"
- android:layout_toStartOf="@+id/button_advanced_settings"
+ android:layout_toStartOf="@id/control_state_bar"
android:textAlignment="viewStart"
tools:text="@string/overclock_enable_description" />
+ <org.dolphinemu.dolphinemu.features.input.ui.ControlStateBarVertical
+ android:id="@+id/control_state_bar"
+ android:layout_width="4dp"
+ android:layout_height="16dp"
+ android:layout_centerVertical="true"
+ android:layout_toStartOf="@id/button_advanced_settings" />
+
<Button
android:id="@+id/button_advanced_settings"
style="?attr/materialIconButtonStyle"
diff --git a/Source/Android/app/src/main/res/layout/list_item_advanced_mapping_control.xml b/Source/Android/app/src/main/res/layout/list_item_advanced_mapping_control.xml
index b5ea979a09..5f4515a53e 100644
--- a/Source/Android/app/src/main/res/layout/list_item_advanced_mapping_control.xml
+++ b/Source/Android/app/src/main/res/layout/list_item_advanced_mapping_control.xml
@@ -1,27 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:orientation="horizontal"
android:minHeight="54dp"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true">
<TextView
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
+ android:layout_weight="2"
style="@style/TextAppearance.MaterialComponents.Headline5"
tools:text="Button A"
- android:layout_alignParentEnd="true"
- android:layout_alignParentStart="true"
- android:layout_alignParentTop="true"
- android:layout_marginStart="@dimen/spacing_large"
- android:layout_marginEnd="@dimen/spacing_large"
- android:layout_marginTop="@dimen/spacing_large"
+ android:padding="@dimen/spacing_large"
android:id="@+id/text_name"
android:textAlignment="viewStart"
android:textSize="16sp" />
-</RelativeLayout>
+ <FrameLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:id="@+id/layout_state">
+
+ <org.dolphinemu.dolphinemu.features.input.ui.ControlStateBarHorizontal
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/control_state_bar" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|center_vertical"
+ style="@style/TextAppearance.MaterialComponents.Headline5"
+ tools:text="0.1234"
+ android:padding="@dimen/spacing_large"
+ android:id="@+id/text_state"
+ android:textAlignment="center"
+ android:textSize="16sp" />
+
+ </FrameLayout>
+
+</LinearLayout>
diff --git a/Source/Android/app/src/main/res/layout/list_item_mapping.xml b/Source/Android/app/src/main/res/layout/list_item_mapping.xml
index de504d3187..30b9e56fb1 100644
--- a/Source/Android/app/src/main/res/layout/list_item_mapping.xml
+++ b/Source/Android/app/src/main/res/layout/list_item_mapping.xml
@@ -22,7 +22,7 @@
android:layout_marginTop="@dimen/spacing_large"
android:textSize="16sp"
android:textAlignment="viewStart"
- android:layout_toStartOf="@+id/button_advanced_settings"
+ android:layout_toStartOf="@id/control_state_bar"
tools:text="Setting Name" />
<TextView
@@ -30,16 +30,23 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
- android:layout_alignStart="@+id/text_setting_name"
- android:layout_below="@+id/text_setting_name"
+ android:layout_alignStart="@id/text_setting_name"
+ android:layout_below="@id/text_setting_name"
android:layout_marginBottom="@dimen/spacing_large"
android:layout_marginEnd="@dimen/spacing_large"
android:layout_marginStart="@dimen/spacing_large"
android:layout_marginTop="@dimen/spacing_small"
- android:layout_toStartOf="@+id/button_advanced_settings"
+ android:layout_toStartOf="@id/control_state_bar"
android:textAlignment="viewStart"
tools:text="@string/overclock_enable_description" />
+ <org.dolphinemu.dolphinemu.features.input.ui.ControlStateBarVertical
+ android:id="@+id/control_state_bar"
+ android:layout_width="4dp"
+ android:layout_height="16dp"
+ android:layout_centerVertical="true"
+ android:layout_toStartOf="@id/button_advanced_settings" />
+
<Button
android:id="@+id/button_advanced_settings"
style="?attr/materialIconButtonStyle"
diff --git a/Source/Android/app/src/main/res/layout/view_control_state_bar_horizontal.xml b/Source/Android/app/src/main/res/layout/view_control_state_bar_horizontal.xml
new file mode 100644
index 0000000000..bf252725ff
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/view_control_state_bar_horizontal.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:parentTag="LinearLayout">
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:id="@+id/view_filled"
+ android:background="@color/dolphin_errorContainer" />
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:id="@+id/view_unfilled" />
+
+</merge>
diff --git a/Source/Android/app/src/main/res/layout/view_control_state_bar_vertical.xml b/Source/Android/app/src/main/res/layout/view_control_state_bar_vertical.xml
new file mode 100644
index 0000000000..2063df22b4
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/view_control_state_bar_vertical.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:parentTag="LinearLayout">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:id="@+id/view_unfilled" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0"
+ android:id="@+id/view_filled"
+ android:background="@color/dolphin_error" />
+
+</merge>