From 66dd5ed6e60547629b9cf91431d030d75886aef8 Mon Sep 17 00:00:00 2001 From: Yiqun Zhang <guiyanakuang@gmail.com> Date: Fri, 24 Nov 2023 16:54:13 +0800 Subject: [PATCH] :bug: Avoid jagged graphics by using native rounded corners --- .../kotlin/com/clipevery/ClipeveryApp.kt | 45 ++++++++++++- .../desktopMain/kotlin/com/clipevery/main.kt | 65 ++++--------------- 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt b/composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt index b06fb58bf..a2f612c68 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt @@ -2,6 +2,7 @@ package com.clipevery import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -15,8 +16,10 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme +import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -28,6 +31,8 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.toComposeImageBitmap @@ -42,7 +47,10 @@ import kotlinx.coroutines.launch @Composable fun ClipeveryApp(dependencies: Dependencies) { MaterialTheme { - Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { + Column(Modifier.fillMaxWidth() + .clip(RoundedCornerShape(10.dp)) + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally) { ClipeveryCommon(dependencies) } } @@ -65,9 +73,8 @@ fun ClipeveryCommon(dependencies: Dependencies) { @Composable fun ClipeveryWithProvidedDependencies() { val configManager = LocalConfigManager.current - val config = remember { mutableStateOf(configManager.config) } - + CustomWindowDecoration() if (!config.value.bindingState) { bindingQRCode() } else { @@ -75,6 +82,38 @@ fun ClipeveryWithProvidedDependencies() { } } +@Composable +fun CustomWindowDecoration() { + Surface( + modifier = Modifier + .fillMaxWidth() + .height(62.dp), + color = MaterialTheme.colors.background, + shape = RoundedCornerShape( + topStart = 10.dp, + topEnd = 10.dp, + bottomEnd = 0.dp, + bottomStart = 0.dp + ) + ) { + Box( + modifier = Modifier.background(Color.Black) + .background( + brush = Brush.verticalGradient( + colors = listOf( + Color.White.copy(alpha = 0.6f), + Color.Transparent + ), + startY = 0.0f, + endY = 3.0f + ) + ), + ) { + // Custom title bar content + } + } +} + @Composable fun bindingQRCode() { diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/main.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/main.kt index 193b6b033..e27151f43 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/main.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/main.kt @@ -1,25 +1,13 @@ package com.clipevery -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Surface -import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier import androidx.compose.ui.awt.ComposeWindow -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Tray import androidx.compose.ui.window.Window import androidx.compose.ui.window.WindowPlacement @@ -50,7 +38,8 @@ import com.clipevery.utils.initAppUI import com.clipevery.utils.ioDispatcher import io.github.oshai.kotlinlogging.KotlinLogging import kotlinx.coroutines.CoroutineScope -import java.awt.geom.RoundRectangle2D +import java.awt.Rectangle +import java.awt.geom.Area import java.nio.file.Path import kotlin.io.path.pathString @@ -86,7 +75,8 @@ fun main() = application { size = getPreferredWindowSize(appUI) ) - Tray(icon = trayIcon, + Tray( + icon = trayIcon, mouseListener = getTrayMouseAdapter(windowState) { showWindow = !showWindow }, ) @@ -104,7 +94,7 @@ fun main() = application { LaunchedEffect(Unit) { window.addComponentListener(object : java.awt.event.ComponentAdapter() { override fun componentResized(e: java.awt.event.ComponentEvent?) { - applyRoundedCorners(window) + setWindowShapeWithTransparentEdges(window, 10) } }) window.addWindowFocusListener(object : java.awt.event.WindowFocusListener { @@ -117,48 +107,21 @@ fun main() = application { } }) } - CustomWindowDecoration() ClipeveryApp(dependencies) } } -@Composable -fun CustomWindowDecoration() { - Surface( - modifier = Modifier - .fillMaxWidth() - .height(62.dp), - color = MaterialTheme.colors.background, - shape = RoundedCornerShape( - topStart = 10.dp, - topEnd = 10.dp, - bottomEnd = 0.dp, - bottomStart = 0.dp - ) - ) { - Box( - modifier = Modifier.background(Color.Black) - .background( - brush = Brush.verticalGradient( - colors = listOf( - Color.White.copy(alpha = 0.6f), - Color.Transparent - ), - startY = 0.0f, - endY = 3.0f - ) - ), - ) { - // Custom title bar content - } - } -} -fun applyRoundedCorners(window: ComposeWindow) { - val radius = 20.0 - val shape = RoundRectangle2D.Double(0.0, 0.0, window.width.toDouble(), window.height.toDouble(), radius, radius) - window.shape = shape + +fun setWindowShapeWithTransparentEdges(window: ComposeWindow, transparentHeight: Int) { + val originalRect = Rectangle(0, 0, window.width, window.height) + val area = Area(originalRect) + val topRect = Rectangle(0, 0, window.width, transparentHeight) + val bottomRect = Rectangle(0, window.height - transparentHeight, window.width, transparentHeight) + area.subtract(Area(topRect)) + area.subtract(Area(bottomRect)) + window.shape = area }