diff --git a/app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt b/app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt index ecf86fd2..0efd832e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt @@ -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>() - /*** * 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() fun rowRepresentables() : List { @@ -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 diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 90601f1d..018fac38 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -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) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Card.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Card.kt index 57363494..f9db2a52 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Card.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Card.kt @@ -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.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 + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt index 76a6b297..b662177f 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt @@ -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 } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt index a583c6c6..0ee772da 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt @@ -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(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(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(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(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 + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt index 66510fd8..7d11d523 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt @@ -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 diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardHeader.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardView.kt similarity index 84% rename from app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardHeader.kt rename to app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardView.kt index 34657bf9..734e51dd 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardHeader.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardView.kt @@ -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, var potSize: Double) : HandHistoryRow { +class StreetCardView(var street: Street, var cards: List, var potSize: Double) : HandHistoryRow { override val viewType: Int = HandRowType.STREET.ordinal diff --git a/app/src/main/res/layout/row_hand_cards.xml b/app/src/main/res/layout/row_hand_cards.xml index 3d6616cb..bf801bdf 100644 --- a/app/src/main/res/layout/row_hand_cards.xml +++ b/app/src/main/res/layout/row_hand_cards.xml @@ -6,32 +6,58 @@ + android:layout_weight="3" + android:layout_margin="4dp"/> + android:layout_weight="1" + android:layout_margin="4dp" /> + android:layout_weight="1" + android:layout_margin="4dp" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index bea117ef..8c51a0c2 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -54,4 +54,7 @@ #ff573d #ff971e + #ff971e + #71fb94 + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 42859281..a2d86ec6 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -354,6 +354,9 @@ @color/kaki_medium + +