@@ -104,6 +104,14 @@ class PolyPlusOnboardingScreen : ComposeScreen(RenderMode.CONTINUOUS) {
104104
105105 @Composable
106106 override fun compose () {
107+ val pages = remember {
108+ buildList {
109+ add(OnboardingPage .LOOK_AND_FEEL )
110+ if (OnboardingFeatures .modsPageAvailable) add(OnboardingPage .MODS )
111+ add(OnboardingPage .COSMETICS )
112+ add(OnboardingPage .DONE )
113+ }
114+ }
107115 var page by remember { mutableIntStateOf(0 ) }
108116 var lightTheme by remember { mutableStateOf(PolyPlusConfig .onboardingLightTheme) }
109117 var uiStyle by remember { mutableIntStateOf(PolyPlusConfig .onboardingUiStyle) }
@@ -173,30 +181,32 @@ class PolyPlusOnboardingScreen : ComposeScreen(RenderMode.CONTINUOUS) {
173181 .background(PanelBackground )
174182 .border(1.3 .dp, PanelBorder , PANEL_SHAPE ),
175183 ) {
176- when (page) {
177- 0 -> LookAndFeelPage (lightTheme, { lightTheme = it }, uiStyle, { uiStyle = it }, hudStyle, { hudStyle = it })
178- 1 -> ModsPage (
184+ when (pages[page]) {
185+ OnboardingPage .LOOK_AND_FEEL ->
186+ LookAndFeelPage (lightTheme, { lightTheme = it }, uiStyle, { uiStyle = it }, hudStyle, { hudStyle = it })
187+ OnboardingPage .MODS -> ModsPage (
179188 toggleSprint,
180189 { toggleSprint = it },
181190 hudSelections,
182191 { hudSelections = it },
183192 motionBlur,
184193 { motionBlur = it },
185194 )
186- 2 -> CosmeticsPage (
195+ OnboardingPage . COSMETICS -> CosmeticsPage (
187196 onClaim = { PolyPlusClient .refreshCosmetics() },
188197 onStore = {
189198 finish()
190199 PolyPlusOneConfigIntegration .openCosmetics()
191200 },
192201 )
193- else -> DonePage ()
202+ OnboardingPage . DONE -> DonePage ()
194203 }
195204 BottomNavigation (
196205 page,
206+ pages.size,
197207 onSkip = finish,
198208 onBack = { page-- },
199- onNext = { if (page == PAGE_COUNT - 1 ) finish() else page++ },
209+ onNext = { if (page == pages.size - 1 ) finish() else page++ },
200210 )
201211 }
202212 }
@@ -243,13 +253,40 @@ private fun ModsPage(
243253 onMotionBlur : (Int ) -> Unit ,
244254) {
245255 Header (" Continuing with" , " Mods" )
246- SectionLabel (" Toggle Sprint" , 140f )
247- Row (Modifier .offset(232 .dp, 172 .dp), horizontalArrangement = Arrangement .spacedBy(18 .dp)) {
256+ val sprint = OnboardingFeatures .polySprintAvailable
257+ val huds = OnboardingFeatures .evergreenAvailable
258+ val blur = OnboardingFeatures .polyBlurAvailable
259+ val heights = buildList {
260+ if (sprint) add(SPRINT_SECTION_HEIGHT )
261+ if (huds) add(HUD_SECTION_HEIGHT )
262+ if (blur) add(BLUR_SECTION_HEIGHT )
263+ }
264+ val total = heights.sum() + SECTION_GAP * (heights.size - 1 ).coerceAtLeast(0 )
265+ var y = CONTENT_TOP + ((CONTENT_BOTTOM - CONTENT_TOP ) - total) / 2f
266+ if (sprint) {
267+ SprintSection (y, toggleSprint, onToggleSprint)
268+ y + = SPRINT_SECTION_HEIGHT + SECTION_GAP
269+ }
270+ if (huds) {
271+ HudSection (y, hud, onHudChange)
272+ y + = HUD_SECTION_HEIGHT + SECTION_GAP
273+ }
274+ if (blur) MotionBlurSection (y, motionBlur, onMotionBlur)
275+ }
276+
277+ @Composable
278+ private fun SprintSection (y : Float , toggleSprint : Boolean , onToggleSprint : (Boolean ) -> Unit ) {
279+ SectionLabel (" Toggle Sprint" , y)
280+ Row (Modifier .offset(232 .dp, (y + LABEL_HEIGHT ).dp), horizontalArrangement = Arrangement .spacedBy(18 .dp)) {
248281 ChoiceButton (" Enabled" , ONBOARDING_ASSETS + " zap.svg" , toggleSprint, 198f ) { onToggleSprint(true ) }
249282 ChoiceButton (" Disabled" , ONBOARDING_ASSETS + " flash-off.svg" , ! toggleSprint, 198f ) { onToggleSprint(false ) }
250283 }
251- SectionLabel (" HUD Mods" , 228f )
252- Column (Modifier .offset(232 .dp, 260 .dp), verticalArrangement = Arrangement .spacedBy(18 .dp)) {
284+ }
285+
286+ @Composable
287+ private fun HudSection (y : Float , hud : HudSelections , onHudChange : (HudSelections ) -> Unit ) {
288+ SectionLabel (" HUD Mods" , y)
289+ Column (Modifier .offset(232 .dp, (y + LABEL_HEIGHT ).dp), verticalArrangement = Arrangement .spacedBy(18 .dp)) {
253290 Row (horizontalArrangement = Arrangement .spacedBy(18 .dp)) {
254291 ChoiceButton (" FPS" , ONBOARDING_ASSETS + " play-square.svg" , hud.fps, 126f ) { onHudChange(hud.copy(fps = ! hud.fps)) }
255292 ChoiceButton (" CPS" , ONBOARDING_ASSETS + " mouse.svg" , hud.cps, 126f ) { onHudChange(hud.copy(cps = ! hud.cps)) }
@@ -261,8 +298,12 @@ private fun ModsPage(
261298 ChoiceButton (" Direction" , ONBOARDING_ASSETS + " compass.svg" , hud.direction, 126f ) { onHudChange(hud.copy(direction = ! hud.direction)) }
262299 }
263300 }
264- SectionLabel (" Motion Blur" , 367f )
265- Row (Modifier .offset(232 .dp, 399 .dp), verticalAlignment = Alignment .CenterVertically ) {
301+ }
302+
303+ @Composable
304+ private fun MotionBlurSection (y : Float , motionBlur : Int , onMotionBlur : (Int ) -> Unit ) {
305+ SectionLabel (" Motion Blur" , y)
306+ Row (Modifier .offset(232 .dp, (y + LABEL_HEIGHT ).dp), verticalAlignment = Alignment .CenterVertically ) {
266307 val thumbSize = 13 .dp
267308 var trackWidthPx by remember { mutableStateOf(0f ) }
268309 val progress by animateFloatAsState(
@@ -321,7 +362,7 @@ private fun ModsPage(
321362 contentAlignment = Alignment .CenterStart ,
322363 ) { OnboardingText (motionBlur.toString(), 12 , Modifier .padding(start = 8 .dp)) }
323364 }
324- MotionBlurPreview (motionBlur, Modifier .offset(233.5 .dp, 442 .dp).size(413 .dp, 115 .dp))
365+ MotionBlurPreview (motionBlur, Modifier .offset(233.5 .dp, (y + BLUR_PREVIEW_OFFSET ) .dp).size(413 .dp, BLUR_PREVIEW_HEIGHT .dp))
325366}
326367
327368@Composable
@@ -471,15 +512,15 @@ private fun Checkerboard(modifier: Modifier) {
471512}
472513
473514@Composable
474- private fun BottomNavigation (page : Int , onSkip : () -> Unit , onBack : () -> Unit , onNext : () -> Unit ) {
515+ private fun BottomNavigation (page : Int , pageCount : Int , onSkip : () -> Unit , onBack : () -> Unit , onNext : () -> Unit ) {
475516 if (page == 0 ) {
476517 ChoiceButton (" Skip" , MAIN_MENU_ASSETS + " x-close.svg" , false , 100f , Modifier .offset(26 .dp, 604 .dp), onSkip)
477518 } else {
478519 ChoiceButton (" Back" , " assets/polyplus/ico/left-arrow.svg" , false , 100f , Modifier .offset(26 .dp, 604 .dp), onBack)
479520 }
480- ChoiceButton (if (page == PAGE_COUNT - 1 ) " Finish" else " Next" , MAIN_MENU_ASSETS + " chevron-right.svg" , true , 100f , Modifier .offset(754 .dp, 604 .dp), onNext)
481- Row (Modifier .offset(((PANEL_WIDTH - (PAGE_COUNT * 17f - 5f )) / 2f ).dp, 614 .dp), horizontalArrangement = Arrangement .spacedBy(5 .dp), verticalAlignment = Alignment .CenterVertically ) {
482- repeat(PAGE_COUNT ) { index ->
521+ ChoiceButton (if (page == pageCount - 1 ) " Finish" else " Next" , MAIN_MENU_ASSETS + " chevron-right.svg" , true , 100f , Modifier .offset(754 .dp, 604 .dp), onNext)
522+ Row (Modifier .offset(((PANEL_WIDTH - (pageCount * 17f - 5f )) / 2f ).dp, 614 .dp), horizontalArrangement = Arrangement .spacedBy(5 .dp), verticalAlignment = Alignment .CenterVertically ) {
523+ repeat(pageCount ) { index ->
483524 Box (
484525 Modifier .size(if (index == page) 12 .dp else 10 .dp)
485526 .clip(RoundedCornerShape (8 .dp))
@@ -552,6 +593,8 @@ private fun loadOnboardingImage(path: String): SkiaImage? = runCatching {
552593 SkiaImage .makeFromEncoded(bytes)
553594}.getOrNull()
554595
596+ private enum class OnboardingPage { LOOK_AND_FEEL , MODS , COSMETICS , DONE }
597+
555598private data class HudSelections (
556599 val fps : Boolean ,
557600 val cps : Boolean ,
@@ -567,8 +610,17 @@ private const val PANEL_X = 520f
567610private const val PANEL_Y = 210f
568611private const val PANEL_WIDTH = 880f
569612private const val PANEL_HEIGHT = 660f
570- private const val PAGE_COUNT = 4
571613private const val MOTION_BLUR_MAX = 10
614+
615+ private const val CONTENT_TOP = 140f
616+ private const val CONTENT_BOTTOM = 557f
617+ private const val SECTION_GAP = 24f
618+ private const val LABEL_HEIGHT = 32f
619+ private const val SPRINT_SECTION_HEIGHT = LABEL_HEIGHT + 32f
620+ private const val HUD_SECTION_HEIGHT = LABEL_HEIGHT + 82f
621+ private const val BLUR_PREVIEW_OFFSET = 75f
622+ private const val BLUR_PREVIEW_HEIGHT = 115f
623+ private const val BLUR_SECTION_HEIGHT = BLUR_PREVIEW_OFFSET + BLUR_PREVIEW_HEIGHT
572624private const val ONBOARDING_ASSETS = " assets/polyplus/onboarding/"
573625private const val MAIN_MENU_ASSETS = " assets/polyplus/mainmenu/"
574626private val PANEL_SHAPE = RoundedCornerShape (10.345 .dp)
0 commit comments