Player and stack drawing

hh
Laurent 6 years ago
parent f7315defe4
commit b084bca418
  1. 6
      app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt
  2. 6
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt
  3. 4
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt
  4. 118
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt
  5. 5
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt
  6. 6
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt
  7. 54
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableCanvas.kt
  8. 99
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt

@ -5,7 +5,7 @@ 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.ReplayerConfiguration
import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableCanvas import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableDrawer
enum class Street : HandStep { enum class Street : HandStep {
PREFLOP, PREFLOP,
@ -41,7 +41,7 @@ enum class Street : HandStep {
} }
override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) {
TableCanvas.drawStreet(this, configuration, canvas, context) TableDrawer.drawStreet(this, configuration, canvas, context)
} }
override fun frames( override fun frames(
@ -50,7 +50,7 @@ enum class Street : HandStep {
context: Context, context: Context,
update: () -> Unit update: () -> Unit
) { ) {
TableCanvas.drawStreet(this, configuration, canvas, context) TableDrawer.drawStreet(this, configuration, canvas, context)
} }
} }

@ -34,7 +34,7 @@ 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.ReplayerConfiguration
import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableCanvas 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
import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager
@ -725,10 +725,10 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
val width = 480 val width = 480
val height = 480 val height = 480
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val tc = TableCanvas(bitmap) val tc = TableDrawer(bitmap)
// draw initial table // draw initial table
TableCanvas.initializeTable(config, tc, requireContext()) TableDrawer.initializeTable(config, tc, requireContext())
val muxer = MMediaMuxer() val muxer = MMediaMuxer()
muxer.Init(requireActivity(), bitmap.width, bitmap.height, "hhVideo", "YES!") muxer.Init(requireActivity(), bitmap.width, bitmap.height, "hhVideo", "YES!")

@ -11,7 +11,7 @@ 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.ReplayerConfiguration
import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableCanvas import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableDrawer
import kotlin.math.max import kotlin.math.max
/*** /***
@ -309,7 +309,7 @@ class ComputedAction(var manager: ActionManager,
get() { return this.action.position } get() { return this.action.position }
override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) {
TableCanvas.drawAction(this, configuration, canvas, context) TableDrawer.drawAction(this, configuration, canvas, context)
} }
override fun frames( override fun frames(

@ -1,14 +1,28 @@
package net.pokeranalytics.android.ui.modules.handhistory.replayer package net.pokeranalytics.android.ui.modules.handhistory.replayer
import android.graphics.RectF import android.graphics.RectF
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.realm.handhistory.HandHistory
class ReplayerConfiguration(var handHistory: HandHistory) { class ReplayerConfiguration(var handHistory: HandHistory) {
data class Circle(var x: Float, var y: Float, var radius: Float)
data class TextPoint(var x: Float, var y: Float, var fontSize: Float)
var width = 100f var width = 100f
var height = 100f var height = 100f
var rect = RectF() var tableRect = RectF()
var playerStackRects = mutableListOf<RectF>()
var playerCircles = mutableListOf<Circle>()
var playerNamePoints = mutableListOf<TextPoint>()
var playerStackPoints = mutableListOf<TextPoint>()
var playerItemsHeight = 10f
var playerItemsWidth = 10f
var paddingPercentage = 0.8f
var tableHPadding = 0f
var tableVPadding = 0f
val speed: Double = 1.0 val speed: Double = 1.0
val showVillainHands: Boolean = true val showVillainHands: Boolean = true
@ -17,10 +31,108 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
this.width = width this.width = width
this.height = height this.height = height
val tp = TableCanvas.tablePadding val portrait = height > width
this.rect = RectF(tp, tp, width - tp, height - tp) val playerPerColumn = if (portrait) 4 else 3
val playerPerRow = 12 / playerPerColumn // 3 or 4
this.tableHPadding = width / playerPerRow / 2
this.tableVPadding = height / playerPerColumn * 0.8f
this.tableRect = RectF(tableHPadding, tableVPadding, width - tableHPadding, height - tableVPadding)
val pzHeight = height / playerPerColumn
val pzWidth = width / playerPerRow
this.playerItemsHeight = pzHeight / 3
this.playerItemsWidth = pzWidth * this.paddingPercentage
// number of players in this order: bottom / left / top / right
val repartition = when (handHistory.numberOfPlayers) {
2 -> mutableListOf(1, 0, 1, 0)
3 -> mutableListOf(1, 1, 0, 1)
4 -> mutableListOf(1, 1, 1, 1)
5 -> mutableListOf(1, 1, 2, 1)
6 -> mutableListOf(2, 1, 2, 1)
7 -> mutableListOf(2, 1, 3, 1)
8 -> mutableListOf(3, 1, 3, 1)
9 -> mutableListOf(3, 1, 4, 1)
10 -> mutableListOf(4, 1, 4, 1)
else -> throw PAIllegalStateException("can't happen")
}
if (portrait && handHistory.numberOfPlayers > 4) { repartition.reverse() }
repartition.forEachIndexed { index, count ->
val x = width / (count + 1)
val y = height / (count + 1)
var xOffset = x
var yOffset = y
var circleOffset = playerItemsHeight * 1.5f
for (i in 1..count) {
when (index) {
0 -> { // bottom
xOffset = x * i
yOffset = height - this.tableVPadding
circleOffset *= -1
}
1 -> { // left
xOffset = this.tableHPadding
yOffset = height - y * i
}
2 -> { // top
xOffset = x * i
yOffset = this.tableVPadding
}
3 -> { // right
xOffset = width - this.tableHPadding
yOffset = y * i
}
else -> throw PAIllegalStateException("can't happen")
}
val left = xOffset - this.playerItemsWidth / 2
val top = yOffset - this.playerItemsHeight / 2
val right = xOffset + this.playerItemsWidth / 2
val bottom = yOffset + this.playerItemsHeight / 2
this.playerStackRects.add(RectF(left, top, right, bottom))
// we give each text zone 1/3rd of the box height, leaving 1/3 for space
// the y given is the bottom of the text rect, giving 1/18th as the offset
// 1 / (3_total_space * 3_each_space * 2_center)
val bottomOffset = this.playerItemsHeight / (3 * 3 * 2)
val fontSize = this.playerItemsHeight / 3
this.playerNamePoints.add(TextPoint(xOffset, yOffset - bottomOffset, fontSize))
this.playerStackPoints.add(TextPoint(xOffset, yOffset + this.playerItemsHeight / 3 + bottomOffset, fontSize))
this.playerCircles.add(Circle(xOffset, yOffset - circleOffset, this.playerItemsHeight / 2))
}
}
} }
fun stackRectForPlayer(i: Int): RectF {
return this.playerStackRects[i]
}
fun circleForPlayer(i: Int): Circle {
return this.playerCircles[i]
}
fun pointForPlayerName(i: Int): TextPoint {
return this.playerNamePoints[i]
}
fun pointForPlayerStack(i: Int): TextPoint {
return this.playerStackPoints[i]
}
} }

@ -13,6 +13,7 @@ import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.fragment.components.BaseFragment import net.pokeranalytics.android.ui.fragment.components.BaseFragment
import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.modules.handhistory.model.HandHistoryViewModel import net.pokeranalytics.android.ui.modules.handhistory.model.HandHistoryViewModel
import timber.log.Timber
class ReplayerFragment : RealmFragment() { class ReplayerFragment : RealmFragment() {
@ -48,7 +49,9 @@ class ReplayerFragment : RealmFragment() {
private fun initData() { private fun initData() {
// TODO change // TODO change
this.model.setHandHistory(getRealm().where(HandHistory::class.java).findFirst()!!) val hh = getRealm().where(HandHistory::class.java).findFirst()!!
Timber.d(">>> Load HH with player count = ${hh.numberOfPlayers}")
this.model.setHandHistory(hh)
loadHand(this.model.handHistory) loadHand(this.model.handHistory)
} }

@ -2,11 +2,9 @@ package net.pokeranalytics.android.ui.modules.handhistory.replayer
import android.content.Context import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF import android.graphics.RectF
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import net.pokeranalytics.android.R
import timber.log.Timber import timber.log.Timber
class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) { class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) {
@ -18,7 +16,7 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs)
init { init {
TableCanvas.configurePaints(context) TableDrawer.configurePaints(context)
this.viewTreeObserver.addOnGlobalLayoutListener { this.viewTreeObserver.addOnGlobalLayoutListener {
this.configuration.setDimension(width.toFloat(), height.toFloat()) this.configuration.setDimension(width.toFloat(), height.toFloat())
} }
@ -35,7 +33,7 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs)
canvas?.let { canvas?.let {
// Timber.d("ReplayerView > onDraw with canvas: ${canvas.width}, ${canvas.height}") // Timber.d("ReplayerView > onDraw with canvas: ${canvas.width}, ${canvas.height}")
TableCanvas.initializeTable(this.configuration, canvas, context) TableDrawer.initializeTable(this.configuration, canvas, context)
this.step?.draw(this.configuration, canvas, context) this.step?.draw(this.configuration, canvas, context)
} }

@ -1,54 +0,0 @@
package net.pokeranalytics.android.ui.modules.handhistory.replayer
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction
class TableCanvas(bitmap: Bitmap) : Canvas(bitmap) {
companion object {
const val strokeWidth = 20f
const val tablePadding = 200f
const val tableCornerRadius = 100f
private val paint = Paint()
fun configurePaints(context: Context) {
paint.isAntiAlias = true
paint.style = Paint.Style.STROKE
paint.strokeWidth = strokeWidth
paint.color = context.getColor(R.color.green)
}
/***
* WARNING: Avoid instancing objects here, as it's called from onDraw method
*/
fun initializeTable(config: ReplayerConfiguration, canvas: Canvas, context: Context) {
canvas.drawRoundRect(config.rect, this.tableCornerRadius, this.tableCornerRadius, this.paint)
}
fun drawStreet(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
}
fun drawAction(action: ComputedAction, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
}
////////
fun setPot(pot: Double, totalPot: Double) {
}
}
}

@ -0,0 +1,99 @@
package net.pokeranalytics.android.ui.modules.handhistory.replayer
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.handhistory.Position
import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction
import net.pokeranalytics.android.util.extensions.formatted
class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
companion object {
const val tableStrokeWidth = 30f
const val playerStrokeWidth = 8f
const val tableCornerRadius = 100f
// const val stackRectRadius = 25f
private val tablePaint = Paint()
private val playerPaint = Paint()
private val fillPaint = Paint()
private val textPaint = Paint()
fun configurePaints(context: Context) {
tablePaint.isAntiAlias = true
tablePaint.style = Paint.Style.STROKE
tablePaint.strokeWidth = tableStrokeWidth
tablePaint.color = context.getColor(R.color.green)
playerPaint.isAntiAlias = true
playerPaint.style = Paint.Style.STROKE
playerPaint.strokeWidth = playerStrokeWidth
playerPaint.color = context.getColor(R.color.green)
fillPaint.color = context.getColor(R.color.green_darker)
fillPaint.isAntiAlias = true
textPaint.color = context.getColor(R.color.white)
textPaint.textAlign = Paint.Align.CENTER
textPaint.isAntiAlias = true
}
/***
* WARNING: Avoid instancing objects here, as it's called from onDraw method
*/
fun initializeTable(config: ReplayerConfiguration, canvas: Canvas, context: Context) {
canvas.drawRoundRect(config.tableRect, this.tableCornerRadius, this.tableCornerRadius, this.tablePaint)
val hh = config.handHistory
val positions = Position.positionsPerPlayers(hh.numberOfPlayers)
for (i in 0 until hh.numberOfPlayers) {
val playerSetup = hh.playerSetupForPosition(i)
// Stack zone
val rect = config.stackRectForPlayer(i)
val radius = (rect.bottom - rect.top) / 4
canvas.drawRoundRect(config.stackRectForPlayer(i), radius, radius, this.fillPaint)
canvas.drawRoundRect(config.stackRectForPlayer(i), radius, radius, this.playerPaint)
// Player portrait zone
val circle = config.circleForPlayer(i)
canvas.drawCircle(circle.x, circle.y, circle.radius, this.fillPaint)
canvas.drawCircle(circle.x, circle.y, circle.radius, this.playerPaint)
val name = playerSetup?.player?.name ?: positions.elementAt(i).value
val pnPoint = config.pointForPlayerName(i)
this.textPaint.textSize = pnPoint.fontSize
canvas.drawText(name, pnPoint.x, pnPoint.y, this.textPaint)
playerSetup?.stack?.formatted?.let { stack ->
val psPoint = config.pointForPlayerStack(i)
this.textPaint.textSize = psPoint.fontSize
canvas.drawText(stack, psPoint.x, psPoint.y, this.textPaint)
}
}
}
fun drawStreet(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
}
fun drawAction(action: ComputedAction, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
}
////////
fun setPot(pot: Double, totalPot: Double) {
}
}
}
Loading…
Cancel
Save