implement import/export for typographie
This commit is contained in:
parent
fb85b49798
commit
c672e0826a
@ -16,6 +16,7 @@ import androidx.compose.material.icons.rounded.Opacity
|
|||||||
import androidx.compose.material.icons.rounded.Palette
|
import androidx.compose.material.icons.rounded.Palette
|
||||||
import androidx.compose.material.icons.rounded.Save
|
import androidx.compose.material.icons.rounded.Save
|
||||||
import androidx.compose.material.icons.rounded.Share
|
import androidx.compose.material.icons.rounded.Share
|
||||||
|
import androidx.compose.material.icons.rounded.TextFields
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
@ -50,12 +51,13 @@ fun ExportThemeSettingsScreen() {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val colorSchemes by viewModel.colorSchemes.collectAsState(emptyList())
|
val colorSchemes by viewModel.colorSchemes.collectAsState(emptyList())
|
||||||
|
val typographyThemes by viewModel.typographySchemes.collectAsState(emptyList())
|
||||||
val shapeThemes by viewModel.shapeSchemes.collectAsState(emptyList())
|
val shapeThemes by viewModel.shapeSchemes.collectAsState(emptyList())
|
||||||
val transparencySchemes by viewModel.transparencySchemes.collectAsState(emptyList())
|
val transparencySchemes by viewModel.transparencySchemes.collectAsState(emptyList())
|
||||||
|
|
||||||
val isValidSelection by remember {
|
val isValidSelection by remember {
|
||||||
derivedStateOf {
|
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)
|
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(
|
ListPreference(
|
||||||
stringResource(R.string.preference_screen_shapes),
|
stringResource(R.string.preference_screen_shapes),
|
||||||
icon = Icons.Rounded.CropSquare,
|
icon = Icons.Rounded.CropSquare,
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import de.mm20.launcher2.themes.shapes.Shapes
|
|||||||
import de.mm20.launcher2.themes.ThemeBundle
|
import de.mm20.launcher2.themes.ThemeBundle
|
||||||
import de.mm20.launcher2.themes.ThemeRepository
|
import de.mm20.launcher2.themes.ThemeRepository
|
||||||
import de.mm20.launcher2.themes.transparencies.Transparencies
|
import de.mm20.launcher2.themes.transparencies.Transparencies
|
||||||
|
import de.mm20.launcher2.themes.typography.Typography
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -28,6 +29,7 @@ class ExportThemeSettingsScreenVM: ViewModel(), KoinComponent {
|
|||||||
private val themeRepository: ThemeRepository by inject()
|
private val themeRepository: ThemeRepository by inject()
|
||||||
|
|
||||||
val colorSchemes = themeRepository.colors.getAll().map { it.filter { !it.builtIn } }
|
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 shapeSchemes = themeRepository.shapes.getAll().map { it.filter { !it.builtIn } }
|
||||||
val transparencySchemes = themeRepository.transparencies.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
|
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)
|
var shapeScheme by mutableStateOf<Shapes?>(null)
|
||||||
@JvmName("_setShapeScheme")
|
@JvmName("_setShapeScheme")
|
||||||
private set
|
private set
|
||||||
@ -69,6 +79,7 @@ class ExportThemeSettingsScreenVM: ViewModel(), KoinComponent {
|
|||||||
author = themeAuthor.takeIf { it.isNotBlank() },
|
author = themeAuthor.takeIf { it.isNotBlank() },
|
||||||
colors = colorScheme,
|
colors = colorScheme,
|
||||||
shapes = shapeScheme,
|
shapes = shapeScheme,
|
||||||
|
typography = typographyScheme,
|
||||||
transparencies = transparencyScheme,
|
transparencies = transparencyScheme,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import androidx.compose.material.icons.rounded.MoreVert
|
|||||||
import androidx.compose.material.icons.rounded.Opacity
|
import androidx.compose.material.icons.rounded.Opacity
|
||||||
import androidx.compose.material.icons.rounded.Palette
|
import androidx.compose.material.icons.rounded.Palette
|
||||||
import androidx.compose.material.icons.rounded.Star
|
import androidx.compose.material.icons.rounded.Star
|
||||||
|
import androidx.compose.material.icons.rounded.TextFields
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.FilledTonalIconButton
|
import androidx.compose.material3.FilledTonalIconButton
|
||||||
import androidx.compose.material3.FilterChip
|
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.LocalTransparencyScheme
|
||||||
import de.mm20.launcher2.ui.theme.transparency.transparency
|
import de.mm20.launcher2.ui.theme.transparency.transparency
|
||||||
import de.mm20.launcher2.ui.theme.transparency.transparencySchemeOf
|
import de.mm20.launcher2.ui.theme.transparency.transparencySchemeOf
|
||||||
|
import de.mm20.launcher2.ui.theme.typography.typographyOf
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@ -124,6 +126,7 @@ fun ImportThemeSettingsScreen(
|
|||||||
if (darkModePreview) darkColorSchemeOf(it) else lightColorSchemeOf(it)
|
if (darkModePreview) darkColorSchemeOf(it) else lightColorSchemeOf(it)
|
||||||
} ?: MaterialTheme.colorScheme,
|
} ?: MaterialTheme.colorScheme,
|
||||||
shapes = themeBundle.shapes?.let { shapesOf(it) } ?: MaterialTheme.shapes,
|
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
|
val transparencies = themeBundle.transparencies?.let { transparencySchemeOf(it) } ?: MaterialTheme.transparency
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
@ -153,6 +156,21 @@ fun ImportThemeSettingsScreen(
|
|||||||
} else null,
|
} 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) {
|
if (themeBundle.shapes != null) {
|
||||||
Preference(
|
Preference(
|
||||||
icon = Icons.Rounded.CropSquare,
|
icon = Icons.Rounded.CropSquare,
|
||||||
|
|||||||
@ -29,6 +29,9 @@ class ImportThemeSettingsScreenVM : ViewModel(), KoinComponent {
|
|||||||
var colorsExists by mutableStateOf(false)
|
var colorsExists by mutableStateOf(false)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var typographyExists by mutableStateOf(false)
|
||||||
|
private set
|
||||||
|
|
||||||
var shapesExists by mutableStateOf(false)
|
var shapesExists by mutableStateOf(false)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@ -56,12 +59,15 @@ class ImportThemeSettingsScreenVM : ViewModel(), KoinComponent {
|
|||||||
if (theme != null) {
|
if (theme != null) {
|
||||||
val colors =
|
val colors =
|
||||||
theme.colors?.id?.let { themeRepository.colors.get(it) }?.first()
|
theme.colors?.id?.let { themeRepository.colors.get(it) }?.first()
|
||||||
|
val typography =
|
||||||
|
theme.typography?.id?.let { themeRepository.typographies.get(it) }?.first()
|
||||||
val shapes =
|
val shapes =
|
||||||
theme.shapes?.id?.let { themeRepository.shapes.get(it) }?.first()
|
theme.shapes?.id?.let { themeRepository.shapes.get(it) }?.first()
|
||||||
val transparencies =
|
val transparencies =
|
||||||
theme.transparencies?.id?.let { themeRepository.transparencies.get(it) }?.first()
|
theme.transparencies?.id?.let { themeRepository.transparencies.get(it) }?.first()
|
||||||
|
|
||||||
colorsExists = colors != null
|
colorsExists = colors != null
|
||||||
|
typographyExists = typography != null
|
||||||
shapesExists = shapes != null
|
shapesExists = shapes != null
|
||||||
transparenciesExists = transparencies != null
|
transparenciesExists = transparencies != null
|
||||||
themeBundle = theme
|
themeBundle = theme
|
||||||
@ -81,6 +87,7 @@ class ImportThemeSettingsScreenVM : ViewModel(), KoinComponent {
|
|||||||
val themeBundle = this.themeBundle ?: return null
|
val themeBundle = this.themeBundle ?: return null
|
||||||
|
|
||||||
val colors = themeBundle.colors
|
val colors = themeBundle.colors
|
||||||
|
val typography = themeBundle.typography
|
||||||
val shapes = themeBundle.shapes
|
val shapes = themeBundle.shapes
|
||||||
val transparencies = themeBundle.transparencies
|
val transparencies = themeBundle.transparencies
|
||||||
|
|
||||||
@ -100,6 +107,16 @@ class ImportThemeSettingsScreenVM : ViewModel(), KoinComponent {
|
|||||||
uiSettings.setColorsId(colors.id)
|
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 (shapes != null) {
|
||||||
if (shapesExist) {
|
if (shapesExist) {
|
||||||
themeRepository.shapes.update(shapes)
|
themeRepository.shapes.update(shapes)
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import de.mm20.launcher2.themes.colors.DefaultLightColorScheme
|
|||||||
import de.mm20.launcher2.themes.colors.EmptyCorePalette
|
import de.mm20.launcher2.themes.colors.EmptyCorePalette
|
||||||
import de.mm20.launcher2.themes.shapes.Shapes
|
import de.mm20.launcher2.themes.shapes.Shapes
|
||||||
import de.mm20.launcher2.themes.transparencies.Transparencies
|
import de.mm20.launcher2.themes.transparencies.Transparencies
|
||||||
|
import de.mm20.launcher2.themes.typography.Typography
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.SerializationException
|
import kotlinx.serialization.SerializationException
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
@ -26,6 +27,7 @@ data class ThemeBundle(
|
|||||||
val name: String,
|
val name: String,
|
||||||
val author: String? = null,
|
val author: String? = null,
|
||||||
val colors: Colors? = null,
|
val colors: Colors? = null,
|
||||||
|
val typography: Typography? = null,
|
||||||
val shapes: Shapes? = null,
|
val shapes: Shapes? = null,
|
||||||
val transparencies: Transparencies? = null,
|
val transparencies: Transparencies? = null,
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -216,6 +216,7 @@ sealed interface FontWeight {
|
|||||||
* Absolute font weight, e.g. 400 for normal, 700 for bold.
|
* Absolute font weight, e.g. 400 for normal, 700 for bold.
|
||||||
*/
|
*/
|
||||||
@JvmInline
|
@JvmInline
|
||||||
|
@Serializable
|
||||||
value class Absolute(val weight: Int) : FontWeight
|
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,
|
* the emphasized style with a relative weight of 100 will have a weight of 500,
|
||||||
*/
|
*/
|
||||||
@JvmInline
|
@JvmInline
|
||||||
|
@Serializable
|
||||||
value class Relative(val relativeWeight: Int) : FontWeight
|
value class Relative(val relativeWeight: Int) : FontWeight
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user