diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dbfb038c..bbc6f280 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -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" />
diff --git a/app/src/main/java/emu/skyline/EmulationActivity.kt b/app/src/main/java/emu/skyline/EmulationActivity.kt
index 1b113012..8149d429 100644
--- a/app/src/main/java/emu/skyline/EmulationActivity.kt
+++ b/app/src/main/java/emu/skyline/EmulationActivity.kt
@@ -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)
 
diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt
index f3341527..16a3fc71 100644
--- a/app/src/main/java/emu/skyline/MainActivity.kt
+++ b/app/src/main/java/emu/skyline/MainActivity.kt
@@ -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())
diff --git a/app/src/main/java/emu/skyline/data/BaseElement.kt b/app/src/main/java/emu/skyline/data/BaseElement.kt
index 25f6acd9..f0f3a6db 100644
--- a/app/src/main/java/emu/skyline/data/BaseElement.kt
+++ b/app/src/main/java/emu/skyline/data/BaseElement.kt
@@ -12,4 +12,4 @@ enum class ElementType {
     Item
 }
 
-abstract class BaseElement(elementType : ElementType) : Serializable
+abstract class BaseElement(val elementType : ElementType) : Serializable
diff --git a/app/src/main/java/emu/skyline/input/ControllerActivity.kt b/app/src/main/java/emu/skyline/input/ControllerActivity.kt
index 2b16c215..17c13408 100644
--- a/app/src/main/java/emu/skyline/input/ControllerActivity.kt
+++ b/app/src/main/java/emu/skyline/input/ControllerActivity.kt
@@ -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)
             })
 
diff --git a/app/src/main/java/emu/skyline/input/GuestEvent.kt b/app/src/main/java/emu/skyline/input/GuestEvent.kt
index 1a939ff6..72cd4eb5 100644
--- a/app/src/main/java/emu/skyline/input/GuestEvent.kt
+++ b/app/src/main/java/emu/skyline/input/GuestEvent.kt
@@ -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]
diff --git a/app/src/main/java/emu/skyline/input/onscreen/OnScreenConfiguration.kt b/app/src/main/java/emu/skyline/input/onscreen/OnScreenConfiguration.kt
index 9d716ccf..39588d4a 100644
--- a/app/src/main/java/emu/skyline/input/onscreen/OnScreenConfiguration.kt
+++ b/app/src/main/java/emu/skyline/input/onscreen/OnScreenConfiguration.kt
@@ -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
 }
diff --git a/app/src/main/java/emu/skyline/input/onscreen/OnScreenControllerView.kt b/app/src/main/java/emu/skyline/input/onscreen/OnScreenControllerView.kt
index e60b477d..1df3d25c 100644
--- a/app/src/main/java/emu/skyline/input/onscreen/OnScreenControllerView.kt
+++ b/app/src/main/java/emu/skyline/input/onscreen/OnScreenControllerView.kt
@@ -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()
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/emu/skyline/input/onscreen/OnScreenEditActivity.kt b/app/src/main/java/emu/skyline/input/onscreen/OnScreenEditActivity.kt
index 389cf34b..ada47a5f 100644
--- a/app/src/main/java/emu/skyline/input/onscreen/OnScreenEditActivity.kt
+++ b/app/src/main/java/emu/skyline/input/onscreen/OnScreenEditActivity.kt
@@ -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)
+        }
+    }
 }
diff --git a/app/src/main/java/emu/skyline/input/onscreen/OnScreenItemDefinitions.kt b/app/src/main/java/emu/skyline/input/onscreen/OnScreenItemDefinitions.kt
index 1a51b8f8..dba3def3 100644
--- a/app/src/main/java/emu/skyline/input/onscreen/OnScreenItemDefinitions.kt
+++ b/app/src/main/java/emu/skyline/input/onscreen/OnScreenItemDefinitions.kt
@@ -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
      */
diff --git a/app/src/main/res/drawable/ic_button.xml b/app/src/main/res/drawable/ic_button.xml
index 84e5688b..0e745b12 100644
--- a/app/src/main/res/drawable/ic_button.xml
+++ b/app/src/main/res/drawable/ic_button.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml
new file mode 100644
index 00000000..13256e17
--- /dev/null
+++ b/app/src/main/res/drawable/ic_close.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_edit.xml b/app/src/main/res/drawable/ic_edit.xml
new file mode 100644
index 00000000..10f94811
--- /dev/null
+++ b/app/src/main/res/drawable/ic_edit.xml
@@ -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>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_rectangular_button.xml b/app/src/main/res/drawable/ic_rectangular_button.xml
index 251af221..6fc96728 100644
--- a/app/src/main/res/drawable/ic_rectangular_button.xml
+++ b/app/src/main/res/drawable/ic_rectangular_button.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_stick.xml b/app/src/main/res/drawable/ic_stick.xml
index 6b1011a1..43cd3feb 100644
--- a/app/src/main/res/drawable/ic_stick.xml
+++ b/app/src/main/res/drawable/ic_stick.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_stick_circle.xml b/app/src/main/res/drawable/ic_stick_circle.xml
index 84e5688b..0e745b12 100644
--- a/app/src/main/res/drawable/ic_stick_circle.xml
+++ b/app/src/main/res/drawable/ic_stick_circle.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_toggle.xml b/app/src/main/res/drawable/ic_toggle.xml
new file mode 100644
index 00000000..44a67e4c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_toggle.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_trigger_button_left.xml b/app/src/main/res/drawable/ic_trigger_button_left.xml
index 6b2ab5f7..91431b17 100644
--- a/app/src/main/res/drawable/ic_trigger_button_left.xml
+++ b/app/src/main/res/drawable/ic_trigger_button_left.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_trigger_button_right.xml b/app/src/main/res/drawable/ic_trigger_button_right.xml
index 5403d742..748cbb73 100644
--- a/app/src/main/res/drawable/ic_trigger_button_right.xml
+++ b/app/src/main/res/drawable/ic_trigger_button_right.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_zoom_in.xml b/app/src/main/res/drawable/ic_zoom_in.xml
new file mode 100644
index 00000000..d50a0ed1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_zoom_in.xml
@@ -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>
diff --git a/app/src/main/res/drawable/ic_zoom_out.xml b/app/src/main/res/drawable/ic_zoom_out.xml
new file mode 100644
index 00000000..8390cbe0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_zoom_out.xml
@@ -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>
diff --git a/app/src/main/res/layout/on_screen_edit_activity.xml b/app/src/main/res/layout/on_screen_edit_activity.xml
new file mode 100644
index 00000000..6d42d697
--- /dev/null
+++ b/app/src/main/res/layout/on_screen_edit_activity.xml
@@ -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>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7c775bb3..90d388d1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -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>