More improvements on HH

hh
Laurent 6 years ago
parent b5f238d165
commit bf9223a3f3
  1. 37
      app/src/main/java/net/pokeranalytics/android/model/handhistory/ComputedAction.kt
  2. 26
      app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt
  3. 30
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Card.kt
  4. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt
  5. 1
      app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt
  6. 7
      app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt
  7. 70
      app/src/main/java/net/pokeranalytics/android/ui/fragment/HandHistoryFragment.kt
  8. 158
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  9. 12
      app/src/main/java/net/pokeranalytics/android/ui/view/handhistory/KeyboardAmountView.kt
  10. 26
      app/src/main/java/net/pokeranalytics/android/ui/view/handhistory/KeyboardContainer.kt
  11. 5
      app/src/main/java/net/pokeranalytics/android/ui/view/handhistory/StreetCardHeader.kt
  12. 64
      app/src/main/java/net/pokeranalytics/android/ui/viewmodel/HandHistoryViewModel.kt
  13. 2
      app/src/main/res/layout/fragment_hand_history.xml
  14. 30
      app/src/main/res/layout/row_hand_action.xml
  15. 7
      app/src/main/res/layout/view_hand_keyboard_amount.xml
  16. 13
      app/src/main/res/values/styles.xml

@ -3,10 +3,13 @@ package net.pokeranalytics.android.model.handhistory
import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.handhistory.HandHistoryKeyboard
interface HandHistoryRow : RowRepresentable {
fun keyboardForCompletion() : HandHistoryKeyboard?
/***
* Returns the appropriate keyboard to complete the row content
*/
fun keyboardForCompletion() : HHKeyboard?
}
class ComputedAction(var action: Action,
@ -20,8 +23,9 @@ class ComputedAction(var action: Action,
val requireAmount: Boolean
get() {
return when(this.action.type) {
Action.Type.BET, Action.Type.RAISE -> true
Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN -> (this.playerRemainingStack == null)
Action.Type.POST_SB, Action.Type.POST_BB,
Action.Type.BET, Action.Type.RAISE -> (this.action.amount == null)
Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN -> (this.playerRemainingStack == null && this.action.amount == null)
else -> false
}
}
@ -39,16 +43,23 @@ class ComputedAction(var action: Action,
override val viewType: Int = RowViewType.ROW_HAND_ACTION.ordinal
override fun keyboardForCompletion() : HandHistoryKeyboard? {
this.action.type?.let { type ->
if (this.requireAmount && this.action.amount == null) {
return HandHistoryKeyboard.ACTION
} else {
return null
}
} ?: run {
return HandHistoryKeyboard.ACTION
override fun keyboardForCompletion() : HHKeyboard? {
return if (this.action.type != null) {
if (this.requireAmount) {
HHKeyboard.AMOUNT
} else {
null
}
} else {
HHKeyboard.ACTION
}
}
/***
* Returns whether the action type can be edited
* SB / BB cannot have their action type edited
*/
val actionTypeCanBeEdited: Boolean
get() { return action.index > 1 }
}

@ -6,12 +6,20 @@ import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.handhistory.HandHistoryKeyboard
import net.pokeranalytics.android.ui.view.handhistory.StreetCardHeader
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import timber.log.Timber
import java.util.*
import kotlin.math.min
enum class HHKeyboard {
ACTION,
AMOUNT,
CARD
}
class HHSelection(var index: Int, var keyboard: HHKeyboard)
class HHBuilder {
/***
@ -141,6 +149,8 @@ class HHBuilder {
*/
fun selectAction(index: Int, actionType: Action.Type) : Boolean {
Timber.d("Sets $actionType at index: $index")
val computedAction = this.actionForIndex(index)
computedAction.action.type = actionType
@ -180,6 +190,8 @@ class HHBuilder {
* In the case of an UNDEFINED_ALLIN, define if it's a RAISE_ALLIN or a CALL_ALLIN
*/
fun setAmount(index: Int, amount: Double) {
Timber.d("Sets $amount at index: $index")
val computedAction = this.actionForIndex(index)
val revisedAmount = computedAction.playerRemainingStack?.let { min(it, amount) } ?: amount
@ -302,15 +314,20 @@ class HHBuilder {
return rows
}
fun indexOfComputedAction(rowRepresentableIndex: Int) : Int {
val computedAction = this.currentRowRepresentables[rowRepresentableIndex] as ComputedAction
return computedAction.action.index
}
/***
* Finds the index of the first incomplete action, if existing
*/
fun findIndexForEdition(): Pair<Int, HandHistoryKeyboard>? {
fun findIndexForEdition(startIndex: Int): HHSelection? {
this.currentRowRepresentables.forEachIndexed { index, rowRepresentable ->
if (rowRepresentable is HandHistoryRow) {
if (index >= startIndex && rowRepresentable is HandHistoryRow) {
rowRepresentable.keyboardForCompletion()?.let { keyboard ->
return Pair(index, keyboard)
return HHSelection(index, keyboard)
}
}
}
@ -318,3 +335,4 @@ class HHBuilder {
}
}

@ -3,27 +3,29 @@ package net.pokeranalytics.android.model.realm.handhistory
import io.realm.RealmObject
import net.pokeranalytics.android.exceptions.PAIllegalStateException
interface CardProperty
open class Card : RealmObject() {
companion object {
fun valueFormatted(value: Int) : String {
return when(value) {
0 -> "x"
in 2..9 -> "$value"
10 -> "T"
11 -> "J"
12 -> "Q"
13 -> "K"
14 -> "A"
else -> throw PAIllegalStateException("card value '$value' not handled")
class Value(var value: Int) : CardProperty {
val formatted: String
get() {
return when(value) {
0 -> "x"
in 2..9 -> "$value"
10 -> "T"
11 -> "J"
12 -> "Q"
13 -> "K"
14 -> "A"
else -> throw PAIllegalStateException("card value '$value' not handled")
}
}
}
}
enum class Suit(val value: String) {
enum class Suit(val value: String) : CardProperty {
UNDEFINED("x"),
SPADES(""),
HEART(""),

@ -39,12 +39,12 @@ open class HandHistory : RealmObject(), RowRepresentable, Identifiable, Filterab
/***
* The small blind
*/
var smallBlind: Double = 0.0
var smallBlind: Double? = null
/***
* The big blind
*/
var bigBlind: Double = 0.0
var bigBlind: Double? = null
/***
* The ante

@ -10,6 +10,7 @@ import net.pokeranalytics.android.ui.view.RowViewType
interface RowRepresentableDelegate {
fun onRowSelected(position: Int, row: RowRepresentable, tag: Int = 0) {}
fun onRowDeselected(position: Int, row: RowRepresentable) {}
fun onRowValueChanged(value: Any?, row: RowRepresentable) {}
fun onRowDeleted(row: RowRepresentable) {}
fun onRowLongClick(itemView: View, row: RowRepresentable, position: Int) {}

@ -153,6 +153,13 @@ interface DisplayableDataSource {
return true
}
/**
* Returns whether the row, or its component, shoudl be enabled
*/
fun color(position: Int, row: RowRepresentable, tag: Int): Int? {
return null
}
/**
* Returns whether the row, or its component, shoudl be enabled
*/

@ -10,9 +10,7 @@ import kotlinx.android.synthetic.main.fragment_hand_history.*
import kotlinx.android.synthetic.main.fragment_settings.recyclerView
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.handhistory.ComputedAction
import net.pokeranalytics.android.model.handhistory.HHBuilder
import net.pokeranalytics.android.model.handhistory.HandSetup
import net.pokeranalytics.android.model.handhistory.*
import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
@ -21,7 +19,6 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.handhistory.HandHistoryKeyboard
import net.pokeranalytics.android.ui.view.handhistory.KeyboardListener
import net.pokeranalytics.android.ui.view.handhistory.StreetCardHeader
import net.pokeranalytics.android.ui.viewmodel.HandHistoryViewModel
@ -105,12 +102,13 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
private fun edit() {
this.model.isEdited = true
findNextActionToEdit(0)
}
private fun findNextActionToEdit() {
this.model.findIndexForEdition()?.let {
private fun findNextActionToEdit(startIndex: Int) {
this.model.findIndexForEdition(startIndex)?.let {
this.keyboard.show(it)
this.highlightCell(it)
this.highlightCell()
} ?: run {
this.keyboard.hide()
}
@ -120,8 +118,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
this.model.isEdited = false
}
private fun highlightCell(handHistoryKeyboard: HandHistoryKeyboard) {
private fun highlightCell() {
this.handHistoryAdapter.notifyDataSetChanged()
}
// RowRepresentableDataSource
@ -149,19 +147,37 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
return
}
this.model.currentSelection = HHSelection(position, HHKeyboard.values()[tag])
when (row) {
is ComputedAction -> {
val keyboard = when (tag) {
1 -> HandHistoryKeyboard.ACTION
2 -> HandHistoryKeyboard.AMOUNT
else -> throw PAIllegalStateException("Unmanaged tag")
HHKeyboard.ACTION.ordinal -> HHKeyboard.ACTION
HHKeyboard.AMOUNT.ordinal -> HHKeyboard.AMOUNT
else -> throw PAIllegalStateException("Unmanaged tag value: $tag")
}
this.keyboard.show(keyboard)
}
is StreetCardHeader -> {
this.keyboard.show(HandHistoryKeyboard.CARD)
this.keyboard.show(HHKeyboard.CARD)
}
}
}
override fun onRowDeselected(position: Int, row: RowRepresentable) {
this.model.currentSelection = null
}
override fun onRowValueChanged(value: Any?, row: RowRepresentable) {
this.model.currentAmount = value as String
}
override fun color(position: Int, row: RowRepresentable, tag: Int): Int? {
val isSelectedIndex = (position == this.model.currentSelection?.index)
val isSelectedAction = (tag == this.model.currentSelection?.keyboard?.ordinal)
val color = if (isSelectedIndex && isSelectedAction) R.color.green_light else R.color.kaki_medium
return context?.getColor(color)
}
// Keyboard Listener
@ -169,21 +185,31 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
override fun actionSelected(action: Action.Type) {
Timber.d(">>> action $action selected")
this.model.actionSelected(action)
this.findNextActionToEdit()
// this.handHistoryAdapter.notifyDataSetChanged()
this.findNextActionToEdit(this.model.actionIndexForSelection)
}
override fun cardValueSelected(value: Int) {
this.model.cardValueSelected(value)
this.handHistoryAdapter.notifyDataSetChanged()
// TODO add test about number of cards before selecting next action?
// this.findNextActionToEdit()
}
override fun cardSelected(value: Card, suit: Card.Suit) {
Timber.d(">>> card $value$suit selected")
this.model.cardSelected(value, suit)
override fun cardSuitSelected(suit: Card.Suit) {
this.model.cardSuitSelected(suit)
this.handHistoryAdapter.notifyDataSetChanged()
// TODO add test about number of cards?
this.findNextActionToEdit()
// this.findNextActionToEdit()
}
override fun amountSelected(amount: Double) {
Timber.d(">>> amount $amount selected")
this.model.amountSelected(amount)
this.findNextActionToEdit()
override fun amountValidated() {
Timber.d(">>> amount validated")
this.model.amountValidated()
// this.handHistoryAdapter.notifyDataSetChanged()
this.findNextActionToEdit(this.model.actionIndexForSelection)
}
}

@ -13,6 +13,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.widget.ContentLoadingProgressBar
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.RecyclerView
import com.github.mikephil.charting.charts.BarChart
import com.github.mikephil.charting.charts.LineChart
@ -28,6 +29,7 @@ import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager
import net.pokeranalytics.android.model.TableSize
import net.pokeranalytics.android.model.extensions.getFormattedGameType
import net.pokeranalytics.android.model.handhistory.ComputedAction
import net.pokeranalytics.android.model.handhistory.HHKeyboard
import net.pokeranalytics.android.model.realm.CustomField
import net.pokeranalytics.android.model.realm.Player
import net.pokeranalytics.android.model.realm.Session
@ -41,6 +43,7 @@ import net.pokeranalytics.android.ui.fragment.BankrollRowRepresentable
import net.pokeranalytics.android.ui.graph.AxisFormatting
import net.pokeranalytics.android.ui.graph.setStyle
import net.pokeranalytics.android.ui.view.rowrepresentable.*
import net.pokeranalytics.android.util.extensions.formatted
import net.pokeranalytics.android.util.extensions.longDate
import timber.log.Timber
@ -87,7 +90,7 @@ enum class RowViewType(private var layoutRes: Int) {
// Custom row
ROW_SESSION(R.layout.row_feed_session),
ROW_TRANSACTION(R.layout.row_transaction),
// ROW_HAND_HISTORY(R.layout.row_hand_history),
// ROW_HAND_HISTORY(R.layout.row_hand_history),
ROW_TOP_10(R.layout.row_top_10),
ROW_BUTTON(R.layout.row_button),
ROW_FOLLOW_US(R.layout.row_follow_us),
@ -182,8 +185,10 @@ enum class RowViewType(private var layoutRes: Int) {
itemView.findViewById<AppCompatTextView>(R.id.title)?.let {
it.text = row.localizedTitle(itemView.context)
}
val computedStat = ComputedStat(Stat.NET_RESULT, report.total, currency = report.currency)
itemView.findViewById<AppCompatTextView?>(R.id.value)?.setTextFormat(computedStat.format(), itemView.context)
val computedStat =
ComputedStat(Stat.NET_RESULT, report.total, currency = report.currency)
itemView.findViewById<AppCompatTextView?>(R.id.value)
?.setTextFormat(computedStat.format(), itemView.context)
}
val listener = View.OnClickListener {
@ -216,7 +221,8 @@ enum class RowViewType(private var layoutRes: Int) {
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.findViewById<View?>(R.id.container)?.setOnClickListener(listener)
itemView.findViewById<View?>(R.id.container)
?.setOnClickListener(listener)
}
}
@ -255,7 +261,12 @@ enum class RowViewType(private var layoutRes: Int) {
imageView.setImageResource(imageRes)
}
row.imageTint?.let { color ->
imageView.setColorFilter(ContextCompat.getColor(imageView.context, color))
imageView.setColorFilter(
ContextCompat.getColor(
imageView.context,
color
)
)
}
if (row.imageClickable == true) {
imageView.addCircleRipple()
@ -303,7 +314,8 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a follow us row
*/
inner class RowFollowUsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class RowFollowUsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.findViewById<AppCompatImageView?>(R.id.icon1)?.setOnClickListener {
adapter.delegate?.onRowSelected(0, row)
@ -328,7 +340,8 @@ enum class RowViewType(private var layoutRes: Int) {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
// Title
itemView.findViewById<AppCompatTextView?>(R.id.title)?.text = row.localizedTitle(itemView.context)
itemView.findViewById<AppCompatTextView?>(R.id.title)?.text =
row.localizedTitle(itemView.context)
// Value
itemView.findViewById<AppCompatTextView?>(R.id.value)?.let { view ->
@ -338,7 +351,8 @@ enum class RowViewType(private var layoutRes: Int) {
}
if (row is StatRow) {
itemView.findViewById<AppCompatImageView?>(R.id.nextArrow)?.isVisible = row.stat.hasProgressGraph
itemView.findViewById<AppCompatImageView?>(R.id.nextArrow)?.isVisible =
row.stat.hasProgressGraph
}
// Listener
@ -400,7 +414,8 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a graph
*/
inner class GraphViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class GraphViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
private fun loadWithDataSet(dataSet: DataSet<*>) {
val context = itemView.context
@ -460,7 +475,8 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a legend
*/
inner class LegendDefaultViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class LegendDefaultViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
@ -489,7 +505,8 @@ enum class RowViewType(private var layoutRes: Int) {
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.findViewById<ConstraintLayout>(R.id.container)?.setOnClickListener(listener)
itemView.findViewById<ConstraintLayout>(R.id.container)
?.setOnClickListener(listener)
}
}
@ -525,7 +542,8 @@ enum class RowViewType(private var layoutRes: Int) {
chipGroup.addView(chip)
}
chipGroup.setOnCheckedChangeListener(object : ChipGroupExtension.SingleSelectionOnCheckedListener() {
chipGroup.setOnCheckedChangeListener(object :
ChipGroupExtension.SingleSelectionOnCheckedListener() {
override fun onCheckedChanged(group: ChipGroup, checkedId: Int) {
super.onCheckedChanged(group, checkedId)
@ -534,7 +552,10 @@ enum class RowViewType(private var layoutRes: Int) {
return
}
adapter.delegate?.onRowValueChanged(CustomField.Type.values()[checkedId], row)
adapter.delegate?.onRowValueChanged(
CustomField.Type.values()[checkedId],
row
)
}
})
}
@ -545,11 +566,15 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a button in a row
*/
inner class RowButtonViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class RowButtonViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.findViewById<AppCompatTextView>(R.id.title).text = row.localizedTitle(itemView.context)
itemView.findViewById<AppCompatTextView>(R.id.title).isVisible = !adapter.dataSource.boolForRow(row)
itemView.findViewById<ContentLoadingProgressBar>(R.id.progressBar).isVisible = adapter.dataSource.boolForRow(row)
itemView.findViewById<AppCompatTextView>(R.id.title).text =
row.localizedTitle(itemView.context)
itemView.findViewById<AppCompatTextView>(R.id.title).isVisible =
!adapter.dataSource.boolForRow(row)
itemView.findViewById<ContentLoadingProgressBar>(R.id.progressBar).isVisible =
adapter.dataSource.boolForRow(row)
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
@ -560,7 +585,8 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a session view
*/
inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.sessionRow.setData(row as Session)
val listener = View.OnClickListener {
@ -573,7 +599,8 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a transaction view
*/
inner class RowTransactionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class RowTransactionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.transactionRow.setData(row as Transaction)
val listener = View.OnClickListener {
@ -586,14 +613,16 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a top 10 row
*/
inner class RowTop10ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class RowTop10ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
if (row is Session) {
itemView.findViewById<AppCompatTextView>(R.id.gameResult)?.let { gameResult ->
val result = row.result?.net ?: 0.0
val formattedStat = ComputedStat(Stat.NET_RESULT, result, currency = row.currency).format()
val formattedStat =
ComputedStat(Stat.NET_RESULT, result, currency = row.currency).format()
gameResult.setTextFormat(formattedStat, itemView.context)
}
@ -602,15 +631,19 @@ enum class RowViewType(private var layoutRes: Int) {
}
// Duration
val durationIcon = itemView.findViewById<AppCompatImageView?>(R.id.sessionInfoDurationIcon)
val durationText = itemView.findViewById<AppCompatTextView?>(R.id.sessionInfoDuration)
val durationIcon =
itemView.findViewById<AppCompatImageView?>(R.id.sessionInfoDurationIcon)
val durationText =
itemView.findViewById<AppCompatTextView?>(R.id.sessionInfoDuration)
durationIcon?.isVisible = true
durationText?.isVisible = true
durationText?.text = row.getFormattedDuration()
// Location
val locationIcon = itemView.findViewById<AppCompatImageView?>(R.id.sessionInfoLocationIcon)
val locationText = itemView.findViewById<AppCompatTextView?>(R.id.sessionInfoLocation)
val locationIcon =
itemView.findViewById<AppCompatImageView?>(R.id.sessionInfoLocationIcon)
val locationText =
itemView.findViewById<AppCompatTextView?>(R.id.sessionInfoLocation)
if (!row.location?.name.isNullOrEmpty()) {
locationIcon?.isVisible = true
@ -622,8 +655,10 @@ enum class RowViewType(private var layoutRes: Int) {
}
// Table Size
val tableSizeIcon = itemView.findViewById<AppCompatImageView?>(R.id.sessionInfoTableSizeIcon)
val tableSizeText = itemView.findViewById<AppCompatTextView?>(R.id.sessionInfoTableSize)
val tableSizeIcon =
itemView.findViewById<AppCompatImageView?>(R.id.sessionInfoTableSizeIcon)
val tableSizeText =
itemView.findViewById<AppCompatTextView?>(R.id.sessionInfoTableSize)
row.tableSize?.let {
tableSizeIcon?.isVisible = true
@ -646,7 +681,8 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a player image view
*/
inner class RowPlayerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class RowPlayerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
if (row is Player) {
@ -672,7 +708,8 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a player image view
*/
inner class RowPlayerImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class RowPlayerImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.findViewById<PlayerImageView?>(R.id.playerImageView)?.let { playerImageView ->
val listener = View.OnClickListener {
@ -692,22 +729,64 @@ enum class RowViewType(private var layoutRes: Int) {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
val computedAction = row as ComputedAction
itemView.findViewById<Button>(R.id.actionButton)?.let { button ->
computedAction.action.type?.resId?.let {
button.text = itemView.context.getString(it)
// Position
itemView.findViewById<Button>(R.id.positionButton)?.let { button ->
button.text = computedAction.position.value
}
// Action
itemView.findViewById<EditText>(R.id.actionEditText)?.let { button ->
button.isFocusable = computedAction.actionTypeCanBeEdited
adapter.dataSource.color(position, row, HHKeyboard.ACTION.ordinal)?.let { color ->
button.setBackgroundColor(color)
}
button.setOnClickListener {
adapter.delegate?.onRowSelected(position, row, 1)
computedAction.action.type?.resId?.let {
button.setText(it)
}
}
// button.setOnClickListener {
// }
button.setOnFocusChangeListener { v, hasFocus ->
Timber.d("Action Focus change: $hasFocus")
if (hasFocus) {
adapter.delegate?.onRowSelected(position, row, HHKeyboard.ACTION.ordinal)
} else {
adapter.delegate?.onRowDeselected(position, row)
}
itemView.findViewById<Button>(R.id.positionButton)?.let { button ->
button.text = computedAction.position.value
adapter.dataSource.color(position, row, HHKeyboard.ACTION.ordinal)?.let { color ->
button.setBackgroundColor(color)
}
}
}
// Amount
itemView.findViewById<EditText>(R.id.amountEditText)?.let { editText ->
adapter.dataSource.color(position, row, HHKeyboard.AMOUNT.ordinal)?.let { color ->
editText.setBackgroundColor(color)
}
editText.setText(computedAction.action.amount?.formatted())
editText.setOnFocusChangeListener { v, hasFocus ->
adapter.delegate?.onRowSelected(position, row, 2)
Timber.d("Amount Focus change: $hasFocus")
if (hasFocus) {
adapter.delegate?.onRowSelected(position, row, HHKeyboard.AMOUNT.ordinal)
} else {
adapter.delegate?.onRowDeselected(position, row)
}
adapter.dataSource.color(position, row, HHKeyboard.AMOUNT.ordinal)
?.let { color ->
editText.setBackgroundColor(color)
}
}
editText.addTextChangedListener {
adapter.delegate?.onRowValueChanged(it.toString(), row)
}
}
@ -726,7 +805,8 @@ enum class RowViewType(private var layoutRes: Int) {
/**
* Display a separator
*/
inner class SeparatorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
inner class SeparatorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
}
}

@ -1,7 +1,19 @@
package net.pokeranalytics.android.ui.view.handhistory
import android.content.Context
import android.view.LayoutInflater
import kotlinx.android.synthetic.main.view_hand_keyboard_amount.view.*
import net.pokeranalytics.android.R
class KeyboardAmountView(context: Context) : AbstractKeyboardView(context) {
init {
LayoutInflater.from(context)
.inflate(R.layout.view_hand_keyboard_amount, this, true)
this.nextButton.setOnClickListener {
this.keyboardListener?.amountValidated()
}
}
}

@ -6,31 +6,28 @@ import android.widget.FrameLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.handhistory.HHKeyboard
import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.Card
import timber.log.Timber
interface KeyboardListener {
fun actionSelected(action: Action.Type)
fun cardSelected(value: Card, suit: Card.Suit)
fun amountSelected(amount: Double)
}
enum class HandHistoryKeyboard {
ACTION,
AMOUNT,
CARD
fun cardValueSelected(value: Int)
fun cardSuitSelected(suit: Card.Suit)
fun amountValidated()
}
class KeyboardContainer(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
var keyboardListener: KeyboardListener? = null
val keyboards = HashMap<HandHistoryKeyboard, AbstractKeyboardView>()
val keyboards = HashMap<HHKeyboard, AbstractKeyboardView>()
private lateinit var constraintLayout: ConstraintLayout
init {
this.setBackgroundColor(context.getColor(R.color.kaki))
this.setBackgroundColor(context.getColor(R.color.kaki_darker))
}
private fun show() {
@ -41,7 +38,8 @@ class KeyboardContainer(context: Context, attrs: AttributeSet?) : FrameLayout(co
this.isVisible = false
}
fun show(type: HandHistoryKeyboard) {
fun show(type: HHKeyboard) {
Timber.d("show keyboard : $type")
show()
@ -49,9 +47,9 @@ class KeyboardContainer(context: Context, attrs: AttributeSet?) : FrameLayout(co
if (view == null) {
view = when(type) {
HandHistoryKeyboard.ACTION -> { KeyboardActionView(context) }
HandHistoryKeyboard.AMOUNT -> { KeyboardAmountView(context) }
HandHistoryKeyboard.CARD -> { KeyboardCardView(context) }
HHKeyboard.ACTION -> { KeyboardActionView(context) }
HHKeyboard.AMOUNT -> { KeyboardAmountView(context) }
HHKeyboard.CARD -> { KeyboardCardView(context) }
}
view.keyboardListener = this.keyboardListener
addView(view)

@ -1,5 +1,6 @@
package net.pokeranalytics.android.ui.view.handhistory
import net.pokeranalytics.android.model.handhistory.HHKeyboard
import net.pokeranalytics.android.model.handhistory.HandHistoryRow
import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.Card
@ -9,9 +10,9 @@ class StreetCardHeader(var street: Street, var cards: List<Card>, var potSize: D
override val viewType: Int = RowViewType.ROW_HAND_STREET.ordinal
override fun keyboardForCompletion(): HandHistoryKeyboard? {
override fun keyboardForCompletion(): HHKeyboard? {
return if (cards.size != street.totalBoardCards) {
HandHistoryKeyboard.CARD
HHKeyboard.CARD
} else {
null
}

@ -3,18 +3,23 @@ package net.pokeranalytics.android.ui.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.handhistory.ComputedAction
import net.pokeranalytics.android.model.handhistory.HHBuilder
import net.pokeranalytics.android.model.handhistory.HHKeyboard
import net.pokeranalytics.android.model.handhistory.HHSelection
import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.ui.view.handhistory.HandHistoryKeyboard
import net.pokeranalytics.android.ui.view.handhistory.StreetCardHeader
import net.pokeranalytics.android.model.realm.handhistory.CardProperty
import timber.log.Timber
class HandHistoryViewModel : ViewModel() {
var isEdited = true
var currentActionIndex: Int? = null
var currentSelection: HHSelection? = null
var currentAmount: String? = null
var lastCardPropertySelection: CardProperty? = null
var builder = MutableLiveData<HHBuilder>()
@ -26,32 +31,53 @@ class HandHistoryViewModel : ViewModel() {
// this.builder.
}
val actionIndexForSelection: Int
get() {
this.currentSelection?.let {
return builder.value?.indexOfComputedAction(it.index) ?: throw PAIllegalStateException("No builder")
} ?: throw PAIllegalStateException("No selection")
}
fun actionSelected(action: Action.Type) {
this.currentActionIndex?.let { index ->
builder.value?.selectAction(index, action)
} ?: run {
throw PAIllegalStateException("No action is selected to set the player action")
builder.value?.selectAction(this.actionIndexForSelection, action)
}
fun amountValidated() {
try {
this.currentAmount?.toDouble()?.let { amount ->
builder.value?.setAmount(this.actionIndexForSelection, amount)
this.currentAmount = null
}
} catch (e: NumberFormatException) {
Timber.w("Parsing exception: ${e.message}")
}
}
fun amountSelected(amount: Double) {
this.currentActionIndex?.let { index ->
builder.value?.setAmount(index, amount)
} ?: run {
throw PAIllegalStateException("No action is selected to set the action amount")
fun cardValueSelected(value: Int) {
this.currentSelection?.let { selection ->
selection.index
// get the appropriate card list, board or player's hand and give the information
}
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun cardSelected(value: Card, suit: Card.Suit) {
// builder.value?.selectCard(value, suit)
fun cardSuitSelected(suit: Card.Suit) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun findIndexForEdition() : HandHistoryKeyboard? {
fun findIndexForEdition(startIndex: Int) : HHKeyboard? {
builder.value?.let { builder ->
val r = builder.findIndexForEdition()
this.currentActionIndex = r?.first
return r?.second
this.currentSelection = builder.findIndexForEdition(startIndex)
this.currentSelection?.let {
Timber.d("Current selection is ${it.index} / ${it.keyboard}")
} ?: run {
Timber.d("No selection")
}
return currentSelection?.keyboard
} ?: throw PAIllegalStateException("Builder not defined")
}

@ -37,7 +37,7 @@
<net.pokeranalytics.android.ui.view.handhistory.KeyboardContainer
android:id="@+id/keyboard"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_height="200dp"
app:layout_constraintTop_toBottomOf="@id/recyclerView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"

@ -6,32 +6,42 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/playerButton"
style="@style/PokerAnalyticsTheme.Button"
style="@style/PokerAnalyticsTheme.HHButton"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginStart="8dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/positionButton"
style="@style/PokerAnalyticsTheme.Button"
style="@style/PokerAnalyticsTheme.HHButton"
android:layout_width="64dp"
android:layout_height="44dp"
android:layout_marginStart="8dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/actionButton"
style="@style/PokerAnalyticsTheme.Button"
android:layout_width="120dp"
android:layout_height="44dp"
<!-- <com.google.android.material.button.MaterialButton-->
<!-- android:id="@+id/actionButton"-->
<!-- style="@style/PokerAnalyticsTheme.HHButton"-->
<!-- android:layout_width="120dp"-->
<!-- android:layout_height="44dp"-->
<!-- android:layout_marginStart="8dp"/>-->
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/actionEditText"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"/>
android:layout_marginEnd="8dp"
android:imeOptions="actionDone"
android:maxLines="1" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/amountEditText"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:imeOptions="actionDone"
android:maxLines="1" />

@ -15,14 +15,16 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/closeButton"
style="@style/PokerAnalyticsTheme.Button"
app:icon="@drawable/ic_close"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginStart="8dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/clearButton"
android:text="@string/clear"
style="@style/PokerAnalyticsTheme.Button"
android:layout_width="44dp"
android:layout_width="64dp"
android:layout_height="44dp"
android:layout_marginStart="8dp"/>
@ -42,8 +44,9 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/nextButton"
android:text="@string/next"
style="@style/PokerAnalyticsTheme.Button"
android:layout_width="44dp"
android:layout_width="64dp"
android:layout_height="44dp"
android:layout_marginStart="8dp"/>

@ -341,6 +341,19 @@
<item name="android:textSize">12sp</item>
</style>
<style name="PokerAnalyticsTheme.HHButton" parent="Widget.MaterialComponents.Button">
<item name="iconPadding">0dp</item>
<item name="android:height">48dp</item>
<item name="iconTint">@color/black</item>
<item name="android:letterSpacing">0</item>
<item name="android:fontFamily">@font/roboto_medium</item>
<item name="android:textColor">@color/black</item>
<item name="android:paddingStart">4dp</item>
<item name="android:paddingEnd">8dp</item>
<item name="android:textSize">12sp</item>
<item name="backgroundTint">@color/kaki_medium</item>
</style>
<style name="PokerAnalyticsTheme.SecondaryButton" parent="PokerAnalyticsTheme.Button">
<item name="backgroundTint">@color/white</item>
</style>

Loading…
Cancel
Save