Simple-Clock/app/src/main/kotlin/com/simplemobiletools/clock/fragments/StopwatchFragment.kt

220 lines
7.9 KiB
Kotlin

package com.simplemobiletools.clock.fragments
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Matrix
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.simplemobiletools.clock.R
import com.simplemobiletools.clock.activities.SimpleActivity
import com.simplemobiletools.clock.adapters.StopwatchAdapter
import com.simplemobiletools.clock.databinding.FragmentStopwatchBinding
import com.simplemobiletools.clock.extensions.config
import com.simplemobiletools.clock.extensions.formatStopwatchTime
import com.simplemobiletools.clock.helpers.SORT_BY_LAP
import com.simplemobiletools.clock.helpers.SORT_BY_LAP_TIME
import com.simplemobiletools.clock.helpers.SORT_BY_TOTAL_TIME
import com.simplemobiletools.clock.helpers.Stopwatch
import com.simplemobiletools.clock.models.Lap
import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.SORT_DESCENDING
class StopwatchFragment : Fragment() {
private var storedTextColor = 0
lateinit var stopwatchAdapter: StopwatchAdapter
private lateinit var binding: FragmentStopwatchBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
storeStateVariables()
val sorting = requireContext().config.stopwatchLapsSort
Lap.sorting = sorting
binding = FragmentStopwatchBinding.inflate(inflater, container, false).apply {
stopwatchTime.setOnClickListener {
togglePlayPause()
}
stopwatchPlayPause.setOnClickListener {
togglePlayPause()
}
stopwatchReset.setOnClickListener {
resetStopwatch()
}
stopwatchSortingIndicator1.setOnClickListener {
changeSorting(SORT_BY_LAP)
}
stopwatchSortingIndicator2.setOnClickListener {
changeSorting(SORT_BY_LAP_TIME)
}
stopwatchSortingIndicator3.setOnClickListener {
changeSorting(SORT_BY_TOTAL_TIME)
}
stopwatchLap.setOnClickListener {
stopwatchSortingIndicatorsHolder.beVisible()
Stopwatch.lap()
updateLaps()
}
stopwatchAdapter = StopwatchAdapter(activity as SimpleActivity, ArrayList(), stopwatchList) {
if (it is Int) {
changeSorting(it)
}
}
stopwatchList.adapter = stopwatchAdapter
}
updateSortingIndicators(sorting)
return binding.root
}
override fun onResume() {
super.onResume()
setupViews()
val configTextColor = requireContext().getProperTextColor()
if (storedTextColor != configTextColor) {
stopwatchAdapter.updateTextColor(configTextColor)
}
Stopwatch.addUpdateListener(updateListener)
updateLaps()
binding.stopwatchSortingIndicatorsHolder.beVisibleIf(Stopwatch.laps.isNotEmpty())
if (Stopwatch.laps.isNotEmpty()) {
updateSorting(Lap.sorting)
}
if (requireContext().config.toggleStopwatch) {
requireContext().config.toggleStopwatch = false
startStopWatch()
}
}
override fun onPause() {
super.onPause()
storeStateVariables()
Stopwatch.removeUpdateListener(updateListener)
}
private fun storeStateVariables() {
storedTextColor = requireContext().getProperTextColor()
}
private fun setupViews() {
val properPrimaryColor = requireContext().getProperPrimaryColor()
binding.apply {
requireContext().updateTextColors(stopwatchFragment)
stopwatchPlayPause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, properPrimaryColor)
stopwatchReset.applyColorFilter(requireContext().getProperTextColor())
}
}
private fun updateIcons(state: Stopwatch.State) {
val drawableId =
if (state == Stopwatch.State.RUNNING) com.simplemobiletools.commons.R.drawable.ic_pause_vector else com.simplemobiletools.commons.R.drawable.ic_play_vector
val iconColor = if (requireContext().getProperPrimaryColor() == Color.WHITE) Color.BLACK else Color.WHITE
binding.stopwatchPlayPause.setImageDrawable(resources.getColoredDrawableWithColor(drawableId, iconColor))
}
private fun togglePlayPause() {
(activity as SimpleActivity).handleNotificationPermission { granted ->
if (granted) {
Stopwatch.toggle(true)
} else {
PermissionRequiredDialog(
activity as SimpleActivity,
com.simplemobiletools.commons.R.string.allow_notifications_reminders,
{ (activity as SimpleActivity).openNotificationSettings() })
}
}
}
private fun updateDisplayedText(totalTime: Long, lapTime: Long, useLongerMSFormat: Boolean) {
binding.stopwatchTime.text = totalTime.formatStopwatchTime(useLongerMSFormat)
if (Stopwatch.laps.isNotEmpty() && lapTime != -1L) {
stopwatchAdapter.updateLastField(lapTime, totalTime)
}
}
private fun resetStopwatch() {
Stopwatch.reset()
updateLaps()
binding.apply {
stopwatchReset.beGone()
stopwatchLap.beGone()
stopwatchTime.text = 0L.formatStopwatchTime(false)
stopwatchSortingIndicatorsHolder.beInvisible()
}
}
private fun changeSorting(clickedValue: Int) {
val sorting = if (Lap.sorting and clickedValue != 0) {
Lap.sorting.flipBit(SORT_DESCENDING)
} else {
clickedValue or SORT_DESCENDING
}
updateSorting(sorting)
}
private fun updateSorting(sorting: Int) {
updateSortingIndicators(sorting)
Lap.sorting = sorting
requireContext().config.stopwatchLapsSort = sorting
updateLaps()
}
private fun updateSortingIndicators(sorting: Int) {
var bitmap = requireContext().resources.getColoredBitmap(R.drawable.ic_sorting_triangle_vector, requireContext().getProperPrimaryColor())
binding.apply {
stopwatchSortingIndicator1.beInvisibleIf(sorting and SORT_BY_LAP == 0)
stopwatchSortingIndicator2.beInvisibleIf(sorting and SORT_BY_LAP_TIME == 0)
stopwatchSortingIndicator3.beInvisibleIf(sorting and SORT_BY_TOTAL_TIME == 0)
val activeIndicator = when {
sorting and SORT_BY_LAP != 0 -> stopwatchSortingIndicator1
sorting and SORT_BY_LAP_TIME != 0 -> stopwatchSortingIndicator2
else -> stopwatchSortingIndicator3
}
if (sorting and SORT_DESCENDING == 0) {
val matrix = Matrix()
matrix.postScale(1f, -1f)
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
activeIndicator.setImageBitmap(bitmap)
}
}
fun startStopWatch() {
if (Stopwatch.state == Stopwatch.State.STOPPED) {
togglePlayPause()
}
}
private fun updateLaps() {
stopwatchAdapter.updateItems(Stopwatch.laps)
}
private val updateListener = object : Stopwatch.UpdateListener {
override fun onUpdate(totalTime: Long, lapTime: Long, useLongerMSFormat: Boolean) {
updateDisplayedText(totalTime, lapTime, useLongerMSFormat)
}
override fun onStateChanged(state: Stopwatch.State) {
updateIcons(state)
binding.stopwatchLap.beVisibleIf(state == Stopwatch.State.RUNNING)
binding.stopwatchReset.beVisibleIf(state != Stopwatch.State.STOPPED)
}
}
}