diff --git a/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt b/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt index ca1a9d1..7cd6e40 100644 --- a/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt +++ b/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt @@ -17,11 +17,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.navigation.NavDestination.Companion.hierarchy -import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.google.accompanist.systemuicontroller.rememberSystemUiController @@ -106,10 +103,7 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener { fabAction: () -> Unit ) { - var topBarTitle by remember { mutableStateOf("") } - var topBarIcon by remember { mutableStateOf(Icons.Filled.Menu) } - var topBarActions by remember { mutableStateOf(emptyList()) } - var topBarNavigationAction by remember { mutableStateOf(NavigationAction {}) } + var topBarState by remember { mutableStateOf(TopBarState()) } Scaffold( floatingActionButton = { @@ -120,76 +114,63 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener { } } }, - topBar = { - TopBar( - topBarTitle, - topBarIcon, - { topBarNavigationAction.action() }, - topBarActions - ) - }) { paddings -> + topBar = { TopBar(topBarState) }) { paddings -> NavHost( navController = navController, - startDestination = "counter", + startDestination = Route.COUNTER.name, modifier = Modifier.padding(paddings) ) { - composable("counter") { + composable(Route.COUNTER) { var expanded by remember { mutableStateOf(false) } - Counter(counterViewModel) - topBarActions = (listOf( - TopBarAction( - Icons.Outlined.Undo, - mainViewModel.isUndoActionActive, - { mainViewModel.undoLastRound() }), - TopBarAction( - Icons.Outlined.Redo, - mainViewModel.isRedoActionActive, - { mainViewModel.redoLastRound() }), - TopBarAction( - Icons.Outlined.MoreVert, - mainViewModel.activeGameHasRounds, - { expanded = true } - ) { - DropDownMenu( - mapOf("new" to R.string.newGame), - "", - expanded, + topBarState = TopBarState( + title = stringResource(R.string.app_name), + actions = (listOf( + TopBarAction( + Icons.Outlined.Undo, + mainViewModel.isUndoActionActive, + { mainViewModel.undoLastRound() }), + TopBarAction( + Icons.Outlined.Redo, + mainViewModel.isRedoActionActive, + { mainViewModel.redoLastRound() }), + TopBarAction( + Icons.Outlined.MoreVert, + mainViewModel.activeGameHasRounds, + { expanded = true } ) { - expanded = false - it?.let { - when (it) { - "new" -> mainViewModel.newGame() + DropDownMenu( + mapOf("new" to R.string.newGame), + "", + expanded, + ) { + expanded = false + it?.let { + when (it) { + "new" -> mainViewModel.newGame() + } } } - } - }, + }, - )) - topBarIcon = Icons.Outlined.Menu - topBarTitle = stringResource(R.string.app_name) - topBarNavigationAction = - NavigationAction { scope.launch { drawerState.open() } } + )) + ) { scope.launch { drawerState.open() } } + + Counter(counterViewModel) } - composable("history") { + composable(Route.HISTORY) { + topBarState = + TopBarState(title = stringResource(R.string.menu_history)) { scope.launch { drawerState.open() } } - HistoryList(historyViewModel) { navController.navigate("counter") } - - topBarActions = emptyList() - topBarIcon = Icons.Outlined.Menu - topBarTitle = stringResource(R.string.menu_history) - topBarNavigationAction = - NavigationAction { scope.launch { drawerState.open() } } + HistoryList(historyViewModel) { navController.navigate(Route.COUNTER) } } - composable("settings") { + composable(Route.SETTINGS) { + topBarState = + TopBarState(title = stringResource(R.string.menu_settings)) { scope.launch { drawerState.open() } } + SettingsView(settingsViewModel) - topBarActions = emptyList() - topBarIcon = Icons.Outlined.Menu - topBarTitle = stringResource(R.string.menu_settings) - topBarNavigationAction = - NavigationAction { scope.launch { drawerState.open() } } } } } @@ -204,40 +185,27 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener { val navController = rememberNavController() val items = listOf( - Screen("counter", Icons.Outlined.Calculate, R.string.app_name), - Screen("history", Icons.Outlined.List, R.string.menu_history), - Screen("settings", Icons.Outlined.Settings, R.string.menu_settings) + Screen(Route.COUNTER, Icons.Outlined.Calculate, R.string.app_name), + Screen(Route.HISTORY, Icons.Outlined.List, R.string.menu_history), + Screen(Route.SETTINGS, Icons.Outlined.Settings, R.string.menu_settings) ) val navBackStackEntry by navController.currentBackStackEntryAsState() - val currentDestination = navBackStackEntry?.destination + val currentDestination = + Route.valueOf(navBackStackEntry?.destination?.route ?: Route.COUNTER.name) ModalNavigationDrawer( drawerState = drawerState, gesturesEnabled = drawerState.isOpen, drawerContent = { - ModalDrawerSheet { + DrawerContent( + screens = items, + selectedScreen = items.first { it.route == currentDestination }) { + scope.launch { + drawerState.close() - Spacer(Modifier.height(20.dp)) - - items.forEach { screen -> - NavigationDrawerItem( - icon = { Icon(screen.icon, contentDescription = null) }, - label = { Text(stringResource(screen.resourceId)) }, - selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true, - onClick = { - scope.launch { drawerState.close() } - navController.navigate(screen.route) { - popUpTo(navController.graph.findStartDestination().id) { - saveState = true - } - launchSingleTop = true - restoreState = true - } - }, - modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding) - ) } + navController.navigate(it) } } ) { @@ -245,10 +213,34 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener { drawerState, scope, navController, - counterViewModel.keyboardHidden && (currentDestination?.hierarchy?.any { it.route == "counter" } == true) + counterViewModel.keyboardHidden && (currentDestination == Route.COUNTER) ) { counterViewModel.showKeyboard() } } } - private class Screen(val route: String, val icon: ImageVector, @StringRes val resourceId: Int) + @OptIn(ExperimentalMaterial3Api::class) + @Composable + private fun DrawerContent( + screens: List, + selectedScreen: Screen, + onElementClicked: (Route) -> Unit + ) { + + ModalDrawerSheet { + + Spacer(Modifier.height(20.dp)) + + screens.forEach { screen -> + NavigationDrawerItem( + icon = { Icon(screen.icon, contentDescription = null) }, + label = { Text(stringResource(screen.resourceId)) }, + selected = screen == selectedScreen, + onClick = { onElementClicked(screen.route) }, + modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding) + ) + } + } + } + + private class Screen(val route: Route, val icon: ImageVector, @StringRes val resourceId: Int) } \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/domain/NavExtensions.kt b/app/src/main/java/me/zobrist/tichucounter/domain/NavExtensions.kt new file mode 100644 index 0000000..3121f23 --- /dev/null +++ b/app/src/main/java/me/zobrist/tichucounter/domain/NavExtensions.kt @@ -0,0 +1,18 @@ +package me.zobrist.tichucounter.domain + +import androidx.compose.runtime.Composable +import androidx.navigation.* +import androidx.navigation.compose.composable + +fun NavController.navigate(route: Route) { + this.navigate(route.name) +} + +fun NavGraphBuilder.composable( + route: Route, + arguments: List = emptyList(), + deepLinks: List = emptyList(), + content: @Composable (NavBackStackEntry) -> Unit +) { + this.composable(route.name, arguments, deepLinks, content) +} diff --git a/app/src/main/java/me/zobrist/tichucounter/domain/NavigationAction.kt b/app/src/main/java/me/zobrist/tichucounter/domain/NavigationAction.kt deleted file mode 100644 index eb9dd5b..0000000 --- a/app/src/main/java/me/zobrist/tichucounter/domain/NavigationAction.kt +++ /dev/null @@ -1,3 +0,0 @@ -package me.zobrist.tichucounter.domain - -class NavigationAction(val action: () -> Unit) \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/domain/Route.kt b/app/src/main/java/me/zobrist/tichucounter/domain/Route.kt new file mode 100644 index 0000000..4ec7402 --- /dev/null +++ b/app/src/main/java/me/zobrist/tichucounter/domain/Route.kt @@ -0,0 +1,3 @@ +package me.zobrist.tichucounter.domain + +enum class Route { COUNTER, HISTORY, SETTINGS } diff --git a/app/src/main/java/me/zobrist/tichucounter/domain/TopBarAction.kt b/app/src/main/java/me/zobrist/tichucounter/domain/TopBarAction.kt index 4820f71..0a9eb39 100644 --- a/app/src/main/java/me/zobrist/tichucounter/domain/TopBarAction.kt +++ b/app/src/main/java/me/zobrist/tichucounter/domain/TopBarAction.kt @@ -3,4 +3,9 @@ package me.zobrist.tichucounter.domain import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector -class TopBarAction(val imageVector: ImageVector, val isActive: Boolean, val action: () -> Unit, val composeCode: @Composable () -> Unit = {}) \ No newline at end of file +class TopBarAction( + val imageVector: ImageVector, + val isActive: Boolean, + val action: () -> Unit, + val composeCode: @Composable () -> Unit = {} +) \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/domain/TopBarState.kt b/app/src/main/java/me/zobrist/tichucounter/domain/TopBarState.kt new file mode 100644 index 0000000..46bbd46 --- /dev/null +++ b/app/src/main/java/me/zobrist/tichucounter/domain/TopBarState.kt @@ -0,0 +1,12 @@ +package me.zobrist.tichucounter.domain + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Menu +import androidx.compose.ui.graphics.vector.ImageVector + +data class TopBarState( + var title: String = "", + var icon: ImageVector = Icons.Outlined.Menu, + var actions: List = emptyList(), + var onNavigate: () -> Unit = {} +) \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/TopBar.kt b/app/src/main/java/me/zobrist/tichucounter/ui/TopBar.kt index ecfcb4e..5ff2232 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/TopBar.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/TopBar.kt @@ -5,6 +5,17 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.style.TextOverflow import me.zobrist.tichucounter.domain.TopBarAction +import me.zobrist.tichucounter.domain.TopBarState + +@Composable +fun TopBar(topBarState: TopBarState) { + TopBar( + topBarState.title, + topBarState.icon, + topBarState.onNavigate, + topBarState.actions + ) +} @OptIn(ExperimentalMaterial3Api::class) @Composable