mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Add option to reverse tapping (#3360)
* Add option to reverse tapping * Fix string for preference key * Invert tapping for Webtoon and Vertical * Use enum instead of boolean * Add option to reader sheet * Hide from reader sheet if tapping disabled and remove hard coded string * Hide option if tapping disabled
This commit is contained in:
		| @@ -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" | ||||
|   | ||||
| @@ -30,4 +30,11 @@ object PreferenceValues { | ||||
|         COMFORTABLE_GRID, | ||||
|         LIST, | ||||
|     } | ||||
|  | ||||
|     enum class TappingInvertMode { | ||||
|         NONE, | ||||
|         HORIZONTAL, | ||||
|         VERTICAL, | ||||
|         BOTH | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 <reified T : Enum<T>> Spinner.bindToPreference(pref: Preference<T>) { | ||||
|         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 <string-array> | ||||
|   | ||||
| @@ -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 }) | ||||
|  | ||||
|   | ||||
| @@ -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() | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -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() | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user