Use composable scaffold.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -96,25 +96,28 @@ dependencies {
|
|||||||
implementation 'androidx.fragment:fragment-ktx:1.5.5'
|
implementation 'androidx.fragment:fragment-ktx:1.5.5'
|
||||||
implementation 'androidx.preference:preference-ktx:1.2.0'
|
implementation 'androidx.preference:preference-ktx:1.2.0'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
|
||||||
implementation 'androidx.compose.material:material-icons-extended:1.3.1'
|
implementation 'androidx.compose.material:material-icons-extended:1.3.1'
|
||||||
implementation 'androidx.activity:activity-compose:1.3.1'
|
implementation 'androidx.activity:activity-compose:1.6.1'
|
||||||
implementation "androidx.compose.ui:ui:$compose_version"
|
implementation "androidx.compose.ui:ui:1.3.3"
|
||||||
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
|
implementation "androidx.compose.ui:ui-tooling-preview:1.3.3"
|
||||||
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
|
implementation "androidx.compose.runtime:runtime-livedata:1.3.3"
|
||||||
|
implementation "androidx.navigation:navigation-compose:2.5.3"
|
||||||
|
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
implementation "com.google.dagger:hilt-android:2.44"
|
implementation "com.google.dagger:hilt-android:2.44"
|
||||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
|
androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.3.3"
|
||||||
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
|
debugImplementation "androidx.compose.ui:ui-tooling:1.3.3"
|
||||||
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
|
debugImplementation "androidx.compose.ui:ui-test-manifest:1.3.3"
|
||||||
kapt "com.google.dagger:hilt-compiler:2.44"
|
kapt "com.google.dagger:hilt-compiler:2.44"
|
||||||
implementation("androidx.room:room-runtime:2.4.3")
|
implementation "androidx.room:room-runtime:2.5.0"
|
||||||
annotationProcessor("androidx.room:room-compiler:2.4.3")
|
annotationProcessor "androidx.room:room-compiler:2.5.0"
|
||||||
kapt("androidx.room:room-compiler:2.4.3")
|
kapt "androidx.room:room-compiler:2.5.0"
|
||||||
implementation("androidx.room:room-ktx:2.4.3")
|
implementation "androidx.room:room-ktx:2.5.0"
|
||||||
implementation("androidx.multidex:multidex:2.0.1")
|
implementation "androidx.multidex:multidex:2.0.1"
|
||||||
|
api "androidx.navigation:navigation-fragment-ktx:2.5.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow references to generated code
|
// Allow references to generated code
|
||||||
|
|||||||
@@ -1,50 +1,163 @@
|
|||||||
package me.zobrist.tichucounter
|
package me.zobrist.tichucounter
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.activity.compose.setContent
|
||||||
import androidx.navigation.findNavController
|
import androidx.activity.viewModels
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
import androidx.annotation.StringRes
|
||||||
import androidx.navigation.ui.navigateUp
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.navigation.ui.setupActionBarWithNavController
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.compose.material.icons.filled.*
|
||||||
import com.google.android.material.navigation.NavigationView
|
import androidx.compose.material.icons.outlined.Calculate
|
||||||
|
import androidx.compose.material.icons.outlined.List
|
||||||
|
import androidx.compose.material.icons.outlined.Settings
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
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 dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import me.zobrist.tichucounter.databinding.ActivityDrawerBinding
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import me.zobrist.tichucounter.ui.counter.*
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : BaseActivity() {
|
class MainActivity : BaseActivity() {
|
||||||
|
|
||||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
private val counterViewModel: CounterViewModel by viewModels()
|
||||||
private lateinit var binding: ActivityDrawerBinding
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
binding = ActivityDrawerBinding.inflate(layoutInflater)
|
setContent {
|
||||||
setContentView(binding.root)
|
NavigationDrawer()
|
||||||
|
}
|
||||||
val drawerLayout: DrawerLayout = binding.drawerLayout
|
|
||||||
val navView: NavigationView = binding.navView
|
|
||||||
val navController = findNavController(R.id.nav_host_fragment_content_drawer)
|
|
||||||
|
|
||||||
setSupportActionBar(binding.appBarDrawer.toolbar)
|
|
||||||
|
|
||||||
// Passing each menu ID as a set of Ids because each
|
|
||||||
// menu should be considered as top level destinations.
|
|
||||||
appBarConfiguration = AppBarConfiguration(
|
|
||||||
setOf(
|
|
||||||
R.id.nav_counter, R.id.nav_history, R.id.nav_settings
|
|
||||||
), drawerLayout
|
|
||||||
)
|
|
||||||
|
|
||||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
|
||||||
navView.setupWithNavController(navController)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSupportNavigateUp(): Boolean {
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
val navController = findNavController(R.id.nav_host_fragment_content_drawer)
|
@Composable
|
||||||
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
|
fun MyScaffoldLayout(
|
||||||
|
drawerState: DrawerState,
|
||||||
|
scope: CoroutineScope,
|
||||||
|
navController: NavHostController
|
||||||
|
) {
|
||||||
|
|
||||||
|
MaterialTheme() {
|
||||||
|
Scaffold(
|
||||||
|
topBar = { TopBar(drawerState, scope) }) {
|
||||||
|
|
||||||
|
NavHost(
|
||||||
|
navController = navController,
|
||||||
|
startDestination = "counter",
|
||||||
|
modifier = Modifier.padding(it)
|
||||||
|
) {
|
||||||
|
composable("counter") {
|
||||||
|
Counter(counterViewModel)
|
||||||
|
}
|
||||||
|
composable("history") {
|
||||||
|
Column() {
|
||||||
|
Text("History")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
composable("settings") {
|
||||||
|
Column() {
|
||||||
|
Text("Settings")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
private fun TopBar(drawerState: DrawerState, scope: CoroutineScope) {
|
||||||
|
CenterAlignedTopAppBar(
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
"Centered TopAppBar",
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
},
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton(onClick = { scope.launch { drawerState.open() } }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.Menu,
|
||||||
|
contentDescription = "Localized description"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions = {
|
||||||
|
IconButton(onClick = { /* doSomething() */ }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.Favorite,
|
||||||
|
contentDescription = "Localized description"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
private fun NavigationDrawer() {
|
||||||
|
val drawerState = rememberDrawerState(DrawerValue.Closed)
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
val navController = rememberNavController()
|
||||||
|
|
||||||
|
val items = listOf(Screen.Calculator, Screen.History, Screen.Settings)
|
||||||
|
|
||||||
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
|
val currentDestination = navBackStackEntry?.destination
|
||||||
|
|
||||||
|
ModalNavigationDrawer(
|
||||||
|
drawerState = drawerState,
|
||||||
|
drawerContent = {
|
||||||
|
ModalDrawerSheet {
|
||||||
|
Spacer(Modifier.height(12.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) {
|
||||||
|
// Pop up to the start destination of the graph to
|
||||||
|
// avoid building up a large stack of destinations
|
||||||
|
// on the back stack as users select items
|
||||||
|
popUpTo(navController.graph.findStartDestination().id) {
|
||||||
|
saveState = true
|
||||||
|
}
|
||||||
|
// Avoid multiple copies of the same destination when
|
||||||
|
// reselecting the same item
|
||||||
|
launchSingleTop = true
|
||||||
|
// Restore state when reselecting a previously selected item
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = { MyScaffoldLayout(drawerState, scope, navController) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class Screen(val route: String, val icon: ImageVector, @StringRes val resourceId: Int) {
|
||||||
|
object Calculator : Screen("counter", Icons.Outlined.Calculate, R.string.menu_counter)
|
||||||
|
object History : Screen("history", Icons.Outlined.List, R.string.menu_history)
|
||||||
|
object Settings : Screen("settings", Icons.Outlined.Settings, R.string.menu_settings)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.*
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.core.view.MenuHost
|
|
||||||
import androidx.core.view.MenuProvider
|
|
||||||
import androidx.lifecycle.Lifecycle
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import me.zobrist.tichucounter.R
|
|
||||||
import me.zobrist.tichucounter.databinding.FragmentCounterBinding
|
|
||||||
import me.zobrist.tichucounter.repository.GameRepository
|
|
||||||
import me.zobrist.tichucounter.ui.FragmentBase
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class CounterFragment : FragmentBase<FragmentCounterBinding>(), MenuProvider {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var gameRepository: GameRepository
|
|
||||||
|
|
||||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentCounterBinding
|
|
||||||
get() = FragmentCounterBinding::inflate
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
val menuHost: MenuHost = requireActivity()
|
|
||||||
menuHost.addMenuProvider(
|
|
||||||
this, viewLifecycleOwner, Lifecycle.State.RESUMED
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
|
||||||
menuInflater.inflate(R.menu.menu_counter, menu)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
|
||||||
return when (menuItem.itemId) {
|
|
||||||
R.id.action_new -> {
|
|
||||||
val builder = context?.let { AlertDialog.Builder(it) }
|
|
||||||
if (builder != null) {
|
|
||||||
builder.setMessage(getString(R.string.confirmNew)).setTitle(R.string.clear)
|
|
||||||
.setCancelable(false)
|
|
||||||
.setPositiveButton(getString(R.string.yes)) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
|
||||||
gameRepository.newGame()
|
|
||||||
}
|
|
||||||
}.setNegativeButton(getString(R.string.no)) { dialog, _ ->
|
|
||||||
dialog.cancel()
|
|
||||||
}
|
|
||||||
builder.create().show()
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
R.id.action_undo -> {
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
|
||||||
gameRepository.revertLastRound()
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package me.zobrist.tichucounter.ui.counter
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Counter(
|
||||||
|
viewModel: CounterViewModel
|
||||||
|
) {
|
||||||
|
Column() {
|
||||||
|
TeamNamesView(
|
||||||
|
viewModel.teamNameA,
|
||||||
|
viewModel.teamNameB,
|
||||||
|
{ viewModel.updateNameA(it) },
|
||||||
|
{ viewModel.updateNameB(it) })
|
||||||
|
|
||||||
|
TeamScoresView(
|
||||||
|
viewModel.totalScoreA,
|
||||||
|
viewModel.totalScoreB
|
||||||
|
)
|
||||||
|
|
||||||
|
RoundListView(
|
||||||
|
viewModel.roundScoreList,
|
||||||
|
Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
|
KeyboardView(
|
||||||
|
viewModel.currentScoreA,
|
||||||
|
viewModel.currentScoreB,
|
||||||
|
viewModel.requestFocusA,
|
||||||
|
viewModel.enableSubmit,
|
||||||
|
{ viewModel.updateFocusStateA(it) },
|
||||||
|
{ viewModel.updateFocusStateB(it) },
|
||||||
|
{ viewModel.digitClicked(it) },
|
||||||
|
{ viewModel.addSub100Clicked(it) },
|
||||||
|
{ viewModel.deleteClicked() },
|
||||||
|
{ viewModel.negateClicked() },
|
||||||
|
{ viewModel.submitClicked() }
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,17 +8,39 @@ import androidx.lifecycle.ViewModel
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import me.zobrist.tichucounter.data.GameDao
|
||||||
|
import me.zobrist.tichucounter.data.Round
|
||||||
|
import me.zobrist.tichucounter.data.RoundDao
|
||||||
import me.zobrist.tichucounter.domain.Tichu
|
import me.zobrist.tichucounter.domain.Tichu
|
||||||
import me.zobrist.tichucounter.repository.GameRepository
|
import me.zobrist.tichucounter.repository.GameRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class KeyboardViewModel @Inject constructor(private val gameRepository: GameRepository) :
|
class CounterViewModel @Inject constructor(
|
||||||
|
private val gameRepository: GameRepository,
|
||||||
|
private val roundDao: RoundDao,
|
||||||
|
private val gameDao: GameDao
|
||||||
|
) :
|
||||||
ViewModel() {
|
ViewModel() {
|
||||||
var scoreA by mutableStateOf("")
|
|
||||||
|
var roundScoreList by mutableStateOf(emptyList<Round>())
|
||||||
|
|
||||||
|
var totalScoreA by mutableStateOf(0)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var scoreB by mutableStateOf("")
|
var totalScoreB by mutableStateOf(0)
|
||||||
|
private set
|
||||||
|
|
||||||
|
var teamNameA by mutableStateOf("")
|
||||||
|
private set
|
||||||
|
|
||||||
|
var teamNameB by mutableStateOf("")
|
||||||
|
private set
|
||||||
|
|
||||||
|
var currentScoreA by mutableStateOf("")
|
||||||
|
private set
|
||||||
|
|
||||||
|
var currentScoreB by mutableStateOf("")
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var enableSubmit by mutableStateOf(false)
|
var enableSubmit by mutableStateOf(false)
|
||||||
@@ -34,89 +56,58 @@ class KeyboardViewModel @Inject constructor(private val gameRepository: GameRepo
|
|||||||
private var activeValue: String
|
private var activeValue: String
|
||||||
get() {
|
get() {
|
||||||
return if (isBFocused) {
|
return if (isBFocused) {
|
||||||
scoreB
|
currentScoreB
|
||||||
} else {
|
} else {
|
||||||
scoreA
|
currentScoreA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
if (isBFocused) {
|
if (isBFocused) {
|
||||||
scoreB = value
|
currentScoreB = value
|
||||||
} else {
|
} else {
|
||||||
scoreA = value
|
currentScoreA = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var inactiveValue: String
|
private var inactiveValue: String
|
||||||
get() {
|
get() {
|
||||||
return if (isAFocused) {
|
return if (isAFocused) {
|
||||||
scoreB
|
currentScoreB
|
||||||
} else {
|
} else {
|
||||||
scoreA
|
currentScoreA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
if (isAFocused) {
|
if (isAFocused) {
|
||||||
scoreB = value
|
currentScoreB = value
|
||||||
} else {
|
} else {
|
||||||
scoreA = value
|
currentScoreA = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
fun submitScore() {
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
gameRepository.addRoundToActiveGame(scoreA.toInt(), scoreB.toInt())
|
roundDao.getForActiveGame().collect {
|
||||||
}
|
roundScoreList = it
|
||||||
scoreA = ""
|
}
|
||||||
scoreB = ""
|
|
||||||
enableSubmit = false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun appendToFocusedScore(toAppend: String) {
|
|
||||||
giveFocusToAIfNone()
|
|
||||||
|
|
||||||
activeValue += toAppend
|
|
||||||
updateOtherScore()
|
|
||||||
updateSubmitButton()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun negateActiveInput() {
|
|
||||||
giveFocusToAIfNone()
|
|
||||||
|
|
||||||
activeValue = if (activeValue.contains("-")) {
|
|
||||||
activeValue.replace("-", "")
|
|
||||||
} else {
|
|
||||||
"-$activeValue"
|
|
||||||
}
|
|
||||||
updateOtherScore()
|
|
||||||
updateSubmitButton()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addToActiveInput(toAdd: Int) {
|
|
||||||
giveFocusToAIfNone()
|
|
||||||
|
|
||||||
activeValue = try {
|
|
||||||
val temp = activeValue.toInt() + toAdd
|
|
||||||
temp.toString()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
toAdd.toString()
|
|
||||||
}
|
|
||||||
if(inactiveValue == "")
|
|
||||||
{
|
|
||||||
updateOtherScore()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSubmitButton()
|
viewModelScope.launch {
|
||||||
}
|
gameDao.getActive().collect {
|
||||||
|
if (it != null) {
|
||||||
fun removeLastCharFromActive() {
|
teamNameA = it.nameA
|
||||||
if (activeValue != "") {
|
teamNameB = it.nameB
|
||||||
activeValue = activeValue.dropLast(1)
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateOtherScore()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
|
roundDao.getRoundSumForActiveGame().collect { score ->
|
||||||
|
totalScoreA = score.scoreA
|
||||||
|
totalScoreB = score.scoreB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun giveFocusToAIfNone() {
|
private fun giveFocusToAIfNone() {
|
||||||
if (!isAFocused && !isBFocused) {
|
if (!isAFocused && !isBFocused) {
|
||||||
@@ -142,7 +133,7 @@ class KeyboardViewModel @Inject constructor(private val gameRepository: GameRepo
|
|||||||
private fun isValidTichuRound(): Boolean {
|
private fun isValidTichuRound(): Boolean {
|
||||||
return try {
|
return try {
|
||||||
val tichu = Tichu()
|
val tichu = Tichu()
|
||||||
tichu.isValidRound(scoreA.toInt(), scoreB.toInt())
|
tichu.isValidRound(currentScoreA.toInt(), currentScoreB.toInt())
|
||||||
} catch (_: java.lang.NumberFormatException) {
|
} catch (_: java.lang.NumberFormatException) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -151,4 +142,80 @@ class KeyboardViewModel @Inject constructor(private val gameRepository: GameRepo
|
|||||||
private fun updateSubmitButton() {
|
private fun updateSubmitButton() {
|
||||||
enableSubmit = isValidTichuRound()
|
enableSubmit = isValidTichuRound()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun submitClicked() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
gameRepository.addRoundToActiveGame(currentScoreA.toInt(), currentScoreB.toInt())
|
||||||
|
}
|
||||||
|
currentScoreA = ""
|
||||||
|
currentScoreB = ""
|
||||||
|
enableSubmit = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun digitClicked(digit: String) {
|
||||||
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
|
activeValue += digit
|
||||||
|
updateOtherScore()
|
||||||
|
updateSubmitButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun negateClicked() {
|
||||||
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
|
activeValue = if (activeValue.contains("-")) {
|
||||||
|
activeValue.replace("-", "")
|
||||||
|
} else {
|
||||||
|
"-$activeValue"
|
||||||
|
}
|
||||||
|
updateOtherScore()
|
||||||
|
updateSubmitButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addSub100Clicked(toAdd: Int) {
|
||||||
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
|
activeValue = try {
|
||||||
|
val temp = activeValue.toInt() + toAdd
|
||||||
|
temp.toString()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
toAdd.toString()
|
||||||
|
}
|
||||||
|
if (inactiveValue == "") {
|
||||||
|
updateOtherScore()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSubmitButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteClicked() {
|
||||||
|
if (activeValue != "") {
|
||||||
|
activeValue = activeValue.dropLast(1)
|
||||||
|
}
|
||||||
|
updateOtherScore()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateNameA(value: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val game = gameRepository.activeGame
|
||||||
|
game.nameA = value
|
||||||
|
gameRepository.updateGame(game)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateNameB(value: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val game = gameRepository.activeGame
|
||||||
|
game.nameB = value
|
||||||
|
gameRepository.updateGame(game)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateFocusStateA(state: Boolean) {
|
||||||
|
isAFocused = state
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateFocusStateB(state: Boolean) {
|
||||||
|
isBFocused = state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.outlined.Backspace
|
|
||||||
import androidx.compose.material.icons.outlined.Check
|
|
||||||
import androidx.compose.material3.*
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.focus.focusRequester
|
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
|
||||||
import androidx.compose.ui.geometry.Rect
|
|
||||||
import androidx.compose.ui.platform.*
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import me.zobrist.tichucounter.R
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class Keyboard : Fragment() {
|
|
||||||
|
|
||||||
|
|
||||||
private val viewModel: KeyboardViewModel by activityViewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
|
|
||||||
return ComposeView(requireContext()).apply {
|
|
||||||
// Dispose of the Composition when the view's LifecycleOwner
|
|
||||||
// is destroyed
|
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
|
||||||
setContent {
|
|
||||||
MaterialTheme {
|
|
||||||
KeyboardView(viewModel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
|
||||||
fun KeyboardView(viewModel: KeyboardViewModel) {
|
|
||||||
val keyboardController = LocalSoftwareKeyboardController.current
|
|
||||||
|
|
||||||
Column {
|
|
||||||
Row {
|
|
||||||
TextField(
|
|
||||||
value = viewModel.scoreA,
|
|
||||||
onValueChange = { },
|
|
||||||
placeholder = { Text("0") },
|
|
||||||
singleLine = true,
|
|
||||||
readOnly = true,
|
|
||||||
modifier = Modifier
|
|
||||||
.onFocusChanged {
|
|
||||||
keyboardController?.hide()
|
|
||||||
viewModel.isAFocused = it.isFocused
|
|
||||||
}
|
|
||||||
.focusRequester(viewModel.requestFocusA)
|
|
||||||
.weight(1f),
|
|
||||||
)
|
|
||||||
TextField(
|
|
||||||
value = viewModel.scoreB,
|
|
||||||
onValueChange = { },
|
|
||||||
placeholder = { Text("0") },
|
|
||||||
singleLine = true,
|
|
||||||
readOnly = true,
|
|
||||||
modifier = Modifier
|
|
||||||
.onFocusChanged {
|
|
||||||
keyboardController?.hide()
|
|
||||||
viewModel.isBFocused = it.isFocused
|
|
||||||
}
|
|
||||||
.weight(1f)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("1") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("1") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("2") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("2") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("3") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("3") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.addToActiveInput(100) },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("+100") }
|
|
||||||
|
|
||||||
}
|
|
||||||
Row {
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("4") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("4") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("5") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("5") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("6") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("6") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.addToActiveInput(-100) },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("-100") }
|
|
||||||
}
|
|
||||||
Row {
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("7") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("7") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("8") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("8") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("9") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("9") }
|
|
||||||
IconButton(
|
|
||||||
onClick = { viewModel.removeLastCharFromActive() },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Icon(Icons.Outlined.Backspace, stringResource(R.string.submit)) }
|
|
||||||
}
|
|
||||||
Row {
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.negateActiveInput() },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("+/-") }
|
|
||||||
TextButton(
|
|
||||||
onClick = { viewModel.appendToFocusedScore("0") },
|
|
||||||
modifier = Modifier.weight(1F)
|
|
||||||
) { Text("0") }
|
|
||||||
Spacer(modifier = Modifier.weight(1F))
|
|
||||||
IconButton(
|
|
||||||
onClick = { viewModel.submitScore() },
|
|
||||||
modifier = Modifier.weight(1F),
|
|
||||||
enabled = viewModel.enableSubmit
|
|
||||||
) { Icon(Icons.Outlined.Check, stringResource(R.string.submit)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
package me.zobrist.tichucounter.ui.counter
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Backspace
|
||||||
|
import androidx.compose.material.icons.outlined.Check
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import me.zobrist.tichucounter.R
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
||||||
|
@Composable
|
||||||
|
fun KeyboardView(
|
||||||
|
scoreA: String,
|
||||||
|
scoreB: String,
|
||||||
|
requestFocusA: FocusRequester,
|
||||||
|
enableSubmit: Boolean,
|
||||||
|
updateFocusStateA: (Boolean) -> Unit,
|
||||||
|
updateFocusStateB: (Boolean) -> Unit,
|
||||||
|
digitClicked: (String) -> Unit,
|
||||||
|
addSub100Clicked: (Int) -> Unit,
|
||||||
|
deleteClicked: () -> Unit,
|
||||||
|
negateClicked: () -> Unit,
|
||||||
|
submitClicked: () -> Unit
|
||||||
|
) {
|
||||||
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Row {
|
||||||
|
TextField(
|
||||||
|
value = scoreA,
|
||||||
|
onValueChange = { },
|
||||||
|
placeholder = { Text("0") },
|
||||||
|
singleLine = true,
|
||||||
|
readOnly = true,
|
||||||
|
modifier = Modifier
|
||||||
|
.onFocusChanged {
|
||||||
|
keyboardController?.hide()
|
||||||
|
updateFocusStateA(it.isFocused)
|
||||||
|
}
|
||||||
|
.focusRequester(requestFocusA)
|
||||||
|
.weight(1f),
|
||||||
|
)
|
||||||
|
TextField(
|
||||||
|
value = scoreB,
|
||||||
|
onValueChange = { },
|
||||||
|
placeholder = { Text("0") },
|
||||||
|
singleLine = true,
|
||||||
|
readOnly = true,
|
||||||
|
modifier = Modifier
|
||||||
|
.onFocusChanged {
|
||||||
|
keyboardController?.hide()
|
||||||
|
updateFocusStateB(it.isFocused)
|
||||||
|
}
|
||||||
|
.weight(1f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("1") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("1") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("2") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("2") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("3") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("3") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { addSub100Clicked(100) },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("+100") }
|
||||||
|
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("4") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("4") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("5") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("5") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("6") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("6") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { addSub100Clicked(-100) },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("-100") }
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("7") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("7") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("8") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("8") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("9") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("9") }
|
||||||
|
IconButton(
|
||||||
|
onClick = { deleteClicked() },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Icon(Icons.Outlined.Backspace, stringResource(R.string.submit)) }
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
TextButton(
|
||||||
|
onClick = { negateClicked() },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("+/-") }
|
||||||
|
TextButton(
|
||||||
|
onClick = { digitClicked("0") },
|
||||||
|
modifier = Modifier.weight(1F)
|
||||||
|
) { Text("0") }
|
||||||
|
Spacer(modifier = Modifier.weight(1F))
|
||||||
|
IconButton(
|
||||||
|
onClick = { submitClicked() },
|
||||||
|
modifier = Modifier.weight(1F),
|
||||||
|
enabled = enableSubmit
|
||||||
|
) { Icon(Icons.Outlined.Check, stringResource(R.string.submit)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import me.zobrist.tichucounter.data.Round
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class RoundList : Fragment() {
|
|
||||||
|
|
||||||
private val viewModel: RoundListViewModel by activityViewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
|
|
||||||
return ComposeView(requireContext()).apply {
|
|
||||||
// Dispose of the Composition when the view's LifecycleOwner
|
|
||||||
// is destroyed
|
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
|
||||||
setContent {
|
|
||||||
MaterialTheme {
|
|
||||||
RoundListView(viewModel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun RoundListView(viewModel: RoundListViewModel) {
|
|
||||||
RoundListView(viewModel.scores)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun RoundListView(rounds: List<Round>) {
|
|
||||||
val lazyListState = rememberLazyListState()
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
LazyColumn(state = lazyListState) {
|
|
||||||
itemsIndexed(rounds) { index, item ->
|
|
||||||
RoundListItem(item, index, lazyListState)
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.launch {
|
|
||||||
lazyListState.animateScrollToItem(viewModel.scores.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun RoundListItem(round: Round, index: Int, lazyListState: LazyListState) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(all = 4.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = round.scoreA.toString(),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
modifier = Modifier.weight(5f),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = index.toString(),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = round.scoreB.toString(),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
modifier = Modifier.weight(5f),
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
@Preview
|
|
||||||
fun RoundListViewPreview() {
|
|
||||||
val rounds = listOf<Round>(
|
|
||||||
Round(1, 10, 90),
|
|
||||||
Round(1, 5, 95),
|
|
||||||
Round(1, 100, 0),
|
|
||||||
Round(1, 125, -25),
|
|
||||||
Round(1, 50, 50)
|
|
||||||
)
|
|
||||||
RoundListView(rounds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package me.zobrist.tichucounter.ui.counter
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import me.zobrist.tichucounter.data.Round
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RoundListView(rounds: List<Round>, modifier: Modifier) {
|
||||||
|
val lazyListState = rememberLazyListState()
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
LazyColumn(state = lazyListState, modifier = modifier) {
|
||||||
|
itemsIndexed(rounds) { index, item ->
|
||||||
|
RoundListItem(item, index, lazyListState)
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.launch {
|
||||||
|
lazyListState.animateScrollToItem(rounds.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RoundListItem(round: Round, index: Int, lazyListState: LazyListState) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(all = 4.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = round.scoreA.toString(),
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
modifier = Modifier.weight(5f),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = index.toString(),
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = round.scoreB.toString(),
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
modifier = Modifier.weight(5f),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@Preview
|
||||||
|
fun RoundListViewPreview() {
|
||||||
|
val rounds = listOf<Round>(
|
||||||
|
Round(1, 10, 90),
|
||||||
|
Round(1, 5, 95),
|
||||||
|
Round(1, 100, 0),
|
||||||
|
Round(1, 125, -25),
|
||||||
|
Round(1, 50, 50)
|
||||||
|
)
|
||||||
|
RoundListView(rounds, Modifier)
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import me.zobrist.tichucounter.data.Round
|
|
||||||
import me.zobrist.tichucounter.data.RoundDao
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@HiltViewModel
|
|
||||||
class RoundListViewModel @Inject constructor(private val roundDao: RoundDao) : ViewModel(){
|
|
||||||
|
|
||||||
var scores by mutableStateOf(emptyList<Round>())
|
|
||||||
|
|
||||||
init {
|
|
||||||
viewModelScope.launch {
|
|
||||||
roundDao.getForActiveGame().collect {
|
|
||||||
scores = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.EditText
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.viewModels
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class TeamNames : Fragment() {
|
|
||||||
|
|
||||||
private val viewModel: TeamNamesViewModel by viewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
|
|
||||||
return ComposeView(requireContext()).apply {
|
|
||||||
// Dispose of the Composition when the view's LifecycleOwner
|
|
||||||
// is destroyed
|
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
|
||||||
setContent {
|
|
||||||
MaterialTheme {
|
|
||||||
TeamNamesView(viewModel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TeamNamesView(viewModel: TeamNamesViewModel) {
|
|
||||||
|
|
||||||
TeamNamesView(
|
|
||||||
viewModel.nameA,
|
|
||||||
viewModel.nameB,
|
|
||||||
{ viewModel.updateNameA(it)},
|
|
||||||
{ viewModel.updateNameB(it)})
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
private fun TeamNamesView(
|
|
||||||
nameA: String,
|
|
||||||
nameB: String,
|
|
||||||
updateA: (String) -> Unit,
|
|
||||||
updateB: (String) -> Unit
|
|
||||||
){
|
|
||||||
Row() {
|
|
||||||
TextField(
|
|
||||||
value = nameA,
|
|
||||||
onValueChange = { updateA(it) },
|
|
||||||
singleLine = true,
|
|
||||||
modifier = Modifier.weight(1f))
|
|
||||||
|
|
||||||
TextField(
|
|
||||||
value = nameB,
|
|
||||||
onValueChange = { updateB(it) },
|
|
||||||
singleLine = true,
|
|
||||||
modifier = Modifier.weight(1f))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
private fun TeamNamesView() {
|
|
||||||
TeamNamesView("TeamA", "TeamB", {}, {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package me.zobrist.tichucounter.ui.counter
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun TeamNamesView(
|
||||||
|
nameA: String,
|
||||||
|
nameB: String,
|
||||||
|
updateA: (String) -> Unit,
|
||||||
|
updateB: (String) -> Unit
|
||||||
|
) {
|
||||||
|
Row() {
|
||||||
|
TextField(
|
||||||
|
value = nameA,
|
||||||
|
onValueChange = { updateA(it) },
|
||||||
|
singleLine = true,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
|
TextField(
|
||||||
|
value = nameB,
|
||||||
|
onValueChange = { updateB(it) },
|
||||||
|
singleLine = true,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun TeamNamesViewPreview() {
|
||||||
|
TeamNamesView("TeamA", "TeamB", {}, {})
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import me.zobrist.tichucounter.data.Game
|
|
||||||
import me.zobrist.tichucounter.data.GameDao
|
|
||||||
import me.zobrist.tichucounter.repository.GameRepository
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@HiltViewModel
|
|
||||||
class TeamNamesViewModel @Inject constructor(
|
|
||||||
private val gameDao: GameDao,
|
|
||||||
private val gameRepository: GameRepository
|
|
||||||
) :
|
|
||||||
ViewModel() {
|
|
||||||
|
|
||||||
var nameA by mutableStateOf("")
|
|
||||||
private set
|
|
||||||
|
|
||||||
var nameB by mutableStateOf("")
|
|
||||||
private set
|
|
||||||
|
|
||||||
init {
|
|
||||||
viewModelScope.launch {
|
|
||||||
gameDao.getActive().collect {
|
|
||||||
if (it != null) {
|
|
||||||
nameA = it.nameA
|
|
||||||
nameB = it.nameB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateNameA(value: String) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
val game = gameRepository.activeGame
|
|
||||||
game.nameA = value
|
|
||||||
gameRepository.updateGame(game)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateNameB(value: String) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
val game = gameRepository.activeGame
|
|
||||||
game.nameB = value
|
|
||||||
gameRepository.updateGame(game)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import me.zobrist.tichucounter.ui.FragmentBase
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class TeamScores : Fragment() {
|
|
||||||
|
|
||||||
private val viewModel: TeamScoresViewModel by activityViewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
|
|
||||||
return ComposeView(requireContext()).apply {
|
|
||||||
// Dispose of the Composition when the view's LifecycleOwner
|
|
||||||
// is destroyed
|
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
|
||||||
setContent {
|
|
||||||
MaterialTheme {
|
|
||||||
TeamScoresView(viewModel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TeamScoresView(viewModel: TeamScoresViewModel) {
|
|
||||||
|
|
||||||
TeamScoresView(viewModel.scoreA, viewModel.scoreB)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TeamScoresView(scoreA: Int, scoreB: Int,){
|
|
||||||
Row() {
|
|
||||||
Text(
|
|
||||||
text = scoreA.toString(),
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
textAlign = TextAlign.Center)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = scoreB.toString(),
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
textAlign = TextAlign.Center)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
private fun TeamNamesView() {
|
|
||||||
TeamScoresView(10, 90)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package me.zobrist.tichucounter.ui.counter
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TeamScoresView(scoreA: Int, scoreB: Int) {
|
||||||
|
Row() {
|
||||||
|
Text(
|
||||||
|
text = scoreA.toString(),
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = scoreB.toString(),
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun TeamNamesView() {
|
||||||
|
TeamScoresView(10, 90)
|
||||||
|
}
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import me.zobrist.tichucounter.data.RoundDao
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@HiltViewModel
|
|
||||||
class TeamScoresViewModel @Inject constructor(private val roundDao: RoundDao) : ViewModel() {
|
|
||||||
|
|
||||||
var scoreA by mutableStateOf(0)
|
|
||||||
private set
|
|
||||||
|
|
||||||
var scoreB by mutableStateOf(0)
|
|
||||||
private set
|
|
||||||
|
|
||||||
init {
|
|
||||||
viewModelScope.launch {
|
|
||||||
|
|
||||||
roundDao.getRoundSumForActiveGame().collect { score ->
|
|
||||||
scoreA = score.scoreA
|
|
||||||
scoreB = score.scoreB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:visibility="visible"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/left"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:weightSum="2"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/right"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/teamNames"
|
|
||||||
android:name="me.zobrist.tichucounter.ui.counter.TeamNames"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:layout="@layout/fragment_team_names" />
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/teamScores"
|
|
||||||
android:name="me.zobrist.tichucounter.ui.counter.TeamScores"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/teamNames"
|
|
||||||
tools:layout="@layout/fragment_team_scores" />
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/scrollHistory"
|
|
||||||
android:name="me.zobrist.tichucounter.ui.counter.RoundList"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:clickable="false"
|
|
||||||
tools:layout="@layout/fragment_round_list" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/right"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="bottom"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/left">
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/keyboard"
|
|
||||||
android:name="me.zobrist.tichucounter.ui.counter.Keyboard"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
tools:layout="@layout/fragment_keyboard" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/drawer_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
tools:openDrawer="start">
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/app_bar_drawer"
|
|
||||||
layout="@layout/app_bar_drawer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<com.google.android.material.navigation.NavigationView
|
|
||||||
android:id="@+id/nav_view"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
app:headerLayout="@layout/nav_header_drawer"
|
|
||||||
app:menu="@menu/activity_main_drawer" />
|
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".MainActivity">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:theme="@style/AppTheme.AppBarOverlay">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:background="?attr/colorPrimary"
|
|
||||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<include layout="@layout/content_drawer" />
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
|
||||||
tools:showIn="@layout/app_bar_drawer">
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/nav_host_fragment_content_drawer"
|
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:defaultNavHost="true"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:navGraph="@navigation/mobile_navigation" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/teamNames"
|
|
||||||
android:name="me.zobrist.tichucounter.ui.counter.TeamNames"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:layout="@layout/fragment_team_names" />
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/teamScores"
|
|
||||||
android:name="me.zobrist.tichucounter.ui.counter.TeamScores"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/teamNames"
|
|
||||||
tools:layout="@layout/fragment_team_scores" />
|
|
||||||
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/dividerTop"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:background="?android:attr/listDivider"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/teamScores"
|
|
||||||
tools:layout_editor_absoluteY="50dp" />
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/scrollHistory"
|
|
||||||
android:name="me.zobrist.tichucounter.ui.counter.RoundList"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/dividerBottom"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/dividerTop"
|
|
||||||
tools:layout="@layout/fragment_round_list" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/dividerBottom"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:background="?android:attr/listDivider"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/keyboard"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/keyboard"
|
|
||||||
android:name="me.zobrist.tichucounter.ui.counter.Keyboard"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
tools:layout="@layout/fragment_keyboard" />
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/nav_header_height"
|
|
||||||
android:background="@drawable/side_nav_bar"
|
|
||||||
android:gravity="bottom"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.Dark">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:contentDescription="@string/nav_header_desc"
|
|
||||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
|
||||||
app:srcCompat="@mipmap/ic_launcher_round" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
|
||||||
android:text="@string/app_name"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/nav_header_subtitle" />
|
|
||||||
</LinearLayout>
|
|
||||||
Reference in New Issue
Block a user