Stat formatting + Preferences

feature/top10
Laurent 7 years ago
parent 098cc3acde
commit 45e61d9a46
  1. 11
      app/src/main/java/net/pokeranalytics/android/calculus/Format.kt
  2. 51
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt
  3. 4
      app/src/main/java/net/pokeranalytics/android/exceptions/Exceptions.kt
  4. 9
      app/src/main/java/net/pokeranalytics/android/ui/adapter/RowRepresentableDataSource.kt
  5. 20
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatsFragment.kt
  6. 4
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  7. 7
      app/src/main/java/net/pokeranalytics/android/util/NumbersExtension.kt
  8. 41
      app/src/main/java/net/pokeranalytics/android/util/Preferences.kt

@ -1,8 +1,15 @@
package net.pokeranalytics.android.calculus package net.pokeranalytics.android.calculus
import android.content.Context
import android.graphics.Color import android.graphics.Color
import androidx.core.content.ContextCompat
class StatFormat(text: String, color: Int = Color.WHITE) { class TextFormat(text: String, color: Int? = null) {
var text: String = text var text: String = text
var color: Int = color private var color: Int? = color
fun getColor(context: Context) : Int {
this.color?.let { return ContextCompat.getColor(context, it) }
return Color.WHITE
}
} }

@ -1,8 +1,15 @@
package net.pokeranalytics.android.calculus package net.pokeranalytics.android.calculus
import android.content.Context
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.FormattingException
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
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.formatted
import net.pokeranalytics.android.util.toMinutes
import java.text.NumberFormat
import java.util.*
/** /**
* An enum representing all the types of Session statistics * An enum representing all the types of Session statistics
@ -72,6 +79,15 @@ enum class Stat : RowRepresentable {
} }
} }
val threshold: Double
get() {
return when (this) {
WIN_RATIO -> 50.0
else -> 0.0
}
}
override val viewType: Int = RowViewType.TITLE_VALUE.ordinal override val viewType: Int = RowViewType.TITLE_VALUE.ordinal
override var displayHeader: Boolean = false override var displayHeader: Boolean = false
override var headerValues: ArrayList<String> = ArrayList() override var headerValues: ArrayList<String> = ArrayList()
@ -106,15 +122,40 @@ class ComputedStat(stat: Stat, value: Double) {
/** /**
* Formats the value of the stat to be suitable for display * Formats the value of the stat to be suitable for display
*/ */
fun format() : StatFormat { fun format(context: Context) : TextFormat {
return StatFormat("${value}".toUpperCase()) when (this.stat) {
// Amounts + red/green
Stat.NETRESULT, Stat.HOURLY_RATE, Stat.AVERAGE, Stat.NET_BB_PER_100_HANDS, Stat.HOURLY_RATE_BB,
Stat.AVERAGE_NET_BB -> {
val numberFormat = NumberFormat.getCurrencyInstance(Preferences.getCurrencyLocale(context))
val color = if (this.value >= this.stat.threshold) R.color.green else R.color.red
return TextFormat(numberFormat.format(this.value), color)
} // white integers
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_GAMES, Stat.HANDS_PLAYED -> {
return TextFormat("${this.value.toInt()}")
} // white durations
Stat.DURATION, Stat.AVERAGE_DURATION -> {
return TextFormat("${this.value.toLong().toMinutes()}")
} // red/green percentages
Stat.WIN_RATIO, Stat.ROI -> {
val color = if (this.value >= this.stat.threshold) R.color.green else R.color.red
return TextFormat("${this.value.formatted()}%", color)
} // white amounts
Stat.AVERAGE_BUYIN, Stat.STANDARD_DEVIATION, Stat.STANDARD_DEVIATION_HOURLY,
Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> {
val numberFormat = NumberFormat.getCurrencyInstance(Preferences.getCurrencyLocale(context))
return TextFormat(numberFormat.format(this.value))
}
else -> throw FormattingException("Stat formatting of ${this.stat.name} not handled")
}
} }
/** /**
* Returns a StatFormat instance for an evolution value located at the specified [index] * Returns a TextFormat instance for an evolution value located at the specified [index]
*/ */
fun evolutionValueFormat(index: Int) : StatFormat { fun evolutionValueFormat(index: Int) : TextFormat {
return StatFormat("undef") return TextFormat("undef")
} }
} }

@ -2,4 +2,8 @@ package net.pokeranalytics.android.exceptions
class ModelException(message: String) : Exception(message) { class ModelException(message: String) : Exception(message) {
}
class FormattingException(message: String) : Exception(message) {
} }

@ -1,10 +1,10 @@
package net.pokeranalytics.android.ui.adapter package net.pokeranalytics.android.ui.adapter
import android.content.Context import android.content.Context
import net.pokeranalytics.android.calculus.TextFormat
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
interface RowRepresentableDataSource : DisplayableDataSource { interface RowRepresentableDataSource : DisplayableDataSource {
fun rowRepresentableForPosition(position:Int): RowRepresentable { fun rowRepresentableForPosition(position:Int): RowRepresentable {
@ -74,6 +74,13 @@ interface DisplayableDataSource {
return "" return ""
} }
/**
* Returns a string for a specific row
*/
fun statFormatForRow(row: RowRepresentable): TextFormat {
return TextFormat("you should override this")
}
/** /**
* Returns an action icon identifier for a specific row * Returns an action icon identifier for a specific row
*/ */

@ -12,6 +12,7 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.SessionGroup import net.pokeranalytics.android.calculus.SessionGroup
import net.pokeranalytics.android.calculus.TextFormat
import net.pokeranalytics.android.model.StatRepresentable import net.pokeranalytics.android.model.StatRepresentable
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.RowRepresentableAdapter
@ -57,14 +58,25 @@ class StatsFragment : PokerAnalyticsFragment(), RowRepresentableDataSource {
return this.rowRepresentables return this.rowRepresentables
} }
override fun stringForRow(row: RowRepresentable): String { override fun statFormatForRow(row: RowRepresentable): TextFormat {
if (row is StatRepresentable) { if (row is StatRepresentable) {
val format = row.computedStat.format() context?.let {
return format.text return row.computedStat.format(it)
}
} }
return "shouldn't happen :)" return TextFormat("shouldn't happen :)")
} }
// override fun stringForRow(row: RowRepresentable): String {
// if (row is StatRepresentable) {
// context?.let {
// val format = row.computedStat.format(it)
// return format.text
// }
// }
// return "shouldn't happen :)"
// }
/** /**
* Init data * Init data
*/ */

@ -208,7 +208,9 @@ enum class RowViewType {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) { override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
itemView.rowStatsTitleValue_title.text = row.localizedTitle(itemView.context) itemView.rowStatsTitleValue_title.text = row.localizedTitle(itemView.context)
adapter.dataSource?.let { adapter.dataSource?.let {
itemView.rowStatsTitleValue_value.text = it.stringForRow(row, itemView.context) val format = it.statFormatForRow(row)
itemView.rowStatsTitleValue_value.text = format.text
itemView.rowStatsTitleValue_value.setTextColor(format.getColor(itemView.context))
} }
val listener = View.OnClickListener { val listener = View.OnClickListener {
adapter.delegate?.onRowSelected(position, row) adapter.delegate?.onRowSelected(position, row)

@ -11,6 +11,13 @@ fun Double.round(): String {
return formatter.format(this) return formatter.format(this)
} }
fun Double.formatted(): String {
val format = NumberFormat.getNumberInstance()
format.maximumFractionDigits = 2
format.minimumFractionDigits = 0
return format.format(this)
}
fun Double.toCurrency(): String { fun Double.toCurrency(): String {
val format = NumberFormat.getCurrencyInstance() val format = NumberFormat.getCurrencyInstance()
format.maximumFractionDigits = 2 format.maximumFractionDigits = 2

@ -0,0 +1,41 @@
package net.pokeranalytics.android.util
import android.content.Context
import android.preference.PreferenceManager
import java.util.*
class Preferences {
enum class Keys(identifier: String) {
CURRENCY_LANGUAGE("CurrencyLanguage")
}
companion object {
fun setString(key: Keys, value: String, context: Context) {
var preferences = PreferenceManager.getDefaultSharedPreferences(context)
var editor = preferences.edit()
editor.putString(key.toString(), value)
editor.commit()
}
fun getString(key: Keys, context: Context) : String? {
var preferences = PreferenceManager.getDefaultSharedPreferences(context)
return preferences.getString(key.name, null)
}
fun setCurrencyLanguage(language: String, context: Context) {
Preferences.setString(Keys.CURRENCY_LANGUAGE, language, context)
}
fun getCurrencyLocale(context : Context) : Locale {
val currencyLanguage = Preferences.getString(Keys.CURRENCY_LANGUAGE, context)
if (currencyLanguage != null) {
return Locale(currencyLanguage)
}
return Locale.getDefault()
}
}
}
Loading…
Cancel
Save