From b084bca418604cae93675c94adce373d186ffef9 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 5 Jun 2020 12:35:13 +0200 Subject: [PATCH] Player and stack drawing --- .../android/model/handhistory/Street.kt | 6 +- .../handhistory/HandHistoryFragment.kt | 6 +- .../handhistory/model/ComputedAction.kt | 4 +- .../replayer/ReplayerConfiguration.kt | 118 +++++++++++++++++- .../handhistory/replayer/ReplayerFragment.kt | 5 +- .../handhistory/replayer/ReplayerView.kt | 6 +- .../handhistory/replayer/TableCanvas.kt | 54 -------- .../handhistory/replayer/TableDrawer.kt | 99 +++++++++++++++ 8 files changed, 228 insertions(+), 70 deletions(-) delete mode 100644 app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableCanvas.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt diff --git a/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt b/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt index 55d913e4..8bec29db 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt @@ -5,7 +5,7 @@ import android.graphics.Canvas import net.pokeranalytics.android.R 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.TableCanvas +import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableDrawer enum class Street : HandStep { PREFLOP, @@ -41,7 +41,7 @@ enum class Street : HandStep { } override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { - TableCanvas.drawStreet(this, configuration, canvas, context) + TableDrawer.drawStreet(this, configuration, canvas, context) } override fun frames( @@ -50,7 +50,7 @@ enum class Street : HandStep { context: Context, update: () -> Unit ) { - TableCanvas.drawStreet(this, configuration, canvas, context) + TableDrawer.drawStreet(this, configuration, canvas, context) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt index f6d39e8c..8fcd2d30 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt @@ -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.replayer.HandStep 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.view.RowRepresentable import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager @@ -725,10 +725,10 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL val width = 480 val height = 480 val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) - val tc = TableCanvas(bitmap) + val tc = TableDrawer(bitmap) // draw initial table - TableCanvas.initializeTable(config, tc, requireContext()) + TableDrawer.initializeTable(config, tc, requireContext()) val muxer = MMediaMuxer() muxer.Init(requireActivity(), bitmap.width, bitmap.height, "hhVideo", "YES!") diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt index 439c889f..a71d81d0 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt @@ -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.replayer.HandStep 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 /*** @@ -309,7 +309,7 @@ class ComputedAction(var manager: ActionManager, get() { return this.action.position } override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { - TableCanvas.drawAction(this, configuration, canvas, context) + TableDrawer.drawAction(this, configuration, canvas, context) } override fun frames( diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt index 0479319e..24841535 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt @@ -1,14 +1,28 @@ package net.pokeranalytics.android.ui.modules.handhistory.replayer import android.graphics.RectF +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.realm.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 height = 100f - var rect = RectF() + var tableRect = RectF() + var playerStackRects = mutableListOf() + var playerCircles = mutableListOf() + var playerNamePoints = mutableListOf() + var playerStackPoints = mutableListOf() + var playerItemsHeight = 10f + var playerItemsWidth = 10f + var paddingPercentage = 0.8f + + var tableHPadding = 0f + var tableVPadding = 0f val speed: Double = 1.0 val showVillainHands: Boolean = true @@ -17,10 +31,108 @@ class ReplayerConfiguration(var handHistory: HandHistory) { this.width = width this.height = height - val tp = TableCanvas.tablePadding - this.rect = RectF(tp, tp, width - tp, height - tp) + val portrait = height > width + 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] + } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt index 973a8173..41199110 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt @@ -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.RealmFragment import net.pokeranalytics.android.ui.modules.handhistory.model.HandHistoryViewModel +import timber.log.Timber class ReplayerFragment : RealmFragment() { @@ -48,7 +49,9 @@ class ReplayerFragment : RealmFragment() { private fun initData() { // 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) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt index 61634048..23815f2d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt @@ -2,11 +2,9 @@ package net.pokeranalytics.android.ui.modules.handhistory.replayer import android.content.Context import android.graphics.Canvas -import android.graphics.Paint import android.graphics.RectF import android.util.AttributeSet import android.view.View -import net.pokeranalytics.android.R import timber.log.Timber class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) { @@ -18,7 +16,7 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) init { - TableCanvas.configurePaints(context) + TableDrawer.configurePaints(context) this.viewTreeObserver.addOnGlobalLayoutListener { this.configuration.setDimension(width.toFloat(), height.toFloat()) } @@ -35,7 +33,7 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) canvas?.let { // 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) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableCanvas.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableCanvas.kt deleted file mode 100644 index ec2f5aa7..00000000 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableCanvas.kt +++ /dev/null @@ -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) { - - } - - } - -} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt new file mode 100644 index 00000000..531491b8 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt @@ -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) { + + } + + } + +} \ No newline at end of file