1717package com.madness.collision.settings
1818
1919import android.content.Context
20+ import androidx.activity.ComponentActivity
21+ import androidx.activity.compose.LocalActivity
2022import androidx.compose.animation.animateColorAsState
2123import androidx.compose.foundation.*
2224import androidx.compose.foundation.layout.*
2325import androidx.compose.foundation.shape.CircleShape
2426import androidx.compose.material3.*
27+ import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
2528import androidx.compose.runtime.*
29+ import androidx.compose.runtime.saveable.rememberSaveable
2630import androidx.compose.ui.Alignment
2731import androidx.compose.ui.Modifier
2832import androidx.compose.ui.draw.clip
2933import androidx.compose.ui.graphics.Color
3034import androidx.compose.ui.platform.LocalContext
3135import androidx.compose.ui.res.painterResource
3236import androidx.compose.ui.res.stringResource
37+ import androidx.compose.ui.unit.Dp
38+ import androidx.compose.ui.unit.coerceAtMost
3339import androidx.compose.ui.unit.dp
3440import androidx.compose.ui.unit.sp
41+ import androidx.core.os.bundleOf
42+ import androidx.fragment.compose.AndroidFragment
43+ import androidx.lifecycle.viewmodel.compose.viewModel
44+ import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND
3545import com.madness.collision.R
3646import com.madness.collision.settings.instant.InstantFragment
3747import com.madness.collision.main.DevOptions
3848import com.madness.collision.main.MainViewModel
3949import com.madness.collision.main.showPage
4050import com.madness.collision.pref.PrefExterior
41- import com.madness.collision.settings.unitmgr.UnitsManagerFragment
4251import com.madness.collision.unit.DescRetriever
52+ import com.madness.collision.unit.Unit as ModUnit
4353import com.madness.collision.util.Page
4454import com.madness.collision.util.dev.DarkPreview
4555import com.madness.collision.util.dev.LayoutDirectionPreviews
@@ -50,38 +60,120 @@ fun SettingsPage(
5060 mainViewModel : MainViewModel ,
5161 paddingValues : PaddingValues ,
5262 showLanguages : () -> Unit ,
63+ ) {
64+ val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
65+ if (windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_MEDIUM_LOWER_BOUND )) {
66+ BoxWithConstraints {
67+ val navWidth = (maxWidth / 3 ).coerceAtMost(240 .dp)
68+ SideBySideLayout (navPaneWidth = navWidth, showLanguages = showLanguages, contentPadding = paddingValues)
69+ }
70+ } else {
71+ SinglePaneLayout (showLanguages = showLanguages, contentPadding = paddingValues)
72+ }
73+ }
74+
75+ private enum class NavDest {
76+ Styles , Languages , About , Instant , ApiUnit
77+ }
78+
79+ @Composable
80+ private fun SinglePaneLayout (
81+ showLanguages : () -> Unit ,
82+ contentPadding : PaddingValues = PaddingValues .Zero ,
83+ ) {
84+ val context = LocalContext .current
85+ val activity = LocalActivity .current as ? ComponentActivity
86+ SettingsNavPanel (
87+ mainViewModel = viewModel(activity!! ),
88+ paddingValues = contentPadding,
89+ onSelectDest = { dest ->
90+ when (dest) {
91+ NavDest .Styles ->
92+ context.showPage<Page > {
93+ putString(" fragmentClass" , PrefExterior ::class .qualifiedName)
94+ putInt(" titleId" , R .string.settings_exterior)
95+ }
96+ NavDest .Languages -> showLanguages()
97+ NavDest .About -> context.showPage<AdviceFragment >()
98+ NavDest .Instant -> context.showPage<InstantFragment >()
99+ NavDest .ApiUnit ->
100+ ModUnit .getBridge(ModUnit .UNIT_NAME_API_VIEWING )
101+ ?.getSettings()?.let (context::showPage)
102+ }
103+ },
104+ )
105+ }
106+
107+ @Composable
108+ private fun SideBySideLayout (
109+ navPaneWidth : Dp ,
110+ showLanguages : () -> Unit ,
111+ modifier : Modifier = Modifier ,
112+ contentPadding : PaddingValues = PaddingValues .Zero ,
113+ ) {
114+ val (navDest, setNavDest) = rememberSaveable {
115+ mutableStateOf<NavDest ?>(null )
116+ }
117+ Row (modifier = modifier) {
118+ Box (
119+ modifier = Modifier
120+ .width(navPaneWidth)
121+ .padding(contentPadding)
122+ ) {
123+ val activity = LocalActivity .current as ? ComponentActivity
124+ SettingsNavPanel (mainViewModel = viewModel(activity!! ), onSelectDest = setNavDest)
125+ }
126+
127+ VerticalDivider (thickness = 0.5 .dp)
128+
129+ var lastDest by rememberSaveable { mutableStateOf<NavDest ?>(null ) }
130+ LaunchedEffect (navDest) { if (navDest != NavDest .Languages ) lastDest = navDest }
131+ if (navDest == NavDest .Languages ) LaunchedEffect (Unit ) { showLanguages() }
132+
133+ when (lastDest) {
134+ NavDest .Styles -> {
135+ val n = PrefExterior ::class .qualifiedName
136+ val args = bundleOf(" fragmentClass" to n, " titleId" to R .string.settings_exterior)
137+ AndroidFragment <Page >(arguments = args)
138+ }
139+ NavDest .Languages -> Unit
140+ NavDest .About -> AndroidFragment <AdviceFragment >()
141+ NavDest .Instant -> AndroidFragment <InstantFragment >()
142+ NavDest .ApiUnit -> {
143+ val n = " com.madness.collision.unit.api_viewing.PrefAv"
144+ val args = bundleOf(" fragmentClass" to n, " titleId" to R .string.apiViewer)
145+ AndroidFragment <Page >(arguments = args)
146+ }
147+ null -> Unit
148+ }
149+ }
150+ }
151+
152+ @Composable
153+ private fun SettingsNavPanel (
154+ mainViewModel : MainViewModel ,
155+ onSelectDest : (NavDest ) -> Unit ,
156+ paddingValues : PaddingValues = PaddingValues .Zero ,
53157) {
54158 val context = LocalContext .current
55159 val options = remember {
56160 val builtIn = listOf (
57161 Triple (R .string.settings_exterior, R .drawable.ic_palette_24) {
58- context.showPage<Page > {
59- putString(" fragmentClass" , PrefExterior ::class .qualifiedName)
60- putInt(" titleId" , R .string.settings_exterior)
61- }
162+ onSelectDest(NavDest .Styles )
62163 },
63164 Triple (R .string.Settings_Button_SwitchLanguage , R .drawable.ic_language_24) {
64- showLanguages( )
165+ onSelectDest( NavDest . Languages )
65166 },
66167 Triple (R .string.Main_TextView_Advice_Text , R .drawable.ic_info_24) {
67- context.showPage<AdviceFragment >()
68- },
69- Triple (R .string.unitsManager, R .drawable.ic_extension_24) {
70- context.showPage<UnitsManagerFragment >()
168+ onSelectDest(NavDest .About )
71169 },
72170 Triple (R .string.Main_TextView_Launcher , R .drawable.ic_flash_24) {
73- context.showPage< InstantFragment >( )
171+ onSelectDest( NavDest . Instant )
74172 },
75173 )
76- val specialOptions = buildList {
77- if (android.os.Build .VERSION .SDK_INT >= android.os.Build .VERSION_CODES .R ) {
78- add(Triple (R .string.app_device_controls, R .drawable.ic_devices_24) {
79- context.showPage<DeviceControlsFragment >()
80- })
81- }
82- }
83174 val unitOptions = getUnitOptions(mainViewModel, context)
84- builtIn + specialOptions + unitOptions
175+ .map { (l, i, _) -> Triple (l, i) { onSelectDest(NavDest .ApiUnit ) } }
176+ builtIn + unitOptions
85177 }
86178 Settings (options = options, paddingValues = paddingValues)
87179}
@@ -193,7 +285,6 @@ private fun SettingsPreview() {
193285 Triple (R .string.settings_exterior, R .drawable.ic_palette_24) { },
194286 Triple (R .string.Settings_Button_SwitchLanguage , R .drawable.ic_language_24) { },
195287 Triple (R .string.Main_TextView_Advice_Text , R .drawable.ic_info_24) { },
196- Triple (R .string.unitsManager, R .drawable.ic_extension_24) { },
197288 Triple (R .string.Main_TextView_Launcher , R .drawable.ic_flash_24) { },
198289 Triple (R .string.apiViewer, R .drawable.ic_android_24) { },
199290 )
0 commit comments