mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-26 10:55:28 +03:00
Implement toggle mode for OSC buttons
When toggle mode is enabled, the button will toggle between the `Pressed` and `Released` state when it's pressed. Without toggle mode: ACTION_DOWN -> Pressed ACTION_UP -> Released ACTION_DOWN -> Pressed ACTION_UP -> Released With toggle mode: ACTION_DOWN -> Pressed ACTION_UP -> No event ACTION_DOWN -> No event ACTION_UP -> Released
This commit is contained in:
parent
78252fbcbd
commit
560fcd9442
@ -14,6 +14,12 @@ interface ConfigurableButton {
|
|||||||
val buttonId : ButtonId
|
val buttonId : ButtonId
|
||||||
val config : OnScreenConfiguration
|
val config : OnScreenConfiguration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this button supports toggle mode
|
||||||
|
* Usually true for buttons and false for sticks
|
||||||
|
*/
|
||||||
|
fun supportsToggleMode() : Boolean = true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a button move session
|
* Starts a button move session
|
||||||
* @param x The x coordinate of the initial touch
|
* @param x The x coordinate of the initial touch
|
||||||
|
@ -107,6 +107,7 @@ abstract class OnScreenButton(
|
|||||||
var partnerPointerId = -1
|
var partnerPointerId = -1
|
||||||
|
|
||||||
var isPressed = false
|
var isPressed = false
|
||||||
|
var isToggled = false
|
||||||
|
|
||||||
var hapticFeedback = false
|
var hapticFeedback = false
|
||||||
|
|
||||||
@ -167,12 +168,26 @@ abstract class OnScreenButton(
|
|||||||
|
|
||||||
abstract fun isTouched(x : Float, y : Float) : Boolean
|
abstract fun isTouched(x : Float, y : Float) : Boolean
|
||||||
|
|
||||||
open fun onFingerDown(x : Float, y : Float) {
|
/**
|
||||||
isPressed = true
|
* @return Whether button events should be sent to guest
|
||||||
|
*/
|
||||||
|
open fun onFingerDown(x : Float, y : Float) : Boolean {
|
||||||
|
if (!config.toggleMode || !isToggled)
|
||||||
|
isPressed = true
|
||||||
|
|
||||||
|
isToggled = !isToggled
|
||||||
|
|
||||||
|
return !config.toggleMode || isToggled
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun onFingerUp(x : Float, y : Float) {
|
/**
|
||||||
isPressed = false
|
* @return Whether button events should be sent to guest
|
||||||
|
*/
|
||||||
|
open fun onFingerUp(x : Float, y : Float) : Boolean {
|
||||||
|
if (!config.toggleMode || !isToggled)
|
||||||
|
isPressed = false
|
||||||
|
|
||||||
|
return !isPressed
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadConfigValues() {
|
fun loadConfigValues() {
|
||||||
@ -264,6 +279,7 @@ abstract class OnScreenButton(
|
|||||||
|
|
||||||
override fun resetConfig() {
|
override fun resetConfig() {
|
||||||
config.enabled = defaultEnabled
|
config.enabled = defaultEnabled
|
||||||
|
config.toggleMode = OnScreenConfiguration.DefaultToggleMode
|
||||||
config.alpha = OnScreenConfiguration.DefaultAlpha
|
config.alpha = OnScreenConfiguration.DefaultAlpha
|
||||||
config.textColor = OnScreenConfiguration.DefaultTextColor
|
config.textColor = OnScreenConfiguration.DefaultTextColor
|
||||||
config.backgroundColor = OnScreenConfiguration.DefaultBackgroundColor
|
config.backgroundColor = OnScreenConfiguration.DefaultBackgroundColor
|
||||||
|
@ -16,6 +16,8 @@ interface OnScreenConfiguration {
|
|||||||
const val GroupEnabled = 1
|
const val GroupEnabled = 1
|
||||||
const val GroupIndeterminate = 2
|
const val GroupIndeterminate = 2
|
||||||
|
|
||||||
|
const val DefaultToggleMode = false
|
||||||
|
|
||||||
const val MinAlpha = 0
|
const val MinAlpha = 0
|
||||||
const val MaxAlpha = 255
|
const val MaxAlpha = 255
|
||||||
const val DefaultAlpha = 128
|
const val DefaultAlpha = 128
|
||||||
@ -35,6 +37,13 @@ interface OnScreenConfiguration {
|
|||||||
*/
|
*/
|
||||||
val groupEnabled get() = if (enabled) GroupEnabled else GroupDisabled
|
val groupEnabled get() = if (enabled) GroupEnabled else GroupDisabled
|
||||||
|
|
||||||
|
var toggleMode : Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The toggle mode of group of buttons, returns an integer that can be used to set the state of a MaterialCheckBox
|
||||||
|
*/
|
||||||
|
val groupToggleMode get() = if (toggleMode) GroupEnabled else GroupDisabled
|
||||||
|
|
||||||
var alpha : Int
|
var alpha : Int
|
||||||
var textColor : Int
|
var textColor : Int
|
||||||
var backgroundColor : Int
|
var backgroundColor : Int
|
||||||
@ -48,6 +57,7 @@ class OnScreenConfigurationImpl(private val context : Context, private val butto
|
|||||||
private inline fun <reified T> config(default : T, prefix : String = "${buttonId.name}_") = sharedPreferences(context, default, prefix, "controller_config")
|
private inline fun <reified T> config(default : T, prefix : String = "${buttonId.name}_") = sharedPreferences(context, default, prefix, "controller_config")
|
||||||
|
|
||||||
override var enabled by config(defaultEnabled)
|
override var enabled by config(defaultEnabled)
|
||||||
|
override var toggleMode by config(OnScreenConfiguration.DefaultToggleMode)
|
||||||
|
|
||||||
override var alpha by config(OnScreenConfiguration.DefaultAlpha)
|
override var alpha by config(OnScreenConfiguration.DefaultAlpha)
|
||||||
override var textColor by config(OnScreenConfiguration.DefaultTextColor)
|
override var textColor by config(OnScreenConfiguration.DefaultTextColor)
|
||||||
|
@ -122,13 +122,13 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
|
|||||||
MotionEvent.ACTION_POINTER_UP -> {
|
MotionEvent.ACTION_POINTER_UP -> {
|
||||||
if (pointerId == button.touchPointerId) {
|
if (pointerId == button.touchPointerId) {
|
||||||
button.touchPointerId = -1
|
button.touchPointerId = -1
|
||||||
button.onFingerUp(x, y)
|
if (button.onFingerUp(x, y))
|
||||||
onButtonStateChangedListener?.invoke(button.buttonId, ButtonState.Released)
|
onButtonStateChangedListener?.invoke(button.buttonId, ButtonState.Released)
|
||||||
handled = true
|
handled = true
|
||||||
} else if (pointerId == button.partnerPointerId) {
|
} else if (pointerId == button.partnerPointerId) {
|
||||||
button.partnerPointerId = -1
|
button.partnerPointerId = -1
|
||||||
button.onFingerUp(x, y)
|
if (button.onFingerUp(x, y))
|
||||||
onButtonStateChangedListener?.invoke(button.buttonId, ButtonState.Released)
|
onButtonStateChangedListener?.invoke(button.buttonId, ButtonState.Released)
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,10 +137,10 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
|
|||||||
MotionEvent.ACTION_POINTER_DOWN -> {
|
MotionEvent.ACTION_POINTER_DOWN -> {
|
||||||
if (button.config.enabled && button.isTouched(x, y)) {
|
if (button.config.enabled && button.isTouched(x, y)) {
|
||||||
button.touchPointerId = pointerId
|
button.touchPointerId = pointerId
|
||||||
button.onFingerDown(x, y)
|
if (button.onFingerDown(x, y))
|
||||||
|
onButtonStateChangedListener?.invoke(button.buttonId, ButtonState.Pressed)
|
||||||
if (hapticFeedback) vibrator.vibrate(effectClick)
|
if (hapticFeedback) vibrator.vibrate(effectClick)
|
||||||
performClick()
|
performClick()
|
||||||
onButtonStateChangedListener?.invoke(button.buttonId, ButtonState.Pressed)
|
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,9 +153,9 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
|
|||||||
for (otherButton in buttonPair) {
|
for (otherButton in buttonPair) {
|
||||||
if (otherButton != button && otherButton.config.enabled && otherButton.isTouched(event.getX(fingerId), event.getY(fingerId))) {
|
if (otherButton != button && otherButton.config.enabled && otherButton.isTouched(event.getX(fingerId), event.getY(fingerId))) {
|
||||||
otherButton.partnerPointerId = fingerId
|
otherButton.partnerPointerId = fingerId
|
||||||
otherButton.onFingerDown(x, y)
|
if (otherButton.onFingerDown(x, y))
|
||||||
|
onButtonStateChangedListener?.invoke(otherButton.buttonId, ButtonState.Pressed)
|
||||||
performClick()
|
performClick()
|
||||||
onButtonStateChangedListener?.invoke(otherButton.buttonId, ButtonState.Pressed)
|
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,6 +318,11 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
|
|||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setButtonToggleMode(toggleMode : Boolean) {
|
||||||
|
editInfo.editButton.config.toggleMode = toggleMode
|
||||||
|
invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
fun setButtonScale(@IntRange(from = 0, to = 100) scale : Int) {
|
fun setButtonScale(@IntRange(from = 0, to = 100) scale : Int) {
|
||||||
fun toScaleRange(value : Int) : Float = (value / 100f) * (OnScreenConfiguration.MaxScale - OnScreenConfiguration.MinScale) + OnScreenConfiguration.MinScale
|
fun toScaleRange(value : Int) : Float = (value / 100f) * (OnScreenConfiguration.MaxScale - OnScreenConfiguration.MinScale) + OnScreenConfiguration.MinScale
|
||||||
|
|
||||||
@ -398,6 +403,21 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
|
|||||||
return OnScreenConfiguration.GroupIndeterminate
|
return OnScreenConfiguration.GroupIndeterminate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override var toggleMode : Boolean
|
||||||
|
get() = controls.allButtons.all { it.supportsToggleMode() == it.config.toggleMode }
|
||||||
|
set(value) {
|
||||||
|
controls.allButtons.forEach { if (it.supportsToggleMode()) it.config.toggleMode = value }
|
||||||
|
}
|
||||||
|
|
||||||
|
override val groupToggleMode : Int
|
||||||
|
get() {
|
||||||
|
if (controls.allButtons.all { !it.supportsToggleMode() || it.config.toggleMode })
|
||||||
|
return OnScreenConfiguration.GroupEnabled
|
||||||
|
if (controls.allButtons.all { !it.supportsToggleMode() || !it.config.toggleMode })
|
||||||
|
return OnScreenConfiguration.GroupDisabled
|
||||||
|
return OnScreenConfiguration.GroupIndeterminate
|
||||||
|
}
|
||||||
|
|
||||||
override var alpha : Int
|
override var alpha : Int
|
||||||
get() = controls.allButtons.sumOf { it.config.alpha } / controls.allButtons.size
|
get() = controls.allButtons.sumOf { it.config.alpha } / controls.allButtons.size
|
||||||
set(value) {
|
set(value) {
|
||||||
|
@ -123,6 +123,9 @@ class OnScreenEditActivity : AppCompatActivity() {
|
|||||||
binding.enabledCheckbox.setOnClickListener { _ ->
|
binding.enabledCheckbox.setOnClickListener { _ ->
|
||||||
binding.onScreenControllerView.setButtonEnabled(binding.enabledCheckbox.isChecked)
|
binding.onScreenControllerView.setButtonEnabled(binding.enabledCheckbox.isChecked)
|
||||||
}
|
}
|
||||||
|
binding.toggleModeCheckbox.setOnClickListener { _ ->
|
||||||
|
binding.onScreenControllerView.setButtonToggleMode(binding.toggleModeCheckbox.isChecked)
|
||||||
|
}
|
||||||
|
|
||||||
binding.moveUpButton.setOnClickListener { binding.onScreenControllerView.moveButtonUp() }
|
binding.moveUpButton.setOnClickListener { binding.onScreenControllerView.moveButtonUp() }
|
||||||
binding.moveDownButton.setOnClickListener { binding.onScreenControllerView.moveButtonDown() }
|
binding.moveDownButton.setOnClickListener { binding.onScreenControllerView.moveButtonDown() }
|
||||||
@ -194,6 +197,8 @@ class OnScreenEditActivity : AppCompatActivity() {
|
|||||||
*/
|
*/
|
||||||
private fun updateActiveButtonDisplayInfo(button : ConfigurableButton) {
|
private fun updateActiveButtonDisplayInfo(button : ConfigurableButton) {
|
||||||
binding.enabledCheckbox.checkedState = button.config.groupEnabled
|
binding.enabledCheckbox.checkedState = button.config.groupEnabled
|
||||||
|
binding.toggleModeCheckbox.isEnabled = button.supportsToggleMode()
|
||||||
|
binding.toggleModeCheckbox.checkedState = button.config.groupToggleMode
|
||||||
currentButtonName = button.buttonId.short ?: ""
|
currentButtonName = button.buttonId.short ?: ""
|
||||||
binding.currentButton.text = getString(R.string.osc_current_button, currentButtonName)
|
binding.currentButton.text = getString(R.string.osc_current_button, currentButtonName)
|
||||||
binding.scaleSlider.slider.value = (button.config.scale - OnScreenConfiguration.MinScale) / (OnScreenConfiguration.MaxScale - OnScreenConfiguration.MinScale) * 100f
|
binding.scaleSlider.slider.value = (button.config.scale - OnScreenConfiguration.MinScale) / (OnScreenConfiguration.MaxScale - OnScreenConfiguration.MinScale) * 100f
|
||||||
|
@ -68,6 +68,8 @@ class JoystickButton(
|
|||||||
var shortDoubleTapped = false
|
var shortDoubleTapped = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
override fun supportsToggleMode() : Boolean = false
|
||||||
|
|
||||||
override fun renderCenteredText(canvas : Canvas, text : String, size : Float, x : Float, y : Float, alpha : Int) = Unit
|
override fun renderCenteredText(canvas : Canvas, text : String, size : Float, x : Float, y : Float, alpha : Int) = Unit
|
||||||
|
|
||||||
override fun render(canvas : Canvas) {
|
override fun render(canvas : Canvas) {
|
||||||
@ -78,7 +80,7 @@ class JoystickButton(
|
|||||||
innerButton.render(canvas)
|
innerButton.render(canvas)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFingerDown(x : Float, y : Float) {
|
override fun onFingerDown(x : Float, y : Float) : Boolean {
|
||||||
val relativeX = x / width
|
val relativeX = x / width
|
||||||
val relativeY = (y - heightDiff) / adjustedHeight
|
val relativeY = (y - heightDiff) / adjustedHeight
|
||||||
if (recenterSticks) {
|
if (recenterSticks) {
|
||||||
@ -99,9 +101,11 @@ class JoystickButton(
|
|||||||
isPressed = true
|
isPressed = true
|
||||||
}
|
}
|
||||||
fingerDownTime = currentTime
|
fingerDownTime = currentTime
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFingerUp(x : Float, y : Float) {
|
override fun onFingerUp(x : Float, y : Float) : Boolean {
|
||||||
loadConfigValues()
|
loadConfigValues()
|
||||||
innerButton.relativeX = relativeX
|
innerButton.relativeX = relativeX
|
||||||
innerButton.relativeY = relativeY
|
innerButton.relativeY = relativeY
|
||||||
@ -109,6 +113,8 @@ class JoystickButton(
|
|||||||
fingerUpTime = SystemClock.elapsedRealtime()
|
fingerUpTime = SystemClock.elapsedRealtime()
|
||||||
shortDoubleTapped = false
|
shortDoubleTapped = false
|
||||||
isPressed = false
|
isPressed = false
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onFingerMoved(x : Float, y : Float, manualMove : Boolean = true) : PointF {
|
fun onFingerMoved(x : Float, y : Float, manualMove : Boolean = true) : PointF {
|
||||||
|
@ -137,7 +137,6 @@
|
|||||||
android:minHeight="0dp"
|
android:minHeight="0dp"
|
||||||
android:paddingVertical="8dp"
|
android:paddingVertical="8dp"
|
||||||
android:text="@string/osc_toggle_mode"
|
android:text="@string/osc_toggle_mode"
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/enabled_checkbox"
|
app:layout_constraintStart_toStartOf="@+id/enabled_checkbox"
|
||||||
app:layout_constraintTop_toBottomOf="@id/enabled_checkbox"
|
app:layout_constraintTop_toBottomOf="@id/enabled_checkbox"
|
||||||
tools:ignore="TouchTargetSizeCheck" />
|
tools:ignore="TouchTargetSizeCheck" />
|
||||||
|
Loading…
Reference in New Issue
Block a user