Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9e90fd2 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Represent the Gallery screen hierarchy as a tree

This CL changes the Gallery app screens to be a tree instead of a list.
This will allow adding sub-menus to the gallery app in case we want
multiple different screens for a single feature, which is the case for
the People activity/screens.

Bug: 238993727
Test: Builds
Change-Id: Idd28fd5a0fa79fd32ab1f8a95ed8c16fa2f465ac
parent 0facbc98
Loading
Loading
Loading
Loading
+20 −18
Original line number Diff line number Diff line
@@ -23,36 +23,38 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.android.systemui.compose.theme.SystemUITheme

enum class Screen {
    Home,
    Typography,
    MaterialColors,
    AndroidColors,
    ExampleFeature,
/** The gallery app screens. */
object GalleryAppScreens {
    val Typography = ChildScreen("typography") { TypographyScreen() }
    val MaterialColors = ChildScreen("material_colors") { MaterialColorsScreen() }
    val AndroidColors = ChildScreen("android_colors") { AndroidColorsScreen() }
    val ExampleFeature = ChildScreen("example_feature") { ExampleFeatureScreen() }

    val Home =
        ParentScreen(
            "home",
            mapOf(
                "Typography" to Typography,
                "Material colors" to MaterialColors,
                "Android colors" to AndroidColors,
                "Example feature" to ExampleFeature,
            )
        )
}

/** The main content of the app, that shows the [HomeScreen] by default. */
/** The main content of the app, that shows [GalleryAppScreens.Home] by default. */
@Composable
private fun MainContent() {
    Box(Modifier.fillMaxSize()) {
        val navController = rememberNavController()
        NavHost(
            navController = navController,
            startDestination = Screen.Home.name,
            startDestination = GalleryAppScreens.Home.identifier,
        ) {
            composable(Screen.Home.name) {
                HomeScreen(
                    onScreenSelected = { navController.navigate(it.name) },
                )
            }
            composable(Screen.Typography.name) { TypographyScreen() }
            composable(Screen.MaterialColors.name) { MaterialColorsScreen() }
            composable(Screen.AndroidColors.name) { AndroidColorsScreen() }
            composable(Screen.ExampleFeature.name) { ExampleFeatureScreen() }
            screen(GalleryAppScreens.Home, navController)
        }
    }
}
+95 −0
Original line number Diff line number Diff line
@@ -30,16 +30,51 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import androidx.navigation.compose.navigation

/**
 * A screen in an app. It is either an [ParentScreen] which lists its child screens to navigate to
 * them or a [ChildScreen] which shows some content.
 */
sealed class Screen(val identifier: String)

class ParentScreen(
    identifier: String,
    val children: Map<String, Screen>,
) : Screen(identifier)

class ChildScreen(
    identifier: String,
    val content: @Composable (NavController) -> Unit,
) : Screen(identifier)

/** Create the navigation graph for [screen]. */
fun NavGraphBuilder.screen(screen: Screen, navController: NavController) {
    when (screen) {
        is ChildScreen -> composable(screen.identifier) { screen.content(navController) }
        is ParentScreen -> {
            val menuRoute = "${screen.identifier}_menu"
            navigation(startDestination = menuRoute, route = screen.identifier) {
                // The menu to navigate to one of the children screens.
                composable(menuRoute) { ScreenMenu(screen, navController) }

                // The content of the child screens.
                screen.children.forEach { (_, child) -> screen(child, navController) }
            }
        }
    }
}

/** The home screen shown when starting the app. */
@Composable
fun HomeScreen(onScreenSelected: (Screen) -> Unit) {
    LazyColumn(
        verticalArrangement = Arrangement.spacedBy(8.dp),
private fun ScreenMenu(
    screen: ParentScreen,
    navController: NavController,
) {
        Screen.values()
            .filter { it != Screen.Home }
            .forEach { screen ->
    LazyColumn(verticalArrangement = Arrangement.spacedBy(8.dp)) {
        screen.children.forEach { (name, child) ->
            item {
                Surface(
                    Modifier.fillMaxWidth(),
@@ -47,10 +82,11 @@ fun HomeScreen(onScreenSelected: (Screen) -> Unit) {
                    shape = CircleShape,
                ) {
                    Column(
                            Modifier.clickable { onScreenSelected(screen) }.padding(16.dp),
                        Modifier.clickable { navController.navigate(child.identifier) }
                            .padding(16.dp),
                        horizontalAlignment = Alignment.CenterHorizontally,
                    ) {
                            Text(screen.name)
                        Text(name)
                    }
                }
            }