Use pure compose themes, not MDC adapter

This commit is contained in:
MM20 2022-04-11 20:04:34 +02:00
parent 840c7db690
commit 19ae7e07e6
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
17 changed files with 280 additions and 74 deletions

View File

@ -0,0 +1,64 @@
package de.mm20.launcher2.ui
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import de.mm20.launcher2.ktx.isAtLeastApiLevel
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
import de.mm20.launcher2.ui.theme.colorscheme.DarkBlackAndWhiteColorScheme
import de.mm20.launcher2.ui.theme.colorscheme.DarkPre31DefaultColorScheme
import de.mm20.launcher2.ui.theme.colorscheme.LightBlackAndWhiteColorScheme
import de.mm20.launcher2.ui.theme.colorscheme.LightPre31DefaultColorScheme
import de.mm20.launcher2.ui.theme.typography.DefaultTypography
import kotlinx.coroutines.flow.map
import org.koin.androidx.compose.inject
@Composable
fun LauncherTheme(
content: @Composable () -> Unit
) {
val dataStore: LauncherDataStore by inject()
val colorSchemePreference by remember { dataStore.data.map { it.appearance.colorScheme } }.collectAsState(
ColorScheme.Default
)
val themePreference by remember { dataStore.data.map { it.appearance.theme } }.collectAsState(
Theme.System
)
val darkTheme =
themePreference == Theme.Dark || themePreference == Theme.System && isSystemInDarkTheme()
val colorScheme = when (colorSchemePreference) {
ColorScheme.BlackAndWhite -> {
if (darkTheme) DarkBlackAndWhiteColorScheme
else LightBlackAndWhiteColorScheme
}
else -> {
if (darkTheme) {
if (isAtLeastApiLevel(31)) dynamicDarkColorScheme(LocalContext.current)
else DarkPre31DefaultColorScheme
} else {
if (isAtLeastApiLevel(31)) dynamicLightColorScheme(LocalContext.current)
else LightPre31DefaultColorScheme
}
}
}
MaterialTheme(
colorScheme = colorScheme,
typography = DefaultTypography,
content = content
)
}

View File

@ -1,13 +0,0 @@
package de.mm20.launcher2.ui
import androidx.compose.runtime.Composable
import com.google.android.material.composethemeadapter.MdcTheme
import com.google.android.material.composethemeadapter3.Mdc3Theme
@Composable
fun MdcLauncherTheme(content: @Composable () -> Unit) {
Mdc3Theme {
MdcTheme(content = content)
}
}

View File

@ -1,50 +1,12 @@
package de.mm20.launcher2.ui.base
import android.os.Bundle
import android.view.Window
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.ui.R
import org.koin.android.ext.android.inject
abstract class BaseActivity : AppCompatActivity() {
private val permissionsManager: PermissionsManager by inject()
private val viewModel: BaseActivityVM by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val theme = viewModel.getTheme()
when (theme) {
Settings.AppearanceSettings.Theme.Light -> AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_NO
)
Settings.AppearanceSettings.Theme.Dark -> AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_YES
)
else -> AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
)
}
viewModel.theme.observe(this) {
if (it != theme && it != null) recreate()
}
val colorScheme = viewModel.getColorScheme()
val colorSchemeThemeId = when (colorScheme) {
Settings.AppearanceSettings.ColorScheme.BlackAndWhite -> R.style.BlackWhiteColors
else -> R.style.DefaultColors
}
this.theme.applyStyle(colorSchemeThemeId, true)
viewModel.colorScheme.observe(this) {
if (it != colorScheme && it != null) recreate()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,

View File

@ -23,6 +23,7 @@ fun LauncherCard(
border = LocalCardStyle.current.borderWidth.takeIf { it > 0 }
?.let { BorderStroke(it.dp, MaterialTheme.colorScheme.surface) },
content = content,
contentColor = MaterialTheme.colorScheme.onSurface,
color = MaterialTheme.colorScheme.surface.copy(alpha = backgroundOpacity.coerceIn(0f, 1f)),
shadowElevation = if (backgroundOpacity == 1f) elevation else 0.dp,
tonalElevation = elevation

View File

@ -20,10 +20,7 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@ -76,10 +73,21 @@ fun ShapedLauncherIcon(
val fgScale = icon.foregroundScale
val bgScale = icon.backgroundScale
val themedFgColor = MaterialTheme.colorScheme.onPrimaryContainer
val themedBgColor = MaterialTheme.colorScheme.primaryContainer
val fg = remember(icon, icon.isThemeable, themedFgColor) {
icon.foreground.also {
if (icon.isThemeable) it.setTint(themedFgColor.toArgb())
}
}
val bg = remember(icon, icon.isThemeable, themedBgColor) {
icon.background?.also {
if (icon.isThemeable) it.setTint(themedBgColor.toArgb())
}
}
Canvas(modifier = Modifier.fillMaxSize()) {
val fg = icon.foreground
val bg = icon.background
drawIntoCanvas {
val paddingFg = (size * (1 - fgScale) * 0.5f).toPx()
val paddingBg = (size * (1 - bgScale) * 0.5f).toPx()

View File

@ -31,7 +31,7 @@ import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import de.mm20.launcher2.ui.MdcLauncherTheme
import de.mm20.launcher2.ui.LauncherTheme
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.base.ProvideSettings
import de.mm20.launcher2.ui.ktx.toPixels
@ -48,7 +48,7 @@ class HiddenItemsView @JvmOverloads constructor(
val composeView = ComposeView(context)
composeView.setContent {
MdcLauncherTheme {
LauncherTheme {
ProvideSettings {
Dialog(
properties = DialogProperties(usePlatformDefaultWidth = false),

View File

@ -216,9 +216,9 @@ fun SearchBar(
}
}) {
when {
style != SearchBarSettings.SearchBarStyle.Transparent -> LocalContentColor.current
style != SearchBarSettings.SearchBarStyle.Transparent -> MaterialTheme.colorScheme.onSurface
it == SearchBarLevel.Resting -> Color.White
else -> LocalContentColor.current
else -> MaterialTheme.colorScheme.onSurface
}
}

View File

@ -14,8 +14,7 @@ import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.MutableLiveData
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.ui.MdcLauncherTheme
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.LauncherTheme
import de.mm20.launcher2.ui.locals.LocalCardStyle
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
@ -49,7 +48,7 @@ class SearchBarView @JvmOverloads constructor(
CompositionLocalProvider(
LocalCardStyle provides cardStyle
) {
MdcLauncherTheme {
LauncherTheme {
Box(contentAlignment = Alignment.TopCenter) {
SearchBar(
level

View File

@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.unit.dp
import de.mm20.launcher2.ui.MdcLauncherTheme
import de.mm20.launcher2.ui.LauncherTheme
import de.mm20.launcher2.ui.base.ProvideSettings
import de.mm20.launcher2.ui.launcher.search.apps.AppResults
import de.mm20.launcher2.ui.launcher.search.appshortcuts.AppShortcutResults
@ -35,7 +35,7 @@ class SearchView @JvmOverloads constructor(
LayoutParams.WRAP_CONTENT
)
view.setContent {
MdcLauncherTheme {
LauncherTheme {
ProvideSettings {
Column(
modifier = Modifier

View File

@ -6,14 +6,12 @@ import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Intent
import android.util.AttributeSet
import android.util.Log
import android.widget.FrameLayout
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi
import androidx.compose.animation.graphics.res.animatedVectorResource
@ -44,7 +42,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import de.mm20.launcher2.ui.ClockWidget
import de.mm20.launcher2.ui.MdcLauncherTheme
import de.mm20.launcher2.ui.LauncherTheme
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.base.ProvideSettings
import de.mm20.launcher2.ui.ktx.toDp
@ -97,7 +95,7 @@ class WidgetsView @JvmOverloads constructor(
val composeView = ComposeView(context)
composeView.setContent {
MdcLauncherTheme {
LauncherTheme {
ProvideSettings {
Column(
modifier = Modifier

View File

@ -18,7 +18,7 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import de.mm20.launcher2.ui.MdcLauncherTheme
import de.mm20.launcher2.ui.LauncherTheme
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.base.BaseActivity
import de.mm20.launcher2.ui.base.ProvideSettings
@ -40,7 +40,7 @@ class PickAppWidgetActivity : BaseActivity() {
val availableWidgets = viewModel.getAvailableWidgets(this)
val selectedAppWidget = viewModel.selectedAppWidget
setContent {
MdcLauncherTheme {
LauncherTheme {
ProvideSettings {
Scaffold(
topBar = {

View File

@ -15,7 +15,7 @@ import de.mm20.launcher2.licenses.AppLicense
import de.mm20.launcher2.licenses.OpenSourceLicenses
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.ui.MdcLauncherTheme
import de.mm20.launcher2.ui.LauncherTheme
import de.mm20.launcher2.ui.base.BaseActivity
import de.mm20.launcher2.ui.locals.LocalCardStyle
import de.mm20.launcher2.ui.locals.LocalNavController
@ -69,7 +69,7 @@ class SettingsActivity : BaseActivity() {
LocalNavController provides navController,
LocalCardStyle provides cardStyle
) {
MdcLauncherTheme {
LauncherTheme {
AnimatedNavHost(
navController = navController,
startDestination = "settings",

View File

@ -0,0 +1,63 @@
package de.mm20.launcher2.ui.theme.colorscheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.ui.graphics.Color
val LightBlackAndWhiteColorScheme = lightColorScheme(
primary = Color.Black,
onPrimary = Color.White,
primaryContainer = Color.White,
onPrimaryContainer = Color.Black,
inversePrimary = Color.White,
secondary = Color.Black,
onSecondary = Color.White,
secondaryContainer = Color.White,
onSecondaryContainer = Color.Black,
tertiary = Color.Black,
onTertiary = Color.White,
tertiaryContainer = Color.White,
onTertiaryContainer = Color.Black,
background = Color.White,
onBackground = Color.Black,
surface = Color.White,
onSurface = Color.Black,
surfaceVariant = Color.White,
onSurfaceVariant = Color.Black,
inverseSurface = Color.Black,
inverseOnSurface = Color.White,
error = Color(0xFFC10000),
onError = Color(0xFFFFFFFF),
errorContainer = Color(0xFFFFDAD3),
onErrorContainer = Color(0xFF410000),
outline = Color.White
)
val DarkBlackAndWhiteColorScheme = darkColorScheme(
primary = Color.White,
onPrimary = Color.Black,
primaryContainer = Color.Black,
onPrimaryContainer = Color.White,
inversePrimary = Color.Black,
secondary = Color.White,
onSecondary = Color.Black,
secondaryContainer = Color.Black,
onSecondaryContainer = Color.White,
tertiary = Color.White,
onTertiary = Color.Black,
tertiaryContainer = Color.Black,
onTertiaryContainer = Color.White,
background = Color.Black,
onBackground = Color.White,
surface = Color.Black,
onSurface = Color.White,
surfaceVariant = Color.Black,
onSurfaceVariant = Color.White,
inverseSurface = Color.White,
inverseOnSurface = Color.Black,
error = Color(0xffffb4a6),
onError = Color(0xff690000),
errorContainer = Color(0xff940000),
onErrorContainer = Color(0xffffb4a6),
outline = Color.White,
)

View File

@ -0,0 +1,63 @@
package de.mm20.launcher2.ui.theme.colorscheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.ui.graphics.Color
val LightPre31DefaultColorScheme = lightColorScheme(
primary = Color(0xFF3C6089),
onPrimary = Color(0xFFFFFFFF),
primaryContainer = Color(0xFFD1E4FF),
onPrimaryContainer = Color(0xFF101C2B),
inversePrimary = Color(0xFFA6C9F8),
secondary = Color(0xFF41617E),
onSecondary = Color(0xFFFFFFFF),
secondaryContainer = Color(0xFFCCE5FF),
onSecondaryContainer = Color(0xFF001D33),
tertiary = Color(0xFF2C6674),
onTertiary = Color(0xFFFFFFFF),
tertiaryContainer = Color(0xFFB2EBFC),
onTertiaryContainer = Color(0xFF001F26),
background = Color(0xFFFDFCFF),
onBackground = Color(0xFF161C27),
surface = Color(0xFFFDFCFF),
onSurface = Color(0xFF161C27),
surfaceVariant = Color(0xFFD8E2FA),
onSurfaceVariant = Color(0xFF3D475A),
inverseSurface = Color(0xFF2B313C),
inverseOnSurface = Color(0xFFEBF0FF),
error = Color(0xFF98434C),
onError = Color(0xFFFFFFFF),
errorContainer = Color(0xFFFFDADD),
onErrorContainer = Color(0xFF40000E),
outline = Color(0xFF6D778C),
)
val DarkPre31DefaultColorScheme = darkColorScheme(
primary = Color(0xFFA6C9F8),
onPrimary = Color(0xFF033259),
primaryContainer = Color(0xFF234870),
onPrimaryContainer = Color(0xFFD1E4FF),
inversePrimary = Color(0xFF3C6089),
secondary = Color(0xFFA9CAEC),
onSecondary = Color(0xFF0E334E),
secondaryContainer = Color(0xFF284965),
onSecondaryContainer = Color(0xFFCCE5FF),
tertiary = Color(0xFF97CFDF),
onTertiary = Color(0xFF003641),
tertiaryContainer = Color(0xFF094E5C),
onTertiaryContainer = Color(0xFFB2EBFC),
background = Color(0xFF161C27),
onBackground = Color(0xFFDDE2F2),
surface = Color(0xFF161C27),
onSurface = Color(0xFFDDE2F2),
surfaceVariant = Color(0xFF3D475A),
onSurfaceVariant = Color(0xFFBDC7DF),
inverseSurface = Color(0xFFDDE2F2),
inverseOnSurface = Color(0xFF2B313C),
error = Color(0xFFFFB3B9),
onError = Color(0xFF5D1521),
errorContainer = Color(0xFF7A2C36),
onErrorContainer = Color(0xFFFFB3B9),
outline = Color(0xFF8791A7),
)

View File

@ -0,0 +1,28 @@
package de.mm20.launcher2.ui.theme.typography
import androidx.compose.material3.Typography
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
fun makeTypography(
headlineFamily: FontFamily? = null,
bodyFamily: FontFamily? = null): Typography {
val baseTypography = Typography()
return Typography(
displayLarge = baseTypography.displayLarge.copy(fontFamily = headlineFamily, fontWeight = FontWeight.Medium),
displayMedium = baseTypography.displayMedium.copy(fontFamily = headlineFamily, fontWeight = FontWeight.Medium),
displaySmall = baseTypography.displaySmall.copy(fontFamily = headlineFamily, fontWeight = FontWeight.Medium),
headlineLarge = baseTypography.headlineLarge.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold),
headlineMedium = baseTypography.headlineMedium.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold),
headlineSmall = baseTypography.headlineSmall.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold),
titleLarge = baseTypography.titleLarge.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold),
titleMedium = baseTypography.titleMedium.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold),
titleSmall = baseTypography.titleSmall.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold),
bodyLarge = baseTypography.bodyLarge.copy(fontFamily = bodyFamily),
bodyMedium = baseTypography.bodyMedium.copy(fontFamily = bodyFamily),
bodySmall = baseTypography.bodySmall.copy(fontFamily = bodyFamily),
labelLarge = baseTypography.labelLarge.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold),
labelMedium = baseTypography.labelMedium.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold),
labelSmall = baseTypography.labelSmall.copy(fontFamily = headlineFamily, fontWeight = FontWeight.SemiBold)
)
}

View File

@ -0,0 +1,5 @@
package de.mm20.launcher2.ui.theme.typography
import de.mm20.launcher2.ui.theme.typography.fontfamily.Poppins
val DefaultTypography = makeTypography(headlineFamily = Poppins)

View File

@ -0,0 +1,28 @@
package de.mm20.launcher2.ui.theme.typography.fontfamily
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import de.mm20.launcher2.ui.R
val Poppins = FontFamily(
Font(R.font.poppins100, weight = FontWeight.Thin, style = FontStyle.Normal),
Font(R.font.poppins200, weight = FontWeight.ExtraLight, style = FontStyle.Normal),
Font(R.font.poppins300, weight = FontWeight.Light, style = FontStyle.Normal),
Font(R.font.poppins400, weight = FontWeight.Normal, style = FontStyle.Normal),
Font(R.font.poppins500, weight = FontWeight.Medium, style = FontStyle.Normal),
Font(R.font.poppins600, weight = FontWeight.SemiBold, style = FontStyle.Normal),
Font(R.font.poppins700, weight = FontWeight.Bold, style = FontStyle.Normal),
Font(R.font.poppins800, weight = FontWeight.ExtraBold, style = FontStyle.Normal),
Font(R.font.poppins900, weight = FontWeight.Black, style = FontStyle.Normal),
Font(R.font.poppins100i, weight = FontWeight.Thin, style = FontStyle.Italic),
Font(R.font.poppins200i, weight = FontWeight.ExtraLight, style = FontStyle.Italic),
Font(R.font.poppins300i, weight = FontWeight.Light, style = FontStyle.Italic),
Font(R.font.poppins400i, weight = FontWeight.Normal, style = FontStyle.Italic),
Font(R.font.poppins500i, weight = FontWeight.Medium, style = FontStyle.Italic),
Font(R.font.poppins600i, weight = FontWeight.SemiBold, style = FontStyle.Italic),
Font(R.font.poppins700i, weight = FontWeight.Bold, style = FontStyle.Italic),
Font(R.font.poppins800i, weight = FontWeight.ExtraBold, style = FontStyle.Italic),
Font(R.font.poppins900i, weight = FontWeight.Black, style = FontStyle.Italic),
)