diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index e3939e2c..e9ee179c 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -519,6 +519,8 @@ Layout Default Compact + Fill screen height + Insert extra space above the clock to fill the entire screen height Style Select a clock Date diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt index cf9a99d3..2cf0e9a3 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt @@ -50,4 +50,6 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent { } val wallpaperBlur = dataStore.data.map { it.appearance.blurWallpaper }.asLiveData() + + val fillClockHeight = dataStore.data.map { it.clockWidget.fillHeight }.asLiveData() } \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt index 1c79e611..f6b3c2a6 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt @@ -87,12 +87,15 @@ fun PagerScaffold( } } } + + val fillClockHeight by viewModel.fillClockHeight.observeAsState(true) + val showNavBarScrim by remember { derivedStateOf { if (isSearchOpen) { !isSearchAtStart } else { - widgetsScrollState.value > 0 && widgetsScrollState.value < widgetsScrollState.maxValue + (widgetsScrollState.value > 0 || !fillClockHeight) && widgetsScrollState.value < widgetsScrollState.maxValue } } } @@ -274,12 +277,16 @@ fun PagerScaffold( val editModePadding by animateDpAsState(if (isWidgetEditMode) 56.dp else 0.dp) val clockPadding by animateDpAsState( - if (isWidgetsScrollZero) 64.dp + insets.calculateBottomPadding() else 0.dp + if (isWidgetsScrollZero && fillClockHeight) 64.dp + insets.calculateBottomPadding() else 0.dp ) val clockHeight by remember { derivedStateOf { - height - (64.dp + insets.calculateTopPadding() + insets.calculateBottomPadding() - clockPadding) + if (fillClockHeight){ + height - (64.dp + insets.calculateTopPadding() + insets.calculateBottomPadding() - clockPadding) + } else { + null + } } } @@ -347,7 +354,7 @@ fun PagerScaffold( derivedStateOf { when { swipeableState.direction != 0f -> SearchBarLevel.Raised - !isSearchOpen && isWidgetsScrollZero -> SearchBarLevel.Resting + !isSearchOpen && isWidgetsScrollZero && fillClockHeight -> SearchBarLevel.Resting isSearchOpen && isSearchAtStart -> SearchBarLevel.Active else -> SearchBarLevel.Raised } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt index 02e9f08d..19477641 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt @@ -88,6 +88,8 @@ fun PullDownScaffold( } } + val fillClockHeight by viewModel.fillClockHeight.observeAsState(true) + val showStatusBarScrim by remember { derivedStateOf { if (isSearchOpen) { @@ -102,7 +104,7 @@ fun PullDownScaffold( if (isSearchOpen) { !isSearchAtEnd } else { - widgetsScrollState.value > 0 && widgetsScrollState.value < widgetsScrollState.maxValue + (widgetsScrollState.value > 0 || !fillClockHeight) && widgetsScrollState.value < widgetsScrollState.maxValue } } } @@ -295,11 +297,15 @@ fun PullDownScaffold( ) val editModePadding by animateDpAsState(if (isWidgetEditMode) 56.dp else 0.dp) val clockPadding by animateDpAsState( - if (isWidgetsAtStart) insets.calculateBottomPadding() else 0.dp + if (isWidgetsAtStart && fillClockHeight) insets.calculateBottomPadding() else 0.dp ) val clockHeight by remember { derivedStateOf { - height - (insets.calculateTopPadding() + insets.calculateBottomPadding() - clockPadding) + if (fillClockHeight) { + height - (insets.calculateTopPadding() + insets.calculateBottomPadding() - clockPadding + 56.dp) + } else { + null + } } } WidgetColumn( @@ -316,6 +322,7 @@ fun PullDownScaffold( .verticalScroll(widgetsScrollState) .windowInsetsPadding(WindowInsets.safeDrawing) .padding(8.dp) + .padding(top = 56.dp) .padding(top = editModePadding), clockHeight = { clockHeight }, clockBottomPadding = { clockPadding }, diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt index a6e80877..1cf68aa0 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt @@ -38,6 +38,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidget import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.ktx.animateTo +import de.mm20.launcher2.ui.ktx.conditional import de.mm20.launcher2.ui.launcher.widgets.picker.PickAppWidgetActivity import de.mm20.launcher2.widgets.ExternalWidget import kotlinx.coroutines.awaitCancellation @@ -46,7 +47,7 @@ import kotlinx.coroutines.launch @Composable fun WidgetColumn( modifier: Modifier = Modifier, - clockHeight: () -> Dp = { 0.dp }, + clockHeight: () -> Dp? = { null }, clockBottomPadding: () -> Dp = { 0.dp }, editMode: Boolean = false, onEditModeChange: (Boolean) -> Unit, @@ -90,7 +91,7 @@ fun WidgetColumn( Box( modifier = Modifier .fillMaxWidth() - .height(clockHeight()) + .then(clockHeight()?.let { Modifier.height(it) } ?: Modifier) .padding(bottom = clockBottomPadding()), contentAlignment = Alignment.BottomCenter ) { diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt index 1811bb5b..8856baca 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt @@ -52,6 +52,13 @@ fun ClockWidgetSettingsScreen() { viewModel.setClockStyle(it) } ) + val fillHeight by viewModel.fillHeight.observeAsState() + SwitchPreference( + title = stringResource(R.string.preference_clock_widget_fill_height), + summary = stringResource(R.string.preference_clock_widget_fill_height_summary), + value = fillHeight == true, + onValueChanged = { viewModel.setFillHeight(it) } + ) } } item { diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt index 5470e183..bbbd2b8d 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt @@ -38,6 +38,19 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent { } } + val fillHeight = dataStore.data.map { it.clockWidget.fillHeight }.asLiveData() + fun setFillHeight(fillHeight: Boolean) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setClockWidget( + it.clockWidget.toBuilder() + .setFillHeight(fillHeight) + ).build() + } + } + } + val datePart = dataStore.data.map { it.clockWidget.datePart }.asLiveData() fun setDatePart(datePart: Boolean) { viewModelScope.launch {