Work on board rows

hh
Laurent 6 years ago
parent 70df3195e5
commit 66730eb43e
  1. 14
      app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt
  2. 3
      app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt
  3. 79
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Card.kt
  4. 6
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt
  5. 112
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt
  6. 13
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardView.kt
  8. 62
      app/src/main/res/layout/row_hand_cards.xml
  9. 3
      app/src/main/res/values/colors.xml
  10. 3
      app/src/main/res/values/styles.xml

@ -5,7 +5,7 @@ import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.modules.handhistory.HandRowType
import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardHeader
import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardView
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import timber.log.Timber
@ -31,11 +31,6 @@ class HHBuilder {
load()
}
/***
* The map containing all actions present in a street
*/
// private val actionsPerStreet = hashMapOf<Street, List<ComputedAction>>()
/***
* All actions sorted by index
*/
@ -374,6 +369,9 @@ class HHBuilder {
}
/***
* The list of row representables, generated from the hand history actions
*/
private var currentRowRepresentables = mutableListOf<RowRepresentable>()
fun rowRepresentables() : List<RowRepresentable> {
@ -391,8 +389,8 @@ class HHBuilder {
rows.add(CustomizableRowRepresentable(customViewType = HandRowType.HEADER, resId = street.resId))
// Cards if not preflop
if (street.totalBoardCards > 0) {
rows.add(StreetCardHeader(street, this.handHistory.cardsForStreet(street), potSize))
if (street.totalBoardCards >= 0) {
rows.add(StreetCardView(street, this.handHistory.cardsForStreet(street), potSize))
}
// Actions

@ -192,10 +192,9 @@ class PokerAnalyticsMigration : RealmMigration {
hhSchema.addField("year", Integer::class.java)
hhSchema.addField("dayOfMonth", Integer::class.java)
val cardSchema = schema.create("Card")
cardSchema.addField("value", Int::class.java)
cardSchema.addField("suit", Int::class.java)
cardSchema.addField("suitIdentifier", Int::class.java)
cardSchema.addField("index", Int::class.java)
hhSchema.addRealmListField("board", cardSchema)

@ -1,16 +1,47 @@
package net.pokeranalytics.android.model.realm.handhistory
import android.content.Context
import android.text.SpannableString
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import io.realm.RealmObject
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import timber.log.Timber
interface CardProperty
fun List<Card>.formatted(context: Context) : CharSequence? {
var span: CharSequence? = null
this.forEach {
val formatted = it.formatted(context)
if (span == null) {
span = formatted
}
else {
span = TextUtils.concat(span, formatted)
}
}
return span
}
open class Card : RealmObject() {
companion object {
fun valueOf(value: Int, suit: Suit) : Card {
val card = Card()
card.value = value
card.suit = suit
Timber.d("suit = ${card.suitIdentifier}")
return card
}
}
class Value(var value: Int) : CardProperty {
val formatted: String
get() {
companion object {
fun format(value: Int) : String {
return when(value) {
0 -> "x"
in 2..9 -> "$value"
@ -21,8 +52,14 @@ open class Card : RealmObject() {
14 -> "A"
else -> throw PAIllegalStateException("card value '$value' not handled")
}
}
}
val formatted: String
get() { return format(this.value) }
}
enum class Suit(val value: String) : CardProperty {
@ -30,7 +67,18 @@ open class Card : RealmObject() {
SPADES(""),
HEART(""),
DIAMOND(""),
CLOVER("")
CLOVER("");
val color: Int
get() {
return when (this) {
UNDEFINED -> R.color.white
SPADES -> R.color.white_dark
HEART -> R.color.red
DIAMOND -> R.color.diamond
CLOVER -> R.color.clover
}
}
}
/***
@ -39,14 +87,37 @@ open class Card : RealmObject() {
*/
var value: Int = 0
val formattedValue: String
get() { return Value.format(this.value) }
/***
* The card suit: heart, spades...
*/
var suit: Int = 0
var suitIdentifier: Int = 0
var suit: Suit
get() {
return Suit.values()[this.suitIdentifier]
}
set(value) {
this.suitIdentifier = value.ordinal
}
/***
* The card index in a list
*/
var index: Int = 0
fun formatted(context: Context) : SpannableString {
val spannable = SpannableString(this.formattedValue + this.suit.value)
spannable.setSpan(
ForegroundColorSpan(context.getColor(this.suit.color)),
0,
spannable.length,
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE
)
return spannable
}
}

@ -94,6 +94,12 @@ open class HandHistory : RealmObject(), RowRepresentable, Identifiable, Filterab
fun configure(handSetup: HandSetup) {
// this.board.addAll(listOf(Card.valueOf(2, Card.Suit.SPADES),
// Card.valueOf(14, Card.Suit.HEART),
// Card.valueOf(5, Card.Suit.CLOVER),
// Card.valueOf(10, Card.Suit.DIAMOND),
// Card.valueOf(12, Card.Suit.SPADES)))
handSetup.tableSize?.let { this.numberOfPlayers = it }
handSetup.smallBlind?.let { this.smallBlind = it }
handSetup.bigBlind?.let { this.bigBlind = it }

@ -9,21 +9,26 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import androidx.core.view.isVisible
import androidx.recyclerview.widget.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.HHKeyboard
import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.formatted
import net.pokeranalytics.android.ui.adapter.BindableHolder
import net.pokeranalytics.android.ui.adapter.RecyclerAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.extensions.hideKeyboard
import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardView
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.holder.RowViewHolder
import net.pokeranalytics.android.ui.view.rowrepresentable.ViewIdentifier
import timber.log.Timber
enum class HandRowType(var layoutRes: Int) : ViewIdentifier {
HEADER(R.layout.row_header_title),
ACTION(R.layout.row_hand_action),
@ -90,14 +95,35 @@ class HandHistoryAdapter(
//
// }
abstract inner class RowHandHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var currentPosition = 0
fun color(isFocused: Boolean) : Int {
val color = if (isFocused) R.color.kaki else R.color.kaki_medium
return itemView.context.getColor(color)
}
fun editTextSelected(editText: EditText, selected: Boolean, tag: Int) {
editText.setBackgroundColor(color(selected))
val row = dataSource.rowRepresentableForPosition(currentPosition)
?: throw PAIllegalStateException("Row Representable not found at index: $currentPosition")
val alreadySelected = dataSource.isSelected(currentPosition, row, tag)
if (!alreadySelected && selected) {
delegate?.onRowSelected(currentPosition, row, tag)
}
}
}
/**
* Display a hand action
*/
inner class RowHandAction(itemView: View) : RecyclerView.ViewHolder(itemView),
inner class RowHandAction(itemView: View) : RowHandHolder(itemView),
BindableHolder {
// private var listener = TextListener()
private var currentPosition = 0
private var actionCanBeEdited = true
private var amountCanBeEdited = true
@ -129,7 +155,6 @@ class HandHistoryAdapter(
amountEditText.isFocusableInTouchMode = true
amountEditText.requestFocus()
// requestFocusAndShowKeyboard(amountEditText)
editTextSelected(amountEditText, true, HHKeyboard.AMOUNT.ordinal)
}
@ -137,18 +162,6 @@ class HandHistoryAdapter(
return@setOnTouchListener true
}
// amountEditText.addTextChangedListener(this.listener)
}
}
private fun editTextSelected(editText: EditText, selected: Boolean, tag: Int) {
editText.setBackgroundColor(color(selected))
val row = dataSource.rowRepresentableForPosition(currentPosition)
?: throw PAIllegalStateException("Row Representable not found at index: $currentPosition")
val alreadySelected = dataSource.isSelected(currentPosition, row, tag)
if (!alreadySelected && selected) {
delegate?.onRowSelected(currentPosition, row, tag)
}
}
@ -164,11 +177,6 @@ class HandHistoryAdapter(
}
}
private fun color(isFocused: Boolean) : Int {
val color = if (isFocused) R.color.kaki else R.color.kaki_medium
return itemView.context.getColor(color)
}
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
Timber.d("onbind @position = $position")
@ -245,11 +253,73 @@ class HandHistoryAdapter(
/**
* Display a hand street
*/
inner class RowHandStreet(itemView: View) : RecyclerView.ViewHolder(itemView),
inner class RowHandStreet(itemView: View) : RowHandHolder(itemView),
BindableHolder {
init {
// Flop
itemView.findViewById<EditText>(R.id.flopEditText)?.let { flopEditText ->
flopEditText.isFocusableInTouchMode = true
flopEditText.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_UP) {
// Both are required, otherwise requestFocus() fails
flopEditText.isFocusable = true
flopEditText.isFocusableInTouchMode = true
flopEditText.requestFocus()
editTextSelected(flopEditText, true, Street.FLOP.ordinal)
}
return@setOnTouchListener true
}
}
}
override fun onBind(position: Int, row: RowRepresentable, adapter: RecyclerAdapter) {
val streetCardView = row as StreetCardView
val street = streetCardView.street
itemView.findViewById<EditText>(R.id.flopEditText)?.let { flopEditText ->
flopEditText.isFocusable = (street == Street.FLOP)
flopEditText.isVisible = true
val text = streetCardView.cards.take(3).formatted(itemView.context)
flopEditText.setText(text)
}
itemView.findViewById<EditText>(R.id.turnEditText)?.let { turnEditText ->
// turnEditText.isVisible = streetCardView.street.ordinal >= Street.TURN.ordinal
turnEditText.isFocusable = (street == Street.TURN)
if (streetCardView.cards.size >= 4) {
val text = streetCardView.cards[3].formatted(itemView.context)
turnEditText.setText(text)
} else {
turnEditText.text = null
}
}
itemView.findViewById<EditText>(R.id.riverEditText)?.let { riverEditText ->
// riverEditText.isVisible = streetCardView.street.ordinal >= Street.RIVER.ordinal
riverEditText.isFocusable = (street == Street.RIVER)
if (streetCardView.cards.size >= 5) {
val text = streetCardView.cards[4].formatted(itemView.context)
riverEditText.setText(text)
} else {
riverEditText.text = null
}
}
}
}
}

@ -18,7 +18,7 @@ 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.modules.handhistory.views.KeyboardListener
import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardHeader
import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardView
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
import net.pokeranalytics.android.util.extensions.findById
@ -113,8 +113,13 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
Timber.d("Current selection is ${selection.index} / ${selection.keyboard}")
retrieveEditTextInputConnection(selection.index)
val positions = this.model.positionsForSelection()
this.keyboard.setPositions(positions)
when (it.keyboard) {
HHKeyboard.ACTION -> {
val positions = this.model.positionsForSelection()
this.keyboard.setPositions(positions)
}
else -> {}
}
} ?: run {
this.keyboard.setEditText(null, null)
}
@ -217,7 +222,7 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDataSource, RowRepr
else -> throw PAIllegalStateException("Unmanaged tag value: $tag")
}
}
is StreetCardHeader -> {
is StreetCardView -> {
HHKeyboard.CARD
}
else -> null

@ -6,7 +6,7 @@ import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.ui.modules.handhistory.HandRowType
class StreetCardHeader(var street: Street, var cards: List<Card>, var potSize: Double) : HandHistoryRow {
class StreetCardView(var street: Street, var cards: List<Card>, var potSize: Double) : HandHistoryRow {
override val viewType: Int = HandRowType.STREET.ordinal

@ -6,32 +6,58 @@
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/flopEditText"
android:layout_width="180dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:imeOptions="actionDone"
android:maxLines="1" />
android:layout_weight="3"
android:layout_margin="4dp"/>
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/turnEditText"
android:layout_width="60dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:imeOptions="actionDone"
android:maxLines="1" />
android:layout_weight="1"
android:layout_margin="4dp" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/riverEditText"
android:layout_width="60dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:imeOptions="actionDone"
android:maxLines="1" />
android:layout_weight="1"
android:layout_margin="4dp" />
<Space
android:layout_width="0dp"
android:layout_height="44dp"
android:layout_weight="3" />
<!-- <androidx.appcompat.widget.AppCompatEditText-->
<!-- android:id="@+id/flopEditText"-->
<!-- android:layout_width="180dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="16dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- android:layout_marginBottom="16dp"-->
<!-- android:imeOptions="actionDone"-->
<!-- android:maxLines="1" />-->
<!-- <androidx.appcompat.widget.AppCompatEditText-->
<!-- android:id="@+id/turnEditText"-->
<!-- android:layout_width="60dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="16dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- android:layout_marginBottom="16dp"-->
<!-- android:imeOptions="actionDone"-->
<!-- android:maxLines="1" />-->
<!-- <androidx.appcompat.widget.AppCompatEditText-->
<!-- android:id="@+id/riverEditText"-->
<!-- android:layout_width="60dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="16dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- android:layout_marginBottom="16dp"-->
<!-- android:imeOptions="actionDone"-->
<!-- android:maxLines="1" />-->
</LinearLayout>

@ -54,4 +54,7 @@
<color name="player_color_8">#ff573d</color>
<color name="player_color_9">#ff971e</color>
<color name="diamond">#ff971e</color>
<color name="clover">#71fb94</color>
</resources>

@ -354,6 +354,9 @@
<item name="backgroundTint">@color/kaki_medium</item>
</style>
<style name="PokerAnalyticsTheme.CardButton" parent="Widget.MaterialComponents.Button">
</style>
<style name="PokerAnalyticsTheme.SecondaryButton" parent="PokerAnalyticsTheme.Button">
<item name="backgroundTint">@color/white</item>
</style>

Loading…
Cancel
Save