feat: Use the High surface color for the navigation bar if possible #167

This commit is contained in:
Artem Chepurnoy 2024-02-18 11:38:48 +02:00
parent 9bcab6a814
commit d7fd67aeae
No known key found for this signature in database
GPG Key ID: FAC37D0CF674043E
6 changed files with 92 additions and 11 deletions

View File

@ -9,7 +9,7 @@ import android.webkit.MimeTypeMap
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
import androidx.compose.material3.MaterialTheme import androidx.compose.animation.animateColorAsState
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.contentColorFor import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -46,6 +46,7 @@ import com.artemchep.keyguard.feature.navigation.N
import com.artemchep.keyguard.feature.navigation.NavigationController import com.artemchep.keyguard.feature.navigation.NavigationController
import com.artemchep.keyguard.feature.navigation.NavigationIntent import com.artemchep.keyguard.feature.navigation.NavigationIntent
import com.artemchep.keyguard.feature.navigation.NavigationRouterBackHandler import com.artemchep.keyguard.feature.navigation.NavigationRouterBackHandler
import com.artemchep.keyguard.ui.surface.LocalBackgroundManager
import com.artemchep.keyguard.ui.surface.LocalSurfaceColor import com.artemchep.keyguard.ui.surface.LocalSurfaceColor
import com.artemchep.keyguard.ui.theme.KeyguardTheme import com.artemchep.keyguard.ui.theme.KeyguardTheme
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
@ -100,7 +101,7 @@ abstract class BaseActivity : AppCompatActivity(), DIAware {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
setContent { setContent {
KeyguardTheme { KeyguardTheme {
val containerColor = MaterialTheme.colorScheme.surfaceContainerHighest val containerColor = LocalBackgroundManager.current.colorHighest
val contentColor = contentColorFor(containerColor) val contentColor = contentColorFor(containerColor)
Surface( Surface(
modifier = Modifier.semantics { modifier = Modifier.semantics {

View File

@ -60,6 +60,7 @@ import com.artemchep.keyguard.ui.scaffoldContentWindowInsets
import com.artemchep.keyguard.ui.screenMaxWidth import com.artemchep.keyguard.ui.screenMaxWidth
import com.artemchep.keyguard.ui.surface.LocalSurfaceColor import com.artemchep.keyguard.ui.surface.LocalSurfaceColor
import com.artemchep.keyguard.ui.surface.LocalSurfaceElevation import com.artemchep.keyguard.ui.surface.LocalSurfaceElevation
import com.artemchep.keyguard.ui.surface.ReportSurfaceColor
import com.artemchep.keyguard.ui.surface.color import com.artemchep.keyguard.ui.surface.color
import com.artemchep.keyguard.ui.surface.splitHigh import com.artemchep.keyguard.ui.surface.splitHigh
import com.artemchep.keyguard.ui.surface.splitLow import com.artemchep.keyguard.ui.surface.splitLow
@ -143,6 +144,8 @@ fun TwoPaneScaffoldScope.TwoPaneLayout(
LocalSurfaceColor provides surfaceElevationColor(elevation.to), LocalSurfaceColor provides surfaceElevationColor(elevation.to),
LocalHasDetailPane provides true, LocalHasDetailPane provides true,
) { ) {
ReportSurfaceColor()
val horizontalInsets = scaffoldContentWindowInsets val horizontalInsets = scaffoldContentWindowInsets
.only(WindowInsetsSides.Horizontal) .only(WindowInsetsSides.Horizontal)
PaneLayout( PaneLayout(
@ -165,6 +168,8 @@ fun TwoPaneScaffoldScope.TwoPaneLayout(
LocalSurfaceColor provides surfaceElevationColor(elevation.to), LocalSurfaceColor provides surfaceElevationColor(elevation.to),
LocalHasDetailPane provides false, LocalHasDetailPane provides false,
) { ) {
ReportSurfaceColor()
PaneLayout( PaneLayout(
modifier = Modifier modifier = Modifier
.background(surfaceElevation.color), .background(surfaceElevation.color),

View File

@ -27,6 +27,7 @@ import com.artemchep.keyguard.platform.leStatusBars
import com.artemchep.keyguard.platform.leSystemBars import com.artemchep.keyguard.platform.leSystemBars
import com.artemchep.keyguard.ui.surface.LocalSurfaceElevation import com.artemchep.keyguard.ui.surface.LocalSurfaceElevation
import com.artemchep.keyguard.ui.surface.ProvideSurfaceColor import com.artemchep.keyguard.ui.surface.ProvideSurfaceColor
import com.artemchep.keyguard.ui.surface.ReportSurfaceColor
import com.artemchep.keyguard.ui.surface.splitLow import com.artemchep.keyguard.ui.surface.splitLow
import com.artemchep.keyguard.ui.surface.surfaceElevationColor import com.artemchep.keyguard.ui.surface.surfaceElevationColor
import com.artemchep.keyguard.ui.theme.Dimens import com.artemchep.keyguard.ui.theme.Dimens
@ -61,6 +62,8 @@ fun TwoPaneScreen(
surfaceElevationColor(elevation) surfaceElevationColor(elevation)
} }
ProvideSurfaceColor(color) { ProvideSurfaceColor(color) {
ReportSurfaceColor()
val detailIsVisible = this@TwoPaneScaffold.tabletUi val detailIsVisible = this@TwoPaneScaffold.tabletUi
val insetsModifier = if (detailIsVisible) { val insetsModifier = if (detailIsVisible) {
val insetsTop = WindowInsets.leSystemBars val insetsTop = WindowInsets.leSystemBars
@ -115,6 +118,8 @@ fun TwoPaneScreen(
} }
val detailSurfaceColor = surfaceElevationColor(surfaceElevation.to) val detailSurfaceColor = surfaceElevationColor(surfaceElevation.to)
ProvideSurfaceColor(detailSurfaceColor) { ProvideSurfaceColor(detailSurfaceColor) {
ReportSurfaceColor()
content( content(
scope, scope,
contentModifier, contentModifier,

View File

@ -0,0 +1,74 @@
package com.artemchep.keyguard.ui.surface
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.Color
import java.util.UUID
class BackgroundManager {
private val surfaceColorsState = mutableStateMapOf<String, Color>()
val colorHighest: Color
@Composable
get() {
val surfaceContainerHigh = MaterialTheme.colorScheme.surfaceContainerHigh
val surfaceContainerHighest = MaterialTheme.colorScheme.surfaceContainerHighest
var maxPriority = 0
surfaceColorsState.values.forEach { color ->
val priority = when (color) {
surfaceContainerHigh -> 1
surfaceContainerHighest -> 2
else -> 0
}
if (maxPriority < priority) {
maxPriority = priority
}
}
return when (maxPriority) {
0 -> surfaceContainerHigh
1 -> surfaceContainerHighest
else -> surfaceContainerHighest
}
}
fun register(
color: Color,
): () -> Unit {
val key = UUID.randomUUID().toString()
surfaceColorsState[key] = color
return {
surfaceColorsState.remove(key)
}
}
}
private val globalBackgroundManager = BackgroundManager()
val LocalBackgroundManager = staticCompositionLocalOf {
globalBackgroundManager
}
/**
* Reports the background color to the background manager. This might affect the
* highest elevation elements such as elevated toolbar or the navigation bar/rail.
*/
@Composable
fun ReportSurfaceColor() {
val surfaceColor = LocalSurfaceColor.current
val backgroundManager = LocalBackgroundManager.current
DisposableEffect(
surfaceColor,
backgroundManager,
) {
val unregister = backgroundManager.register(surfaceColor)
onDispose {
unregister()
}
}
}

View File

@ -1,12 +1,9 @@
package com.artemchep.keyguard.ui.toolbar.util package com.artemchep.keyguard.ui.toolbar.util
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.isUnspecified import androidx.compose.ui.graphics.isUnspecified
import androidx.compose.ui.unit.dp import com.artemchep.keyguard.ui.surface.LocalBackgroundManager
import com.artemchep.keyguard.feature.home.vault.component.surfaceColorAtElevationSemi
import com.artemchep.keyguard.ui.surface.LocalSurfaceColor import com.artemchep.keyguard.ui.surface.LocalSurfaceColor
object ToolbarColors { object ToolbarColors {
@ -24,8 +21,6 @@ object ToolbarColors {
return containerColor return containerColor
} }
val tint = MaterialTheme.colorScheme return LocalBackgroundManager.current.colorHighest
.surfaceColorAtElevationSemi(elevation = 2.0.dp)
return tint.compositeOver(MaterialTheme.colorScheme.surfaceContainerLow)
} }
} }

View File

@ -1,6 +1,6 @@
package com.artemchep.keyguard package com.artemchep.keyguard
import androidx.compose.material3.MaterialTheme import androidx.compose.animation.animateColorAsState
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.contentColorFor import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -46,6 +46,7 @@ import com.artemchep.keyguard.feature.navigation.NavigationRouterBackHandler
import com.artemchep.keyguard.platform.lifecycle.LeLifecycleState import com.artemchep.keyguard.platform.lifecycle.LeLifecycleState
import com.artemchep.keyguard.res.Res import com.artemchep.keyguard.res.Res
import com.artemchep.keyguard.ui.LocalComposeWindow import com.artemchep.keyguard.ui.LocalComposeWindow
import com.artemchep.keyguard.ui.surface.LocalBackgroundManager
import com.artemchep.keyguard.ui.surface.LocalSurfaceColor import com.artemchep.keyguard.ui.surface.LocalSurfaceColor
import com.artemchep.keyguard.ui.theme.KeyguardTheme import com.artemchep.keyguard.ui.theme.KeyguardTheme
import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.painterResource
@ -262,7 +263,7 @@ private fun ApplicationScope.KeyguardWindow(
title = "Keyguard", title = "Keyguard",
) { ) {
KeyguardTheme { KeyguardTheme {
val containerColor = MaterialTheme.colorScheme.surfaceContainerHighest val containerColor = LocalBackgroundManager.current.colorHighest
val contentColor = contentColorFor(containerColor) val contentColor = contentColorFor(containerColor)
Surface( Surface(
modifier = Modifier.semantics { modifier = Modifier.semantics {