From d62285a16ef2bba995566ca74c51f04ef007e17b Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 10 Jun 2020 12:40:17 +0200 Subject: [PATCH] Toolbar improvement + buttons logic --- .../android/model/handhistory/Street.kt | 5 + .../modules/handhistory/model/ActionList.kt | 8 ++ .../handhistory/model/ComputedAction.kt | 4 + .../handhistory/model/HandHistoryViewModel.kt | 4 + .../modules/handhistory/replayer/HandStep.kt | 2 + .../replayer/ReplayerConfiguration.kt | 10 ++ .../handhistory/replayer/ReplayerFragment.kt | 90 ++++++++------ .../handhistory/replayer/ReplayerModel.kt | 51 ++++++++ .../handhistory/replayer/ReplayerView.kt | 38 ++++-- .../handhistory/replayer/TableDrawer.kt | 15 ++- .../res/drawable/ic_fast_forward_white.xml | 9 ++ .../res/drawable/ic_fast_rewind_white.xml | 9 ++ app/src/main/res/drawable/ic_play_arrow.xml | 9 ++ .../main/res/drawable/ic_skip_next_white.xml | 9 ++ .../res/drawable/ic_skip_previous_white.xml | 9 ++ app/src/main/res/layout/fragment_replayer.xml | 113 +++++++++++------- app/src/main/res/menu/toolbar_replayer.xml | 35 ++++++ app/src/main/res/values/strings.xml | 2 + 18 files changed, 324 insertions(+), 98 deletions(-) create mode 100644 app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerModel.kt create mode 100644 app/src/main/res/drawable/ic_fast_forward_white.xml create mode 100644 app/src/main/res/drawable/ic_fast_rewind_white.xml create mode 100644 app/src/main/res/drawable/ic_play_arrow.xml create mode 100644 app/src/main/res/drawable/ic_skip_next_white.xml create mode 100644 app/src/main/res/drawable/ic_skip_previous_white.xml create mode 100644 app/src/main/res/menu/toolbar_replayer.xml 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 8bec29db..fbfd18d0 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 @@ -2,6 +2,7 @@ package net.pokeranalytics.android.model.handhistory import android.content.Context import android.graphics.Canvas +import io.realm.internal.Table import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.modules.handhistory.replayer.HandStep import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerConfiguration @@ -44,6 +45,10 @@ enum class Street : HandStep { TableDrawer.drawStreet(this, configuration, canvas, context) } + override fun undo(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { + TableDrawer.undoStreet(this, configuration, canvas, context) + } + override fun frames( configuration: ReplayerConfiguration, canvas: Canvas, diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt index 397b8a0b..ec52a631 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt @@ -681,4 +681,12 @@ class ActionList(var listener: ActionListListener? = null) : ArrayList (Unit)) fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) + fun undo(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) companion object { @@ -18,6 +19,7 @@ interface HandStep { val actionList = ActionList() actionList.load(handHistory) + actionList.removeBlinds() val steps = mutableListOf() Street.values().forEach { street -> 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 580c98f8..6e9e703f 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 @@ -4,15 +4,25 @@ import android.graphics.RectF import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.ui.modules.handhistory.model.ActionList +import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction import timber.log.Timber class ReplayerConfiguration(var handHistory: HandHistory) { + var initialActions: List + var actionList: ActionList = ActionList(null) private set + var steps: List + init { + this.actionList.load(this.handHistory) + + this.initialActions = actionList.filter { it.action.type?.isBlind == true } + + this.steps = HandStep.createSteps(this.handHistory) } data class Size(var width: Float, var height: Float) 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 41199110..3f1c6931 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 @@ -10,21 +10,15 @@ import androidx.lifecycle.ViewModelProviders import kotlinx.android.synthetic.main.fragment_replayer.* import net.pokeranalytics.android.R 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() { /*** * The fragment's ViewModel */ - private lateinit var model: HandHistoryViewModel - - private var steps: List = listOf() - -// private lateinit var configuration: ReplayerConfiguration + private lateinit var model: ReplayerModel override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { super.onCreateView(inflater, container, savedInstanceState) @@ -41,7 +35,7 @@ class ReplayerFragment : RealmFragment() { super.onCreate(savedInstanceState) this.model = activity?.run { - ViewModelProviders.of(this)[HandHistoryViewModel::class.java] + ViewModelProviders.of(this)[ReplayerModel::class.java] } ?: throw Exception("Invalid Activity") } @@ -50,73 +44,91 @@ class ReplayerFragment : RealmFragment() { // TODO change val hh = getRealm().where(HandHistory::class.java).findFirst()!! - Timber.d(">>> Load HH with player count = ${hh.numberOfPlayers}") - this.model.setHandHistory(hh) +// Timber.d(">>> Load HH with player count = ${hh.numberOfPlayers}") +// this.model.setHandHistory(hh) - loadHand(this.model.handHistory) + val hhm = ViewModelProviders.of(this)[HandHistoryViewModel::class.java] + loadHand(hh) } private fun initUI() { + this.next_action.setOnClickListener { + nextAction() + } + this.previous_action.setOnClickListener { + previousAction() + } + this.next_hand.setOnClickListener { + nextHand() + } + this.previous_hand.setOnClickListener { + previousHand() + } + this.play_pause.setOnClickListener { + playOrPause() + } + this.speed.setOnClickListener { + changeSpeed() + } + updateSpeedButtonText() } - private fun loadHand(handHistory: HandHistory) { - this.steps = HandStep.createSteps(handHistory) - this.replayer.configuration = ReplayerConfiguration(handHistory) + private fun updateSpeedButtonText() { + this.speed.text = "${this.model.speedMultiplier}x" } - var isPlaying: Boolean = false - - val mainHandler = Handler(Looper.getMainLooper()) + private fun loadHand(handHistory: HandHistory) { + val config = ReplayerConfiguration(handHistory) + this.replayer.configuration = config + this.model.configuration = config + } - val actionSpeed = 1000L - var speedMultiplier = 1 + private val mainHandler = Handler(Looper.getMainLooper()) private val timerRunnable: Runnable = Runnable { nextAction() } - fun playOrPause() { + private fun playOrPause() { - if (this.isPlaying) { + if (this.model.isPlaying) { mainHandler.removeCallbacks(timerRunnable) } else { mainHandler.postDelayed(timerRunnable, 0L) } - this.isPlaying = !this.isPlaying + this.model.isPlaying = !this.model.isPlaying } - private var stepIndex: Int = 0 + private fun nextAction() { - fun nextAction() { - if (this.stepIndex < this.steps.size - 1) { - this.stepIndex += 1 - playAction() + this.model.next?.let { + this.replayer.next(it) } - if (this.isPlaying) { - mainHandler.postDelayed(timerRunnable, speedMultiplier * actionSpeed) + + if (this.model.isPlaying) { + mainHandler.postDelayed(timerRunnable, this.model.actionDelay) } } - fun previousAction() { - if (this.stepIndex > 0) { - this.stepIndex -= 1 - playAction() + private fun previousAction() { + this.model.previous?.let { + this.replayer.previous(it) } } - fun playAction() { - this.replayer.step = this.steps[this.stepIndex] - this.replayer.invalidate() // force redraw - } - fun nextHand() { + private fun nextHand() { } - fun previousHand() { + private fun previousHand() { } + private fun changeSpeed() { + this.model.changeSpeed() + updateSpeedButtonText() + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerModel.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerModel.kt new file mode 100644 index 00000000..53de0530 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerModel.kt @@ -0,0 +1,51 @@ +package net.pokeranalytics.android.ui.modules.handhistory.replayer + +import androidx.lifecycle.ViewModel + +class ReplayerModel : ViewModel() { + + var configuration: ReplayerConfiguration? = null + + var isPlaying: Boolean = false + + val actionSpeed = 1000L + + var speedMultiplier = 1.0 + private set + + private var stepIndex: Int = 0 + + val previous: HandStep? + get() { + this.configuration?.steps?.let { steps -> + if (this.stepIndex > 1) { + this.stepIndex -= 1 + return steps[this.stepIndex] + } + } + return null + } + + val next: HandStep? + get() { + this.configuration?.steps?.let { steps -> + if (steps.size > this.stepIndex + 1) { + this.stepIndex += 1 + return steps[this.stepIndex] + } + } + return null + } + + val actionDelay: Long + get() { return (speedMultiplier * actionSpeed).toLong() } + + fun changeSpeed() { + this.speedMultiplier = when (speedMultiplier) { + 1.0 -> 1.5 + 1.5 -> 2.0 + else -> 1.0 + } + } + +} \ No newline at end of file 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 23815f2d..3feaa544 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,17 +2,16 @@ package net.pokeranalytics.android.ui.modules.handhistory.replayer import android.content.Context import android.graphics.Canvas -import android.graphics.RectF import android.util.AttributeSet import android.view.View -import timber.log.Timber + +private data class ReplayerAction(val step: HandStep, val draw: Boolean) class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) { - var step: HandStep? = null - lateinit var configuration: ReplayerConfiguration + private var actionsToDraw = mutableListOf() - var rect = RectF() + lateinit var configuration: ReplayerConfiguration init { @@ -22,20 +21,35 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) } } - override fun onDraw(canvas: Canvas?) { - super.onDraw(canvas) - Timber.d("ReplayerView > onDraw, rect = $rect") + fun previous(handStep: HandStep) { + val action = ReplayerAction(handStep, false) + this.addAction(action) + } + fun next(handStep: HandStep) { + val action = ReplayerAction(handStep, true) + this.addAction(action) + } -// canvas?.drawCircle(100f, 100f, 50f, paint) + private fun addAction(action: ReplayerAction) { + this.actionsToDraw.add(action) + this.invalidate() + } + override fun onDraw(canvas: Canvas?) { + super.onDraw(canvas) canvas?.let { + this.actionsToDraw.dropWhile { action -> -// Timber.d("ReplayerView > onDraw with canvas: ${canvas.width}, ${canvas.height}") - TableDrawer.initializeTable(this.configuration, canvas, context) + if (action.draw) { + action.step.draw(this.configuration, canvas, context) + } else { + action.step.undo(this.configuration, canvas, context) + } - this.step?.draw(this.configuration, canvas, context) + this.actionsToDraw.isNotEmpty() + } } } 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 index 9f0145ea..b0a0dc1f 100644 --- 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 @@ -93,14 +93,14 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { // val chipText = config.chipText(i) // drawChip(2000.0, chipText, chipCircle, canvas, context) - drawStreet(Street.RIVER, config, canvas, context) +// drawStreet(Street.RIVER, config, canvas, context) // drawPot(100.0, 200.0, config, canvas, context) } - val blinds = config.actionList.filter { it.action.type?.isBlind ?: false } - blinds.forEach { action -> +// val blinds = config.actionList.filter { it.action.type?.isBlind ?: false } + config.initialActions.forEach { action -> action.action.amount?.let { amount -> drawChip(amount, action.positionIndex, config, canvas, context) } @@ -110,7 +110,6 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { drawPot(pot, totalPot, config, canvas, context) - // drawAction(action, false, config, canvas, context) } @@ -311,6 +310,14 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { } + fun undoAction(computedAction: ComputedAction, highlighted: Boolean, configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { + // TODO + } + + fun undoStreet(street: Street, configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { + // TODO + } + } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_fast_forward_white.xml b/app/src/main/res/drawable/ic_fast_forward_white.xml new file mode 100644 index 00000000..79b6cf63 --- /dev/null +++ b/app/src/main/res/drawable/ic_fast_forward_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_fast_rewind_white.xml b/app/src/main/res/drawable/ic_fast_rewind_white.xml new file mode 100644 index 00000000..652b6753 --- /dev/null +++ b/app/src/main/res/drawable/ic_fast_rewind_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_play_arrow.xml b/app/src/main/res/drawable/ic_play_arrow.xml new file mode 100644 index 00000000..f600eb18 --- /dev/null +++ b/app/src/main/res/drawable/ic_play_arrow.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_skip_next_white.xml b/app/src/main/res/drawable/ic_skip_next_white.xml new file mode 100644 index 00000000..8a9ba215 --- /dev/null +++ b/app/src/main/res/drawable/ic_skip_next_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_skip_previous_white.xml b/app/src/main/res/drawable/ic_skip_previous_white.xml new file mode 100644 index 00000000..fd203118 --- /dev/null +++ b/app/src/main/res/drawable/ic_skip_previous_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_replayer.xml b/app/src/main/res/layout/fragment_replayer.xml index f7ee434a..8d24ecde 100644 --- a/app/src/main/res/layout/fragment_replayer.xml +++ b/app/src/main/res/layout/fragment_replayer.xml @@ -28,64 +28,91 @@ android:id="@+id/replayer" android:layout_width="wrap_content" android:layout_height="0dp" - app:layout_constraintBottom_toTopOf="@+id/controls" + app:layout_constraintBottom_toTopOf="@+id/bottomBar" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/appBar" /> - -