瀏覽代碼

shadows improvements

milan jurkulák 2 年之前
父節點
當前提交
0a8da1ad16

+ 0 - 2
build.gradle.kts

@@ -81,8 +81,6 @@ allprojects {
         implementation("io.github.irgaly.kfswatch:kfswatch:1.3.0")
         // tts
         implementation("nl.marc-apps:tts:2.5.0")
-        implementation("nl.marc-apps:tts-compose:2.5.0")
-
         // bar code
 //        implementation("io.github.alexzhirkevich:qrose-oned:1.0.1")
         // flow extensions

+ 20 - 27
src/main/kotlin/eu/mjdev/desktop/components/controlcenter/ControlCenter.kt

@@ -19,11 +19,10 @@ import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.window.WindowPosition
 import eu.mjdev.desktop.components.controlcenter.ControlCenterPage.Companion.rememberControlCenterScope
-import eu.mjdev.desktop.components.shadow.LeftShadow
-import eu.mjdev.desktop.components.shadow.RightShadow
 import eu.mjdev.desktop.components.sliding.SlidingMenu
 import eu.mjdev.desktop.components.sliding.VisibilityState
 import eu.mjdev.desktop.components.sliding.VisibilityState.Companion.rememberVisibilityState
+import eu.mjdev.desktop.extensions.Modifier.rightShadow
 import eu.mjdev.desktop.provider.DesktopProvider
 import eu.mjdev.desktop.provider.DesktopProvider.Companion.LocalDesktop
 import eu.mjdev.desktop.windows.ChromeWindow
@@ -36,8 +35,7 @@ fun ControlCenter(
     api: DesktopProvider = LocalDesktop.current,
     backgroundColor: Color = api.currentUser.theme.backgroundColor,
     backgroundAlpha: Float = api.currentUser.theme.controlCenterBackgroundAlpha,
-    shadowColor: Color = backgroundColor, // todo theme
-    controlCenterDividerColor: Color = backgroundColor,// todo theme
+    shadowColor: Color = Color.Black.copy(alpha = 0.3f), // todo theme
     controlCenterExpandedWidth: Dp = api.currentUser.theme.controlCenterExpandedWidth,
     controlCenterDividerWidth: Dp = api.currentUser.theme.controlCenterDividerWidth,
     controlCenterIconColor: Color = api.currentUser.theme.controlCenterIconColor,
@@ -82,10 +80,11 @@ fun ControlCenter(
                 thickness = controlCenterDividerWidth
             )
         } else {
-            LeftShadow(
-                modifier = Modifier.fillMaxHeight().wrapContentSize(),
-                color = shadowColor,
-                contentBackgroundColor = backgroundColor.copy(alpha = backgroundAlpha)
+            Box(
+                modifier = Modifier
+                    .fillMaxHeight()
+                    .wrapContentSize()
+                    .background(backgroundColor.copy(alpha = backgroundAlpha)),
             ) {
                 Row(
                     modifier = Modifier.fillMaxHeight().wrapContentSize(),
@@ -122,20 +121,13 @@ fun ControlCenter(
                                 )
                             }
                         }
-                        Divider(
+                        Box(
                             modifier = Modifier
+                                .padding(
+                                    end = controlCenterIconSize.width + 16.dp
+                                )
                                 .fillMaxHeight()
-                                .width(2.dp),
-                            color = Color.White.copy(0.1f),
-                            thickness = 2.dp
-                        )
-                        RightShadow(
-                            modifier = Modifier.padding(
-                                end = controlCenterIconSize.width + 16.dp
-                            ).fillMaxHeight().wrapContentSize(),
-                            color = Color.Black,
-                            alpha = 0.3f,
-                            contentBackgroundColor = Color.Transparent
+                                .wrapContentSize(),
                         ) {
                             Row {
                                 Divider(
@@ -146,22 +138,23 @@ fun ControlCenter(
                                     thickness = 2.dp
                                 )
                                 Box(
-                                    modifier = Modifier.width(controlCenterExpandedWidth),
+                                    modifier = Modifier
+                                        .width(controlCenterExpandedWidth)
+                                        .rightShadow(
+                                            color = shadowColor,
+                                            offsetX = 4.dp,
+                                            blur = 10.dp,
+                                        ),
                                 ) {
                                     with(pagesFiltered.value[pagerState.value]) {
                                         content(cscope)
                                     }
                                 }
-                                Divider(
-                                    modifier = Modifier.fillMaxHeight().width(controlCenterDividerWidth),
-                                    color = controlCenterDividerColor,
-                                    thickness = controlCenterDividerWidth
-                                )
                             }
                         }
                         Divider(
                             modifier = Modifier.fillMaxHeight().width(controlCenterDividerWidth),
-                            color = controlCenterDividerColor,
+                            color = Color.White.copy(0.1f),
                             thickness = controlCenterDividerWidth
                         )
                     }

+ 1 - 1
src/main/kotlin/eu/mjdev/desktop/components/controlcenter/pages/MainSettingsPage.kt

@@ -27,7 +27,7 @@ fun MainSettingsPage() = ControlCenterPage(
             modifier = Modifier
                 .fillMaxWidth()
                 .align(Alignment.TopCenter)
-                .rectShadow(8.dp, Color.Black)
+                .rectShadow(8.dp, Color.Black.copy(alpha = 0.3f))
         ) {
             UserAvatar(
                 backgroundColor = backgroundColor,

+ 1 - 1
src/main/kotlin/eu/mjdev/desktop/components/custom/PowerBlock.kt

@@ -27,7 +27,7 @@ import eu.mjdev.desktop.extensions.Modifier.rectShadow
 @Composable
 fun PowerBlock(
     backgroundColor: Color,
-    shadowColor: Color = Color.Black,
+    shadowColor: Color = Color.Black.copy(alpha = 0.3f),
     bottomBoxHeight: Dp = 128.dp,
     iconHeight: Dp = 64.dp,
     onPowerButtonClick: () -> Unit = {}

+ 60 - 53
src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/DesktopPanel.kt

@@ -24,12 +24,12 @@ import androidx.compose.ui.window.WindowPosition
 import eu.mjdev.desktop.components.desktoppanel.applets.DesktopMenuIcon
 import eu.mjdev.desktop.components.desktoppanel.applets.DesktopPanelFavoriteApps
 import eu.mjdev.desktop.components.desktoppanel.applets.DesktopPanelLanguage
-import eu.mjdev.desktop.components.shadow.TopShadow
 import eu.mjdev.desktop.components.sliding.SlidingMenu
 import eu.mjdev.desktop.components.sliding.VisibilityState
 import eu.mjdev.desktop.components.sliding.VisibilityState.Companion.rememberVisibilityState
 import eu.mjdev.desktop.data.App
 import eu.mjdev.desktop.extensions.Compose.height
+import eu.mjdev.desktop.extensions.Modifier.topShadow
 import eu.mjdev.desktop.provider.DesktopProvider
 import eu.mjdev.desktop.provider.DesktopProvider.Companion.LocalDesktop
 import eu.mjdev.desktop.windows.ChromeWindow
@@ -40,16 +40,19 @@ import eu.mjdev.desktop.windows.ChromeWindow
 fun DesktopPanel(
     api: DesktopProvider = LocalDesktop.current,
     backgroundColor: Color = api.currentUser.theme.backgroundColor,
-    shadowColor: Color = backgroundColor,
+    shadowColor: Color = Color.Black.copy(alpha = 0.3f),
     iconColor: Color = Color.Black,
     iconBackgroundColor: Color = Color.White,
     dividerWidth: Dp = 4.dp,
     iconSize: DpSize = DpSize(56.dp, 56.dp),
     iconPadding: PaddingValues = PaddingValues(4.dp),
     iconOuterPadding: PaddingValues = PaddingValues(2.dp),
-    panelAlpha: Float = 0.7f,
     showMenuIcon: Boolean = true,
-    panelContentPadding: PaddingValues = PaddingValues(4.dp),
+    panelContentPadding: PaddingValues = PaddingValues(
+        start = 4.dp,
+        bottom = 4.dp,
+        top = 4.dp
+    ),
     panelState: VisibilityState = rememberVisibilityState(),
     enterAnimation: EnterTransition = fadeIn() + slideInVertically(initialOffsetY = { it }),
     exitAnimation: ExitTransition = slideOutVertically(targetOffsetY = { it }) + fadeOut(),
@@ -58,7 +61,7 @@ fun DesktopPanel(
     onTooltip: (item: Any?) -> Unit = { item -> tooltipData.value = item },
     panelHeight: (visible: Boolean) -> Dp = { visible ->
         if (visible)
-            iconSize.height + iconOuterPadding.height + tooltipHeight + panelContentPadding.height + 6.dp
+            iconSize.height + iconOuterPadding.height + tooltipHeight + panelContentPadding.height
         else
             dividerWidth
     },
@@ -112,67 +115,71 @@ fun DesktopPanel(
             ) {
                 Column {
                     Box(
-                        modifier = Modifier.fillMaxWidth()
+                        modifier = Modifier
+                            .fillMaxWidth()
                             .height(tooltipHeight)
+
                     )
-                    TopShadow(
-                        modifier = Modifier.fillMaxWidth()
+                    Column(
+                        modifier = Modifier
+                            .fillMaxWidth()
                             .wrapContentHeight()
+                            .background(
+                                brush = Brush.verticalGradient(
+                                    colors = listOf(
+                                        backgroundColor.copy(alpha = 0.3f),
+                                        backgroundColor.copy(alpha = 0.7f),
+                                        backgroundColor.copy(alpha = 0.3f),
+                                    )
+                                )
+                            )
+                            .topShadow(
+                                color = shadowColor,
+                                offsetY = 4.dp,
+                                blur = 10.dp
+                            )
                             .onPlaced(panelState::onPlaced),
-                        color = shadowColor,
-                        contentBackgroundColor = backgroundColor.copy(alpha = panelAlpha)
                     ) {
-                        Column {
-                            Divider(
-                                modifier = Modifier
-                                    .fillMaxWidth()
-                                    .height(2.dp),
-                                color = Color.White.copy(0.1f),
-                                thickness = 2.dp
-                            )
-                            Box(
-                                modifier = Modifier.fillMaxWidth()
-                                    .wrapContentHeight()
-                                    .background(
-                                        brush = Brush.verticalGradient(
-                                            colors = listOf(
-                                                backgroundColor.copy(alpha = 0.3f),
-                                                backgroundColor.copy(alpha = 0.7f),
-                                                backgroundColor.copy(alpha = 0.3f),
-                                            )
-                                        )
-                                    )
-                                    .padding(panelContentPadding)
-                            ) {
-                                if (showMenuIcon) {
-                                    DesktopMenuIcon(
-                                        modifier = Modifier.align(Alignment.CenterStart),
-                                        iconColor = iconColor,
-                                        iconBackgroundColor = iconBackgroundColor,
-                                        iconSize = iconSize,
-                                        iconPadding = iconPadding,
-                                        iconOuterPadding = iconOuterPadding,
-                                        onTooltip = onTooltip,
-                                        onClick = onMenuIconClicked
-                                    )
-                                }
-                                DesktopPanelFavoriteApps(
-                                    modifier = Modifier.align(Alignment.Center),
+                        Divider(
+                            modifier = Modifier
+                                .fillMaxWidth()
+                                .height(2.dp),
+                            color = Color.White.copy(0.1f),
+                            thickness = 2.dp
+                        )
+                        Box(
+                            modifier = Modifier.fillMaxWidth()
+                                .wrapContentHeight()
+                                .padding(panelContentPadding)
+                        ) {
+                            if (showMenuIcon) {
+                                DesktopMenuIcon(
+                                    modifier = Modifier.align(Alignment.CenterStart),
                                     iconColor = iconColor,
                                     iconBackgroundColor = iconBackgroundColor,
                                     iconSize = iconSize,
                                     iconPadding = iconPadding,
                                     iconOuterPadding = iconOuterPadding,
-                                    onTooltip = onTooltip
-                                )
-                                DesktopPanelLanguage(
-                                    modifier = Modifier.align(Alignment.CenterEnd),
                                     onTooltip = onTooltip,
-                                    onClick = {
-                                        // todo
-                                    }
+                                    onClick = onMenuIconClicked
                                 )
                             }
+                            DesktopPanelFavoriteApps(
+                                modifier = Modifier.align(Alignment.Center),
+                                iconColor = iconColor,
+                                iconBackgroundColor = iconBackgroundColor,
+                                iconSize = iconSize,
+                                iconPadding = iconPadding,
+                                iconOuterPadding = iconOuterPadding,
+                                onTooltip = onTooltip
+                            )
+                            DesktopPanelLanguage(
+                                modifier = Modifier.align(Alignment.CenterEnd),
+                                onTooltip = onTooltip,
+                                onClick = {
+                                    // todo
+                                }
+                            )
                         }
                     }
                 }

+ 0 - 48
src/main/kotlin/eu/mjdev/desktop/components/shadow/LeftShadow.kt

@@ -1,48 +0,0 @@
-package eu.mjdev.desktop.components.shadow
-
-import androidx.compose.desktop.ui.tooling.preview.Preview
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.*
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Brush
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
-
-@Suppress("unused")
-@Preview
-@Composable
-fun LeftShadow(
-    modifier: Modifier = Modifier,
-    alpha: Float = 0.5f,
-    height: Dp = 8.dp,
-    color: Color = Color.Black,
-    contentBackgroundColor: Color = Color.SuperDarkGray,
-    content: @Composable () -> Unit = {}
-) = Row(
-    modifier = modifier,
-    verticalAlignment = Alignment.Top,
-    horizontalArrangement = Arrangement.Start
-) {
-    Box(
-        modifier = Modifier
-            .fillMaxHeight()
-            .width(height)
-            .background(
-                brush = Brush.horizontalGradient(
-                    colors = listOf(
-                        Color.Transparent,
-                        color.copy(alpha = alpha),
-                    )
-                )
-            )
-    )
-    Box(
-        modifier = Modifier.background(contentBackgroundColor)
-    ) {
-        content()
-    }
-}

+ 0 - 48
src/main/kotlin/eu/mjdev/desktop/components/shadow/RightShadow.kt

@@ -1,48 +0,0 @@
-package eu.mjdev.desktop.components.shadow
-
-import androidx.compose.desktop.ui.tooling.preview.Preview
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.*
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Brush
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
-
-@Suppress("unused")
-@Preview
-@Composable
-fun RightShadow(
-    modifier: Modifier = Modifier,
-    alpha: Float = 0.5f,
-    height: Dp = 8.dp,
-    color: Color = Color.Black,
-    contentBackgroundColor: Color = Color.SuperDarkGray,
-    content: @Composable () -> Unit = {}
-) = Row(
-    modifier = modifier,
-    verticalAlignment = Alignment.Top,
-    horizontalArrangement = Arrangement.Start
-) {
-    Box(
-        modifier = Modifier.background(contentBackgroundColor)
-    ) {
-        content()
-    }
-    Box(
-        modifier = Modifier
-            .fillMaxHeight()
-            .width(height)
-            .background(
-                brush = Brush.horizontalGradient(
-                    colors = listOf(
-                        color.copy(alpha = alpha),
-                        Color.Transparent,
-                    )
-                )
-            )
-    )
-}

+ 0 - 46
src/main/kotlin/eu/mjdev/desktop/components/shadow/TopShadow.kt

@@ -1,46 +0,0 @@
-package eu.mjdev.desktop.components.shadow
-
-import androidx.compose.desktop.ui.tooling.preview.Preview
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.*
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Brush
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
-
-@Suppress("unused")
-@Preview
-@Composable
-fun TopShadow(
-    modifier: Modifier = Modifier,
-    alpha: Float = 0.5f,
-    height: Dp = 8.dp,
-    color: Color = Color.Black,
-    contentBackgroundColor: Color = Color.SuperDarkGray,
-    content: @Composable () -> Unit = {}
-) = Column(
-    modifier = modifier,
-    verticalArrangement = Arrangement.Top
-) {
-    Box(
-        modifier = Modifier
-            .fillMaxWidth()
-            .height(height)
-            .background(
-                brush = Brush.verticalGradient(
-                    colors = listOf(
-                        Color.Transparent,
-                        color.copy(alpha = alpha),
-                    )
-                )
-            )
-    )
-    Box(
-        modifier = Modifier.fillMaxWidth().wrapContentHeight().background(contentBackgroundColor)
-    ) {
-        content()
-    }
-}

+ 1 - 1
src/main/kotlin/eu/mjdev/desktop/components/text/TextWithShadow.kt

@@ -19,7 +19,7 @@ import androidx.compose.ui.unit.sp
 fun TextWithShadow(
     modifier: Modifier = Modifier,
     shadowSize: Dp = 4.dp,
-    shadowColor: Color = Color.Black,
+    shadowColor: Color = Color.Black.copy(alpha = 0.3f),
     offsetX: Dp = 0.dp,
     offsetY: Dp = 0.dp,
     fontWeight: FontWeight = FontWeight.Normal,

+ 124 - 0
src/main/kotlin/eu/mjdev/desktop/extensions/Modifier.kt

@@ -1,3 +1,5 @@
+@file:Suppress("MemberVisibilityCanBePrivate")
+
 package eu.mjdev.desktop.extensions
 
 import androidx.compose.animation.core.animateFloatAsState
@@ -10,13 +12,18 @@ import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.Modifier.Node
 import androidx.compose.ui.composed
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.draw.shadow
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.*
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
 import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import eu.mjdev.desktop.extensions.Custom.setMaskFilter
@@ -119,4 +126,121 @@ object Modifier {
         }
     )
 
+    fun Modifier.rightShadow(
+        color: Color,
+        offsetX: Dp,
+        blur: Dp
+    ) = dropShadow(
+        shape = RectangleShape,
+        color = color,
+        offsetX = -offsetX,
+        offsetY = 0.dp,
+        blur = blur,
+        spread = offsetX,
+    )
+
+    fun Modifier.leftShadow(
+        color: Color,
+        offsetX: Dp,
+        blur: Dp
+    ) = dropShadow(
+        shape = RectangleShape,
+        color = color,
+        offsetX = offsetX,
+        offsetY = 0.dp,
+        blur = blur,
+        spread = offsetX,
+    )
+
+    fun Modifier.topShadow(
+        color: Color,
+        offsetY: Dp,
+        blur: Dp
+    ) = dropShadow(
+        shape = RectangleShape,
+        color = color,
+        offsetX = 0.dp,
+        offsetY = -offsetY,
+        blur = blur,
+        spread = offsetY,
+    )
+
+    fun Modifier.bottomShadow(
+        color: Color,
+        offsetY: Dp,
+        blur: Dp
+    ) = dropShadow(
+        shape = RectangleShape,
+        color = color,
+        offsetX = 0.dp,
+        offsetY = offsetY,
+        blur = blur,
+        spread = offsetY,
+    )
+
+    fun Modifier.dropShadow(
+        shape: Shape,
+        color: Color = Color.Black.copy(0.25f),
+        offsetX: Dp = 0.dp,
+        offsetY: Dp = 4.dp,
+        blur: Dp = 4.dp,
+        spread: Dp = 0.dp
+    ): Modifier {
+        return this then DropShadowNodeElement(shape, color, offsetX, offsetY, blur, spread)
+    }
+
+    private data class DropShadowNodeElement(
+        val shape: Shape,
+        val color: Color,
+        val offsetX: Dp,
+        val offsetY: Dp,
+        val blur: Dp,
+        val spread: Dp,
+    ) : ModifierNodeElement<DropShadowNode>() {
+        override fun create() = DropShadowNode(shape, color, offsetX, offsetY, blur, spread)
+
+        override fun update(node: DropShadowNode) {
+            node.shape = shape
+            node.color = color
+            node.offsetX = offsetX
+            node.offsetY = offsetY
+            node.blur = blur
+            node.spread = spread
+        }
+    }
+
+    private class DropShadowNode(
+        var shape: Shape,
+        var color: Color,
+        var offsetX: Dp,
+        var offsetY: Dp,
+        var blur: Dp,
+        var spread: Dp,
+    ) : DrawModifierNode, Node() {
+        override fun ContentDrawScope.draw() {
+            val shadowSize = Size(size.width + spread.toPx(), size.height + spread.toPx())
+            val shadowOutline = shape.createOutline(shadowSize, layoutDirection, this)
+            val rOffsetX = offsetX.toPx() - spread.toPx() / 2
+            val rOffsetY = offsetY.toPx() - spread.toPx() / 2
+            val paint = Paint()
+            paint.color = color
+            if (blur.value > 0) {
+                paint.asFrameworkPaint().apply {
+                    setMaskFilter(blur.toPx())
+                }
+            }
+            drawIntoCanvas { canvas ->
+                // Save the canvas state
+                canvas.save()
+                // Translate to specified offsets
+                canvas.translate(rOffsetX, rOffsetY)
+                // Draw the shadow
+                canvas.drawOutline(shadowOutline, paint)
+                // Restore the canvas state
+                canvas.restore()
+            }
+            drawContent()
+        }
+    }
+
 }