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 b48d8937..831a350f 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 @@ -1,6 +1,7 @@ package de.mm20.launcher2.ui.launcher.widgets.clock import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -19,6 +20,9 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Alarm +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.BatteryFull import androidx.compose.material.icons.rounded.DarkMode @@ -30,6 +34,8 @@ import androidx.compose.material.icons.rounded.Star import androidx.compose.material.icons.rounded.Today import androidx.compose.material.icons.rounded.Tune import androidx.compose.material.icons.rounded.VerticalSplit +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -58,12 +64,15 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel +import de.mm20.launcher2.preferences.Settings import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle +import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetAlignment import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.base.LocalTime import de.mm20.launcher2.ui.component.BottomSheetDialog +import de.mm20.launcher2.ui.component.preferences.Preference import de.mm20.launcher2.ui.component.preferences.SwitchPreference import de.mm20.launcher2.ui.launcher.widgets.clock.clocks.AnalogClock import de.mm20.launcher2.ui.launcher.widgets.clock.clocks.BinaryClock @@ -84,6 +93,7 @@ fun ClockWidget( val layout by viewModel.layout.collectAsState() val clockStyle by viewModel.clockStyle.collectAsState() val color by viewModel.color.collectAsState() + val alignment by viewModel.alignment.collectAsState() val time = LocalTime.current val contentColor = @@ -146,7 +156,11 @@ fun ClockWidget( } else { Box( modifier = modifier, - contentAlignment = Alignment.BottomCenter + contentAlignment = when (alignment) { + ClockWidgetAlignment.Center -> Alignment.Center + ClockWidgetAlignment.Top -> Alignment.TopCenter + else -> Alignment.BottomCenter + } ) { CompositionLocalProvider( @@ -277,6 +291,7 @@ fun ConfigureClockWidgetSheet( val color by viewModel.color.collectAsState() val style by viewModel.clockStyle.collectAsState() val fillHeight by viewModel.fillHeight.collectAsState() + val alignment by viewModel.alignment.collectAsState() val date by viewModel.datePart.collectAsState() val favorites by viewModel.favoritesPart.collectAsState() @@ -404,6 +419,66 @@ fun ConfigureClockWidgetSheet( viewModel.setFillHeight(it) } ) + AnimatedVisibility(fillHeight == true) { + var showDropdown by remember { mutableStateOf(false) } + Preference( + title = "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 + } + ) + 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 + }) + } + } } } OutlinedCard( diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt index 8aeb394d..c3ccbece 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt @@ -62,6 +62,9 @@ class ClockWidgetVM : ViewModel(), KoinComponent { val color = dataStore.data.map { it.clockWidget.color } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null) + val alignment = dataStore.data.map { it.clockWidget.alignment } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null) + fun updateTime(time: Long) { partProviders.value.forEach { it.setTime(time) } } 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 159df54d..4e3b4697 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 @@ -140,4 +140,19 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent { } } } + + val alignment = dataStore.data.map { it.clockWidget.alignment } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null) + + fun setAlignment(alignment: ClockWidgetSettings.ClockWidgetAlignment) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setClockWidget( + it.clockWidget.toBuilder() + .setAlignment(alignment) + ).build() + } + } + } } \ No newline at end of file diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml index 7d7bad28..e53efccf 100644 --- a/core/i18n/src/main/res/values/strings.xml +++ b/core/i18n/src/main/res/values/strings.xml @@ -585,6 +585,10 @@ Color Style Select a clock + Alignment + Top + Center + Bottom Date Show the current date Favorites diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt index bf63dc8a..2ba95c97 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt @@ -49,6 +49,7 @@ fun createFactorySettings(context: Context): Settings { .setDatePart(true) .setFavoritesPart(false) .setFillHeight(true) + .setAlignment(Settings.ClockWidgetSettings.ClockWidgetAlignment.Bottom) .build() ) .setFavorites( diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_17_18.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_17_18.kt index 94330910..34d1997c 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_17_18.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_17_18.kt @@ -8,5 +8,8 @@ class Migration_17_18 : VersionedMigration(17, 18) { .setAppearance(builder.appearance.toBuilder() .setBlurWallpaperRadius(32) ) + .setClockWidget(builder.clockWidget.toBuilder() + .setAlignment(Settings.ClockWidgetSettings.ClockWidgetAlignment.Bottom) + ) } } \ No newline at end of file diff --git a/core/preferences/src/main/proto/settings.proto b/core/preferences/src/main/proto/settings.proto index d4dfe8e0..0d3e6439 100644 --- a/core/preferences/src/main/proto/settings.proto +++ b/core/preferences/src/main/proto/settings.proto @@ -144,6 +144,13 @@ message Settings { Dark = 2; } ClockWidgetColors color = 9; + + enum ClockWidgetAlignment { + Bottom = 0; + Center = 1; + Top = 2; + } + ClockWidgetAlignment alignment = 10; } ClockWidgetSettings clock_widget = 7;