ReaderSettingsSheet.kt 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package eu.kanade.tachiyomi.ui.reader
  2. import android.os.Bundle
  3. import android.widget.CompoundButton
  4. import android.widget.Spinner
  5. import androidx.annotation.ArrayRes
  6. import androidx.core.view.isGone
  7. import androidx.core.view.isVisible
  8. import androidx.core.widget.NestedScrollView
  9. import com.google.android.material.bottomsheet.BottomSheetDialog
  10. import com.tfcporciuncula.flow.Preference
  11. import eu.kanade.tachiyomi.R
  12. import eu.kanade.tachiyomi.data.preference.PreferencesHelper
  13. import eu.kanade.tachiyomi.databinding.ReaderSettingsSheetBinding
  14. import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer
  15. import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
  16. import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
  17. import uy.kohesive.injekt.injectLazy
  18. /**
  19. * Sheet to show reader and viewer preferences.
  20. */
  21. class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDialog(activity) {
  22. private val preferences by injectLazy<PreferencesHelper>()
  23. private val binding = ReaderSettingsSheetBinding.inflate(activity.layoutInflater, null, false)
  24. init {
  25. val scroll = NestedScrollView(activity)
  26. scroll.addView(binding.root)
  27. setContentView(scroll)
  28. }
  29. /**
  30. * Called when the sheet is created. It initializes the listeners and values of the preferences.
  31. */
  32. override fun onCreate(savedInstanceState: Bundle?) {
  33. super.onCreate(savedInstanceState)
  34. initGeneralPreferences()
  35. when (activity.viewer) {
  36. is PagerViewer -> initPagerPreferences()
  37. is WebtoonViewer -> initWebtoonPreferences()
  38. }
  39. }
  40. /**
  41. * Init general reader preferences.
  42. */
  43. private fun initGeneralPreferences() {
  44. binding.viewer.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
  45. activity.presenter.setMangaViewer(position)
  46. val mangaViewer = activity.presenter.getMangaViewer()
  47. if (mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS) {
  48. initWebtoonPreferences()
  49. } else {
  50. initPagerPreferences()
  51. }
  52. }
  53. binding.viewer.setSelection(activity.presenter.manga?.viewer ?: 0, false)
  54. binding.rotationMode.bindToPreference(preferences.rotation(), 1)
  55. binding.backgroundColor.bindToIntPreference(preferences.readerTheme(), R.array.reader_themes_values)
  56. binding.showPageNumber.bindToPreference(preferences.showPageNumber())
  57. binding.fullscreen.bindToPreference(preferences.fullscreen())
  58. binding.keepscreen.bindToPreference(preferences.keepScreenOn())
  59. binding.longTap.bindToPreference(preferences.readWithLongTap())
  60. binding.alwaysShowChapterTransition.bindToPreference(preferences.alwaysShowChapterTransition())
  61. binding.pageTransitions.bindToPreference(preferences.pageTransitions())
  62. // If the preference is explicitly disabled, that means the setting was configured since there is a cutout
  63. if (activity.hasCutout || !preferences.cutoutShort().get()) {
  64. binding.cutoutShort.isVisible = true
  65. binding.cutoutShort.bindToPreference(preferences.cutoutShort())
  66. }
  67. }
  68. /**
  69. * Init the preferences for the pager reader.
  70. */
  71. private fun initPagerPreferences() {
  72. binding.webtoonPrefsGroup.root.isGone = true
  73. binding.pagerPrefsGroup.root.isVisible = true
  74. binding.pagerPrefsGroup.tappingPrefsGroup.isVisible = preferences.readWithTapping().get()
  75. binding.pagerPrefsGroup.tappingInverted.bindToPreference(preferences.pagerNavInverted())
  76. binding.pagerPrefsGroup.pagerNav.bindToPreference(preferences.navigationModePager())
  77. binding.pagerPrefsGroup.scaleType.bindToPreference(preferences.imageScaleType(), 1)
  78. binding.pagerPrefsGroup.zoomStart.bindToPreference(preferences.zoomStart(), 1)
  79. binding.pagerPrefsGroup.cropBorders.bindToPreference(preferences.cropBorders())
  80. }
  81. /**
  82. * Init the preferences for the webtoon reader.
  83. */
  84. private fun initWebtoonPreferences() {
  85. binding.pagerPrefsGroup.root.isGone = true
  86. binding.webtoonPrefsGroup.root.isVisible = true
  87. binding.webtoonPrefsGroup.tappingPrefsGroup.isVisible = preferences.readWithTapping().get()
  88. binding.webtoonPrefsGroup.tappingInverted.bindToPreference(preferences.webtoonNavInverted())
  89. binding.webtoonPrefsGroup.webtoonNav.bindToPreference(preferences.navigationModeWebtoon())
  90. binding.webtoonPrefsGroup.cropBordersWebtoon.bindToPreference(preferences.cropBordersWebtoon())
  91. binding.webtoonPrefsGroup.webtoonSidePadding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
  92. }
  93. /**
  94. * Binds a checkbox or switch view with a boolean preference.
  95. */
  96. private fun CompoundButton.bindToPreference(pref: Preference<Boolean>) {
  97. isChecked = pref.get()
  98. setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) }
  99. }
  100. /**
  101. * Binds a spinner to an int preference with an optional offset for the value.
  102. */
  103. private fun Spinner.bindToPreference(pref: Preference<Int>, offset: Int = 0) {
  104. onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
  105. pref.set(position + offset)
  106. }
  107. setSelection(pref.get() - offset, false)
  108. }
  109. /**
  110. * Binds a spinner to an enum preference.
  111. */
  112. private inline fun <reified T : Enum<T>> Spinner.bindToPreference(pref: Preference<T>) {
  113. val enumConstants = T::class.java.enumConstants
  114. onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
  115. enumConstants?.get(position)?.let { pref.set(it) }
  116. }
  117. enumConstants?.indexOf(pref.get())?.let { setSelection(it, false) }
  118. }
  119. /**
  120. * Binds a spinner to an int preference. The position of the spinner item must
  121. * correlate with the [intValues] resource item (in arrays.xml), which is a <string-array>
  122. * of int values that will be parsed here and applied to the preference.
  123. */
  124. private fun Spinner.bindToIntPreference(pref: Preference<Int>, @ArrayRes intValuesResource: Int) {
  125. val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() }
  126. onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
  127. pref.set(intValues[position]!!)
  128. }
  129. setSelection(intValues.indexOf(pref.get()), false)
  130. }
  131. }