From 8ae2fc93fc9b7f160c77731bed6e139131374df2 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Sun, 13 Jul 2025 20:55:29 +0200 Subject: [PATCH] Bring back clock widget fill height option Close #1493 --- .../scaffold/ClockAndWidgetsHomeComponent.kt | 41 ++++-- .../ui/launcher/widgets/clock/ClockWidget.kt | 131 ++++++++++-------- .../ClockWidgetSettingsScreenVM.kt | 10 ++ .../preferences/LauncherSettingsData.kt | 1 - .../preferences/ui/ClockWidgetSettings.kt | 8 +- 5 files changed, 117 insertions(+), 74 deletions(-) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/scaffold/ClockAndWidgetsHomeComponent.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/scaffold/ClockAndWidgetsHomeComponent.kt index c0cacac0..0456a18f 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/scaffold/ClockAndWidgetsHomeComponent.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/scaffold/ClockAndWidgetsHomeComponent.kt @@ -1,18 +1,17 @@ package de.mm20.launcher2.ui.launcher.scaffold -import android.annotation.SuppressLint import androidx.activity.compose.BackHandler import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateDpAsState -import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.ScrollState -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons @@ -26,6 +25,7 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf @@ -35,17 +35,18 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.composed -import androidx.compose.ui.draw.alpha import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex +import de.mm20.launcher2.preferences.ui.ClockWidgetSettings import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.ktx.toDp import de.mm20.launcher2.ui.launcher.widgets.WidgetColumn import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidget import kotlinx.coroutines.launch +import org.koin.compose.koinInject -internal object ClockAndWidgetsHomeComponent: ScaffoldComponent() { +internal object ClockAndWidgetsHomeComponent : ScaffoldComponent() { private var editMode by mutableStateOf(false) private val scrollState = ScrollState(0) @@ -54,7 +55,7 @@ internal object ClockAndWidgetsHomeComponent: ScaffoldComponent() { } override val isAtBottom: State = derivedStateOf { - !scrollState.canScrollForward + !scrollState.canScrollForward || scrollState.value == 0 } override val drawBackground: Boolean = false @@ -72,11 +73,19 @@ internal object ClockAndWidgetsHomeComponent: ScaffoldComponent() { ) { val scope = rememberCoroutineScope() - val topPadding by animateDpAsState(if (editMode) 80.dp else 0.dp) + val clockWidgetSettings: ClockWidgetSettings = koinInject() + val fillHeight by clockWidgetSettings.fillHeight.collectAsState(null) + if (fillHeight == null) return + + val topPadding by animateDpAsState(if (editMode) 80.dp else 0.dp) val previousScroll = remember { mutableIntStateOf(scrollState.value) } - LaunchedEffect(scrollState.value, scrollState.canScrollForward, scrollState.canScrollBackward) { + LaunchedEffect( + scrollState.value, + scrollState.canScrollForward, + scrollState.canScrollBackward + ) { val delta = scrollState.value - previousScroll.intValue previousScroll.intValue = scrollState.value if (!editMode) { @@ -92,8 +101,15 @@ internal object ClockAndWidgetsHomeComponent: ScaffoldComponent() { .padding(insets), ) { ClockWidget( + modifier = Modifier + .fillMaxWidth() + then if (fillHeight == true) Modifier.height( + state.size.height.toDp() - insets.calculateTopPadding() + ).padding( + bottom = insets.calculateBottomPadding() + ) else Modifier, editMode = editMode, - fillScreenHeight = false, + fillScreenHeight = fillHeight == true, ) WidgetColumn( modifier = Modifier @@ -126,7 +142,10 @@ internal object ClockAndWidgetsHomeComponent: ScaffoldComponent() { scope.launch { state.unlock() } } ) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, stringResource(R.string.action_done)) + Icon( + Icons.AutoMirrored.Rounded.ArrowBack, + stringResource(R.string.action_done) + ) } }, colors = TopAppBarDefaults.topAppBarColors( diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt index 09807498..a762e0a7 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt @@ -24,10 +24,10 @@ import androidx.compose.material.icons.rounded.AlignVerticalBottom import androidx.compose.material.icons.rounded.AlignVerticalCenter import androidx.compose.material.icons.rounded.AlignVerticalTop import androidx.compose.material.icons.rounded.AutoAwesome -import androidx.compose.material.icons.rounded.AvTimer import androidx.compose.material.icons.rounded.BatteryFull import androidx.compose.material.icons.rounded.ColorLens import androidx.compose.material.icons.rounded.DarkMode +import androidx.compose.material.icons.rounded.Height import androidx.compose.material.icons.rounded.HorizontalSplit import androidx.compose.material.icons.rounded.LightMode import androidx.compose.material.icons.rounded.MusicNote @@ -363,6 +363,7 @@ fun ConfigureClockWidgetSheet( val color by viewModel.color.collectAsState() val style by viewModel.clockStyle.collectAsState() val fillHeight by viewModel.fillHeight.collectAsState() + val widgetsOnHome by viewModel.widgetsOnHome.collectAsState() val alignment by viewModel.alignment.collectAsState() val showSeconds by viewModel.showSeconds.collectAsState() val timeFormat by viewModel.timeFormat.collectAsState() @@ -564,71 +565,79 @@ fun ConfigureClockWidgetSheet( } } } - if (fillHeight == true) { - OutlinedCard( - modifier = Modifier.padding(top = 16.dp), + OutlinedCard( + modifier = Modifier.padding(top = 16.dp), + ) { + Column( + modifier = Modifier.fillMaxWidth() ) { - Column( - modifier = Modifier.fillMaxWidth() - ) { - var showDropdown by remember { mutableStateOf(false) } - Preference( - title = stringResource(R.string.preference_clock_widget_alignment), - summary = when (alignment) { - ClockWidgetAlignment.Top -> stringResource(R.string.preference_clock_widget_alignment_top) - ClockWidgetAlignment.Center -> stringResource(R.string.preference_clock_widget_alignment_center) - else -> stringResource(R.string.preference_clock_widget_alignment_bottom) - }, - icon = when (alignment) { - ClockWidgetAlignment.Top -> Icons.Rounded.AlignVerticalTop - ClockWidgetAlignment.Center -> Icons.Rounded.AlignVerticalCenter - else -> Icons.Rounded.AlignVerticalBottom + SwitchPreference( + title = stringResource(R.string.preference_clock_widget_fill_height), + icon = Icons.Rounded.Height, + value = fillHeight == true || widgetsOnHome == false, + onValueChanged = { + viewModel.setFillHeight(it) + }, + enabled = widgetsOnHome == true, + ) + var showDropdown by remember { mutableStateOf(false) } + Preference( + title = stringResource(R.string.preference_clock_widget_alignment), + summary = when (alignment) { + ClockWidgetAlignment.Top -> stringResource(R.string.preference_clock_widget_alignment_top) + ClockWidgetAlignment.Center -> stringResource(R.string.preference_clock_widget_alignment_center) + else -> stringResource(R.string.preference_clock_widget_alignment_bottom) + }, + icon = when (alignment) { + ClockWidgetAlignment.Top -> Icons.Rounded.AlignVerticalTop + ClockWidgetAlignment.Center -> Icons.Rounded.AlignVerticalCenter + else -> Icons.Rounded.AlignVerticalBottom + }, + onClick = { + showDropdown = true + }, + enabled = fillHeight == true, + ) + DropdownMenu( + expanded = showDropdown, + onDismissRequest = { showDropdown = false }) { + DropdownMenuItem( + leadingIcon = { + Icon( + Icons.Rounded.AlignVerticalTop, + null + ) }, + text = { Text(stringResource(R.string.preference_clock_widget_alignment_top)) }, onClick = { - showDropdown = true + viewModel.setAlignment(ClockWidgetAlignment.Top) + showDropdown = false } ) - DropdownMenu( - expanded = showDropdown, - onDismissRequest = { showDropdown = false }) { - DropdownMenuItem( - leadingIcon = { - Icon( - Icons.Rounded.AlignVerticalTop, - null - ) - }, - text = { Text(stringResource(R.string.preference_clock_widget_alignment_top)) }, - onClick = { - viewModel.setAlignment(ClockWidgetAlignment.Top) - showDropdown = false - } - ) - DropdownMenuItem( - leadingIcon = { - Icon( - Icons.Rounded.AlignVerticalCenter, - null - ) - }, - text = { Text(stringResource(R.string.preference_clock_widget_alignment_center)) }, - onClick = { - viewModel.setAlignment(ClockWidgetAlignment.Center) - showDropdown = false - }) - DropdownMenuItem( - leadingIcon = { - Icon( - Icons.Rounded.AlignVerticalBottom, - null - ) - }, - text = { Text(stringResource(R.string.preference_clock_widget_alignment_bottom)) }, - onClick = { - viewModel.setAlignment(ClockWidgetAlignment.Bottom) - showDropdown = false - }) - } + DropdownMenuItem( + leadingIcon = { + Icon( + Icons.Rounded.AlignVerticalCenter, + null + ) + }, + text = { Text(stringResource(R.string.preference_clock_widget_alignment_center)) }, + onClick = { + viewModel.setAlignment(ClockWidgetAlignment.Center) + showDropdown = false + }) + DropdownMenuItem( + leadingIcon = { + Icon( + Icons.Rounded.AlignVerticalBottom, + null + ) + }, + text = { Text(stringResource(R.string.preference_clock_widget_alignment_bottom)) }, + onClick = { + viewModel.setAlignment(ClockWidgetAlignment.Bottom) + showDropdown = false + }) } } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt index 792800c7..bb6f6886 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt @@ -7,6 +7,7 @@ import de.mm20.launcher2.preferences.ClockWidgetColors import de.mm20.launcher2.preferences.ClockWidgetStyle import de.mm20.launcher2.preferences.TimeFormat import de.mm20.launcher2.preferences.ui.ClockWidgetSettings +import de.mm20.launcher2.preferences.ui.UiSettings import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn @@ -15,6 +16,8 @@ import org.koin.core.component.inject class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent { private val settings: ClockWidgetSettings by inject() + private val uiSettings: UiSettings by inject() + val compact = settings.compact .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null) fun setCompact(compact: Boolean) { @@ -68,9 +71,16 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent { settings.setUseThemeColor(boolean) } + val widgetsOnHome = uiSettings.homeScreenWidgets + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null) + val fillHeight = settings.fillHeight .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null) + fun setFillHeight(fillHeight: Boolean) { + settings.setFillHeight(fillHeight) + } + val parts = settings.parts .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null) 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 57438b51..5e01f759 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 @@ -51,7 +51,6 @@ data class LauncherSettingsData internal constructor( val clockWidgetBatteryPart: Boolean = true, val clockWidgetMusicPart: Boolean = true, val clockWidgetDatePart: Boolean = true, - @Deprecated("Use homeScreenWidgets") val clockWidgetFillHeight: Boolean = true, val clockWidgetAlignment: ClockWidgetAlignment = ClockWidgetAlignment.Bottom, diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/ui/ClockWidgetSettings.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/ui/ClockWidgetSettings.kt index 632a1a29..6341536a 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/ui/ClockWidgetSettings.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/ui/ClockWidgetSettings.kt @@ -64,7 +64,13 @@ class ClockWidgetSettings internal constructor( } val fillHeight - get() = launcherDataStore.data.map { !it.homeScreenWidgets } + get() = launcherDataStore.data.map { it.clockWidgetFillHeight || !it.homeScreenWidgets } + + fun setFillHeight(fillHeight: Boolean) { + launcherDataStore.update { + it.copy(clockWidgetFillHeight = fillHeight) + } + } val dock get() = launcherDataStore.data.map { it.homeScreenDock }