mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-06-18 22:18:48 +02:00
![◱ PixelyIon](/assets/img/avatar_default.png)
This commit adds in the UI for Controller Configuration to Settings, in addition to introducing the storage and loading of aforementioned configurations to a file that can be saved/loaded at runtime. This commit also fixes updating of individual fields in Settings when changed from an external activity.
124 lines
5.1 KiB
Kotlin
124 lines
5.1 KiB
Kotlin
/*
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
* Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
|
*/
|
|
|
|
package emu.skyline.input.dialog
|
|
|
|
import android.animation.LayoutTransition
|
|
import android.os.Bundle
|
|
import android.os.VibrationEffect
|
|
import android.view.*
|
|
import android.view.animation.LinearInterpolator
|
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
|
import emu.skyline.R
|
|
import emu.skyline.adapter.ControllerGeneralItem
|
|
import emu.skyline.input.ControllerActivity
|
|
import kotlinx.android.synthetic.main.rumble_dialog.*
|
|
|
|
/**
|
|
* This dialog is used to set a device to pass on any rumble/force feedback data onto
|
|
*
|
|
* @param item This is used to hold the [ControllerGeneralItem] between instances
|
|
*/
|
|
class RumbleDialog(val item : ControllerGeneralItem) : BottomSheetDialogFragment() {
|
|
/**
|
|
* This inflates the layout of the dialog after initial view creation
|
|
*/
|
|
override fun onCreateView(inflater : LayoutInflater, container : ViewGroup?, savedInstanceState : Bundle?) : View? = inflater.inflate(R.layout.rumble_dialog, container)
|
|
|
|
/**
|
|
* This expands the bottom sheet so that it's fully visible
|
|
*/
|
|
override fun onStart() {
|
|
super.onStart()
|
|
|
|
val behavior = BottomSheetBehavior.from(requireView().parent as View)
|
|
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
|
}
|
|
|
|
/**
|
|
* This sets up all user interaction with this dialog
|
|
*/
|
|
override fun onActivityCreated(savedInstanceState : Bundle?) {
|
|
super.onActivityCreated(savedInstanceState)
|
|
|
|
if (context is ControllerActivity) {
|
|
val context = requireContext() as ControllerActivity
|
|
val controller = context.manager.controllers[context.id]!!
|
|
|
|
// Set up the reset button to clear out [Controller.rumbleDevice] when pressed
|
|
rumble_reset.setOnClickListener {
|
|
controller.rumbleDevice = null
|
|
item.update()
|
|
|
|
dismiss()
|
|
}
|
|
|
|
// Ensure that layout animations are proper
|
|
rumble_layout.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
|
|
rumble_controller.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
|
|
|
|
var deviceId : Int? = null // The ID of the currently selected device
|
|
|
|
dialog?.setOnKeyListener { _, _, event ->
|
|
// We want all input events from Joysticks and game pads
|
|
if (event.isFromSource(InputDevice.SOURCE_GAMEPAD) || event.isFromSource(InputDevice.SOURCE_JOYSTICK)) {
|
|
if (event.repeatCount == 0 && event.action == KeyEvent.ACTION_DOWN) {
|
|
val vibrator = event.device.vibrator
|
|
|
|
when {
|
|
// If the device doesn't match the currently selected device then update the UI accordingly and set [deviceId] to the current device
|
|
deviceId != event.deviceId -> {
|
|
rumble_controller_name.text = event.device.name
|
|
|
|
if (vibrator.hasVibrator()) {
|
|
rumble_controller_supported.text = getString(R.string.supported)
|
|
rumble_title.text = getString(R.string.confirm_button_again)
|
|
|
|
vibrator.vibrate(VibrationEffect.createOneShot(250, VibrationEffect.DEFAULT_AMPLITUDE))
|
|
} else {
|
|
rumble_controller_supported.text = getString(R.string.not_supported)
|
|
rumble_title.text = getString(R.string.press_any_button)
|
|
}
|
|
|
|
rumble_controller_icon.animate().apply {
|
|
interpolator = LinearInterpolator()
|
|
duration = 100
|
|
alpha(if (vibrator.hasVibrator()) 0.75f else 0.5f)
|
|
start()
|
|
}
|
|
|
|
deviceId = event.deviceId
|
|
}
|
|
|
|
// If the currently selected device has a vibrator then go ahead and select it
|
|
vibrator.hasVibrator() -> {
|
|
vibrator.vibrate(VibrationEffect.createOneShot(250, VibrationEffect.DEFAULT_AMPLITUDE))
|
|
|
|
controller.rumbleDevice = Pair(event.device.descriptor, event.device.name)
|
|
|
|
item.update()
|
|
|
|
dismiss()
|
|
}
|
|
|
|
// If the currently selected device doesn't have a vibrator then dismiss the dialog entirely
|
|
else -> {
|
|
dismiss()
|
|
}
|
|
}
|
|
}
|
|
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
} else {
|
|
dismiss()
|
|
}
|
|
}
|
|
}
|