|
@@ -2,26 +2,22 @@
|
|
|
|
|
|
|
|
package eu.mjdev.desktop.extensions
|
|
package eu.mjdev.desktop.extensions
|
|
|
|
|
|
|
|
-import androidx.compose.foundation.border
|
|
|
|
|
-import androidx.compose.foundation.shape.CircleShape
|
|
|
|
|
|
|
+import androidx.compose.foundation.layout.PaddingValues
|
|
|
import androidx.compose.material.ButtonDefaults
|
|
import androidx.compose.material.ButtonDefaults
|
|
|
-import androidx.compose.runtime.*
|
|
|
|
|
-import androidx.compose.ui.Modifier
|
|
|
|
|
-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.graphics.*
|
|
|
|
|
-import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
|
|
|
|
-import androidx.compose.ui.unit.Dp
|
|
|
|
|
-import androidx.compose.ui.unit.dp
|
|
|
|
|
|
|
+import androidx.compose.material.MaterialTheme
|
|
|
|
|
+import androidx.compose.runtime.Composable
|
|
|
|
|
+import androidx.compose.runtime.LaunchedEffect
|
|
|
|
|
+import androidx.compose.runtime.MutableState
|
|
|
|
|
+import androidx.compose.ui.graphics.Color
|
|
|
|
|
+import androidx.compose.ui.graphics.painter.Painter
|
|
|
|
|
+import androidx.compose.ui.input.key.KeyEvent
|
|
|
|
|
+import androidx.compose.ui.unit.*
|
|
|
import androidx.compose.ui.window.FrameWindowScope
|
|
import androidx.compose.ui.window.FrameWindowScope
|
|
|
import androidx.compose.ui.window.Window
|
|
import androidx.compose.ui.window.Window
|
|
|
import androidx.compose.ui.window.WindowPlacement
|
|
import androidx.compose.ui.window.WindowPlacement
|
|
|
import androidx.compose.ui.window.rememberWindowState
|
|
import androidx.compose.ui.window.rememberWindowState
|
|
|
|
|
+import eu.mjdev.desktop.provider.DesktopProvider.Companion.desktopLocalProvider
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
-import org.jetbrains.skia.FilterBlurMode
|
|
|
|
|
-import org.jetbrains.skia.MaskFilter
|
|
|
|
|
|
|
|
|
|
object Compose {
|
|
object Compose {
|
|
|
|
|
|
|
@@ -37,17 +33,28 @@ object Compose {
|
|
|
val Color.Companion.LiteDarkGray: Color
|
|
val Color.Companion.LiteDarkGray: Color
|
|
|
get() = Color(0xffc0c0c0)
|
|
get() = Color(0xffc0c0c0)
|
|
|
|
|
|
|
|
- fun Modifier.conditional(
|
|
|
|
|
- condition: Boolean,
|
|
|
|
|
- onFalse: (Modifier.() -> Modifier)? = null,
|
|
|
|
|
- onTrue: Modifier.() -> Modifier,
|
|
|
|
|
- ): Modifier = if (condition) {
|
|
|
|
|
- then(onTrue(Modifier))
|
|
|
|
|
- } else if (onFalse != null) {
|
|
|
|
|
- then(onFalse(Modifier))
|
|
|
|
|
- } else {
|
|
|
|
|
- this
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ val PaddingValues.width: Dp
|
|
|
|
|
+ get() = calculateLeftPadding(LayoutDirection.Ltr) + calculateRightPadding(LayoutDirection.Ltr)
|
|
|
|
|
+
|
|
|
|
|
+ val Dp.sp: TextUnit
|
|
|
|
|
+ get() = value.sp
|
|
|
|
|
+
|
|
|
|
|
+ val PaddingValues.height: Dp
|
|
|
|
|
+ get() = calculateTopPadding() + calculateBottomPadding()
|
|
|
|
|
+
|
|
|
|
|
+ val PaddingValues.size: DpSize
|
|
|
|
|
+ get() = DpSize(width, height)
|
|
|
|
|
+
|
|
|
|
|
+ @Composable
|
|
|
|
|
+ fun launchedEffect(
|
|
|
|
|
+ block: suspend CoroutineScope.() -> Unit
|
|
|
|
|
+ ) = LaunchedEffect(Unit, block)
|
|
|
|
|
+
|
|
|
|
|
+ @Composable
|
|
|
|
|
+ fun launchedEffect(
|
|
|
|
|
+ key: Any?,
|
|
|
|
|
+ block: suspend CoroutineScope.() -> Unit
|
|
|
|
|
+ ) = LaunchedEffect(key, block)
|
|
|
|
|
|
|
|
@Composable
|
|
@Composable
|
|
|
fun <T> textFrom(text: T?): String = when (text) {
|
|
fun <T> textFrom(text: T?): String = when (text) {
|
|
@@ -63,17 +70,6 @@ object Compose {
|
|
|
fun ButtonDefaults.noElevation() =
|
|
fun ButtonDefaults.noElevation() =
|
|
|
elevation(0.dp, 0.dp, 0.dp, 0.dp, 0.dp)
|
|
elevation(0.dp, 0.dp, 0.dp, 0.dp, 0.dp)
|
|
|
|
|
|
|
|
- @Composable
|
|
|
|
|
- fun launchedEffect(
|
|
|
|
|
- block: suspend CoroutineScope.() -> Unit
|
|
|
|
|
- ) = LaunchedEffect(Unit, block)
|
|
|
|
|
-
|
|
|
|
|
- @Composable
|
|
|
|
|
- fun launchedEffect(
|
|
|
|
|
- key: Any?,
|
|
|
|
|
- block: suspend CoroutineScope.() -> Unit
|
|
|
|
|
- ) = LaunchedEffect(key, block)
|
|
|
|
|
-
|
|
|
|
|
@Composable
|
|
@Composable
|
|
|
fun ButtonDefaults.color(color: Color) = buttonColors(
|
|
fun ButtonDefaults.color(color: Color) = buttonColors(
|
|
|
backgroundColor = color,
|
|
backgroundColor = color,
|
|
@@ -90,78 +86,77 @@ object Compose {
|
|
|
disabledBackgroundColor = Color.Transparent
|
|
disabledBackgroundColor = Color.Transparent
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- @Stable
|
|
|
|
|
- fun Modifier.shadow(
|
|
|
|
|
- elevation: Dp,
|
|
|
|
|
- shape: Shape = RectangleShape,
|
|
|
|
|
- color: Color = DefaultShadowColor,
|
|
|
|
|
- clip: Boolean = false,
|
|
|
|
|
- ): Modifier = shadow(elevation, shape, clip, color, color)
|
|
|
|
|
-
|
|
|
|
|
- @Composable
|
|
|
|
|
- fun Modifier.rectShadow(
|
|
|
|
|
- size: Dp = 8.dp,
|
|
|
|
|
- color: Color = Color.Black,
|
|
|
|
|
- shape: Shape = RectangleShape
|
|
|
|
|
- ) = shadow(size, shape, color)
|
|
|
|
|
-
|
|
|
|
|
- @Composable
|
|
|
|
|
- fun Modifier.circleShadow(
|
|
|
|
|
- size: Dp = 8.dp,
|
|
|
|
|
- color: Color = Color.Black,
|
|
|
|
|
- shape: Shape = CircleShape
|
|
|
|
|
- ) = shadow(size, shape, color)
|
|
|
|
|
-
|
|
|
|
|
- @Composable
|
|
|
|
|
- fun Modifier.clipCircle() = clip(CircleShape)
|
|
|
|
|
-
|
|
|
|
|
@Composable
|
|
@Composable
|
|
|
- fun Modifier.circleBorder(
|
|
|
|
|
- width: Dp = 2.dp,
|
|
|
|
|
- color: Color = Color.White
|
|
|
|
|
- ) = clipCircle().border(width, color, CircleShape)
|
|
|
|
|
-
|
|
|
|
|
- @Composable
|
|
|
|
|
- fun Modifier.coloredCircleShadow(
|
|
|
|
|
- color: Color,
|
|
|
|
|
- blurRadius: Float,
|
|
|
|
|
- offsetY: Dp,
|
|
|
|
|
- offsetX: Dp,
|
|
|
|
|
- ) = then(
|
|
|
|
|
- drawBehind {
|
|
|
|
|
- drawIntoCanvas { canvas ->
|
|
|
|
|
- val paint = Paint()
|
|
|
|
|
- val frameworkPaint = paint.asFrameworkPaint()
|
|
|
|
|
- if (blurRadius != 0f) {
|
|
|
|
|
- frameworkPaint.setMaskFilter(blurRadius)
|
|
|
|
|
|
|
+ fun FullScreenWindow(
|
|
|
|
|
+ visible: Boolean = true,
|
|
|
|
|
+ title: String = "",
|
|
|
|
|
+ icon: Painter? = null,
|
|
|
|
|
+ focusable: Boolean = true,
|
|
|
|
|
+ alwaysOnTop: Boolean = false,
|
|
|
|
|
+ onPreviewKeyEvent: (KeyEvent) -> Boolean = { false },
|
|
|
|
|
+ onKeyEvent: (KeyEvent) -> Boolean = { false },
|
|
|
|
|
+ onCloseRequest: () -> Unit = {},
|
|
|
|
|
+ content: @Composable FrameWindowScope.() -> Unit
|
|
|
|
|
+ ) = Window(
|
|
|
|
|
+ state = rememberWindowState(
|
|
|
|
|
+ placement = WindowPlacement.Fullscreen
|
|
|
|
|
+ ),
|
|
|
|
|
+ resizable = false,
|
|
|
|
|
+ undecorated = true,
|
|
|
|
|
+ transparent = true,
|
|
|
|
|
+ focusable = focusable,
|
|
|
|
|
+ alwaysOnTop = alwaysOnTop,
|
|
|
|
|
+ visible = visible,
|
|
|
|
|
+ title = title,
|
|
|
|
|
+ icon = icon,
|
|
|
|
|
+ onPreviewKeyEvent = onPreviewKeyEvent,
|
|
|
|
|
+ onKeyEvent = onKeyEvent,
|
|
|
|
|
+ onCloseRequest = onCloseRequest,
|
|
|
|
|
+ content = {
|
|
|
|
|
+ MaterialTheme {
|
|
|
|
|
+ desktopLocalProvider {
|
|
|
|
|
+ content()
|
|
|
}
|
|
}
|
|
|
- frameworkPaint.color = color.toArgb()
|
|
|
|
|
- val centerX = size.width / 2 + offsetX.toPx()
|
|
|
|
|
- val centerY = size.height / 2 + offsetY.toPx()
|
|
|
|
|
- val radius = size.width.coerceAtLeast(size.height) / 2
|
|
|
|
|
- canvas.drawCircle(Offset(centerX, centerY), radius, paint)
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- fun NativePaint.setMaskFilter(
|
|
|
|
|
- blurRadius: Float
|
|
|
|
|
- ) {
|
|
|
|
|
- this.maskFilter = MaskFilter.makeBlur(FilterBlurMode.NORMAL, blurRadius / 2, true)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
@Composable
|
|
@Composable
|
|
|
- fun fullScreenWindow(
|
|
|
|
|
|
|
+ fun TopWindow(
|
|
|
|
|
+ // todo
|
|
|
|
|
+ @Suppress("UNUSED_PARAMETER") movable: Boolean = false,
|
|
|
|
|
+ resizable: Boolean = false,
|
|
|
|
|
+ undecorated: Boolean = true,
|
|
|
|
|
+ visible: Boolean = true,
|
|
|
|
|
+ title: String = "",
|
|
|
|
|
+ icon: Painter? = null,
|
|
|
|
|
+ focusable: Boolean = true,
|
|
|
|
|
+ onPreviewKeyEvent: (KeyEvent) -> Boolean = { false },
|
|
|
|
|
+ onKeyEvent: (KeyEvent) -> Boolean = { false },
|
|
|
onCloseRequest: () -> Unit = {},
|
|
onCloseRequest: () -> Unit = {},
|
|
|
content: @Composable FrameWindowScope.() -> Unit
|
|
content: @Composable FrameWindowScope.() -> Unit
|
|
|
) = Window(
|
|
) = Window(
|
|
|
state = rememberWindowState(
|
|
state = rememberWindowState(
|
|
|
- placement = WindowPlacement.Fullscreen
|
|
|
|
|
|
|
+ placement = WindowPlacement.Floating
|
|
|
),
|
|
),
|
|
|
- resizable = false,
|
|
|
|
|
- undecorated = true,
|
|
|
|
|
|
|
+ resizable = resizable,
|
|
|
|
|
+ undecorated = undecorated,
|
|
|
onCloseRequest = onCloseRequest,
|
|
onCloseRequest = onCloseRequest,
|
|
|
- content = content
|
|
|
|
|
|
|
+ visible = visible,
|
|
|
|
|
+ transparent = true,
|
|
|
|
|
+ title = title,
|
|
|
|
|
+ icon = icon,
|
|
|
|
|
+ focusable = focusable,
|
|
|
|
|
+ alwaysOnTop = true,
|
|
|
|
|
+ onPreviewKeyEvent = onPreviewKeyEvent,
|
|
|
|
|
+ onKeyEvent = onKeyEvent,
|
|
|
|
|
+ content = {
|
|
|
|
|
+ MaterialTheme {
|
|
|
|
|
+ desktopLocalProvider {
|
|
|
|
|
+ content()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
}
|
|
}
|