mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 13:51:49 +01:00
Add on screen controls layout edit settings
This commit is contained in:
parent
30cf1c4b6a
commit
5c4aa95da6
@ -61,7 +61,9 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name="emu.skyline.input.onscreen.OnScreenEditActivity"
|
||||
android:exported="true">
|
||||
android:exported="true"
|
||||
android:screenOrientation="landscape"
|
||||
tools:ignore="LockedOrientationActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="emu.skyline.input.ControllerActivity" />
|
||||
|
@ -231,7 +231,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
game_view.setOnTouchListener(this)
|
||||
|
||||
// Hide on screen controls when first controller is not set
|
||||
on_screen_controller_view.isInvisible = InputManager.controllers[0]!!.type == ControllerType.None
|
||||
on_screen_controller_view.isInvisible = !InputManager.controllers[0]!!.type.firstController || !sharedPreferences.getBoolean("on_screen_control", false)
|
||||
on_screen_controller_view.setOnButtonStateChangedListener(::onButtonStateChanged)
|
||||
on_screen_controller_view.setOnStickStateChangedListener(::onStickStateChanged)
|
||||
|
||||
|
@ -33,6 +33,7 @@ import emu.skyline.adapter.LayoutType
|
||||
import emu.skyline.data.AppItem
|
||||
import emu.skyline.data.BaseElement
|
||||
import emu.skyline.data.BaseHeader
|
||||
import emu.skyline.data.ElementType
|
||||
import emu.skyline.loader.LoaderResult
|
||||
import emu.skyline.loader.RomFile
|
||||
import emu.skyline.loader.RomFormat
|
||||
@ -111,7 +112,7 @@ class MainActivity : AppCompatActivity() {
|
||||
if (loadFromFile) {
|
||||
try {
|
||||
loadSerializedList<BaseElement>(romsFile).forEach {
|
||||
if (it is BaseHeader)
|
||||
if (it.elementType == ElementType.Header && it is BaseHeader)
|
||||
adapter.addItem(HeaderViewItem(it.title))
|
||||
else if (it is AppItem)
|
||||
adapter.addItem(it.toViewItem())
|
||||
|
@ -12,4 +12,4 @@ enum class ElementType {
|
||||
Item
|
||||
}
|
||||
|
||||
abstract class BaseElement(elementType : ElementType) : Serializable
|
||||
abstract class BaseElement(val elementType : ElementType) : Serializable
|
||||
|
@ -9,6 +9,7 @@ import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import emu.skyline.R
|
||||
@ -46,6 +47,8 @@ class ControllerActivity : AppCompatActivity() {
|
||||
*/
|
||||
val axisMap = mutableMapOf<AxisId, ControllerStickViewItem>()
|
||||
|
||||
private val sharedPrefs by lazy { PreferenceManager.getDefaultSharedPreferences(this) }
|
||||
|
||||
/**
|
||||
* This function updates the [adapter] based on information from [InputManager]
|
||||
*/
|
||||
@ -62,8 +65,9 @@ class ControllerActivity : AppCompatActivity() {
|
||||
if (id == 0 && controller.type.firstController) {
|
||||
adapter.addItem(HeaderViewItem(getString(R.string.osc)))
|
||||
|
||||
adapter.addItem(ControllerCheckBoxViewItem(getString(R.string.osc_enable), getString(R.string.osc_not_shown), false) { item, position ->
|
||||
adapter.addItem(ControllerCheckBoxViewItem(getString(R.string.osc_enable), getString(R.string.osc_not_shown), sharedPrefs.getBoolean("on_screen_control", false)) { item, position ->
|
||||
item.summary = getString(if (item.checked) R.string.osc_shown else R.string.osc_not_shown)
|
||||
sharedPrefs.edit().putBoolean("on_screen_control", item.checked).apply()
|
||||
adapter.notifyItemChanged(position)
|
||||
})
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package emu.skyline.input
|
||||
|
||||
import emu.skyline.R.string
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
@ -13,22 +14,22 @@ import kotlin.math.abs
|
||||
* This enumerates all of the buttons that the emulator recognizes
|
||||
*/
|
||||
enum class ButtonId(val short : String? = null, val long : Int? = null) {
|
||||
A("A", emu.skyline.R.string.a_button),
|
||||
B("B", emu.skyline.R.string.b_button),
|
||||
X("X", emu.skyline.R.string.x_button),
|
||||
Y("Y", emu.skyline.R.string.y_button),
|
||||
LeftStick("L"),
|
||||
RightStick("R"),
|
||||
L("L", emu.skyline.R.string.left_shoulder),
|
||||
R("R", emu.skyline.R.string.right_shoulder),
|
||||
ZL("ZL", emu.skyline.R.string.left_trigger),
|
||||
ZR("ZR", emu.skyline.R.string.right_trigger),
|
||||
Plus("+", emu.skyline.R.string.plus_button),
|
||||
Minus("-", emu.skyline.R.string.minus_button),
|
||||
DpadLeft("◀", emu.skyline.R.string.left),
|
||||
DpadUp("▲", emu.skyline.R.string.up),
|
||||
DpadRight("▶", emu.skyline.R.string.right),
|
||||
DpadDown("▼", emu.skyline.R.string.down),
|
||||
A("A", string.a_button),
|
||||
B("B", string.b_button),
|
||||
X("X", string.x_button),
|
||||
Y("Y", string.y_button),
|
||||
LeftStick("L", string.left_stick),
|
||||
RightStick("R", string.right_stick),
|
||||
L("L", string.left_shoulder),
|
||||
R("R", string.right_shoulder),
|
||||
ZL("ZL", string.left_trigger),
|
||||
ZR("ZR", string.right_trigger),
|
||||
Plus("+", string.plus_button),
|
||||
Minus("-", string.minus_button),
|
||||
DpadLeft("◀", string.left),
|
||||
DpadUp("▲", string.up),
|
||||
DpadRight("▶", string.right),
|
||||
DpadDown("▼", string.down),
|
||||
LeftStickLeft,
|
||||
LeftStickUp,
|
||||
LeftStickRight,
|
||||
@ -37,11 +38,11 @@ enum class ButtonId(val short : String? = null, val long : Int? = null) {
|
||||
RightStickUp,
|
||||
RightStickRight,
|
||||
RightStickDown,
|
||||
LeftSL("SL", emu.skyline.R.string.left_shoulder),
|
||||
LeftSR("SR", emu.skyline.R.string.right_shoulder),
|
||||
RightSL("SL", emu.skyline.R.string.left_shoulder),
|
||||
RightSR("SR", emu.skyline.R.string.right_shoulder),
|
||||
Menu("⌂", emu.skyline.R.string.emu_menu_button);
|
||||
LeftSL("SL", string.left_shoulder),
|
||||
LeftSR("SR", string.right_shoulder),
|
||||
RightSL("SL", string.left_shoulder),
|
||||
RightSR("SR", string.right_shoulder),
|
||||
Menu("⌂", string.emu_menu_button);
|
||||
|
||||
/**
|
||||
* This returns the value as setting the [ordinal]-th bit in a [Long]
|
||||
|
@ -11,6 +11,7 @@ import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
interface ControllerConfiguration {
|
||||
var enabled : Boolean
|
||||
var globalScale : Float
|
||||
var relativeX : Float
|
||||
var relativeY : Float
|
||||
@ -20,6 +21,7 @@ class ControllerConfigurationDummy(
|
||||
defaultRelativeX : Float,
|
||||
defaultRelativeY : Float
|
||||
) : ControllerConfiguration {
|
||||
override var enabled = true
|
||||
override var globalScale = 1f
|
||||
override var relativeX = defaultRelativeX
|
||||
override var relativeY = defaultRelativeY
|
||||
@ -31,10 +33,10 @@ class ControllerConfigurationImpl(
|
||||
defaultRelativeX : Float,
|
||||
defaultRelativeY : Float
|
||||
) : ControllerConfiguration {
|
||||
override var globalScale by ControllerPrefs(context, "on_screen_controller_", Float::class.java, 1f)
|
||||
|
||||
private inline fun <reified T> config(default : T) = ControllerPrefs(context, "${buttonId.name}_", T::class.java, default)
|
||||
|
||||
override var enabled by config(true)
|
||||
override var globalScale by ControllerPrefs(context, "on_screen_controller_", Float::class.java, 1f)
|
||||
override var relativeX by config(defaultRelativeX)
|
||||
override var relativeY by config(defaultRelativeY)
|
||||
}
|
||||
@ -50,8 +52,8 @@ private class ControllerPrefs<T>(context : Context, private val prefix : String,
|
||||
override fun setValue(thisRef : Any, property : KProperty<*>, value : T) {
|
||||
prefs.edit().apply {
|
||||
when (clazz) {
|
||||
Float::class.java,
|
||||
java.lang.Float::class.java -> putFloat(prefix + property.name, value as Float)
|
||||
Float::class.java, java.lang.Float::class.java -> putFloat(prefix + property.name, value as Float)
|
||||
Boolean::class.java, java.lang.Boolean::class.java -> putBoolean(prefix + property.name, value as Boolean)
|
||||
else -> error("Unsupported type $clazz ${Float::class.java}")
|
||||
}
|
||||
}.apply()
|
||||
@ -59,10 +61,11 @@ private class ControllerPrefs<T>(context : Context, private val prefix : String,
|
||||
|
||||
override fun getValue(thisRef : Any, property : KProperty<*>) : T =
|
||||
prefs.let {
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY")
|
||||
when (clazz) {
|
||||
Float::class.java,
|
||||
java.lang.Float::class.java -> it.getFloat(prefix + property.name, default as Float)
|
||||
else -> error("Unsupported type $clazz ${Float::class.java}")
|
||||
Float::class.java, java.lang.Float::class.java -> it.getFloat(prefix + property.name, default as Float)
|
||||
Boolean::class.java, java.lang.Boolean::class.java -> it.getBoolean(prefix + property.name, default as Boolean)
|
||||
else -> error("Unsupported type $clazz")
|
||||
}
|
||||
} as T
|
||||
}
|
||||
|
@ -36,10 +36,12 @@ class OnScreenControllerView @JvmOverloads constructor(
|
||||
override fun onDraw(canvas : Canvas) {
|
||||
super.onDraw(canvas)
|
||||
|
||||
(controls.circularButtons + controls.rectangularButtons + controls.triggerButtons + controls.joysticks).forEach {
|
||||
it.width = width
|
||||
it.height = height
|
||||
it.render(canvas)
|
||||
controls.allButtons.forEach {
|
||||
if (it.config.enabled) {
|
||||
it.width = width
|
||||
it.height = height
|
||||
it.render(canvas)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +65,7 @@ class OnScreenControllerView @JvmOverloads constructor(
|
||||
}
|
||||
MotionEvent.ACTION_DOWN,
|
||||
MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
if (button.isTouched(x, y)) {
|
||||
if (button.config.enabled && button.isTouched(x, y)) {
|
||||
button.touchPointerId = pointerId
|
||||
button.onFingerDown(x, y)
|
||||
performClick()
|
||||
@ -120,7 +122,7 @@ class OnScreenControllerView @JvmOverloads constructor(
|
||||
}
|
||||
MotionEvent.ACTION_DOWN,
|
||||
MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
if (joystick.isTouched(x, y)) {
|
||||
if (joystick.config.enabled && joystick.isTouched(x, y)) {
|
||||
joystickAnimators[joystick]?.cancel()
|
||||
joystickAnimators[joystick] = null
|
||||
joystick.touchPointerId = pointerId
|
||||
@ -147,7 +149,7 @@ class OnScreenControllerView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
private val editingTouchHandler = OnTouchListener { _, event ->
|
||||
(controls.circularButtons + controls.rectangularButtons + controls.triggerButtons + controls.joysticks).any { button ->
|
||||
controls.allButtons.any { button ->
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_UP,
|
||||
MotionEvent.ACTION_POINTER_UP,
|
||||
@ -159,7 +161,7 @@ class OnScreenControllerView @JvmOverloads constructor(
|
||||
}
|
||||
MotionEvent.ACTION_DOWN,
|
||||
MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
if (button.isTouched(event.x, event.y)) {
|
||||
if (button.config.enabled && button.isTouched(event.x, event.y)) {
|
||||
button.startEdit()
|
||||
performClick()
|
||||
return@any true
|
||||
@ -183,7 +185,10 @@ class OnScreenControllerView @JvmOverloads constructor(
|
||||
fun setEditMode(editMode : Boolean) = setOnTouchListener(if (editMode) editingTouchHandler else playingTouchHandler)
|
||||
|
||||
fun resetControls() {
|
||||
(controls.circularButtons + controls.rectangularButtons + controls.triggerButtons + controls.joysticks).forEach { it.resetRelativeValues() }
|
||||
controls.allButtons.forEach {
|
||||
it.resetRelativeValues()
|
||||
it.config.enabled = true
|
||||
}
|
||||
controls.globalScale = 1f
|
||||
invalidate()
|
||||
}
|
||||
@ -205,4 +210,11 @@ class OnScreenControllerView @JvmOverloads constructor(
|
||||
fun setOnStickStateChangedListener(listener : OnStickStateChangedListener) {
|
||||
onStickStateChangedListener = listener
|
||||
}
|
||||
|
||||
fun getButtonProps() = controls.allButtons.map { Pair(it.buttonId, it.config.enabled) }
|
||||
|
||||
fun setButtonEnabled(buttonId : ButtonId, enabled : Boolean) {
|
||||
controls.allButtons.first { it.buttonId == buttonId }.config.enabled = enabled
|
||||
invalidate()
|
||||
}
|
||||
}
|
@ -5,8 +5,113 @@
|
||||
|
||||
package emu.skyline.input.onscreen
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowInsetsController
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import emu.skyline.R
|
||||
import kotlinx.android.synthetic.main.main_activity.fab_parent
|
||||
import kotlinx.android.synthetic.main.on_screen_edit_activity.*
|
||||
|
||||
class OnScreenEditActivity : AppCompatActivity() {
|
||||
private var fullEditVisible = true
|
||||
private var editMode = false
|
||||
|
||||
private val closeAction : () -> Unit = {
|
||||
if (editMode) {
|
||||
toggleFabVisibility(true)
|
||||
on_screen_controller_view.setEditMode(false)
|
||||
editMode = false
|
||||
} else {
|
||||
fullEditVisible = !fullEditVisible
|
||||
toggleFabVisibility(fullEditVisible)
|
||||
fabMapping[R.drawable.ic_close]!!.animate().rotationBy(if (fullEditVisible) -45f else 45f)
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleFabVisibility(visible : Boolean) {
|
||||
actions.forEach {
|
||||
if (it.first != R.drawable.ic_close)
|
||||
if (visible) fabMapping[it.first]!!.show()
|
||||
else fabMapping[it.first]!!.hide()
|
||||
}
|
||||
}
|
||||
|
||||
private val editAction = {
|
||||
editMode = true
|
||||
on_screen_controller_view.setEditMode(true)
|
||||
toggleFabVisibility(false)
|
||||
}
|
||||
|
||||
private val toggleAction : () -> Unit = {
|
||||
val buttonProps = on_screen_controller_view.getButtonProps()
|
||||
val checkArray = buttonProps.map { it.second }.toBooleanArray()
|
||||
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setMultiChoiceItems(buttonProps.map {
|
||||
val longText = getString(it.first.long!!)
|
||||
if (it.first.short == longText) longText else "$longText: ${it.first.short}"
|
||||
}.toTypedArray(), checkArray) { _, which, isChecked ->
|
||||
checkArray[which] = isChecked
|
||||
}.setPositiveButton(R.string.confirm) { _, _ ->
|
||||
buttonProps.forEachIndexed { index, pair ->
|
||||
if (checkArray[index] != pair.second)
|
||||
on_screen_controller_view.setButtonEnabled(pair.first, checkArray[index])
|
||||
}
|
||||
}.setNegativeButton(R.string.cancel, null)
|
||||
.setOnDismissListener { fullScreen() }
|
||||
.show()
|
||||
}
|
||||
|
||||
private val actions : List<Pair<Int, () -> Unit>> = listOf(
|
||||
Pair(R.drawable.ic_refresh, { on_screen_controller_view.resetControls() }),
|
||||
Pair(R.drawable.ic_toggle, toggleAction),
|
||||
Pair(R.drawable.ic_edit, editAction),
|
||||
Pair(R.drawable.ic_zoom_out, { on_screen_controller_view.decreaseScale() }),
|
||||
Pair(R.drawable.ic_zoom_in, { on_screen_controller_view.increaseScale() }),
|
||||
Pair(R.drawable.ic_close, closeAction)
|
||||
)
|
||||
|
||||
private val fabMapping = mutableMapOf<Int, FloatingActionButton>()
|
||||
|
||||
override fun onCreate(savedInstanceState : Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.on_screen_edit_activity)
|
||||
|
||||
actions.forEach { pair ->
|
||||
fab_parent.addView(FloatingActionButton(this).apply {
|
||||
size = FloatingActionButton.SIZE_MINI
|
||||
setColorFilter(Color.WHITE)
|
||||
setImageDrawable(ContextCompat.getDrawable(context, pair.first))
|
||||
setOnClickListener { pair.second.invoke() }
|
||||
fabMapping[pair.first] = this
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
fullScreen()
|
||||
}
|
||||
|
||||
private fun fullScreen() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
window.insetsController?.hide(WindowInsets.Type.navigationBars() or WindowInsets.Type.systemBars() or WindowInsets.Type.systemGestures() or WindowInsets.Type.statusBars())
|
||||
window.insetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ class JoystickButton(
|
||||
val secondTapDiff = currentTime - fingerUpTime
|
||||
if (firstTapDiff in 0..500 && secondTapDiff in 0..500) {
|
||||
shortDoubleTapped = true
|
||||
drawable.alpha = 50
|
||||
}
|
||||
fingerDownTime = currentTime
|
||||
}
|
||||
@ -97,6 +98,7 @@ class JoystickButton(
|
||||
|
||||
fingerUpTime = SystemClock.elapsedRealtime()
|
||||
shortDoubleTapped = false
|
||||
drawable.alpha = 255
|
||||
}
|
||||
|
||||
fun onFingerMoved(x : Float, y : Float) : PointF {
|
||||
@ -152,8 +154,7 @@ open class RectangularButton(
|
||||
defaultRelativeHeight,
|
||||
drawableId
|
||||
) {
|
||||
override fun isTouched(x : Float, y : Float) =
|
||||
currentBounds.contains(x.roundToInt(), y.roundToInt())
|
||||
override fun isTouched(x : Float, y : Float) = currentBounds.contains(x.roundToInt(), y.roundToInt())
|
||||
|
||||
override fun onFingerDown(x : Float, y : Float) {
|
||||
drawable.alpha = (255 * 0.5f).roundToInt()
|
||||
@ -217,6 +218,8 @@ class Controls(onScreenControllerView : OnScreenControllerView) {
|
||||
TriggerButton(onScreenControllerView, ZR, 0.9f, 0.1f, 0.075f, 0.08f)
|
||||
)
|
||||
|
||||
val allButtons = circularButtons + joysticks + rectangularButtons + triggerButtons
|
||||
|
||||
/**
|
||||
* We can take any of the global scale variables from the buttons
|
||||
*/
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
android:shape="oval">
|
||||
<solid android:color="#50FFFFFF" />
|
||||
<stroke
|
||||
android:width="2.5dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
android:width="2.5dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
</shape>
|
||||
|
10
app/src/main/res/drawable/ic_close.xml
Normal file
10
app/src/main/res/drawable/ic_close.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="#000"
|
||||
android:pathData="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_edit.xml
Normal file
10
app/src/main/res/drawable/ic_edit.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="#000"
|
||||
android:pathData="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z" />
|
||||
</vector>
|
@ -4,11 +4,11 @@
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#50FFFFFF" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
android:width="2dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
<size
|
||||
android:width="25dp"
|
||||
android:height="25dp" />
|
||||
android:width="25dp"
|
||||
android:height="25dp" />
|
||||
<corners android:radius="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
@ -4,24 +4,24 @@
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#50FFFFFF" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
android:width="2dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
<size
|
||||
android:width="25dp"
|
||||
android:height="25dp" />
|
||||
android:width="25dp"
|
||||
android:height="25dp" />
|
||||
<padding
|
||||
android:bottom="10dp"
|
||||
android:left="10dp"
|
||||
android:right="10dp"
|
||||
android:top="10dp" />
|
||||
android:bottom="10dp"
|
||||
android:left="10dp"
|
||||
android:right="10dp"
|
||||
android:top="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#50000000" />
|
||||
<size
|
||||
android:width="30dp"
|
||||
android:height="30dp" />
|
||||
android:width="30dp"
|
||||
android:height="30dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
android:shape="oval">
|
||||
<solid android:color="#50FFFFFF" />
|
||||
<stroke
|
||||
android:width="2.5dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
android:width="2.5dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
</shape>
|
||||
|
10
app/src/main/res/drawable/ic_toggle.xml
Normal file
10
app/src/main/res/drawable/ic_toggle.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="#000"
|
||||
android:pathData="M7,10A2,2 0 0,1 9,12A2,2 0 0,1 7,14A2,2 0 0,1 5,12A2,2 0 0,1 7,10M17,7A5,5 0 0,1 22,12A5,5 0 0,1 17,17H7A5,5 0 0,1 2,12A5,5 0 0,1 7,7H17M7,9A3,3 0 0,0 4,12A3,3 0 0,0 7,15H17A3,3 0 0,0 20,12A3,3 0 0,0 17,9H7Z" />
|
||||
</vector>
|
@ -4,16 +4,16 @@
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#50FFFFFF" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
android:width="2dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
<size
|
||||
android:width="25dp"
|
||||
android:height="25dp" />
|
||||
android:width="25dp"
|
||||
android:height="25dp" />
|
||||
<corners
|
||||
android:bottomLeftRadius="10dp"
|
||||
android:bottomRightRadius="10dp"
|
||||
android:topLeftRadius="50dp"
|
||||
android:topRightRadius="10dp" />
|
||||
android:bottomLeftRadius="10dp"
|
||||
android:bottomRightRadius="10dp"
|
||||
android:topLeftRadius="50dp"
|
||||
android:topRightRadius="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
@ -4,16 +4,16 @@
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#50FFFFFF" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
android:width="2dp"
|
||||
android:color="#A0FFFFFF" />
|
||||
<size
|
||||
android:width="25dp"
|
||||
android:height="25dp" />
|
||||
android:width="25dp"
|
||||
android:height="25dp" />
|
||||
<corners
|
||||
android:bottomLeftRadius="10dp"
|
||||
android:bottomRightRadius="10dp"
|
||||
android:topLeftRadius="10dp"
|
||||
android:topRightRadius="50dp" />
|
||||
android:bottomLeftRadius="10dp"
|
||||
android:bottomRightRadius="10dp"
|
||||
android:topLeftRadius="10dp"
|
||||
android:topRightRadius="50dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
10
app/src/main/res/drawable/ic_zoom_in.xml
Normal file
10
app/src/main/res/drawable/ic_zoom_in.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="#000"
|
||||
android:pathData="M15.5,14L20.5,19L19,20.5L14,15.5V14.71L13.73,14.43C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.43,13.73L14.71,14H15.5M9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14M12,10H10V12H9V10H7V9H9V7H10V9H12V10Z" />
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_zoom_out.xml
Normal file
10
app/src/main/res/drawable/ic_zoom_out.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="#000"
|
||||
android:pathData="M15.5,14H14.71L14.43,13.73C15.41,12.59 16,11.11 16,9.5A6.5,6.5 0 0,0 9.5,3A6.5,6.5 0 0,0 3,9.5A6.5,6.5 0 0,0 9.5,16C11.11,16 12.59,15.41 13.73,14.43L14,14.71V15.5L19,20.5L20.5,19L15.5,14M9.5,14C7,14 5,12 5,9.5C5,7 7,5 9.5,5C12,5 14,7 14,9.5C14,12 12,14 9.5,14M7,9H12V10H7V9Z" />
|
||||
</vector>
|
19
app/src/main/res/layout/on_screen_edit_activity.xml
Normal file
19
app/src/main/res/layout/on_screen_edit_activity.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<emu.skyline.input.onscreen.OnScreenControllerView
|
||||
android:id="@+id/on_screen_controller_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<emu.skyline.views.CustomLinearLayout
|
||||
android:id="@+id/fab_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="horizontal" />
|
||||
</FrameLayout>
|
@ -57,6 +57,9 @@
|
||||
<string name="osc_not_shown">On-Screen Controls won\'t be shown</string>
|
||||
<string name="osc_shown">On-Screen Controls will be shown</string>
|
||||
<string name="osc_edit">Edit On-Screen Controls layout</string>
|
||||
<string name="joystick">Joystick</string>
|
||||
<string name="confirm">Confirm</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="controller">Controller</string>
|
||||
<string name="config_controller">Configure Controller</string>
|
||||
<string name="controller_type">Controller Type</string>
|
||||
@ -106,6 +109,8 @@
|
||||
<string name="left">Left</string>
|
||||
<string name="right">Right</string>
|
||||
<string name="dpad">D-pad</string>
|
||||
<string name="left_stick">Left Stick</string>
|
||||
<string name="right_stick">Right Stick</string>
|
||||
<string name="face_buttons">Face Buttons</string>
|
||||
<string name="shoulder_trigger"><![CDATA[Shoulder & Trigger Buttons]]></string>
|
||||
<string name="shoulder_rail">Shoulder Buttons on Joy-Con Rail</string>
|
||||
|
Loading…
Reference in New Issue
Block a user