Merge branch 'master' of gitlab.com:stax-river/poker-analytics

# Conflicts:
#	app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt
#	app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt
#	app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt
#	app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
#	app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt
#	app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt
#	app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
feature/top10
Aurelien Hubert 7 years ago
commit 67d0ecffa2
  1. 4
      app/src/androidTest/java/net/pokeranalytics/android/ExampleInstrumentedUnitTest.kt
  2. 4
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  3. 9
      app/src/main/java/net/pokeranalytics/android/model/interfaces/Savable.kt
  4. 155
      app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt
  5. 11
      app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt
  6. 13
      app/src/main/java/net/pokeranalytics/android/model/realm/Location.kt
  7. 50
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  8. 3
      app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt
  9. 87
      app/src/main/java/net/pokeranalytics/android/model/realm/TournamentFeature.kt
  10. 120
      app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt
  11. 43
      app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableAdapter.kt
  12. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/DataListFragment.kt
  13. 20
      app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt
  14. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/HistoryFragment.kt
  15. 25
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt
  16. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt
  17. 14
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/DateTimePickerManager.kt
  18. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt
  19. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt
  20. 34
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt
  21. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt
  22. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListGameFragment.kt
  23. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetSumFragment.kt
  24. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetTableSizeGridFragment.kt
  25. 30
      app/src/main/java/net/pokeranalytics/android/ui/view/RowEditable.kt
  26. 7
      app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentable.kt
  27. 14
      app/src/main/java/net/pokeranalytics/android/ui/view/RowRepresentableEditDescriptor.kt
  28. 99
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  29. 64
      app/src/main/res/layout/row_title_switch.xml

@ -177,14 +177,14 @@ class ExampleInstrumentedUnitTest : RealmInstrumentedUnitTest() {
val stdHourly = results.computedStat(Stat.STANDARD_DEVIATION_HOURLY) val stdHourly = results.computedStat(Stat.STANDARD_DEVIATION_HOURLY)
if (stdHourly != null) { if (stdHourly != null) {
assertEquals(50.0, stdHourly.value, delta) assertEquals(111.8, stdHourly.value, delta)
} else { } else {
Assert.fail("No stdHourly stat") Assert.fail("No stdHourly stat")
} }
val std100 = results.computedStat(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS) val std100 = results.computedStat(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS)
if (std100 != null) { if (std100 != null) {
assertEquals(250.0, std100.value, delta) assertEquals(559.01, std100.value, delta)
} else { } else {
Assert.fail("No std100 stat") Assert.fail("No std100 stat")
} }

@ -194,8 +194,8 @@ class Calculator {
// Session Set // Session Set
var hourlyStdSum: Double = 0.0 var hourlyStdSum: Double = 0.0
sessionSets.forEach { sg -> sessionSets.forEach { set ->
hourlyStdSum += Math.pow(sg.hourlyRate - hourlyRate, 2.0) hourlyStdSum += Math.pow(set.hourlyRate - hourlyRate, 2.0)
} }
val hourlyStandardDeviation: Double = Math.sqrt(hourlyStdSum / sessionSets.size) val hourlyStandardDeviation: Double = Math.sqrt(hourlyStdSum / sessionSets.size)

@ -1,5 +1,7 @@
package net.pokeranalytics.android.model.interfaces package net.pokeranalytics.android.model.interfaces
import net.pokeranalytics.android.ui.view.RowRepresentable
/** /**
* An interface to easily handle the validity of any object we want to save * An interface to easily handle the validity of any object we want to save
*/ */
@ -16,4 +18,11 @@ interface Savable {
* A unique identifier getter * A unique identifier getter
*/ */
fun uniqueIdentifier(): String fun uniqueIdentifier(): String
/**
* a method to handle the modification of the object.
* Through [RowRepresentable] the object is able to update the right variable with the new value.
*/
fun updateValue(value: Any?, row: RowRepresentable)
} }

@ -3,92 +3,91 @@ package net.pokeranalytics.android.model.realm
import android.text.InputType import android.text.InputType
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.model.interfaces.Savable import net.pokeranalytics.android.model.interfaces.Savable
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.* import net.pokeranalytics.android.ui.view.*
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
open class Bankroll(name: String = "") : RealmObject(), Savable, open class Bankroll(name: String = "") : RealmObject(), Savable,
RowRepresentableDataSource, RowRepresentableDataSource, RowRepresentable {
RowEditable, RowRepresentable {
companion object {
companion object { fun newInstance() : Bankroll {
fun newInstance(): Bankroll { var bankroll: Bankroll = Bankroll()
var bankroll: Bankroll = Bankroll() return bankroll
return bankroll }
} }
}
@PrimaryKey
@PrimaryKey var id = UUID.randomUUID().toString()
var id = UUID.randomUUID().toString()
// the name of the bankroll
// the name of the bankroll var name: String = name
var name: String = name
// Indicates whether the bankroll is live or online
// Indicates whether the bankroll is live or online var live: Boolean = true
var live: Boolean = true
// The list of transactions of the bankroll
// The list of transactions of the bankroll var transactions: RealmList<Transaction> = RealmList()
var transactions: RealmList<Transaction> = RealmList()
// The currency of the bankroll
// The currency of the bankroll var currency: Currency? = null
var currency: Currency? = null
// @todo rate management
// @todo rate management
override fun getDisplayName(): String {
override fun getDisplayName(): String { return this.name
return this.name }
}
override fun uniqueIdentifier(): String {
override fun uniqueIdentifier(): String { return this.id
return this.id }
}
override fun adapterRows(): ArrayList<RowRepresentable> {
override fun adapterRows(): ArrayList<RowRepresentable> { val rows = ArrayList<RowRepresentable>()
val rows = ArrayList<RowRepresentable>() rows.add(SimpleRow.NAME)
rows.add(SimpleRow.NAME) rows.addAll(BankrollRow.values())
rows.addAll(BankrollRow.values()) return rows
return rows }
}
override fun stringForRow(row: RowRepresentable): String {
override fun stringForRow(row: RowRepresentable): String { return when (row) {
return when (row) { SimpleRow.NAME -> this.name
SimpleRow.NAME -> this.name else -> return super.stringForRow(row)
BankrollRow.LIVE -> if (this.live) "live" else "online" }
BankrollRow.CURRENCY -> this.currency?.code ?: "" }
else -> return super.stringForRow(row)
} override fun boolForRow(row: RowRepresentable): Boolean {
} when (row) {
BankrollRow.LIVE -> return this.live
override fun boolForRow(row: RowRepresentable): Boolean { else -> return super.boolForRow(row)
when (row) { }
BankrollRow.LIVE -> return true }
else -> return super.boolForRow(row)
} override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> {
} val data = java.util.ArrayList<RowRepresentableEditDescriptor>()
when (row) {
override fun rowEditableDescriptors(row: RowRepresentable): ArrayList<RowEditableDescriptor> { SimpleRow.NAME -> data.add(
val data = java.util.ArrayList<RowEditableDescriptor>() RowRepresentableEditDescriptor(
when (row) { this.name,
SimpleRow.NAME -> data.add( SimpleRow.NAME.resId,
RowEditableDescriptor( InputType.TYPE_CLASS_TEXT
this.name, )
SimpleRow.NAME.resId, )
InputType.TYPE_CLASS_TEXT }
) return data
) }
}
return data override fun updateValue(value: Any?, row: RowRepresentable) {
} when (row) {
SimpleRow.NAME -> this.name = value as String? ?: ""
override fun updateValue(value: Any?, row: RowRepresentable) { BankrollRow.LIVE -> this.live = value as Boolean? ?: false
when (row) {
SimpleRow.NAME -> this.name = value as String? ?: "" }
} }
}
override fun isValidForSave(): Boolean { override fun isValidForSave(): Boolean {
return this.name.isNotEmpty() return this.name.isNotEmpty()

@ -6,10 +6,11 @@ import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.model.interfaces.Savable import net.pokeranalytics.android.model.interfaces.Savable
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.* import net.pokeranalytics.android.ui.view.*
import java.util.* import java.util.*
open class Game : RealmObject(), Savable, RowRepresentableDataSource, RowEditable, open class Game : RealmObject(), Savable, RowRepresentableDataSource,
RowRepresentable { RowRepresentable {
@PrimaryKey @PrimaryKey
@ -44,18 +45,18 @@ open class Game : RealmObject(), Savable, RowRepresentableDataSource, RowEditabl
} }
} }
override fun rowEditableDescriptors(row: RowRepresentable): ArrayList<RowEditableDescriptor> { override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> {
val data = java.util.ArrayList<RowEditableDescriptor>() val data = java.util.ArrayList<RowRepresentableEditDescriptor>()
when (row) { when (row) {
SimpleRow.NAME -> data.add( SimpleRow.NAME -> data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
this.name, this.name,
SimpleRow.NAME.resId, SimpleRow.NAME.resId,
InputType.TYPE_CLASS_TEXT InputType.TYPE_CLASS_TEXT
) )
) )
GameRow.SHORT_NAME -> data.add( GameRow.SHORT_NAME -> data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
this.shortName, this.shortName,
GameRow.SHORT_NAME.resId, GameRow.SHORT_NAME.resId,
InputType.TYPE_CLASS_TEXT InputType.TYPE_CLASS_TEXT

@ -6,11 +6,14 @@ import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.model.interfaces.Savable import net.pokeranalytics.android.model.interfaces.Savable
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.view.* import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.LocationRow
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.SimpleRow
import java.util.* import java.util.*
open class Location : RealmObject(), Savable, RowRepresentableDataSource, RowEditable, RowRepresentable { open class Location : RealmObject(), Savable, RowRepresentableDataSource, RowRepresentable {
@PrimaryKey @PrimaryKey
var id = UUID.randomUUID().toString() var id = UUID.randomUUID().toString()
@ -46,11 +49,11 @@ open class Location : RealmObject(), Savable, RowRepresentableDataSource, RowEdi
} }
} }
override fun rowEditableDescriptors(row: RowRepresentable): ArrayList<RowEditableDescriptor> { override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> {
val data = java.util.ArrayList<RowEditableDescriptor>() val data = java.util.ArrayList<RowRepresentableEditDescriptor>()
when (row) { when (row) {
SimpleRow.NAME -> data.add( SimpleRow.NAME -> data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
this.name, this.name,
SimpleRow.NAME.resId, SimpleRow.NAME.resId,
InputType.TYPE_CLASS_TEXT InputType.TYPE_CLASS_TEXT

@ -14,21 +14,19 @@ import net.pokeranalytics.android.model.extensions.SessionState
import net.pokeranalytics.android.model.extensions.getState import net.pokeranalytics.android.model.extensions.getState
import net.pokeranalytics.android.model.interfaces.Savable import net.pokeranalytics.android.model.interfaces.Savable
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowEditable import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowEditableDescriptor
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.SessionRow import net.pokeranalytics.android.ui.view.SessionRow
import net.pokeranalytics.android.util.getDuration import net.pokeranalytics.android.util.getDuration
import net.pokeranalytics.android.util.round import net.pokeranalytics.android.util.round
import net.pokeranalytics.android.util.shortDateTime import net.pokeranalytics.android.util.short
import net.pokeranalytics.android.util.toCurrency import net.pokeranalytics.android.util.toCurrency
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
open class Session : RealmObject(), SessionInterface, Savable, open class Session : RealmObject(), SessionInterface, Savable,
RowRepresentableDataSource, RowRepresentableDataSource, RowRepresentable {
RowEditable, RowRepresentable {
@PrimaryKey @PrimaryKey
var id = UUID.randomUUID().toString() var id = UUID.randomUUID().toString()
@ -307,25 +305,25 @@ open class Session : RealmObject(), SessionInterface, Savable,
} }
} }
override fun rowEditableDescriptors(row: RowRepresentable): ArrayList<RowEditableDescriptor> { override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> {
val data = ArrayList<RowEditableDescriptor>() val data = ArrayList<RowRepresentableEditDescriptor>()
when (row) { when (row) {
SessionRow.BUY_IN -> { SessionRow.BUY_IN -> {
// Add first & second buttons values, current value & set the 2 edit texts // Add first & second buttons values, current value & set the 2 edit texts
data.add(RowEditableDescriptor(100.0 * (cgBigBlind ?: 0.0))) data.add(RowRepresentableEditDescriptor(100.0 * (cgBigBlind ?: 0.0)))
data.add(RowEditableDescriptor(200.0 * (cgBigBlind ?: 0.0))) data.add(RowRepresentableEditDescriptor(200.0 * (cgBigBlind ?: 0.0)))
data.add(RowEditableDescriptor(buyin)) data.add(RowRepresentableEditDescriptor(buyin))
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
"", "",
inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
) )
) )
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
"", "",
inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
) )
@ -333,7 +331,7 @@ open class Session : RealmObject(), SessionInterface, Savable,
} }
SessionRow.CASHED_OUT -> { SessionRow.CASHED_OUT -> {
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
result?.cashout, result?.cashout,
inputType = InputType.TYPE_CLASS_NUMBER inputType = InputType.TYPE_CLASS_NUMBER
) )
@ -342,30 +340,30 @@ open class Session : RealmObject(), SessionInterface, Savable,
SessionRow.TIPS -> { SessionRow.TIPS -> {
// Disable the buttons with value = 0, add current value & set the 2 edit texts // Disable the buttons with value = 0, add current value & set the 2 edit texts
// TODO: manage tips // TODO: manage tips
data.add(RowEditableDescriptor(cgSmallBlind ?: 0.0)) data.add(RowRepresentableEditDescriptor(cgSmallBlind ?: 0.0))
data.add(RowEditableDescriptor(cgBigBlind ?: 0.0)) data.add(RowRepresentableEditDescriptor(cgBigBlind ?: 0.0))
data.add(RowEditableDescriptor(0)) data.add(RowRepresentableEditDescriptor(0))
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
"", "",
inputType = InputType.TYPE_CLASS_NUMBER inputType = InputType.TYPE_CLASS_NUMBER
) )
) )
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
"", "",
inputType = InputType.TYPE_CLASS_NUMBER inputType = InputType.TYPE_CLASS_NUMBER
) )
) )
} }
SessionRow.TABLE_SIZE -> { SessionRow.TABLE_SIZE -> {
data.add(RowEditableDescriptor(tableSize)) data.add(RowRepresentableEditDescriptor(tableSize))
} }
SessionRow.GAME -> { SessionRow.GAME -> {
// Add current game & games list // Add current game & games list
data.add(RowEditableDescriptor(limit)) data.add(RowRepresentableEditDescriptor(limit))
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
game, game,
data = LiveData.GAME.items(realm) data = LiveData.GAME.items(realm)
) )
@ -374,7 +372,7 @@ open class Session : RealmObject(), SessionInterface, Savable,
SessionRow.LOCATION -> { SessionRow.LOCATION -> {
// Add current location and locations list // Add current location and locations list
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
location, location,
data = LiveData.LOCATION.items(realm) data = LiveData.LOCATION.items(realm)
) )
@ -383,7 +381,7 @@ open class Session : RealmObject(), SessionInterface, Savable,
SessionRow.BANKROLL -> { SessionRow.BANKROLL -> {
// Add current bankroll and bankrolls list // Add current bankroll and bankrolls list
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
bankroll, bankroll,
data = LiveData.BANKROLL.items(realm) data = LiveData.BANKROLL.items(realm)
) )
@ -391,14 +389,14 @@ open class Session : RealmObject(), SessionInterface, Savable,
} }
SessionRow.BLINDS -> { SessionRow.BLINDS -> {
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
cgSmallBlind, cgSmallBlind,
R.string.smallblind, R.string.smallblind,
InputType.TYPE_CLASS_NUMBER InputType.TYPE_CLASS_NUMBER
) )
) )
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
cgBigBlind, cgBigBlind,
R.string.bigblind, R.string.bigblind,
InputType.TYPE_CLASS_NUMBER InputType.TYPE_CLASS_NUMBER
@ -407,7 +405,7 @@ open class Session : RealmObject(), SessionInterface, Savable,
} }
SessionRow.COMMENT -> { SessionRow.COMMENT -> {
data.add( data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
comment, comment,
R.string.comment, R.string.comment,
InputType.TYPE_CLASS_TEXT InputType.TYPE_CLASS_TEXT

@ -41,6 +41,9 @@ open class SessionSet() : RealmObject() {
@Ignore // a duration shortcut @Ignore // a duration shortcut
var hourlyRate: Double = 0.0 var hourlyRate: Double = 0.0
get () {
return this.netResult / this.hourlyDuration
}
@Ignore @Ignore
var estimatedHands: Double = 25.0 * (this.timeFrame?.hourlyDuration?.toDouble() ?: 0.0) var estimatedHands: Double = 25.0 * (this.timeFrame?.hourlyDuration?.toDouble() ?: 0.0)

@ -6,59 +6,62 @@ import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.model.interfaces.Savable import net.pokeranalytics.android.model.interfaces.Savable
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.view.* import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.SimpleRow
import net.pokeranalytics.android.ui.view.TournamentFeatureRow
import java.util.* import java.util.*
open class TournamentFeature : RealmObject(), Savable, RowRepresentableDataSource, RowEditable, RowRepresentable { open class TournamentFeature : RealmObject(), Savable, RowRepresentableDataSource, RowRepresentable {
@PrimaryKey @PrimaryKey
var id = UUID.randomUUID().toString() var id = UUID.randomUUID().toString()
// The name of the feature // The name of the feature
var name: String = "" var name: String = ""
override fun getDisplayName(): String { override fun getDisplayName(): String {
return this.name return this.name
} }
override fun uniqueIdentifier(): String { override fun uniqueIdentifier(): String {
return this.id return this.id
} }
override fun adapterRows(): ArrayList<RowRepresentable> { override fun adapterRows(): ArrayList<RowRepresentable> {
val rows = ArrayList<RowRepresentable>() val rows = ArrayList<RowRepresentable>()
rows.add(SimpleRow.NAME) rows.add(SimpleRow.NAME)
rows.addAll(TournamentFeatureRow.values()) rows.addAll(TournamentFeatureRow.values())
return rows return rows
} }
override fun stringForRow(row: RowRepresentable): String { override fun stringForRow(row: RowRepresentable): String {
return when (row) { return when (row) {
SimpleRow.NAME -> this.name SimpleRow.NAME -> this.name
else -> return super.stringForRow(row) else -> return super.stringForRow(row)
} }
} }
override fun rowEditableDescriptors(row: RowRepresentable): ArrayList<RowEditableDescriptor> { override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> {
val data = java.util.ArrayList<RowEditableDescriptor>() val data = java.util.ArrayList<RowRepresentableEditDescriptor>()
when (row) { when (row) {
SimpleRow.NAME -> data.add( SimpleRow.NAME -> data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
this.name, this.name,
SimpleRow.NAME.resId, SimpleRow.NAME.resId,
InputType.TYPE_CLASS_TEXT InputType.TYPE_CLASS_TEXT
) )
) )
} }
return data return data
} }
override fun updateValue(value: Any?, row: RowRepresentable) { override fun updateValue(value: Any?, row: RowRepresentable) {
when (row) { when (row) {
SimpleRow.NAME -> this.name = value as String? ?: "" SimpleRow.NAME -> this.name = value as String? ?: ""
} }
} }
override fun isValidForSave(): Boolean { override fun isValidForSave(): Boolean {
return this.name.isNotEmpty() return this.name.isNotEmpty()

@ -10,64 +10,64 @@ import net.pokeranalytics.android.ui.view.*
import java.util.* import java.util.*
open class TransactionType : RealmObject(), Savable, RowRepresentableDataSource, RowEditable, RowRepresentable { open class TransactionType : RealmObject(), Savable, RowRepresentableDataSource, RowRepresentable {
@PrimaryKey @PrimaryKey
var id = UUID.randomUUID().toString() var id = UUID.randomUUID().toString()
// The name of the transaction type // The name of the transaction type
var name: String = "" var name: String = ""
// Whether or not the amount is added, or subtracted to the bankroll total // Whether or not the amount is added, or subtracted to the bankroll total
var additive: Boolean = false var additive: Boolean = false
// Whether or not the type can be deleted by the user // Whether or not the type can be deleted by the user
var lock: Boolean = false var lock: Boolean = false
// The predefined kind, if necessary, like: Withdrawal, deposit, or tips // The predefined kind, if necessary, like: Withdrawal, deposit, or tips
var kind: Int? = null var kind: Int? = null
override fun getDisplayName(): String { override fun getDisplayName(): String {
return this.name return this.name
} }
override fun uniqueIdentifier(): String { override fun uniqueIdentifier(): String {
return this.id return this.id
} }
override fun adapterRows(): ArrayList<RowRepresentable> { override fun adapterRows(): ArrayList<RowRepresentable> {
val rows = ArrayList<RowRepresentable>() val rows = ArrayList<RowRepresentable>()
rows.add(SimpleRow.NAME) rows.add(SimpleRow.NAME)
rows.addAll(TransactionTypeRow.values()) rows.addAll(TransactionTypeRow.values())
return rows return rows
} }
override fun stringForRow(row: RowRepresentable): String { override fun stringForRow(row: RowRepresentable): String {
return when (row) { return when (row) {
SimpleRow.NAME -> this.name SimpleRow.NAME -> this.name
else -> return super.stringForRow(row) else -> return super.stringForRow(row)
} }
} }
override fun rowEditableDescriptors(row: RowRepresentable): ArrayList<RowEditableDescriptor> { override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> {
val data = java.util.ArrayList<RowEditableDescriptor>() val data = java.util.ArrayList<RowRepresentableEditDescriptor>()
when (row) { when (row) {
SimpleRow.NAME -> data.add( SimpleRow.NAME -> data.add(
RowEditableDescriptor( RowRepresentableEditDescriptor(
this.name, this.name,
SimpleRow.NAME.resId, SimpleRow.NAME.resId,
InputType.TYPE_CLASS_TEXT InputType.TYPE_CLASS_TEXT
) )
) )
} }
return data return data
} }
override fun updateValue(value: Any?, row: RowRepresentable) { override fun updateValue(value: Any?, row: RowRepresentable) {
when (row) { when (row) {
SimpleRow.NAME -> this.name = value as String? ?: "" SimpleRow.NAME -> this.name = value as String? ?: ""
} }
} }
override fun isValidForSave(): Boolean { override fun isValidForSave(): Boolean {
return this.name.isNotEmpty() return this.name.isNotEmpty()
@ -80,6 +80,6 @@ open class TransactionType : RealmObject(), Savable, RowRepresentableDataSource,
} }
enum class TransactionKind { enum class TransactionKind {
WITHDRAWAL, WITHDRAWAL,
DEPOSIT DEPOSIT
} }

@ -1,10 +1,11 @@
package net.pokeranalytics.android.ui.adapter package net.pokeranalytics.android.ui.adapter
import android.view.View import android.os.Handler
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import net.pokeranalytics.android.ui.view.BindableHolder import net.pokeranalytics.android.ui.view.BindableHolder
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
@ -28,10 +29,18 @@ interface RowRepresentableDataSource : DisplayableDataSource {
fun indexForRow(row:RowRepresentable): Int { fun indexForRow(row:RowRepresentable): Int {
return this.adapterRows().indexOf(row) return this.adapterRows().indexOf(row)
} }
/**
* A list of [RowRepresentableEditDescriptor] object specifying the way the edition will be handled
*/
fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor> {
return ArrayList()
}
} }
interface RowRepresentableDelegate : DisplayableDelegate { interface RowRepresentableDelegate {
fun onIndexSelected(position: Int) {} fun onRowSelected(position: Int, row: RowRepresentable, fromAction:Boolean = false) {}
fun onRowValueChanged(value: Any?, row: RowRepresentable) {}
} }
/** /**
@ -77,14 +86,6 @@ interface DisplayableDataSource {
* */ * */
} }
/**
* A delegate used to propagate UI actions
*/
interface DisplayableDelegate {
fun onRowSelected(row: RowRepresentable) {}
fun onActionSelected(row: RowRepresentable) {}
}
/** /**
* An adapter capable of displaying a list of RowRepresentables * An adapter capable of displaying a list of RowRepresentables
* @param dataSource the datasource providing rows * @param dataSource the datasource providing rows
@ -110,18 +111,8 @@ class RowRepresentableAdapter(
} }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val dynamicRow = this.dataSource.rowRepresentableForPosition(position) val rowRepresentable = this.dataSource.rowRepresentableForPosition(position)
(holder as BindableHolder).bind(position, rowRepresentable, this)
val listener = View.OnClickListener {
delegate?.onRowSelected(dynamicRow)
delegate?.onIndexSelected(position)
}
val actionListener = View.OnClickListener {
delegate?.onActionSelected(dynamicRow)
}
(holder as BindableHolder).bind(dynamicRow, this.dataSource, listener, actionListener)
} }
/** /**
@ -130,7 +121,11 @@ class RowRepresentableAdapter(
fun refreshRow(row: RowRepresentable) { fun refreshRow(row: RowRepresentable) {
val index = this.dataSource.indexForRow(row) val index = this.dataSource.indexForRow(row)
if (index >= 0) { if (index >= 0) {
notifyItemChanged(index) val handler = Handler()
handler.post {
notifyItemChanged(index)
}
} }
} }

@ -53,7 +53,7 @@ class DataListFragment : PokerAnalyticsFragment(), RowRepresentableDataSource,
return this.items.indexOf(row) return this.items.indexOf(row)
} }
override fun onIndexSelected(position: Int) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
this.dataType.relatedResultsRepresentable?.let { this.dataType.relatedResultsRepresentable?.let {
EditableDataActivity.newInstance(requireContext(), it.ordinal, (this.items[position] as Savable).uniqueIdentifier()) EditableDataActivity.newInstance(requireContext(), it.ordinal, (this.items[position] as Savable).uniqueIdentifier())
} }

@ -18,7 +18,7 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetDelegate import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetDelegate
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.view.RowEditable import net.pokeranalytics.android.ui.view.BankrollRow
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import timber.log.Timber import timber.log.Timber
@ -55,27 +55,17 @@ class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate,
return true return true
} }
override fun onRowSelected(row: RowRepresentable) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
BottomSheetFragment.create(fragmentManager, row, this, (this.item as RowEditable).rowEditableDescriptors(row)) BottomSheetFragment.create(fragmentManager, row,this, (this.item as RowRepresentableDataSource).editDescriptors(row))
} }
override fun clickOnAdd(row: RowRepresentable) { override fun clickOnAdd(row: RowRepresentable) {
Toast.makeText(requireContext(), "Add new element: $row", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), "Add new element: $row", Toast.LENGTH_SHORT).show()
} }
override fun clickOnClear(row: RowRepresentable) { override fun onRowValueChanged(value: Any?, row: RowRepresentable) {
Toast.makeText(requireContext(), "Clear: $row", Toast.LENGTH_SHORT).show()
this.getRealm().executeTransaction { this.getRealm().executeTransaction {
(this.item as RowEditable).updateValue(null, row) (this.item as Savable).updateValue(value, row)
it.copyToRealmOrUpdate(this.item)
}
rowRepresentableAdapter.refreshRow(row)
}
override fun setValue(value: Any?, row: RowRepresentable) {
this.getRealm().executeTransaction {
(this.item as RowEditable).updateValue(value, row)
it.copyToRealmOrUpdate(this.item)
} }
rowRepresentableAdapter.refreshRow(row) rowRepresentableAdapter.refreshRow(row)
} }

@ -144,7 +144,7 @@ class HistoryFragment : PokerAnalyticsFragment(), RowRepresentableDataSource,
return this.sessions.indexOf(row) return this.sessions.indexOf(row)
} }
override fun onRowSelected(row: RowRepresentable) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
SessionActivity.newInstance(requireContext(), sessionId = (row as Savable).uniqueIdentifier()) SessionActivity.newInstance(requireContext(), sessionId = (row as Savable).uniqueIdentifier())
} }
} }

@ -66,8 +66,13 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott
} }
override fun onRowSelected(row: RowRepresentable) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
val data = currentSession.rowEditableDescriptors(row) if (fromAction) {
Toast.makeText(requireContext(), "Action for row: $row", Toast.LENGTH_SHORT).show()
return
}
val data = currentSession.editDescriptors(row)
when (row) { when (row) {
SessionRow.START_DATE -> DateTimePickerManager.create( SessionRow.START_DATE -> DateTimePickerManager.create(
requireContext(), requireContext(),
@ -81,14 +86,10 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott
this, this,
currentSession.timeFrame?.endDate currentSession.timeFrame?.endDate
) )
else -> BottomSheetFragment.create(fragmentManager, row, this, data) else -> BottomSheetFragment.create(fragmentManager, row,this, data)
} }
} }
override fun onActionSelected(row: RowRepresentable) {
Toast.makeText(requireContext(), "Action for row: $row", Toast.LENGTH_SHORT).show()
}
override fun clickOnAdd(row: RowRepresentable) { override fun clickOnAdd(row: RowRepresentable) {
when (row) { when (row) {
SessionRow.GAME -> EditableDataActivity.newInstance(requireContext(), LiveData.GAME.ordinal) SessionRow.GAME -> EditableDataActivity.newInstance(requireContext(), LiveData.GAME.ordinal)
@ -97,15 +98,7 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott
} }
} }
override fun clickOnClear(row: RowRepresentable) { override fun onRowValueChanged(value: Any?, row: RowRepresentable) {
currentSession.updateValue(null, row)
sessionAdapter.refreshRow(row)
when (row) {
SessionRow.START_DATE, SessionRow.END_DATE -> updateSessionUI()
}
}
override fun setValue(value: Any?, row: RowRepresentable) {
currentSession.updateValue(value, row) currentSession.updateValue(value, row)
sessionAdapter.refreshRow(row) sessionAdapter.refreshRow(row)
when (row) { when (row) {

@ -49,7 +49,7 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDataSource,
return rows return rows
} }
override fun onRowSelected(row: RowRepresentable) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
DataListActivity.newInstance(requireContext(), (row as SettingRow).ordinal) DataListActivity.newInstance(requireContext(), (row as SettingRow).ordinal)
} }

@ -8,7 +8,7 @@ import android.text.format.DateFormat
import android.widget.DatePicker import android.widget.DatePicker
import android.widget.TimePicker import android.widget.TimePicker
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import java.util.* import java.util.*
@ -18,14 +18,14 @@ class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
private var context: Context? = null private var context: Context? = null
lateinit var row: RowRepresentable lateinit var row: RowRepresentable
lateinit var bottomSheetDelegate: BottomSheetDelegate lateinit var delegate: RowRepresentableDelegate
lateinit var calendar: Calendar lateinit var calendar: Calendar
companion object { companion object {
fun create( fun create(
context: Context, context: Context,
row: RowRepresentable, row: RowRepresentable,
bottomSheetDelegate: BottomSheetDelegate, delegate: RowRepresentableDelegate,
date: Date? date: Date?
) : DateTimePickerManager { ) : DateTimePickerManager {
@ -35,7 +35,7 @@ class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
val dateTimePickerManager = DateTimePickerManager() val dateTimePickerManager = DateTimePickerManager()
dateTimePickerManager.context = context dateTimePickerManager.context = context
dateTimePickerManager.row = row dateTimePickerManager.row = row
dateTimePickerManager.bottomSheetDelegate = bottomSheetDelegate dateTimePickerManager.delegate = delegate
dateTimePickerManager.calendar = calendar dateTimePickerManager.calendar = calendar
dateTimePickerManager.showDatePicker() dateTimePickerManager.showDatePicker()
@ -54,7 +54,7 @@ class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
override fun onTimeSet(view: TimePicker?, hourOfDay: Int, minute: Int) { override fun onTimeSet(view: TimePicker?, hourOfDay: Int, minute: Int) {
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay) calendar.set(Calendar.HOUR_OF_DAY, hourOfDay)
calendar.set(Calendar.MINUTE, minute) calendar.set(Calendar.MINUTE, minute)
bottomSheetDelegate.setValue(calendar.time, row) delegate.onRowValueChanged(calendar.time, row)
} }
/** /**
@ -67,7 +67,7 @@ class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
context?.let { context?.let {
val datePickerDialog = DatePickerDialog(it, this, year, month, day) val datePickerDialog = DatePickerDialog(it, this, year, month, day)
datePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, it.getString(R.string.clear)) { dialog, _ -> datePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, it.getString(R.string.clear)) { dialog, _ ->
bottomSheetDelegate.clickOnClear(row) delegate.onRowValueChanged(null, row)
dialog.dismiss() dialog.dismiss()
} }
datePickerDialog.show() datePickerDialog.show()
@ -83,7 +83,7 @@ class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
context?.let { context?.let {
val timePickerDialog = TimePickerDialog(context, this, hour, minute, DateFormat.is24HourFormat(context)) val timePickerDialog = TimePickerDialog(context, this, hour, minute, DateFormat.is24HourFormat(context))
timePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, it.getString(R.string.clear)) { dialog, _ -> timePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, it.getString(R.string.clear)) { dialog, _ ->
bottomSheetDelegate.clickOnClear(row) delegate.onRowValueChanged(null, row)
dialog.dismiss() dialog.dismiss()
} }
timePickerDialog.show() timePickerDialog.show()

@ -63,7 +63,7 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() {
editText2.setOnEditorActionListener { v, actionId, event -> editText2.setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE) { if (actionId == EditorInfo.IME_ACTION_DONE) {
bottomSheetDelegate.setValue(values, row) this.delegate.onRowValueChanged(values, row)
dismiss() dismiss()
true true
} else { } else {

@ -56,7 +56,7 @@ class BottomSheetEditTextFragment : BottomSheetFragment() {
editText1.setOnEditorActionListener { v, actionId, event -> editText1.setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE) { if (actionId == EditorInfo.IME_ACTION_DONE) {
bottomSheetDelegate.setValue(value, row) delegate.onRowValueChanged(value, row)
dismiss() dismiss()
true true
} else { } else {

@ -9,7 +9,8 @@ import androidx.fragment.app.FragmentManager
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.fragment_bottom_sheet.* import kotlinx.android.synthetic.main.fragment_bottom_sheet.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.view.RowEditableDescriptor import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
enum class BottomSheetType { enum class BottomSheetType {
@ -23,25 +24,26 @@ enum class BottomSheetType {
SUM SUM
} }
interface BottomSheetDelegate { interface BottomSheetDelegate : RowRepresentableDelegate {
fun clickOnAdd(row: RowRepresentable) fun clickOnAdd(row: RowRepresentable) {}
fun clickOnClear(row: RowRepresentable) fun clickOnClear(row: RowRepresentable) {
fun setValue(value: Any?, row: RowRepresentable) this.onRowValueChanged(null, row)
}
} }
open class BottomSheetFragment : BottomSheetDialogFragment() { open class BottomSheetFragment : BottomSheetDialogFragment() {
lateinit var row: RowRepresentable lateinit var row: RowRepresentable
lateinit var bottomSheetDelegate: BottomSheetDelegate lateinit var delegate: BottomSheetDelegate
private var data: ArrayList<RowEditableDescriptor> = ArrayList() private var rowRepresentableEditDescriptors: ArrayList<RowRepresentableEditDescriptor> = ArrayList()
companion object { companion object {
fun create( fun create(
fragmentManager: FragmentManager?, fragmentManager: FragmentManager?,
row: RowRepresentable, row: RowRepresentable,
bottomSheetDelegate: BottomSheetDelegate, delegate: BottomSheetDelegate,
data: ArrayList<RowEditableDescriptor> rowRepresentableEditDescriptors: ArrayList<RowRepresentableEditDescriptor>
): BottomSheetFragment { ): BottomSheetFragment {
val bottomSheetFragment = when (row.bottomSheetType) { val bottomSheetFragment = when (row.bottomSheetType) {
@ -57,8 +59,8 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
bottomSheetFragment.show(fragmentManager, "bottomSheet") bottomSheetFragment.show(fragmentManager, "bottomSheet")
bottomSheetFragment.row = row bottomSheetFragment.row = row
bottomSheetFragment.bottomSheetDelegate = bottomSheetDelegate bottomSheetFragment.delegate = delegate
bottomSheetFragment.data = data bottomSheetFragment.rowRepresentableEditDescriptors = rowRepresentableEditDescriptors
return bottomSheetFragment return bottomSheetFragment
} }
} }
@ -93,16 +95,16 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
// Menu // Menu
bottomSheetToolbar.menu.findItem(R.id.actionClear).setOnMenuItemClickListener { bottomSheetToolbar.menu.findItem(R.id.actionClear).setOnMenuItemClickListener {
bottomSheetDelegate.clickOnClear(row) this.delegate.clickOnClear(row)
dismiss() dismiss()
true true
} }
bottomSheetToolbar.menu.findItem(R.id.actionAdd).setOnMenuItemClickListener { bottomSheetToolbar.menu.findItem(R.id.actionAdd).setOnMenuItemClickListener {
bottomSheetDelegate.clickOnAdd(row) this.delegate.clickOnAdd(row)
true true
} }
bottomSheetToolbar.menu.findItem(R.id.actionCheck).setOnMenuItemClickListener { bottomSheetToolbar.menu.findItem(R.id.actionCheck).setOnMenuItemClickListener {
bottomSheetDelegate.setValue(getValue(), row) this.delegate.onRowValueChanged(getValue(), row)
dismiss() dismiss()
true true
} }
@ -112,8 +114,8 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
/** /**
* Return the data list * Return the data list
*/ */
fun getData(): ArrayList<RowEditableDescriptor> { fun getData(): ArrayList<RowRepresentableEditDescriptor> {
return data return this.rowRepresentableEditDescriptors
} }
open fun getValue(): Any? { open fun getValue(): Any? {

@ -56,15 +56,15 @@ class BottomSheetListFragment : BottomSheetFragment(), RowRepresentableDataSourc
return super.indexForRow(row) return super.indexForRow(row)
} }
override fun onIndexSelected(position: Int) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
realmData?.let { realmData?.let {
val selectedData = it[position] val selectedData = it[position]
selectedData?.let {data -> selectedData?.let {data ->
bottomSheetDelegate.setValue(data, row) this.delegate.onRowValueChanged(data, row)
dismiss() dismiss()
} }
} }
super.onIndexSelected(position) super.onRowSelected(position, row, fromAction)
} }
/** /**

@ -66,16 +66,16 @@ class BottomSheetListGameFragment : BottomSheetFragment(),
return super.indexForRow(row) return super.indexForRow(row)
} }
override fun onIndexSelected(position: Int) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
realmData?.let { realmData?.let {
val selectedData = it[position] val selectedData = it[position]
selectedData?.let { data -> selectedData?.let { data ->
values[1] = data values[1] = data
bottomSheetDelegate.setValue(values, row) this.delegate.onRowValueChanged(data, row)
dismiss() dismiss()
} }
} }
super.onIndexSelected(position) super.onRowSelected(position, row, fromAction)
} }
/** /**

@ -70,7 +70,7 @@ class BottomSheetSumFragment : BottomSheetFragment() {
button1.text = defaultValue1.toCurrency() button1.text = defaultValue1.toCurrency()
button1.visibility = if (defaultValue1 > 0) View.VISIBLE else View.GONE button1.visibility = if (defaultValue1 > 0) View.VISIBLE else View.GONE
button1.setOnClickListener { button1.setOnClickListener {
bottomSheetDelegate.setValue(currentDefaultValue + defaultValue1, row) this.delegate.onRowValueChanged(data, row)
dismiss() dismiss()
} }
@ -84,7 +84,7 @@ class BottomSheetSumFragment : BottomSheetFragment() {
button2.text = defaultValue2.toCurrency() button2.text = defaultValue2.toCurrency()
button2.visibility = if (defaultValue2 > 0) View.VISIBLE else View.GONE button2.visibility = if (defaultValue2 > 0) View.VISIBLE else View.GONE
button2.setOnClickListener { button2.setOnClickListener {
bottomSheetDelegate.setValue(currentDefaultValue + defaultValue2, row) this.delegate.onRowValueChanged(data, row)
dismiss() dismiss()
} }
@ -110,7 +110,7 @@ class BottomSheetSumFragment : BottomSheetFragment() {
editText2.setOnEditorActionListener { v, actionId, event -> editText2.setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE) { if (actionId == EditorInfo.IME_ACTION_DONE) {
bottomSheetDelegate.setValue(value, row) this.delegate.onRowValueChanged(data, row)
dismiss() dismiss()
true true
} else { } else {

@ -84,8 +84,8 @@ class BottomSheetTableSizeGridFragment : BottomSheetFragment(),
return TableSize.all.size return TableSize.all.size
} }
override fun onRowSelected(row: RowRepresentable) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
bottomSheetDelegate.setValue((this.row as TableSize).numberOfPlayer, this.row) this.delegate.onRowValueChanged((this.row as TableSize).numberOfPlayer, row)
dismiss() dismiss()
} }
@ -149,7 +149,7 @@ class BottomSheetTableSizeGridFragment : BottomSheetFragment() {
val viewManager = GridLayoutManager(requireContext(), 3) val viewManager = GridLayoutManager(requireContext(), 3)
dataAdapter = TableSizeGridAdapter(dataList) dataAdapter = TableSizeGridAdapter(dataList)
dataAdapter.onClickOnItem = { position -> dataAdapter.onClickOnItem = { position ->
bottomSheetDelegate.setValue(position + 2, row) bottomSheetDelegate.onRowValueChangedFromBottomSheet(position + 2, row)
dismiss() dismiss()
} }

@ -1,30 +0,0 @@
package net.pokeranalytics.android.ui.view
import android.text.InputType
import io.realm.RealmResults
/**
* An interface to describe how an object can be editable and to handle the update of the object
*/
interface RowEditable {
/**
* A list of [RowEditableDescriptor] object specifying the way the edition will be handled
*/
fun rowEditableDescriptors(row: RowRepresentable): ArrayList<RowEditableDescriptor>
/**
* a method to handle the modification of the object.
* Through [RowRepresentable] the object is able to update the right variable with the new value.
*/
fun updateValue(value: Any?, row: RowRepresentable)
}
/**
* An container class to describe the way an field of an object will be edited
*/
class RowEditableDescriptor(
var defaultValue: Any? = null,
var hint: Int? = null,
var inputType: Int? = InputType.TYPE_CLASS_TEXT,
var data: RealmResults<*>? = null
)

@ -199,21 +199,19 @@ enum class SimpleRow : RowRepresentable {
} }
enum class BankrollRow : RowRepresentable { enum class BankrollRow : RowRepresentable {
LIVE, LIVE;
CURRENCY;
override val resId: Int? override val resId: Int?
get() { get() {
return when (this) { return when (this) {
LIVE -> R.string.live LIVE -> R.string.live
CURRENCY -> R.string.currency
} }
} }
override val viewType: Int override val viewType: Int
get() { get() {
return when (this) { return when (this) {
LIVE, CURRENCY -> RowViewType.TITLE_VALUE.ordinal LIVE -> RowViewType.TITLE_SWITCH.ordinal
} }
} }
@ -221,7 +219,6 @@ enum class BankrollRow : RowRepresentable {
get() { get() {
return when (this) { return when (this) {
LIVE -> BottomSheetType.NONE LIVE -> BottomSheetType.NONE
CURRENCY -> BottomSheetType.LIST
} }
} }

@ -0,0 +1,14 @@
package net.pokeranalytics.android.ui.view
import android.text.InputType
import io.realm.RealmResults
/**
* An container class to describe the way an field of an object will be edited
*/
class RowRepresentableEditDescriptor(
var defaultValue: Any? = null,
var hint: Int? = null,
var inputType: Int? = InputType.TYPE_CLASS_TEXT,
var data: RealmResults<*>? = null
)

@ -10,18 +10,23 @@ import kotlinx.android.synthetic.main.row_bottom_sheet_title.view.*
import kotlinx.android.synthetic.main.row_header_title_value.view.* import kotlinx.android.synthetic.main.row_header_title_value.view.*
import kotlinx.android.synthetic.main.row_history_session.view.* import kotlinx.android.synthetic.main.row_history_session.view.*
import kotlinx.android.synthetic.main.row_title.view.* import kotlinx.android.synthetic.main.row_title.view.*
import kotlinx.android.synthetic.main.row_title_switch.view.*
import kotlinx.android.synthetic.main.row_title_value.view.* import kotlinx.android.synthetic.main.row_title_value.view.*
import kotlinx.android.synthetic.main.row_title_value_action.view.* import kotlinx.android.synthetic.main.row_title_value_action.view.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
/** /**
* An interface used to factor the configuration of RecyclerView.ViewHolder * An interface used to factor the configuration of RecyclerView.ViewHolder
*/ */
interface BindableHolder { interface BindableHolder {
fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource? = null, listener: View.OnClickListener, actionListener: View.OnClickListener? = null) {} fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
}
} }
@ -32,6 +37,7 @@ enum class RowViewType {
TITLE, TITLE,
TITLE_VALUE, TITLE_VALUE,
TITLE_VALUE_ACTION, TITLE_VALUE_ACTION,
TITLE_SWITCH,
DATA, DATA,
BOTTOM_SHEET_DATA, BOTTOM_SHEET_DATA,
TITLE_GRID, TITLE_GRID,
@ -39,13 +45,14 @@ enum class RowViewType {
inner class FakeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class FakeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder { BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
} }
} }
inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class RowSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder { BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
if (row.displayHeader) { if (row.displayHeader) {
itemView.sessionHeader.isVisible = true itemView.sessionHeader.isVisible = true
@ -55,68 +62,111 @@ enum class RowViewType {
} }
itemView.sessionRow.setData(row as Session) itemView.sessionRow.setData(row as Session)
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.sessionRow.setOnClickListener(listener) itemView.sessionRow.setOnClickListener(listener)
} }
} }
inner class CellSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { inner class CellSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.title.text = row.localizedTitle(itemView.context) itemView.title.text = row.localizedTitle(itemView.context)
itemView.container.setOnClickListener(listener) val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.container.setOnClickListener(listener)
} }
} }
inner class DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { inner class DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.rowTitle_title.text = row.getDisplayName() itemView.rowTitle_title.text = row.getDisplayName()
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.rowTitle_container.setOnClickListener(listener) itemView.rowTitle_container.setOnClickListener(listener)
} }
} }
inner class BottomSheetDataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { inner class BottomSheetDataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.rowBottomSheet_title.text = row.getDisplayName() itemView.rowBottomSheet_title.text = row.getDisplayName()
val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.rowBottomSheet_container.setOnClickListener(listener) itemView.rowBottomSheet_container.setOnClickListener(listener)
} }
} }
inner class TitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class TitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder { BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.rowTitle_title.text = row.localizedTitle(itemView.context) itemView.rowTitle_title.text = row.localizedTitle(itemView.context)
itemView.rowTitle_container.setOnClickListener(listener) val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.rowTitle_container.setOnClickListener(listener)
} }
} }
inner class HeaderTitleValueViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class HeaderTitleValueViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder { BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.rowHeaderTitleValue_title.text = row.localizedTitle(itemView.context) itemView.rowHeaderTitleValue_title.text = row.localizedTitle(itemView.context)
rowRepresentableDataSource?.let { adapter.dataSource?.let {
itemView.rowHeaderTitleValue_value.text = it.stringForRow(row) itemView.rowHeaderTitleValue_value.text = it.stringForRow(row)
} }
itemView.rowHeaderTitleValue_container.setOnClickListener(listener) val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.rowHeaderTitleValue_container.setOnClickListener(listener)
itemView.rowHeaderTitleValue_separator.visibility = if (row.needSeparator) View.VISIBLE else View.GONE itemView.rowHeaderTitleValue_separator.visibility = if (row.needSeparator) View.VISIBLE else View.GONE
} }
} }
inner class TitleValueViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class TitleValueViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder { BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.rowTitleValue_title.text = row.localizedTitle(itemView.context) itemView.rowTitleValue_title.text = row.localizedTitle(itemView.context)
rowRepresentableDataSource?.let { adapter.dataSource?.let {
itemView.rowTitleValue_value.text = it.stringForRow(row) itemView.rowTitleValue_value.text = it.stringForRow(row)
} }
itemView.rowTitleValue_container.setOnClickListener(listener) val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
itemView.rowTitleValue_container.setOnClickListener(listener)
itemView.rowTitleValue_separator.visibility = if (row.needSeparator) View.VISIBLE else View.GONE itemView.rowTitleValue_separator.visibility = if (row.needSeparator) View.VISIBLE else View.GONE
} }
} }
inner class TitleSwitchViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.rowTitleSwitch_title.text = row.localizedTitle(itemView.context)
adapter.dataSource.let {
itemView.rowTitleSwitch_switch.isChecked = it.boolForRow(row)
itemView.rowTitleSwitch_switch.setOnCheckedChangeListener { _, b ->
adapter.delegate?.onRowValueChanged(b, row)
}
}
val listener = View.OnClickListener {
itemView.rowTitleSwitch_switch.isChecked = !itemView.rowTitleSwitch_switch.isChecked
adapter.delegate?.onRowValueChanged(itemView.rowTitleSwitch_switch.isChecked, row)
}
itemView.rowTitleSwitch_container.setOnClickListener(listener)
itemView.rowTitleSwitch_separator.visibility = if (row.needSeparator) View.VISIBLE else View.GONE
}
}
inner class TitleValueActionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class TitleValueActionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder { BindableHolder {
override fun bind(row: RowRepresentable, rowRepresentableDataSource: RowRepresentableDataSource?, listener: View.OnClickListener, actionListener: View.OnClickListener?) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.rowTitleValueAction_title.text = row.localizedTitle(itemView.context) itemView.rowTitleValueAction_title.text = row.localizedTitle(itemView.context)
rowRepresentableDataSource?.let { rowDelegate -> adapter.dataSource?.let { rowDelegate ->
val value = rowDelegate.stringForRow(row) val value = rowDelegate.stringForRow(row)
itemView.rowTitleValueAction_value.text = value itemView.rowTitleValueAction_value.text = value
@ -125,7 +175,13 @@ enum class RowViewType {
itemView.rowTitleValueAction_action.setImageResource(icon) itemView.rowTitleValueAction_action.setImageResource(icon)
} }
} }
itemView.rowTitleValueAction_container.setOnClickListener(listener) val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row)
}
val actionListener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row, true)
}
itemView.rowTitleValueAction_container.setOnClickListener(listener)
itemView.rowTitleValueAction_action.setOnClickListener(actionListener) itemView.rowTitleValueAction_action.setOnClickListener(actionListener)
} }
} }
@ -161,6 +217,13 @@ enum class RowViewType {
false false
) )
) )
TITLE_SWITCH -> TitleSwitchViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.row_title_switch,
parent,
false
)
)
DATA -> DataViewHolder( DATA -> DataViewHolder(
LayoutInflater.from(parent.context).inflate( LayoutInflater.from(parent.context).inflate(
R.layout.row_title, R.layout.row_title,

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rowTitleSwitch.container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/rowTitleSwitch.title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"
app:layout_constraintTop_toTopOf="parent"
tools:text="Data Type Title"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="16dp"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/rowTitleSwitch.switch"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@+id/rowTitleSwitch.title"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="356dp"/>
<FrameLayout
android:id="@+id/rowTitleSwitch.separator"
android:layout_width="match_parent"
android:layout_height="16dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="center"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="@color/kaki" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save