diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt index 31f7c854d..0a9f6581d 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt @@ -47,22 +47,23 @@ import de.mm20.launcher2.ui.base.BaseActivity import de.mm20.launcher2.ui.base.ProvideCompositionLocals import de.mm20.launcher2.ui.component.NavBarEffects import de.mm20.launcher2.ui.ktx.animateTo +import de.mm20.launcher2.ui.launcher.scaffold.Gesture +import de.mm20.launcher2.ui.launcher.scaffold.LauncherScaffold +import de.mm20.launcher2.ui.launcher.scaffold.ScaffoldAnimation +import de.mm20.launcher2.ui.launcher.scaffold.ScaffoldConfiguration +import de.mm20.launcher2.ui.launcher.scaffold.ScaffoldGesture +import de.mm20.launcher2.ui.launcher.scaffold.SearchBarPosition import de.mm20.launcher2.ui.launcher.scaffold.components.ClockAndWidgetsHomeComponent import de.mm20.launcher2.ui.launcher.scaffold.components.ClockHomeComponent import de.mm20.launcher2.ui.launcher.scaffold.components.DismissComponent import de.mm20.launcher2.ui.launcher.scaffold.components.FeedComponent -import de.mm20.launcher2.ui.launcher.scaffold.Gesture import de.mm20.launcher2.ui.launcher.scaffold.components.LaunchComponent -import de.mm20.launcher2.ui.launcher.scaffold.LauncherScaffold +import de.mm20.launcher2.ui.launcher.scaffold.components.LauncherSettingsComponent import de.mm20.launcher2.ui.launcher.scaffold.components.NotificationsComponent import de.mm20.launcher2.ui.launcher.scaffold.components.PowerMenuComponent import de.mm20.launcher2.ui.launcher.scaffold.components.QuickSettingsComponent import de.mm20.launcher2.ui.launcher.scaffold.components.RecentsComponent -import de.mm20.launcher2.ui.launcher.scaffold.ScaffoldAnimation -import de.mm20.launcher2.ui.launcher.scaffold.ScaffoldConfiguration -import de.mm20.launcher2.ui.launcher.scaffold.ScaffoldGesture import de.mm20.launcher2.ui.launcher.scaffold.components.ScreenOffComponent -import de.mm20.launcher2.ui.launcher.scaffold.SearchBarPosition import de.mm20.launcher2.ui.launcher.scaffold.components.SearchComponent import de.mm20.launcher2.ui.launcher.scaffold.components.SecretComponent import de.mm20.launcher2.ui.launcher.scaffold.components.WidgetsComponent @@ -215,7 +216,7 @@ abstract class SharedLauncherActivity( OverlayHost( modifier = Modifier .background( - if (dimBackground && darkTheme) Color( 0f, 0f, 0f, 0.3f) + if (dimBackground && darkTheme) Color(0f, 0f, 0f, 0.3f) else Color.Transparent ) .fillMaxSize(), @@ -294,7 +295,9 @@ abstract class SharedLauncherActivity( null } else { ScaffoldGesture( - component = WidgetsComponent.forTarget(action.target), + component = WidgetsComponent.forTarget( + action.target + ), animation = if (gesture.orientation == null) ScaffoldAnimation.ZoomIn else ScaffoldAnimation.Push, ) } @@ -337,6 +340,11 @@ abstract class SharedLauncherActivity( animation = if (gesture.orientation == null) ScaffoldAnimation.ZoomIn else ScaffoldAnimation.Push, ) + is GestureAction.LauncherSettings -> ScaffoldGesture( + component = LauncherSettingsComponent(this@SharedLauncherActivity), + animation = if (gesture.orientation == null) ScaffoldAnimation.ZoomIn else ScaffoldAnimation.Push, + ) + else -> null } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/scaffold/components/LauncherSettingsComponent.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/scaffold/components/LauncherSettingsComponent.kt new file mode 100644 index 000000000..773113e4e --- /dev/null +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/scaffold/components/LauncherSettingsComponent.kt @@ -0,0 +1,134 @@ +package de.mm20.launcher2.ui.launcher.scaffold.components + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Intent +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex +import androidx.core.app.ActivityOptionsCompat +import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.component.preferences.Preference +import de.mm20.launcher2.ui.component.preferences.PreferenceCategory +import de.mm20.launcher2.ui.ktx.toIntOffset +import de.mm20.launcher2.ui.launcher.scaffold.LauncherScaffoldState +import de.mm20.launcher2.ui.settings.SettingsActivity +import kotlinx.coroutines.delay +import kotlin.time.Duration.Companion.milliseconds + +internal class LauncherSettingsComponent( + private val activity: Activity, +) : ScaffoldComponent() { + override val showSearchBar = false + + override val isAtTop: State = mutableStateOf(true) + override val isAtBottom: State = mutableStateOf(true) + + @Composable + override fun Component( + modifier: Modifier, + insets: PaddingValues, + state: LauncherScaffoldState + ) { + + Scaffold( + modifier = modifier + .zIndex(10f) + .alpha((state.currentProgress * 2f).coerceAtMost(1f)), + topBar = { + CenterAlignedTopAppBar( + title = { + Text(stringResource(R.string.settings)) + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.surfaceContainer, + scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainerHigh, + ), + navigationIcon = { + IconButton(onClick = {}) { + Icon( + painter = painterResource(R.drawable.arrow_back_24px), + contentDescription = "Back" + ) + } + }, + ) + }, + containerColor = MaterialTheme.colorScheme.surfaceContainer + ) { + Column( + modifier = Modifier + .fillMaxSize() + .verticalScroll(rememberScrollState(), enabled = false) + .padding(it) + .padding(12.dp), + ) { + PreferenceCategory { + for (i in 0 until 11) { + Preference( + title = "", + summary = "", + ) + } + } + } + } + } + + override suspend fun onActivate(state: LauncherScaffoldState) { + super.onActivate(state) + val view = activity.window.decorView + val options = ActivityOptionsCompat.makeClipRevealAnimation( + view, + 0, + 0, + view.width, + view.height + ) + + val intent = Intent(activity, SettingsActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity.startActivity(intent, options.toBundle()) + + delay(500.milliseconds) + state.reset() + } + + override fun homePageModifier( + state: LauncherScaffoldState, + defaultModifier: Modifier + ): Modifier { + return defaultModifier.alpha(1f - state.currentProgress) + } + + @SuppressLint("ModifierFactoryExtensionFunction") + override fun searchBarModifier( + state: LauncherScaffoldState, + defaultModifier: Modifier + ): Modifier { + return defaultModifier + .offset { state.currentOffset.toIntOffset() } + .alpha(1f - state.currentProgress) + } + +} \ No newline at end of file diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/SearchBarMenu.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/SearchBarMenu.kt index 7eff1501e..1b6cac470 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/SearchBarMenu.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/SearchBarMenu.kt @@ -90,7 +90,10 @@ fun RowScope.SearchBarMenu( DropdownMenuItem( shape = MenuDefaults.middleItemShape, onClick = { - context.startActivity(Intent(context, SettingsActivity::class.java)) + context.startActivity( + Intent(context, SettingsActivity::class.java) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + ) showOverflowMenu = false }, text = { diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GesturePreference.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GesturePreference.kt index ed44aeba9..9e45f5e58 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GesturePreference.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GesturePreference.kt @@ -274,6 +274,15 @@ internal fun GesturePreference( } ) } + GestureItem( + title = stringResource(R.string.settings), + icon = R.drawable.settings_24px, + selected = value is GestureAction.LauncherSettings, + onClick = { + onValueChanged(GestureAction.LauncherSettings, null) + showSheet = false + } + ) GestureItem( title = stringResource(R.string.gesture_action_launch_select_app), icon = R.drawable.action_key_24px, @@ -402,6 +411,7 @@ private fun getActionLabel( GestureAction.Recents -> resources.getString(R.string.gesture_action_recents) GestureAction.ScreenLock -> resources.getString(R.string.gesture_action_lock_screen) GestureAction.Search -> resources.getString(R.string.gesture_action_open_search) + GestureAction.LauncherSettings -> resources.getString(R.string.settings) is GestureAction.Widgets -> { when (action.target) { WidgetScreenTarget.Widgets1 -> resources.getString(R.string.gesture_action_widgets) diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt index 2e566b38e..768236754 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt @@ -409,6 +409,10 @@ sealed interface GestureAction { @Serializable @SerialName("feed") data object Feed : GestureAction + + @Serializable + @SerialName("launcher_settings") + data object LauncherSettings : GestureAction }