diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/Action.kt b/app/src/main/java/de/jrpie/android/launcher/actions/Action.kt index 2d03061..ddef92a 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/Action.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/Action.kt @@ -21,6 +21,9 @@ sealed interface Action { fun getIcon(context: Context): Drawable? fun isAvailable(context: Context): Boolean + // Can the action be used to reach µLauncher settings? + fun canReachSettings(): Boolean + fun bindToGesture(prefEditor: Editor, id: String) { prefEditor.putString(id, Json.encodeToString(this)) @@ -50,7 +53,10 @@ sealed interface Action { .map { Pair(it, Json.decodeFromString(it)) } .firstOrNull { it.second.isAvailable(context) } ?.apply { - boundActions.add(first) + // allow to bind CHOOSE to multiple gestures + if (second != LauncherAction.CHOOSE) { + boundActions.add(first) + } second.bindToGesture(editor, gesture.id) } } diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt b/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt index 4b71a90..90145aa 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt @@ -74,4 +74,8 @@ class AppAction(val app: AppInfo) : Action { // check if app is installed return DetailedAppInfo.fromAppInfo(app, context) != null } + + override fun canReachSettings(): Boolean { + return false + } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/Gesture.kt b/app/src/main/java/de/jrpie/android/launcher/actions/Gesture.kt index e7358ba..dba314d 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/Gesture.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/Gesture.kt @@ -168,6 +168,12 @@ enum class Gesture( R.string.settings_gesture_description_double_right, R.array.default_double_right, R.anim.left_right + ), + BACK( + "action.back", + R.string.settings_gesture_back, + R.string.settings_gesture_description_back, + R.array.default_up ); enum class Edge { diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/LauncherAction.kt b/app/src/main/java/de/jrpie/android/launcher/actions/LauncherAction.kt index 03f4b11..ac6958b 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/LauncherAction.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/LauncherAction.kt @@ -13,6 +13,7 @@ import android.os.UserManager import android.provider.Settings import android.view.KeyEvent import android.widget.Toast +import androidx.appcompat.widget.AppCompatDrawableManager import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.apps.AppFilter @@ -40,25 +41,29 @@ enum class LauncherAction( val label: Int, val icon: Int, val launch: (Context) -> Unit, - val available: (Context) -> Boolean = { true } + private val canReachSettings: Boolean = false, + val available: (Context) -> Boolean = { true }, ) : Action { SETTINGS( "settings", R.string.list_other_settings, R.drawable.baseline_settings_24, - ::openSettings + ::openSettings, + true ), CHOOSE( "choose", R.string.list_other_list, R.drawable.baseline_menu_24, - ::openAppsList + ::openAppsList, + true ), CHOOSE_FROM_FAVORITES( "choose_from_favorites", R.string.list_other_list_favorites, R.drawable.baseline_favorite_24, - { context -> openAppsList(context, true) } + { context -> openAppsList(context, true) }, + true ), TOGGLE_PRIVATE_SPACE_LOCK( "toggle_private_space_lock", @@ -127,7 +132,11 @@ enum class LauncherAction( } override fun isAvailable(context: Context): Boolean { - return true + return this.available(context) + } + + override fun canReachSettings(): Boolean { + return this.canReachSettings } companion object { diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt index bb59948..9460125 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt @@ -7,6 +7,7 @@ import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion1 +import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion2 import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersionUnknown import de.jrpie.android.launcher.ui.HomeActivity @@ -14,7 +15,7 @@ import de.jrpie.android.launcher.ui.HomeActivity * Increase when breaking changes are introduced and write an appropriate case in * `migratePreferencesToNewVersion` */ -const val PREFERENCE_VERSION = 2 +const val PREFERENCE_VERSION = 3 const val UNKNOWN_PREFERENCE_VERSION = -1 private const val TAG = "Launcher - Preferences" @@ -32,13 +33,16 @@ fun migratePreferencesToNewVersion(context: Context) { UNKNOWN_PREFERENCE_VERSION -> { /* still using the old preferences file */ migratePreferencesFromVersionUnknown(context) - - Log.i(TAG, "migration of preferences complete.") + Log.i(TAG, "migration of preferences complete (${UNKNOWN_PREFERENCE_VERSION} -> ${PREFERENCE_VERSION}).") } 1 -> { migratePreferencesFromVersion1() - Log.i(TAG, "migration of preferences complete.") + Log.i(TAG, "migration of preferences complete (1 -> ${PREFERENCE_VERSION}).") + } + 2 -> { + migratePreferencesFromVersion2() + Log.i(TAG, "migration of preferences complete (2 -> ${PREFERENCE_VERSION}).") } else -> { diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt index 66723ad..d617127 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt @@ -117,11 +117,12 @@ private fun migrateAction(key: String) { * (see [PREFERENCE_VERSION]) */ fun migratePreferencesFromVersion1() { - assert(PREFERENCE_VERSION == 2) assert(LauncherPreferences.internal().versionCode() == 1) Gesture.entries.forEach { g -> migrateAction(g.id) } migrateAppInfoSet(LauncherPreferences.apps().keys().hidden()) migrateAppInfoSet(LauncherPreferences.apps().keys().favorites()) migrateAppInfoStringMap(LauncherPreferences.apps().keys().customNames()) LauncherPreferences.internal().versionCode(2) + + migratePreferencesFromVersion2() } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt new file mode 100644 index 0000000..bcac3ae --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt @@ -0,0 +1,20 @@ +package de.jrpie.android.launcher.preferences.legacy + +import de.jrpie.android.launcher.actions.Action +import de.jrpie.android.launcher.actions.Gesture +import de.jrpie.android.launcher.actions.LauncherAction +import de.jrpie.android.launcher.preferences.LauncherPreferences +import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION + + +/** + * Migrate preferences from version 2 (used until version 0.0.21) to the current format + * (see [PREFERENCE_VERSION]) + */ +fun migratePreferencesFromVersion2() { + assert(PREFERENCE_VERSION == 3) + assert(LauncherPreferences.internal().versionCode() == 2) + // previously there was no setting for this + Action.setActionForGesture(Gesture.BACK, LauncherAction.CHOOSE) + LauncherPreferences.internal().versionCode(3) +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/VersionUnknown.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/VersionUnknown.kt index 1ecbd74..c61ca95 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/VersionUnknown.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/VersionUnknown.kt @@ -50,7 +50,6 @@ private const val TAG = "Preferences ? -> 1" * and a different file was used. */ fun migratePreferencesFromVersionUnknown(context: Context) { - assert(PREFERENCE_VERSION == 2) Log.i( TAG, diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt index 1d5381d..42dc01b 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt @@ -9,6 +9,7 @@ import android.util.DisplayMetrics import android.view.GestureDetector import android.view.KeyEvent import android.view.MotionEvent +import android.view.View import android.view.ViewConfiguration import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity @@ -54,6 +55,10 @@ class HomeActivity : UIObject, AppCompatActivity(), ) { recreate() } + + if (prefKey?.startsWith("action.") == true) { + updateSettingsFallbackButtonVisibility() + } } private var edgeWidth = 0.15f @@ -80,6 +85,10 @@ class HomeActivity : UIObject, AppCompatActivity(), handleBack() } } + binding.buttonFallbackSettings.setOnClickListener { + LauncherAction.SETTINGS.invoke(this) + } + } @@ -96,6 +105,20 @@ class HomeActivity : UIObject, AppCompatActivity(), } + private fun updateSettingsFallbackButtonVisibility() { + // If µLauncher settings can not be reached from any action bound to an enabled gesture, + // show the fallback button. + binding.buttonFallbackSettings.visibility = if ( + !Gesture.entries.any { g -> + g.isEnabled() && Action.forGesture(g)?.canReachSettings() == true + } + ) { + View.VISIBLE + } else { + View.GONE + } + } + private fun initClock() { val locale = Locale.getDefault() val dateVisible = LauncherPreferences.clock().dateVisible() @@ -152,6 +175,7 @@ class HomeActivity : UIObject, AppCompatActivity(), edgeWidth = LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f initClock() + updateSettingsFallbackButtonVisibility() } override fun onDestroy() { @@ -299,7 +323,7 @@ class HomeActivity : UIObject, AppCompatActivity(), private fun handleBack() { - LauncherAction.CHOOSE.launch(this) + Gesture.BACK(this) } override fun isHomeScreen(): Boolean { diff --git a/app/src/main/res/layout/home.xml b/app/src/main/res/layout/home.xml index f59b211..ecefdea 100644 --- a/app/src/main/res/layout/home.xml +++ b/app/src/main/res/layout/home.xml @@ -34,4 +34,18 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> + + + \ No newline at end of file diff --git a/app/src/main/res/values/defaults.xml b/app/src/main/res/values/defaults.xml index 5ed9327..276651d 100644 --- a/app/src/main/res/values/defaults.xml +++ b/app/src/main/res/values/defaults.xml @@ -3,6 +3,12 @@ + + + {\"type\": \"action:launcher\", \"value\": \"choose\"} + + + {\"type\": \"action:launcher\", \"value\": \"choose\"} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b12eb4c..9c07ed6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -25,6 +25,8 @@ - Settings : Apps - --> + Back + Back button / back gesture Up Swipe up Double Up