@@ -52,14 +52,20 @@ import androidx.compose.ui.Modifier
5252import androidx.compose.ui.draw.alpha
5353import androidx.compose.ui.draw.clip
5454import androidx.compose.ui.draw.rotate
55+ import androidx.compose.ui.geometry.Offset
56+ import androidx.compose.ui.geometry.Size
5557import androidx.compose.ui.graphics.graphicsLayer
5658import androidx.compose.ui.graphics.Brush
5759import androidx.compose.ui.graphics.Color
60+ import androidx.compose.ui.graphics.LinearGradientShader
61+ import androidx.compose.ui.graphics.Shader
62+ import androidx.compose.ui.graphics.ShaderBrush
5863import androidx.compose.ui.graphics.ImageBitmap
5964import androidx.compose.ui.graphics.TransformOrigin
6065import androidx.compose.ui.graphics.toComposeImageBitmap
6166import androidx.compose.ui.layout.ContentScale
6267import androidx.compose.ui.layout.onSizeChanged
68+ import androidx.compose.ui.platform.LocalDensity
6369import androidx.compose.ui.text.TextStyle
6470import androidx.compose.ui.text.SpanStyle
6571import androidx.compose.ui.text.buildAnnotatedString
@@ -347,20 +353,42 @@ private const val ASSETS = "assets/polyplus/mainmenu/"
347353
348354private val PageBackground = Color (0xFF11171C )
349355private val PreviewGradient = Color (0xFF0F1C33 )
350- private val PanelBackground = Color (0x80273137 )
351- private val PanelBorder = Color (0x99FFFFFF )
356+ private val PanelBackground : Color
357+ @Composable get() = LocalTheme .current.componentBackground.copy(alpha = 0.5f )
358+ private const val PanelBorderAngleDeg = 20.0
359+
360+ private val PanelBorderBrush : Brush = object : ShaderBrush () {
361+ override fun createShader (size : Size ): Shader {
362+ val radians = Math .toRadians(PanelBorderAngleDeg )
363+ val ux = kotlin.math.cos(radians).toFloat()
364+ val uy = kotlin.math.sin(radians).toFloat()
365+ val len = size.width * ux + size.height * uy
366+ return LinearGradientShader (
367+ from = Offset .Zero ,
368+ to = Offset (ux * len, uy * len),
369+ colors = listOf (
370+ Color .White .copy(alpha = 0.5f ),
371+ Color .White .copy(alpha = 0.15f ),
372+ Color .White .copy(alpha = 0.5f ),
373+ ),
374+ colorStops = listOf (0f , 0.5f , 1f ),
375+ )
376+ }
377+ }
352378private val ServerIconBackground = Color (0x33FFFFFF )
353379private val CloseBackground = Color (0x80FF4444 )
354380private val Color .asSelectedBackground: Color get() = copy(alpha = 0.22f )
355381
356382private val Scrim = Color (0xB3000000 )
357383private val WarnColor = Color (0xFFF5A623 )
358384private val DangerColor = Color (0xFFFF5A5A )
359- private val TextPrimary = Color .White
360- private val TextSecondary = Color (0xBFFFFFFF )
385+ private val TextPrimary : Color
386+ @Composable get() = LocalTheme .current.textColor
387+ private val TextSecondary : Color
388+ @Composable get() = LocalTheme .current.textColorSecondary
361389
362390private val PanelShape = RoundedCornerShape (9 .dp)
363- private val BorderWidth = 0.75 .dp
391+ private val BorderWidth = 1.5 .dp
364392
365393private val Outfit : FontFamily by lazy {
366394 runCatching {
@@ -403,6 +431,10 @@ private fun MainMenu(
403431 CompositionLocalProvider (
404432 LocalUiOversample provides (LocalUiOversample .current * scale.coerceAtLeast(1f )),
405433 ) {
434+ val density = LocalDensity .current
435+ var rightColumnHeightPx by remember { mutableStateOf(0 ) }
436+ val rightColumnHeightDp = rightColumnHeightPx / density.density
437+ val columnBottomPadding = ((BASE_HEIGHT - rightColumnHeightDp) / 2f ).coerceAtLeast(0f )
406438 Box (
407439 modifier = Modifier
408440 .align(Alignment .Center )
@@ -412,11 +444,22 @@ private fun MainMenu(
412444 scaleY = scale
413445 },
414446 ) {
415- CenterColumn (Modifier .align(Alignment .Center ), actions, assetsReady)
447+ CenterColumn (
448+ Modifier .align(Alignment .BottomCenter ).padding(bottom = columnBottomPadding.dp),
449+ actions,
450+ assetsReady,
451+ )
416452 if (! PolyPlusConfig .hideMainMenuQuickplay) {
417453 LeftColumn (Modifier .align(Alignment .CenterStart ).padding(start = 48 .dp), servers, pingTick, actions, assetsReady)
418454 }
419- RightColumn (Modifier .align(Alignment .CenterEnd ).padding(end = 48 .dp), assetsReady, screen)
455+ RightColumn (
456+ Modifier
457+ .align(Alignment .BottomEnd )
458+ .padding(end = 48 .dp, bottom = columnBottomPadding.dp)
459+ .onSizeChanged { rightColumnHeightPx = it.height },
460+ assetsReady,
461+ screen,
462+ )
420463 }
421464 WindowControls (
422465 Modifier .align(Alignment .TopEnd ).padding(16 .dp).guiScaled(scale, TransformOrigin (1f , 0f )),
@@ -513,7 +556,7 @@ private fun serverStatusText(server: net.minecraft.client.multiplayer.ServerData
513556private fun RightColumn (modifier : Modifier , assetsReady : Boolean , screen : net.minecraft.client.gui.screens.Screen ) {
514557 Column (
515558 modifier = modifier.width(300 .dp),
516- verticalArrangement = Arrangement .spacedBy(12 .dp),
559+ verticalArrangement = Arrangement .spacedBy(14 .dp),
517560 horizontalAlignment = Alignment .CenterHorizontally ,
518561 ) {
519562 if (! PolyPlusConfig .hideMainMenuPlayerPreview) {
@@ -626,7 +669,7 @@ private fun HintBubble(text: String) {
626669 .width(280 .dp)
627670 .clip(PanelShape )
628671 .background(PanelBackground )
629- .border(BorderWidth , PanelBorder , PanelShape )
672+ .border(BorderWidth , PanelBorderBrush , PanelShape )
630673 .padding(horizontal = 14 .dp, vertical = 10 .dp),
631674 contentAlignment = Alignment .Center ,
632675 ) {
@@ -712,7 +755,6 @@ private fun HostWorldPopup(
712755 modifier = Modifier .weight(1f ),
713756 assetsReady = assetsReady,
714757 onClick = onDismiss,
715- borderColor = LocalTheme .current.borderColor,
716758 )
717759 PillButton (
718760 label = " Host" ,
@@ -725,7 +767,6 @@ private fun HostWorldPopup(
725767 HostWorldManager .host(screen, chosen, gameMode, allowCheats)
726768 }
727769 },
728- borderColor = LocalTheme .current.borderColor,
729770 )
730771 }
731772 }
@@ -765,6 +806,7 @@ private fun WorldRow(
765806 }
766807}
767808
809+ @Composable
768810private fun compatColor (compat : HostWorldManager .Compat ): Color = when (compat) {
769811 HostWorldManager .Compat .CURRENT -> TextSecondary
770812 HostWorldManager .Compat .OLDER -> WarnColor
@@ -931,13 +973,15 @@ private fun Footer(modifier: Modifier, guiScale: Float, assetsReady: Boolean) {
931973@Composable
932974private fun FooterBrandText (platform : String , assetsReady : Boolean ) {
933975 val bodyFont = LocalTheme .current.typography.family
976+ val primary = TextPrimary
977+ val secondary = TextSecondary
934978
935979 BasicText (
936980 text = buildAnnotatedString {
937- withStyle(SpanStyle (color = TextPrimary , fontWeight = FontWeight .Bold , fontFamily = if (assetsReady) Outfit else FontFamily .Default )) {
981+ withStyle(SpanStyle (color = primary , fontWeight = FontWeight .Bold , fontFamily = if (assetsReady) Outfit else FontFamily .Default )) {
938982 append(" ONECLIENT" )
939983 }
940- withStyle(SpanStyle (color = TextSecondary , fontFamily = bodyFont)) {
984+ withStyle(SpanStyle (color = secondary , fontFamily = bodyFont)) {
941985 append(" " )
942986 append(platform)
943987 }
@@ -951,13 +995,13 @@ private fun FooterBrandText(platform: String, assetsReady: Boolean) {
951995}
952996
953997@Composable
954- private fun PillButton (label : String , icon : String , modifier : Modifier = Modifier , assetsReady : Boolean , onClick : () -> Unit = {}, borderColor : Color = PanelBorder ) {
998+ private fun PillButton (label : String , icon : String , modifier : Modifier = Modifier , assetsReady : Boolean , onClick : () -> Unit = {}, borderBrush : Brush = PanelBorderBrush ) {
955999 Row (
9561000 modifier = modifier
9571001 .height(45 .dp)
9581002 .clip(PanelShape )
9591003 .background(PanelBackground )
960- .border(BorderWidth , borderColor , PanelShape )
1004+ .border(BorderWidth , borderBrush , PanelShape )
9611005 .clickableWithSound(onClick)
9621006 .padding(horizontal = 18 .dp),
9631007 horizontalArrangement = Arrangement .spacedBy(12 .dp, Alignment .CenterHorizontally ),
@@ -976,7 +1020,7 @@ private fun DropdownPill(label: String, leadingIcon: String, expanded: Boolean,
9761020 .height(45 .dp)
9771021 .clip(PanelShape )
9781022 .background(PanelBackground )
979- .border(BorderWidth , PanelBorder , PanelShape )
1023+ .border(BorderWidth , PanelBorderBrush , PanelShape )
9801024 .clickableWithSound(onClick)
9811025 .padding(horizontal = 12 .dp),
9821026 contentAlignment = Alignment .Center ,
@@ -1008,7 +1052,7 @@ private fun ServerRow(
10081052 .height(64 .dp)
10091053 .clip(PanelShape )
10101054 .background(PanelBackground )
1011- .border(BorderWidth , PanelBorder , PanelShape )
1055+ .border(BorderWidth , PanelBorderBrush , PanelShape )
10121056 .clickableWithSound(onClick)
10131057 .padding(horizontal = 14 .dp),
10141058 verticalAlignment = Alignment .CenterVertically ,
@@ -1044,7 +1088,7 @@ private fun AccountPill(name: String, assetsReady: Boolean) {
10441088 .height(45 .dp)
10451089 .clip(PanelShape )
10461090 .background(PanelBackground )
1047- .border(BorderWidth , PanelBorder , PanelShape )
1091+ .border(BorderWidth , PanelBorderBrush , PanelShape )
10481092 .clickable {}
10491093 .padding(horizontal = 10 .dp),
10501094 contentAlignment = Alignment .Center ,
@@ -1074,7 +1118,7 @@ private fun IconButton(
10741118 .size(45 .dp)
10751119 .clip(PanelShape )
10761120 .background(background)
1077- .border(BorderWidth , PanelBorder , PanelShape )
1121+ .border(BorderWidth , PanelBorderBrush , PanelShape )
10781122 .clickableWithSound(onClick),
10791123 contentAlignment = Alignment .Center ,
10801124 ) {
0 commit comments