mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-07-05 20:42:08 -07:00
Add Touch Button Haptics to Android
This commit is contained in:
parent
28f017d640
commit
cb5870f30d
9 changed files with 67 additions and 0 deletions
|
@ -83,6 +83,11 @@ class Preferences(context: Context)
|
|||
get() = sharedPreferences.getBoolean(motionEnabledKey, true)
|
||||
set(value) { sharedPreferences.edit().putBoolean(motionEnabledKey, value).apply() }
|
||||
|
||||
val buttonHapticEnabledKey get() = resources.getString(R.string.preferences_button_haptic_enabled_key)
|
||||
var buttonHapticEnabled
|
||||
get() = sharedPreferences.getBoolean(buttonHapticEnabledKey, true)
|
||||
set(value) { sharedPreferences.edit().putBoolean(buttonHapticEnabledKey, value).apply() }
|
||||
|
||||
val logVerboseKey get() = resources.getString(R.string.preferences_log_verbose_key)
|
||||
var logVerbose
|
||||
get() = sharedPreferences.getBoolean(logVerboseKey, false)
|
||||
|
|
|
@ -27,6 +27,7 @@ class DataStore(val preferences: Preferences): PreferenceDataStore()
|
|||
preferences.swapCrossMoonKey -> preferences.swapCrossMoon
|
||||
preferences.rumbleEnabledKey -> preferences.rumbleEnabled
|
||||
preferences.motionEnabledKey -> preferences.motionEnabled
|
||||
preferences.buttonHapticEnabledKey -> preferences.buttonHapticEnabled
|
||||
else -> defValue
|
||||
}
|
||||
|
||||
|
@ -38,6 +39,7 @@ class DataStore(val preferences: Preferences): PreferenceDataStore()
|
|||
preferences.swapCrossMoonKey -> preferences.swapCrossMoon = value
|
||||
preferences.rumbleEnabledKey -> preferences.rumbleEnabled = value
|
||||
preferences.motionEnabledKey -> preferences.motionEnabled = value
|
||||
preferences.buttonHapticEnabledKey -> preferences.buttonHapticEnabled = value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.metallic.chiaki.touchcontrols
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.metallic.chiaki.common.Preferences
|
||||
|
||||
class ButtonHaptics(val context: Context)
|
||||
{
|
||||
private val enabled = Preferences(context).buttonHapticEnabled
|
||||
|
||||
fun trigger(harder: Boolean = false)
|
||||
{
|
||||
if(!enabled)
|
||||
return
|
||||
val vibrator = context.getSystemService(AppCompatActivity.VIBRATOR_SERVICE) as Vibrator
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
vibrator.vibrate(
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
VibrationEffect.createPredefined(if(harder) VibrationEffect.EFFECT_CLICK else VibrationEffect.EFFECT_TICK)
|
||||
else
|
||||
VibrationEffect.createOneShot(10, if(harder) 200 else 100)
|
||||
)
|
||||
else
|
||||
vibrator.vibrate(10)
|
||||
}
|
||||
}
|
|
@ -16,6 +16,8 @@ class ButtonView @JvmOverloads constructor(
|
|||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
) : View(context, attrs, defStyleAttr)
|
||||
{
|
||||
private val haptics = ButtonHaptics(context)
|
||||
|
||||
var buttonPressed = false
|
||||
private set(value)
|
||||
{
|
||||
|
@ -23,6 +25,8 @@ class ButtonView @JvmOverloads constructor(
|
|||
field = value
|
||||
if(diff)
|
||||
{
|
||||
if(value)
|
||||
haptics.trigger()
|
||||
invalidate()
|
||||
buttonPressedCallback?.let { it(field) }
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ class DPadView @JvmOverloads constructor(
|
|||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
) : View(context, attrs, defStyleAttr)
|
||||
{
|
||||
private val haptics = ButtonHaptics(context)
|
||||
|
||||
enum class Direction {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
|
@ -113,6 +115,8 @@ class DPadView @JvmOverloads constructor(
|
|||
|
||||
if(state != newState)
|
||||
{
|
||||
if(newState != null)
|
||||
haptics.trigger()
|
||||
state = newState
|
||||
invalidate()
|
||||
stateChangeCallback?.let { it(state) }
|
||||
|
|
|
@ -26,6 +26,8 @@ class TouchpadView @JvmOverloads constructor(
|
|||
private const val BUTTON_HOLD_DELAY_MS = 500L
|
||||
}
|
||||
|
||||
private val haptics = ButtonHaptics(context)
|
||||
|
||||
private val drawableIdle: Drawable?
|
||||
private val drawablePressed: Drawable?
|
||||
|
||||
|
@ -49,8 +51,10 @@ class TouchpadView @JvmOverloads constructor(
|
|||
val startButtonHoldRunnable = Runnable {
|
||||
if(!moveInsignificant || buttonHeld)
|
||||
return@Runnable
|
||||
haptics.trigger(true)
|
||||
state.buttons = state.buttons or ControllerState.BUTTON_TOUCHPAD
|
||||
buttonHeld = true
|
||||
triggerStateChanged()
|
||||
}
|
||||
}
|
||||
private val pointerTouches = mutableMapOf<Int, Touch>()
|
||||
|
@ -105,6 +109,7 @@ class TouchpadView @JvmOverloads constructor(
|
|||
{
|
||||
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
state.startTouch(touchX(event, event.actionIndex), touchY(event, event.actionIndex))?.let {
|
||||
haptics.trigger()
|
||||
val touch = Touch(it, event.getX(event.actionIndex), event.getY(event.actionIndex))
|
||||
pointerTouches[event.getPointerId(event.actionIndex)] = touch
|
||||
if(!buttonHeld)
|
||||
|
|
9
android/app/src/main/res/drawable/ic_button_haptic.xml
Normal file
9
android/app/src/main/res/drawable/ic_button_haptic.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M9,11.24V7.5C9,6.12 10.12,5 11.5,5S14,6.12 14,7.5v3.74c1.21,-0.81 2,-2.18 2,-3.74C16,5.01 13.99,3 11.5,3S7,5.01 7,7.5C7,9.06 7.79,10.43 9,11.24zM18.84,15.87l-4.54,-2.26c-0.17,-0.07 -0.35,-0.11 -0.54,-0.11H13v-6C13,6.67 12.33,6 11.5,6S10,6.67 10,7.5v10.74c-3.6,-0.76 -3.54,-0.75 -3.67,-0.75c-0.31,0 -0.59,0.13 -0.79,0.33l-0.79,0.8l4.94,4.94C9.96,23.83 10.34,24 10.75,24h6.79c0.75,0 1.33,-0.55 1.44,-1.28l0.75,-5.27c0.01,-0.07 0.02,-0.14 0.02,-0.2C19.75,16.63 19.37,16.09 18.84,15.87z"/>
|
||||
</vector>
|
|
@ -92,6 +92,8 @@
|
|||
<string name="preferences_rumble_enabled_summary">Use phone vibration motor for rumble</string>
|
||||
<string name="preferences_motion_enabled_title">Motion</string>
|
||||
<string name="preferences_motion_enabled_summary">Use device\'s motion sensors for controller motion</string>
|
||||
<string name="preferences_button_haptic_enabled_title">Touch Haptics</string>
|
||||
<string name="preferences_button_haptic_enabled_summary">Use phone vibration motor for short haptic feedback on button touches</string>
|
||||
<string name="alert_message_delete_registered_host">Are you sure you want to delete the registered console %s with ID %s?</string>
|
||||
<string name="alert_message_delete_manual_host">Are you sure you want to delete the console entry for %s?</string>
|
||||
<string name="action_keep">Keep</string>
|
||||
|
@ -108,6 +110,7 @@
|
|||
<string name="preferences_touchpad_only_enabled_key">touchpad_only_enabled</string>
|
||||
<string name="preferences_rumble_enabled_key">rumble_enabled</string>
|
||||
<string name="preferences_motion_enabled_key">motion_enabled</string>
|
||||
<string name="preferences_button_haptic_enabled_key">button_haptic_enabled</string>
|
||||
<string name="preferences_log_verbose_key">log_verbose</string>
|
||||
<string name="preferences_import_settings_key">import_settings</string>
|
||||
<string name="preferences_export_settings_key">export_settings</string>
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
app:summary="@string/preferences_motion_enabled_summary"
|
||||
app:icon="@drawable/ic_motion" />
|
||||
|
||||
<SwitchPreference
|
||||
app:key="@string/preferences_button_haptic_enabled_key"
|
||||
app:title="@string/preferences_button_haptic_enabled_title"
|
||||
app:summary="@string/preferences_button_haptic_enabled_summary"
|
||||
app:icon="@drawable/ic_button_haptic" />
|
||||
|
||||
<SwitchPreference
|
||||
app:key="@string/preferences_log_verbose_key"
|
||||
app:title="@string/preferences_log_verbose_title"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue