From 7f146994ce79acfa84d2231844ba073962d878dc Mon Sep 17 00:00:00 2001 From: FunkyMuse Date: Wed, 28 Jun 2023 15:46:24 +0200 Subject: [PATCH] feat: add infra to create colors mapping or maybe come up with better idea? --- .../calculator/activities/SettingsActivity.kt | 5 +- .../compose/extensions/ComposeExtensions.kt | 10 ++ .../calculator/compose/theme/Theme.kt | 159 +++++++++++++++--- 3 files changed, 150 insertions(+), 24 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/ComposeExtensions.kt diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/activities/SettingsActivity.kt index 46e43fa..082d3e1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calculator/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/activities/SettingsActivity.kt @@ -7,7 +7,6 @@ import android.os.Bundle import android.view.View import androidx.activity.compose.setContent import androidx.appcompat.app.AppCompatActivity -import androidx.compose.ui.graphics.Color import com.simplemobiletools.calculator.compose.screens.SettingsScreen import com.simplemobiletools.calculator.compose.theme.AppThemeSurface import com.simplemobiletools.calculator.compose.theme.Theme @@ -30,7 +29,9 @@ class SettingsActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { - AppThemeSurface { + AppThemeSurface( + theme = Theme.systemDefaultMaterialYou() + ) { SettingsScreen( customizeColors = ::handleCustomizeColorsClick, goBack = ::finish, backgroundColor = getProperBackgroundColor(), diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/ComposeExtensions.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/ComposeExtensions.kt new file mode 100644 index 0000000..1590881 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/ComposeExtensions.kt @@ -0,0 +1,10 @@ +package com.simplemobiletools.calculator.compose.extensions + +import android.app.Activity +import android.content.Context +import android.content.ContextWrapper + +fun Context.getActivity(): Activity { + if (this is Activity) return this + return if (this is ContextWrapper) baseContext.getActivity() else getActivity() +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/Theme.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/Theme.kt index 86d2936..ca3def2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/Theme.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/Theme.kt @@ -1,21 +1,24 @@ package com.simplemobiletools.calculator.compose.theme +import android.os.Build +import androidx.compose.foundation.LocalOverscrollConfiguration import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.material3.* +import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.luminance import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import com.google.accompanist.systemuicontroller.rememberSystemUiController -import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.calculator.compose.theme.Theme.Companion.systemDefaultMaterialYou +import com.simplemobiletools.calculator.extensions.config +import com.simplemobiletools.commons.extensions.adjustAlpha +import com.simplemobiletools.commons.extensions.getProperStatusBarColor +import com.simplemobiletools.commons.extensions.isUsingGestureNavigation +import com.simplemobiletools.commons.extensions.navigationBarHeight import com.simplemobiletools.commons.helpers.HIGHER_ALPHA @@ -57,16 +60,121 @@ fun preferenceSummaryColor(isEnabled: Boolean) = @Composable fun preferenceTitleColor(isEnabled: Boolean) = if (isEnabled) Color.Unspecified else disabledTextColor +@Composable +fun getTheme(): Theme { + val context = LocalContext.current + val config = remember { context.config } + //todo ask for help to create all of these mappings for the theme + return systemDefaultMaterialYou() +} + +interface CommonTheme { + val primaryColorInt: Int + val backgroundColorInt: Int + val appIconColorInt: Int + val textColorInt: Int + + val primaryColor get() = Color(primaryColorInt) + val backgroundColor get() = Color(backgroundColorInt) + val appIconColor get() = Color(appIconColorInt) + val textColor get() = Color(textColorInt) +} + +@Stable +sealed class Theme : CommonTheme { + data class SystemDefaultMaterialYou( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class AutoLightDark( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : + Theme() + + data class Light( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class Dark( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class DarkRed( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class White( + val accentColor: Int, + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class BlackAndWhite( + val accentColor: Int, + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class Custom( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + companion object { + @Composable + fun systemDefaultMaterialYou() = SystemDefaultMaterialYou( + appIconColorInt = LocalContext.current.config.appIconColor, + primaryColorInt = MaterialTheme.colorScheme.primary.toArgb(), + backgroundColorInt = MaterialTheme.colorScheme.background.toArgb(), + textColorInt = (if (isSystemInDarkTheme() || MaterialTheme.colorScheme.background.luminance() < 0.5) Color.White else Color.Black).toArgb() + ) + } +} + @Composable fun Theme( useTransparentNavigation: Boolean = true, - properBackgroundColor: Int, - content: @Composable () -> Unit, statusBarColor: Int, + theme: Theme, + content: @Composable () -> Unit, ) { - //todo val context = LocalContext.current val systemUiController = rememberSystemUiController() + + val colorScheme = when { + theme is Theme.SystemDefaultMaterialYou && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + if (isSystemInDarkTheme()) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + theme is Theme.AutoLightDark -> if (isSystemInDarkTheme()) DarkColorScheme else LightColorScheme + theme is Theme.Dark || theme is Theme.DarkRed -> darkColorScheme(primary = theme.primaryColor, background = theme.backgroundColor) + theme is Theme.Light -> lightColorScheme(primary = theme.primaryColor, background = theme.backgroundColor) + theme is Theme.White -> lightColorScheme(primary = theme.primaryColor, background = theme.backgroundColor, tertiary = Color(theme.accentColor)) + theme is Theme.BlackAndWhite -> darkColorScheme(primary = theme.primaryColor, background = theme.backgroundColor, tertiary = Color(theme.accentColor)) + theme is Theme.Custom -> darkColorScheme(primary = theme.primaryColor, background = theme.backgroundColor) + else -> LightColorScheme + } LaunchedEffect(Unit) { if (context.navigationBarHeight > 0 || context.isUsingGestureNavigation() && useTransparentNavigation) { systemUiController.isNavigationBarVisible = false @@ -74,30 +182,37 @@ fun Theme( systemUiController.setStatusBarColor( color = Color(statusBarColor) ) - systemUiController.setNavigationBarColor(Color(properBackgroundColor.adjustAlpha(HIGHER_ALPHA))) + systemUiController.setNavigationBarColor(Color(theme.backgroundColorInt.adjustAlpha(HIGHER_ALPHA))) } - MaterialTheme( - colorScheme = DarkColorScheme, - content = content, - ) + CompositionLocalProvider( + LocalContentColor provides theme.textColor, + LocalOverscrollConfiguration provides null, + ) { + MaterialTheme( + colorScheme = colorScheme, + content = content, + ) + } } + @Composable fun AppThemeSurface( modifier: Modifier = Modifier, - properBackgroundColor: Int = LocalContext.current.getProperBackgroundColor(), - backgroundColor: Int = MaterialTheme.colorScheme.background.toArgb(), - statusBarColor: Int = LocalContext.current.getProperStatusBarColor(), + theme: Theme = systemDefaultMaterialYou(), content: @Composable () -> Unit, ) { - Theme(properBackgroundColor = properBackgroundColor, content = { + val context = LocalContext.current + val statusBarColor = remember { context.getProperStatusBarColor() } + Theme(statusBarColor = statusBarColor, theme = theme) { Surface( modifier = modifier .fillMaxSize() - .background(Color(backgroundColor)) + .background(theme.backgroundColor) ) { content() } - }, statusBarColor = statusBarColor) + } } +