work in progress: table drawing fucked up, added navigation between hh edit and replay, plus next/forward hh

hh
Laurent 5 years ago
parent d8c6e6cbd5
commit f8fccc72cf
  1. 7
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedFragment.kt
  2. 166
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryActivity.kt
  3. 143
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt
  4. 76
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerAnimator.kt
  5. 72
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerFragment.kt
  6. 4
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt
  7. 9
      app/src/main/res/drawable/ic_edit.xml
  8. 9
      app/src/main/res/drawable/ic_player.xml
  9. 6
      app/src/main/res/menu/toolbar_hand_history.xml
  10. 34
      app/src/main/res/menu/toolbar_replayer.xml
  11. 1
      app/src/main/res/values/strings.xml

@ -466,10 +466,9 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate {
*/
private fun createNewHandHistory() {
val intent = Intent(requireContext(), TestActivity::class.java)
startActivity(intent)
return
// val intent = Intent(requireContext(), TestActivity::class.java)
// startActivity(intent)
// return
AppGuard.endOfUse?.let { endDate ->
if (Date().after(endDate)) {

@ -1,13 +1,21 @@
package net.pokeranalytics.android.ui.modules.handhistory
import android.Manifest
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.extensions.toByteArray
import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerAnimator
import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerFragment
import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableDrawer
import net.pokeranalytics.android.util.video.MMediaMuxer
import timber.log.Timber
class HandHistoryActivity : BaseActivity() {
@ -18,7 +26,7 @@ class HandHistoryActivity : BaseActivity() {
ATTACHED("attached")
}
private var fragment: HandHistoryFragment? = null
private var fragment: Fragment? = null
companion object {
@ -50,6 +58,16 @@ class HandHistoryActivity : BaseActivity() {
private fun initUI() {
val handHistoryId = intent.getStringExtra(IntentKey.IDENTIFIER.keyName)
if (handHistoryId != null) {
showReplayer(handHistoryId)
} else {
showEditMode()
}
}
fun showEditMode(handHistoryId: String? = null) {
val sessionId = intent.getStringExtra(IntentKey.SESSION_CONFIGURATION.keyName)
val attached = intent.getBooleanExtra(IntentKey.ATTACHED.keyName, false)
@ -62,11 +80,24 @@ class HandHistoryActivity : BaseActivity() {
this.fragment = fragment
}
fun showReplayer(handHistoryId: String) {
// val sessionId = intent.getStringExtra(IntentKey.SESSION_CONFIGURATION.keyName)
// val attached = intent.getBooleanExtra(IntentKey.ATTACHED.keyName, false)
val fragment = ReplayerFragment.newInstance(handHistoryId)
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.container, fragment)
fragmentTransaction.commit()
this.fragment = fragment
}
override fun onBackPressed() {
var shouldShowDataLossWarning = false
this.fragment?.let { hhFragment ->
if (hhFragment.isEditing) {
if ((hhFragment as? HandHistoryFragment)?.isEditing == true) {
shouldShowDataLossWarning = true
}
}
@ -87,4 +118,135 @@ class HandHistoryActivity : BaseActivity() {
}
private lateinit var handHistory: HandHistory
/***
* Shows a popup with the various export options
*/
fun exportHand(handHistory: HandHistory) {
this.handHistory = handHistory
val builder: android.app.AlertDialog.Builder = android.app.AlertDialog.Builder(this)
builder.setTitle(R.string.export)
builder.setItems(
arrayOf<CharSequence>(
getString(R.string.text),
getString(R.string.video)
// "GIF"
)
) { _, index ->
// The 'which' argument contains the index position
// of the selected item
when (index) {
0 -> this.textExport()
1 -> this.videoExportAskForPermission()
2 -> this.gifExport()
}
}
builder.create().show()
}
private fun videoExportAskForPermission() {
askForPermission(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), RequestCode.PERMISSION_WRITE_EXTERNAL_STORAGE.value) { granted ->
if (granted) {
videoExport()
}
}
}
private fun videoExport() {
val animator = ReplayerAnimator(this.handHistory, true)
val square = 1024f
val width = square
val height = square
animator.setDimension(width, height)
TableDrawer.configurePaints(this, animator)
val muxer = MMediaMuxer()
muxer.Init(this, width.toInt(), height.toInt(), "hhVideo", "YES!")
animator.frames(this) { bitmap, count ->
try {
val byteArray = bitmap.toByteArray()
muxer.AddFrame(byteArray, count, false)
} catch (e: Exception) {
Timber.e("error = ${e.message}")
}
}
muxer.CreateVideo()
val path = muxer.GetPath()
Timber.d("**** Video path = $path")
// Timber.d("**** Start video test")
//
// val width = 480
// val height = 480
//
// val bitmap = Bitmap.createBitmap(480, 480, Bitmap.Config.ARGB_8888)
// val canvas = Canvas(bitmap)
//
// val paint = Paint()
// paint.isAntiAlias = true
// paint.style = Paint.Style.STROKE
// paint.strokeWidth = 20.0.toFloat()
// paint.color = requireContext().getColor(R.color.blue)
//
// canvas.drawRect(Rect(0,0, width, height), paint)
//
// bitmap.let {
//
// val muxer = MMediaMuxer()
//
// Timber.d("width = ${it.width}, height = ${it.height}")
//
// val width = (it.width / 2) * 2
// val height= (it.height / 2) * 2
//
// muxer.Init(requireActivity(), width, height, "hhVideo", "YES!")
//
// Timber.d("**** Adds frames")
// for (i in 0..50) {
//
// try {
// val byteArray = it.toByteArray()
// muxer.AddFrame(byteArray)
// } catch (e: Exception) {
// Timber.e("error = ${e.message}")
// }
// }
// Timber.d("**** Create video")
// muxer.CreateVideo()
//
// val path = muxer.GetPath()
// Timber.d("**** Video path = $path")
// }
}
private fun gifExport() {
}
private fun textExport() {
val hhString = this.handHistory.localizedString(this)
Timber.d("hand = $hhString")
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.type = "text/plain"
shareIntent.putExtra(Intent.EXTRA_TEXT, hhString)
startActivity(Intent.createChooser(shareIntent, "Share hand history"))
}
}

@ -1,12 +1,9 @@
package net.pokeranalytics.android.ui.modules.handhistory
import android.Manifest
import android.animation.ValueAnimator
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Canvas
import android.os.Bundle
import android.os.Handler
import android.view.*
@ -27,21 +24,16 @@ 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
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
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.ReplayerAnimator
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
import net.pokeranalytics.android.util.extensions.findById
import net.pokeranalytics.android.util.video.MMediaMuxer
import timber.log.Timber
@ -220,6 +212,7 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.replayer -> showReplayer()
R.id.edit_save -> saveOrEdit()
R.id.add -> addNewHand()
R.id.delete -> deleteHand()
@ -230,6 +223,14 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
return true
}
private fun showReplayer() {
(this.activity as HandHistoryActivity).showReplayer(this.model.handHistory.id)
}
private fun exportHand() {
(this.activity as HandHistoryActivity).exportHand(this.model.handHistory)
}
/***
* Shows or hide the keyboard depending on the [selection]
*/
@ -694,131 +695,5 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
this.model.clearSelection()
}
/***
* Shows a popup with the various export options
*/
private fun exportHand() {
val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder.setTitle(R.string.export)
builder.setItems(
arrayOf<CharSequence>(
getString(R.string.text),
getString(R.string.video)
// "GIF"
)
) { _, index ->
// The 'which' argument contains the index position
// of the selected item
when (index) {
0 -> this.textExport()
1 -> this.videoExportAskForPermission()
2 -> this.gifExport()
}
}
builder.create().show()
}
private fun videoExportAskForPermission() {
askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, RequestCode.PERMISSION_WRITE_EXTERNAL_STORAGE.value) { granted ->
if (granted) {
videoExport()
}
}
}
private fun videoExport() {
val animator = ReplayerAnimator(this.model.handHistory, true)
val square = 1024f
val width = square
val height = square
animator.setDimension(width, height)
TableDrawer.configurePaints(requireContext(), animator)
val muxer = MMediaMuxer()
muxer.Init(requireActivity(), width.toInt(), height.toInt(), "hhVideo", "YES!")
animator.frames(requireContext()) { bitmap, count ->
try {
val byteArray = bitmap.toByteArray()
muxer.AddFrame(byteArray, count, false)
} catch (e: Exception) {
Timber.e("error = ${e.message}")
}
}
muxer.CreateVideo()
val path = muxer.GetPath()
Timber.d("**** Video path = $path")
// Timber.d("**** Start video test")
//
// val width = 480
// val height = 480
//
// val bitmap = Bitmap.createBitmap(480, 480, Bitmap.Config.ARGB_8888)
// val canvas = Canvas(bitmap)
//
// val paint = Paint()
// paint.isAntiAlias = true
// paint.style = Paint.Style.STROKE
// paint.strokeWidth = 20.0.toFloat()
// paint.color = requireContext().getColor(R.color.blue)
//
// canvas.drawRect(Rect(0,0, width, height), paint)
//
// bitmap.let {
//
// val muxer = MMediaMuxer()
//
// Timber.d("width = ${it.width}, height = ${it.height}")
//
// val width = (it.width / 2) * 2
// val height= (it.height / 2) * 2
//
// muxer.Init(requireActivity(), width, height, "hhVideo", "YES!")
//
// Timber.d("**** Adds frames")
// for (i in 0..50) {
//
// try {
// val byteArray = it.toByteArray()
// muxer.AddFrame(byteArray)
// } catch (e: Exception) {
// Timber.e("error = ${e.message}")
// }
// }
// Timber.d("**** Create video")
// muxer.CreateVideo()
//
// val path = muxer.GetPath()
// Timber.d("**** Video path = $path")
// }
}
private fun gifExport() {
}
private fun textExport() {
val hhString = this.model.handHistory.localizedString(this.requireContext())
Timber.d("hand = $hhString")
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.type = "text/plain"
shareIntent.putExtra(Intent.EXTRA_TEXT, hhString)
startActivity(Intent.createChooser(shareIntent, "Share hand history"))
}
}

@ -10,6 +10,7 @@ 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
import kotlin.math.abs
import kotlin.math.max
class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
@ -82,6 +83,15 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
}
}
private val visualOccurences: Int
get() {
return if (this.currentStepIndex == this.steps.size - 1 && this.currentFrame == this.numberOfFramesForCurrentStep - 1) {
FrameType.STATE.visualOccurences * 4
} else {
this.frameType.visualOccurences
}
}
/***
* Returns if the animator has more frame to show
*/
@ -99,7 +109,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
/***
* The list of steps, scannable with back/forward buttons
*/
private var steps: List<HandStep>
private var steps: List<HandStep> = listOf()
/***
* The index of the last blind in the action list
@ -121,9 +131,13 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
}
init {
this.actionList.load(this.handHistory)
loadHandHistory(this.handHistory)
}
this.steps = HandStep.createSteps(this.handHistory)
fun loadHandHistory(handHistory: HandHistory) {
this.actionList.load(handHistory)
this.steps = HandStep.createSteps(handHistory)
val bi = this.steps.indexOfLast { it is ComputedAction && it.action.type?.isBlind == true }
this.lastBlindIndex = max(bi, 0) // in case indexOfLast returns -1
@ -162,7 +176,8 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
get() { return this.height / 2f }
var tableRect = RectF()
var tableCornerRadius = 0f
var tableCornerXRadius = 0f
var tableCornerYRadius = 0f
var cardSpecs: Size = Size(0f, 0f)
var cardRadius = 0f
@ -212,17 +227,36 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
this.height = height
val maxPlayerCards = this.handHistory.maxPlayerCards
val grid = when (this.handHistory.numberOfPlayers) {
2, 3 -> Pair(2, 3)
9, 10 -> Pair(4, 5)
else -> Pair(3, 4)
}
val portrait = height > width
val playerPerColumn = if (portrait) 4 else 3
val playerPerRow = 12 / playerPerColumn // 3 or 4
val playerPerColumn = if (portrait) grid.second else grid.first
val playerPerRow = if (portrait) grid.first else grid.second
val padding = if (portrait) 0.8f else 0.95f
this.tableHPadding = width / playerPerRow / 2 * padding
this.tableVPadding = height / playerPerColumn * 0.8f
this.tableRect = RectF(tableHPadding, tableVPadding, width - tableHPadding, height - tableVPadding)
this.tableCornerRadius = (if (portrait) width else height) / 8
this.tableCornerXRadius = this.tableRect.width() / 3
this.tableCornerYRadius = this.tableRect.height() / 3
// for (i in (0 until handHistory.numberOfPlayers)) {
//
// val angle = i * (2 * Math.PI / handHistory.numberOfPlayers)
// val x =
// val y =
//
// }
// this.tableCornerRadius = (if (portrait) width else height) / 8
this.tableStrokeWidth = tableHPadding / 5f
this.playerStrokeWidth = this.tableStrokeWidth / 4f
@ -280,8 +314,8 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
var pIndex = -1
repartition.forEachIndexed { index, count ->
val x = width / (count + 1)
val y = height / (count + 1)
val xItemSpacing = width / (count + 1)
val yItemSpacing = height / (count + 1)
var rectCenterX: Float
var rectCenterY: Float
@ -305,7 +339,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
when (index) {
0 -> { // bottom
rectCenterX = x * i
rectCenterX = xItemSpacing * i
rectCenterY = height - this.tableVPadding
circleOffset *= -1
chipXOffset = cornerDirection * chipsHorizontalOffsetFromStackCenter
@ -313,21 +347,33 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
chipTextYOffsetCoef = 1f
}
1 -> { // left
rectCenterY = if (count == 4 && (i == 2 || i == 3)) {
height - yItemSpacing - this.playerItemsHeight * 1.2f - pzHeight * (i - 2)
} else {
height - yItemSpacing * i
}
rectCenterX = this.tableHPadding
rectCenterY = height - y * i
// rectCenterY = height - yItemSpacing * i
chipXOffset = 1 * chipsHorizontalOffsetFromStackCenter
chipYOffset = cornerDirection * -1 * chipsVerticalOffsetFromStackCenter
chipTextYOffsetCoef = 1f * (i - 1) / count
if (count == 4 && i == 1) {
circleOffset *= -1
} else {
circleOffset = abs(circleOffset)
}
}
2 -> { // top
rectCenterX = x * i
rectCenterX = xItemSpacing * i
rectCenterY = this.tableVPadding
chipXOffset = cornerDirection * -1 * chipsHorizontalOffsetFromStackCenter
chipYOffset = 1 * chipsVerticalOffsetFromStackCenter
}
3 -> { // right
rectCenterX = width - this.tableHPadding
rectCenterY = y * i
rectCenterY = yItemSpacing * i
chipXOffset = -1 * chipsHorizontalOffsetFromStackCenter
chipYOffset = cornerDirection * chipsVerticalOffsetFromStackCenter
chipTextYOffsetCoef = 1f * (count - i + 1) / count
@ -502,7 +548,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
fun frames(context: Context, frameHandler: (Bitmap, Int) -> Unit) {
this.steps.forEach { step ->
this.steps.forEach { _ ->
while (this.shouldShowAdditionalFrame) {
@ -510,7 +556,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
val canvas = Canvas(bitmap)
TableDrawer.drawTable(this, canvas, context)
frameHandler(bitmap, this.frameType.visualOccurences)
frameHandler(bitmap, this.visualOccurences)
frameDrawn()
}

@ -3,18 +3,34 @@ 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 android.view.*
import androidx.lifecycle.ViewModelProviders
import io.realm.Sort
import kotlinx.android.synthetic.main.fragment_replayer.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.modules.handhistory.model.HandHistoryViewModel
import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity
import net.pokeranalytics.android.util.extensions.findById
class ReplayerFragment : RealmFragment() {
private enum class BundleKey(var value: String) {
HAND_HISTORY_ID("hand_history_id"),
}
companion object {
fun newInstance(handHistoryId: String): ReplayerFragment {
val fragment = ReplayerFragment()
val bundle = Bundle()
bundle.putSerializable(BundleKey.HAND_HISTORY_ID.value, handHistoryId)
fragment.arguments = bundle
return fragment
}
}
/***
* The fragment's ViewModel
*/
@ -40,15 +56,23 @@ class ReplayerFragment : RealmFragment() {
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.toolbar_replayer, menu)
}
private fun initData() {
val id = arguments?.getString(BundleKey.HAND_HISTORY_ID.value) ?: throw PAIllegalStateException("Attempt to start a replayer without hh id")
val hh = getRealm().findById<HandHistory>(id) ?: throw PAIllegalStateException("hh with id: $id not found")
loadHand(hh)
// TODO change
val hh = 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)
// val hhm = ViewModelProviders.of(this)[HandHistoryViewModel::class.java]
val hhm = ViewModelProviders.of(this)[HandHistoryViewModel::class.java]
loadHand(hh)
}
private fun initUI() {
@ -74,6 +98,24 @@ class ReplayerFragment : RealmFragment() {
updateSpeedButtonText()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.edit -> edit()
R.id.share -> share()
}
return true
}
private fun edit() {
(activity as? HandHistoryActivity)?.showEditMode(this.model.animator?.handHistory?.id)
}
private fun share() {
this.model.animator?.handHistory?.let {
(this.activity as HandHistoryActivity).exportHand(it)
} ?: throw PAIllegalStateException("Attempt to export without a hand")
}
private fun updateSpeedButtonText() {
this.speed.text = "${this.model.speedMultiplier.value}x"
}
@ -143,11 +185,23 @@ class ReplayerFragment : RealmFragment() {
}
private fun nextHand() {
// TODO
val hands = getRealm().where(HandHistory::class.java).sort("date", Sort.DESCENDING).findAll()
val index = hands.indexOfFirst { it.id == this.model.animator?.handHistory?.id }
if (index < hands.size - 1) {
hands[index + 1]?.let {
loadHand(it)
}
}
}
private fun previousHand() {
// TODO
val hands = getRealm().where(HandHistory::class.java).sort("date", Sort.DESCENDING).findAll()
val index = hands.indexOfFirst { it.id == this.model.animator?.handHistory?.id }
if (index > 0) {
hands[index - 1]?.let {
loadHand(it)
}
}
}
private fun changeSpeed() {

@ -212,14 +212,14 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
canvas.drawColor(context.getColor(backgroundColor))
canvas.drawRoundRect(animator.tableRect, animator.tableCornerRadius, animator.tableCornerRadius, this.tablePaint)
canvas.drawRoundRect(animator.tableRect, animator.tableCornerXRadius, animator.tableCornerYRadius, this.tablePaint)
this.cardTextPaint.textSize = animator.cardSpecs.height * .38f
val hh = animator.handHistory
for (i in 0 until hh.numberOfPlayers) {
drawPlayerRectangle(i,false, animator, canvas, context)
drawPlayerCircle(i, animator, canvas, context)
// drawDealerButton(animator, canvas, context)
}
}

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="36dp"
android:height="36dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"
android:fillColor="#ffffff"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="36dp"
android:height="36dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20,8L4,8L4,6h16v2zM18,2L6,2v2h12L18,2zM22,12v8c0,1.1 -0.9,2 -2,2L4,22c-1.1,0 -2,-0.9 -2,-2v-8c0,-1.1 0.9,-2 2,-2h16c1.1,0 2,0.9 2,2zM16,16l-6,-3.27v6.53L16,16z"
android:fillColor="#ffffff"/>
</vector>

@ -2,6 +2,12 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/replayer"
android:icon="@drawable/ic_player"
android:title="@string/replayer"
app:showAsAction="always" />
<item
android:id="@+id/edit_save"
android:title="@string/save"

@ -3,33 +3,15 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/previous_hand"
android:title="@string/previous"
android:icon="@drawable/ic_skip_previous_white"
app:showAsAction="ifRoom" />
<item
android:id="@+id/next_hand"
android:title="@string/next"
android:icon="@drawable/ic_skip_next_white"
app:showAsAction="ifRoom" />
<item
android:id="@+id/play_pause"
android:title="@string/pause"
android:icon="@drawable/ic_play_arrow"
app:showAsAction="ifRoom" />
<item
android:id="@+id/speed"
android:title="1x"
app:showAsAction="ifRoom" />
<item
android:id="@+id/previous_action"
android:title="@string/previous"
android:icon="@drawable/ic_fast_rewind_white"
app:showAsAction="ifRoom" />
android:id="@+id/share"
android:title="@string/sharing"
android:icon="@drawable/ic_share"
app:showAsAction="always" />
<item
android:id="@+id/next_action"
android:title="@string/next"
android:icon="@drawable/ic_fast_forward_white"
android:id="@+id/edit"
android:title="@string/edit"
android:icon="@drawable/ic_edit"
app:showAsAction="ifRoom" />
</menu>

@ -799,5 +799,6 @@
<string name="hh_player_setting">tap to set player, hand or stack</string>
<string name="board">board</string>
<string name="data_loss_warning">All unsaved changes will be lost. Do you really want to continue?</string>
<string name="replayer">Replayer</string>
</resources>

Loading…
Cancel
Save