Merge "Add PageModel framework, and use it in ArgumentPageModel."
This commit is contained in:
@@ -49,16 +49,8 @@ object SpaEnvironment {
|
||||
IllustrationPageProvider,
|
||||
),
|
||||
rootPageData = listOf(
|
||||
SettingsPage(HomePageProvider.name),
|
||||
SettingsPage(
|
||||
ArgumentPageProvider.name,
|
||||
ArgumentPageProvider.buildArgument("foo")
|
||||
),
|
||||
SettingsPage(
|
||||
ArgumentPageProvider.name,
|
||||
ArgumentPageProvider.buildArgument("bar")
|
||||
),
|
||||
)
|
||||
SettingsPage(HomePageProvider.name)
|
||||
) + ArgumentPageProvider.buildRootPages()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,64 +19,47 @@ package com.android.settingslib.spa.gallery.page
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.navigation.NamedNavArgument
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPage
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.compose.toState
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.framework.util.getIntArg
|
||||
import com.android.settingslib.spa.framework.util.getStringArg
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.framework.util.normalize
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
private const val TITLE = "Sample page with arguments"
|
||||
private const val STRING_PARAM_NAME = "stringParam"
|
||||
private const val INT_PARAM_NAME = "intParam"
|
||||
|
||||
object ArgumentPageProvider : SettingsPageProvider {
|
||||
override val name = "Argument"
|
||||
override val name = ArgumentPageModel.name
|
||||
|
||||
override val parameter = listOf(
|
||||
navArgument(STRING_PARAM_NAME) { type = NavType.StringType },
|
||||
navArgument(INT_PARAM_NAME) { type = NavType.IntType },
|
||||
)
|
||||
override val parameter = ArgumentPageModel.parameter
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
if (!parameter.isValid(arguments)) return emptyList()
|
||||
if (!ArgumentPageModel.isValidArgument(arguments)) return emptyList()
|
||||
|
||||
val owner = SettingsPage(name, parameter.normalize(arguments))
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
val stringParamEntry = SettingsEntryBuilder.create("string_param", owner)
|
||||
stringParamEntry.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "String param value"
|
||||
override val summary =
|
||||
parameter.getStringArg(STRING_PARAM_NAME, arguments)!!.toState()
|
||||
})
|
||||
}
|
||||
entryList.add(stringParamEntry.build())
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("string_param", owner)
|
||||
// Set attributes
|
||||
.setIsAllowSearch(true)
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(arguments).genStringParamPreferenceModel())
|
||||
}.build()
|
||||
)
|
||||
|
||||
val intParamEntry = SettingsEntryBuilder.create("int_param", owner)
|
||||
intParamEntry.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Int param value"
|
||||
override val summary =
|
||||
parameter.getIntArg(INT_PARAM_NAME, arguments)!!.toString().toState()
|
||||
})
|
||||
}
|
||||
entryList.add(intParamEntry.build())
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("int_param", owner)
|
||||
// Set attributes
|
||||
.setIsAllowSearch(true)
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(arguments).genIntParamPreferenceModel())
|
||||
}.build()
|
||||
)
|
||||
|
||||
val intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
|
||||
val entryFoo = buildInjectEntry(buildNextArgument("foo", intParam))
|
||||
val entryBar = buildInjectEntry(buildNextArgument("bar", intParam))
|
||||
val entryFoo = buildInjectEntry(ArgumentPageModel.buildNextArgument("foo", arguments))
|
||||
val entryBar = buildInjectEntry(ArgumentPageModel.buildNextArgument("bar", arguments))
|
||||
if (entryFoo != null) entryList.add(entryFoo.setLink(fromPage = owner).build())
|
||||
if (entryBar != null) entryList.add(entryBar.setLink(fromPage = owner).build())
|
||||
|
||||
@@ -84,30 +67,33 @@ object ArgumentPageProvider : SettingsPageProvider {
|
||||
}
|
||||
|
||||
private fun buildInjectEntry(arguments: Bundle?): SettingsEntryBuilder? {
|
||||
if (!parameter.isValid(arguments)) return null
|
||||
if (!ArgumentPageModel.isValidArgument(arguments)) return null
|
||||
|
||||
val seBuilder =
|
||||
SettingsEntryBuilder.createInject(name, parameter.normalize(arguments))
|
||||
seBuilder.setIsAllowSearch(false)
|
||||
return SettingsEntryBuilder.createInject(name, parameter.normalize(arguments))
|
||||
// Set attributes
|
||||
.setIsAllowSearch(false)
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(arguments).genInjectPreferenceModel())
|
||||
}
|
||||
}
|
||||
|
||||
seBuilder.setUiLayoutFn {
|
||||
val summaryArray = listOf(
|
||||
"$STRING_PARAM_NAME=" + parameter.getStringArg(STRING_PARAM_NAME, arguments)!!,
|
||||
"$INT_PARAM_NAME=" + parameter.getIntArg(INT_PARAM_NAME, arguments)!!
|
||||
)
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val summary = summaryArray.joinToString(", ").toState()
|
||||
override val onClick = navigator(name + parameter.navLink(arguments))
|
||||
})
|
||||
}
|
||||
|
||||
return seBuilder
|
||||
fun buildRootPages(): List<SettingsPage> {
|
||||
return listOf(
|
||||
SettingsPage(
|
||||
ArgumentPageModel.name,
|
||||
ArgumentPageModel.buildArgument("foo")
|
||||
),
|
||||
SettingsPage(
|
||||
ArgumentPageModel.name,
|
||||
ArgumentPageModel.buildArgument("bar")
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = TITLE) {
|
||||
RegularScaffold(title = ArgumentPageModel.create(arguments).genPageTitle()) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.uiLayout()
|
||||
}
|
||||
@@ -116,21 +102,8 @@ object ArgumentPageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
fun EntryItem(stringParam: String, intParam: Int) {
|
||||
buildInjectEntry(buildArgument(stringParam, intParam))?.build()?.uiLayout?.let { it() }
|
||||
}
|
||||
|
||||
fun buildArgument(stringParam: String, intParam: Int? = null): Bundle {
|
||||
val args = Bundle()
|
||||
args.putString(STRING_PARAM_NAME, stringParam)
|
||||
if (intParam != null) args.putInt(INT_PARAM_NAME, intParam)
|
||||
return args
|
||||
}
|
||||
|
||||
private fun buildNextArgument(stringParam: String, intParam: Int? = null): Bundle {
|
||||
return if (intParam == null)
|
||||
buildArgument(stringParam)
|
||||
else
|
||||
buildArgument(stringParam, intParam + 1)
|
||||
buildInjectEntry(ArgumentPageModel.buildArgument(stringParam, intParam))
|
||||
?.build()?.uiLayout?.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,12 +112,7 @@ object ArgumentPageProvider : SettingsPageProvider {
|
||||
private fun ArgumentPagePreview() {
|
||||
SettingsTheme {
|
||||
ArgumentPageProvider.Page(
|
||||
ArgumentPageProvider.buildArgument(stringParam = "foo", intParam = 0)
|
||||
ArgumentPageModel.buildArgument(stringParam = "foo", intParam = 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<NamedNavArgument>.isValid(arguments: Bundle?): Boolean {
|
||||
val stringParam = getStringArg(STRING_PARAM_NAME, arguments)
|
||||
return (stringParam != null && listOf("foo", "bar").contains(stringParam))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settingslib.spa.gallery.page
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.framework.common.PageModel
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.compose.stateOf
|
||||
import com.android.settingslib.spa.framework.util.getIntArg
|
||||
import com.android.settingslib.spa.framework.util.getStringArg
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TITLE = "Sample page with arguments"
|
||||
private const val STRING_PARAM_NAME = "stringParam"
|
||||
private const val INT_PARAM_NAME = "intParam"
|
||||
|
||||
class ArgumentPageModel : PageModel() {
|
||||
|
||||
companion object {
|
||||
const val name = "Argument"
|
||||
val parameter = listOf(
|
||||
navArgument(STRING_PARAM_NAME) { type = NavType.StringType },
|
||||
navArgument(INT_PARAM_NAME) { type = NavType.IntType },
|
||||
)
|
||||
|
||||
fun buildArgument(stringParam: String, intParam: Int? = null): Bundle {
|
||||
val args = Bundle()
|
||||
args.putString(STRING_PARAM_NAME, stringParam)
|
||||
if (intParam != null) args.putInt(INT_PARAM_NAME, intParam)
|
||||
return args
|
||||
}
|
||||
|
||||
fun buildNextArgument(newStringParam: String, arguments: Bundle? = null): Bundle {
|
||||
val intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
|
||||
return if (intParam == null)
|
||||
buildArgument(newStringParam)
|
||||
else
|
||||
buildArgument(newStringParam, intParam + 1)
|
||||
}
|
||||
|
||||
fun isValidArgument(arguments: Bundle?): Boolean {
|
||||
val stringParam = parameter.getStringArg(STRING_PARAM_NAME, arguments)
|
||||
return (stringParam != null && listOf("foo", "bar").contains(stringParam))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun create(arguments: Bundle?): ArgumentPageModel {
|
||||
val pageModel: ArgumentPageModel = viewModel(key = arguments.toString())
|
||||
pageModel.initOnce(arguments)
|
||||
return pageModel
|
||||
}
|
||||
}
|
||||
|
||||
private val title = TITLE
|
||||
private var arguments: Bundle? = null
|
||||
private var stringParam: String? = null
|
||||
private var intParam: Int? = null
|
||||
|
||||
override fun initialize(arguments: Bundle?) {
|
||||
logMsg("init with args " + arguments.toString())
|
||||
this.arguments = arguments
|
||||
stringParam = parameter.getStringArg(STRING_PARAM_NAME, arguments)
|
||||
intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun genPageTitle(): String {
|
||||
return title
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun genStringParamPreferenceModel(): PreferenceModel {
|
||||
return object : PreferenceModel {
|
||||
override val title = "String param value"
|
||||
override val summary = stateOf(stringParam!!)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun genIntParamPreferenceModel(): PreferenceModel {
|
||||
return object : PreferenceModel {
|
||||
override val title = "Int param value"
|
||||
override val summary = stateOf(intParam!!.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun genInjectPreferenceModel(): PreferenceModel {
|
||||
val summaryArray = listOf(
|
||||
"$STRING_PARAM_NAME=" + stringParam!!,
|
||||
"$INT_PARAM_NAME=" + intParam!!
|
||||
)
|
||||
return object : PreferenceModel {
|
||||
override val title = genPageTitle()
|
||||
override val summary = stateOf(summaryArray.joinToString(", "))
|
||||
override val onClick = navigator(name + parameter.navLink(arguments))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun logMsg(message: String) {
|
||||
Log.d("ArgumentPageModel", message)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settingslib.spa.framework.common
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
open class PageModel : ViewModel() {
|
||||
var initialized = false
|
||||
|
||||
fun initOnce(arguments: Bundle?) {
|
||||
// Initialize only once
|
||||
if (initialized) return
|
||||
initialized = true
|
||||
initialize(arguments)
|
||||
}
|
||||
|
||||
open fun initialize(arguments: Bundle?) {}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package com.android.settingslib.spa.framework.common
|
||||
import android.util.Log
|
||||
import java.util.LinkedList
|
||||
|
||||
const val MAX_ENTRY_SIZE = 5000
|
||||
private const val MAX_ENTRY_SIZE = 5000
|
||||
|
||||
/**
|
||||
* The repository to maintain all Settings entries
|
||||
|
||||
Reference in New Issue
Block a user