(fix) crash when typography font weigh is > 900

This commit is contained in:
MM20 2025-06-19 21:11:14 +02:00
parent c672e0826a
commit 1f0d2da13b
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
2 changed files with 165 additions and 38 deletions

View File

@ -1,37 +1,51 @@
package de.mm20.launcher2.ui.settings.typography package de.mm20.launcher2.ui.settings.typography
import android.content.Context import android.content.Context
import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.OpenInNew
import androidx.compose.material.icons.rounded.FormatBold import androidx.compose.material.icons.rounded.FormatBold
import androidx.compose.material.icons.rounded.FormatLineSpacing import androidx.compose.material.icons.rounded.FormatLineSpacing
import androidx.compose.material.icons.rounded.FormatSize import androidx.compose.material.icons.rounded.FormatSize
import androidx.compose.material.icons.rounded.HorizontalDistribute import androidx.compose.material.icons.rounded.OpenInNew
import androidx.compose.material.icons.rounded.Person
import androidx.compose.material.icons.rounded.RestartAlt import androidx.compose.material.icons.rounded.RestartAlt
import androidx.compose.material.icons.rounded.Tag
import androidx.compose.material.icons.rounded.Work
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.LeadingIconTab
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Slider import androidx.compose.material3.Slider
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.Typography
import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -63,6 +77,7 @@ import de.mm20.launcher2.themes.typography.DefaultTextStyles
import de.mm20.launcher2.themes.typography.FontManager import de.mm20.launcher2.themes.typography.FontManager
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.BottomSheetDialog import de.mm20.launcher2.ui.component.BottomSheetDialog
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
import de.mm20.launcher2.ui.component.preferences.Preference import de.mm20.launcher2.ui.component.preferences.Preference
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
@ -95,6 +110,7 @@ fun TypographySettingsScreen(themeId: UUID) {
) { viewModel.getTypography(themeId) }.collectAsStateWithLifecycle(null) ) { viewModel.getTypography(themeId) }.collectAsStateWithLifecycle(null)
val previewTypography = theme?.let { typographyOf(it) } val previewTypography = theme?.let { typographyOf(it) }
val previewTexts = PreviewTexts()
var editName by remember { mutableStateOf(false) } var editName by remember { mutableStateOf(false) }
@ -157,6 +173,17 @@ fun TypographySettingsScreen(themeId: UUID) {
} }
item { item {
PreferenceCategory("Body") { PreferenceCategory("Body") {
TypographyPreview(previewTypography, previewTexts) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
ShapedLauncherIcon(
size = 48.dp,
modifier = Modifier.padding(bottom = 8.dp),
)
Text(previewTexts.Medium1, textAlign = TextAlign.Center, style = MaterialTheme.typography.bodySmall)
}
}
TextStylePreference( TextStylePreference(
title = "Body Small", title = "Body Small",
textStyle = previewTypography.bodySmall, textStyle = previewTypography.bodySmall,
@ -169,7 +196,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(bodySmall = it) styles = theme!!.styles.copy(bodySmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Body Medium", title = "Body Medium",
@ -183,7 +211,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(bodyMedium = it) styles = theme!!.styles.copy(bodyMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Body Large", title = "Body Large",
@ -197,7 +226,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(bodyLarge = it) styles = theme!!.styles.copy(bodyLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Body Small Emphasized", title = "Body Small Emphasized",
@ -213,7 +243,8 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(bodySmall = it) emphasizedStyles = theme!!.emphasizedStyles.copy(bodySmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Body Medium Emphasized", title = "Body Medium Emphasized",
@ -229,7 +260,8 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(bodyMedium = it) emphasizedStyles = theme!!.emphasizedStyles.copy(bodyMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Body Large Emphasized", title = "Body Large Emphasized",
@ -245,12 +277,33 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(bodyLarge = it) emphasizedStyles = theme!!.emphasizedStyles.copy(bodyLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
} }
} }
item { item {
PreferenceCategory("Label") { PreferenceCategory("Label") {
TypographyPreview(previewTypography, previewTexts) {
FilterChip(
modifier = Modifier
.padding(end = 16.dp),
label = { Text(previewTexts.Short1
) },
leadingIcon = {
Icon(
Icons.Rounded.Tag,
contentDescription = null,
modifier = Modifier.size(FilterChipDefaults.IconSize)
)
},
selected = false,
onClick = {},
)
Button(onClick = {}) {
Text(previewTexts.Medium2)
}
}
TextStylePreference( TextStylePreference(
title = "Label Small", title = "Label Small",
textStyle = previewTypography.labelSmall, textStyle = previewTypography.labelSmall,
@ -263,7 +316,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(labelSmall = it) styles = theme!!.styles.copy(labelSmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Label Medium", title = "Label Medium",
@ -277,7 +331,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(labelMedium = it) styles = theme!!.styles.copy(labelMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Label Large", title = "Label Large",
@ -291,7 +346,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(labelLarge = it) styles = theme!!.styles.copy(labelLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Label Small Emphasized", title = "Label Small Emphasized",
@ -307,7 +363,8 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(labelSmall = it) emphasizedStyles = theme!!.emphasizedStyles.copy(labelSmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Label Medium Emphasized", title = "Label Medium Emphasized",
@ -323,7 +380,8 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(labelMedium = it) emphasizedStyles = theme!!.emphasizedStyles.copy(labelMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Label Large Emphasized", title = "Label Large Emphasized",
@ -339,12 +397,39 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(labelLarge = it) emphasizedStyles = theme!!.emphasizedStyles.copy(labelLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
} }
} }
item { item {
PreferenceCategory("Title") { PreferenceCategory("Title") {
TypographyPreview(previewTypography, previewTexts) {
PrimaryTabRow(0, modifier = Modifier.width(300.dp)) {
LeadingIconTab(
selected = true,
text = { Text(previewTexts.Short1) },
icon = {
Icon(
Icons.Rounded.Person,
contentDescription = null
)
},
onClick = {}
)
LeadingIconTab(
selected = false,
text = { Text(previewTexts.Short2) },
icon = {
Icon(
Icons.Rounded.Work,
contentDescription = null
)
},
onClick = {}
)
}
}
TextStylePreference( TextStylePreference(
title = "Title Small", title = "Title Small",
textStyle = previewTypography.titleSmall, textStyle = previewTypography.titleSmall,
@ -357,7 +442,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(titleSmall = it) styles = theme!!.styles.copy(titleSmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Title Medium", title = "Title Medium",
@ -371,7 +457,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(titleMedium = it) styles = theme!!.styles.copy(titleMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Title Large", title = "Title Large",
@ -385,7 +472,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(titleLarge = it) styles = theme!!.styles.copy(titleLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Title Small Emphasized", title = "Title Small Emphasized",
@ -401,7 +489,8 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(titleSmall = it) emphasizedStyles = theme!!.emphasizedStyles.copy(titleSmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Title Medium Emphasized", title = "Title Medium Emphasized",
@ -417,7 +506,8 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(titleMedium = it) emphasizedStyles = theme!!.emphasizedStyles.copy(titleMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Title Large Emphasized", title = "Title Large Emphasized",
@ -433,7 +523,8 @@ fun TypographySettingsScreen(themeId: UUID) {
emphasizedStyles = theme!!.emphasizedStyles.copy(titleLarge = it) emphasizedStyles = theme!!.emphasizedStyles.copy(titleLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
} }
} }
@ -451,7 +542,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(headlineSmall = it) styles = theme!!.styles.copy(headlineSmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Headline Medium", title = "Headline Medium",
@ -465,7 +557,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(headlineMedium = it) styles = theme!!.styles.copy(headlineMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Headline Large", title = "Headline Large",
@ -479,7 +572,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(headlineLarge = it) styles = theme!!.styles.copy(headlineLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Headline Small Emphasized", title = "Headline Small Emphasized",
@ -496,7 +590,8 @@ fun TypographySettingsScreen(themeId: UUID) {
theme!!.emphasizedStyles.copy(headlineSmall = it) theme!!.emphasizedStyles.copy(headlineSmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Headline Medium Emphasized", title = "Headline Medium Emphasized",
@ -513,7 +608,8 @@ fun TypographySettingsScreen(themeId: UUID) {
theme!!.emphasizedStyles.copy(headlineMedium = it) theme!!.emphasizedStyles.copy(headlineMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Headline Large Emphasized", title = "Headline Large Emphasized",
@ -530,7 +626,8 @@ fun TypographySettingsScreen(themeId: UUID) {
theme!!.emphasizedStyles.copy(headlineLarge = it) theme!!.emphasizedStyles.copy(headlineLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
} }
} }
@ -548,7 +645,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(displaySmall = it) styles = theme!!.styles.copy(displaySmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Display Medium", title = "Display Medium",
@ -562,7 +660,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(displayMedium = it) styles = theme!!.styles.copy(displayMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Display Large", title = "Display Large",
@ -576,7 +675,8 @@ fun TypographySettingsScreen(themeId: UUID) {
styles = theme!!.styles.copy(displayLarge = it) styles = theme!!.styles.copy(displayLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Display Small Emphasized", title = "Display Small Emphasized",
@ -593,7 +693,8 @@ fun TypographySettingsScreen(themeId: UUID) {
theme!!.emphasizedStyles.copy(displaySmall = it) theme!!.emphasizedStyles.copy(displaySmall = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Display Medium Emphasized", title = "Display Medium Emphasized",
@ -610,7 +711,8 @@ fun TypographySettingsScreen(themeId: UUID) {
theme!!.emphasizedStyles.copy(displayMedium = it) theme!!.emphasizedStyles.copy(displayMedium = it)
) )
) )
} },
previewTexts = previewTexts,
) )
TextStylePreference( TextStylePreference(
title = "Display Large Emphasized", title = "Display Large Emphasized",
@ -627,7 +729,8 @@ fun TypographySettingsScreen(themeId: UUID) {
theme!!.emphasizedStyles.copy(displayLarge = it) theme!!.emphasizedStyles.copy(displayLarge = it)
) )
) )
} },
previewTexts = previewTexts,
) )
} }
} }
@ -844,8 +947,8 @@ private fun TextStylePreference(
defaultValue: ThemeTextStyle<ThemeFontWeight>?, defaultValue: ThemeTextStyle<ThemeFontWeight>?,
defaultValueParent: ThemeTextStyle<ThemeFontWeight.Absolute?>? = null, defaultValueParent: ThemeTextStyle<ThemeFontWeight.Absolute?>? = null,
onValueChange: (ThemeTextStyle<ThemeFontWeight.Absolute?>?) -> Unit = {}, onValueChange: (ThemeTextStyle<ThemeFontWeight.Absolute?>?) -> Unit = {},
previewTexts: PreviewTexts,
) { ) {
val preview = PreviewTexts()
val context = LocalContext.current val context = LocalContext.current
var showDialog by remember { mutableStateOf(false) } var showDialog by remember { mutableStateOf(false) }
@ -859,7 +962,7 @@ private fun TextStylePreference(
}, },
icon = { icon = {
Text( Text(
text = preview.ExtraShort, text = previewTexts.ExtraShort,
style = textStyle, style = textStyle,
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary,
maxLines = 1, maxLines = 1,
@ -944,7 +1047,7 @@ private fun TextStylePreference(
) { ) {
Text( Text(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
text = preview.TwoLines, text = previewTexts.TwoLines,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary,
fontFamily = fontFamilyOf(context, fonts[actualFontFamily]), fontFamily = fontFamilyOf(context, fonts[actualFontFamily]),
@ -985,7 +1088,7 @@ private fun TextStylePreference(
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
) { ) {
Text( Text(
text = preview.ExtraShort, text = previewTexts.ExtraShort,
fontFamily = f, fontFamily = f,
style = MaterialTheme.typography.headlineSmall, style = MaterialTheme.typography.headlineSmall,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
@ -1080,4 +1183,28 @@ private fun TextStylePreference(
} }
} }
}
@Composable
private fun TypographyPreview(
previewTypography: Typography,
previewTexts: PreviewTexts,
content: @Composable () -> Unit,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clip(MaterialTheme.shapes.extraSmall)
.background(MaterialTheme.colorScheme.surfaceContainerLowest)
.horizontalScroll(rememberScrollState())
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
MaterialTheme(
typography = previewTypography
) {
content()
}
}
} }

View File

@ -253,7 +253,7 @@ private fun textStyleOf(
fontFamily = (style?.fontFamily ?: fallback.fontFamily)?.let { fonts[it] } fontFamily = (style?.fontFamily ?: fallback.fontFamily)?.let { fonts[it] }
?: base.fontFamily, ?: base.fontFamily,
fontWeight = (style?.fontWeight?.weight fontWeight = (style?.fontWeight?.weight
?: fallback.fontWeight?.weight)?.let { FontWeight(it) } ?: base.fontWeight, ?: fallback.fontWeight?.weight)?.let { FontWeight(it.coerceIn(100, 900)) } ?: base.fontWeight,
fontSize = (style?.fontSize ?: fallback.fontSize)?.sp ?: base.fontSize, fontSize = (style?.fontSize ?: fallback.fontSize)?.sp ?: base.fontSize,
lineHeight = (style?.lineHeight ?: fallback.lineHeight)?.em ?: base.lineHeight, lineHeight = (style?.lineHeight ?: fallback.lineHeight)?.em ?: base.lineHeight,
letterSpacing = (style?.letterSpacing ?: fallback.letterSpacing)?.em ?: base.letterSpacing, letterSpacing = (style?.letterSpacing ?: fallback.letterSpacing)?.em ?: base.letterSpacing,
@ -272,9 +272,9 @@ private fun emphasizedTextStyleOf(
val parentWeight = parent?.fontWeight ?: fallbackParent.fontWeight val parentWeight = parent?.fontWeight ?: fallbackParent.fontWeight
val fontWeight = when (weight) { val fontWeight = when (weight) {
is ThemeFontWeight.Absolute -> FontWeight(weight.weight) is ThemeFontWeight.Absolute -> FontWeight(weight.weight.coerceIn(100, 900))
is ThemeFontWeight.Relative if (parentWeight != null) -> { is ThemeFontWeight.Relative if (parentWeight != null) -> {
FontWeight(parentWeight.weight + weight.relativeWeight) FontWeight((parentWeight.weight + weight.relativeWeight).coerceIn(100, 900))
} }
else -> base.fontWeight else -> base.fontWeight