This commit is contained in:
@@ -74,12 +74,16 @@ class KeyboardViewModel @Inject constructor(private val gameRepository: GameRepo
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun appendToFocusedScore(toAppend: String) {
|
fun appendToFocusedScore(toAppend: String) {
|
||||||
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
activeValue += toAppend
|
activeValue += toAppend
|
||||||
updateOtherScore()
|
updateOtherScore()
|
||||||
updateSubmitButton()
|
updateSubmitButton()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun negateActiveInput() {
|
fun negateActiveInput() {
|
||||||
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
activeValue = if (activeValue.contains("-")) {
|
activeValue = if (activeValue.contains("-")) {
|
||||||
activeValue.replace("-", "")
|
activeValue.replace("-", "")
|
||||||
} else {
|
} else {
|
||||||
@@ -90,6 +94,8 @@ class KeyboardViewModel @Inject constructor(private val gameRepository: GameRepo
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addToActiveInput(toAdd: Int) {
|
fun addToActiveInput(toAdd: Int) {
|
||||||
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
activeValue = try {
|
activeValue = try {
|
||||||
val temp = activeValue.toInt() + toAdd
|
val temp = activeValue.toInt() + toAdd
|
||||||
temp.toString()
|
temp.toString()
|
||||||
@@ -119,17 +125,17 @@ class KeyboardViewModel @Inject constructor(private val gameRepository: GameRepo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateOtherScore() {
|
private fun updateOtherScore() {
|
||||||
try {
|
inactiveValue = try {
|
||||||
val tichu = Tichu()
|
val tichu = Tichu()
|
||||||
val myScore = activeValue.toInt()
|
val myScore = activeValue.toInt()
|
||||||
val hisScore = tichu.calculateOtherScore(myScore)
|
val hisScore = tichu.calculateOtherScore(myScore)
|
||||||
if (tichu.isValidRound(myScore, hisScore)) {
|
if (tichu.isValidRound(myScore, hisScore)) {
|
||||||
inactiveValue = hisScore?.toString() ?: ""
|
hisScore?.toString() ?: ""
|
||||||
} else {
|
} else {
|
||||||
inactiveValue = ""
|
""
|
||||||
}
|
}
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
inactiveValue = ""
|
""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,41 +4,81 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.widget.doAfterTextChanged
|
import android.widget.EditText
|
||||||
import androidx.fragment.app.activityViewModels
|
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
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import me.zobrist.tichucounter.databinding.FragmentTeamNamesBinding
|
|
||||||
import me.zobrist.tichucounter.ui.FragmentBase
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class TeamNames : FragmentBase<FragmentTeamNamesBinding>() {
|
class TeamNames : Fragment() {
|
||||||
|
|
||||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentTeamNamesBinding
|
private val viewModel: TeamNamesViewModel by viewModels()
|
||||||
get() = FragmentTeamNamesBinding::inflate
|
|
||||||
|
|
||||||
private val viewModel: TeamNamesViewModel by activityViewModels()
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
return ComposeView(requireContext()).apply {
|
||||||
|
// Dispose of the Composition when the view's LifecycleOwner
|
||||||
binding.nameTeamA.doAfterTextChanged {
|
// is destroyed
|
||||||
viewModel.setNameA(binding.nameTeamA.text.toString())
|
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||||
}
|
setContent {
|
||||||
|
MaterialTheme {
|
||||||
binding.nameTeamB.doAfterTextChanged {
|
TeamNamesView(viewModel)
|
||||||
viewModel.setNameB(binding.nameTeamB.text.toString())
|
}
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.nameA.observe(viewLifecycleOwner) { value ->
|
|
||||||
if (value != binding.nameTeamA.text.toString()) {
|
|
||||||
binding.nameTeamA.setText(value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.nameB.observe(viewLifecycleOwner) { value ->
|
@Composable
|
||||||
if (value != binding.nameTeamB.text.toString()) {
|
private fun TeamNamesView(viewModel: TeamNamesViewModel) {
|
||||||
binding.nameTeamB.setText(value)
|
|
||||||
}
|
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", {}, {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
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.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
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.Game
|
||||||
import me.zobrist.tichucounter.data.GameDao
|
import me.zobrist.tichucounter.data.GameDao
|
||||||
import me.zobrist.tichucounter.repository.GameRepository
|
import me.zobrist.tichucounter.repository.GameRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -17,40 +21,35 @@ class TeamNamesViewModel @Inject constructor(
|
|||||||
) :
|
) :
|
||||||
ViewModel() {
|
ViewModel() {
|
||||||
|
|
||||||
private val _nameA: MutableLiveData<String> = MutableLiveData()
|
var nameA by mutableStateOf("")
|
||||||
private val _nameB: MutableLiveData<String> = MutableLiveData()
|
private set
|
||||||
|
|
||||||
val nameA: LiveData<String>
|
var nameB by mutableStateOf("")
|
||||||
get() {
|
private set
|
||||||
return _nameA
|
|
||||||
}
|
|
||||||
|
|
||||||
val nameB: LiveData<String>
|
|
||||||
get() {
|
|
||||||
return _nameB
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
gameDao.getActive().collect {
|
gameDao.getActive().collect {
|
||||||
_nameA.value = it?.nameA
|
if (it != null) {
|
||||||
_nameB.value = it?.nameB
|
nameA = it.nameA
|
||||||
|
nameB = it.nameB
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setNameA(name: String) {
|
fun updateNameA(value: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val game = gameRepository.activeGame
|
val game = gameRepository.activeGame
|
||||||
game.nameA = name
|
game.nameA = value
|
||||||
gameRepository.updateGame(game)
|
gameRepository.updateGame(game)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setNameB(name: String) {
|
fun updateNameB(value: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val game = gameRepository.activeGame
|
val game = gameRepository.activeGame
|
||||||
game.nameB = name
|
game.nameB = value
|
||||||
gameRepository.updateGame(game)
|
gameRepository.updateGame(game)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,27 +4,70 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
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 androidx.fragment.app.activityViewModels
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import me.zobrist.tichucounter.databinding.FragmentTeamScoresBinding
|
import me.zobrist.tichucounter.databinding.FragmentTeamScoresBinding
|
||||||
import me.zobrist.tichucounter.ui.FragmentBase
|
import me.zobrist.tichucounter.ui.FragmentBase
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class TeamScores : FragmentBase<FragmentTeamScoresBinding>() {
|
class TeamScores : Fragment() {
|
||||||
|
|
||||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentTeamScoresBinding
|
|
||||||
get() = FragmentTeamScoresBinding::inflate
|
|
||||||
|
|
||||||
private val viewModel: TeamScoresViewModel by activityViewModels()
|
private val viewModel: TeamScoresViewModel by activityViewModels()
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
|
||||||
viewModel.scoreA.observe(viewLifecycleOwner) {
|
return ComposeView(requireContext()).apply {
|
||||||
binding.scoreA.text = it?.toString() ?: ""
|
// Dispose of the Composition when the view's LifecycleOwner
|
||||||
}
|
// is destroyed
|
||||||
|
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||||
viewModel.scoreB.observe(viewLifecycleOwner) {
|
setContent {
|
||||||
binding.scoreB.text = it?.toString() ?: ""
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package me.zobrist.tichucounter.ui.counter
|
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.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -12,26 +15,20 @@ import javax.inject.Inject
|
|||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class TeamScoresViewModel @Inject constructor(private val roundDao: RoundDao) : ViewModel() {
|
class TeamScoresViewModel @Inject constructor(private val roundDao: RoundDao) : ViewModel() {
|
||||||
|
|
||||||
private var _scoreA: MutableLiveData<Int> = MutableLiveData()
|
var scoreA by mutableStateOf(0)
|
||||||
private var _scoreB: MutableLiveData<Int> = MutableLiveData()
|
private set
|
||||||
|
|
||||||
|
var scoreB by mutableStateOf(0)
|
||||||
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|
||||||
roundDao.getRoundSumForActiveGame().collect { score ->
|
roundDao.getRoundSumForActiveGame().collect { score ->
|
||||||
_scoreA.value = if (score?.scoreA != null) score.scoreA else 0
|
scoreA = score.scoreA
|
||||||
_scoreB.value = if (score?.scoreB != null) score.scoreB else 0
|
scoreB = score.scoreB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val scoreA: LiveData<Int>
|
|
||||||
get() {
|
|
||||||
return _scoreA
|
|
||||||
}
|
|
||||||
|
|
||||||
val scoreB: LiveData<Int>
|
|
||||||
get() {
|
|
||||||
return _scoreB
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.counter.TeamNames">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/viewNames"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/nameTeamA"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:autofillHints=""
|
|
||||||
android:gravity="center"
|
|
||||||
android:imeOptions="actionDone"
|
|
||||||
android:inputType="text"
|
|
||||||
android:selectAllOnFocus="true"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text="@string/team_a"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/nameTeamB"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:autofillHints=""
|
|
||||||
android:gravity="center"
|
|
||||||
android:imeOptions="actionDone"
|
|
||||||
android:inputType="text"
|
|
||||||
android:selectAllOnFocus="true"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text="@string/team_b"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.counter.TeamScores">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/viewScore"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/scoreA"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="0"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
tools:ignore="HardcodedText" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/scoreB"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="0"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
tools:ignore="HardcodedText" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
Reference in New Issue
Block a user