Theme.kt (5953B)
1 /* 2 * This file is part of GNU Taler 3 * (C) 2026 Taler Systems S.A. 4 * 5 * GNU Taler is free software; you can redistribute it and/or modify it under the 6 * terms of the GNU General Public License as published by the Free Software 7 * Foundation; either version 3, or (at your option) any later version. 8 * 9 * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 package net.taler.wallet.ui.theme 18 19 import android.os.Build 20 import androidx.compose.foundation.isSystemInDarkTheme 21 import androidx.compose.material3.MaterialTheme 22 import androidx.compose.material3.darkColorScheme 23 import androidx.compose.material3.dynamicDarkColorScheme 24 import androidx.compose.material3.dynamicLightColorScheme 25 import androidx.compose.material3.lightColorScheme 26 import androidx.compose.runtime.Composable 27 import androidx.compose.runtime.CompositionLocalProvider 28 import androidx.compose.runtime.Immutable 29 import androidx.compose.runtime.staticCompositionLocalOf 30 import androidx.compose.ui.graphics.Color 31 import androidx.compose.ui.platform.LocalContext 32 33 private val lightScheme = lightColorScheme( 34 primary = primaryLight, 35 onPrimary = onPrimaryLight, 36 primaryContainer = primaryContainerLight, 37 onPrimaryContainer = onPrimaryContainerLight, 38 secondary = secondaryLight, 39 onSecondary = onSecondaryLight, 40 secondaryContainer = secondaryContainerLight, 41 onSecondaryContainer = onSecondaryContainerLight, 42 tertiary = tertiaryLight, 43 onTertiary = onTertiaryLight, 44 tertiaryContainer = tertiaryContainerLight, 45 onTertiaryContainer = onTertiaryContainerLight, 46 error = errorLight, 47 onError = onErrorLight, 48 errorContainer = errorContainerLight, 49 onErrorContainer = onErrorContainerLight, 50 background = backgroundLight, 51 onBackground = onBackgroundLight, 52 surface = surfaceLight, 53 onSurface = onSurfaceLight, 54 surfaceVariant = surfaceVariantLight, 55 onSurfaceVariant = onSurfaceVariantLight, 56 outline = outlineLight, 57 outlineVariant = outlineVariantLight, 58 scrim = scrimLight, 59 inverseSurface = inverseSurfaceLight, 60 inverseOnSurface = inverseOnSurfaceLight, 61 inversePrimary = inversePrimaryLight, 62 surfaceDim = surfaceDimLight, 63 surfaceBright = surfaceBrightLight, 64 surfaceContainerLowest = surfaceContainerLowestLight, 65 surfaceContainerLow = surfaceContainerLowLight, 66 surfaceContainer = surfaceContainerLight, 67 surfaceContainerHigh = surfaceContainerHighLight, 68 surfaceContainerHighest = surfaceContainerHighestLight, 69 ) 70 71 private val darkScheme = darkColorScheme( 72 primary = primaryDark, 73 onPrimary = onPrimaryDark, 74 primaryContainer = primaryContainerDark, 75 onPrimaryContainer = onPrimaryContainerDark, 76 secondary = secondaryDark, 77 onSecondary = onSecondaryDark, 78 secondaryContainer = secondaryContainerDark, 79 onSecondaryContainer = onSecondaryContainerDark, 80 tertiary = tertiaryDark, 81 onTertiary = onTertiaryDark, 82 tertiaryContainer = tertiaryContainerDark, 83 onTertiaryContainer = onTertiaryContainerDark, 84 error = errorDark, 85 onError = onErrorDark, 86 errorContainer = errorContainerDark, 87 onErrorContainer = onErrorContainerDark, 88 background = backgroundDark, 89 onBackground = onBackgroundDark, 90 surface = surfaceDark, 91 onSurface = onSurfaceDark, 92 surfaceVariant = surfaceVariantDark, 93 onSurfaceVariant = onSurfaceVariantDark, 94 outline = outlineDark, 95 outlineVariant = outlineVariantDark, 96 scrim = scrimDark, 97 inverseSurface = inverseSurfaceDark, 98 inverseOnSurface = inverseOnSurfaceDark, 99 inversePrimary = inversePrimaryDark, 100 surfaceDim = surfaceDimDark, 101 surfaceBright = surfaceBrightDark, 102 surfaceContainerLowest = surfaceContainerLowestDark, 103 surfaceContainerLow = surfaceContainerLowDark, 104 surfaceContainer = surfaceContainerDark, 105 surfaceContainerHigh = surfaceContainerHighDark, 106 surfaceContainerHighest = surfaceContainerHighestDark, 107 ) 108 109 @Immutable 110 data class TalerColorScheme( 111 val success: Color = Color.Unspecified, 112 val onSuccess: Color = Color.Unspecified, 113 val successContainer: Color = Color.Unspecified, 114 val onSuccessContainer: Color = Color.Unspecified, 115 ) 116 117 private val talerLightScheme = TalerColorScheme( 118 success = successLight, 119 onSuccess = onSuccessLight, 120 successContainer = successContainerLight, 121 onSuccessContainer = onSuccessContainerLight, 122 ) 123 124 private val talerDarkScheme = TalerColorScheme( 125 success = successDark, 126 onSuccess = onSuccessDark, 127 successContainer = successContainerDark, 128 onSuccessContainer = onSuccessContainerDark, 129 ) 130 131 val LocalTalerColorScheme = staticCompositionLocalOf { talerLightScheme } 132 133 object TalerTheme { 134 val extraColors: TalerColorScheme@Composable 135 get() = LocalTalerColorScheme.current 136 } 137 138 @Composable 139 fun TalerTheme( 140 darkTheme: Boolean = isSystemInDarkTheme(), 141 // Dynamic color is available on Android 12+ 142 dynamicColor: Boolean = false, 143 content: @Composable () -> Unit 144 ) { 145 val colorScheme = when { 146 dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { 147 val context = LocalContext.current 148 if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) 149 } 150 151 darkTheme -> darkScheme 152 else -> lightScheme 153 } 154 155 val talerColorScheme = if(darkTheme) { 156 talerDarkScheme 157 } else { 158 talerLightScheme 159 } 160 161 CompositionLocalProvider(LocalTalerColorScheme provides talerColorScheme) { 162 MaterialTheme( 163 colorScheme = colorScheme, 164 content = content 165 ) 166 } 167 }