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 9b17bc59..55d913e4 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 @@ -44,5 +44,14 @@ enum class Street : HandStep { TableCanvas.drawStreet(this, configuration, canvas, context) } + override fun frames( + configuration: ReplayerConfiguration, + canvas: Canvas, + context: Context, + update: () -> Unit + ) { + TableCanvas.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 c4b04fda..f6d39e8c 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 @@ -18,7 +18,6 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.handhistory.Position -import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.realm.Player import net.pokeranalytics.android.model.realm.handhistory.Action import net.pokeranalytics.android.model.realm.handhistory.Card @@ -26,6 +25,7 @@ import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.ui.activity.components.RequestCode import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.extensions.px +import net.pokeranalytics.android.ui.extensions.toByteArray import net.pokeranalytics.android.ui.fragment.components.BaseFragment import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment @@ -39,6 +39,7 @@ import net.pokeranalytics.android.ui.modules.handhistory.views.KeyboardListener import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager import net.pokeranalytics.android.util.extensions.findById +import net.pokeranalytics.android.util.video.MMediaMuxer import timber.log.Timber @@ -72,7 +73,11 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL companion object { - fun newInstance(id: String? = null, configurationId: String? = null, attached: Boolean = false): HandHistoryFragment { + fun newInstance( + id: String? = null, + configurationId: String? = null, + attached: Boolean = false + ): HandHistoryFragment { val fragment = HandHistoryFragment() val bundle = Bundle() bundle.putSerializable(BundleKey.HAND_HISTORY_ID.value, id) @@ -93,7 +98,11 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { super.onCreateView(inflater, container, savedInstanceState) return inflater.inflate(R.layout.fragment_hand_history, container, false) } @@ -115,8 +124,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL this.model.setHandHistory(hhCopy) this.setEditing(false) } ?: run { - val configurationId= this.arguments?.getString(BundleKey.CONFIGURATION_ID.value) - val attached= this.arguments?.getBoolean(BundleKey.ATTACHED.value) ?: false + val configurationId = this.arguments?.getString(BundleKey.CONFIGURATION_ID.value) + val attached = this.arguments?.getBoolean(BundleKey.ATTACHED.value) ?: false this.model.createNewHandHistory(getRealm(), configurationId, attached) this.setEditing(true) @@ -130,7 +139,7 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL setDisplayHomeAsUpEnabled(true) - this.handHistoryAdapter = HandHistoryAdapter(this.model,this) + this.handHistoryAdapter = HandHistoryAdapter(this.model, this) // val swipeToDelete = SwipeToDeleteCallback { position -> // this.model.deleteIfPossible(position) @@ -162,7 +171,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL val selection = this.model.currentSelection retrieveEditTextInputConnection(selection) } - else -> {} + else -> { + } } } @@ -185,7 +195,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL RequestCode.PLAYER_SELECTION.ordinal -> { if (resultCode == Activity.RESULT_OK) { - val playerId = data?.getStringExtra(BaseFragment.BundleKey.PRIMARY_KEY.value) ?: throw PAIllegalStateException("Primary key not set where as activity has finished") + val playerId = data?.getStringExtra(BaseFragment.BundleKey.PRIMARY_KEY.value) + ?: throw PAIllegalStateException("Primary key not set where as activity has finished") getRealm().findById(playerId)?.let { player -> this.model.playerSelected(player) } ?: throw PAIllegalStateException("Player (id=$playerId) not found") @@ -238,7 +249,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL HHKeyboard.AMOUNT -> { retrieveEditTextInputConnection(selection) } - else -> {} + else -> { + } } this.showKeyboard(kb) { @@ -270,10 +282,14 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL val handRow = this.model.rowRepresentableForPosition(selection.index) as? HandHistoryRow - val holder = recyclerView.findViewHolderForAdapterPosition(selection.index) as? HandHistoryAdapter.RowHandHolder + val holder = + recyclerView.findViewHolderForAdapterPosition(selection.index) as? HandHistoryAdapter.RowHandHolder holder?.let { val amountEditText = it.editTextForTag(selection.tag) - this.keyboard.setAmountEditText(amountEditText, handRow?.amountForTag(this.model.handHistory, selection.tag)) + this.keyboard.setAmountEditText( + amountEditText, + handRow?.amountForTag(this.model.handHistory, selection.tag) + ) } ?: run { Timber.d("no holder, or not RowHandAction") } @@ -337,17 +353,31 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL } when (row.bottomSheetType) { // Comment, number of players... - BottomSheetType.NONE -> {} + BottomSheetType.NONE -> { + } else -> { val editDescriptors = this.model.editDescriptors(row) when (row) { HandRowType.PLAYER_NUMBER -> { - BottomSheetFragment.create(requireFragmentManager(), row, this, editDescriptors, isClearable = false, alternativeLabels = true) + BottomSheetFragment.create( + requireFragmentManager(), + row, + this, + editDescriptors, + isClearable = false, + alternativeLabels = true + ) } else -> { - BottomSheetFragment.create(requireFragmentManager(), row, this, editDescriptors, alternativeLabels = true) + BottomSheetFragment.create( + requireFragmentManager(), + row, + this, + editDescriptors, + alternativeLabels = true + ) } } @@ -527,7 +557,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL onRowSelected(rowRepresentableIndex, it, ComputedAction.Tag.ACTION.ordinal) this.handHistoryAdapter.notifyItemChanged(rowRepresentableIndex) this.scrollToPosition(rowRepresentableIndex) - } ?: throw PAIllegalStateException("Rowrepresentable not fouind at index $rowRepresentableIndex") + } + ?: throw PAIllegalStateException("Rowrepresentable not fouind at index $rowRepresentableIndex") } // Table @@ -642,9 +673,11 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder.setTitle(R.string.position) - builder.setItems(arrayOf( - getString(R.string.remove) - )) { _, index -> + builder.setItems( + arrayOf( + getString(R.string.remove) + ) + ) { _, index -> // The 'which' argument contains the index position // of the selected item when (index) { @@ -666,11 +699,13 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder.setTitle(R.string.export) - builder.setItems(arrayOf( - getString(R.string.text) + builder.setItems( + arrayOf( + getString(R.string.text) // getString(R.string.video), // "GIF" - )) { _, index -> + ) + ) { _, index -> // The 'which' argument contains the index position // of the selected item when (index) { @@ -687,17 +722,33 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL val config = ReplayerConfiguration(this.model.handHistory) - val bitmap = Bitmap.createBitmap(480, 480, Bitmap.Config.ARGB_8888) + val width = 480 + val height = 480 + val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val tc = TableCanvas(bitmap) // draw initial table TableCanvas.initializeTable(config, tc, requireContext()) - HandStep.build(this.model.handHistory).forEach { - it.draw(config, tc, requireContext()) - } + val muxer = MMediaMuxer() + muxer.Init(requireActivity(), bitmap.width, bitmap.height, "hhVideo", "YES!") + HandStep.createSteps(this.model.handHistory).forEach { step -> + + step.frames(config, tc, requireContext()) { + try { + val byteArray = bitmap.toByteArray() + muxer.AddFrame(byteArray) + } catch (e: Exception) { + Timber.e("error = ${e.message}") + } + } + + } + muxer.CreateVideo() + val path = muxer.GetPath() + Timber.d("**** Video path = $path") // Timber.d("**** Start video test") // 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 1c06b0b4..439c889f 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 @@ -312,4 +312,13 @@ class ComputedAction(var manager: ActionManager, TableCanvas.drawAction(this, configuration, canvas, context) } + override fun frames( + configuration: ReplayerConfiguration, + canvas: Canvas, + context: Context, + update: () -> Unit + ) { +// TODO("Not yet implemented") + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt index e0c46429..a4baa403 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt @@ -8,11 +8,13 @@ import net.pokeranalytics.android.ui.modules.handhistory.model.ActionList interface HandStep { + fun frames(configuration: ReplayerConfiguration, canvas: Canvas, context: Context, update: () -> (Unit)) + fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) companion object { - fun build(handHistory: HandHistory): List { + fun createSteps(handHistory: HandHistory): List { val actionList = ActionList() actionList.load(handHistory) 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 6df0dde2..0479319e 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,13 +1,27 @@ package net.pokeranalytics.android.ui.modules.handhistory.replayer +import android.graphics.RectF import net.pokeranalytics.android.model.realm.handhistory.HandHistory class ReplayerConfiguration(var handHistory: HandHistory) { - val speed: Double = 1.0 + var width = 100f + var height = 100f + + var rect = RectF() + val speed: Double = 1.0 val showVillainHands: Boolean = true + fun setDimension(width: Float, height: Float) { + this.width = width + this.height = height + + val tp = TableCanvas.tablePadding + this.rect = RectF(tp, tp, width - tp, height - tp) + } + + } 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 e344db4b..973a8173 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 @@ -1,13 +1,29 @@ package net.pokeranalytics.android.ui.modules.handhistory.replayer import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +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 -class ReplayerFragment : BaseFragment() { +class ReplayerFragment : RealmFragment() { + + /*** + * The fragment's ViewModel + */ + private lateinit var model: HandHistoryViewModel + + private var steps: List = listOf() + +// private lateinit var configuration: ReplayerConfiguration override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { super.onCreateView(inflater, container, savedInstanceState) @@ -20,28 +36,75 @@ class ReplayerFragment : BaseFragment() { initUI() } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + this.model = activity?.run { + ViewModelProviders.of(this)[HandHistoryViewModel::class.java] + } ?: throw Exception("Invalid Activity") + + } + private fun initData() { + // TODO change + this.model.setHandHistory(getRealm().where(HandHistory::class.java).findFirst()!!) + + loadHand(this.model.handHistory) } private fun initUI() { } - fun play() { + private fun loadHand(handHistory: HandHistory) { + this.steps = HandStep.createSteps(handHistory) + this.replayer.configuration = ReplayerConfiguration(handHistory) + } + + var isPlaying: Boolean = false + + val mainHandler = Handler(Looper.getMainLooper()) + + val actionSpeed = 1000L + var speedMultiplier = 1 + private val timerRunnable: Runnable = Runnable { + nextAction() } - fun resume() { + fun playOrPause() { + if (this.isPlaying) { + mainHandler.removeCallbacks(timerRunnable) + } else { + mainHandler.postDelayed(timerRunnable, 0L) + } + this.isPlaying = !this.isPlaying } - fun nextAction() { + private var stepIndex: Int = 0 + fun nextAction() { + if (this.stepIndex < this.steps.size - 1) { + this.stepIndex += 1 + playAction() + } + if (this.isPlaying) { + mainHandler.postDelayed(timerRunnable, speedMultiplier * actionSpeed) + } } fun previousAction() { + if (this.stepIndex > 0) { + this.stepIndex -= 1 + playAction() + } + } + fun playAction() { + this.replayer.step = this.steps[this.stepIndex] + this.replayer.invalidate() // force redraw } fun nextHand() { 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 410fc1ae..61634048 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,23 +2,42 @@ 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) { - lateinit var replayerConfiguration: ReplayerConfiguration + var step: HandStep? = null + lateinit var configuration: ReplayerConfiguration - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - Timber.d("ReplayerView > onMeasure") + var rect = RectF() + + init { + + TableCanvas.configurePaints(context) + this.viewTreeObserver.addOnGlobalLayoutListener { + this.configuration.setDimension(width.toFloat(), height.toFloat()) + } } override fun onDraw(canvas: Canvas?) { - Timber.d("ReplayerView > onDraw") + super.onDraw(canvas) + Timber.d("ReplayerView > onDraw, rect = $rect") + + +// canvas?.drawCircle(100f, 100f, 50f, paint) + canvas?.let { -// TableCanvas.draw(this.replayerConfiguration, it, context) + +// Timber.d("ReplayerView > onDraw with canvas: ${canvas.width}, ${canvas.height}") + TableCanvas.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 index 44923a03..ec2f5aa7 100644 --- 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 @@ -13,10 +13,27 @@ import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction class TableCanvas(bitmap: Bitmap) : Canvas(bitmap) { companion object { - const val STROKE_WIDTH = 20.0f + 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) { @@ -34,18 +51,4 @@ class TableCanvas(bitmap: Bitmap) : Canvas(bitmap) { } - fun load(context: Context) { - // create canvasses - - val paint = Paint() - paint.color = context.getColor(R.color.green) - paint.style = Paint.Style.STROKE - paint.strokeWidth = STROKE_WIDTH - paint.isAntiAlias = true - - val rect = RectF(10f, 10f, 10f, 10.0f) - drawRoundRect(rect, 8f, 8f, paint) - } - - } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TestActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TestActivity.kt index 24b367ac..5b632005 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TestActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TestActivity.kt @@ -16,20 +16,20 @@ class TestActivity : BaseActivity() { } fun initUI() { - + showFragment(ReplayerFragment(), R.id.container) } override fun onStart() { super.onStart() - val bm = Bitmap.createBitmap( - this.container.width, - this.container.height, - Bitmap.Config.ARGB_8888) - - val tc = TableCanvas(bm) - tc.load(this) - - this.image_view.setImageBitmap(bm) +// val bm = Bitmap.createBitmap( +// this.container.width, +// this.container.height, +// Bitmap.Config.ARGB_8888) +// +// val tc = TableCanvas(bm) +// tc.load(this) +// +// this.image_view.setImageBitmap(bm) } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_replayer.xml b/app/src/main/res/layout/fragment_replayer.xml index 385acd4c..f7ee434a 100644 --- a/app/src/main/res/layout/fragment_replayer.xml +++ b/app/src/main/res/layout/fragment_replayer.xml @@ -9,28 +9,83 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:theme="@style/PokerAnalyticsTheme.Toolbar.Session" + app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> + app:title="@string/hand_history" /> + + +