implement import/export for typographie

This commit is contained in:
MM20 2025-06-18 22:46:54 +02:00
parent fb85b49798
commit c672e0826a
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
6 changed files with 64 additions and 1 deletions

View File

@ -16,6 +16,7 @@ import androidx.compose.material.icons.rounded.Opacity
import androidx.compose.material.icons.rounded.Palette
import androidx.compose.material.icons.rounded.Save
import androidx.compose.material.icons.rounded.Share
import androidx.compose.material.icons.rounded.TextFields
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
@ -50,12 +51,13 @@ fun ExportThemeSettingsScreen() {
val context = LocalContext.current
val colorSchemes by viewModel.colorSchemes.collectAsState(emptyList())
val typographyThemes by viewModel.typographySchemes.collectAsState(emptyList())
val shapeThemes by viewModel.shapeSchemes.collectAsState(emptyList())
val transparencySchemes by viewModel.transparencySchemes.collectAsState(emptyList())
val isValidSelection by remember {
derivedStateOf {
viewModel.colorScheme != null || viewModel.shapeScheme != null || viewModel.transparencyScheme != null
viewModel.colorScheme != null || viewModel.typographyScheme != null || viewModel.shapeScheme != null || viewModel.transparencyScheme != null
}
}
@ -102,6 +104,17 @@ fun ExportThemeSettingsScreen() {
viewModel.setColorScheme(newValue)
}
)
ListPreference(
stringResource(R.string.preference_screen_typography),
icon = Icons.Rounded.TextFields,
value = viewModel.typographyScheme,
items = listOf(stringResource(R.string.no_selection) to null) + typographyThemes.map {
it.name to it
},
onValueChanged = { newValue ->
viewModel.setTypographyScheme(newValue)
}
)
ListPreference(
stringResource(R.string.preference_screen_shapes),
icon = Icons.Rounded.CropSquare,

View File

@ -15,6 +15,7 @@ import de.mm20.launcher2.themes.shapes.Shapes
import de.mm20.launcher2.themes.ThemeBundle
import de.mm20.launcher2.themes.ThemeRepository
import de.mm20.launcher2.themes.transparencies.Transparencies
import de.mm20.launcher2.themes.typography.Typography
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
@ -28,6 +29,7 @@ class ExportThemeSettingsScreenVM: ViewModel(), KoinComponent {
private val themeRepository: ThemeRepository by inject()
val colorSchemes = themeRepository.colors.getAll().map { it.filter { !it.builtIn } }
val typographySchemes = themeRepository.typographies.getAll().map { it.filter { !it.builtIn } }
val shapeSchemes = themeRepository.shapes.getAll().map { it.filter { !it.builtIn } }
val transparencySchemes = themeRepository.transparencies.getAll().map { it.filter { !it.builtIn } }
@ -47,6 +49,14 @@ class ExportThemeSettingsScreenVM: ViewModel(), KoinComponent {
colorScheme = scheme
}
var typographyScheme by mutableStateOf<Typography?>(null)
@JvmName("_setTypographyScheme")
private set
fun setTypographyScheme(scheme: Typography?) {
if (themeName.isBlank() && scheme != null) themeName = scheme.name
typographyScheme = scheme
}
var shapeScheme by mutableStateOf<Shapes?>(null)
@JvmName("_setShapeScheme")
private set
@ -69,6 +79,7 @@ class ExportThemeSettingsScreenVM: ViewModel(), KoinComponent {
author = themeAuthor.takeIf { it.isNotBlank() },
colors = colorScheme,
shapes = shapeScheme,
typography = typographyScheme,
transparencies = transparencyScheme,
)
}

View File

@ -22,6 +22,7 @@ import androidx.compose.material.icons.rounded.MoreVert
import androidx.compose.material.icons.rounded.Opacity
import androidx.compose.material.icons.rounded.Palette
import androidx.compose.material.icons.rounded.Star
import androidx.compose.material.icons.rounded.TextFields
import androidx.compose.material3.Button
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.FilterChip
@ -72,6 +73,7 @@ import de.mm20.launcher2.ui.theme.shapes.shapesOf
import de.mm20.launcher2.ui.theme.transparency.LocalTransparencyScheme
import de.mm20.launcher2.ui.theme.transparency.transparency
import de.mm20.launcher2.ui.theme.transparency.transparencySchemeOf
import de.mm20.launcher2.ui.theme.typography.typographyOf
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
@ -124,6 +126,7 @@ fun ImportThemeSettingsScreen(
if (darkModePreview) darkColorSchemeOf(it) else lightColorSchemeOf(it)
} ?: MaterialTheme.colorScheme,
shapes = themeBundle.shapes?.let { shapesOf(it) } ?: MaterialTheme.shapes,
typography = themeBundle.typography?.let { typographyOf(it) } ?: MaterialTheme.typography,
) {
val transparencies = themeBundle.transparencies?.let { transparencySchemeOf(it) } ?: MaterialTheme.transparency
CompositionLocalProvider(
@ -153,6 +156,21 @@ fun ImportThemeSettingsScreen(
} else null,
)
}
if (themeBundle.typography != null) {
Preference(
icon = Icons.Rounded.TextFields,
title = stringResource(R.string.preference_screen_typography),
summary = themeBundle.typography?.name,
controls = if (viewModel.typographyExists) {
{
Icon(
Icons.Rounded.ChangeCircle,
stringResource(R.string.import_theme_exists)
)
}
} else null,
)
}
if (themeBundle.shapes != null) {
Preference(
icon = Icons.Rounded.CropSquare,

View File

@ -29,6 +29,9 @@ class ImportThemeSettingsScreenVM : ViewModel(), KoinComponent {
var colorsExists by mutableStateOf(false)
private set
var typographyExists by mutableStateOf(false)
private set
var shapesExists by mutableStateOf(false)
private set
@ -56,12 +59,15 @@ class ImportThemeSettingsScreenVM : ViewModel(), KoinComponent {
if (theme != null) {
val colors =
theme.colors?.id?.let { themeRepository.colors.get(it) }?.first()
val typography =
theme.typography?.id?.let { themeRepository.typographies.get(it) }?.first()
val shapes =
theme.shapes?.id?.let { themeRepository.shapes.get(it) }?.first()
val transparencies =
theme.transparencies?.id?.let { themeRepository.transparencies.get(it) }?.first()
colorsExists = colors != null
typographyExists = typography != null
shapesExists = shapes != null
transparenciesExists = transparencies != null
themeBundle = theme
@ -81,6 +87,7 @@ class ImportThemeSettingsScreenVM : ViewModel(), KoinComponent {
val themeBundle = this.themeBundle ?: return null
val colors = themeBundle.colors
val typography = themeBundle.typography
val shapes = themeBundle.shapes
val transparencies = themeBundle.transparencies
@ -100,6 +107,16 @@ class ImportThemeSettingsScreenVM : ViewModel(), KoinComponent {
uiSettings.setColorsId(colors.id)
}
}
if (typography != null) {
if (typographyExists) {
themeRepository.typographies.update(typography)
} else {
themeRepository.typographies.create(typography)
}
if (applyTheme) {
uiSettings.setTypographyId(typography.id)
}
}
if (shapes != null) {
if (shapesExist) {
themeRepository.shapes.update(shapes)

View File

@ -11,6 +11,7 @@ import de.mm20.launcher2.themes.colors.DefaultLightColorScheme
import de.mm20.launcher2.themes.colors.EmptyCorePalette
import de.mm20.launcher2.themes.shapes.Shapes
import de.mm20.launcher2.themes.transparencies.Transparencies
import de.mm20.launcher2.themes.typography.Typography
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.JsonObject
@ -26,6 +27,7 @@ data class ThemeBundle(
val name: String,
val author: String? = null,
val colors: Colors? = null,
val typography: Typography? = null,
val shapes: Shapes? = null,
val transparencies: Transparencies? = null,
/**

View File

@ -216,6 +216,7 @@ sealed interface FontWeight {
* Absolute font weight, e.g. 400 for normal, 700 for bold.
*/
@JvmInline
@Serializable
value class Absolute(val weight: Int) : FontWeight
/**
@ -224,5 +225,6 @@ sealed interface FontWeight {
* the emphasized style with a relative weight of 100 will have a weight of 500,
*/
@JvmInline
@Serializable
value class Relative(val relativeWeight: Int) : FontWeight
}