Refactoring + documenting

hh
Laurent 5 years ago
parent 40d60ff559
commit a18e180f07
  1. 4
      app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt
  2. 4
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt
  3. 5
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt
  4. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt
  5. 95
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerAnimator.kt
  6. 16
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt
  7. 6
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerModel.kt
  8. 21
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt
  9. 206
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt

@ -4,7 +4,7 @@ import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.modules.handhistory.replayer.HandStep import net.pokeranalytics.android.ui.modules.handhistory.replayer.HandStep
import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerConfiguration import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerAnimator
enum class Street : HandStep { enum class Street : HandStep {
PREFLOP, PREFLOP,
@ -46,7 +46,7 @@ enum class Street : HandStep {
// } // }
override fun frames( override fun frames(
configuration: ReplayerConfiguration, animator: ReplayerAnimator,
canvas: Canvas, canvas: Canvas,
context: Context, context: Context,
update: () -> Unit update: () -> Unit

@ -33,7 +33,7 @@ import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheet
import net.pokeranalytics.android.ui.modules.datalist.DataListActivity import net.pokeranalytics.android.ui.modules.datalist.DataListActivity
import net.pokeranalytics.android.ui.modules.handhistory.model.* import net.pokeranalytics.android.ui.modules.handhistory.model.*
import net.pokeranalytics.android.ui.modules.handhistory.replayer.HandStep import net.pokeranalytics.android.ui.modules.handhistory.replayer.HandStep
import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerConfiguration import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerAnimator
import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableDrawer import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableDrawer
import net.pokeranalytics.android.ui.modules.handhistory.views.KeyboardListener import net.pokeranalytics.android.ui.modules.handhistory.views.KeyboardListener
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
@ -720,7 +720,7 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
private fun videoExport() { private fun videoExport() {
val config = ReplayerConfiguration(this.model.handHistory) val config = ReplayerAnimator(this.model.handHistory)
val width = 480 val width = 480
val height = 480 val height = 480

@ -10,8 +10,7 @@ import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.model.realm.handhistory.toReadRow import net.pokeranalytics.android.model.realm.handhistory.toReadRow
import net.pokeranalytics.android.ui.modules.handhistory.HandRowType import net.pokeranalytics.android.ui.modules.handhistory.HandRowType
import net.pokeranalytics.android.ui.modules.handhistory.replayer.HandStep import net.pokeranalytics.android.ui.modules.handhistory.replayer.HandStep
import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerConfiguration import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerAnimator
import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableDrawer
import kotlin.math.max import kotlin.math.max
/*** /***
@ -318,7 +317,7 @@ class ComputedAction(var manager: ActionManager,
// } // }
override fun frames( override fun frames(
configuration: ReplayerConfiguration, animator: ReplayerAnimator,
canvas: Canvas, canvas: Canvas,
context: Context, context: Context,
update: () -> Unit update: () -> Unit

@ -22,7 +22,7 @@ interface HandStep {
// //
// class DistributeChips(street: Street) : Animation(street) // class DistributeChips(street: Street) : Animation(street)
fun frames(configuration: ReplayerConfiguration, canvas: Canvas, context: Context, update: () -> (Unit)) fun frames(animator: ReplayerAnimator, canvas: Canvas, context: Context, update: () -> (Unit))
companion object { companion object {

@ -9,7 +9,9 @@ import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction
import timber.log.Timber import timber.log.Timber
import kotlin.math.max import kotlin.math.max
class ReplayerConfiguration(var handHistory: HandHistory) { class ReplayerAnimator(var handHistory: HandHistory) {
// Steps & Frames
enum class FrameType { enum class FrameType {
STATE, STATE,
@ -17,14 +19,27 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
DISTRIBUTION_ANIMATION DISTRIBUTION_ANIMATION
} }
/***
* The number of frames per second
*/
private val animationFramesPerSecond = 60 private val animationFramesPerSecond = 60
val animationRate: Long val animationRate: Long
get() { return 1000L / this.animationFramesPerSecond} get() { return 1000L / this.animationFramesPerSecond}
private val animationDuration = 200L
/***
* The animation duration
*/
private val chipAnimationDuration = 200L
/***
* The number of frames required for a chip animation
*/
private val framesForChipsAnimation: Int private val framesForChipsAnimation: Int
get() { return (animationDuration / animationRate).toInt() } get() { return (chipAnimationDuration / animationRate).toInt() }
/***
* The total number of frames for each kind of step
*/
private val numberOfFramesForCurrentStep: Int private val numberOfFramesForCurrentStep: Int
get() { get() {
return when (val step = this.currentStep) { return when (val step = this.currentStep) {
@ -35,8 +50,14 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
} }
} }
/***
* The index of the current frame
*/
private var currentFrame = 0 private var currentFrame = 0
/***
* The frame type for the current combination of step + frame index
*/
val frameType: FrameType val frameType: FrameType
get() { get() {
return when (val step = this.currentStep) { return when (val step = this.currentStep) {
@ -58,19 +79,28 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
} }
} }
// val isLastFrame: Boolean /***
// get() { return this.currentFrame == numberOfFramesForCurrentStep - 1 } * Returns if the animator has more frame to show
*/
val shouldShowAdditionalFrame: Boolean val shouldShowAdditionalFrame: Boolean
get() { get() {
return this.currentFrame < this.numberOfFramesForCurrentStep return this.currentFrame < this.numberOfFramesForCurrentStep
} }
/***
* The list of actions associated with the hand history
*/
var actionList: ActionList = ActionList(null) var actionList: ActionList = ActionList(null)
private set private set
/***
* The list of steps, scannable with back/forward buttons
*/
private var steps: List<HandStep> private var steps: List<HandStep>
/***
* The index of the last blind in the action list
*/
private var lastBlindIndex: Int = 0 private var lastBlindIndex: Int = 0
private var currentStepIndex: Int = 0 private var currentStepIndex: Int = 0
@ -82,15 +112,38 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
this.currentFrame = if (backwards) this.numberOfFramesForCurrentStep - 1 else 0 this.currentFrame = if (backwards) this.numberOfFramesForCurrentStep - 1 else 0
} }
init { val currentStep: HandStep
get() {
return this.steps[this.currentStepIndex]
}
init {
this.actionList.load(this.handHistory) this.actionList.load(this.handHistory)
this.lastBlindIndex = max(this.actionList.indexOfLast { it.action.type?.isBlind == true }, 0)
this.currentStepIndex = this.lastBlindIndex + 1 // initialize at big blind
this.steps = HandStep.createSteps(this.handHistory) this.steps = HandStep.createSteps(this.handHistory)
val bi = this.steps.indexOfLast { it is ComputedAction && it.action.type?.isBlind == true }
this.lastBlindIndex = max(bi, 0) // in case indexOfLast returns -1
this.currentStepIndex = this.lastBlindIndex + 1 // initialize at big blind
} }
/***
* Let the animator know when a frame has been drawn
*/
fun frameDrawn() {
this.currentFrame += 1
}
/***
* Reset the step and the frame to the start of the hand
*/
fun restart() {
this.currentStepIndex = 0
this.currentFrame = 0
}
// Dimensions
data class Size(var width: Float, var height: Float) data class Size(var width: Float, var height: Float)
data class Circle(var x: Float, var y: Float, var radius: Float) data class Circle(var x: Float, var y: Float, var radius: Float)
data class TextPoint(var x: Float, var y: Float, var fontSize: Float) data class TextPoint(var x: Float, var y: Float, var fontSize: Float)
@ -143,6 +196,10 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
var totalPotTextPoint = TextPoint(0f, 0f, 0f) var totalPotTextPoint = TextPoint(0f, 0f, 0f)
var potChipCircle = Circle(0f, 0f, 0f) var potChipCircle = Circle(0f, 0f, 0f)
var tableStrokeWidth = 30f
var playerStrokeWidth = 8f
var cardStrokeWidth = 8f
/*** /***
* Calculates the position of all elements to draw * Calculates the position of all elements to draw
*/ */
@ -163,9 +220,12 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
this.tableRect = RectF(tableHPadding, tableVPadding, width - tableHPadding, height - tableVPadding) this.tableRect = RectF(tableHPadding, tableVPadding, width - tableHPadding, height - tableVPadding)
this.tableCornerRadius = (if (portrait) width else height) / 8 this.tableCornerRadius = (if (portrait) width else height) / 8
this.tableStrokeWidth = tableHPadding / 5f
this.playerStrokeWidth = this.tableStrokeWidth / 4f
this.cardStrokeWidth = this.tableStrokeWidth / 4f
// pz for Player Zone // pz for Player Zone
val pzHeight = height / playerPerColumn val pzHeight = height / playerPerColumn
// val pzWidth = width / playerPerRow
this.playerItemsHeight = pzHeight / 3 this.playerItemsHeight = pzHeight / 3
this.playerItemsWidth = this.tableHPadding * 2 * this.paddingPercentage this.playerItemsWidth = this.tableHPadding * 2 * this.paddingPercentage
@ -374,11 +434,6 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
} }
} }
val currentStep: HandStep
get() {
return this.steps[this.currentStepIndex]
}
private val lastActionAtStep: ComputedAction? private val lastActionAtStep: ComputedAction?
get() { get() {
when (val step = this.currentStep) { when (val step = this.currentStep) {
@ -417,10 +472,6 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
return null return null
} }
fun frameDrawn() {
this.currentFrame += 1
}
fun animatedChipCircleFromPot(positionIndex: Int): Circle { fun animatedChipCircleFromPot(positionIndex: Int): Circle {
return this.animatedChipCircle(this.potChipCircle, this.chipCircle(positionIndex)) return this.animatedChipCircle(this.potChipCircle, this.chipCircle(positionIndex))
} }
@ -430,7 +481,6 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
} }
private fun animatedChipCircle(origin: Circle, destination: Circle): Circle { private fun animatedChipCircle(origin: Circle, destination: Circle): Circle {
val completion = (this.currentFrame + 1).toFloat() / this.numberOfFramesForCurrentStep.toFloat() val completion = (this.currentFrame + 1).toFloat() / this.numberOfFramesForCurrentStep.toFloat()
val x = origin.x + (destination.x - origin.x) * completion val x = origin.x + (destination.x - origin.x) * completion
@ -439,11 +489,6 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
return Circle(x, y, radius) return Circle(x, y, radius)
} }
fun restart() {
this.currentStepIndex = 0
this.currentFrame = 0
}
fun isPlayerAllin(playerIndex: Int): Boolean { fun isPlayerAllin(playerIndex: Int): Boolean {
this.lastActionAtStep?.action?.index?.let { index -> this.lastActionAtStep?.action?.index?.let { index ->
return this.actionList.isPlayerAllin(playerIndex, index) return this.actionList.isPlayerAllin(playerIndex, index)

@ -79,9 +79,9 @@ class ReplayerFragment : RealmFragment() {
} }
private fun loadHand(handHistory: HandHistory) { private fun loadHand(handHistory: HandHistory) {
val config = ReplayerConfiguration(handHistory) val config = ReplayerAnimator(handHistory)
this.replayer.configuration = config this.replayer.animator = config
this.model.configuration = config this.model.animator = config
} }
private val mainHandler = Handler(Looper.getMainLooper()) private val mainHandler = Handler(Looper.getMainLooper())
@ -101,18 +101,18 @@ class ReplayerFragment : RealmFragment() {
private fun play() { private fun play() {
val isFinished = this.model.configuration?.isReplayFinished ?: false val isFinished = this.model.animator?.isReplayFinished ?: false
if (isFinished) { if (isFinished) {
this.model.configuration?.restart() this.model.animator?.restart()
} }
mainHandler.postDelayed(timerRunnable, 0L) this.mainHandler.postDelayed(timerRunnable, 0L)
this.model.isPlaying = true this.model.isPlaying = true
this.play_pause.setImageResource(R.drawable.ic_outline_pause) this.play_pause.setImageResource(R.drawable.ic_outline_pause)
} }
private fun pause() { private fun pause() {
mainHandler.removeCallbacks(timerRunnable) this.mainHandler.removeCallbacks(timerRunnable)
this.model.isPlaying = false this.model.isPlaying = false
this.play_pause.setImageResource(R.drawable.ic_play_arrow) this.play_pause.setImageResource(R.drawable.ic_play_arrow)
} }
@ -129,7 +129,7 @@ class ReplayerFragment : RealmFragment() {
private fun refreshPlayButtonIfNecessary() { private fun refreshPlayButtonIfNecessary() {
val isFinished = this.model.configuration?.isReplayFinished ?: true val isFinished = this.model.animator?.isReplayFinished ?: true
if (isFinished) { if (isFinished) {
pause() pause()
} }

@ -10,7 +10,7 @@ class ReplayerModel : ViewModel() {
FAST(2.0) FAST(2.0)
} }
var configuration: ReplayerConfiguration? = null var animator: ReplayerAnimator? = null
var isPlaying: Boolean = false var isPlaying: Boolean = false
@ -20,11 +20,11 @@ class ReplayerModel : ViewModel() {
private set private set
fun previousStep() { fun previousStep() {
this.configuration?.previous() this.animator?.previous()
} }
fun nextStep() { fun nextStep() {
this.configuration?.next() this.animator?.next()
} }
val actionDelay: Long val actionDelay: Long

@ -6,14 +6,10 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction
import timber.log.Timber
class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) { class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) {
lateinit var configuration: ReplayerConfiguration lateinit var animator: ReplayerAnimator
private val animationHandler = Handler(Looper.getMainLooper()) private val animationHandler = Handler(Looper.getMainLooper())
@ -22,18 +18,17 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs)
} }
init { init {
TableDrawer.configurePaints(context)
this.viewTreeObserver.addOnGlobalLayoutListener { this.viewTreeObserver.addOnGlobalLayoutListener {
this.configuration.setDimension(width.toFloat(), height.toFloat()) this.animator.setDimension(width.toFloat(), height.toFloat())
TableDrawer.configurePaints(context, this.animator)
} }
} }
fun refresh() { fun refresh() {
if (this.configuration.shouldShowAdditionalFrame) { if (this.animator.shouldShowAdditionalFrame) {
this.invalidate() this.invalidate()
animationHandler.postDelayed(this.timerRunnable, this.configuration.animationRate) this.animationHandler.postDelayed(this.timerRunnable, this.animator.animationRate)
} }
} }
@ -41,12 +36,8 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs)
override fun onDraw(canvas: Canvas?) { override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas) super.onDraw(canvas)
// Timber.d("ReplayerView > onDraw")
canvas?.let { canvas?.let {
TableDrawer.drawTable(animator, canvas, context)
TableDrawer.drawTable(configuration, canvas, context)
} }
} }

@ -42,10 +42,6 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
companion object { companion object {
private const val tableStrokeWidth = 30f
private const val playerStrokeWidth = 8f
private const val cardStrokeWidth = 8f
private const val backgroundColor = R.color.green_darker private const val backgroundColor = R.color.green_darker
private val backgroundPaint = Paint() private val backgroundPaint = Paint()
private val strokePaint = Paint() private val strokePaint = Paint()
@ -59,7 +55,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
private val colorsByAmount = hashMapOf<Double, ChipColor>() private val colorsByAmount = hashMapOf<Double, ChipColor>()
fun configurePaints(context: Context) { fun configurePaints(context: Context, animator: ReplayerAnimator) {
this.colorsByAmount.clear() this.colorsByAmount.clear()
@ -67,16 +63,16 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
tablePaint.isAntiAlias = true tablePaint.isAntiAlias = true
tablePaint.style = Paint.Style.STROKE tablePaint.style = Paint.Style.STROKE
tablePaint.strokeWidth = tableStrokeWidth tablePaint.strokeWidth = animator.tableStrokeWidth
tablePaint.color = context.getColor(R.color.green) tablePaint.color = context.getColor(R.color.green)
strokePaint.isAntiAlias = true strokePaint.isAntiAlias = true
strokePaint.style = Paint.Style.STROKE strokePaint.style = Paint.Style.STROKE
strokePaint.strokeWidth = playerStrokeWidth strokePaint.strokeWidth = animator.playerStrokeWidth
cardStrokePaint.isAntiAlias = true cardStrokePaint.isAntiAlias = true
cardStrokePaint.style = Paint.Style.STROKE cardStrokePaint.style = Paint.Style.STROKE
cardStrokePaint.strokeWidth = cardStrokeWidth cardStrokePaint.strokeWidth = animator.cardStrokeWidth
chipBorderPaint.isAntiAlias = true chipBorderPaint.isAntiAlias = true
chipBorderPaint.style = Paint.Style.STROKE chipBorderPaint.style = Paint.Style.STROKE
@ -94,56 +90,56 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
cardTextPaint.isAntiAlias = true cardTextPaint.isAntiAlias = true
} }
fun drawTable(config: ReplayerConfiguration, canvas: Canvas, context: Context) { fun drawTable(animator: ReplayerAnimator, canvas: Canvas, context: Context) {
drawTableItems(config, canvas, context) drawTableItems(animator, canvas, context)
config.frameDrawn() animator.frameDrawn()
} }
private fun drawTableItems(config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawTableItems(animator: ReplayerAnimator, canvas: Canvas, context: Context) {
// base // base
initializeTable(config, canvas, context) initializeTable(animator, canvas, context)
val step = config.currentStep val step = animator.currentStep
val street = step.street val street = step.street
val computedAction = step as? ComputedAction? val computedAction = step as? ComputedAction?
// draw pot // draw pot
drawPot(street, computedAction, config, canvas, context) drawPot(street, computedAction, animator, canvas, context)
// draw board // draw board
drawBoardCards(street, config, canvas, context) drawBoardCards(street, animator, canvas, context)
// draw player shapes and chips // draw player shapes and chips
val hh = config.handHistory val hh = animator.handHistory
for (i in 0 until hh.numberOfPlayers) { for (i in 0 until hh.numberOfPlayers) {
drawPlayerShapes(i, computedAction, config, canvas, context) drawPlayerShapes(i, computedAction, animator, canvas, context)
drawPlayerChips(i, config, canvas, context) drawPlayerChips(i, animator, canvas, context)
} }
// draw player cards // draw player cards
config.activePositions.forEach { animator.activePositions.forEach {
drawCards(it, config, canvas, context) drawCards(it, animator, canvas, context)
} }
} }
private fun drawPlayerShapes(i: Int, computedAction: ComputedAction?, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawPlayerShapes(i: Int, computedAction: ComputedAction?, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
// draw player rectangles with action or name + stack // draw player rectangles with action or name + stack
if (computedAction?.positionIndex == i) { if (computedAction?.positionIndex == i) {
drawPlayerRectangle(i, true, config, canvas, context) drawPlayerRectangle(i, true, animator, canvas, context)
drawAction(i, computedAction, config, canvas, context) drawAction(i, computedAction, animator, canvas, context)
} else { } else {
val info = if (config.isPlayerAllin(i)) { val info = if (animator.isPlayerAllin(i)) {
context.getString(R.string.allin) context.getString(R.string.allin)
} else { } else {
val remainingStack = config.playerRemainingStack(i) val remainingStack = animator.playerRemainingStack(i)
remainingStack?.formatted remainingStack?.formatted
} }
drawPlayerRectangle(i, false, config, canvas, context) drawPlayerRectangle(i, false, animator, canvas, context)
drawPositionAndInfo(i, info, config, canvas) drawPositionAndInfo(i, info, animator, canvas)
} }
} }
@ -152,57 +148,57 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
* Draw chips * Draw chips
* A chip should appears when the player has put some money during the current street * A chip should appears when the player has put some money during the current street
*/ */
private fun drawPlayerChips(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawPlayerChips(i: Int, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
when (config.currentStep) { when (animator.currentStep) {
is Street -> { is Street -> {
when (config.frameType) { when (animator.frameType) {
ReplayerConfiguration.FrameType.STATE -> { ReplayerAnimator.FrameType.STATE -> {
if (config.currentStep == Street.SUMMARY) { if (animator.currentStep == Street.SUMMARY) {
val winnerPots = config.handHistory.winnerPots.firstOrNull { it.position == i } val winnerPots = animator.handHistory.winnerPots.firstOrNull { it.position == i }
winnerPots?.let { pot -> winnerPots?.let { pot ->
val color = colorForAmount(pot.amount) val color = colorForAmount(pot.amount)
val circle = config.animatedChipCircleFromPot(i) val circle = animator.animatedChipCircleFromPot(i)
drawChipCircle(circle, color, canvas, context) drawChipCircle(circle, color, canvas, context)
drawChipText(pot.amount, config.chipText(i), canvas, context) drawChipText(pot.amount, animator.chipText(i), canvas, context)
} }
} }
} }
ReplayerConfiguration.FrameType.GATHER_ANIMATION -> { ReplayerAnimator.FrameType.GATHER_ANIMATION -> {
lastCommittedAmount(i, config)?.let { amount -> lastCommittedAmount(i, animator)?.let { amount ->
val color = colorForAmount(amount) val color = colorForAmount(amount)
val circle = config.animatedChipCircleToPot(i) val circle = animator.animatedChipCircleToPot(i)
drawChipCircle(circle, color, canvas, context) drawChipCircle(circle, color, canvas, context)
} }
} }
ReplayerConfiguration.FrameType.DISTRIBUTION_ANIMATION -> { ReplayerAnimator.FrameType.DISTRIBUTION_ANIMATION -> {
val winnerPots = config.handHistory.winnerPots.firstOrNull { it.position == i } val winnerPots = animator.handHistory.winnerPots.firstOrNull { it.position == i }
winnerPots?.let { pot -> winnerPots?.let { pot ->
val color = colorForAmount(pot.amount) val color = colorForAmount(pot.amount)
val circle = config.animatedChipCircleFromPot(i) val circle = animator.animatedChipCircleFromPot(i)
drawChipCircle(circle, color, canvas, context) drawChipCircle(circle, color, canvas, context)
} }
} }
} }
} }
is ComputedAction -> { is ComputedAction -> {
drawChipForAction(i, config, canvas, context) drawChipForAction(i, animator, canvas, context)
} }
} }
} }
private fun drawChipForAction(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawChipForAction(i: Int, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
lastCommittedAmount(i, config)?.let { amount -> lastCommittedAmount(i, animator)?.let { amount ->
drawChip(amount, i, config, canvas, context) drawChip(amount, i, animator, canvas, context)
} }
} }
private fun lastCommittedAmount(i: Int, config: ReplayerConfiguration): Double? { private fun lastCommittedAmount(i: Int, animator: ReplayerAnimator): Double? {
var committingAction = config.lastChipCommittingActionOfPlayer(i) var committingAction = animator.lastChipCommittingActionOfPlayer(i)
if (committingAction?.action?.type?.isCall == true) { if (committingAction?.action?.type?.isCall == true) {
committingAction = committingAction.getStreetLastSignificantAction() committingAction = committingAction.getStreetLastSignificantAction()
} }
@ -212,26 +208,26 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
/*** /***
* WARNING: Avoid instancing objects here, as it's called from onDraw method * WARNING: Avoid instancing objects here, as it's called from onDraw method
*/ */
private fun initializeTable(config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun initializeTable(animator: ReplayerAnimator, canvas: Canvas, context: Context) {
canvas.drawColor(context.getColor(backgroundColor)) canvas.drawColor(context.getColor(backgroundColor))
canvas.drawRoundRect(config.tableRect, config.tableCornerRadius, config.tableCornerRadius, this.tablePaint) canvas.drawRoundRect(animator.tableRect, animator.tableCornerRadius, animator.tableCornerRadius, this.tablePaint)
this.cardTextPaint.textSize = config.cardSpecs.height * .38f this.cardTextPaint.textSize = animator.cardSpecs.height * .38f
val hh = config.handHistory val hh = animator.handHistory
for (i in 0 until hh.numberOfPlayers) { for (i in 0 until hh.numberOfPlayers) {
drawPlayerRectangle(i,false, config, canvas, context) drawPlayerRectangle(i,false, animator, canvas, context)
drawPlayerCircle(i, config, canvas, context) drawPlayerCircle(i, animator, canvas, context)
drawDealerButton(config, canvas, context) drawDealerButton(animator, canvas, context)
} }
} }
private fun drawDealerButton(config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawDealerButton(animator: ReplayerAnimator, canvas: Canvas, context: Context) {
// Dealer button // Dealer button
val dealerCircle = config.dealerCircle val dealerCircle = animator.dealerCircle
this.fillPaint.color = context.getColor(R.color.red) this.fillPaint.color = context.getColor(R.color.red)
canvas.drawCircle(dealerCircle.x, dealerCircle.y, dealerCircle.radius, fillPaint) canvas.drawCircle(dealerCircle.x, dealerCircle.y, dealerCircle.radius, fillPaint)
this.strokePaint.color = context.getColor(R.color.white) this.strokePaint.color = context.getColor(R.color.white)
@ -241,19 +237,19 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
} }
private fun drawChip(amount: Double, playerIndex: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawChip(amount: Double, playerIndex: Int, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
val circle = config.chipCircle(playerIndex) val circle = animator.chipCircle(playerIndex)
val text = config.chipText(playerIndex) val text = animator.chipText(playerIndex)
drawChip(amount, text, circle, canvas, context) drawChip(amount, text, circle, canvas, context)
} }
private fun drawChip(amount: Double, chipText: ReplayerConfiguration.TextPoint, chipCircle: ReplayerConfiguration.Circle, canvas: Canvas, context: Context) { private fun drawChip(amount: Double, chipText: ReplayerAnimator.TextPoint, chipCircle: ReplayerAnimator.Circle, canvas: Canvas, context: Context) {
val color = colorForAmount(amount) val color = colorForAmount(amount)
drawChipCircle(chipCircle, color, canvas, context) drawChipCircle(chipCircle, color, canvas, context)
drawChipText(amount, chipText, canvas, context) drawChipText(amount, chipText, canvas, context)
} }
private fun drawChipText(amount: Double, chipText: ReplayerConfiguration.TextPoint, canvas: Canvas, context: Context) { private fun drawChipText(amount: Double, chipText: ReplayerAnimator.TextPoint, canvas: Canvas, context: Context) {
this.textPaint.textSize = chipText.fontSize this.textPaint.textSize = chipText.fontSize
this.textPaint.color = context.getColor(R.color.white) this.textPaint.color = context.getColor(R.color.white)
canvas.drawText(amount.formatted, chipText.x, chipText.y, this.textPaint) canvas.drawText(amount.formatted, chipText.x, chipText.y, this.textPaint)
@ -269,7 +265,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
return color return color
} }
private fun drawChipCircle(chipCircle: ReplayerConfiguration.Circle, chipColor: ChipColor, canvas: Canvas, context: Context) { private fun drawChipCircle(chipCircle: ReplayerAnimator.Circle, chipColor: ChipColor, canvas: Canvas, context: Context) {
this.fillPaint.color = context.getColor(chipColor.fillColor) this.fillPaint.color = context.getColor(chipColor.fillColor)
canvas.drawCircle(chipCircle.x, chipCircle.y, chipCircle.radius, this.fillPaint) canvas.drawCircle(chipCircle.x, chipCircle.y, chipCircle.radius, this.fillPaint)
@ -282,50 +278,50 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
} }
private fun drawCards(playerIndex: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawCards(playerIndex: Int, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
val playerSetup = config.handHistory.playerSetupForPosition(playerIndex) val playerSetup = animator.handHistory.playerSetupForPosition(playerIndex)
val cardRects = config.cardRects(playerIndex) val cardRects = animator.cardRects(playerIndex)
val cards = playerSetup?.cards val cards = playerSetup?.cards
val isHero = (config.handHistory.heroIndex == playerIndex) val isHero = (animator.handHistory.heroIndex == playerIndex)
cardRects.forEachIndexed { j, cardRect -> cardRects.forEachIndexed { j, cardRect ->
if (j < cards?.size ?: 0 && (config.showVillainHands || isHero)) { // show card if (j < cards?.size ?: 0 && (animator.showVillainHands || isHero)) { // show card
val card = cards?.get(j)!! // tested line before val card = cards?.get(j)!! // tested line before
drawCard(card, cardRect, config, canvas, context) drawCard(card, cardRect, animator, canvas, context)
} else { // show hidden cards } else { // show hidden cards
fillPaint.color = context.getColor(R.color.card_fill) fillPaint.color = context.getColor(R.color.card_fill)
canvas.drawRoundRect(cardRect, config.cardRadius, config.cardRadius, fillPaint) canvas.drawRoundRect(cardRect, animator.cardRadius, animator.cardRadius, fillPaint)
cardStrokePaint.color = context.getColor(R.color.card_border) cardStrokePaint.color = context.getColor(R.color.card_border)
canvas.drawRoundRect(cardRect, config.cardRadius, config.cardRadius, cardStrokePaint) canvas.drawRoundRect(cardRect, animator.cardRadius, animator.cardRadius, cardStrokePaint)
} }
} }
} }
private fun drawCard(card: Card, cardRect: RectF, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawCard(card: Card, cardRect: RectF, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
fillPaint.color = context.getColor(R.color.white) fillPaint.color = context.getColor(R.color.white)
canvas.drawRoundRect(cardRect, config.cardRadius, config.cardRadius, fillPaint) canvas.drawRoundRect(cardRect, animator.cardRadius, animator.cardRadius, fillPaint)
cardTextPaint.color = context.getColor(R.color.black) cardTextPaint.color = context.getColor(R.color.black)
val valueY = cardRect.top + config.cardSpecs.height * 0.44f val valueY = cardRect.top + animator.cardSpecs.height * 0.44f
canvas.drawText(card.formattedValue, cardRect.centerX(), valueY, cardTextPaint) canvas.drawText(card.formattedValue, cardRect.centerX(), valueY, cardTextPaint)
val suit = card.suit ?: Card.Suit.UNDEFINED val suit = card.suit ?: Card.Suit.UNDEFINED
cardTextPaint.color = context.getColor(suit.color) cardTextPaint.color = context.getColor(suit.color)
val suitY = cardRect.top + config.cardSpecs.height * 0.88f val suitY = cardRect.top + animator.cardSpecs.height * 0.88f
canvas.drawText(suit.value, cardRect.centerX(), suitY, cardTextPaint) canvas.drawText(suit.value, cardRect.centerX(), suitY, cardTextPaint)
} }
private fun drawPlayerCircle(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawPlayerCircle(i: Int, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
val playerSetup = config.handHistory.playerSetupForPosition(i) val playerSetup = animator.handHistory.playerSetupForPosition(i)
// Player portrait zone // Player portrait zone
val circle = config.circleForPlayer(i) val circle = animator.circleForPlayer(i)
val radius = circle.radius val radius = circle.radius
this.fillPaint.color = context.getColor(R.color.green_darker) this.fillPaint.color = context.getColor(R.color.green_darker)
canvas.drawCircle(circle.x, circle.y, radius, this.fillPaint) canvas.drawCircle(circle.x, circle.y, radius, this.fillPaint)
@ -351,65 +347,65 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
/*** /***
* [i] is the player position in the hand * [i] is the player position in the hand
*/ */
private fun drawPlayerRectangle(i: Int, highlighted: Boolean, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawPlayerRectangle(i: Int, highlighted: Boolean, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
val rect = config.stackRectForPlayer(i) val rect = animator.stackRectForPlayer(i)
val rectRadius = (rect.bottom - rect.top) / 4 val rectRadius = (rect.bottom - rect.top) / 4
val color = if (highlighted) R.color.kaki else R.color.green_darker val color = if (highlighted) R.color.kaki else R.color.green_darker
fillPaint.color = context.getColor(color) fillPaint.color = context.getColor(color)
canvas.drawRoundRect( canvas.drawRoundRect(
config.stackRectForPlayer(i), animator.stackRectForPlayer(i),
rectRadius, rectRadius,
rectRadius, rectRadius,
this.fillPaint this.fillPaint
) )
strokePaint.color = context.getColor(R.color.green) strokePaint.color = context.getColor(R.color.green)
canvas.drawRoundRect( canvas.drawRoundRect(
config.stackRectForPlayer(i), animator.stackRectForPlayer(i),
rectRadius, rectRadius,
rectRadius, rectRadius,
this.strokePaint this.strokePaint
) )
if (i == config.handHistory.heroIndex) { // refresh dealer button if (i == animator.handHistory.heroIndex) { // refresh dealer button
drawDealerButton(config, canvas, context) drawDealerButton(animator, canvas, context)
} }
} }
private fun drawPositionAndInfo(i: Int, secondLine: String?, config: ReplayerConfiguration, canvas: Canvas) { private fun drawPositionAndInfo(i: Int, secondLine: String?, animator: ReplayerAnimator, canvas: Canvas) {
val hh = config.handHistory val hh = animator.handHistory
// Player position // Player position
val positions = Position.positionsPerPlayers(hh.numberOfPlayers) val positions = Position.positionsPerPlayers(hh.numberOfPlayers)
val name = positions.elementAt(i).value val name = positions.elementAt(i).value
val pnPoint = config.pointForPlayerName(i) val pnPoint = animator.pointForPlayerName(i)
this.textPaint.textSize = pnPoint.fontSize this.textPaint.textSize = pnPoint.fontSize
canvas.drawText(name, pnPoint.x, pnPoint.y, this.textPaint) canvas.drawText(name, pnPoint.x, pnPoint.y, this.textPaint)
// Player stack // Player stack
secondLine?.let { secondLine?.let {
val psPoint = config.pointForPlayerStack(i) val psPoint = animator.pointForPlayerStack(i)
this.textPaint.textSize = psPoint.fontSize this.textPaint.textSize = psPoint.fontSize
canvas.drawText(it, psPoint.x, psPoint.y, this.textPaint) canvas.drawText(it, psPoint.x, psPoint.y, this.textPaint)
} }
} }
private fun drawAction(i: Int, action: ComputedAction, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawAction(i: Int, action: ComputedAction, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
action.action.type?.let { type -> action.action.type?.let { type ->
val actionName = context.getString(type.resId) val actionName = context.getString(type.resId)
val actionPoint: ReplayerConfiguration.TextPoint val actionPoint: ReplayerAnimator.TextPoint
if (!type.isPassive) { // show action + amount if (!type.isPassive) { // show action + amount
actionPoint = config.pointForPlayerName(i) actionPoint = animator.pointForPlayerName(i)
action.action.displayedAmount?.let { amount -> action.action.displayedAmount?.let { amount ->
val amountPoint = config.pointForPlayerStack(i) val amountPoint = animator.pointForPlayerStack(i)
this.textPaint.textSize = amountPoint.fontSize this.textPaint.textSize = amountPoint.fontSize
canvas.drawText(amount.formatted, amountPoint.x, amountPoint.y, this.textPaint) canvas.drawText(amount.formatted, amountPoint.x, amountPoint.y, this.textPaint)
} }
} else { // show action name only } else { // show action name only
actionPoint = config.pointForPlayerAction(i) actionPoint = animator.pointForPlayerAction(i)
} }
this.textPaint.textSize = actionPoint.fontSize this.textPaint.textSize = actionPoint.fontSize
canvas.drawText(actionName, actionPoint.x, actionPoint.y, this.textPaint) canvas.drawText(actionName, actionPoint.x, actionPoint.y, this.textPaint)
@ -418,36 +414,36 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
} }
private fun drawBoardCards(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawBoardCards(street: Street, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
val cards = config.handHistory.cardsForStreet(street) val cards = animator.handHistory.cardsForStreet(street)
config.boardCardRects.take(street.totalBoardCards).forEachIndexed { index, rectF -> animator.boardCardRects.take(street.totalBoardCards).forEachIndexed { index, rectF ->
drawCard(cards[index], rectF, config, canvas, context) drawCard(cards[index], rectF, animator, canvas, context)
} }
} }
private fun drawPot(street: Street, computedAction: ComputedAction?, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawPot(street: Street, computedAction: ComputedAction?, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
if (street == Street.SUMMARY && config.frameType != ReplayerConfiguration.FrameType.GATHER_ANIMATION) { if (street == Street.SUMMARY && animator.frameType != ReplayerAnimator.FrameType.GATHER_ANIMATION) {
return return
} }
val pot = config.actionList.potSizeForStreet(street) val pot = animator.actionList.potSizeForStreet(street)
val action = computedAction ?: config.lastActionBeforeStreet(street) val action = computedAction ?: animator.lastActionBeforeStreet(street)
val totalPot = action?.let { val totalPot = action?.let {
config.actionList.totalPotSize(it.action.index + 1) animator.actionList.totalPotSize(it.action.index + 1)
} ?: run { } ?: run {
pot pot
} }
drawChip(pot, config.potTextPoint, config.potChipCircle, canvas, context) drawChip(pot, animator.potTextPoint, animator.potChipCircle, canvas, context)
val tpTextPoint = config.totalPotTextPoint val tpTextPoint = animator.totalPotTextPoint
this.textPaint.textSize = tpTextPoint.fontSize this.textPaint.textSize = tpTextPoint.fontSize
this.textPaint.color = context.getColor(R.color.white) this.textPaint.color = context.getColor(R.color.white)
canvas.drawText(totalPot.formatted, config.totalPotTextPoint.x, config.totalPotTextPoint.y, this.textPaint) canvas.drawText(totalPot.formatted, animator.totalPotTextPoint.x, animator.totalPotTextPoint.y, this.textPaint)
} }

Loading…
Cancel
Save