Style keyboard. Add Counter previerw.
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:
@@ -6,11 +6,15 @@ import androidx.compose.foundation.layout.Row
|
|||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import me.zobrist.tichucounter.data.Round
|
||||||
|
import me.zobrist.tichucounter.ui.AppTheme
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Counter(viewModel: CounterViewModel) {
|
fun Counter(viewModel: ICounterViewModel = PreviewViewModel()) {
|
||||||
|
|
||||||
var orientation by remember { mutableStateOf(Configuration.ORIENTATION_PORTRAIT) }
|
var orientation by remember { mutableStateOf(Configuration.ORIENTATION_PORTRAIT) }
|
||||||
orientation = LocalConfiguration.current.orientation
|
orientation = LocalConfiguration.current.orientation
|
||||||
@@ -25,7 +29,7 @@ fun Counter(viewModel: CounterViewModel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Landscape(viewModel: CounterViewModel) {
|
fun Landscape(viewModel: ICounterViewModel) {
|
||||||
Row {
|
Row {
|
||||||
Column(Modifier.weight(1f)) {
|
Column(Modifier.weight(1f)) {
|
||||||
TeamNamesView(
|
TeamNamesView(
|
||||||
@@ -65,7 +69,7 @@ fun Landscape(viewModel: CounterViewModel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Portrait(viewModel: CounterViewModel) {
|
fun Portrait(viewModel: ICounterViewModel) {
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
TeamNamesView(
|
TeamNamesView(
|
||||||
@@ -99,3 +103,70 @@ fun Portrait(viewModel: CounterViewModel) {
|
|||||||
) { viewModel.submitClicked() }
|
) { viewModel.submitClicked() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Preview(name = "Light Mode")
|
||||||
|
@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun CounterViewPreview() {
|
||||||
|
AppTheme {
|
||||||
|
Counter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class PreviewViewModel: ICounterViewModel {
|
||||||
|
override var roundScoreList: List<Round> = listOf(Round(1, 10, 90), Round(1,50,50), Round(1,70,30))
|
||||||
|
override var totalScoreA: Int = 350
|
||||||
|
override var totalScoreB: Int = 750
|
||||||
|
override var teamNameA: String = "Team A"
|
||||||
|
override var teamNameB: String = "Team B"
|
||||||
|
override var currentScoreA: String = ""
|
||||||
|
override var currentScoreB: String = "45"
|
||||||
|
override var enableSubmit: Boolean = false
|
||||||
|
override var isAFocused: Boolean = false
|
||||||
|
override var isBFocused: Boolean = false
|
||||||
|
override var requestFocusA: FocusRequester = FocusRequester()
|
||||||
|
override var activeValue: String = currentScoreA
|
||||||
|
override var inactiveValue: String = currentScoreB
|
||||||
|
|
||||||
|
override fun giveFocusToAIfNone() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateOtherScore() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isValidTichuRound(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateSubmitButton() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submitClicked() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun digitClicked(digit: String) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun negateClicked() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addSub100Clicked(toAdd: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deleteClicked() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateNameA(value: String) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateNameB(value: String) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateFocusStateA(state: Boolean) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateFocusStateB(state: Boolean) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,45 +15,67 @@ 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
|
||||||
|
|
||||||
|
interface ICounterViewModel {
|
||||||
|
var roundScoreList: List<Round>
|
||||||
|
var totalScoreA: Int
|
||||||
|
var totalScoreB: Int
|
||||||
|
var teamNameA: String
|
||||||
|
var teamNameB: String
|
||||||
|
var currentScoreA: String
|
||||||
|
var currentScoreB: String
|
||||||
|
var enableSubmit: Boolean
|
||||||
|
var isAFocused: Boolean
|
||||||
|
var isBFocused: Boolean
|
||||||
|
var requestFocusA: FocusRequester
|
||||||
|
var activeValue: String
|
||||||
|
var inactiveValue: String
|
||||||
|
|
||||||
|
fun giveFocusToAIfNone()
|
||||||
|
fun updateOtherScore()
|
||||||
|
fun isValidTichuRound(): Boolean
|
||||||
|
fun updateSubmitButton()
|
||||||
|
fun submitClicked()
|
||||||
|
fun digitClicked(digit: String)
|
||||||
|
fun negateClicked()
|
||||||
|
fun addSub100Clicked(toAdd: Int)
|
||||||
|
fun deleteClicked()
|
||||||
|
fun updateNameA(value: String)
|
||||||
|
fun updateNameB(value: String)
|
||||||
|
fun updateFocusStateA(state: Boolean)
|
||||||
|
fun updateFocusStateB(state: Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class CounterViewModel @Inject constructor(
|
class CounterViewModel @Inject constructor(
|
||||||
private val gameRepository: GameRepository,
|
private val gameRepository: GameRepository,
|
||||||
private val roundDao: RoundDao,
|
private val roundDao: RoundDao,
|
||||||
private val gameDao: GameDao
|
private val gameDao: GameDao
|
||||||
) :
|
) :
|
||||||
ViewModel() {
|
ViewModel(), ICounterViewModel {
|
||||||
|
|
||||||
var roundScoreList by mutableStateOf(emptyList<Round>())
|
override var roundScoreList by mutableStateOf(emptyList<Round>())
|
||||||
|
|
||||||
var totalScoreA by mutableStateOf(0)
|
override var totalScoreA by mutableStateOf(0)
|
||||||
private set
|
|
||||||
|
|
||||||
var totalScoreB by mutableStateOf(0)
|
override var totalScoreB by mutableStateOf(0)
|
||||||
private set
|
|
||||||
|
|
||||||
var teamNameA by mutableStateOf("")
|
override var teamNameA by mutableStateOf("")
|
||||||
private set
|
|
||||||
|
|
||||||
var teamNameB by mutableStateOf("")
|
override var teamNameB by mutableStateOf("")
|
||||||
private set
|
|
||||||
|
|
||||||
var currentScoreA by mutableStateOf("")
|
override var currentScoreA by mutableStateOf("")
|
||||||
private set
|
|
||||||
|
|
||||||
var currentScoreB by mutableStateOf("")
|
override var currentScoreB by mutableStateOf("")
|
||||||
private set
|
|
||||||
|
|
||||||
var enableSubmit by mutableStateOf(false)
|
override var enableSubmit by mutableStateOf(false)
|
||||||
private set
|
|
||||||
|
|
||||||
var isAFocused by mutableStateOf(false)
|
override var isAFocused by mutableStateOf(false)
|
||||||
|
|
||||||
var isBFocused by mutableStateOf(false)
|
override var isBFocused by mutableStateOf(false)
|
||||||
|
|
||||||
var requestFocusA by mutableStateOf(FocusRequester())
|
override var requestFocusA by mutableStateOf(FocusRequester())
|
||||||
private set
|
|
||||||
|
|
||||||
private var activeValue: String
|
override var activeValue: String
|
||||||
get() {
|
get() {
|
||||||
return if (isBFocused) {
|
return if (isBFocused) {
|
||||||
currentScoreB
|
currentScoreB
|
||||||
@@ -69,7 +91,7 @@ class CounterViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var inactiveValue: String
|
override var inactiveValue: String
|
||||||
get() {
|
get() {
|
||||||
return if (isAFocused) {
|
return if (isAFocused) {
|
||||||
currentScoreB
|
currentScoreB
|
||||||
@@ -109,13 +131,13 @@ class CounterViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun giveFocusToAIfNone() {
|
override fun giveFocusToAIfNone() {
|
||||||
if (!isAFocused && !isBFocused) {
|
if (!isAFocused && !isBFocused) {
|
||||||
requestFocusA.requestFocus()
|
requestFocusA.requestFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateOtherScore() {
|
override fun updateOtherScore() {
|
||||||
inactiveValue = try {
|
inactiveValue = try {
|
||||||
val tichu = Tichu()
|
val tichu = Tichu()
|
||||||
val myScore = activeValue.toInt()
|
val myScore = activeValue.toInt()
|
||||||
@@ -130,7 +152,7 @@ class CounterViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isValidTichuRound(): Boolean {
|
override fun isValidTichuRound(): Boolean {
|
||||||
return try {
|
return try {
|
||||||
val tichu = Tichu()
|
val tichu = Tichu()
|
||||||
tichu.isValidRound(currentScoreA.toInt(), currentScoreB.toInt())
|
tichu.isValidRound(currentScoreA.toInt(), currentScoreB.toInt())
|
||||||
@@ -139,11 +161,11 @@ class CounterViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSubmitButton() {
|
override fun updateSubmitButton() {
|
||||||
enableSubmit = isValidTichuRound()
|
enableSubmit = isValidTichuRound()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun submitClicked() {
|
override fun submitClicked() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
gameRepository.addRoundToActiveGame(currentScoreA.toInt(), currentScoreB.toInt())
|
gameRepository.addRoundToActiveGame(currentScoreA.toInt(), currentScoreB.toInt())
|
||||||
}
|
}
|
||||||
@@ -152,7 +174,7 @@ class CounterViewModel @Inject constructor(
|
|||||||
enableSubmit = false
|
enableSubmit = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun digitClicked(digit: String) {
|
override fun digitClicked(digit: String) {
|
||||||
giveFocusToAIfNone()
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
activeValue += digit
|
activeValue += digit
|
||||||
@@ -160,7 +182,7 @@ class CounterViewModel @Inject constructor(
|
|||||||
updateSubmitButton()
|
updateSubmitButton()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun negateClicked() {
|
override fun negateClicked() {
|
||||||
giveFocusToAIfNone()
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
activeValue = if (activeValue.contains("-")) {
|
activeValue = if (activeValue.contains("-")) {
|
||||||
@@ -172,7 +194,7 @@ class CounterViewModel @Inject constructor(
|
|||||||
updateSubmitButton()
|
updateSubmitButton()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addSub100Clicked(toAdd: Int) {
|
override fun addSub100Clicked(toAdd: Int) {
|
||||||
giveFocusToAIfNone()
|
giveFocusToAIfNone()
|
||||||
|
|
||||||
activeValue = try {
|
activeValue = try {
|
||||||
@@ -188,14 +210,15 @@ class CounterViewModel @Inject constructor(
|
|||||||
updateSubmitButton()
|
updateSubmitButton()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteClicked() {
|
override fun deleteClicked() {
|
||||||
if (activeValue != "") {
|
if (activeValue != "") {
|
||||||
activeValue = activeValue.dropLast(1)
|
activeValue = activeValue.dropLast(1)
|
||||||
}
|
}
|
||||||
updateOtherScore()
|
updateOtherScore()
|
||||||
|
updateSubmitButton()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateNameA(value: String) {
|
override fun updateNameA(value: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val game = gameRepository.activeGame
|
val game = gameRepository.activeGame
|
||||||
game.nameA = value
|
game.nameA = value
|
||||||
@@ -203,7 +226,7 @@ class CounterViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateNameB(value: String) {
|
override fun updateNameB(value: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val game = gameRepository.activeGame
|
val game = gameRepository.activeGame
|
||||||
game.nameB = value
|
game.nameB = value
|
||||||
@@ -211,11 +234,11 @@ class CounterViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateFocusStateA(state: Boolean) {
|
override fun updateFocusStateA(state: Boolean) {
|
||||||
isAFocused = state
|
isAFocused = state
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateFocusStateB(state: Boolean) {
|
override fun updateFocusStateB(state: Boolean) {
|
||||||
isBFocused = state
|
isBFocused = state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,21 +15,24 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.platform.SoftwareKeyboardController
|
import androidx.compose.ui.platform.SoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.constraintlayout.helper.widget.MotionPlaceholder
|
||||||
import me.zobrist.tichucounter.R
|
import me.zobrist.tichucounter.R
|
||||||
import me.zobrist.tichucounter.ui.AppTheme
|
import me.zobrist.tichucounter.ui.AppTheme
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun KeyboardView(
|
fun KeyboardView(
|
||||||
scoreA: String,
|
scoreA: String,
|
||||||
scoreB: String,
|
scoreB: String,
|
||||||
requestFocusA: FocusRequester,
|
requestFocus: FocusRequester,
|
||||||
enableSubmit: Boolean,
|
enableSubmit: Boolean,
|
||||||
updateFocusStateA: (Boolean) -> Unit,
|
updateFocusStateA: (Boolean) -> Unit,
|
||||||
updateFocusStateB: (Boolean) -> Unit,
|
updateFocusStateB: (Boolean) -> Unit,
|
||||||
@@ -44,139 +47,156 @@ fun KeyboardView(
|
|||||||
Column {
|
Column {
|
||||||
Row {
|
Row {
|
||||||
Column(Modifier.weight(1f)) {
|
Column(Modifier.weight(1f)) {
|
||||||
|
|
||||||
CenteredTextField(
|
CenteredTextField(
|
||||||
scoreA,
|
scoreA,
|
||||||
keyboardController,
|
"0",
|
||||||
requestFocusA
|
Modifier
|
||||||
) {
|
.focusRequester(requestFocus)
|
||||||
updateFocusStateA(it)
|
.onFocusChanged {
|
||||||
}
|
keyboardController?.hide()
|
||||||
|
updateFocusStateA(it.isFocused)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
Column(Modifier.weight(1f)) {
|
Column(Modifier.weight(1f)) {
|
||||||
|
|
||||||
CenteredTextField(
|
CenteredTextField(
|
||||||
scoreB,
|
scoreB,
|
||||||
keyboardController,
|
"0",
|
||||||
null
|
Modifier
|
||||||
) {
|
.onFocusChanged {
|
||||||
updateFocusStateB(it)
|
keyboardController?.hide()
|
||||||
|
updateFocusStateB(it.isFocused)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardTextButton("1") {
|
||||||
|
digitClicked("1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardTextButton("2") {
|
||||||
|
digitClicked("2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardTextButton("3") {
|
||||||
|
digitClicked("3")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardTextButton("+100") {
|
||||||
|
addSub100Clicked(100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardTextButton("4") {
|
||||||
|
digitClicked("4")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardTextButton("5") {
|
||||||
|
digitClicked("5")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardTextButton("6") {
|
||||||
|
digitClicked("6")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardTextButton("-100") {
|
||||||
|
addSub100Clicked(-100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
TextButton(
|
Column(Modifier.weight(1f)) {
|
||||||
onClick = { digitClicked("1") },
|
KeyboardTextButton("7") {
|
||||||
modifier = Modifier.weight(1F)
|
digitClicked("7")
|
||||||
) { Text("1") }
|
}
|
||||||
TextButton(
|
}
|
||||||
onClick = { digitClicked("2") },
|
Column(Modifier.weight(1f)) {
|
||||||
modifier = Modifier.weight(1F)
|
KeyboardTextButton("8") {
|
||||||
) { Text("2") }
|
digitClicked("8")
|
||||||
TextButton(
|
}
|
||||||
onClick = { digitClicked("3") },
|
}
|
||||||
modifier = Modifier.weight(1F)
|
Column(Modifier.weight(1f)) {
|
||||||
) { Text("3") }
|
KeyboardTextButton("9") {
|
||||||
TextButton(
|
digitClicked("9")
|
||||||
onClick = { addSub100Clicked(100) },
|
}
|
||||||
modifier = Modifier.weight(1F)
|
}
|
||||||
) { Text("+100") }
|
Column(Modifier.weight(1f)) {
|
||||||
|
KeyboardIconButton(Icons.Outlined.Backspace) {
|
||||||
}
|
deleteClicked()
|
||||||
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.back),
|
|
||||||
tint = MaterialTheme.colorScheme.primary
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
TextButton(
|
Column(Modifier.weight(1f)) {
|
||||||
onClick = { negateClicked() },
|
KeyboardTextButton("+/-") {
|
||||||
modifier = Modifier.weight(1F)
|
negateClicked()
|
||||||
) { Text("+/-") }
|
}
|
||||||
TextButton(
|
}
|
||||||
onClick = { digitClicked("0") },
|
Column(Modifier.weight(1f)) {
|
||||||
modifier = Modifier.weight(1F)
|
KeyboardTextButton("0") {
|
||||||
) { Text("0") }
|
digitClicked("0")
|
||||||
Spacer(modifier = Modifier.weight(1F))
|
}
|
||||||
IconButton(
|
}
|
||||||
onClick = { submitClicked() },
|
Column(Modifier.weight(2f)) {
|
||||||
modifier = Modifier.weight(1F),
|
KeyboardIconButton(Icons.Outlined.Check, enableSubmit) {
|
||||||
enabled = enableSubmit
|
submitClicked()
|
||||||
) {
|
}
|
||||||
Icon(
|
|
||||||
Icons.Outlined.Check,
|
|
||||||
stringResource(R.string.submit),
|
|
||||||
tint = MaterialTheme.colorScheme.primary
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class)
|
@Composable
|
||||||
|
fun KeyboardTextButton(text: String, onClicked: () -> Unit) {
|
||||||
|
ElevatedButton(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onClick = { onClicked() },
|
||||||
|
) { Text(text) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun KeyboardIconButton(icon: ImageVector, enabled: Boolean = true, onClicked: () -> Unit) {
|
||||||
|
|
||||||
|
ElevatedButton(
|
||||||
|
onClick = { onClicked() },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
enabled = enabled,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CenteredTextField(
|
fun CenteredTextField(
|
||||||
value: String,
|
value: String,
|
||||||
keyboardController: SoftwareKeyboardController?,
|
placeholder: String,
|
||||||
focusRequester: FocusRequester?,
|
modifier: Modifier,
|
||||||
updateFocusState: (Boolean) -> Unit
|
|
||||||
) {
|
) {
|
||||||
var modifier = Modifier
|
|
||||||
.onFocusChanged {
|
|
||||||
keyboardController?.hide()
|
|
||||||
updateFocusState(it.isFocused)
|
|
||||||
}
|
|
||||||
.fillMaxWidth()
|
|
||||||
|
|
||||||
if (focusRequester != null) {
|
|
||||||
modifier.focusRequester(focusRequester)
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
value = value,
|
value = value,
|
||||||
onValueChange = { },
|
onValueChange = { },
|
||||||
placeholder = {
|
placeholder = {
|
||||||
Text(
|
Text(
|
||||||
"0",
|
placeholder,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
@@ -184,12 +204,11 @@ fun CenteredTextField(
|
|||||||
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
|
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
readOnly = true,
|
readOnly = true,
|
||||||
modifier = modifier
|
modifier = modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
|
||||||
@Preview(name = "Light Mode")
|
@Preview(name = "Light Mode")
|
||||||
@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
|
@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -210,6 +229,4 @@ fun KeyboardViewPreview() {
|
|||||||
{})
|
{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ package me.zobrist.tichucounter.ui.counter
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.ElevatedCard
|
import androidx.compose.material3.ElevatedCard
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
@@ -21,18 +22,18 @@ fun TeamScoresView(scoreA: Int, scoreB: Int) {
|
|||||||
ElevatedCard() {
|
ElevatedCard() {
|
||||||
Row() {
|
Row() {
|
||||||
Text(
|
Text(
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
text = scoreA.toString(),
|
text = scoreA.toString(),
|
||||||
modifier = Modifier.weight(5f),
|
modifier = Modifier.weight(5f).padding(6.dp),
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
text = scoreB.toString(),
|
text = scoreB.toString(),
|
||||||
modifier = Modifier.weight(5f),
|
modifier = Modifier.weight(5f).padding(6.dp),
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user