优化代码
This commit is contained in:
@@ -1,151 +1,13 @@
|
||||
package io.legado.app.ui.theme
|
||||
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialExpressiveTheme
|
||||
import androidx.compose.material3.MotionScheme
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||
import top.yukonga.miuix.kmp.theme.ThemeController
|
||||
import io.legado.app.ui.theme.CustomColorScheme
|
||||
import io.legado.app.ui.theme.ThemeResolver
|
||||
|
||||
// 用户自定义的颜色集合
|
||||
data class UserColorPalette(
|
||||
val primaryColor: Color, // 用户定义的主题色
|
||||
val secondaryColor: Color, // 用户定义的次要主题色
|
||||
val backgroundColor: Color, // 用户定义的背景色
|
||||
val primaryFontColor: Color, // 用户定义的主要字体色
|
||||
val secondaryFontColor: Color, // 用户定义的次要字体色
|
||||
val labelContainerColor: Color // 用户定义的标签容器色
|
||||
)
|
||||
|
||||
// 将用户自定义颜色映射到 Material Theme 的 ColorScheme
|
||||
fun generateColorScheme(userPalette: UserColorPalette, isDark: Boolean): androidx.compose.material3.ColorScheme {
|
||||
return if (isDark) {
|
||||
darkColorScheme(
|
||||
primary = userPalette.primaryColor,
|
||||
onPrimary = userPalette.primaryFontColor, // 关键映射:主要字体色 -> onPrimary
|
||||
primaryContainer = userPalette.labelContainerColor, // 关键映射:标签容器色 -> primaryContainer
|
||||
onPrimaryContainer = userPalette.primaryFontColor,
|
||||
|
||||
secondary = userPalette.secondaryColor,
|
||||
onSecondary = userPalette.secondaryFontColor,
|
||||
secondaryContainer = userPalette.labelContainerColor,
|
||||
onSecondaryContainer = userPalette.secondaryFontColor,
|
||||
|
||||
tertiary = userPalette.secondaryColor, // 可以将次要主题色也用作第三色
|
||||
onTertiary = userPalette.secondaryFontColor,
|
||||
|
||||
background = userPalette.backgroundColor,
|
||||
surface = userPalette.backgroundColor,
|
||||
onBackground = userPalette.primaryFontColor,
|
||||
onSurface = userPalette.primaryFontColor, // 关键映射:主要字体色 -> onSurface
|
||||
surfaceVariant = userPalette.labelContainerColor,
|
||||
onSurfaceVariant = userPalette.secondaryFontColor, // 关键映射:次要字体色 -> onSurfaceVariant
|
||||
|
||||
// 其他颜色
|
||||
error = Color(0xFFB3261E),
|
||||
onError = Color(0xFFFFFFFF),
|
||||
errorContainer = Color(0xFFF9DEDC),
|
||||
onErrorContainer = Color(0xFF410E0B),
|
||||
outline = Color(0xFF79747E),
|
||||
outlineVariant = Color(0xFFC4C7C5),
|
||||
scrim = Color(0xFF000000),
|
||||
|
||||
// 表面颜色变体
|
||||
surfaceBright = userPalette.backgroundColor,
|
||||
surfaceDim = userPalette.backgroundColor,
|
||||
surfaceContainer = userPalette.backgroundColor,
|
||||
surfaceContainerHigh = userPalette.backgroundColor,
|
||||
surfaceContainerHighest = userPalette.backgroundColor,
|
||||
surfaceContainerLow = userPalette.labelContainerColor,
|
||||
surfaceContainerLowest = userPalette.backgroundColor,
|
||||
|
||||
// 固定颜色
|
||||
primaryFixed = userPalette.primaryColor,
|
||||
primaryFixedDim = userPalette.primaryColor.copy(alpha = 0.8f),
|
||||
onPrimaryFixed = userPalette.primaryFontColor,
|
||||
onPrimaryFixedVariant = userPalette.primaryFontColor,
|
||||
secondaryFixed = userPalette.secondaryColor,
|
||||
secondaryFixedDim = userPalette.secondaryColor.copy(alpha = 0.8f),
|
||||
onSecondaryFixed = userPalette.secondaryFontColor,
|
||||
onSecondaryFixedVariant = userPalette.secondaryFontColor,
|
||||
tertiaryFixed = userPalette.secondaryColor,
|
||||
tertiaryFixedDim = userPalette.secondaryColor.copy(alpha = 0.8f),
|
||||
onTertiaryFixed = userPalette.secondaryFontColor,
|
||||
onTertiaryFixedVariant = userPalette.secondaryFontColor
|
||||
)
|
||||
} else {
|
||||
lightColorScheme(
|
||||
primary = userPalette.primaryColor,
|
||||
onPrimary = userPalette.primaryFontColor,
|
||||
primaryContainer = userPalette.labelContainerColor,
|
||||
onPrimaryContainer = userPalette.primaryFontColor,
|
||||
|
||||
secondary = userPalette.secondaryColor,
|
||||
onSecondary = userPalette.secondaryFontColor,
|
||||
secondaryContainer = userPalette.labelContainerColor,
|
||||
onSecondaryContainer = userPalette.secondaryFontColor,
|
||||
|
||||
tertiary = userPalette.secondaryColor,
|
||||
onTertiary = userPalette.secondaryFontColor,
|
||||
|
||||
background = userPalette.backgroundColor,
|
||||
surface = userPalette.backgroundColor,
|
||||
onBackground = userPalette.primaryFontColor,
|
||||
onSurface = userPalette.primaryFontColor,
|
||||
surfaceVariant = userPalette.labelContainerColor,
|
||||
onSurfaceVariant = userPalette.secondaryFontColor,
|
||||
|
||||
// 其他颜色
|
||||
error = Color(0xFFB3261E),
|
||||
onError = Color(0xFFFFFFFF),
|
||||
errorContainer = Color(0xFFF9DEDC),
|
||||
onErrorContainer = Color(0xFF410E0B),
|
||||
outline = Color(0xFF79747E),
|
||||
outlineVariant = Color(0xFFC4C7C5),
|
||||
scrim = Color(0xFF000000),
|
||||
|
||||
// 表面颜色变体
|
||||
surfaceBright = userPalette.backgroundColor,
|
||||
surfaceDim = userPalette.backgroundColor,
|
||||
surfaceContainer = userPalette.backgroundColor,
|
||||
surfaceContainerHigh = userPalette.backgroundColor,
|
||||
surfaceContainerHighest = userPalette.backgroundColor,
|
||||
surfaceContainerLow = userPalette.labelContainerColor,
|
||||
surfaceContainerLowest = userPalette.backgroundColor,
|
||||
|
||||
// 固定颜色
|
||||
primaryFixed = userPalette.primaryColor,
|
||||
primaryFixedDim = userPalette.primaryColor.copy(alpha = 0.8f),
|
||||
onPrimaryFixed = userPalette.primaryFontColor,
|
||||
onPrimaryFixedVariant = userPalette.primaryFontColor,
|
||||
secondaryFixed = userPalette.secondaryColor,
|
||||
secondaryFixedDim = userPalette.secondaryColor.copy(alpha = 0.8f),
|
||||
onSecondaryFixed = userPalette.secondaryFontColor,
|
||||
onSecondaryFixedVariant = userPalette.secondaryFontColor,
|
||||
tertiaryFixed = userPalette.secondaryColor,
|
||||
tertiaryFixedDim = userPalette.secondaryColor.copy(alpha = 0.8f),
|
||||
onTertiaryFixed = userPalette.secondaryFontColor,
|
||||
onTertiaryFixedVariant = userPalette.secondaryFontColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
@@ -154,17 +16,18 @@ fun AppTheme(
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
// 1. 获取基础配置
|
||||
val appThemeMode = ThemeResolver.resolveThemeMode(ThemeConfig.appTheme)
|
||||
val themeModeValue = ThemeConfig.themeMode
|
||||
val isPureBlack = ThemeConfig.isPureBlack
|
||||
val paletteStyleValue = ThemeConfig.paletteStyle
|
||||
val materialVersion = ThemeConfig.materialVersion
|
||||
val composeEngine = ThemeConfig.composeEngine
|
||||
val useMiuixMonet = ThemeConfig.useMiuixMonet
|
||||
val customPrimary = ThemeConfig.cPrimary
|
||||
val customNightPrimary = ThemeConfig.cNPrimary
|
||||
val appFontPath = ThemeConfig.appFontPath
|
||||
|
||||
|
||||
// 2. 深度个性化配置
|
||||
val enableDeepPersonalization = ThemeConfig.enableDeepPersonalization
|
||||
val themeColor = ThemeConfig.themeColor
|
||||
val secondaryThemeColor = ThemeConfig.secondaryThemeColor
|
||||
@@ -172,87 +35,44 @@ fun AppTheme(
|
||||
val secondaryTextColor = ThemeConfig.secondaryTextColor
|
||||
val themeBackgroundColor = ThemeConfig.themeBackgroundColor
|
||||
val customLabelContainerColor = ThemeConfig.labelContainerColor
|
||||
|
||||
val colorSchemeMode = ThemeResolver.resolveColorSchemeMode(themeModeValue)
|
||||
val miuixColorSchemeMode = remember(themeModeValue, useMiuixMonet) {
|
||||
ThemeResolver.resolveMiuixColorSchemeMode(themeModeValue, useMiuixMonet)
|
||||
}
|
||||
|
||||
// 加载自定义字体
|
||||
val customFontFamily = remember(ThemeConfig.appFontPath, context) {
|
||||
if (!ThemeConfig.appFontPath.isNullOrEmpty()) {
|
||||
try {
|
||||
val uri = Uri.parse(ThemeConfig.appFontPath)
|
||||
val typeface: Typeface? = if (uri.scheme == "content") {
|
||||
context.contentResolver.openFileDescriptor(uri, "r")?.use {
|
||||
Typeface.Builder(it.fileDescriptor).build()
|
||||
}
|
||||
} else {
|
||||
Typeface.createFromFile(uri.path)
|
||||
}
|
||||
typeface?.let {
|
||||
FontFamily(it)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
// 3. 加载自定义字体
|
||||
val customFontFamily = rememberCustomFont(appFontPath)
|
||||
|
||||
// 4. 解析配色方案 (Material 3 ColorScheme)
|
||||
val colorScheme = remember(
|
||||
context, appThemeMode, darkTheme, isPureBlack, customPrimary, customNightPrimary,
|
||||
enableDeepPersonalization, themeColor, secondaryThemeColor, primaryTextColor,
|
||||
secondaryTextColor, themeBackgroundColor, customLabelContainerColor,
|
||||
paletteStyleValue, materialVersion
|
||||
) {
|
||||
if (enableDeepPersonalization &&
|
||||
(themeColor != 0 || secondaryThemeColor != 0 || primaryTextColor != 0 ||
|
||||
secondaryTextColor != 0 || themeBackgroundColor != 0 || customLabelContainerColor != 0)) {
|
||||
val userPalette = UserColorPalette(
|
||||
primaryColor = if (themeColor != 0) Color(themeColor) else Color(0xFF6750A4),
|
||||
secondaryColor = if (secondaryThemeColor != 0) Color(secondaryThemeColor) else Color(0xFF625B71),
|
||||
backgroundColor = if (themeBackgroundColor != 0) Color(themeBackgroundColor) else Color(0xFFFEF7FF),
|
||||
primaryFontColor = if (primaryTextColor != 0) Color(primaryTextColor) else Color(0xFF1C1B1F),
|
||||
secondaryFontColor = if (secondaryTextColor != 0) Color(secondaryTextColor) else Color(0xFF49454F),
|
||||
labelContainerColor = if (customLabelContainerColor != 0) Color(customLabelContainerColor) else Color(0xFFF7F2FA)
|
||||
)
|
||||
generateColorScheme(userPalette, darkTheme)
|
||||
} else {
|
||||
null
|
||||
val customSeedColor = if (darkTheme) customNightPrimary else customPrimary
|
||||
ThemeEngine.getColorScheme(
|
||||
context = context,
|
||||
mode = appThemeMode,
|
||||
darkTheme = darkTheme,
|
||||
isAmoled = isPureBlack,
|
||||
paletteStyle = paletteStyleValue,
|
||||
materialVersion = materialVersion,
|
||||
customSeedColor = customSeedColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val paletteStyle = remember(paletteStyleValue) {
|
||||
ThemeResolver.resolvePaletteStyle(paletteStyleValue)
|
||||
}
|
||||
|
||||
val colorScheme =
|
||||
remember(
|
||||
context,
|
||||
appThemeMode,
|
||||
darkTheme,
|
||||
isPureBlack,
|
||||
customPrimary,
|
||||
customNightPrimary,
|
||||
enableDeepPersonalization,
|
||||
themeColor,
|
||||
secondaryThemeColor,
|
||||
primaryTextColor,
|
||||
secondaryTextColor,
|
||||
themeBackgroundColor,
|
||||
customLabelContainerColor,
|
||||
paletteStyleValue,
|
||||
materialVersion
|
||||
) {
|
||||
if (enableDeepPersonalization &&
|
||||
(themeColor != 0 ||
|
||||
secondaryThemeColor != 0 ||
|
||||
primaryTextColor != 0 ||
|
||||
secondaryTextColor != 0 ||
|
||||
themeBackgroundColor != 0 ||
|
||||
customLabelContainerColor != 0)) {
|
||||
val userPalette = UserColorPalette(
|
||||
primaryColor = if (themeColor != 0) Color(themeColor) else Color(0xFF6750A4),
|
||||
secondaryColor = if (secondaryThemeColor != 0) Color(secondaryThemeColor) else Color(0xFF625B71),
|
||||
backgroundColor = if (themeBackgroundColor != 0) Color(themeBackgroundColor) else Color(0xFFFEF7FF),
|
||||
primaryFontColor = if (primaryTextColor != 0) Color(primaryTextColor) else Color(0xFF1C1B1F),
|
||||
secondaryFontColor = if (secondaryTextColor != 0) Color(secondaryTextColor) else Color(0xFF49454F),
|
||||
labelContainerColor = if (customLabelContainerColor != 0) Color(customLabelContainerColor) else Color(0xFFF7F2FA)
|
||||
)
|
||||
generateColorScheme(userPalette, darkTheme)
|
||||
} else {
|
||||
val customSeedColor = if (darkTheme) customNightPrimary else customPrimary
|
||||
ThemeEngine.getColorScheme(
|
||||
context = context,
|
||||
mode = appThemeMode,
|
||||
darkTheme = darkTheme,
|
||||
isAmoled = isPureBlack,
|
||||
paletteStyle = paletteStyleValue,
|
||||
materialVersion = materialVersion,
|
||||
customSeedColor = customSeedColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 确定种子颜色
|
||||
val themeSeedColor = remember(appThemeMode, colorScheme.primary) {
|
||||
if (appThemeMode == AppThemeMode.Custom) {
|
||||
val seed = if (darkTheme) customNightPrimary else customPrimary
|
||||
@@ -261,21 +81,13 @@ fun AppTheme(
|
||||
colorScheme.primary
|
||||
}
|
||||
}
|
||||
val miuixPaletteStyle = remember(paletteStyleValue) {
|
||||
ThemeResolver.resolveMiuixPaletteStyle(paletteStyleValue)
|
||||
}
|
||||
val miuixColorSpec = remember(materialVersion, paletteStyleValue) {
|
||||
ThemeResolver.resolveMiuixColorSpec(materialVersion, paletteStyleValue)
|
||||
}
|
||||
|
||||
// 6. 构造 Legado 主题模式数据
|
||||
val themeColors = remember(
|
||||
colorScheme,
|
||||
darkTheme,
|
||||
themeSeedColor,
|
||||
paletteStyle,
|
||||
colorSchemeMode,
|
||||
composeEngine
|
||||
colorScheme, darkTheme, themeSeedColor, paletteStyleValue, composeEngine, appThemeMode
|
||||
) {
|
||||
val paletteStyle = ThemeResolver.resolvePaletteStyle(paletteStyleValue)
|
||||
val colorSchemeMode = ThemeResolver.resolveColorSchemeMode(ThemeConfig.themeMode)
|
||||
LegadoThemeMode(
|
||||
colorScheme = colorScheme,
|
||||
isDark = darkTheme,
|
||||
@@ -287,258 +99,22 @@ fun AppTheme(
|
||||
)
|
||||
}
|
||||
|
||||
// 7. 提供主题数据并根据引擎渲染
|
||||
CompositionLocalProvider(
|
||||
LocalLegadoThemeColors provides themeColors
|
||||
) {
|
||||
if (ThemeResolver.isMiuixEngine(themeColors.composeEngine)) {
|
||||
val keyColor = if (useMiuixMonet &&
|
||||
themeColors.useDynamicColor &&
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
) {
|
||||
// colorResource 只能在 @Composable 上下文中调用
|
||||
// 这里使用一个固定颜色作为替代
|
||||
Color(0xFF6750A4)
|
||||
} else {
|
||||
themeSeedColor
|
||||
}
|
||||
|
||||
val controller = remember(
|
||||
miuixColorSchemeMode,
|
||||
useMiuixMonet,
|
||||
keyColor,
|
||||
miuixPaletteStyle,
|
||||
miuixColorSpec,
|
||||
darkTheme
|
||||
) {
|
||||
if (useMiuixMonet) {
|
||||
ThemeController(
|
||||
colorSchemeMode = miuixColorSchemeMode,
|
||||
keyColor = keyColor,
|
||||
paletteStyle = miuixPaletteStyle,
|
||||
colorSpec = miuixColorSpec,
|
||||
isDark = darkTheme
|
||||
)
|
||||
} else {
|
||||
ThemeController(
|
||||
colorSchemeMode = miuixColorSchemeMode,
|
||||
isDark = darkTheme
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
MiuixTheme(controller = controller) {
|
||||
val miuixStyles = MiuixTheme.textStyles
|
||||
val legadoTypography = remember<LegadoTypography>(miuixStyles, customFontFamily) {
|
||||
val typography = miuixStylesToM3Typography(miuixStyles)
|
||||
val baseLegadoTypography = typography.toLegadoTypography()
|
||||
if (customFontFamily != null) {
|
||||
baseLegadoTypography.copy(
|
||||
headlineLarge = baseLegadoTypography.headlineLarge.copy(fontFamily = customFontFamily),
|
||||
headlineLargeEmphasized = baseLegadoTypography.headlineLargeEmphasized.copy(fontFamily = customFontFamily),
|
||||
headlineMedium = baseLegadoTypography.headlineMedium.copy(fontFamily = customFontFamily),
|
||||
headlineMediumEmphasized = baseLegadoTypography.headlineMediumEmphasized.copy(fontFamily = customFontFamily),
|
||||
headlineSmall = baseLegadoTypography.headlineSmall.copy(fontFamily = customFontFamily),
|
||||
headlineSmallEmphasized = baseLegadoTypography.headlineSmallEmphasized.copy(fontFamily = customFontFamily),
|
||||
titleLarge = baseLegadoTypography.titleLarge.copy(fontFamily = customFontFamily),
|
||||
titleLargeEmphasized = baseLegadoTypography.titleLargeEmphasized.copy(fontFamily = customFontFamily),
|
||||
titleMedium = baseLegadoTypography.titleMedium.copy(fontFamily = customFontFamily),
|
||||
titleMediumEmphasized = baseLegadoTypography.titleMediumEmphasized.copy(fontFamily = customFontFamily),
|
||||
titleSmall = baseLegadoTypography.titleSmall.copy(fontFamily = customFontFamily),
|
||||
titleSmallEmphasized = baseLegadoTypography.titleSmallEmphasized.copy(fontFamily = customFontFamily),
|
||||
bodyLarge = baseLegadoTypography.bodyLarge.copy(fontFamily = customFontFamily),
|
||||
bodyLargeEmphasized = baseLegadoTypography.bodyLargeEmphasized.copy(fontFamily = customFontFamily),
|
||||
bodyMedium = baseLegadoTypography.bodyMedium.copy(fontFamily = customFontFamily),
|
||||
bodyMediumEmphasized = baseLegadoTypography.bodyMediumEmphasized.copy(fontFamily = customFontFamily),
|
||||
bodySmall = baseLegadoTypography.bodySmall.copy(fontFamily = customFontFamily),
|
||||
bodySmallEmphasized = baseLegadoTypography.bodySmallEmphasized.copy(fontFamily = customFontFamily),
|
||||
labelLarge = baseLegadoTypography.labelLarge.copy(fontFamily = customFontFamily),
|
||||
labelLargeEmphasized = baseLegadoTypography.labelLargeEmphasized.copy(fontFamily = customFontFamily),
|
||||
labelMedium = baseLegadoTypography.labelMedium.copy(fontFamily = customFontFamily),
|
||||
labelMediumEmphasized = baseLegadoTypography.labelMediumEmphasized.copy(fontFamily = customFontFamily),
|
||||
labelSmall = baseLegadoTypography.labelSmall.copy(fontFamily = customFontFamily),
|
||||
labelSmallEmphasized = baseLegadoTypography.labelSmallEmphasized.copy(fontFamily = customFontFamily)
|
||||
)
|
||||
} else {
|
||||
baseLegadoTypography
|
||||
}
|
||||
}
|
||||
|
||||
val miuixColorScheme = MiuixTheme.colorScheme
|
||||
|
||||
val mappedColorScheme = remember(miuixColorScheme) {
|
||||
val customBgColor = if (ThemeConfig.enableDeepPersonalization && ThemeConfig.themeBackgroundColor != 0) {
|
||||
Color(ThemeConfig.themeBackgroundColor)
|
||||
} else {
|
||||
miuixColorScheme.background
|
||||
}
|
||||
val customFontColor = if (ThemeConfig.enableDeepPersonalization && ThemeConfig.primaryTextColor != 0) {
|
||||
Color(ThemeConfig.primaryTextColor)
|
||||
} else {
|
||||
miuixColorScheme.onSurface
|
||||
}
|
||||
val customTopBarColor = miuixColorScheme.surface
|
||||
val customNavBarColor = miuixColorScheme.surface
|
||||
|
||||
LegadoColorScheme(
|
||||
primary = miuixColorScheme.primary,
|
||||
onPrimary = miuixColorScheme.onPrimary,
|
||||
primaryContainer = miuixColorScheme.primaryContainer,
|
||||
onPrimaryContainer = miuixColorScheme.onPrimaryContainer,
|
||||
inversePrimary = miuixColorScheme.primaryVariant,
|
||||
|
||||
secondary = miuixColorScheme.secondary,
|
||||
onSecondary = miuixColorScheme.onSecondary,
|
||||
secondaryContainer = miuixColorScheme.secondaryContainer,
|
||||
onSecondaryContainer = miuixColorScheme.onSecondaryContainer,
|
||||
|
||||
tertiary = miuixColorScheme.primary,
|
||||
onTertiary = miuixColorScheme.onPrimary,
|
||||
tertiaryContainer = miuixColorScheme.primaryContainer,
|
||||
onTertiaryContainer = miuixColorScheme.primaryVariant,
|
||||
|
||||
background = customBgColor,
|
||||
onBackground = customFontColor,
|
||||
|
||||
surface = miuixColorScheme.surface,
|
||||
onSurface = customFontColor,
|
||||
surfaceVariant = miuixColorScheme.surfaceVariant,
|
||||
onSurfaceVariant = customFontColor,
|
||||
surfaceTint = miuixColorScheme.primary,
|
||||
inverseSurface = miuixColorScheme.onSurface,
|
||||
inverseOnSurface = miuixColorScheme.surface,
|
||||
|
||||
error = miuixColorScheme.error,
|
||||
onError = miuixColorScheme.onError,
|
||||
errorContainer = miuixColorScheme.errorContainer,
|
||||
onErrorContainer = miuixColorScheme.onErrorContainer,
|
||||
|
||||
outline = miuixColorScheme.outline,
|
||||
outlineVariant = miuixColorScheme.dividerLine,
|
||||
scrim = miuixColorScheme.windowDimming,
|
||||
|
||||
surfaceBright = miuixColorScheme.surface,
|
||||
surfaceDim = miuixColorScheme.background,
|
||||
surfaceContainer = miuixColorScheme.surfaceContainer,
|
||||
surfaceContainerHigh = miuixColorScheme.surfaceContainerHigh,
|
||||
surfaceContainerHighest = miuixColorScheme.surfaceContainerHighest,
|
||||
surfaceContainerLow = miuixColorScheme.secondaryContainer.copy(alpha = 0.32f),
|
||||
surfaceContainerLowest = miuixColorScheme.background,
|
||||
|
||||
primaryFixed = miuixColorScheme.primaryContainer,
|
||||
primaryFixedDim = miuixColorScheme.primary,
|
||||
onPrimaryFixed = miuixColorScheme.onPrimaryContainer,
|
||||
onPrimaryFixedVariant = miuixColorScheme.onPrimary,
|
||||
secondaryFixed = miuixColorScheme.secondaryContainer,
|
||||
secondaryFixedDim = miuixColorScheme.secondary,
|
||||
onSecondaryFixed = miuixColorScheme.onSecondaryContainer,
|
||||
onSecondaryFixedVariant = miuixColorScheme.onSecondary,
|
||||
tertiaryFixed = miuixColorScheme.tertiaryContainer,
|
||||
tertiaryFixedDim = miuixColorScheme.tertiaryContainerVariant,
|
||||
onTertiaryFixed = miuixColorScheme.onTertiaryContainer,
|
||||
onTertiaryFixedVariant = miuixColorScheme.onTertiaryContainer,
|
||||
|
||||
cardContainer = miuixColorScheme.disabledPrimary,
|
||||
onCardContainer = miuixColorScheme.primary,
|
||||
onSheetContent = miuixColorScheme.surface.copy(alpha = 0.5f)
|
||||
)
|
||||
}
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalLegadoTypography provides legadoTypography,
|
||||
LocalLegadoColorScheme provides mappedColorScheme
|
||||
) {
|
||||
AppBackground(darkTheme = darkTheme) { content() }
|
||||
}
|
||||
}
|
||||
MiuixThemeWrapper(
|
||||
themeColors = themeColors,
|
||||
customFontFamily = customFontFamily,
|
||||
content = content
|
||||
)
|
||||
} else {
|
||||
val materialTypography = remember(customFontFamily) {
|
||||
if (customFontFamily != null) {
|
||||
Typography(
|
||||
headlineLarge = Typography().headlineLarge.copy(fontFamily = customFontFamily),
|
||||
headlineMedium = Typography().headlineMedium.copy(fontFamily = customFontFamily),
|
||||
headlineSmall = Typography().headlineSmall.copy(fontFamily = customFontFamily),
|
||||
titleLarge = Typography().titleLarge.copy(fontFamily = customFontFamily),
|
||||
titleMedium = Typography().titleMedium.copy(fontFamily = customFontFamily),
|
||||
titleSmall = Typography().titleSmall.copy(fontFamily = customFontFamily),
|
||||
bodyLarge = Typography().bodyLarge.copy(fontFamily = customFontFamily),
|
||||
bodyMedium = Typography().bodyMedium.copy(fontFamily = customFontFamily),
|
||||
bodySmall = Typography().bodySmall.copy(fontFamily = customFontFamily),
|
||||
labelLarge = Typography().labelLarge.copy(fontFamily = customFontFamily),
|
||||
labelMedium = Typography().labelMedium.copy(fontFamily = customFontFamily),
|
||||
labelSmall = Typography().labelSmall.copy(fontFamily = customFontFamily)
|
||||
)
|
||||
} else {
|
||||
Typography()
|
||||
}
|
||||
}
|
||||
MaterialExpressiveTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = materialTypography,
|
||||
motionScheme = MotionScheme.expressive(),
|
||||
shapes = Shapes()
|
||||
) {
|
||||
val legadoTypography = remember(materialTypography, customFontFamily) {
|
||||
val baseLegadoTypography = materialTypography.toLegadoTypography()
|
||||
if (customFontFamily != null) {
|
||||
baseLegadoTypography.copy(
|
||||
headlineLarge = baseLegadoTypography.headlineLarge.copy(fontFamily = customFontFamily),
|
||||
headlineLargeEmphasized = baseLegadoTypography.headlineLargeEmphasized.copy(fontFamily = customFontFamily),
|
||||
headlineMedium = baseLegadoTypography.headlineMedium.copy(fontFamily = customFontFamily),
|
||||
headlineMediumEmphasized = baseLegadoTypography.headlineMediumEmphasized.copy(fontFamily = customFontFamily),
|
||||
headlineSmall = baseLegadoTypography.headlineSmall.copy(fontFamily = customFontFamily),
|
||||
headlineSmallEmphasized = baseLegadoTypography.headlineSmallEmphasized.copy(fontFamily = customFontFamily),
|
||||
titleLarge = baseLegadoTypography.titleLarge.copy(fontFamily = customFontFamily),
|
||||
titleLargeEmphasized = baseLegadoTypography.titleLargeEmphasized.copy(fontFamily = customFontFamily),
|
||||
titleMedium = baseLegadoTypography.titleMedium.copy(fontFamily = customFontFamily),
|
||||
titleMediumEmphasized = baseLegadoTypography.titleMediumEmphasized.copy(fontFamily = customFontFamily),
|
||||
titleSmall = baseLegadoTypography.titleSmall.copy(fontFamily = customFontFamily),
|
||||
titleSmallEmphasized = baseLegadoTypography.titleSmallEmphasized.copy(fontFamily = customFontFamily),
|
||||
bodyLarge = baseLegadoTypography.bodyLarge.copy(fontFamily = customFontFamily),
|
||||
bodyLargeEmphasized = baseLegadoTypography.bodyLargeEmphasized.copy(fontFamily = customFontFamily),
|
||||
bodyMedium = baseLegadoTypography.bodyMedium.copy(fontFamily = customFontFamily),
|
||||
bodyMediumEmphasized = baseLegadoTypography.bodyMediumEmphasized.copy(fontFamily = customFontFamily),
|
||||
bodySmall = baseLegadoTypography.bodySmall.copy(fontFamily = customFontFamily),
|
||||
bodySmallEmphasized = baseLegadoTypography.bodySmallEmphasized.copy(fontFamily = customFontFamily),
|
||||
labelLarge = baseLegadoTypography.labelLarge.copy(fontFamily = customFontFamily),
|
||||
labelLargeEmphasized = baseLegadoTypography.labelLargeEmphasized.copy(fontFamily = customFontFamily),
|
||||
labelMedium = baseLegadoTypography.labelMedium.copy(fontFamily = customFontFamily),
|
||||
labelMediumEmphasized = baseLegadoTypography.labelMediumEmphasized.copy(fontFamily = customFontFamily),
|
||||
labelSmall = baseLegadoTypography.labelSmall.copy(fontFamily = customFontFamily),
|
||||
labelSmallEmphasized = baseLegadoTypography.labelSmallEmphasized.copy(fontFamily = customFontFamily)
|
||||
)
|
||||
} else {
|
||||
baseLegadoTypography
|
||||
}
|
||||
}
|
||||
val semanticColors = remember(colorScheme) {
|
||||
val customBgColor = if (ThemeConfig.enableDeepPersonalization && ThemeConfig.themeBackgroundColor != 0) {
|
||||
Color(ThemeConfig.themeBackgroundColor)
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
val customFontColor = if (ThemeConfig.enableDeepPersonalization && ThemeConfig.primaryTextColor != 0) {
|
||||
Color(ThemeConfig.primaryTextColor)
|
||||
} else {
|
||||
colorScheme.onSurface
|
||||
}
|
||||
val customTopBarColor = colorScheme.surface
|
||||
val customNavBarColor = colorScheme.surface
|
||||
|
||||
colorScheme.toLegadoColorScheme(
|
||||
customBgColor = customBgColor,
|
||||
customFontColor = customFontColor,
|
||||
customTopBarColor = customTopBarColor,
|
||||
customNavBarColor = customNavBarColor
|
||||
)
|
||||
}
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalLegadoTypography provides legadoTypography,
|
||||
LocalLegadoColorScheme provides semanticColors
|
||||
) {
|
||||
AppBackground(darkTheme = darkTheme) { content() }
|
||||
}
|
||||
}
|
||||
MaterialThemeWrapper(
|
||||
themeColors = themeColors,
|
||||
customFontFamily = customFontFamily,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
package io.legado.app.ui.theme
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialExpressiveTheme
|
||||
import androidx.compose.material3.MotionScheme
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import io.legado.app.ui.config.themeConfig.ThemeConfig
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||
import top.yukonga.miuix.kmp.theme.ThemeController
|
||||
import top.yukonga.miuix.kmp.theme.TextStyles
|
||||
|
||||
@Composable
|
||||
fun rememberCustomFont(fontPath: String?): FontFamily? {
|
||||
val context = LocalContext.current
|
||||
return remember(fontPath, context) {
|
||||
if (!fontPath.isNullOrEmpty()) {
|
||||
try {
|
||||
val uri = Uri.parse(fontPath)
|
||||
val typeface: Typeface? = if (uri.scheme == "content") {
|
||||
context.contentResolver.openFileDescriptor(uri, "r")?.use {
|
||||
Typeface.Builder(it.fileDescriptor).build()
|
||||
}
|
||||
} else {
|
||||
Typeface.createFromFile(uri.path)
|
||||
}
|
||||
typeface?.let { FontFamily(it) }
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun MiuixThemeWrapper(
|
||||
themeColors: LegadoThemeMode,
|
||||
customFontFamily: FontFamily?,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val themeModeValue = ThemeConfig.themeMode
|
||||
val useMiuixMonet = ThemeConfig.useMiuixMonet
|
||||
val paletteStyleValue = ThemeConfig.paletteStyle
|
||||
val materialVersion = ThemeConfig.materialVersion
|
||||
val darkTheme = themeColors.isDark
|
||||
|
||||
val miuixColorSchemeMode = remember(themeModeValue, useMiuixMonet) {
|
||||
ThemeResolver.resolveMiuixColorSchemeMode(themeModeValue, useMiuixMonet)
|
||||
}
|
||||
val miuixPaletteStyle = remember(paletteStyleValue) {
|
||||
ThemeResolver.resolveMiuixPaletteStyle(paletteStyleValue)
|
||||
}
|
||||
val miuixColorSpec = remember(materialVersion, paletteStyleValue) {
|
||||
ThemeResolver.resolveMiuixColorSpec(materialVersion, paletteStyleValue)
|
||||
}
|
||||
|
||||
val keyColor = if (useMiuixMonet &&
|
||||
themeColors.useDynamicColor &&
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
) {
|
||||
Color(0xFF6750A4) // 默认颜色,因为 colorResource 只能在 Composable 中
|
||||
} else {
|
||||
themeColors.seedColor
|
||||
}
|
||||
|
||||
val controller = remember(
|
||||
miuixColorSchemeMode,
|
||||
useMiuixMonet,
|
||||
keyColor,
|
||||
miuixPaletteStyle,
|
||||
miuixColorSpec,
|
||||
darkTheme
|
||||
) {
|
||||
if (useMiuixMonet) {
|
||||
ThemeController(
|
||||
colorSchemeMode = miuixColorSchemeMode,
|
||||
keyColor = keyColor,
|
||||
paletteStyle = miuixPaletteStyle,
|
||||
colorSpec = miuixColorSpec,
|
||||
isDark = darkTheme
|
||||
)
|
||||
} else {
|
||||
ThemeController(
|
||||
colorSchemeMode = miuixColorSchemeMode,
|
||||
isDark = darkTheme
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
MiuixTheme(controller = controller) {
|
||||
val miuixStyles = MiuixTheme.textStyles
|
||||
val legadoTypography = remember(miuixStyles, customFontFamily) {
|
||||
miuixStylesToM3Typography(miuixStyles)
|
||||
.toLegadoTypography()
|
||||
.withFont(customFontFamily)
|
||||
}
|
||||
|
||||
val miuixColorScheme = MiuixTheme.colorScheme
|
||||
val mappedColorScheme = remember(miuixColorScheme) {
|
||||
val customBgColor = if (ThemeConfig.enableDeepPersonalization && ThemeConfig.themeBackgroundColor != 0) {
|
||||
Color(ThemeConfig.themeBackgroundColor)
|
||||
} else {
|
||||
miuixColorScheme.background
|
||||
}
|
||||
val customFontColor = if (ThemeConfig.enableDeepPersonalization && ThemeConfig.primaryTextColor != 0) {
|
||||
Color(ThemeConfig.primaryTextColor)
|
||||
} else {
|
||||
miuixColorScheme.onSurface
|
||||
}
|
||||
|
||||
LegadoColorScheme(
|
||||
primary = miuixColorScheme.primary,
|
||||
onPrimary = miuixColorScheme.onPrimary,
|
||||
primaryContainer = miuixColorScheme.primaryContainer,
|
||||
onPrimaryContainer = miuixColorScheme.onPrimaryContainer,
|
||||
inversePrimary = miuixColorScheme.primaryVariant,
|
||||
|
||||
secondary = miuixColorScheme.secondary,
|
||||
onSecondary = miuixColorScheme.onSecondary,
|
||||
secondaryContainer = miuixColorScheme.secondaryContainer,
|
||||
onSecondaryContainer = miuixColorScheme.onSecondaryContainer,
|
||||
|
||||
tertiary = miuixColorScheme.primary,
|
||||
onTertiary = miuixColorScheme.onPrimary,
|
||||
tertiaryContainer = miuixColorScheme.primaryContainer,
|
||||
onTertiaryContainer = miuixColorScheme.primaryVariant,
|
||||
|
||||
background = customBgColor,
|
||||
onBackground = customFontColor,
|
||||
|
||||
surface = miuixColorScheme.surface,
|
||||
onSurface = customFontColor,
|
||||
surfaceVariant = miuixColorScheme.surfaceVariant,
|
||||
onSurfaceVariant = customFontColor,
|
||||
surfaceTint = miuixColorScheme.primary,
|
||||
inverseSurface = miuixColorScheme.onSurface,
|
||||
inverseOnSurface = miuixColorScheme.surface,
|
||||
|
||||
error = miuixColorScheme.error,
|
||||
onError = miuixColorScheme.onError,
|
||||
errorContainer = miuixColorScheme.errorContainer,
|
||||
onErrorContainer = miuixColorScheme.onErrorContainer,
|
||||
|
||||
outline = miuixColorScheme.outline,
|
||||
outlineVariant = miuixColorScheme.dividerLine,
|
||||
scrim = miuixColorScheme.windowDimming,
|
||||
|
||||
surfaceBright = miuixColorScheme.surface,
|
||||
surfaceDim = miuixColorScheme.background,
|
||||
surfaceContainer = miuixColorScheme.surfaceContainer,
|
||||
surfaceContainerHigh = miuixColorScheme.surfaceContainerHigh,
|
||||
surfaceContainerHighest = miuixColorScheme.surfaceContainerHighest,
|
||||
surfaceContainerLow = miuixColorScheme.surfaceContainer,
|
||||
surfaceContainerLowest = miuixColorScheme.background,
|
||||
|
||||
primaryFixed = miuixColorScheme.primaryContainer,
|
||||
primaryFixedDim = miuixColorScheme.primary,
|
||||
onPrimaryFixed = miuixColorScheme.onPrimaryContainer,
|
||||
onPrimaryFixedVariant = miuixColorScheme.onPrimary,
|
||||
secondaryFixed = miuixColorScheme.secondaryContainer,
|
||||
secondaryFixedDim = miuixColorScheme.secondary,
|
||||
onSecondaryFixed = miuixColorScheme.onSecondaryContainer,
|
||||
onSecondaryFixedVariant = miuixColorScheme.onSecondary,
|
||||
tertiaryFixed = miuixColorScheme.tertiaryContainer,
|
||||
tertiaryFixedDim = miuixColorScheme.tertiaryContainerVariant,
|
||||
onTertiaryFixed = miuixColorScheme.onTertiaryContainer,
|
||||
onTertiaryFixedVariant = miuixColorScheme.onTertiaryContainer,
|
||||
|
||||
cardContainer = miuixColorScheme.surfaceContainer,
|
||||
onCardContainer = miuixColorScheme.onSurface,
|
||||
onSheetContent = miuixColorScheme.surface.copy(alpha = 0.5f)
|
||||
)
|
||||
}
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalLegadoTypography provides legadoTypography,
|
||||
LocalLegadoColorScheme provides mappedColorScheme
|
||||
) {
|
||||
AppBackground(darkTheme = darkTheme) { content() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun MaterialThemeWrapper(
|
||||
themeColors: LegadoThemeMode,
|
||||
customFontFamily: FontFamily?,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val darkTheme = themeColors.isDark
|
||||
val colorScheme = themeColors.colorScheme
|
||||
|
||||
val materialTypography = remember(customFontFamily) {
|
||||
val base = Typography()
|
||||
if (customFontFamily != null) {
|
||||
base.copy(
|
||||
headlineLarge = base.headlineLarge.copy(fontFamily = customFontFamily),
|
||||
headlineMedium = base.headlineMedium.copy(fontFamily = customFontFamily),
|
||||
headlineSmall = base.headlineSmall.copy(fontFamily = customFontFamily),
|
||||
titleLarge = base.titleLarge.copy(fontFamily = customFontFamily),
|
||||
titleMedium = base.titleMedium.copy(fontFamily = customFontFamily),
|
||||
titleSmall = base.titleSmall.copy(fontFamily = customFontFamily),
|
||||
bodyLarge = base.bodyLarge.copy(fontFamily = customFontFamily),
|
||||
bodyMedium = base.bodyMedium.copy(fontFamily = customFontFamily),
|
||||
bodySmall = base.bodySmall.copy(fontFamily = customFontFamily),
|
||||
labelLarge = base.labelLarge.copy(fontFamily = customFontFamily),
|
||||
labelMedium = base.labelMedium.copy(fontFamily = customFontFamily),
|
||||
labelSmall = base.labelSmall.copy(fontFamily = customFontFamily)
|
||||
)
|
||||
} else {
|
||||
base
|
||||
}
|
||||
}
|
||||
|
||||
MaterialExpressiveTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = materialTypography,
|
||||
motionScheme = MotionScheme.expressive(),
|
||||
shapes = Shapes()
|
||||
) {
|
||||
val legadoTypography = remember(materialTypography, customFontFamily) {
|
||||
materialTypography.toLegadoTypography().withFont(customFontFamily)
|
||||
}
|
||||
val semanticColors = remember(colorScheme) {
|
||||
val customBgColor = if (ThemeConfig.enableDeepPersonalization && ThemeConfig.themeBackgroundColor != 0) {
|
||||
Color(ThemeConfig.themeBackgroundColor)
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
val customFontColor = if (ThemeConfig.enableDeepPersonalization && ThemeConfig.primaryTextColor != 0) {
|
||||
Color(ThemeConfig.primaryTextColor)
|
||||
} else {
|
||||
colorScheme.onSurface
|
||||
}
|
||||
|
||||
colorScheme.toLegadoColorScheme(
|
||||
customBgColor = customBgColor,
|
||||
customFontColor = customFontColor,
|
||||
customTopBarColor = colorScheme.surface,
|
||||
customNavBarColor = colorScheme.surface
|
||||
)
|
||||
}
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalLegadoTypography provides legadoTypography,
|
||||
LocalLegadoColorScheme provides semanticColors
|
||||
) {
|
||||
AppBackground(darkTheme = darkTheme) { content() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,4 +64,34 @@ fun Typography.toLegadoTypography(): LegadoTypography {
|
||||
labelSmall = labelSmall,
|
||||
labelSmallEmphasized = labelSmall.copy(fontWeight = FontWeight.Medium)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun LegadoTypography.withFont(fontFamily: androidx.compose.ui.text.font.FontFamily?): LegadoTypography {
|
||||
if (fontFamily == null) return this
|
||||
return copy(
|
||||
headlineLarge = headlineLarge.copy(fontFamily = fontFamily),
|
||||
headlineLargeEmphasized = headlineLargeEmphasized.copy(fontFamily = fontFamily),
|
||||
headlineMedium = headlineMedium.copy(fontFamily = fontFamily),
|
||||
headlineMediumEmphasized = headlineMediumEmphasized.copy(fontFamily = fontFamily),
|
||||
headlineSmall = headlineSmall.copy(fontFamily = fontFamily),
|
||||
headlineSmallEmphasized = headlineSmallEmphasized.copy(fontFamily = fontFamily),
|
||||
titleLarge = titleLarge.copy(fontFamily = fontFamily),
|
||||
titleLargeEmphasized = titleLargeEmphasized.copy(fontFamily = fontFamily),
|
||||
titleMedium = titleMedium.copy(fontFamily = fontFamily),
|
||||
titleMediumEmphasized = titleMediumEmphasized.copy(fontFamily = fontFamily),
|
||||
titleSmall = titleSmall.copy(fontFamily = fontFamily),
|
||||
titleSmallEmphasized = titleSmallEmphasized.copy(fontFamily = fontFamily),
|
||||
bodyLarge = bodyLarge.copy(fontFamily = fontFamily),
|
||||
bodyLargeEmphasized = bodyLargeEmphasized.copy(fontFamily = fontFamily),
|
||||
bodyMedium = bodyMedium.copy(fontFamily = fontFamily),
|
||||
bodyMediumEmphasized = bodyMediumEmphasized.copy(fontFamily = fontFamily),
|
||||
bodySmall = bodySmall.copy(fontFamily = fontFamily),
|
||||
bodySmallEmphasized = bodySmallEmphasized.copy(fontFamily = fontFamily),
|
||||
labelLarge = labelLarge.copy(fontFamily = fontFamily),
|
||||
labelLargeEmphasized = labelLargeEmphasized.copy(fontFamily = fontFamily),
|
||||
labelMedium = labelMedium.copy(fontFamily = fontFamily),
|
||||
labelMediumEmphasized = labelMediumEmphasized.copy(fontFamily = fontFamily),
|
||||
labelSmall = labelSmall.copy(fontFamily = fontFamily),
|
||||
labelSmallEmphasized = labelSmallEmphasized.copy(fontFamily = fontFamily)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
package io.legado.app.ui.theme
|
||||
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
// 用户自定义的颜色集合
|
||||
data class UserColorPalette(
|
||||
val primaryColor: Color, // 用户定义的主题色
|
||||
val secondaryColor: Color, // 用户定义的次要主题色
|
||||
val backgroundColor: Color, // 用户定义的背景色
|
||||
val primaryFontColor: Color, // 用户定义的主要字体色
|
||||
val secondaryFontColor: Color, // 用户定义的次要字体色
|
||||
val labelContainerColor: Color // 用户定义的标签容器色
|
||||
)
|
||||
|
||||
// 将用户自定义颜色映射到 Material Theme 的 ColorScheme
|
||||
fun generateColorScheme(userPalette: UserColorPalette, isDark: Boolean): androidx.compose.material3.ColorScheme {
|
||||
return if (isDark) {
|
||||
darkColorScheme(
|
||||
primary = userPalette.primaryColor,
|
||||
onPrimary = userPalette.primaryFontColor,
|
||||
primaryContainer = userPalette.labelContainerColor,
|
||||
onPrimaryContainer = userPalette.primaryFontColor,
|
||||
|
||||
secondary = userPalette.secondaryColor,
|
||||
onSecondary = userPalette.secondaryFontColor,
|
||||
secondaryContainer = userPalette.labelContainerColor,
|
||||
onSecondaryContainer = userPalette.secondaryFontColor,
|
||||
|
||||
tertiary = userPalette.secondaryColor,
|
||||
onTertiary = userPalette.secondaryFontColor,
|
||||
|
||||
background = userPalette.backgroundColor,
|
||||
surface = userPalette.backgroundColor,
|
||||
onBackground = userPalette.primaryFontColor,
|
||||
onSurface = userPalette.primaryFontColor,
|
||||
surfaceVariant = userPalette.labelContainerColor,
|
||||
onSurfaceVariant = userPalette.secondaryFontColor,
|
||||
|
||||
// 其他颜色
|
||||
error = Color(0xFFB3261E),
|
||||
onError = Color(0xFFFFFFFF),
|
||||
errorContainer = Color(0xFFF9DEDC),
|
||||
onErrorContainer = Color(0xFF410E0B),
|
||||
outline = Color(0xFF79747E),
|
||||
outlineVariant = Color(0xFFC4C7C5),
|
||||
scrim = Color(0xFF000000),
|
||||
|
||||
// 表面颜色变体
|
||||
surfaceBright = userPalette.backgroundColor,
|
||||
surfaceDim = userPalette.backgroundColor,
|
||||
surfaceContainer = userPalette.backgroundColor,
|
||||
surfaceContainerHigh = userPalette.backgroundColor,
|
||||
surfaceContainerHighest = userPalette.backgroundColor,
|
||||
surfaceContainerLow = userPalette.labelContainerColor,
|
||||
surfaceContainerLowest = userPalette.backgroundColor,
|
||||
|
||||
// 固定颜色
|
||||
primaryFixed = userPalette.primaryColor,
|
||||
primaryFixedDim = userPalette.primaryColor.copy(alpha = 0.8f),
|
||||
onPrimaryFixed = userPalette.primaryFontColor,
|
||||
onPrimaryFixedVariant = userPalette.primaryFontColor,
|
||||
secondaryFixed = userPalette.secondaryColor,
|
||||
secondaryFixedDim = userPalette.secondaryColor.copy(alpha = 0.8f),
|
||||
onSecondaryFixed = userPalette.secondaryFontColor,
|
||||
onSecondaryFixedVariant = userPalette.secondaryFontColor,
|
||||
tertiaryFixed = userPalette.secondaryColor,
|
||||
tertiaryFixedDim = userPalette.secondaryColor.copy(alpha = 0.8f),
|
||||
onTertiaryFixed = userPalette.secondaryFontColor,
|
||||
onTertiaryFixedVariant = userPalette.secondaryFontColor
|
||||
)
|
||||
} else {
|
||||
lightColorScheme(
|
||||
primary = userPalette.primaryColor,
|
||||
onPrimary = userPalette.primaryFontColor,
|
||||
primaryContainer = userPalette.labelContainerColor,
|
||||
onPrimaryContainer = userPalette.primaryFontColor,
|
||||
|
||||
secondary = userPalette.secondaryColor,
|
||||
onSecondary = userPalette.secondaryFontColor,
|
||||
secondaryContainer = userPalette.labelContainerColor,
|
||||
onSecondaryContainer = userPalette.secondaryFontColor,
|
||||
|
||||
tertiary = userPalette.secondaryColor,
|
||||
onTertiary = userPalette.secondaryFontColor,
|
||||
|
||||
background = userPalette.backgroundColor,
|
||||
surface = userPalette.backgroundColor,
|
||||
onBackground = userPalette.primaryFontColor,
|
||||
onSurface = userPalette.primaryFontColor,
|
||||
surfaceVariant = userPalette.labelContainerColor,
|
||||
onSurfaceVariant = userPalette.secondaryFontColor,
|
||||
|
||||
// 其他颜色
|
||||
error = Color(0xFFB3261E),
|
||||
onError = Color(0xFFFFFFFF),
|
||||
errorContainer = Color(0xFFF9DEDC),
|
||||
onErrorContainer = Color(0xFF410E0B),
|
||||
outline = Color(0xFF79747E),
|
||||
outlineVariant = Color(0xFFC4C7C5),
|
||||
scrim = Color(0xFF000000),
|
||||
|
||||
// 表面颜色变体
|
||||
surfaceBright = userPalette.backgroundColor,
|
||||
surfaceDim = userPalette.backgroundColor,
|
||||
surfaceContainer = userPalette.backgroundColor,
|
||||
surfaceContainerHigh = userPalette.backgroundColor,
|
||||
surfaceContainerHighest = userPalette.backgroundColor,
|
||||
surfaceContainerLow = userPalette.labelContainerColor,
|
||||
surfaceContainerLowest = userPalette.backgroundColor,
|
||||
|
||||
// 固定颜色
|
||||
primaryFixed = userPalette.primaryColor,
|
||||
primaryFixedDim = userPalette.primaryColor.copy(alpha = 0.8f),
|
||||
onPrimaryFixed = userPalette.primaryFontColor,
|
||||
onPrimaryFixedVariant = userPalette.primaryFontColor,
|
||||
secondaryFixed = userPalette.secondaryColor,
|
||||
secondaryFixedDim = userPalette.secondaryColor.copy(alpha = 0.8f),
|
||||
onSecondaryFixed = userPalette.secondaryFontColor,
|
||||
onSecondaryFixedVariant = userPalette.secondaryFontColor,
|
||||
tertiaryFixed = userPalette.secondaryColor,
|
||||
tertiaryFixedDim = userPalette.secondaryColor.copy(alpha = 0.8f),
|
||||
onTertiaryFixed = userPalette.secondaryFontColor,
|
||||
onTertiaryFixedVariant = userPalette.secondaryFontColor
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user