Add option to use system headline fonts
This commit is contained in:
parent
e6f9bb8971
commit
34f8cfb31a
@ -411,6 +411,8 @@
|
|||||||
<string name="preference_colors_auto_generate">Generate from primary color</string>
|
<string name="preference_colors_auto_generate">Generate from primary color</string>
|
||||||
<string name="preference_category_custom_colors_light">Light color scheme</string>
|
<string name="preference_category_custom_colors_light">Light color scheme</string>
|
||||||
<string name="preference_category_custom_colors_dark">Dark color scheme</string>
|
<string name="preference_category_custom_colors_dark">Dark color scheme</string>
|
||||||
|
<string name="preference_font">Font</string>
|
||||||
|
<string name="preference_font_system">System default</string>
|
||||||
<string name="preference_screen_about">About</string>
|
<string name="preference_screen_about">About</string>
|
||||||
<string name="preference_version">Version</string>
|
<string name="preference_version">Version</string>
|
||||||
<string name="preference_category_links">Links</string>
|
<string name="preference_category_links">Links</string>
|
||||||
|
|||||||
@ -17,6 +17,7 @@ fun createFactorySettings(context: Context): Settings {
|
|||||||
.setLightScheme(DefaultLightCustomColorScheme)
|
.setLightScheme(DefaultLightCustomColorScheme)
|
||||||
.setDarkScheme(DefaultDarkCustomColorScheme)
|
.setDarkScheme(DefaultDarkCustomColorScheme)
|
||||||
)
|
)
|
||||||
|
.setFont(Settings.AppearanceSettings.Font.Poppins)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.setWeather(
|
.setWeather(
|
||||||
|
|||||||
@ -70,6 +70,12 @@ message Settings {
|
|||||||
Pager = 1;
|
Pager = 1;
|
||||||
}
|
}
|
||||||
Layout layout = 9;
|
Layout layout = 9;
|
||||||
|
|
||||||
|
enum Font {
|
||||||
|
Poppins = 0;
|
||||||
|
SystemDefault = 1;
|
||||||
|
}
|
||||||
|
Font font = 10;
|
||||||
}
|
}
|
||||||
AppearanceSettings appearance = 2;
|
AppearanceSettings appearance = 2;
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
package de.mm20.launcher2.ui.component.preferences
|
package de.mm20.launcher2.ui.component.preferences
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
@ -25,7 +22,12 @@ fun <T> ListPreference(
|
|||||||
value: T,
|
value: T,
|
||||||
summary: String? = items.firstOrNull { value == it.value }?.label,
|
summary: String? = items.firstOrNull { value == it.value }?.label,
|
||||||
onValueChanged: (T) -> Unit,
|
onValueChanged: (T) -> Unit,
|
||||||
enabled: Boolean = true
|
enabled: Boolean = true,
|
||||||
|
itemLabel: @Composable RowScope.(item: ListPreferenceItem<T>) -> Unit = {
|
||||||
|
Text(
|
||||||
|
text = it.label,
|
||||||
|
)
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
var showDialog by remember { mutableStateOf(false) }
|
var showDialog by remember { mutableStateOf(false) }
|
||||||
Preference(
|
Preference(
|
||||||
@ -71,16 +73,24 @@ fun <T> ListPreference(
|
|||||||
onValueChanged(it.value)
|
onValueChanged(it.value)
|
||||||
showDialog = false
|
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 = {
|
RadioButton(
|
||||||
onValueChanged(it.value)
|
selected = it.value == value,
|
||||||
showDialog = false
|
onClick = null,
|
||||||
})
|
modifier = Modifier
|
||||||
Text(
|
.padding(end = 16.dp)
|
||||||
text = it.label,
|
|
||||||
modifier = Modifier.padding(start = 16.dp)
|
|
||||||
)
|
)
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalTextStyle provides MaterialTheme.typography.titleMedium
|
||||||
|
) {
|
||||||
|
itemLabel(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.SearchBar
|
||||||
import de.mm20.launcher2.ui.launcher.search.SearchBarLevel
|
import de.mm20.launcher2.ui.launcher.search.SearchBarLevel
|
||||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||||
|
import de.mm20.launcher2.ui.theme.getTypography
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
|
|
||||||
@ -86,6 +87,25 @@ fun AppearanceSettingsScreen() {
|
|||||||
navController?.navigate("settings/appearance/colorscheme")
|
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(
|
Preference(
|
||||||
title = stringResource(R.string.preference_cards),
|
title = stringResource(R.string.preference_cards),
|
||||||
summary = stringResource(R.string.preference_cards_summary),
|
summary = stringResource(R.string.preference_cards_summary),
|
||||||
|
|||||||
@ -7,8 +7,7 @@ import de.mm20.launcher2.icons.IconPack
|
|||||||
import de.mm20.launcher2.icons.IconRepository
|
import de.mm20.launcher2.icons.IconRepository
|
||||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||||
import de.mm20.launcher2.preferences.Settings
|
import de.mm20.launcher2.preferences.Settings
|
||||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
|
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.*
|
||||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
|
|
||||||
import de.mm20.launcher2.preferences.Settings.SearchBarSettings
|
import de.mm20.launcher2.preferences.Settings.SearchBarSettings
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
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()
|
val columnCount = dataStore.data.map { it.grid.columnCount }.asLiveData()
|
||||||
fun setColumnCount(columnCount: Int) {
|
fun setColumnCount(columnCount: Int) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.mm20.launcher2.ui.theme
|
package de.mm20.launcher2.ui.theme
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.shape.CornerSize
|
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.locals.LocalDarkTheme
|
||||||
import de.mm20.launcher2.ui.theme.colorscheme.*
|
import de.mm20.launcher2.ui.theme.colorscheme.*
|
||||||
import de.mm20.launcher2.ui.theme.typography.DefaultTypography
|
import de.mm20.launcher2.ui.theme.typography.DefaultTypography
|
||||||
|
import de.mm20.launcher2.ui.theme.typography.getDeviceDefaultTypography
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import org.koin.androidx.compose.inject
|
import org.koin.androidx.compose.inject
|
||||||
|
|
||||||
@ -25,6 +27,7 @@ fun LauncherTheme(
|
|||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
val dataStore: LauncherDataStore by inject()
|
val dataStore: LauncherDataStore by inject()
|
||||||
|
|
||||||
val colorSchemePreference by remember {
|
val colorSchemePreference by remember {
|
||||||
@ -48,7 +51,7 @@ fun LauncherTheme(
|
|||||||
|
|
||||||
val baseShape by remember {
|
val baseShape by remember {
|
||||||
dataStore.data.map {
|
dataStore.data.map {
|
||||||
when(it.cards.shape) {
|
when (it.cards.shape) {
|
||||||
Settings.CardSettings.Shape.Cut -> CutCornerShape(0f)
|
Settings.CardSettings.Shape.Cut -> CutCornerShape(0f)
|
||||||
else -> RoundedCornerShape(0f)
|
else -> RoundedCornerShape(0f)
|
||||||
}
|
}
|
||||||
@ -57,12 +60,20 @@ fun LauncherTheme(
|
|||||||
|
|
||||||
val colorScheme by colorSchemeAsState(colorSchemePreference, darkTheme)
|
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(
|
CompositionLocalProvider(
|
||||||
LocalDarkTheme provides darkTheme
|
LocalDarkTheme provides darkTheme
|
||||||
) {
|
) {
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
typography = DefaultTypography,
|
typography = typography,
|
||||||
shapes = Shapes(
|
shapes = Shapes(
|
||||||
extraSmall = baseShape.copy(CornerSize(cornerRadius / 3f)),
|
extraSmall = baseShape.copy(CornerSize(cornerRadius / 3f)),
|
||||||
small = baseShape.copy(CornerSize(cornerRadius / 3f * 2f)),
|
small = baseShape.copy(CornerSize(cornerRadius / 3f * 2f)),
|
||||||
@ -76,7 +87,10 @@ fun LauncherTheme(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun colorSchemeAsState(colorScheme: AppearanceSettings.ColorScheme, darkTheme: Boolean): MutableState<ColorScheme> {
|
fun colorSchemeAsState(
|
||||||
|
colorScheme: AppearanceSettings.ColorScheme,
|
||||||
|
darkTheme: Boolean
|
||||||
|
): MutableState<ColorScheme> {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dataStore: LauncherDataStore by inject()
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,4 +2,4 @@ package de.mm20.launcher2.ui.theme.typography
|
|||||||
|
|
||||||
import de.mm20.launcher2.ui.theme.typography.fontfamily.Poppins
|
import de.mm20.launcher2.ui.theme.typography.fontfamily.Poppins
|
||||||
|
|
||||||
val DefaultTypography = makeTypography(headlineFamily = Poppins)
|
val DefaultTypography = makeTypography(headlineFamily = Poppins)
|
||||||
@ -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))
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user