mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 10:45:28 +03:00
Add Controller Setup Guide
A setup guide for controllers that goes through every available button/stick sequentially and opens up a corresponding dialog to map them.
This commit is contained in:
parent
e2cae74425
commit
5dea15632c
@ -35,6 +35,8 @@ class ControllerGeneralViewItem(private val controllerId : Int, val type : Gener
|
||||
}
|
||||
|
||||
GeneralType.RumbleDevice -> controller.rumbleDeviceName ?: context.getString(R.string.none)
|
||||
|
||||
GeneralType.SetupGuide -> context.getString(R.string.setup_guide_description)
|
||||
}
|
||||
super.bind(binding, position)
|
||||
|
||||
|
@ -31,6 +31,7 @@ enum class ControllerType(val stringRes : Int, val firstController : Boolean, va
|
||||
enum class GeneralType(val stringRes : Int, val compatibleControllers : Array<ControllerType>? = null) {
|
||||
PartnerJoyCon(R.string.partner_joycon, arrayOf(ControllerType.JoyConLeft)),
|
||||
RumbleDevice(R.string.rumble_device),
|
||||
SetupGuide(R.string.setup_guide),
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,14 +9,15 @@ import android.content.Intent
|
||||
import android.graphics.Canvas
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDialogFragment
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.marginTop
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import emu.skyline.R
|
||||
@ -55,6 +56,10 @@ class ControllerActivity : AppCompatActivity() {
|
||||
*/
|
||||
val axisMap = mutableMapOf<AxisId, ControllerStickViewItem>()
|
||||
|
||||
val stickItems = mutableListOf<ControllerStickViewItem>()
|
||||
|
||||
val buttonItems = mutableListOf<ControllerButtonViewItem>()
|
||||
|
||||
@Inject
|
||||
lateinit var settings : Settings
|
||||
|
||||
@ -108,17 +113,14 @@ class ControllerActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
wroteTitle = false
|
||||
if (controller.type.sticks.isNotEmpty())
|
||||
items.add(ControllerHeaderItem(getString(R.string.sticks)))
|
||||
|
||||
for (stick in controller.type.sticks) {
|
||||
if (!wroteTitle) {
|
||||
items.add(ControllerHeaderItem(getString(R.string.sticks)))
|
||||
wroteTitle = true
|
||||
}
|
||||
|
||||
val stickItem = ControllerStickViewItem(id, stick, onControllerStickClick)
|
||||
|
||||
items.add(stickItem)
|
||||
stickItems.add(stickItem)
|
||||
buttonMap[stick.button] = stickItem
|
||||
axisMap[stick.xAxis] = stickItem
|
||||
axisMap[stick.yAxis] = stickItem
|
||||
@ -132,32 +134,26 @@ class ControllerActivity : AppCompatActivity() {
|
||||
val buttonArrays = arrayOf(dpadButtons, faceButtons, shoulderTriggerButtons, shoulderRailButtons)
|
||||
|
||||
for (buttonArray in buttonArrays) {
|
||||
wroteTitle = false
|
||||
val filteredButtons = controller.type.buttons.filter { it in buttonArray.second }
|
||||
|
||||
for (button in controller.type.buttons.filter { it in buttonArray.second }) {
|
||||
if (!wroteTitle) {
|
||||
items.add(ControllerHeaderItem(getString(buttonArray.first)))
|
||||
wroteTitle = true
|
||||
}
|
||||
if (filteredButtons.isNotEmpty())
|
||||
items.add(ControllerHeaderItem(getString(buttonArray.first)))
|
||||
|
||||
for (button in filteredButtons) {
|
||||
val buttonItem = ControllerButtonViewItem(id, button, onControllerButtonClick)
|
||||
|
||||
items.add(buttonItem)
|
||||
buttonItems.add(buttonItem)
|
||||
buttonMap[button] = buttonItem
|
||||
}
|
||||
}
|
||||
|
||||
wroteTitle = false
|
||||
|
||||
items.add(ControllerHeaderItem(getString(R.string.misc_buttons))) // The menu button will always exist
|
||||
for (button in controller.type.buttons.filterNot { item -> buttonArrays.any { item in it.second } }.plus(ButtonId.Menu)) {
|
||||
if (!wroteTitle) {
|
||||
items.add(ControllerHeaderItem(getString(R.string.misc_buttons)))
|
||||
wroteTitle = true
|
||||
}
|
||||
|
||||
val buttonItem = ControllerButtonViewItem(id, button, onControllerButtonClick)
|
||||
|
||||
items.add(buttonItem)
|
||||
buttonItems.add(buttonItem)
|
||||
buttonMap[button] = buttonItem
|
||||
}
|
||||
} finally {
|
||||
@ -309,6 +305,18 @@ class ControllerActivity : AppCompatActivity() {
|
||||
GeneralType.RumbleDevice -> {
|
||||
RumbleDialog(item).show(supportFragmentManager, null)
|
||||
}
|
||||
|
||||
GeneralType.SetupGuide -> {
|
||||
var dialogFragment : BottomSheetDialogFragment? = null
|
||||
|
||||
for (buttonItem in buttonItems.reversed())
|
||||
dialogFragment = ButtonDialog(buttonItem, dialogFragment)
|
||||
|
||||
for (stickItem in stickItems.reversed())
|
||||
dialogFragment = StickDialog(stickItem, dialogFragment)
|
||||
|
||||
dialogFragment?.show(supportFragmentManager, null)
|
||||
}
|
||||
}
|
||||
Unit
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.*
|
||||
import android.view.animation.LinearInterpolator
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.fragment.app.commit
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import emu.skyline.R
|
||||
@ -25,7 +27,7 @@ import kotlin.math.abs
|
||||
*
|
||||
* @param item This is used to hold the [ControllerButtonViewItem] between instances
|
||||
*/
|
||||
class ButtonDialog @JvmOverloads constructor(private val item : ControllerButtonViewItem? = null) : BottomSheetDialogFragment() {
|
||||
class ButtonDialog @JvmOverloads constructor(private val item : ControllerButtonViewItem? = null, private val nextDialog : BottomSheetDialogFragment? = null) : BottomSheetDialogFragment() {
|
||||
private var _binding : ButtonDialogBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
@ -42,8 +44,22 @@ class ButtonDialog @JvmOverloads constructor(private val item : ControllerButton
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
val behavior = BottomSheetBehavior.from(requireView().parent as View)
|
||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
val parentView = requireView().parent as View
|
||||
if (parentView.layoutParams is CoordinatorLayout.LayoutParams) {
|
||||
val behavior = BottomSheetBehavior.from(parentView)
|
||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
}
|
||||
|
||||
private fun gotoNextOrDismiss() {
|
||||
if (nextDialog != null) {
|
||||
parentFragmentManager.commit {
|
||||
remove(this@ButtonDialog)
|
||||
add(nextDialog, null)
|
||||
}
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view : View, savedInstanceState : Bundle?) {
|
||||
@ -69,7 +85,7 @@ class ButtonDialog @JvmOverloads constructor(private val item : ControllerButton
|
||||
|
||||
item.update()
|
||||
|
||||
dismiss()
|
||||
gotoNextOrDismiss()
|
||||
}
|
||||
|
||||
// Ensure that layout animations are proper
|
||||
@ -131,7 +147,7 @@ class ButtonDialog @JvmOverloads constructor(private val item : ControllerButton
|
||||
|
||||
item.update()
|
||||
|
||||
dismiss()
|
||||
gotoNextOrDismiss()
|
||||
}
|
||||
|
||||
true
|
||||
@ -209,7 +225,7 @@ class ButtonDialog @JvmOverloads constructor(private val item : ControllerButton
|
||||
|
||||
item.update()
|
||||
|
||||
dismiss()
|
||||
gotoNextOrDismiss()
|
||||
}
|
||||
|
||||
axisHandler.postDelayed(axisRunnable!!, 1000)
|
||||
|
@ -12,6 +12,8 @@ import android.os.Looper
|
||||
import android.util.TypedValue
|
||||
import android.view.*
|
||||
import android.view.animation.LinearInterpolator
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.fragment.app.commit
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import emu.skyline.R
|
||||
@ -29,7 +31,7 @@ import kotlin.math.max
|
||||
*
|
||||
* @param item This is used to hold the [ControllerStickViewItem] between instances
|
||||
*/
|
||||
class StickDialog @JvmOverloads constructor(val item : ControllerStickViewItem? = null) : BottomSheetDialogFragment() {
|
||||
class StickDialog @JvmOverloads constructor(val item : ControllerStickViewItem? = null, private val nextDialog : BottomSheetDialogFragment? = null) : BottomSheetDialogFragment() {
|
||||
/**
|
||||
* This enumerates all of the stages this dialog can be in
|
||||
*/
|
||||
@ -82,6 +84,17 @@ class StickDialog @JvmOverloads constructor(val item : ControllerStickViewItem?
|
||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
|
||||
private fun gotoNextOrDismiss() {
|
||||
if (nextDialog != null) {
|
||||
parentFragmentManager.commit {
|
||||
remove(this@StickDialog)
|
||||
add(nextDialog, null)
|
||||
}
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function converts [dip] (Density Independent Pixels) to normal pixels
|
||||
*/
|
||||
@ -218,6 +231,8 @@ class StickDialog @JvmOverloads constructor(val item : ControllerStickViewItem?
|
||||
binding.stickNext.text = getString(if (ordinal + 1 == size) R.string.done else R.string.next)
|
||||
|
||||
updateAnimation()
|
||||
} else if (ordinal == size) {
|
||||
gotoNextOrDismiss()
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
@ -254,7 +269,7 @@ class StickDialog @JvmOverloads constructor(val item : ControllerStickViewItem?
|
||||
|
||||
item.update()
|
||||
|
||||
dismiss()
|
||||
gotoNextOrDismiss()
|
||||
}
|
||||
|
||||
// Ensure that layout animations are proper
|
||||
|
@ -68,7 +68,8 @@
|
||||
android:max="100"
|
||||
android:progress="25"
|
||||
android:secondaryProgressTintMode="screen"
|
||||
android:visibility="gone" />
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_reset"
|
||||
|
@ -161,4 +161,6 @@
|
||||
<!-- Misc -->
|
||||
<!--suppress AndroidLintUnusedResources -->
|
||||
<string name="expand_button_title" tools:override="true">Expand</string>
|
||||
<string name="setup_guide">Setup Guide</string>
|
||||
<string name="setup_guide_description">Sequentially map every stick and button</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user