Factor the way EditText are handled

hh
Laurent 6 years ago
parent 7411aa460b
commit d5bc0309aa
  1. 5
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt
  2. 5
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/PlayerSetup.kt
  3. 245
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt
  4. 9
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt
  5. 59
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/CardsRow.kt
  6. 17
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt
  7. 63
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/HandHistoryViewModel.kt
  8. 29
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/PlayerSetupRow.kt

@ -11,11 +11,12 @@ import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.interfaces.TimeFilterable import net.pokeranalytics.android.model.interfaces.TimeFilterable
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.modules.handhistory.views.CardHolder import net.pokeranalytics.android.ui.modules.handhistory.model.CardHolder
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import java.util.* import java.util.*
open class HandHistory : RealmObject(), RowRepresentable, Identifiable, Filterable, TimeFilterable, CardHolder { open class HandHistory : RealmObject(), RowRepresentable, Identifiable, Filterable, TimeFilterable,
CardHolder {
@PrimaryKey @PrimaryKey
override var id = UUID.randomUUID().toString() override var id = UUID.randomUUID().toString()

@ -3,9 +3,10 @@ package net.pokeranalytics.android.model.realm.handhistory
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
import net.pokeranalytics.android.model.realm.Player import net.pokeranalytics.android.model.realm.Player
import net.pokeranalytics.android.ui.modules.handhistory.views.CardHolder import net.pokeranalytics.android.ui.modules.handhistory.model.CardHolder
open class PlayerSetup : RealmObject(), CardHolder { open class PlayerSetup : RealmObject(),
CardHolder {
/*** /***
* The player * The player

@ -13,6 +13,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import kotlinx.android.synthetic.main.row_hand_action.view.* import kotlinx.android.synthetic.main.row_hand_action.view.*
import kotlinx.android.synthetic.main.row_hand_cards.view.*
import kotlinx.android.synthetic.main.row_hhsettings_blinds.view.* import kotlinx.android.synthetic.main.row_hhsettings_blinds.view.*
import kotlinx.android.synthetic.main.row_hhsettings_player_setup.view.* import kotlinx.android.synthetic.main.row_hhsettings_player_setup.view.*
import kotlinx.android.synthetic.main.row_hhsettings_straddle.view.* import kotlinx.android.synthetic.main.row_hhsettings_straddle.view.*
@ -21,7 +22,6 @@ import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.handhistory.Position import net.pokeranalytics.android.model.handhistory.Position
import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.model.realm.handhistory.formatted
import net.pokeranalytics.android.ui.adapter.BindableHolder import net.pokeranalytics.android.ui.adapter.BindableHolder
import net.pokeranalytics.android.ui.adapter.RecyclerAdapter import net.pokeranalytics.android.ui.adapter.RecyclerAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
@ -29,13 +29,10 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.extensions.px import net.pokeranalytics.android.ui.extensions.px
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
import net.pokeranalytics.android.ui.modules.handhistory.model.* import net.pokeranalytics.android.ui.modules.handhistory.model.*
import net.pokeranalytics.android.ui.modules.handhistory.views.PlayerCardsRow
import net.pokeranalytics.android.ui.modules.handhistory.views.PositionAdapter import net.pokeranalytics.android.ui.modules.handhistory.views.PositionAdapter
import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardsRow
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.holder.RowViewHolder import net.pokeranalytics.android.ui.view.holder.RowViewHolder
import net.pokeranalytics.android.ui.view.rowrepresentable.ViewIdentifier import net.pokeranalytics.android.ui.view.rowrepresentable.ViewIdentifier
import net.pokeranalytics.android.util.extensions.formatted
import timber.log.Timber import timber.log.Timber
@ -70,7 +67,7 @@ enum class HandRowType(var layoutRes: Int) : ViewIdentifier, RowRepresentable, H
} }
} }
override fun keyboardForTag(tag: Int): HHKeyboard { override fun keyboardForTag(tag: Int): HHKeyboard? {
return when (this) { return when (this) {
BLINDS -> HHKeyboard.AMOUNT BLINDS -> HHKeyboard.AMOUNT
else -> throw PAIllegalStateException("unmanaged tag $tag") else -> throw PAIllegalStateException("unmanaged tag $tag")
@ -193,7 +190,30 @@ class HandHistoryAdapter(
this.currentPosition = position this.currentPosition = position
} }
protected fun toggleFocus(editText: EditText, focused: Boolean) { protected fun configureEditTexts(index: Int, position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
this.configureEditTexts(index..index, position, row, adapter)
}
protected fun configureEditTexts(range: IntRange, position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
range.forEach { tag ->
val string = adapter.dataSource.stringForRow(row, itemView.context, tag)
// Text
val editText = itemView.findViewWithTag<EditText>(tag) ?: throw PAIllegalStateException("Edit Text not found for tag: $tag, class: $this")
editText.setText(string)
// Focus
val selected = adapter.dataSource.isSelected(position, row, tag)
toggleFocus(editText, selected)
// Background
editText.setBackgroundColor(color(selected))
}
}
private fun toggleFocus(editText: EditText, focused: Boolean) {
if (focused) { if (focused) {
editText.requestFocus() editText.requestFocus()
} else { } else {
@ -202,41 +222,41 @@ class HandHistoryAdapter(
} }
open fun editTextForTag(tag: Int) : EditText { open fun editTextForTag(tag: Int) : EditText {
throw PAIllegalStateException("Should overriden by class : $this") return itemView.findViewWithTag(tag)
// throw PAIllegalStateException("Field at tag: $tag requires to return an EditText in order to connect the keyboard to it. Should be overridden by class : $this")
} }
} }
inner class RowHandBlinds(itemView: View) : RowHandHolder(itemView) { inner class RowHandBlinds(itemView: View) : RowHandHolder(itemView) {
init {
itemView.smallBlindEditText.tag = 0
itemView.bigBlindEditText.tag = 1
itemView.anteEditText.tag = 2
}
// sb, bb, ante, bb ante // sb, bb, ante, bb ante
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) { override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
super.onBind(position, row, adapter) super.onBind(position, row, adapter)
itemView.smallBlindEditText.setText(adapter.dataSource.stringForRow(row, itemView.context, 0)) configureEditTexts(0..2, position, row, adapter)
itemView.bigBlindEditText.setText(adapter.dataSource.stringForRow(row, itemView.context, 1))
itemView.anteEditText.setText(adapter.dataSource.stringForRow(row, itemView.context, 2))
itemView.bbAnteSwitch.isChecked = adapter.dataSource.isSelected(position, row, 0)
val sbSelected = adapter.dataSource.isSelected(position, row, 0)
toggleFocus(itemView.smallBlindEditText, sbSelected)
val bbSelected = adapter.dataSource.isSelected(position, row, 1) // itemView.smallBlindEditText.setText(adapter.dataSource.stringForRow(row, itemView.context, 0))
toggleFocus(itemView.bigBlindEditText, bbSelected) // itemView.bigBlindEditText.setText(adapter.dataSource.stringForRow(row, itemView.context, 1))
// itemView.anteEditText.setText(adapter.dataSource.stringForRow(row, itemView.context, 2))
// itemView.bbAnteSwitch.isChecked = adapter.dataSource.isSelected(position, row, 0)
//
// val sbSelected = adapter.dataSource.isSelected(position, row, 0)
// toggleFocus(itemView.smallBlindEditText, sbSelected)
//
// val bbSelected = adapter.dataSource.isSelected(position, row, 1)
// toggleFocus(itemView.bigBlindEditText, bbSelected)
//
// val anteSelected = adapter.dataSource.isSelected(position, row, 2)
// toggleFocus(itemView.anteEditText, anteSelected)
val anteSelected = adapter.dataSource.isSelected(position, row, 2)
toggleFocus(itemView.anteEditText, anteSelected)
}
override fun editTextForTag(tag: Int): EditText {
return when (tag) {
0 -> itemView.smallBlindEditText
1 -> itemView.bigBlindEditText
2 -> itemView.anteEditText
else -> throw PAIllegalStateException("unmanaged tag $tag")
}
} }
} }
@ -271,9 +291,7 @@ class HandHistoryAdapter(
itemView.positionsChipGroup.addView(chip) itemView.positionsChipGroup.addView(chip)
} }
} }
} }
/** /**
@ -282,6 +300,9 @@ class HandHistoryAdapter(
inner class RowHandAction(itemView: View) : RowHandHolder(itemView) { inner class RowHandAction(itemView: View) : RowHandHolder(itemView) {
init { init {
itemView.actionButton.tag = ComputedAction.Tag.ACTION.ordinal
itemView.amountEditText.tag = ComputedAction.Tag.AMOUNT.ordinal
// Action // Action
itemView.findViewById<Button>(R.id.actionButton)?.let { actionButton -> itemView.findViewById<Button>(R.id.actionButton)?.let { actionButton ->
actionButton.setOnClickListener { actionButton.setOnClickListener {
@ -316,9 +337,9 @@ class HandHistoryAdapter(
} }
} }
override fun editTextForTag(tag: Int): EditText { // override fun editTextForTag(tag: Int): EditText {
return itemView.amountEditText // return itemView.amountEditText
} // }
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) { override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
super.onBind(position, row, adapter) super.onBind(position, row, adapter)
@ -334,9 +355,7 @@ class HandHistoryAdapter(
itemView.findViewById<Button>(R.id.actionButton)?.let { actionButton -> itemView.findViewById<Button>(R.id.actionButton)?.let { actionButton ->
actionButton.isEnabled = computedAction.actionTypeCanBeEdited actionButton.isEnabled = computedAction.actionTypeCanBeEdited
val tag = HHKeyboard.ACTION.ordinal val selected = adapter.dataSource.isSelected(position, row, actionButton.tag as Int)
val selected = adapter.dataSource.isSelected(position, row, tag)
actionButton.backgroundTintList = ColorStateList.valueOf(color(selected)) actionButton.backgroundTintList = ColorStateList.valueOf(color(selected))
computedAction.action.type?.resId?.let { computedAction.action.type?.resId?.let {
@ -351,22 +370,24 @@ class HandHistoryAdapter(
itemView.findViewById<EditText>(R.id.amountEditText)?.let { amountEditText -> itemView.findViewById<EditText>(R.id.amountEditText)?.let { amountEditText ->
amountEditText.isEnabled = computedAction.amountCanBeEdited amountEditText.isEnabled = computedAction.amountCanBeEdited
val tag = HHKeyboard.AMOUNT.ordinal val tag = amountEditText.tag as Int
val selected = adapter.dataSource.isSelected(position, row, tag) val selected = adapter.dataSource.isSelected(position, row, tag)
amountEditText.setBackgroundColor(color(selected)) // amountEditText.setBackgroundColor(color(selected))
// Useful to have the cursor disappear when the keyboard is closed // Useful to have the cursor disappear when the keyboard is closed
amountEditText.isFocusable = selected && computedAction.amountCanBeEdited amountEditText.isFocusable = selected && computedAction.amountCanBeEdited
amountEditText.isFocusableInTouchMode = selected && computedAction.amountCanBeEdited amountEditText.isFocusableInTouchMode = selected && computedAction.amountCanBeEdited
amountEditText.setText(computedAction.action.formattedAmount) configureEditTexts(tag, position, row, adapter)
if (selected) {
amountEditText.requestFocus() // amountEditText.setText(computedAction.action.formattedAmount)
} else { //
amountEditText.clearFocus() // if (selected) {
} // amountEditText.requestFocus()
// } else {
// amountEditText.clearFocus()
// }
Timber.d("Amount at $position is selected: $selected, focusable = ${amountEditText.isFocusable}, isFocusableInTouchMode = ${amountEditText.isFocusableInTouchMode}, hasFocus = ${amountEditText.hasFocus()}, enabled = ${amountEditText.isEnabled}") Timber.d("Amount at $position is selected: $selected, focusable = ${amountEditText.isFocusable}, isFocusableInTouchMode = ${amountEditText.isFocusableInTouchMode}, hasFocus = ${amountEditText.hasFocus()}, enabled = ${amountEditText.isEnabled}")
} }
@ -382,6 +403,10 @@ class HandHistoryAdapter(
init { init {
itemView.flopEditText.tag = Street.FLOP.ordinal
itemView.turnEditText.tag = Street.TURN.ordinal
itemView.riverEditText.tag = Street.RIVER.ordinal
// Flop // Flop
itemView.findViewById<EditText>(R.id.flopEditText)?.let { flopEditText -> itemView.findViewById<EditText>(R.id.flopEditText)?.let { flopEditText ->
@ -411,17 +436,19 @@ class HandHistoryAdapter(
val streetCardView = row as StreetCardsRow val streetCardView = row as StreetCardsRow
val street = streetCardView.street val street = streetCardView.street
configureEditTexts(0..2, position, row, adapter)
itemView.findViewById<EditText>(R.id.flopEditText)?.let { flopEditText -> itemView.findViewById<EditText>(R.id.flopEditText)?.let { flopEditText ->
flopEditText.isFocusable = (street == Street.FLOP) flopEditText.isFocusable = (street == Street.FLOP)
flopEditText.isVisible = true flopEditText.isVisible = true
val flop = streetCardView.cardHolder?.cards?.take(3)
val text = flop?.formatted(itemView.context)
flopEditText.setText(text)
val selected = adapter.dataSource.isSelected(position, row, Street.FLOP.ordinal) // val flop = streetCardView.cardHolder?.cards?.take(3)
toggleFocus(flopEditText, selected) // val text = flop?.formatted(itemView.context)
// flopEditText.setText(text)
//
// val selected = adapter.dataSource.isSelected(position, row, Street.FLOP.ordinal)
// toggleFocus(flopEditText, selected)
} }
@ -429,30 +456,30 @@ class HandHistoryAdapter(
// turnEditText.isVisible = streetCardView.street.ordinal >= Street.TURN.ordinal // turnEditText.isVisible = streetCardView.street.ordinal >= Street.TURN.ordinal
turnEditText.isFocusable = (street == Street.TURN) turnEditText.isFocusable = (street == Street.TURN)
if (streetCardView.cardCount > 3) { // if (streetCardView.cardCount > 3) {
val text = streetCardView.cardAtIndex(3)?.formatted(itemView.context) // val text = streetCardView.cardAtIndex(3)?.formatted(itemView.context)
turnEditText.setText(text) // turnEditText.setText(text)
} else { // } else {
turnEditText.text = null // turnEditText.text = null
} // }
//
val selected = adapter.dataSource.isSelected(position, row, Street.TURN.ordinal) // val selected = adapter.dataSource.isSelected(position, row, Street.TURN.ordinal)
toggleFocus(turnEditText, selected) // toggleFocus(turnEditText, selected)
} }
itemView.findViewById<EditText>(R.id.riverEditText)?.let { riverEditText -> itemView.findViewById<EditText>(R.id.riverEditText)?.let { riverEditText ->
// riverEditText.isVisible = streetCardView.street.ordinal >= Street.RIVER.ordinal // riverEditText.isVisible = streetCardView.street.ordinal >= Street.RIVER.ordinal
riverEditText.isFocusable = (street == Street.RIVER) riverEditText.isFocusable = (street == Street.RIVER)
if (streetCardView.cardCount > 4) { // if (streetCardView.cardCount > 4) {
val text = streetCardView.cardAtIndex(4)?.formatted(itemView.context) // val text = streetCardView.cardAtIndex(4)?.formatted(itemView.context)
riverEditText.setText(text) // riverEditText.setText(text)
} else { // } else {
riverEditText.text = null // riverEditText.text = null
} // }
//
val selected = adapter.dataSource.isSelected(position, row, Street.RIVER.ordinal) // val selected = adapter.dataSource.isSelected(position, row, Street.RIVER.ordinal)
toggleFocus(riverEditText, selected) // toggleFocus(riverEditText, selected)
} }
} }
@ -465,13 +492,13 @@ class HandHistoryAdapter(
*/ */
inner class RowHandPlayerSummary(itemView: View) : RowHandHolder(itemView) { inner class RowHandPlayerSummary(itemView: View) : RowHandHolder(itemView) {
private val CARDS_TAG = 0
init { init {
// Cards // Cards
itemView.findViewById<EditText>(R.id.cardsEditText)?.let { cardsEditText -> itemView.findViewById<EditText>(R.id.cardsEditText)?.let { cardsEditText ->
cardsEditText.tag = PlayerCardsRow.Tag.CARDS.ordinal
cardsEditText.isFocusableInTouchMode = true cardsEditText.isFocusableInTouchMode = true
cardsEditText.setOnTouchListener { _, event -> cardsEditText.setOnTouchListener { _, event ->
@ -483,7 +510,7 @@ class HandHistoryAdapter(
cardsEditText.requestFocus() cardsEditText.requestFocus()
editTextSelected(cardsEditText, true, CARDS_TAG) editTextSelected(cardsEditText, true, PlayerCardsRow.Tag.CARDS.ordinal)
} }
return@setOnTouchListener true return@setOnTouchListener true
} }
@ -499,23 +526,25 @@ class HandHistoryAdapter(
// Position // Position
itemView.findViewById<Button>(R.id.positionButton)?.let { positionButton -> itemView.findViewById<Button>(R.id.positionButton)?.let { positionButton ->
positionButton.text = playerCardView.position.value positionButton.text = playerCardView.position?.value ?: throw PAIllegalStateException("Should not happen")
} }
// Amount // Amount
itemView.findViewById<EditText>(R.id.cardsEditText)?.let { cardsEditText -> itemView.findViewById<EditText>(R.id.cardsEditText)?.let { cardsEditText ->
val selected = adapter.dataSource.isSelected(position, row, CARDS_TAG) val selected = adapter.dataSource.isSelected(position, row, PlayerCardsRow.Tag.CARDS.ordinal)
// Both are required, otherwise requestFocus() fails // Both are required, otherwise requestFocus() fails
cardsEditText.isFocusable = selected cardsEditText.isFocusable = selected
cardsEditText.isFocusableInTouchMode = selected cardsEditText.isFocusableInTouchMode = selected
Timber.d("cardsEditText at $position is selected: $selected, focusable = ${cardsEditText.isFocusable}, isFocusableInTouchMode = ${cardsEditText.isFocusableInTouchMode}, hasFocus = ${cardsEditText.hasFocus()}, enabled = ${cardsEditText.isEnabled}") configureEditTexts(PlayerCardsRow.Tag.CARDS.ordinal, position, row, adapter)
cardsEditText.setBackgroundColor(color(selected))
cardsEditText.setText(playerCardView.cardHolder?.cards?.formatted(itemView.context)) // Timber.d("cardsEditText at $position is selected: $selected, focusable = ${cardsEditText.isFocusable}, isFocusableInTouchMode = ${cardsEditText.isFocusableInTouchMode}, hasFocus = ${cardsEditText.hasFocus()}, enabled = ${cardsEditText.isEnabled}")
toggleFocus(cardsEditText, selected) // cardsEditText.setBackgroundColor(color(selected))
//
// cardsEditText.setText(playerCardView.cardHolder?.cards?.formatted(itemView.context))
// toggleFocus(cardsEditText, selected)
} }
} }
} }
@ -527,6 +556,9 @@ class HandHistoryAdapter(
init { init {
itemView.handEditText.tag = PlayerSetupRow.Tag.CARDS.ordinal
itemView.stackEditText.tag = PlayerSetupRow.Tag.STACK.ordinal
// Position Recycler // Position Recycler
val positionViewManager = LinearLayoutManager(itemView.context, RecyclerView.HORIZONTAL, false) val positionViewManager = LinearLayoutManager(itemView.context, RecyclerView.HORIZONTAL, false)
@ -536,12 +568,34 @@ class HandHistoryAdapter(
adapter = positionAdapter adapter = positionAdapter
} }
itemView.findViewById<EditText>(R.id.stackEditText)?.let { stackEditText ->
stackEditText.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL
stackEditText.isFocusableInTouchMode = true
stackEditText.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_UP) {
// Both are required, otherwise requestFocus() fails
stackEditText.isFocusable = true
stackEditText.isFocusableInTouchMode = true
stackEditText.requestFocus()
editTextSelected(stackEditText, true, stackEditText.tag as Int)
}
return@setOnTouchListener true
}
}
} }
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) { override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
super.onBind(position, row, adapter) super.onBind(position, row, adapter)
val setup = row as PlayerSetupRowRepresentable val setup = row as PlayerSetupRow
val state = setup.state val state = setup.state
this.delegate = adapter.delegate this.delegate = adapter.delegate
@ -549,7 +603,7 @@ class HandHistoryAdapter(
itemView.title.text = setup.title(itemView.context) itemView.title.text = setup.title(itemView.context)
// Position recycler // Position recycler
val visibility = if (state == PlayerSetupRowRepresentable.State.SETUP_ONLY) View.GONE else View.VISIBLE val visibility = if (state == PlayerSetupRow.State.SETUP_ONLY) View.GONE else View.VISIBLE
itemView.positionRecyclerView.visibility = visibility itemView.positionRecyclerView.visibility = visibility
this.positionAdapter.positions = adapter.dataSource.contentForRow(row, itemView.context, Position::class) this.positionAdapter.positions = adapter.dataSource.contentForRow(row, itemView.context, Position::class)
@ -565,21 +619,25 @@ class HandHistoryAdapter(
itemView.positionRecyclerView.visibility = View.VISIBLE itemView.positionRecyclerView.visibility = View.VISIBLE
itemView.posButton.backgroundTintList = ColorStateList.valueOf(color(true)) itemView.posButton.backgroundTintList = ColorStateList.valueOf(color(true))
} }
val positionSelected = adapter.dataSource.isSelected(position, row, PlayerSetupRowRepresentable.Tag.POSITION.ordinal) val positionSelected = adapter.dataSource.isSelected(position, row, PlayerSetupRow.Tag.POSITION.ordinal)
itemView.posButton.backgroundTintList = ColorStateList.valueOf(color(positionSelected)) itemView.posButton.backgroundTintList = ColorStateList.valueOf(color(positionSelected))
// Settings // Settings
itemView.settings_container.visibility = if (state == PlayerSetupRowRepresentable.State.POSITIONS_ONLY) View.GONE else View.VISIBLE itemView.settings_container.visibility = if (state == PlayerSetupRow.State.POSITIONS_ONLY) View.GONE else View.VISIBLE
// Hand configureEditTexts(1..2, position, row, adapter)
itemView.handEditText.setText(setup.playerSetup?.cards?.formatted(itemView.context))
val handSelected = adapter.dataSource.isSelected(position, row, PlayerSetupRowRepresentable.Tag.CARDS.ordinal)
itemView.handEditText.setBackgroundColor(color(handSelected))
// Stack // Hand
itemView.stackEditText.setText(setup.playerSetup?.stack?.formatted()) // itemView.handEditText.setText(setup.playerSetup?.cards?.formatted(itemView.context))
val stackSelected = adapter.dataSource.isSelected(position, row, PlayerSetupRowRepresentable.Tag.STACK.ordinal) // val handSelected = adapter.dataSource.isSelected(position, row, PlayerSetupRow.Tag.CARDS.ordinal)
itemView.stackEditText.setBackgroundColor(color(stackSelected)) // itemView.handEditText.setBackgroundColor(color(handSelected))
// toggleFocus(itemView.handEditText, handSelected)
//
// // Stack
// itemView.stackEditText.setText(setup.playerSetup?.stack?.formatted())
// val stackSelected = adapter.dataSource.isSelected(position, row, PlayerSetupRow.Tag.STACK.ordinal)
// itemView.stackEditText.setBackgroundColor(color(stackSelected))
// toggleFocus(itemView.stackEditText, stackSelected)
// itemView.handEditText.setText(adapter.dataSource.stringForRow(row, itemView.context, 0)) // itemView.handEditText.setText(adapter.dataSource.stringForRow(row, itemView.context, 0))
@ -587,6 +645,13 @@ class HandHistoryAdapter(
} }
// override fun editTextForTag(tag: Int): EditText {
// return when (tag) {
// PlayerSetupRow.Tag.STACK.ordinal -> itemView.stackEditText
// else -> throw PAIllegalStateException("unmanaged tag $tag")
// }
// }
} }
} }

@ -120,7 +120,12 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
} }
else -> {} else -> {}
} }
this.keyboard.show(keyboard)
keyboard?.let {
this.keyboard.show(it)
} ?: run {
this.keyboard.hide()
}
} ?: run { } ?: run {
this.keyboard.hide() this.keyboard.hide()
@ -249,7 +254,7 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
is StraddleRowRepresentable -> { is StraddleRowRepresentable -> {
this.model.changeStraddleSelection(value as LinkedHashSet<Position>) this.model.changeStraddleSelection(value as LinkedHashSet<Position>)
} }
is PlayerSetupRowRepresentable -> { is PlayerSetupRow -> {
when (value) { when (value) {
is Int -> { is Int -> {
this.model.setPlayerSetupPosition(row, value) this.model.setPlayerSetupPosition(row, value)

@ -1,4 +1,4 @@
package net.pokeranalytics.android.ui.modules.handhistory.views package net.pokeranalytics.android.ui.modules.handhistory.model
import io.realm.Realm import io.realm.Realm
import io.realm.RealmList import io.realm.RealmList
@ -8,27 +8,28 @@ import net.pokeranalytics.android.model.handhistory.Position
import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.Card import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.model.realm.handhistory.PlayerSetup
import net.pokeranalytics.android.ui.modules.handhistory.HandRowType import net.pokeranalytics.android.ui.modules.handhistory.HandRowType
import net.pokeranalytics.android.ui.modules.handhistory.model.HHKeyboard
import net.pokeranalytics.android.ui.modules.handhistory.model.HandHistoryRow
interface CardHolder : RealmModel { interface CardHolder : RealmModel {
val cards: RealmList<Card> val cards: RealmList<Card>
} }
abstract class CardsRow(var cardHolder: CardHolder?) : HandHistoryRow { abstract class CardsRow : HandHistoryRow {
private val MAXCARDS = 7 private val MAXCARDS = 7
val cardCount: Int val cardCount: Int
get() { return this.cardHolder?.cards?.size ?: 0 } get() { return this.cardHolder?.cards?.size ?: 0 }
abstract fun createHolder() : CardHolder abstract fun createHolder()
abstract fun cardLimit() : Int? abstract fun cardLimit() : Int?
abstract val realmInstance: Realm abstract val realmInstance: Realm
abstract val cardHolder: CardHolder?
override fun tagForCompletion(handHistory: HandHistory): Int? { override fun tagForCompletion(handHistory: HandHistory): Int? {
return when { return when {
this.cardCount < cardLimit() ?: MAXCARDS -> 0 this.cardCount < cardLimit() ?: MAXCARDS -> 0
@ -37,7 +38,7 @@ abstract class CardsRow(var cardHolder: CardHolder?) : HandHistoryRow {
} }
} }
override fun keyboardForTag(tag: Int): HHKeyboard { override fun keyboardForTag(tag: Int): HHKeyboard? {
return HHKeyboard.CARD return HHKeyboard.CARD
} }
@ -84,7 +85,7 @@ abstract class CardsRow(var cardHolder: CardHolder?) : HandHistoryRow {
} }
if (this.cardHolder == null) { if (this.cardHolder == null) {
this.cardHolder = this.createHolder() this.createHolder()
} }
this.cardHolder?.cards?.lastOrNull()?.let { this.cardHolder?.cards?.lastOrNull()?.let {
@ -135,11 +136,14 @@ abstract class CardsRow(var cardHolder: CardHolder?) : HandHistoryRow {
} }
class StreetCardsRow(var street: Street, var handHistory: HandHistory) : CardsRow(handHistory) { class StreetCardsRow(var street: Street, var handHistory: HandHistory) : CardsRow() {
override val viewType: Int = HandRowType.STREET.ordinal override val viewType: Int = HandRowType.STREET.ordinal
override fun createHolder(): CardHolder { override val cardHolder: CardHolder?
get() { return this.handHistory }
override fun createHolder() {
throw PAIllegalStateException("This cannot happen") throw PAIllegalStateException("This cannot happen")
} }
@ -172,23 +176,42 @@ class StreetCardsRow(var street: Street, var handHistory: HandHistory) : CardsRo
} }
} }
} fun cardsForTag(tag: Int): List<Card>? {
this.cardHolder?.cards?.let { cards ->
return when (tag) {
Street.FLOP.ordinal -> cards.take(3)
Street.TURN.ordinal -> {
if (cards.size > 3) { listOf(cards[4]!!) } else { null }
}
Street.RIVER.ordinal -> {
if (cards.size > 4) { listOf(cards[5]!!) } else { null }
}
else -> throw PAIllegalStateException("unmanaged tag $tag")
}
}
return null
}
class PlayerCardsRow(var position: Position, var positionIndex: Int, var handHistory: HandHistory, cardHolder: CardHolder?, var maxCards: Int? = null) : CardsRow(cardHolder) { }
companion object { open class PlayerCardsRow(var position: Position?,
var positionIndex: Int?,
var handHistory: HandHistory,
var playerSetup: PlayerSetup?,
var maxCards: Int? = null) : CardsRow() {
fun newInstance(position: Position, handHistory: HandHistory, positionIndex: Int, maxCards: Int? = null): PlayerCardsRow { enum class Tag {
val playerSetup = handHistory.playerSetupForPosition(positionIndex) CARDS
return PlayerCardsRow(position, positionIndex, handHistory, playerSetup, maxCards)
} }
} override val cardHolder: CardHolder?
get() { return this.playerSetup }
override val viewType: Int = HandRowType.PLAYER_SUMMARY.ordinal override val viewType: Int = HandRowType.PLAYER_SUMMARY.ordinal
override fun createHolder(): CardHolder { override fun createHolder() {
return this.handHistory.createPlayerSetup(this.positionIndex) this.playerSetup = this.handHistory.createPlayerSetup(this.positionIndex
?: throw PAIllegalStateException("Can't create a PlayerSetup without a position"))
} }
override fun cardLimit() : Int? { override fun cardLimit() : Int? {

@ -17,7 +17,7 @@ interface HandHistoryRow : RowRepresentable {
*/ */
fun tagForCompletion(handHistory: HandHistory): Int? fun tagForCompletion(handHistory: HandHistory): Int?
fun keyboardForTag(tag: Int): HHKeyboard fun keyboardForTag(tag: Int): HHKeyboard?
fun amountForTag(handHistory: HandHistory, tag: Int): Double? { return null } fun amountForTag(handHistory: HandHistory, tag: Int): Double? { return null }
@ -34,6 +34,11 @@ class ComputedAction(var manager: ActionManager,
var position: Position var position: Position
) : HandHistoryRow { ) : HandHistoryRow {
enum class Tag {
ACTION,
AMOUNT
}
/*** /***
* Returns whether the action requires the user to enter an amount for the selected action * Returns whether the action requires the user to enter an amount for the selected action
*/ */
@ -170,19 +175,19 @@ class ComputedAction(var manager: ActionManager,
Timber.d("index = ${action.index} / type = ${this.action.type} / amount = ${this.action.amount}") Timber.d("index = ${action.index} / type = ${this.action.type} / amount = ${this.action.amount}")
return if (this.action.type != null) { return if (this.action.type != null) {
if (this.requiresAmount) { if (this.requiresAmount) {
1 Tag.AMOUNT.ordinal
} else { } else {
null null
} }
} else { } else {
0 Tag.ACTION.ordinal
} }
} }
override fun keyboardForTag(tag: Int): HHKeyboard { override fun keyboardForTag(tag: Int): HHKeyboard? {
return when (tag) { return when (tag) {
0 -> HHKeyboard.ACTION Tag.ACTION.ordinal -> HHKeyboard.ACTION
1 -> HHKeyboard.AMOUNT Tag.AMOUNT.ordinal -> HHKeyboard.AMOUNT
else -> throw PAIllegalStateException("unmanaged tag: $tag") else -> throw PAIllegalStateException("unmanaged tag: $tag")
} }
} }

@ -9,15 +9,10 @@ import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.handhistory.HandSetup import net.pokeranalytics.android.model.handhistory.HandSetup
import net.pokeranalytics.android.model.handhistory.Position import net.pokeranalytics.android.model.handhistory.Position
import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.Action import net.pokeranalytics.android.model.realm.handhistory.*
import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.modules.handhistory.HandRowType import net.pokeranalytics.android.ui.modules.handhistory.HandRowType
import net.pokeranalytics.android.ui.modules.handhistory.views.CardCentralizer import net.pokeranalytics.android.ui.modules.handhistory.views.CardCentralizer
import net.pokeranalytics.android.ui.modules.handhistory.views.CardsRow
import net.pokeranalytics.android.ui.modules.handhistory.views.PlayerCardsRow
import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardsRow
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.util.extensions.formatted import net.pokeranalytics.android.util.extensions.formatted
@ -204,7 +199,9 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource, CardCentra
val positions = this.sortedActions.activePositions(lastActionIndex, true) val positions = this.sortedActions.activePositions(lastActionIndex, true)
positions.forEach { positions.forEach {
val positionIndex = this.sortedActions.positions.indexOf(it) val positionIndex = this.sortedActions.positions.indexOf(it)
val playerCardsRow = PlayerCardsRow.newInstance(it, this.handHistory, positionIndex, this.playerHandMaxCards) val playerCardsRow = PlayerCardsRow(it, positionIndex, this.handHistory,
this.handHistory.playerSetupForPosition(positionIndex), this.playerHandMaxCards)
// val playerCardsRow = PlayerCardsRow.newInstance(it, this.handHistory, positionIndex, this.playerHandMaxCards)
rows.add(playerCardsRow) rows.add(playerCardsRow)
} }
} }
@ -236,7 +233,11 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource, CardCentra
if (street.totalBoardCards > 0) { if (street.totalBoardCards > 0) {
// create new StreetCardsRow // create new StreetCardsRow
val boardView = StreetCardsRow(street, this.handHistory) val boardView =
StreetCardsRow(
street,
this.handHistory
)
rowRepresentables.add(boardView) rowRepresentables.add(boardView)
} }
@ -353,6 +354,9 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource, CardCentra
is ComputedAction -> { is ComputedAction -> {
row.setAmount(amount) row.setAmount(amount)
} }
is PlayerSetupRow -> {
row.setStack(amount)
}
else -> {} else -> {}
} }
@ -540,20 +544,31 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource, CardCentra
override fun stringForRow(row: RowRepresentable, context: Context, tag: Int): String { override fun stringForRow(row: RowRepresentable, context: Context, tag: Int): String {
return when (row) { val string = when (row) {
HandRowType.PLAYER_NUMBER -> this.handHistory.numberOfPlayers.toString() HandRowType.PLAYER_NUMBER -> this.handHistory.numberOfPlayers.toString()
HandRowType.COMMENT -> this.handHistory.comment ?: context.getString(R.string.comment) HandRowType.COMMENT -> this.handHistory.comment ?: context.getString(R.string.comment)
HandRowType.BLINDS -> { HandRowType.BLINDS -> {
when (tag) { when (tag) {
0 -> this.handHistory.smallBlind?.formatted() ?: "" 0 -> this.handHistory.smallBlind?.formatted()
1 -> this.handHistory.bigBlind?.formatted() ?: "" 1 -> this.handHistory.bigBlind?.formatted()
2 -> this.handHistory.ante.formatted() 2 -> this.handHistory.ante.formatted()
else -> throw PAIllegalStateException("Unmanaged case with $row, tag = $tag") else -> throw PAIllegalStateException("Unmanaged case with $row, tag = $tag")
} }
} }
is ComputedAction -> row.action.formattedAmount
is StreetCardsRow -> row.cardsForTag(tag)?.formatted(context)
is PlayerSetupRow -> {
when (tag) {
PlayerSetupRow.Tag.CARDS.ordinal -> row.cardHolder?.cards?.formatted(context)
PlayerSetupRow.Tag.STACK.ordinal -> row.playerSetup?.stack?.formatted()
else -> throw PAIllegalStateException("Unmanaged case with $row, tag = $tag")
}
}
is PlayerCardsRow -> row.cardHolder?.cards?.formatted(context)
else -> throw PAIllegalStateException("Unmanaged case with $row, tag = $tag") else -> throw PAIllegalStateException("Unmanaged case with $row, tag = $tag")
} }
return string?.let { it.toString() } ?: "" // we don't want "null" so we keep the let
} }
override fun <T : Any> contentForRow(row: RowRepresentable, context: Context, clazz: KClass<T>) : List<T> { override fun <T : Any> contentForRow(row: RowRepresentable, context: Context, clazz: KClass<T>) : List<T> {
@ -589,36 +604,46 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource, CardCentra
* Will show rows for existing PlayerSetup, as well as a row for the hero if not set, * Will show rows for existing PlayerSetup, as well as a row for the hero if not set,
* and a row for a new player if necessary * and a row for a new player if necessary
*/ */
private fun playerSetups(): List<PlayerSetupRowRepresentable> { private fun playerSetups(): List<PlayerSetupRow> {
val hh = this.handHistory val hh = this.handHistory
val arrangedSetups = hh.playerSetups.sortedBy { it.position }.map { PlayerSetupRowRepresentable(playerSetup = it) }.toMutableList() val arrangedSetups = hh.playerSetups.sortedBy { it.position }.map {
createPlayerSetupRow(false, it)
}.toMutableList()
val heroSetup = arrangedSetups.firstOrNull { it.playerSetup?.position == hh.heroIndex } val heroSetup = arrangedSetups.firstOrNull { it.playerSetup?.position == hh.heroIndex }
heroSetup?.let { heroSetup?.let {
it.hero = true it.hero = true
arrangedSetups.remove(it) arrangedSetups.remove(it)
arrangedSetups.add(0, it) arrangedSetups.add(0, it)
} ?: run { } ?: run {
arrangedSetups.add(PlayerSetupRowRepresentable(true, null)) arrangedSetups.add(createPlayerSetupRow(true))
} }
if (arrangedSetups.size < hh.numberOfPlayers) { if (arrangedSetups.size < hh.numberOfPlayers) {
arrangedSetups.add(PlayerSetupRowRepresentable(false, null)) arrangedSetups.add(createPlayerSetupRow(false))
} }
return arrangedSetups return arrangedSetups
} }
/***
* Convenience method to create a PlayerSetupRow
*/
private fun createPlayerSetupRow(hero: Boolean, playerSetup: PlayerSetup? = null): PlayerSetupRow {
return PlayerSetupRow(hero, null, null, this.handHistory, playerSetup, this.playerHandMaxCards)
}
/*** /***
* Sets the both [positionIndex] and position for a PlayerSetup inside a [psRowRepresentable] * Sets the both [positionIndex] and position for a PlayerSetup inside a [psRowRepresentable]
*/ */
fun setPlayerSetupPosition(psRowRepresentable: PlayerSetupRowRepresentable, positionIndex: Int) { fun setPlayerSetupPosition(psRowRepresentable: PlayerSetupRow, positionIndex: Int) {
var setupCreated = false var setupCreated = false
psRowRepresentable.playerSetup?.let { psRowRepresentable.playerSetup?.let { setup ->
it.position = positionIndex setup.position = positionIndex
} ?: run { } ?: run {
psRowRepresentable.playerSetup = this.handHistory.createPlayerSetup(positionIndex) psRowRepresentable.playerSetup = this.handHistory.createPlayerSetup(positionIndex)
setupCreated = true setupCreated = true
@ -630,7 +655,7 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource, CardCentra
if (!psRowRepresentable.hero && setupCreated) { if (!psRowRepresentable.hero && setupCreated) {
if (this.handHistory.undefinedPositions().isNotEmpty()) { if (this.handHistory.undefinedPositions().isNotEmpty()) {
val newPlayerRow = PlayerSetupRowRepresentable(false, null) val newPlayerRow = createPlayerSetupRow(false)
val index = this.indexOfRowRepresentable(psRowRepresentable) val index = this.indexOfRowRepresentable(psRowRepresentable)
this.rowsLiveData.value?.add(index + 1, newPlayerRow) this.rowsLiveData.value?.add(index + 1, newPlayerRow)
} }

@ -8,10 +8,13 @@ import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.model.realm.handhistory.PlayerSetup import net.pokeranalytics.android.model.realm.handhistory.PlayerSetup
import net.pokeranalytics.android.ui.modules.handhistory.HandRowType import net.pokeranalytics.android.ui.modules.handhistory.HandRowType
class PlayerSetupRowRepresentable(var hero: Boolean = false, var playerSetup: PlayerSetup? = null) : class PlayerSetupRow(var hero: Boolean = false,
HandHistoryRow { position: Position?,
positionIndex: Int?,
var position: Position? = null handHistory: HandHistory,
playerSetup: PlayerSetup?,
maxCards: Int? = null) :
PlayerCardsRow(position, positionIndex, handHistory, playerSetup, maxCards) {
enum class State { enum class State {
POSITIONS_ONLY, POSITIONS_ONLY,
@ -54,18 +57,22 @@ class PlayerSetupRowRepresentable(var hero: Boolean = false, var playerSetup: Pl
override val viewType: Int = HandRowType.PLAYER_SETUP.ordinal override val viewType: Int = HandRowType.PLAYER_SETUP.ordinal
override fun tagForCompletion(handHistory: HandHistory): Int? { override fun tagForCompletion(handHistory: HandHistory): Int? {
this.playerSetup?.let {
if (it.cards.isEmpty()) { // check cards
super.tagForCompletion(handHistory)?.let { tag ->
return Tag.CARDS.ordinal return Tag.CARDS.ordinal
} else if (it.stack == null) {
return Tag.STACK.ordinal
} }
// stack
if (this.playerSetup?.stack == null) {
return Tag.STACK.ordinal
} }
return null return null
} }
override fun keyboardForTag(tag: Int): HHKeyboard { override fun keyboardForTag(tag: Int): HHKeyboard? {
return when (tag) { return when (tag) {
Tag.POSITION.ordinal -> null
Tag.CARDS.ordinal -> HHKeyboard.CARD Tag.CARDS.ordinal -> HHKeyboard.CARD
Tag.STACK.ordinal -> HHKeyboard.AMOUNT Tag.STACK.ordinal -> HHKeyboard.AMOUNT
else -> throw PAIllegalStateException("unmanaged tag: $tag") else -> throw PAIllegalStateException("unmanaged tag: $tag")
@ -79,4 +86,8 @@ class PlayerSetupRowRepresentable(var hero: Boolean = false, var playerSetup: Pl
} }
} }
fun setStack(amount: Double) {
this.playerSetup?.stack = amount
}
} }
Loading…
Cancel
Save