@@ -35,7 +35,14 @@ import androidx.compose.ui.Alignment
3535import androidx.compose.ui.Modifier
3636import androidx.compose.ui.draw.clip
3737import androidx.compose.ui.draw.shadow
38+ import androidx.compose.ui.geometry.Offset
39+ import androidx.compose.ui.geometry.Size
40+ import androidx.compose.ui.graphics.Brush
3841import androidx.compose.ui.graphics.Color
42+ import androidx.compose.ui.graphics.LinearGradientShader
43+ import androidx.compose.ui.graphics.Shader
44+ import androidx.compose.ui.graphics.ShaderBrush
45+ import androidx.compose.ui.graphics.SolidColor
3946import androidx.compose.ui.graphics.TransformOrigin
4047import androidx.compose.ui.graphics.graphicsLayer
4148import androidx.compose.ui.graphics.skiaCanvas
@@ -53,6 +60,7 @@ import org.jetbrains.skia.Image as SkiaImage
5360import org.polyfrost.oneconfig.internal.ui.components.Icon
5461import org.polyfrost.oneconfig.internal.ui.components.LocalUiOversample
5562import org.polyfrost.oneconfig.internal.ui.compose.ComposeScreen
63+ import org.polyfrost.oneconfig.internal.ui.themes.Accent
5664import org.polyfrost.oneconfig.internal.ui.themes.LocalTheme
5765import org.polyfrost.oneconfig.internal.ui.themes.Theme
5866import org.polyfrost.polyplus.client.PolyPlusConfig
@@ -177,8 +185,8 @@ class PolyPlusOnboardingScreen : ComposeScreen(RenderMode.CONTINUOUS) {
177185 spotColor = ShadowColor ,
178186 )
179187 .clip(PANEL_SHAPE )
180- .background(PanelBackground )
181- .border(1.3 .dp, PanelBorder , PANEL_SHAPE ),
188+ .background(PageBackground .copy(alpha = 0.9f ) )
189+ .border(BorderWidth , LocalTheme .current.borderColor , PANEL_SHAPE ),
182190 ) {
183191 when (pages[page]) {
184192 OnboardingPage .LOOK_AND_FEEL ->
@@ -340,10 +348,10 @@ private fun MotionBlurSection(y: Float, motionBlur: Int, onMotionBlur: (Int) ->
340348 .width(332 .dp)
341349 .height(7 .dp)
342350 .clip(RoundedCornerShape (4 .dp))
343- .background(Color ( 0x80273137 ) )
344- .border(1 .dp, PanelBorder , RoundedCornerShape (4 .dp)),
351+ .background(ChoiceBackground )
352+ .border(1 .dp, PanelBorderBrush , RoundedCornerShape (4 .dp)),
345353 ) {
346- Box (Modifier .fillMaxWidth(progress).height(7 .dp).background(Brand ))
354+ Box (Modifier .fillMaxWidth(progress).height(7 .dp).background(Accent ))
347355 }
348356 Box (
349357 Modifier
@@ -356,8 +364,8 @@ private fun MotionBlurSection(y: Float, motionBlur: Int, onMotionBlur: (Int) ->
356364 }
357365 Spacer (Modifier .width(18 .dp))
358366 Box (
359- Modifier .width(64 .dp).height(26 .dp).clip(RoundedCornerShape (6 .dp)).background(Color ( 0x80273137 ) )
360- .border(1 .dp, PanelBorder , RoundedCornerShape (6 .dp)),
367+ Modifier .width(64 .dp).height(26 .dp).clip(RoundedCornerShape (6 .dp)).background(ChoiceBackground )
368+ .border(1 .dp, PanelBorderBrush , RoundedCornerShape (6 .dp)),
361369 contentAlignment = Alignment .CenterStart ,
362370 ) { OnboardingText (motionBlur.toString(), 12 , Modifier .padding(start = 8 .dp)) }
363371 }
@@ -379,8 +387,8 @@ private fun CosmeticsPage(onClaim: () -> Unit, onStore: () -> Unit) {
379387 CosmeticCard (" Starter Cape" )
380388 CosmeticCard (" Starter Bag" )
381389 }
382- ChoiceButton (" Claim Free Cosmetics" , ONBOARDING_ASSETS + " diamond.svg" , true , 272f , Modifier .offset(304 .dp, 445 .dp), onClaim)
383- ChoiceButton (" Check Out the Store" , ONBOARDING_ASSETS + " shopping-bag.svg" , false , 272f , Modifier .offset(304 .dp, 493 .dp), onStore)
390+ ChoiceButton (" Claim Free Cosmetics" , ONBOARDING_ASSETS + " diamond.svg" , true , 272f , Modifier .offset(304 .dp, 445 .dp), onClick = onClaim)
391+ ChoiceButton (" Check Out the Store" , ONBOARDING_ASSETS + " shopping-bag.svg" , false , 272f , Modifier .offset(304 .dp, 493 .dp), onClick = onStore)
384392}
385393
386394@Composable
@@ -414,29 +422,38 @@ private fun ChoiceButton(
414422 selected : Boolean ,
415423 width : Float ,
416424 modifier : Modifier = Modifier ,
425+ primary : Boolean = false,
417426 onClick : () -> Unit ,
418427) {
428+ val contentColor = if (primary) Color .White else TextPrimary
419429 Row (
420430 modifier
421431 .width(width.dp)
422432 .height(32 .dp)
423433 .clip(ButtonShape )
424- .background(ChoiceBackground )
425- .border(if (selected) 2 .dp else 1 .dp, if (selected) Brand else PanelBorder , ButtonShape )
434+ .background(
435+ when {
436+ primary -> Accent
437+ selected -> Accent .asSelectedBackground
438+ else -> ChoiceBackground
439+ },
440+ )
441+ .border(BorderWidth , if (selected || primary) SolidColor (Accent ) else PanelBorderBrush , ButtonShape )
426442 .clickableWithSound(onClick),
427443 horizontalArrangement = Arrangement .spacedBy(10 .dp, Alignment .CenterHorizontally ),
428444 verticalAlignment = Alignment .CenterVertically ,
429445 ) {
430- OnboardingIcon (icon, TextPrimary , Modifier .size(17 .dp))
431- OnboardingText (label, 14 , color = TextPrimary , weight = FontWeight .Medium )
446+ OnboardingIcon (icon, contentColor , Modifier .size(17 .dp))
447+ OnboardingText (label, 14 , color = contentColor , weight = FontWeight .Medium )
432448 }
433449}
434450
435451@Composable
436452private fun StyleCard (label : String , selected : Boolean , rounded : Boolean , onClick : () -> Unit ) {
437453 Box (
438- Modifier .size(198 .dp, 155 .dp).clip(ButtonShape ).background(ChoiceBackground )
439- .border(if (selected) 2 .dp else 1 .dp, if (selected) Brand else PanelBorder , ButtonShape )
454+ Modifier .size(198 .dp, 155 .dp).clip(ButtonShape )
455+ .background(if (selected) Accent .asSelectedBackground else ChoiceBackground )
456+ .border(BorderWidth , if (selected) SolidColor (Accent ) else PanelBorderBrush , ButtonShape )
440457 .clickableWithSound(onClick),
441458 ) {
442459 UiPreview (Modifier .offset(13 .dp, 12 .dp), rounded)
@@ -449,15 +466,15 @@ private fun UiPreview(modifier: Modifier, rounded: Boolean) {
449466 val shape = if (rounded) RoundedCornerShape (8 .dp) else RoundedCornerShape (0 .dp)
450467 Row (modifier.size(172 .dp, 108 .dp).clip(shape).border(1 .dp, Color (0x1AFFFFFF ), shape)) {
451468 Column (Modifier .width(44 .dp).height(108 .dp).background(Color (0xB3151C22 )).padding(8 .dp, 7 .dp), verticalArrangement = Arrangement .spacedBy(5 .dp)) {
452- Box (Modifier .size(29 .dp, 7 .dp).background(Brand ))
469+ Box (Modifier .size(29 .dp, 7 .dp).background(Accent ))
453470 repeat(3 ) { Box (Modifier .width(if (it == 0 ) 20 .dp else 29 .dp).height(4 .dp).background(if (it == 0 ) TextSecondary else TextPrimary )) }
454471 }
455472 Column (Modifier .width(128 .dp).height(108 .dp).background(Color (0xF211171C )).padding(8 .dp, 7 .dp)) {
456473 Row { Box (Modifier .width(43 .dp).height(7 .dp).background(TextPrimary )); Spacer (Modifier .width(61 .dp)); Box (Modifier .size(7 .dp).background(TextPrimary )) }
457474 Spacer (Modifier .height(8 .dp))
458475 repeat(3 ) {
459476 Row (horizontalArrangement = Arrangement .spacedBy(5 .dp)) {
460- repeat(3 ) { Box (Modifier .size(34 .dp, 23 .dp).background(Color (0xFF1A2229 )).border(0 .dp, Color .Transparent ).padding(top = 17 .dp).background(Brand )) }
477+ repeat(3 ) { Box (Modifier .size(34 .dp, 23 .dp).background(Color (0xFF1A2229 )).border(0 .dp, Color .Transparent ).padding(top = 17 .dp).background(Accent )) }
461478 }
462479 Spacer (Modifier .height(5 .dp))
463480 }
@@ -468,8 +485,9 @@ private fun UiPreview(modifier: Modifier, rounded: Boolean) {
468485@Composable
469486private fun HudCard (label : String , selected : Boolean , rounded : Boolean , onClick : () -> Unit ) {
470487 Box (
471- Modifier .size(198 .dp, 94 .dp).clip(ButtonShape ).background(ChoiceBackground )
472- .border(if (selected) 2 .dp else 1 .dp, if (selected) Brand else PanelBorder , ButtonShape )
488+ Modifier .size(198 .dp, 94 .dp).clip(ButtonShape )
489+ .background(if (selected) Accent .asSelectedBackground else ChoiceBackground )
490+ .border(BorderWidth , if (selected) SolidColor (Accent ) else PanelBorderBrush , ButtonShape )
473491 .clickableWithSound(onClick),
474492 ) {
475493 Box (
@@ -484,7 +502,7 @@ private fun HudCard(label: String, selected: Boolean, rounded: Boolean, onClick:
484502
485503@Composable
486504private fun CosmeticCard (label : String ) {
487- Box (Modifier .size(180 .dp, 202 .dp).clip(RoundedCornerShape (10 .dp)).background(ChoiceBackground ).border(1 .dp, Color ( 0x66FFFFFF ) , RoundedCornerShape (10 .dp))) {
505+ Box (Modifier .size(180 .dp, 202 .dp).clip(RoundedCornerShape (10 .dp)).background(ChoiceBackground ).border(BorderWidth , PanelBorderBrush , RoundedCornerShape (10 .dp))) {
488506 Checkerboard (Modifier .offset(17 .dp, 18 .dp).size(146 .dp, 146 .dp).clip(RoundedCornerShape (4 .dp)))
489507 OnboardingText (label, 14 , Modifier .align(Alignment .BottomCenter ).padding(bottom = 13 .dp), TextPrimary , FontWeight .Medium )
490508 }
@@ -513,11 +531,11 @@ private fun Checkerboard(modifier: Modifier) {
513531@Composable
514532private fun BottomNavigation (page : Int , pageCount : Int , onSkip : () -> Unit , onBack : () -> Unit , onNext : () -> Unit ) {
515533 if (page == 0 ) {
516- ChoiceButton (" Skip" , MAIN_MENU_ASSETS + " x-close.svg" , false , 100f , Modifier .offset(26 .dp, 604 .dp), onSkip)
534+ ChoiceButton (" Skip" , MAIN_MENU_ASSETS + " x-close.svg" , false , 100f , Modifier .offset(26 .dp, 604 .dp), onClick = onSkip)
517535 } else {
518- ChoiceButton (" Back" , " assets/polyplus/ico/left-arrow.svg" , false , 100f , Modifier .offset(26 .dp, 604 .dp), onBack)
536+ ChoiceButton (" Back" , " assets/polyplus/ico/left-arrow.svg" , false , 100f , Modifier .offset(26 .dp, 604 .dp), onClick = onBack)
519537 }
520- ChoiceButton (if (page == pageCount - 1 ) " Finish" else " Next" , MAIN_MENU_ASSETS + " chevron- right.svg" , true , 100f , Modifier .offset(754 .dp, 604 .dp), onNext)
538+ 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)
521539 Row (Modifier .offset(((PANEL_WIDTH - (pageCount * 17f - 5f )) / 2f ).dp, 614 .dp), horizontalArrangement = Arrangement .spacedBy(5 .dp), verticalAlignment = Alignment .CenterVertically ) {
522540 repeat(pageCount) { index ->
523541 Box (
@@ -555,7 +573,7 @@ private fun MotionBlurPreview(strength: Int, modifier: Modifier = Modifier) {
555573 modifier
556574 .clip(shape)
557575 .background(Color (0xFF273137 ))
558- .border(1 .dp, Color . White , shape),
576+ .border(1 .dp, PanelBorderBrush , shape),
559577 ) {
560578 if (image != null ) {
561579 Canvas (Modifier .fillMaxSize()) {
@@ -622,12 +640,38 @@ private const val BLUR_PREVIEW_HEIGHT = 115f
622640private const val BLUR_SECTION_HEIGHT = BLUR_PREVIEW_OFFSET + BLUR_PREVIEW_HEIGHT
623641private const val ONBOARDING_ASSETS = " assets/polyplus/onboarding/"
624642private const val MAIN_MENU_ASSETS = " assets/polyplus/mainmenu/"
625- private val PANEL_SHAPE = RoundedCornerShape (10.345 .dp)
626- private val ButtonShape = RoundedCornerShape (6 .dp)
627- private val PanelBackground = Color (0x73232D32 )
628- private val PanelBorder = Color (0x66FFFFFF )
643+
644+ private val PANEL_SHAPE = RoundedCornerShape (9 .dp)
645+ private val ButtonShape = RoundedCornerShape (9 .dp)
646+ private val BorderWidth = 1.5 .dp
647+ private const val PanelBorderAngleDeg = 20.0
648+
649+ private val PageBackground = Color (0xFF11171C )
629650private val ShadowColor = Color (0x26000000 )
630- private val ChoiceBackground = Color (0x80273137 )
631- private val Brand = Color (0xFF3F7CE4 )
632- private val TextPrimary = Color (0xFFD5DBFF )
633- private val TextSecondary = Color (0xFF78818D )
651+
652+ private val ChoiceBackground : Color
653+ @Composable get() = LocalTheme .current.componentBackground.copy(alpha = 0.5f )
654+ private val TextPrimary : Color
655+ @Composable get() = LocalTheme .current.textColor
656+ private val TextSecondary : Color
657+ @Composable get() = LocalTheme .current.textColorSecondary
658+ private val Color .asSelectedBackground: Color get() = copy(alpha = 0.22f )
659+
660+ private val PanelBorderBrush : Brush = object : ShaderBrush () {
661+ override fun createShader (size : Size ): Shader {
662+ val radians = Math .toRadians(PanelBorderAngleDeg )
663+ val ux = kotlin.math.cos(radians).toFloat()
664+ val uy = kotlin.math.sin(radians).toFloat()
665+ val len = size.width * ux + size.height * uy
666+ return LinearGradientShader (
667+ from = Offset .Zero ,
668+ to = Offset (ux * len, uy * len),
669+ colors = listOf (
670+ Color .White .copy(alpha = 0.5f ),
671+ Color .White .copy(alpha = 0.15f ),
672+ Color .White .copy(alpha = 0.5f ),
673+ ),
674+ colorStops = listOf (0f , 0.5f , 1f ),
675+ )
676+ }
677+ }
0 commit comments