Better support for argument pages.
1. Add arguments in Entry.UiLayout API for runtime parameters 2. Remove EntryItem for all pages in gallery, use entry.UiLayout instead. 3. Link argument page in gallery's home page 4. Disable "open page" / "open entry" when there is runtime parameter in DebugActivity 5. Add debug message to open all pages in SPA Bug: 244122804 Test: manual - build Spa gallery Change-Id: Ibd5dfe3f1d154b6464a50cc3d8ccb084d15d3bf4
This commit is contained in:
@@ -52,7 +52,7 @@ object SpaEnvironment {
|
||||
),
|
||||
rootPages = listOf(
|
||||
SettingsPage.create(HomePageProvider.name)
|
||||
) + ArgumentPageProvider.buildRootPages()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.android.settingslib.spa.framework.common.SettingsPage
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.gallery.R
|
||||
import com.android.settingslib.spa.gallery.page.ArgumentPageModel
|
||||
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.FooterPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.IllustrationPageProvider
|
||||
@@ -39,52 +40,28 @@ object HomePageProvider : SettingsPageProvider {
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val owner = SettingsPage.create(name)
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
PreferenceMainPageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = owner).build()
|
||||
return listOf(
|
||||
PreferenceMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ArgumentPageProvider.buildInjectEntry("foo")!!.setLink(fromPage = owner).build(),
|
||||
SliderPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
SpinnerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
SettingsPagerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
FooterPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
IllustrationPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
)
|
||||
entryList.add(
|
||||
SliderPageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = owner).build()
|
||||
)
|
||||
entryList.add(
|
||||
SpinnerPageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = owner).build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsPagerPageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = owner).build()
|
||||
)
|
||||
entryList.add(
|
||||
FooterPageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = owner).build()
|
||||
)
|
||||
entryList.add(
|
||||
IllustrationPageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = owner).build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
HomePage()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HomePage() {
|
||||
HomeScaffold(title = stringResource(R.string.app_name)) {
|
||||
PreferenceMainPageProvider.EntryItem()
|
||||
ArgumentPageProvider.EntryItem(stringParam = "foo", intParam = 0)
|
||||
|
||||
SliderPageProvider.EntryItem()
|
||||
SpinnerPageProvider.EntryItem()
|
||||
SettingsPagerPageProvider.EntryItem()
|
||||
FooterPageProvider.EntryItem()
|
||||
IllustrationPageProvider.EntryItem()
|
||||
HomeScaffold(title = stringResource(R.string.app_name)) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
if (entry.name.startsWith(ArgumentPageModel.name)) {
|
||||
entry.UiLayout(ArgumentPageModel.buildArgument(intParam = 0))
|
||||
} else {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +69,6 @@ private fun HomePage() {
|
||||
@Composable
|
||||
private fun HomeScreenPreview() {
|
||||
SettingsTheme {
|
||||
HomePage()
|
||||
HomePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ object ArgumentPageProvider : SettingsPageProvider {
|
||||
.setIsAllowSearch(true)
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(arguments).genStringParamPreferenceModel())
|
||||
Preference(ArgumentPageModel.create(it).genStringParamPreferenceModel())
|
||||
}.build()
|
||||
)
|
||||
|
||||
@@ -53,54 +53,44 @@ object ArgumentPageProvider : SettingsPageProvider {
|
||||
.setIsAllowSearch(true)
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(arguments).genIntParamPreferenceModel())
|
||||
Preference(ArgumentPageModel.create(it).genIntParamPreferenceModel())
|
||||
}.build()
|
||||
)
|
||||
|
||||
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())
|
||||
entryList.add(buildInjectEntry("foo")!!.setLink(fromPage = owner).build())
|
||||
entryList.add(buildInjectEntry("bar")!!.setLink(fromPage = owner).build())
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
private fun buildInjectEntry(arguments: Bundle?): SettingsEntryBuilder? {
|
||||
fun buildInjectEntry(stringParam: String): SettingsEntryBuilder? {
|
||||
val arguments = ArgumentPageModel.buildArgument(stringParam)
|
||||
if (!ArgumentPageModel.isValidArgument(arguments)) return null
|
||||
|
||||
return SettingsEntryBuilder.createInject(
|
||||
entryName = ArgumentPageModel.getInjectEntryName(arguments),
|
||||
entryName = "${name}_$stringParam",
|
||||
owner = SettingsPage.create(name, parameter, arguments)
|
||||
)
|
||||
// Set attributes
|
||||
.setIsAllowSearch(false)
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(arguments).genInjectPreferenceModel())
|
||||
Preference(ArgumentPageModel.create(it).genInjectPreferenceModel())
|
||||
}
|
||||
}
|
||||
|
||||
fun buildRootPages(): List<SettingsPage> {
|
||||
return listOf(
|
||||
SettingsPage.create(name, parameter, ArgumentPageModel.buildArgument("foo")),
|
||||
SettingsPage.create(name, parameter, ArgumentPageModel.buildArgument("bar")),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = ArgumentPageModel.create(arguments).genPageTitle()) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.uiLayout()
|
||||
if (entry.name.startsWith(name)) {
|
||||
entry.UiLayout(ArgumentPageModel.buildNextArgument(arguments))
|
||||
} else {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem(stringParam: String, intParam: Int) {
|
||||
buildInjectEntry(ArgumentPageModel.buildArgument(stringParam, intParam))
|
||||
?.build()?.uiLayout?.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
|
||||
@@ -44,19 +44,17 @@ class ArgumentPageModel : PageModel() {
|
||||
navArgument(INT_PARAM_NAME) { type = NavType.IntType },
|
||||
)
|
||||
|
||||
fun buildArgument(stringParam: String, intParam: Int? = null): Bundle {
|
||||
fun buildArgument(stringParam: String? = null, intParam: Int? = null): Bundle {
|
||||
val args = Bundle()
|
||||
args.putString(STRING_PARAM_NAME, stringParam)
|
||||
if (stringParam != null) 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 {
|
||||
fun buildNextArgument(arguments: Bundle? = null): Bundle {
|
||||
val intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
|
||||
return if (intParam == null)
|
||||
buildArgument(newStringParam)
|
||||
else
|
||||
buildArgument(newStringParam, intParam + 1)
|
||||
val nextIntParam = if (intParam != null) intParam + 1 else null
|
||||
return buildArgument(intParam = nextIntParam)
|
||||
}
|
||||
|
||||
fun isValidArgument(arguments: Bundle?): Boolean {
|
||||
@@ -64,10 +62,6 @@ class ArgumentPageModel : PageModel() {
|
||||
return (stringParam != null && listOf("foo", "bar").contains(stringParam))
|
||||
}
|
||||
|
||||
fun getInjectEntryName(arguments: Bundle?): String {
|
||||
return "${name}_${parameter.getStringArg(STRING_PARAM_NAME, arguments)}"
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun create(arguments: Bundle?): ArgumentPageModel {
|
||||
val pageModel: ArgumentPageModel = viewModel(key = arguments.toString())
|
||||
|
||||
@@ -69,22 +69,12 @@ object FooterPageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
FooterPage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun FooterPage() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in FooterPageProvider.buildEntry(arguments = null)) {
|
||||
entry.uiLayout()
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
Footer(footerText = "Footer text always at the end of page.")
|
||||
}
|
||||
Footer(footerText = "Footer text always at the end of page.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +82,6 @@ private fun FooterPage() {
|
||||
@Composable
|
||||
private fun FooterPagePreview() {
|
||||
SettingsTheme {
|
||||
FooterPage()
|
||||
FooterPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,20 +84,10 @@ object IllustrationPageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
IllustrationPage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun IllustrationPage() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in IllustrationPageProvider.buildEntry(arguments = null)) {
|
||||
entry.uiLayout()
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +96,6 @@ private fun IllustrationPage() {
|
||||
@Composable
|
||||
private fun IllustrationPagePreview() {
|
||||
SettingsTheme {
|
||||
IllustrationPage()
|
||||
IllustrationPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,20 +48,10 @@ object SettingsPagerPageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
SettingsPagerPage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettingsPagerPage() {
|
||||
SettingsScaffold(title = TITLE) {
|
||||
SettingsPager(listOf("Personal", "Work")) {
|
||||
PlaceholderTitle("Page $it")
|
||||
SettingsScaffold(title = TITLE) {
|
||||
SettingsPager(listOf("Personal", "Work")) {
|
||||
PlaceholderTitle("Page $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,6 +60,6 @@ private fun SettingsPagerPage() {
|
||||
@Composable
|
||||
private fun SettingsPagerPagePreview() {
|
||||
SettingsTheme {
|
||||
SettingsPagerPage()
|
||||
SettingsPagerPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,20 +121,10 @@ object SliderPageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
SliderPage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SliderPage() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in SliderPageProvider.buildEntry(arguments = null)) {
|
||||
entry.uiLayout()
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,6 +133,6 @@ private fun SliderPage() {
|
||||
@Composable
|
||||
private fun SliderPagePreview() {
|
||||
SettingsTheme {
|
||||
SliderPage()
|
||||
SliderPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,20 +74,10 @@ object MainSwitchPreferencePageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
MainSwitchPreferencePage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainSwitchPreferencePage() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in MainSwitchPreferencePageProvider.buildEntry(arguments = null)) {
|
||||
entry.uiLayout()
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,6 +111,6 @@ private fun SampleNotChangeableMainSwitchPreference() {
|
||||
@Composable
|
||||
private fun MainSwitchPreferencePagePreview() {
|
||||
SettingsTheme {
|
||||
MainSwitchPreferencePage()
|
||||
MainSwitchPreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,25 +33,16 @@ object PreferenceMainPageProvider : SettingsPageProvider {
|
||||
override val name = "PreferenceMain"
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
return listOf(
|
||||
PreferencePageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = SettingsPage.create(name)).build()
|
||||
)
|
||||
entryList.add(
|
||||
.setLink(fromPage = SettingsPage.create(name)).build(),
|
||||
SwitchPreferencePageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = SettingsPage.create(name)).build()
|
||||
)
|
||||
entryList.add(
|
||||
.setLink(fromPage = SettingsPage.create(name)).build(),
|
||||
MainSwitchPreferencePageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = SettingsPage.create(name)).build()
|
||||
)
|
||||
entryList.add(
|
||||
.setLink(fromPage = SettingsPage.create(name)).build(),
|
||||
TwoTargetSwitchPreferencePageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = SettingsPage.create(name)).build()
|
||||
.setLink(fromPage = SettingsPage.create(name)).build(),
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
@@ -67,21 +58,10 @@ object PreferenceMainPageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
PreferenceMain()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PreferenceMain() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
PreferencePageProvider.EntryItem()
|
||||
SwitchPreferencePageProvider.EntryItem()
|
||||
MainSwitchPreferencePageProvider.EntryItem()
|
||||
TwoTargetSwitchPreferencePageProvider.EntryItem()
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,20 +143,10 @@ object PreferencePageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
PreferencePage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PreferencePage() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in PreferencePageProvider.buildEntry(arguments = null)) {
|
||||
entry.uiLayout()
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,6 +155,6 @@ private fun PreferencePage() {
|
||||
@Composable
|
||||
private fun PreferencePagePreview() {
|
||||
SettingsTheme {
|
||||
PreferencePage()
|
||||
PreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,20 +90,10 @@ object SwitchPreferencePageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
SwitchPreferencePage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SwitchPreferencePage() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in SwitchPreferencePageProvider.buildEntry(arguments = null)) {
|
||||
entry.uiLayout()
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,6 +158,6 @@ private fun SampleNotChangeableSwitchPreference() {
|
||||
@Composable
|
||||
private fun SwitchPreferencePagePreview() {
|
||||
SettingsTheme {
|
||||
SwitchPreferencePage()
|
||||
SwitchPreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,20 +90,10 @@ object TwoTargetSwitchPreferencePageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
TwoTargetSwitchPreferencePage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TwoTargetSwitchPreferencePage() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in TwoTargetSwitchPreferencePageProvider.buildEntry(arguments = null)) {
|
||||
entry.uiLayout()
|
||||
RegularScaffold(title = TITLE) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,6 +158,6 @@ private fun SampleNotChangeableTwoTargetSwitchPreference() {
|
||||
@Composable
|
||||
private fun TwoTargetSwitchPreferencePagePreview() {
|
||||
SettingsTheme {
|
||||
TwoTargetSwitchPreferencePage()
|
||||
TwoTargetSwitchPreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,28 +51,20 @@ object SpinnerPageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
SpinnerPage()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EntryItem() {
|
||||
buildInjectEntry().build().uiLayout.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SpinnerPage() {
|
||||
RegularScaffold(title = TITLE) {
|
||||
val selectedIndex = rememberSaveable { mutableStateOf(0) }
|
||||
Spinner(
|
||||
options = (1..3).map { "Option $it" },
|
||||
selectedIndex = selectedIndex.value,
|
||||
setIndex = { selectedIndex.value = it },
|
||||
)
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Selected index"
|
||||
override val summary = remember { derivedStateOf { selectedIndex.value.toString() } }
|
||||
})
|
||||
RegularScaffold(title = TITLE) {
|
||||
val selectedIndex = rememberSaveable { mutableStateOf(0) }
|
||||
Spinner(
|
||||
options = (1..3).map { "Option $it" },
|
||||
selectedIndex = selectedIndex.value,
|
||||
setIndex = { selectedIndex.value = it },
|
||||
)
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Selected index"
|
||||
override val summary = remember {
|
||||
derivedStateOf { selectedIndex.value.toString() }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +72,6 @@ private fun SpinnerPage() {
|
||||
@Composable
|
||||
private fun SpinnerPagePreview() {
|
||||
SettingsTheme {
|
||||
SpinnerPage()
|
||||
SpinnerPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,17 @@ open class DebugActivity(
|
||||
setTheme(R.style.Theme_SpaLib_DayNight)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val packageName = browseActivityClass.packageName
|
||||
val className = browseActivityClass.toString().removePrefix("class $packageName")
|
||||
for (pageWithEntry in entryRepository.getAllPageWithEntry()) {
|
||||
if (pageWithEntry.page.hasRuntimeParam()) continue
|
||||
val route = pageWithEntry.page.buildRoute()
|
||||
Log.d(
|
||||
"DEBUG ACTIVITY",
|
||||
"adb shell am start -n $packageName/$className -e $KEY_DESTINATION $route"
|
||||
)
|
||||
}
|
||||
|
||||
setContent {
|
||||
SettingsTheme {
|
||||
MainContent()
|
||||
@@ -136,6 +147,7 @@ open class DebugActivity(
|
||||
Text(text = "Entry size: ${pageWithEntry.entries.size}")
|
||||
Preference(model = object : PreferenceModel {
|
||||
override val title = "open page"
|
||||
override val enabled = (!pageWithEntry.page.hasRuntimeParam()).toState()
|
||||
override val onClick = openPage(pageWithEntry.page)
|
||||
})
|
||||
EntryList(pageWithEntry.entries)
|
||||
@@ -149,6 +161,7 @@ open class DebugActivity(
|
||||
RegularScaffold(title = "Entry ${entry.displayName}") {
|
||||
Preference(model = object : PreferenceModel {
|
||||
override val title = "open entry"
|
||||
override val enabled = (!entry.hasRuntimeParam()).toState()
|
||||
override val onClick = openEntry(entry)
|
||||
})
|
||||
Text(text = entry.formatAll())
|
||||
@@ -168,7 +181,8 @@ open class DebugActivity(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun openPage(page: SettingsPage): () -> Unit {
|
||||
private fun openPage(page: SettingsPage): (() -> Unit)? {
|
||||
if (page.hasRuntimeParam()) return null
|
||||
val route = page.buildRoute()
|
||||
val context = LocalContext.current
|
||||
val intent = Intent(context, browseActivityClass).apply {
|
||||
@@ -181,7 +195,8 @@ open class DebugActivity(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun openEntry(entry: SettingsEntry): () -> Unit {
|
||||
private fun openEntry(entry: SettingsEntry): (() -> Unit)? {
|
||||
if (entry.hasRuntimeParam()) return null
|
||||
val route = entry.buildRoute()
|
||||
val context = LocalContext.current
|
||||
val intent = Intent(context, browseActivityClass).apply {
|
||||
|
||||
@@ -19,9 +19,9 @@ package com.android.settingslib.spa.framework.common
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.navigation.NamedNavArgument
|
||||
import androidx.navigation.NavType
|
||||
import com.android.settingslib.spa.framework.BrowseActivity
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.framework.util.normalize
|
||||
|
||||
const val INJECT_ENTRY_NAME = "INJECT"
|
||||
const val ROOT_ENTRY_NAME = "ROOT"
|
||||
@@ -85,6 +85,10 @@ data class SettingsPage(
|
||||
"?${BrowseActivity.HIGHLIGHT_ENTRY_PARAM_NAME}=$highlightEntryName"
|
||||
return name + parameter.navLink(arguments) + highlightParam
|
||||
}
|
||||
|
||||
fun hasRuntimeParam(): Boolean {
|
||||
return parameter.hasRuntimeParam(arguments)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +143,7 @@ data class SettingsEntry(
|
||||
* injected entry. In the long term, we may deprecate the @Composable Page() API in SPP, and
|
||||
* use each entries' UI rendering function in the page instead.
|
||||
*/
|
||||
val uiLayout: (@Composable () -> Unit) = {},
|
||||
val uiLayoutImpl: (@Composable (arguments: Bundle?) -> Unit) = {},
|
||||
) {
|
||||
fun formatAll(): String {
|
||||
val content = listOf<String>(
|
||||
@@ -150,10 +154,25 @@ data class SettingsEntry(
|
||||
return content.joinToString("\n")
|
||||
}
|
||||
|
||||
private fun getDisplayPage(): SettingsPage {
|
||||
// Display the entry on its from-page, or on its owner page if the from-page is unset.
|
||||
return fromPage ?: owner
|
||||
}
|
||||
|
||||
fun buildRoute(): String {
|
||||
// Open entry in its fromPage.
|
||||
val page = fromPage ?: owner
|
||||
return page.buildRoute(name)
|
||||
return getDisplayPage().buildRoute(name)
|
||||
}
|
||||
|
||||
fun hasRuntimeParam(): Boolean {
|
||||
return getDisplayPage().hasRuntimeParam()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UiLayout(runtimeArguments: Bundle? = null) {
|
||||
val arguments = Bundle()
|
||||
if (owner.arguments != null) arguments.putAll(owner.arguments)
|
||||
if (runtimeArguments != null) arguments.putAll(runtimeArguments)
|
||||
uiLayoutImpl(arguments)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +215,7 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
private var isAllowSearch: Boolean? = null
|
||||
|
||||
private var searchDataFn: () -> SearchData? = { null }
|
||||
private var uiLayoutFn: (@Composable () -> Unit) = {}
|
||||
private var uiLayoutFn: (@Composable (arguments: Bundle?) -> Unit) = {}
|
||||
|
||||
fun build(): SettingsEntry {
|
||||
return SettingsEntry(
|
||||
@@ -214,7 +233,7 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
|
||||
// functions
|
||||
searchData = searchDataFn,
|
||||
uiLayout = uiLayoutFn,
|
||||
uiLayoutImpl = uiLayoutFn,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -237,7 +256,7 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
return this
|
||||
}
|
||||
|
||||
fun setUiLayoutFn(fn: @Composable () -> Unit): SettingsEntryBuilder {
|
||||
fun setUiLayoutFn(fn: @Composable (arguments: Bundle?) -> Unit): SettingsEntryBuilder {
|
||||
this.uiLayoutFn = fn
|
||||
return this
|
||||
}
|
||||
@@ -272,3 +291,33 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
private fun String.toUniqueId(): Int {
|
||||
return this.hashCode()
|
||||
}
|
||||
|
||||
private fun List<NamedNavArgument>.normalize(arguments: Bundle? = null): Bundle? {
|
||||
if (this.isEmpty()) return null
|
||||
val normArgs = Bundle()
|
||||
for (navArg in this) {
|
||||
when (navArg.argument.type) {
|
||||
NavType.StringType -> {
|
||||
val value = arguments?.getString(navArg.name)
|
||||
if (value != null)
|
||||
normArgs.putString(navArg.name, value)
|
||||
else
|
||||
normArgs.putString("unset_" + navArg.name, null)
|
||||
}
|
||||
NavType.IntType -> {
|
||||
if (arguments != null && arguments.containsKey(navArg.name))
|
||||
normArgs.putInt(navArg.name, arguments.getInt(navArg.name))
|
||||
else
|
||||
normArgs.putString("unset_" + navArg.name, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
return normArgs
|
||||
}
|
||||
|
||||
private fun List<NamedNavArgument>.hasRuntimeParam(arguments: Bundle? = null): Boolean {
|
||||
for (navArg in this) {
|
||||
if (arguments == null || !arguments.containsKey(navArg.name)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -40,29 +40,6 @@ fun List<NamedNavArgument>.navLink(arguments: Bundle? = null): String {
|
||||
return argsArray.joinToString("") { arg -> "/$arg" }
|
||||
}
|
||||
|
||||
fun List<NamedNavArgument>.normalize(arguments: Bundle? = null): Bundle? {
|
||||
if (this.isEmpty()) return null
|
||||
val normArgs = Bundle()
|
||||
for (navArg in this) {
|
||||
when (navArg.argument.type) {
|
||||
NavType.StringType -> {
|
||||
val value = arguments?.getString(navArg.name)
|
||||
if (value != null)
|
||||
normArgs.putString(navArg.name, value)
|
||||
else
|
||||
normArgs.putString("unset_" + navArg.name, null)
|
||||
}
|
||||
NavType.IntType -> {
|
||||
if (arguments != null && arguments.containsKey(navArg.name))
|
||||
normArgs.putInt(navArg.name, arguments.getInt(navArg.name))
|
||||
else
|
||||
normArgs.putString("unset_" + navArg.name, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
return normArgs
|
||||
}
|
||||
|
||||
fun List<NamedNavArgument>.getStringArg(name: String, arguments: Bundle? = null): String? {
|
||||
if (this.containsStringArg(name) && arguments != null) {
|
||||
return arguments.getString(name)
|
||||
|
||||
Reference in New Issue
Block a user