diff --git a/fabric.gradle.kts b/fabric.gradle.kts index 16fe367..3ea562e 100644 --- a/fabric.gradle.kts +++ b/fabric.gradle.kts @@ -141,6 +141,21 @@ loomExt.runs.named("client") { vmArg("-Dpolyplus.badge.debug=true") } +// Every version node declares its own `runClient`/`runServer` + `downloadAssets`, all +// pointing at the shared `run/` dir. A bare `./gradlew runClient` matches the run task +// in every version, dragging in each version's `downloadAssets` — which all write to the +// same directory the active client reads, a hard "implicit dependency" validation +// failure on Gradle 9 (and a needless download of every MC version's assets). Only the +// Stonecutter-active version can actually be launched, so disable these tasks on the +// rest; the bare command then resolves to just the active node. +if (!stonecutter.current.isActive) { + tasks.matching { + it.name == "runClient" || it.name == "runServer" || it.name == "downloadAssets" + }.configureEach { + enabled = false + } +} + tasks.withType().configureEach { val modName = project.property("mod.name") as String val modVersion = project.property("mod.version") as String diff --git a/fabric.obf.gradle.kts b/fabric.obf.gradle.kts index 93fb37e..27f5f4e 100644 --- a/fabric.obf.gradle.kts +++ b/fabric.obf.gradle.kts @@ -143,6 +143,21 @@ loomExt.runs.named("client") { runDir("../../run") } +// Every version node declares its own `runClient`/`runServer` + `downloadAssets`, all +// pointing at the shared `run/` dir. A bare `./gradlew runClient` matches the run task +// in every version, dragging in each version's `downloadAssets` — which all write to the +// same directory the active client reads, a hard "implicit dependency" validation +// failure on Gradle 9 (and a needless download of every MC version's assets). Only the +// Stonecutter-active version can actually be launched, so disable these tasks on the +// rest; the bare command then resolves to just the active node. +if (!stonecutter.current.isActive) { + tasks.matching { + it.name == "runClient" || it.name == "runServer" || it.name == "downloadAssets" + }.configureEach { + enabled = false + } +} + tasks.withType().configureEach { val modName = project.property("mod.name") as String val modVersion = project.property("mod.version") as String diff --git a/src/main/kotlin/org/polyfrost/polyplus/client/gui/PolyPlusMainMenuScreen.kt b/src/main/kotlin/org/polyfrost/polyplus/client/gui/PolyPlusMainMenuScreen.kt index 72bc83d..16f7135 100644 --- a/src/main/kotlin/org/polyfrost/polyplus/client/gui/PolyPlusMainMenuScreen.kt +++ b/src/main/kotlin/org/polyfrost/polyplus/client/gui/PolyPlusMainMenuScreen.kt @@ -52,14 +52,20 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.rotate +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.LinearGradientShader +import androidx.compose.ui.graphics.Shader +import androidx.compose.ui.graphics.ShaderBrush import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.toComposeImageBitmap import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString @@ -347,8 +353,28 @@ private const val ASSETS = "assets/polyplus/mainmenu/" private val PageBackground = Color(0xFF11171C) private val PreviewGradient = Color(0xFF0F1C33) -private val PanelBackground = Color(0x80273137) -private val PanelBorder = Color(0x99FFFFFF) +private val PanelBackground: Color + @Composable get() = LocalTheme.current.componentBackground.copy(alpha = 0.5f) +private const val PanelBorderAngleDeg = 20.0 + +private val PanelBorderBrush: Brush = object : ShaderBrush() { + override fun createShader(size: Size): Shader { + val radians = Math.toRadians(PanelBorderAngleDeg) + val ux = kotlin.math.cos(radians).toFloat() + val uy = kotlin.math.sin(radians).toFloat() + val len = size.width * ux + size.height * uy + return LinearGradientShader( + from = Offset.Zero, + to = Offset(ux * len, uy * len), + colors = listOf( + Color.White.copy(alpha = 0.5f), + Color.White.copy(alpha = 0.15f), + Color.White.copy(alpha = 0.5f), + ), + colorStops = listOf(0f, 0.5f, 1f), + ) + } +} private val ServerIconBackground = Color(0x33FFFFFF) private val CloseBackground = Color(0x80FF4444) private val Color.asSelectedBackground: Color get() = copy(alpha = 0.22f) @@ -356,11 +382,13 @@ private val Color.asSelectedBackground: Color get() = copy(alpha = 0.22f) private val Scrim = Color(0xB3000000) private val WarnColor = Color(0xFFF5A623) private val DangerColor = Color(0xFFFF5A5A) -private val TextPrimary = Color.White -private val TextSecondary = Color(0xBFFFFFFF) +private val TextPrimary: Color + @Composable get() = LocalTheme.current.textColor +private val TextSecondary: Color + @Composable get() = LocalTheme.current.textColorSecondary private val PanelShape = RoundedCornerShape(9.dp) -private val BorderWidth = 0.75.dp +private val BorderWidth = 1.5.dp private val Outfit: FontFamily by lazy { runCatching { @@ -403,6 +431,10 @@ private fun MainMenu( CompositionLocalProvider( LocalUiOversample provides (LocalUiOversample.current * scale.coerceAtLeast(1f)), ) { + val density = LocalDensity.current + var rightColumnHeightPx by remember { mutableStateOf(0) } + val rightColumnHeightDp = rightColumnHeightPx / density.density + val columnBottomPadding = ((BASE_HEIGHT - rightColumnHeightDp) / 2f).coerceAtLeast(0f) Box( modifier = Modifier .align(Alignment.Center) @@ -412,12 +444,33 @@ private fun MainMenu( scaleY = scale }, ) { - CenterColumn(Modifier.align(Alignment.Center), actions, assetsReady) - if (!PolyPlusConfig.hideMainMenuQuickplay) { - LeftColumn(Modifier.align(Alignment.CenterStart).padding(start = 48.dp), servers, pingTick, actions, assetsReady) - } - RightColumn(Modifier.align(Alignment.CenterEnd).padding(end = 48.dp), assetsReady, screen) + CenterColumn( + Modifier.align(Alignment.BottomCenter).padding(bottom = columnBottomPadding.dp), + actions, + assetsReady, + ) } + if (!PolyPlusConfig.hideMainMenuQuickplay) { + LeftColumn( + Modifier + .align(Alignment.CenterStart) + .padding(start = 50.dp) + .guiScaled(scale, TransformOrigin(0f, 0.5f)), + servers, + pingTick, + actions, + assetsReady, + ) + } + RightColumn( + Modifier + .align(Alignment.CenterEnd) + .padding(end = 50.dp) + .guiScaled(scale, TransformOrigin(1f, 0.5f)) + .onSizeChanged { rightColumnHeightPx = it.height }, + assetsReady, + screen, + ) WindowControls( Modifier.align(Alignment.TopEnd).padding(16.dp).guiScaled(scale, TransformOrigin(1f, 0f)), actions, @@ -513,7 +566,7 @@ private fun serverStatusText(server: net.minecraft.client.multiplayer.ServerData private fun RightColumn(modifier: Modifier, assetsReady: Boolean, screen: net.minecraft.client.gui.screens.Screen) { Column( modifier = modifier.width(300.dp), - verticalArrangement = Arrangement.spacedBy(12.dp), + verticalArrangement = Arrangement.spacedBy(14.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { if (!PolyPlusConfig.hideMainMenuPlayerPreview) { @@ -626,7 +679,7 @@ private fun HintBubble(text: String) { .width(280.dp) .clip(PanelShape) .background(PanelBackground) - .border(BorderWidth, PanelBorder, PanelShape) + .border(BorderWidth, PanelBorderBrush, PanelShape) .padding(horizontal = 14.dp, vertical = 10.dp), contentAlignment = Alignment.Center, ) { @@ -712,7 +765,6 @@ private fun HostWorldPopup( modifier = Modifier.weight(1f), assetsReady = assetsReady, onClick = onDismiss, - borderColor = LocalTheme.current.borderColor, ) PillButton( label = "Host", @@ -725,7 +777,6 @@ private fun HostWorldPopup( HostWorldManager.host(screen, chosen, gameMode, allowCheats) } }, - borderColor = LocalTheme.current.borderColor, ) } } @@ -765,6 +816,7 @@ private fun WorldRow( } } +@Composable private fun compatColor(compat: HostWorldManager.Compat): Color = when (compat) { HostWorldManager.Compat.CURRENT -> TextSecondary HostWorldManager.Compat.OLDER -> WarnColor @@ -931,13 +983,15 @@ private fun Footer(modifier: Modifier, guiScale: Float, assetsReady: Boolean) { @Composable private fun FooterBrandText(platform: String, assetsReady: Boolean) { val bodyFont = LocalTheme.current.typography.family + val primary = TextPrimary + val secondary = TextSecondary BasicText( text = buildAnnotatedString { - withStyle(SpanStyle(color = TextPrimary, fontWeight = FontWeight.Bold, fontFamily = if (assetsReady) Outfit else FontFamily.Default)) { + withStyle(SpanStyle(color = primary, fontWeight = FontWeight.Bold, fontFamily = if (assetsReady) Outfit else FontFamily.Default)) { append("ONECLIENT") } - withStyle(SpanStyle(color = TextSecondary, fontFamily = bodyFont)) { + withStyle(SpanStyle(color = secondary, fontFamily = bodyFont)) { append(" ") append(platform) } @@ -951,13 +1005,13 @@ private fun FooterBrandText(platform: String, assetsReady: Boolean) { } @Composable -private fun PillButton(label: String, icon: String, modifier: Modifier = Modifier, assetsReady: Boolean, onClick: () -> Unit = {}, borderColor: Color = PanelBorder) { +private fun PillButton(label: String, icon: String, modifier: Modifier = Modifier, assetsReady: Boolean, onClick: () -> Unit = {}, borderBrush: Brush = PanelBorderBrush) { Row( modifier = modifier .height(45.dp) .clip(PanelShape) .background(PanelBackground) - .border(BorderWidth, borderColor, PanelShape) + .border(BorderWidth, borderBrush, PanelShape) .clickableWithSound(onClick) .padding(horizontal = 18.dp), horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally), @@ -976,7 +1030,7 @@ private fun DropdownPill(label: String, leadingIcon: String, expanded: Boolean, .height(45.dp) .clip(PanelShape) .background(PanelBackground) - .border(BorderWidth, PanelBorder, PanelShape) + .border(BorderWidth, PanelBorderBrush, PanelShape) .clickableWithSound(onClick) .padding(horizontal = 12.dp), contentAlignment = Alignment.Center, @@ -1008,7 +1062,7 @@ private fun ServerRow( .height(64.dp) .clip(PanelShape) .background(PanelBackground) - .border(BorderWidth, PanelBorder, PanelShape) + .border(BorderWidth, PanelBorderBrush, PanelShape) .clickableWithSound(onClick) .padding(horizontal = 14.dp), verticalAlignment = Alignment.CenterVertically, @@ -1044,7 +1098,7 @@ private fun AccountPill(name: String, assetsReady: Boolean) { .height(45.dp) .clip(PanelShape) .background(PanelBackground) - .border(BorderWidth, PanelBorder, PanelShape) + .border(BorderWidth, PanelBorderBrush, PanelShape) .clickable {} .padding(horizontal = 10.dp), contentAlignment = Alignment.Center, @@ -1074,7 +1128,7 @@ private fun IconButton( .size(45.dp) .clip(PanelShape) .background(background) - .border(BorderWidth, PanelBorder, PanelShape) + .border(BorderWidth, PanelBorderBrush, PanelShape) .clickableWithSound(onClick), contentAlignment = Alignment.Center, ) { diff --git a/src/main/kotlin/org/polyfrost/polyplus/client/gui/PolyPlusOnboardingScreen.kt b/src/main/kotlin/org/polyfrost/polyplus/client/gui/PolyPlusOnboardingScreen.kt index e9436d6..c3b8be9 100644 --- a/src/main/kotlin/org/polyfrost/polyplus/client/gui/PolyPlusOnboardingScreen.kt +++ b/src/main/kotlin/org/polyfrost/polyplus/client/gui/PolyPlusOnboardingScreen.kt @@ -35,7 +35,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.shadow +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.LinearGradientShader +import androidx.compose.ui.graphics.Shader +import androidx.compose.ui.graphics.ShaderBrush +import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.skiaCanvas @@ -53,6 +60,7 @@ import org.jetbrains.skia.Image as SkiaImage import org.polyfrost.oneconfig.internal.ui.components.Icon import org.polyfrost.oneconfig.internal.ui.components.LocalUiOversample import org.polyfrost.oneconfig.internal.ui.compose.ComposeScreen +import org.polyfrost.oneconfig.internal.ui.themes.Accent import org.polyfrost.oneconfig.internal.ui.themes.LocalTheme import org.polyfrost.oneconfig.internal.ui.themes.Theme import org.polyfrost.polyplus.client.PolyPlusConfig @@ -177,8 +185,8 @@ class PolyPlusOnboardingScreen : ComposeScreen(RenderMode.CONTINUOUS) { spotColor = ShadowColor, ) .clip(PANEL_SHAPE) - .background(PanelBackground) - .border(1.3.dp, PanelBorder, PANEL_SHAPE), + .background(PageBackground.copy(alpha = 0.9f)) + .border(BorderWidth, LocalTheme.current.borderColor, PANEL_SHAPE), ) { when (pages[page]) { OnboardingPage.LOOK_AND_FEEL -> @@ -340,10 +348,10 @@ private fun MotionBlurSection(y: Float, motionBlur: Int, onMotionBlur: (Int) -> .width(332.dp) .height(7.dp) .clip(RoundedCornerShape(4.dp)) - .background(Color(0x80273137)) - .border(1.dp, PanelBorder, RoundedCornerShape(4.dp)), + .background(ChoiceBackground) + .border(1.dp, PanelBorderBrush, RoundedCornerShape(4.dp)), ) { - Box(Modifier.fillMaxWidth(progress).height(7.dp).background(Brand)) + Box(Modifier.fillMaxWidth(progress).height(7.dp).background(Accent)) } Box( Modifier @@ -356,8 +364,8 @@ private fun MotionBlurSection(y: Float, motionBlur: Int, onMotionBlur: (Int) -> } Spacer(Modifier.width(18.dp)) Box( - Modifier.width(64.dp).height(26.dp).clip(RoundedCornerShape(6.dp)).background(Color(0x80273137)) - .border(1.dp, PanelBorder, RoundedCornerShape(6.dp)), + Modifier.width(64.dp).height(26.dp).clip(RoundedCornerShape(6.dp)).background(ChoiceBackground) + .border(1.dp, PanelBorderBrush, RoundedCornerShape(6.dp)), contentAlignment = Alignment.CenterStart, ) { OnboardingText(motionBlur.toString(), 12, Modifier.padding(start = 8.dp)) } } @@ -379,8 +387,8 @@ private fun CosmeticsPage(onClaim: () -> Unit, onStore: () -> Unit) { CosmeticCard("Starter Cape") CosmeticCard("Starter Bag") } - ChoiceButton("Claim Free Cosmetics", ONBOARDING_ASSETS + "diamond.svg", true, 272f, Modifier.offset(304.dp, 445.dp), onClaim) - ChoiceButton("Check Out the Store", ONBOARDING_ASSETS + "shopping-bag.svg", false, 272f, Modifier.offset(304.dp, 493.dp), onStore) + ChoiceButton("Claim Free Cosmetics", ONBOARDING_ASSETS + "diamond.svg", true, 272f, Modifier.offset(304.dp, 445.dp), onClick = onClaim) + ChoiceButton("Check Out the Store", ONBOARDING_ASSETS + "shopping-bag.svg", false, 272f, Modifier.offset(304.dp, 493.dp), onClick = onStore) } @Composable @@ -414,29 +422,38 @@ private fun ChoiceButton( selected: Boolean, width: Float, modifier: Modifier = Modifier, + primary: Boolean = false, onClick: () -> Unit, ) { + val contentColor = if (primary) Color.White else TextPrimary Row( modifier .width(width.dp) .height(32.dp) .clip(ButtonShape) - .background(ChoiceBackground) - .border(if (selected) 2.dp else 1.dp, if (selected) Brand else PanelBorder, ButtonShape) + .background( + when { + primary -> Accent + selected -> Accent.asSelectedBackground + else -> ChoiceBackground + }, + ) + .border(BorderWidth, if (selected || primary) SolidColor(Accent) else PanelBorderBrush, ButtonShape) .clickableWithSound(onClick), horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally), verticalAlignment = Alignment.CenterVertically, ) { - OnboardingIcon(icon, TextPrimary, Modifier.size(17.dp)) - OnboardingText(label, 14, color = TextPrimary, weight = FontWeight.Medium) + OnboardingIcon(icon, contentColor, Modifier.size(17.dp)) + OnboardingText(label, 14, color = contentColor, weight = FontWeight.Medium) } } @Composable private fun StyleCard(label: String, selected: Boolean, rounded: Boolean, onClick: () -> Unit) { Box( - Modifier.size(198.dp, 155.dp).clip(ButtonShape).background(ChoiceBackground) - .border(if (selected) 2.dp else 1.dp, if (selected) Brand else PanelBorder, ButtonShape) + Modifier.size(198.dp, 155.dp).clip(ButtonShape) + .background(if (selected) Accent.asSelectedBackground else ChoiceBackground) + .border(BorderWidth, if (selected) SolidColor(Accent) else PanelBorderBrush, ButtonShape) .clickableWithSound(onClick), ) { UiPreview(Modifier.offset(13.dp, 12.dp), rounded) @@ -449,7 +466,7 @@ private fun UiPreview(modifier: Modifier, rounded: Boolean) { val shape = if (rounded) RoundedCornerShape(8.dp) else RoundedCornerShape(0.dp) Row(modifier.size(172.dp, 108.dp).clip(shape).border(1.dp, Color(0x1AFFFFFF), shape)) { Column(Modifier.width(44.dp).height(108.dp).background(Color(0xB3151C22)).padding(8.dp, 7.dp), verticalArrangement = Arrangement.spacedBy(5.dp)) { - Box(Modifier.size(29.dp, 7.dp).background(Brand)) + Box(Modifier.size(29.dp, 7.dp).background(Accent)) repeat(3) { Box(Modifier.width(if (it == 0) 20.dp else 29.dp).height(4.dp).background(if (it == 0) TextSecondary else TextPrimary)) } } Column(Modifier.width(128.dp).height(108.dp).background(Color(0xF211171C)).padding(8.dp, 7.dp)) { @@ -457,7 +474,7 @@ private fun UiPreview(modifier: Modifier, rounded: Boolean) { Spacer(Modifier.height(8.dp)) repeat(3) { Row(horizontalArrangement = Arrangement.spacedBy(5.dp)) { - repeat(3) { Box(Modifier.size(34.dp, 23.dp).background(Color(0xFF1A2229)).border(0.dp, Color.Transparent).padding(top = 17.dp).background(Brand)) } + repeat(3) { Box(Modifier.size(34.dp, 23.dp).background(Color(0xFF1A2229)).border(0.dp, Color.Transparent).padding(top = 17.dp).background(Accent)) } } Spacer(Modifier.height(5.dp)) } @@ -468,8 +485,9 @@ private fun UiPreview(modifier: Modifier, rounded: Boolean) { @Composable private fun HudCard(label: String, selected: Boolean, rounded: Boolean, onClick: () -> Unit) { Box( - Modifier.size(198.dp, 94.dp).clip(ButtonShape).background(ChoiceBackground) - .border(if (selected) 2.dp else 1.dp, if (selected) Brand else PanelBorder, ButtonShape) + Modifier.size(198.dp, 94.dp).clip(ButtonShape) + .background(if (selected) Accent.asSelectedBackground else ChoiceBackground) + .border(BorderWidth, if (selected) SolidColor(Accent) else PanelBorderBrush, ButtonShape) .clickableWithSound(onClick), ) { Box( @@ -484,7 +502,7 @@ private fun HudCard(label: String, selected: Boolean, rounded: Boolean, onClick: @Composable private fun CosmeticCard(label: String) { - Box(Modifier.size(180.dp, 202.dp).clip(RoundedCornerShape(10.dp)).background(ChoiceBackground).border(1.dp, Color(0x66FFFFFF), RoundedCornerShape(10.dp))) { + Box(Modifier.size(180.dp, 202.dp).clip(RoundedCornerShape(10.dp)).background(ChoiceBackground).border(BorderWidth, PanelBorderBrush, RoundedCornerShape(10.dp))) { Checkerboard(Modifier.offset(17.dp, 18.dp).size(146.dp, 146.dp).clip(RoundedCornerShape(4.dp))) OnboardingText(label, 14, Modifier.align(Alignment.BottomCenter).padding(bottom = 13.dp), TextPrimary, FontWeight.Medium) } @@ -513,11 +531,11 @@ private fun Checkerboard(modifier: Modifier) { @Composable private fun BottomNavigation(page: Int, pageCount: Int, onSkip: () -> Unit, onBack: () -> Unit, onNext: () -> Unit) { if (page == 0) { - ChoiceButton("Skip", MAIN_MENU_ASSETS + "x-close.svg", false, 100f, Modifier.offset(26.dp, 604.dp), onSkip) + ChoiceButton("Skip", MAIN_MENU_ASSETS + "x-close.svg", false, 100f, Modifier.offset(26.dp, 604.dp), onClick = onSkip) } else { - ChoiceButton("Back", "assets/polyplus/ico/left-arrow.svg", false, 100f, Modifier.offset(26.dp, 604.dp), onBack) + ChoiceButton("Back", "assets/polyplus/ico/left-arrow.svg", false, 100f, Modifier.offset(26.dp, 604.dp), onClick = onBack) } - ChoiceButton(if (page == pageCount - 1) "Finish" else "Next", MAIN_MENU_ASSETS + "chevron-right.svg", true, 100f, Modifier.offset(754.dp, 604.dp), onNext) + ChoiceButton(if (page == pageCount - 1) "Finish" else "Next", "assets/polyplus/ico/right-arrow.svg", false, 100f, Modifier.offset(754.dp, 604.dp), primary = true, onClick = onNext) Row(Modifier.offset(((PANEL_WIDTH - (pageCount * 17f - 5f)) / 2f).dp, 614.dp), horizontalArrangement = Arrangement.spacedBy(5.dp), verticalAlignment = Alignment.CenterVertically) { repeat(pageCount) { index -> Box( @@ -555,7 +573,7 @@ private fun MotionBlurPreview(strength: Int, modifier: Modifier = Modifier) { modifier .clip(shape) .background(Color(0xFF273137)) - .border(1.dp, Color.White, shape), + .border(1.dp, PanelBorderBrush, shape), ) { if (image != null) { Canvas(Modifier.fillMaxSize()) { @@ -622,12 +640,38 @@ private const val BLUR_PREVIEW_HEIGHT = 115f private const val BLUR_SECTION_HEIGHT = BLUR_PREVIEW_OFFSET + BLUR_PREVIEW_HEIGHT private const val ONBOARDING_ASSETS = "assets/polyplus/onboarding/" private const val MAIN_MENU_ASSETS = "assets/polyplus/mainmenu/" -private val PANEL_SHAPE = RoundedCornerShape(10.345.dp) -private val ButtonShape = RoundedCornerShape(6.dp) -private val PanelBackground = Color(0x73232D32) -private val PanelBorder = Color(0x66FFFFFF) + +private val PANEL_SHAPE = RoundedCornerShape(9.dp) +private val ButtonShape = RoundedCornerShape(9.dp) +private val BorderWidth = 1.5.dp +private const val PanelBorderAngleDeg = 20.0 + +private val PageBackground = Color(0xFF11171C) private val ShadowColor = Color(0x26000000) -private val ChoiceBackground = Color(0x80273137) -private val Brand = Color(0xFF3F7CE4) -private val TextPrimary = Color(0xFFD5DBFF) -private val TextSecondary = Color(0xFF78818D) + +private val ChoiceBackground: Color + @Composable get() = LocalTheme.current.componentBackground.copy(alpha = 0.5f) +private val TextPrimary: Color + @Composable get() = LocalTheme.current.textColor +private val TextSecondary: Color + @Composable get() = LocalTheme.current.textColorSecondary +private val Color.asSelectedBackground: Color get() = copy(alpha = 0.22f) + +private val PanelBorderBrush: Brush = object : ShaderBrush() { + override fun createShader(size: Size): Shader { + val radians = Math.toRadians(PanelBorderAngleDeg) + val ux = kotlin.math.cos(radians).toFloat() + val uy = kotlin.math.sin(radians).toFloat() + val len = size.width * ux + size.height * uy + return LinearGradientShader( + from = Offset.Zero, + to = Offset(ux * len, uy * len), + colors = listOf( + Color.White.copy(alpha = 0.5f), + Color.White.copy(alpha = 0.15f), + Color.White.copy(alpha = 0.5f), + ), + colorStops = listOf(0f, 0.5f, 1f), + ) + } +} diff --git a/src/main/resources/assets/polyplus/ico/right-arrow.svg b/src/main/resources/assets/polyplus/ico/right-arrow.svg index e24e701..ab35751 100644 --- a/src/main/resources/assets/polyplus/ico/right-arrow.svg +++ b/src/main/resources/assets/polyplus/ico/right-arrow.svg @@ -1,3 +1,3 @@ - +