diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index c2ba44e16b..14246b57e6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -55,6 +55,8 @@ object PreferenceKeys { const val readWithTapping = "reader_tap" + const val readWithTappingInverted = "reader_tapping_inverted" + const val readWithLongTap = "reader_long_tap" const val readWithVolumeKeys = "reader_volume_keys" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt index 312544684d..e60f7f508a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt @@ -30,4 +30,11 @@ object PreferenceValues { COMFORTABLE_GRID, LIST, } + + enum class TappingInvertMode { + NONE, + HORIZONTAL, + VERTICAL, + BOTH + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 76d049c6a1..61c209f2f5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -121,6 +121,8 @@ class PreferencesHelper(val context: Context) { fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true) + fun readWithTappingInverted() = flowPrefs.getEnum(Keys.readWithTappingInverted, Values.TappingInvertMode.NONE) + fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true) fun readWithVolumeKeys() = flowPrefs.getBoolean(Keys.readWithVolumeKeys, false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt index 19e9e6c572..87d50f85e9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt @@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer +import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.invisible import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener @@ -23,11 +24,13 @@ import kotlinx.android.synthetic.main.reader_settings_sheet.cutout_short import kotlinx.android.synthetic.main.reader_settings_sheet.fullscreen import kotlinx.android.synthetic.main.reader_settings_sheet.keepscreen import kotlinx.android.synthetic.main.reader_settings_sheet.long_tap +import kotlinx.android.synthetic.main.reader_settings_sheet.navigation_prefs_group import kotlinx.android.synthetic.main.reader_settings_sheet.page_transitions import kotlinx.android.synthetic.main.reader_settings_sheet.pager_prefs_group import kotlinx.android.synthetic.main.reader_settings_sheet.rotation_mode import kotlinx.android.synthetic.main.reader_settings_sheet.scale_type import kotlinx.android.synthetic.main.reader_settings_sheet.show_page_number +import kotlinx.android.synthetic.main.reader_settings_sheet.tapping_inverted import kotlinx.android.synthetic.main.reader_settings_sheet.true_color import kotlinx.android.synthetic.main.reader_settings_sheet.viewer import kotlinx.android.synthetic.main.reader_settings_sheet.webtoon_prefs_group @@ -57,6 +60,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia super.onCreate(savedInstanceState) initGeneralPreferences() + initNavigationPreferences() when (activity.viewer) { is PagerViewer -> initPagerPreferences() @@ -119,6 +123,17 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values) } + /** + * Init the preferences for navigation. + */ + private fun initNavigationPreferences() { + if (!preferences.readWithTapping().get()) { + navigation_prefs_group.gone() + } + + tapping_inverted.bindToPreference(preferences.readWithTappingInverted()) + } + /** * Binds a checkbox or switch view with a boolean preference. */ @@ -137,6 +152,19 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia setSelection(pref.get() - offset, false) } + /** + * Binds a spinner to an enum preference. + */ + private inline fun > Spinner.bindToPreference(pref: Preference) { + val enumConstants = T::class.java.enumConstants + + onItemSelectedListener = IgnoreFirstSpinnerListener { position -> + enumConstants?.get(position)?.let { pref.set(it) } + } + + enumConstants?.indexOf(pref.get())?.let { setSelection(it, false) } + } + /** * Binds a spinner to an int preference. The position of the spinner item must * correlate with the [intValues] resource item (in arrays.xml), which is a diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt index 7520458216..78590a1c5f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer import com.tfcporciuncula.flow.Preference +import eu.kanade.tachiyomi.data.preference.PreferenceValues.TappingInvertMode import eu.kanade.tachiyomi.data.preference.PreferencesHelper import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -20,6 +21,7 @@ abstract class ViewerConfig(preferences: PreferencesHelper) { var tappingEnabled = true var longTapEnabled = true + var tappingInverted = TappingInvertMode.NONE var doubleTapAnimDuration = 500 var volumeKeysEnabled = false var volumeKeysInverted = false @@ -30,6 +32,9 @@ abstract class ViewerConfig(preferences: PreferencesHelper) { preferences.readWithTapping() .register({ tappingEnabled = it }) + preferences.readWithTappingInverted() + .register({ tappingInverted = it }) + preferences.readWithLongTap() .register({ longTapEnabled = it }) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt index 4bef6dd007..ef5c029d10 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt @@ -7,6 +7,7 @@ import android.view.View import android.view.ViewGroup.LayoutParams import androidx.viewpager.widget.ViewPager import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.preference.PreferenceValues.TappingInvertMode import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition import eu.kanade.tachiyomi.ui.reader.model.ReaderPage @@ -80,18 +81,28 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer { } }) pager.tapListener = { event -> + val invertMode = config.tappingInverted + if (this is VerticalPagerViewer) { val positionY = event.y + val tappingInverted = invertMode == TappingInvertMode.VERTICAL || invertMode == TappingInvertMode.BOTH + val topSideTap = positionY < pager.height * 0.33f && config.tappingEnabled + val bottomSideTap = positionY > pager.height * 0.66f && config.tappingEnabled + when { - positionY < pager.height * 0.33f && config.tappingEnabled -> moveLeft() - positionY > pager.height * 0.66f && config.tappingEnabled -> moveRight() + topSideTap && !tappingInverted || bottomSideTap && tappingInverted -> moveLeft() + bottomSideTap && !tappingInverted || topSideTap && tappingInverted -> moveRight() else -> activity.toggleMenu() } } else { val positionX = event.x + val tappingInverted = invertMode == TappingInvertMode.HORIZONTAL || invertMode == TappingInvertMode.BOTH + val leftSideTap = positionX < pager.width * 0.33f && config.tappingEnabled + val rightSideTap = positionX > pager.width * 0.66f && config.tappingEnabled + when { - positionX < pager.width * 0.33f && config.tappingEnabled -> moveLeft() - positionX > pager.width * 0.66f && config.tappingEnabled -> moveRight() + leftSideTap && !tappingInverted || rightSideTap && tappingInverted -> moveLeft() + rightSideTap && !tappingInverted || leftSideTap && tappingInverted -> moveRight() else -> activity.toggleMenu() } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt index 802f969e0f..b42d6594aa 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import android.view.ViewGroup.LayoutParams.MATCH_PARENT import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.WebtoonLayoutManager +import eu.kanade.tachiyomi.data.preference.PreferenceValues.TappingInvertMode import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition import eu.kanade.tachiyomi.ui.reader.model.ReaderPage @@ -94,9 +95,15 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr }) recycler.tapListener = { event -> val positionY = event.rawY + val invertMode = config.tappingInverted + val topSideTap = positionY < recycler.height * 0.33f && config.tappingEnabled + val bottomSideTap = positionY > recycler.height * 0.66f && config.tappingEnabled + + val tappingInverted = invertMode == TappingInvertMode.VERTICAL || invertMode == TappingInvertMode.BOTH + when { - positionY < recycler.height * 0.33f && config.tappingEnabled -> scrollUp() - positionY > recycler.height * 0.66f && config.tappingEnabled -> scrollDown() + topSideTap && !tappingInverted || bottomSideTap && tappingInverted -> scrollUp() + bottomSideTap && !tappingInverted || topSideTap && tappingInverted -> scrollDown() else -> activity.toggleMenu() } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt index 12fe7f5caa..86d561712c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt @@ -4,14 +4,18 @@ import android.os.Build import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys +import eu.kanade.tachiyomi.data.preference.PreferenceValues.TappingInvertMode +import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.util.preference.defaultValue import eu.kanade.tachiyomi.util.preference.entriesRes import eu.kanade.tachiyomi.util.preference.intListPreference +import eu.kanade.tachiyomi.util.preference.listPreference import eu.kanade.tachiyomi.util.preference.preferenceCategory import eu.kanade.tachiyomi.util.preference.summaryRes import eu.kanade.tachiyomi.util.preference.switchPreference import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.system.hasDisplayCutout +import kotlinx.coroutines.flow.launchIn class SettingsReaderController : SettingsController() { @@ -190,6 +194,26 @@ class SettingsReaderController : SettingsController() { titleRes = R.string.pref_read_with_tapping defaultValue = true } + listPreference { + key = Keys.readWithTappingInverted + titleRes = R.string.pref_read_with_tapping_inverted + entriesRes = arrayOf( + R.string.tapping_inverted_none, + R.string.tapping_inverted_horizontal, + R.string.tapping_inverted_vertical, + R.string.tapping_inverted_both + ) + entryValues = arrayOf( + TappingInvertMode.NONE.name, + TappingInvertMode.HORIZONTAL.name, + TappingInvertMode.VERTICAL.name, + TappingInvertMode.BOTH.name + ) + defaultValue = TappingInvertMode.NONE.name + summary = "%s" + + preferences.readWithTapping().asImmediateFlow { isVisible = it }.launchIn(scope) + } switchPreference { key = Keys.readWithLongTap titleRes = R.string.pref_read_with_long_tap diff --git a/app/src/main/res/layout/reader_settings_sheet.xml b/app/src/main/res/layout/reader_settings_sheet.xml index d7170ff69a..66a7938525 100644 --- a/app/src/main/res/layout/reader_settings_sheet.xml +++ b/app/src/main/res/layout/reader_settings_sheet.xml @@ -188,7 +188,7 @@ android:textColor="?attr/colorAccent" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/end_general_preferences" /> + app:layout_constraintTop_toBottomOf="@id/end_navigation_preferences" /> + + + + + + + + + + + app:layout_constraintTop_toBottomOf="@id/end_navigation_preferences" /> + + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index df09ca0f16..eacccb2d18 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -79,4 +79,11 @@ @string/filter_mode_multiply @string/filter_mode_screen + + + @string/tapping_inverted_none + @string/tapping_inverted_horizontal + @string/tapping_inverted_vertical + @string/tapping_inverted_both + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 53a413ce7e..0a8ac7df76 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -668,5 +668,10 @@ Backup and restore Progress Complete + Invert tapping + None + Horizontal + Vertical + Both