From 34f8cfb31ae8ef15329c4620ee1c70448fde3844 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Tue, 5 Jul 2022 18:50:50 +0200 Subject: [PATCH] Add option to use system headline fonts --- i18n/src/main/res/values/strings.xml | 2 + .../de/mm20/launcher2/preferences/Defaults.kt | 1 + preferences/src/main/proto/settings.proto | 6 +++ .../component/preferences/ListPreference.kt | 36 +++++++++++------- .../appearance/AppearanceSettingsScreen.kt | 20 ++++++++++ .../appearance/AppearanceSettingsScreenVM.kt | 14 ++++++- .../mm20/launcher2/ui/theme/LauncherTheme.kt | 27 +++++++++++-- .../launcher2/ui/theme/typography/Default.kt | 2 +- .../ui/theme/typography/SystemDefault.kt | 10 +++++ .../typography/fontfamily/DeviceDefault.kt | 38 +++++++++++++++++++ 10 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 ui/src/main/java/de/mm20/launcher2/ui/theme/typography/SystemDefault.kt create mode 100644 ui/src/main/java/de/mm20/launcher2/ui/theme/typography/fontfamily/DeviceDefault.kt diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index 9430665b..81de5467 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -411,6 +411,8 @@ Generate from primary color Light color scheme Dark color scheme + Font + System default About Version Links diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt index a46272cf..7ddad708 100644 --- a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt +++ b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt @@ -17,6 +17,7 @@ fun createFactorySettings(context: Context): Settings { .setLightScheme(DefaultLightCustomColorScheme) .setDarkScheme(DefaultDarkCustomColorScheme) ) + .setFont(Settings.AppearanceSettings.Font.Poppins) .build() ) .setWeather( diff --git a/preferences/src/main/proto/settings.proto b/preferences/src/main/proto/settings.proto index b7a28933..359729fc 100644 --- a/preferences/src/main/proto/settings.proto +++ b/preferences/src/main/proto/settings.proto @@ -70,6 +70,12 @@ message Settings { Pager = 1; } Layout layout = 9; + + enum Font { + Poppins = 0; + SystemDefault = 1; + } + Font font = 10; } AppearanceSettings appearance = 2; diff --git a/ui/src/main/java/de/mm20/launcher2/ui/component/preferences/ListPreference.kt b/ui/src/main/java/de/mm20/launcher2/ui/component/preferences/ListPreference.kt index 9d7ccdf2..a3edfcae 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/component/preferences/ListPreference.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/component/preferences/ListPreference.kt @@ -1,10 +1,7 @@ package de.mm20.launcher2.ui.component.preferences import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape @@ -25,7 +22,12 @@ fun ListPreference( value: T, summary: String? = items.firstOrNull { value == it.value }?.label, onValueChanged: (T) -> Unit, - enabled: Boolean = true + enabled: Boolean = true, + itemLabel: @Composable RowScope.(item: ListPreferenceItem) -> Unit = { + Text( + text = it.label, + ) + } ) { var showDialog by remember { mutableStateOf(false) } Preference( @@ -71,16 +73,24 @@ fun ListPreference( onValueChanged(it.value) showDialog = false } - .padding(start = 16.dp, top = 4.dp, bottom = 4.dp, end = 24.dp) + .padding( + start = 16.dp, + top = 16.dp, + bottom = 16.dp, + end = 24.dp + ) ) { - RadioButton(selected = it.value == value, onClick = { - onValueChanged(it.value) - showDialog = false - }) - Text( - text = it.label, - modifier = Modifier.padding(start = 16.dp) + RadioButton( + selected = it.value == value, + onClick = null, + modifier = Modifier + .padding(end = 16.dp) ) + CompositionLocalProvider( + LocalTextStyle provides MaterialTheme.typography.titleMedium + ) { + itemLabel(it) + } } } } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt index 20c66b18..1f03c47e 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt @@ -41,6 +41,7 @@ import de.mm20.launcher2.ui.component.preferences.* import de.mm20.launcher2.ui.launcher.search.SearchBar import de.mm20.launcher2.ui.launcher.search.SearchBarLevel import de.mm20.launcher2.ui.locals.LocalNavController +import de.mm20.launcher2.ui.theme.getTypography import kotlinx.coroutines.delay import kotlinx.coroutines.isActive @@ -86,6 +87,25 @@ fun AppearanceSettingsScreen() { navController?.navigate("settings/appearance/colorscheme") } ) + val font by viewModel.font.observeAsState() + ListPreference( + title = stringResource(R.string.preference_font), + items = listOf( + "Poppins" to AppearanceSettings.Font.Poppins, + stringResource(R.string.preference_font_system) to AppearanceSettings.Font.SystemDefault, + ), + value = font, + onValueChanged = { + if (it != null) viewModel.setFont(it) + }, + itemLabel = { + val typography = remember(it.value) { + getTypography(context, it.value) + } + Text(it.first, style = typography.titleMedium) + } + ) + Preference( title = stringResource(R.string.preference_cards), summary = stringResource(R.string.preference_cards_summary), diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt index 27b0fd8e..b110cea8 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt @@ -7,8 +7,7 @@ import de.mm20.launcher2.icons.IconPack import de.mm20.launcher2.icons.IconRepository import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.preferences.Settings -import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme -import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme +import de.mm20.launcher2.preferences.Settings.AppearanceSettings.* import de.mm20.launcher2.preferences.Settings.SearchBarSettings import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -42,6 +41,17 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent { } } + val font = dataStore.data.map { it.appearance.font }.asLiveData() + fun setFont(font: Font) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setAppearance(it.appearance.toBuilder().setFont(font)) + .build() + } + } + } + val columnCount = dataStore.data.map { it.grid.columnCount }.asLiveData() fun setColumnCount(columnCount: Int) { viewModelScope.launch { diff --git a/ui/src/main/java/de/mm20/launcher2/ui/theme/LauncherTheme.kt b/ui/src/main/java/de/mm20/launcher2/ui/theme/LauncherTheme.kt index abfca97b..1a250162 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/theme/LauncherTheme.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/theme/LauncherTheme.kt @@ -1,5 +1,6 @@ package de.mm20.launcher2.ui.theme +import android.content.Context import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.shape.CornerSize @@ -16,6 +17,7 @@ import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme import de.mm20.launcher2.ui.locals.LocalDarkTheme import de.mm20.launcher2.ui.theme.colorscheme.* import de.mm20.launcher2.ui.theme.typography.DefaultTypography +import de.mm20.launcher2.ui.theme.typography.getDeviceDefaultTypography import kotlinx.coroutines.flow.map import org.koin.androidx.compose.inject @@ -25,6 +27,7 @@ fun LauncherTheme( content: @Composable () -> Unit ) { + val context = LocalContext.current val dataStore: LauncherDataStore by inject() val colorSchemePreference by remember { @@ -48,7 +51,7 @@ fun LauncherTheme( val baseShape by remember { dataStore.data.map { - when(it.cards.shape) { + when (it.cards.shape) { Settings.CardSettings.Shape.Cut -> CutCornerShape(0f) else -> RoundedCornerShape(0f) } @@ -57,12 +60,20 @@ fun LauncherTheme( val colorScheme by colorSchemeAsState(colorSchemePreference, darkTheme) + val font by remember { dataStore.data.map { it.appearance.font } }.collectAsState( + AppearanceSettings.Font.Poppins + ) + + val typography = remember(font) { + getTypography(context, font) + } + CompositionLocalProvider( LocalDarkTheme provides darkTheme ) { MaterialTheme( colorScheme = colorScheme, - typography = DefaultTypography, + typography = typography, shapes = Shapes( extraSmall = baseShape.copy(CornerSize(cornerRadius / 3f)), small = baseShape.copy(CornerSize(cornerRadius / 3f * 2f)), @@ -76,7 +87,10 @@ fun LauncherTheme( } @Composable -fun colorSchemeAsState(colorScheme: AppearanceSettings.ColorScheme, darkTheme: Boolean): MutableState { +fun colorSchemeAsState( + colorScheme: AppearanceSettings.ColorScheme, + darkTheme: Boolean +): MutableState { val context = LocalContext.current val dataStore: LauncherDataStore by inject() @@ -134,3 +148,10 @@ fun colorSchemeAsState(colorScheme: AppearanceSettings.ColorScheme, darkTheme: B } } + +fun getTypography(context: Context, font: AppearanceSettings.Font?): Typography { + return when (font) { + AppearanceSettings.Font.SystemDefault -> getDeviceDefaultTypography(context) + else -> DefaultTypography + } +} \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/Default.kt b/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/Default.kt index ceed1b73..9cce7953 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/Default.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/Default.kt @@ -2,4 +2,4 @@ package de.mm20.launcher2.ui.theme.typography import de.mm20.launcher2.ui.theme.typography.fontfamily.Poppins -val DefaultTypography = makeTypography(headlineFamily = Poppins) +val DefaultTypography = makeTypography(headlineFamily = Poppins) \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/SystemDefault.kt b/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/SystemDefault.kt new file mode 100644 index 00000000..2df017cb --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/SystemDefault.kt @@ -0,0 +1,10 @@ +package de.mm20.launcher2.ui.theme.typography + +import android.content.Context +import androidx.compose.material3.Typography +import androidx.compose.ui.text.font.* +import de.mm20.launcher2.ui.theme.typography.fontfamily.getDeviceHeadlineFontFamily + +fun getDeviceDefaultTypography(context: Context): Typography { + return makeTypography(headlineFamily = getDeviceHeadlineFontFamily(context)) +} \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/fontfamily/DeviceDefault.kt b/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/fontfamily/DeviceDefault.kt new file mode 100644 index 00000000..8cbb348a --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/theme/typography/fontfamily/DeviceDefault.kt @@ -0,0 +1,38 @@ +package de.mm20.launcher2.ui.theme.typography.fontfamily + +import android.content.Context +import androidx.compose.ui.text.ExperimentalTextApi +import androidx.compose.ui.text.font.* + +@OptIn(ExperimentalTextApi::class) +fun getDeviceHeadlineFontFamily(context: Context): FontFamily { + val configResId = context.resources + .getIdentifier("config_headlineFontFamily", "string", "android") + + if (configResId != 0) { + val fontFamily = context.resources.getString(configResId) + return FontFamily( + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Thin, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.ExtraLight, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Light, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Normal, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Medium, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.SemiBold, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Bold, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.ExtraBold, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Black, style = FontStyle.Normal), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Thin, style = FontStyle.Italic), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.ExtraLight, style = FontStyle.Italic), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Light, style = FontStyle.Italic), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Normal, style = FontStyle.Italic), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Medium, style = FontStyle.Italic), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.SemiBold, style = FontStyle.Italic), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Bold, style = FontStyle.Italic), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.ExtraBold, style = FontStyle.Italic), + Font(DeviceFontFamilyName(fontFamily), weight = FontWeight.Black, style = FontStyle.Italic), + ) + } + + return FontFamily.SansSerif + +} \ No newline at end of file