mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Viewer navigation (#3869)
* Viewer navigation Co-authored-by: Harsh Parekh <h.x.dev@outlook.com> * Match current reader behavior and add ability to invert it * A bit of clean up * Clean up inversion * Only create navigator when changed and change tap zone when invertTapping is changed * Clean up PagerConfig * Change how Viewer navigation works * Add Edge Navigation Co-authored-by: Harsh Parekh <h.x.dev@outlook.com>
This commit is contained in:
		| @@ -65,6 +65,10 @@ object PreferenceKeys { | ||||
|  | ||||
|     const val readWithVolumeKeysInverted = "reader_volume_keys_inverted" | ||||
|  | ||||
|     const val navigationModePager = "reader_navigation_mode_pager" | ||||
|  | ||||
|     const val navigationModeWebtoon = "reader_navigation_mode_webtoon" | ||||
|  | ||||
|     const val webtoonSidePadding = "webtoon_side_padding" | ||||
|  | ||||
|     const val portraitColumns = "pref_library_columns_portrait_key" | ||||
|   | ||||
| @@ -31,10 +31,10 @@ object PreferenceValues { | ||||
|         LIST, | ||||
|     } | ||||
|  | ||||
|     enum class TappingInvertMode { | ||||
|     enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) { | ||||
|         NONE, | ||||
|         HORIZONTAL, | ||||
|         VERTICAL, | ||||
|         BOTH | ||||
|         HORIZONTAL(shouldInvertHorizontal = true), | ||||
|         VERTICAL(shouldInvertVertical = true), | ||||
|         BOTH(shouldInvertHorizontal = true, shouldInvertVertical = true) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -138,6 +138,10 @@ class PreferencesHelper(val context: Context) { | ||||
|  | ||||
|     fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false) | ||||
|  | ||||
|     fun navigationModePager() = flowPrefs.getInt(Keys.navigationModePager, 0) | ||||
|  | ||||
|     fun navigationModeWebtoon() = flowPrefs.getInt(Keys.navigationModeWebtoon, 0) | ||||
|  | ||||
|     fun portraitColumns() = flowPrefs.getInt(Keys.portraitColumns, 0) | ||||
|  | ||||
|     fun landscapeColumns() = flowPrefs.getInt(Keys.landscapeColumns, 0) | ||||
|   | ||||
| @@ -86,6 +86,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia | ||||
|         binding.webtoonPrefsGroup.isInvisible = true | ||||
|         binding.pagerPrefsGroup.isVisible = true | ||||
|  | ||||
|         binding.pagerNav.bindToPreference(preferences.navigationModePager()) | ||||
|         binding.scaleType.bindToPreference(preferences.imageScaleType(), 1) | ||||
|         binding.zoomStart.bindToPreference(preferences.zoomStart(), 1) | ||||
|         binding.cropBorders.bindToPreference(preferences.cropBorders()) | ||||
| @@ -98,6 +99,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia | ||||
|         binding.pagerPrefsGroup.isInvisible = true | ||||
|         binding.webtoonPrefsGroup.isVisible = true | ||||
|  | ||||
|         binding.webtoonNav.bindToPreference(preferences.navigationModeWebtoon()) | ||||
|         binding.cropBordersWebtoon.bindToPreference(preferences.cropBordersWebtoon()) | ||||
|         binding.webtoonSidePadding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values) | ||||
|     } | ||||
|   | ||||
| @@ -28,13 +28,18 @@ abstract class ViewerConfig(preferences: PreferencesHelper) { | ||||
|     var volumeKeysInverted = false | ||||
|     var trueColor = false | ||||
|     var alwaysShowChapterTransition = true | ||||
|     var navigationMode = 0 | ||||
|         protected set | ||||
|  | ||||
|     abstract var navigator: ViewerNavigation | ||||
|         protected set | ||||
|  | ||||
|     init { | ||||
|         preferences.readWithTapping() | ||||
|             .register({ tappingEnabled = it }) | ||||
|  | ||||
|         preferences.readWithTappingInverted() | ||||
|             .register({ tappingInverted = it }) | ||||
|             .register({ tappingInverted = it }, { navigator.invertMode = it }) | ||||
|  | ||||
|         preferences.readWithLongTap() | ||||
|             .register({ longTapEnabled = it }) | ||||
| @@ -58,6 +63,10 @@ abstract class ViewerConfig(preferences: PreferencesHelper) { | ||||
|             .register({ alwaysShowChapterTransition = it }) | ||||
|     } | ||||
|  | ||||
|     protected abstract fun defaultNavigation(): ViewerNavigation | ||||
|  | ||||
|     abstract fun updateNavigation(navigationMode: Int) | ||||
|  | ||||
|     fun <T> Preference<T>.register( | ||||
|         valueAssignment: (T) -> Unit, | ||||
|         onChanged: (T) -> Unit = {} | ||||
|   | ||||
| @@ -0,0 +1,43 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer | ||||
|  | ||||
| import android.graphics.PointF | ||||
| import android.graphics.RectF | ||||
| import eu.kanade.tachiyomi.data.preference.PreferenceValues | ||||
| import eu.kanade.tachiyomi.util.lang.invert | ||||
|  | ||||
| abstract class ViewerNavigation { | ||||
|  | ||||
|     enum class NavigationRegion { | ||||
|         NEXT, PREV, MENU | ||||
|     } | ||||
|  | ||||
|     data class Region( | ||||
|         val rectF: RectF, | ||||
|         val type: NavigationRegion | ||||
|     ) { | ||||
|         fun invert(invertMode: PreferenceValues.TappingInvertMode): Region { | ||||
|             if (invertMode == PreferenceValues.TappingInvertMode.NONE) return this | ||||
|             return this.copy( | ||||
|                 rectF = this.rectF.invert(invertMode) | ||||
|             ) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private var constantMenuRegion: RectF = RectF(0f, 0f, 1f, 0.05f) | ||||
|  | ||||
|     abstract var regions: List<Region> | ||||
|  | ||||
|     var invertMode: PreferenceValues.TappingInvertMode = PreferenceValues.TappingInvertMode.NONE | ||||
|  | ||||
|     fun getAction(pos: PointF): NavigationRegion { | ||||
|         val x = pos.x | ||||
|         val y = pos.y | ||||
|         val region = regions.map { it.invert(invertMode) } | ||||
|             .find { it.rectF.contains(x, y) } | ||||
|         return when { | ||||
|             region != null -> region.type | ||||
|             constantMenuRegion.contains(x, y) -> NavigationRegion.MENU | ||||
|             else -> NavigationRegion.MENU | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,32 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer.navigation | ||||
|  | ||||
| import android.graphics.RectF | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation | ||||
|  | ||||
| /** | ||||
|  * Visualization of default state without any inversion | ||||
|  * +---+---+---+ | ||||
|  * | N | N | N |   P: Previous | ||||
|  * +---+---+---+ | ||||
|  * | N | M | N |   M: Menu | ||||
|  * +---+---+---+ | ||||
|  * | N | P | N |   N: Next | ||||
|  * +---+---+---+ | ||||
| */ | ||||
| class EdgeNavigation : ViewerNavigation() { | ||||
|  | ||||
|     override var regions: List<Region> = listOf( | ||||
|         Region( | ||||
|             rectF = RectF(0f, 0f, 0.33f, 1f), | ||||
|             type = NavigationRegion.NEXT | ||||
|         ), | ||||
|         Region( | ||||
|             rectF = RectF(0.33f, 0.66f, 0.66f, 1f), | ||||
|             type = NavigationRegion.PREV | ||||
|         ), | ||||
|         Region( | ||||
|             rectF = RectF(0.66f, 0f, 1f, 1f), | ||||
|             type = NavigationRegion.NEXT | ||||
|         ), | ||||
|     ) | ||||
| } | ||||
| @@ -0,0 +1,28 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer.navigation | ||||
|  | ||||
| import android.graphics.RectF | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation | ||||
|  | ||||
| /** | ||||
|  * Visualization of default state without any inversion | ||||
|  * +---+---+---+ | ||||
|  * | M | M | M |   P: Previous | ||||
|  * +---+---+---+ | ||||
|  * | P | N | N |   M: Menu | ||||
|  * +---+---+---+ | ||||
|  * | P | N | N |   N: Next | ||||
|  * +---+---+---+ | ||||
| */ | ||||
| class KindlishNavigation : ViewerNavigation() { | ||||
|  | ||||
|     override var regions: List<Region> = listOf( | ||||
|         Region( | ||||
|             rectF = RectF(0.33f, 0.33f, 1f, 1f), | ||||
|             type = NavigationRegion.NEXT | ||||
|         ), | ||||
|         Region( | ||||
|             rectF = RectF(0f, 0.33f, 0.33f, 1f), | ||||
|             type = NavigationRegion.PREV | ||||
|         ) | ||||
|     ) | ||||
| } | ||||
| @@ -0,0 +1,36 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer.navigation | ||||
|  | ||||
| import android.graphics.RectF | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation | ||||
|  | ||||
| /** | ||||
|  * Visualization of default state without any inversion | ||||
|  * +---+---+---+ | ||||
|  * | N | N | N |   P: Previous | ||||
|  * +---+---+---+ | ||||
|  * | N | M | P |   M: Menu | ||||
|  * +---+---+---+ | ||||
|  * | P | P | P |   N: Next | ||||
|  * +---+---+---+ | ||||
|  */ | ||||
| open class LNavigation : ViewerNavigation() { | ||||
|  | ||||
|     override var regions: List<Region> = listOf( | ||||
|         Region( | ||||
|             rectF = RectF(0f, 0.33f, 0.33f, 0.66f), | ||||
|             type = NavigationRegion.NEXT | ||||
|         ), | ||||
|         Region( | ||||
|             rectF = RectF(0f, 0f, 1f, 0.33f), | ||||
|             type = NavigationRegion.NEXT | ||||
|         ), | ||||
|         Region( | ||||
|             rectF = RectF(0.66f, 0.33f, 1f, 0.66f), | ||||
|             type = NavigationRegion.PREV | ||||
|         ), | ||||
|         Region( | ||||
|             rectF = RectF(0f, 0.66f, 1f, 1f), | ||||
|             type = NavigationRegion.PREV | ||||
|         ) | ||||
|     ) | ||||
| } | ||||
| @@ -2,6 +2,10 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager | ||||
|  | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerConfig | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.navigation.EdgeNavigation | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.navigation.KindlishNavigation | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.navigation.LNavigation | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
|  | ||||
| @@ -29,6 +33,9 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe | ||||
|  | ||||
|         preferences.cropBorders() | ||||
|             .register({ imageCropBorders = it }, { imagePropertyChangedListener?.invoke() }) | ||||
|  | ||||
|         preferences.navigationModePager() | ||||
|             .register({ navigationMode = it }, { updateNavigation(navigationMode) }) | ||||
|     } | ||||
|  | ||||
|     private fun zoomTypeFromPreference(value: Int) { | ||||
| @@ -48,6 +55,28 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override var navigator: ViewerNavigation = defaultNavigation() | ||||
|         set(value) { | ||||
|             field = value.also { it.invertMode = this.tappingInverted } | ||||
|         } | ||||
|  | ||||
|     override fun defaultNavigation(): ViewerNavigation { | ||||
|         return when (viewer) { | ||||
|             is VerticalPagerViewer -> VerticalPagerDefaultNavigation() | ||||
|             else -> PagerDefaultNavigation() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun updateNavigation(navigationMode: Int) { | ||||
|         navigator = when (navigationMode) { | ||||
|             0 -> defaultNavigation() | ||||
|             1 -> LNavigation() | ||||
|             2 -> KindlishNavigation() | ||||
|             3 -> EdgeNavigation() | ||||
|             else -> defaultNavigation() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     enum class ZoomType { | ||||
|         Left, Center, Right | ||||
|     } | ||||
|   | ||||
| @@ -0,0 +1,31 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer.pager | ||||
|  | ||||
| import android.graphics.RectF | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.navigation.LNavigation | ||||
|  | ||||
| /** | ||||
|  * Visualization of default state without any inversion | ||||
|  * +---+---+---+ | ||||
|  * | N | M | P |   P: Previous | ||||
|  * +---+---+---+ | ||||
|  * | N | M | P |   M: Menu | ||||
|  * +---+---+---+ | ||||
|  * | N | M | P |   N: Next | ||||
|  * +---+---+---+ | ||||
|  */ | ||||
| class PagerDefaultNavigation : ViewerNavigation() { | ||||
|  | ||||
|     override var regions: List<Region> = listOf( | ||||
|         Region( | ||||
|             rectF = RectF(0f, 0f, 0.33f, 1f), | ||||
|             type = NavigationRegion.NEXT | ||||
|         ), | ||||
|         Region( | ||||
|             rectF = RectF(0.66f, 0f, 1f, 1f), | ||||
|             type = NavigationRegion.PREV | ||||
|         ), | ||||
|     ) | ||||
| } | ||||
|  | ||||
| class VerticalPagerDefaultNavigation : LNavigation() | ||||
| @@ -1,5 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer.pager | ||||
|  | ||||
| import android.graphics.PointF | ||||
| import android.view.InputDevice | ||||
| import android.view.KeyEvent | ||||
| import android.view.MotionEvent | ||||
| @@ -9,12 +10,12 @@ import androidx.core.view.isGone | ||||
| import androidx.core.view.isVisible | ||||
| 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 | ||||
| import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation | ||||
| import timber.log.Timber | ||||
| import kotlin.math.min | ||||
|  | ||||
| @@ -89,34 +90,12 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer { | ||||
|                 return@f | ||||
|             } | ||||
|  | ||||
|             val positionX = event.x | ||||
|             val positionY = event.y | ||||
|             val topSideTap = positionY < pager.height * 0.25f | ||||
|             val bottomSideTap = positionY > pager.height * 0.75f | ||||
|             val leftSideTap = positionX < pager.width * 0.33f | ||||
|             val rightSideTap = positionX > pager.width * 0.66f | ||||
|  | ||||
|             val invertMode = config.tappingInverted | ||||
|             val invertVertical = invertMode == TappingInvertMode.VERTICAL || invertMode == TappingInvertMode.BOTH | ||||
|             val invertHorizontal = invertMode == TappingInvertMode.HORIZONTAL || invertMode == TappingInvertMode.BOTH | ||||
|  | ||||
|             if (this is VerticalPagerViewer) { | ||||
|                 when { | ||||
|                     topSideTap && !invertVertical || bottomSideTap && invertVertical -> moveLeft() | ||||
|                     bottomSideTap && !invertVertical || topSideTap && invertVertical -> moveRight() | ||||
|  | ||||
|                     leftSideTap && !invertHorizontal || rightSideTap && invertHorizontal -> moveLeft() | ||||
|                     rightSideTap && !invertHorizontal || leftSideTap && invertHorizontal -> moveRight() | ||||
|  | ||||
|                     else -> activity.toggleMenu() | ||||
|                 } | ||||
|             } else { | ||||
|                 when { | ||||
|                     leftSideTap && !invertHorizontal || rightSideTap && invertHorizontal -> moveLeft() | ||||
|                     rightSideTap && !invertHorizontal || leftSideTap && invertHorizontal -> moveRight() | ||||
|  | ||||
|                     else -> activity.toggleMenu() | ||||
|                 } | ||||
|             val pos = PointF(event.rawX / pager.width, event.rawY / pager.height) | ||||
|             val navigator = config.navigator | ||||
|             when (navigator.getAction(pos)) { | ||||
|                 ViewerNavigation.NavigationRegion.MENU -> activity.toggleMenu() | ||||
|                 ViewerNavigation.NavigationRegion.NEXT -> moveToNext() | ||||
|                 ViewerNavigation.NavigationRegion.PREV -> moveToPrevious() | ||||
|             } | ||||
|         } | ||||
|         pager.longTapListener = f@{ | ||||
|   | ||||
| @@ -2,6 +2,10 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon | ||||
|  | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerConfig | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.navigation.EdgeNavigation | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.navigation.KindlishNavigation | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.navigation.LNavigation | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
|  | ||||
| @@ -22,5 +26,27 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) : ViewerConfi | ||||
|  | ||||
|         preferences.webtoonSidePadding() | ||||
|             .register({ sidePadding = it }, { imagePropertyChangedListener?.invoke() }) | ||||
|  | ||||
|         preferences.navigationModeWebtoon() | ||||
|             .register({ navigationMode = it }, { updateNavigation(it) }) | ||||
|     } | ||||
|  | ||||
|     override var navigator: ViewerNavigation = defaultNavigation() | ||||
|         set(value) { | ||||
|             field = value.also { it.invertMode = tappingInverted } | ||||
|         } | ||||
|  | ||||
|     override fun defaultNavigation(): ViewerNavigation { | ||||
|         return WebtoonDefaultNavigation() | ||||
|     } | ||||
|  | ||||
|     override fun updateNavigation(navigationMode: Int) { | ||||
|         this.navigator = when (navigationMode) { | ||||
|             0 -> defaultNavigation() | ||||
|             1 -> LNavigation() | ||||
|             2 -> KindlishNavigation() | ||||
|             3 -> EdgeNavigation() | ||||
|             else -> defaultNavigation() | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer.webtoon | ||||
|  | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.navigation.LNavigation | ||||
|  | ||||
| class WebtoonDefaultNavigation : LNavigation() | ||||
| @@ -1,5 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer.webtoon | ||||
|  | ||||
| import android.graphics.PointF | ||||
| import android.view.KeyEvent | ||||
| import android.view.MotionEvent | ||||
| import android.view.View | ||||
| @@ -9,12 +10,12 @@ import androidx.core.view.isGone | ||||
| import androidx.core.view.isVisible | ||||
| 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 | ||||
| import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation | ||||
| import rx.subscriptions.CompositeSubscription | ||||
| import timber.log.Timber | ||||
| import kotlin.math.max | ||||
| @@ -101,25 +102,15 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr | ||||
|                 return@f | ||||
|             } | ||||
|  | ||||
|             val positionX = event.rawX | ||||
|             val positionY = event.rawY | ||||
|             val topSideTap = positionY < recycler.height * 0.25f | ||||
|             val bottomSideTap = positionY > recycler.height * 0.75f | ||||
|             val leftSideTap = positionX < recycler.width * 0.33f | ||||
|             val rightSideTap = positionX > recycler.width * 0.66f | ||||
|  | ||||
|             val invertMode = config.tappingInverted | ||||
|             val invertVertical = invertMode == TappingInvertMode.VERTICAL || invertMode == TappingInvertMode.BOTH | ||||
|             val invertHorizontal = invertMode == TappingInvertMode.HORIZONTAL || invertMode == TappingInvertMode.BOTH | ||||
|  | ||||
|             when { | ||||
|                 topSideTap && !invertVertical || bottomSideTap && invertVertical -> scrollUp() | ||||
|                 bottomSideTap && !invertVertical || topSideTap && invertVertical -> scrollDown() | ||||
|  | ||||
|                 leftSideTap && !invertHorizontal || rightSideTap && invertHorizontal -> scrollUp() | ||||
|                 rightSideTap && !invertHorizontal || leftSideTap && invertHorizontal -> scrollDown() | ||||
|  | ||||
|                 else -> activity.toggleMenu() | ||||
|             val pos = PointF(event.rawX / recycler.width, event.rawY / recycler.height) | ||||
|             if (!config.tappingEnabled) activity.toggleMenu() | ||||
|             else { | ||||
|                 val navigator = config.navigator | ||||
|                 when (navigator.getAction(pos)) { | ||||
|                     ViewerNavigation.NavigationRegion.MENU -> activity.toggleMenu() | ||||
|                     ViewerNavigation.NavigationRegion.NEXT -> scrollDown() | ||||
|                     ViewerNavigation.NavigationRegion.PREV -> scrollUp() | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         recycler.longTapListener = f@{ event -> | ||||
|   | ||||
| @@ -0,0 +1,15 @@ | ||||
| package eu.kanade.tachiyomi.util.lang | ||||
|  | ||||
| import android.graphics.RectF | ||||
| import eu.kanade.tachiyomi.data.preference.PreferenceValues | ||||
|  | ||||
| fun RectF.invert(invertMode: PreferenceValues.TappingInvertMode): RectF { | ||||
|     val horizontal = invertMode.shouldInvertHorizontal | ||||
|     val vertical = invertMode.shouldInvertVertical | ||||
|     return when { | ||||
|         horizontal && vertical -> RectF(1f - this.right, 1f - this.bottom, 1f - this.left, 1f - this.top) | ||||
|         vertical -> RectF(this.left, 1f - this.bottom, this.right, 1f - this.top) | ||||
|         horizontal -> RectF(1f - this.right, this.top, 1f - this.left, this.bottom) | ||||
|         else -> this | ||||
|     } | ||||
| } | ||||
| @@ -203,6 +203,25 @@ | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|         app:layout_constraintTop_toBottomOf="@id/end_navigation_preferences" /> | ||||
|  | ||||
|     <TextView | ||||
|         android:id="@+id/pager_nav_text" | ||||
|         android:layout_width="0dp" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:text="@string/pref_viewer_nav" | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|         app:layout_constraintEnd_toStartOf="@id/verticalcenter" | ||||
|         app:layout_constraintBaseline_toBaselineOf="@id/pager_nav"/> | ||||
|  | ||||
|     <androidx.appcompat.widget.AppCompatSpinner | ||||
|         android:id="@+id/pager_nav" | ||||
|         android:layout_width="0dp" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:entries="@array/pager_nav" | ||||
|         android:layout_marginTop="16dp" | ||||
|         app:layout_constraintTop_toBottomOf="@id/pager_prefs" | ||||
|         app:layout_constraintStart_toEndOf="@id/verticalcenter" | ||||
|         app:layout_constraintEnd_toEndOf="@id/spinner_end" /> | ||||
|  | ||||
|     <TextView | ||||
|         android:id="@+id/scale_type_text" | ||||
|         android:layout_width="0dp" | ||||
| @@ -220,7 +239,7 @@ | ||||
|         android:entries="@array/image_scale_type" | ||||
|         app:layout_constraintEnd_toEndOf="@id/spinner_end" | ||||
|         app:layout_constraintStart_toEndOf="@id/verticalcenter" | ||||
|         app:layout_constraintTop_toBottomOf="@id/pager_prefs" /> | ||||
|         app:layout_constraintTop_toBottomOf="@+id/pager_nav" /> | ||||
|  | ||||
|     <TextView | ||||
|         android:id="@+id/zoom_start_text" | ||||
| @@ -326,6 +345,26 @@ | ||||
|         app:layout_constraintRight_toRightOf="@id/spinner_end" | ||||
|         app:layout_constraintTop_toBottomOf="@id/webtoon_prefs" /> | ||||
|  | ||||
|     <TextView | ||||
|         android:id="@+id/webtoon_nav_text" | ||||
|         android:layout_width="0dp" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:text="@string/pref_viewer_nav" | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|         app:layout_constraintEnd_toStartOf="@id/verticalcenter" | ||||
|         app:layout_constraintBaseline_toBaselineOf="@id/webtoon_nav"/> | ||||
|  | ||||
|     <androidx.appcompat.widget.AppCompatSpinner | ||||
|         android:id="@+id/webtoon_nav" | ||||
|         android:layout_width="0dp" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginTop="20dp" | ||||
|         android:entries="@array/webtoon_nav" | ||||
|         app:layout_constraintEnd_toEndOf="@id/spinner_end" | ||||
|         app:layout_constraintHorizontal_bias="0.0" | ||||
|         app:layout_constraintStart_toEndOf="@id/verticalcenter" | ||||
|         app:layout_constraintTop_toBottomOf="@+id/webtoon_side_padding" /> | ||||
|  | ||||
|     <com.google.android.material.switchmaterial.SwitchMaterial | ||||
|         android:id="@+id/crop_borders_webtoon" | ||||
|         android:layout_width="match_parent" | ||||
| @@ -333,7 +372,7 @@ | ||||
|         android:layout_marginTop="10dp" | ||||
|         android:text="@string/pref_crop_borders" | ||||
|         android:textColor="?android:attr/textColorSecondary" | ||||
|         app:layout_constraintTop_toBottomOf="@id/webtoon_side_padding" /> | ||||
|         app:layout_constraintTop_toBottomOf="@+id/webtoon_nav" /> | ||||
|  | ||||
|     <!-- Groups of preferences --> | ||||
|  | ||||
| @@ -342,7 +381,7 @@ | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:visibility="gone" | ||||
|         app:constraint_referenced_ids="pager_prefs,scale_type_text,scale_type,zoom_start_text,zoom_start,crop_borders" | ||||
|         app:constraint_referenced_ids="pager_prefs,pager_nav_text,pager_nav,scale_type_text,scale_type,zoom_start_text,zoom_start,crop_borders" | ||||
|         tools:visibility="visible" /> | ||||
|  | ||||
|     <androidx.constraintlayout.widget.Group | ||||
| @@ -350,7 +389,7 @@ | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:visibility="gone" | ||||
|         app:constraint_referenced_ids="webtoon_prefs,crop_borders_webtoon,webtoon_side_padding_text,webtoon_side_padding" /> | ||||
|         app:constraint_referenced_ids="webtoon_prefs,webtoon_nav_text,webtoon_nav,crop_borders_webtoon,webtoon_side_padding_text,webtoon_side_padding" /> | ||||
|  | ||||
|     <androidx.constraintlayout.widget.Guideline | ||||
|         android:id="@+id/verticalcenter" | ||||
|   | ||||
| @@ -91,4 +91,18 @@ | ||||
|         <item>@string/manga_from_library</item> | ||||
|         <item>@string/downloaded_chapters</item> | ||||
|     </string-array> | ||||
|  | ||||
|     <string-array name="pager_nav"> | ||||
|         <item>@string/default_nav</item> | ||||
|         <item>@string/l_nav</item> | ||||
|         <item>@string/kindlish_nav</item> | ||||
|         <item>@string/edge_nav</item> | ||||
|     </string-array> | ||||
|  | ||||
|     <string-array name="webtoon_nav"> | ||||
|         <item>@string/default_nav</item> | ||||
|         <item>@string/l_nav</item> | ||||
|         <item>@string/kindlish_nav</item> | ||||
|         <item>@string/edge_nav</item> | ||||
|     </string-array> | ||||
| </resources> | ||||
|   | ||||
| @@ -277,12 +277,17 @@ | ||||
|     <string name="black_background">Black</string> | ||||
|     <string name="pref_viewer_type">Default reading mode</string> | ||||
|     <string name="default_viewer">Default</string> | ||||
|     <string name="default_nav">Default</string> | ||||
|     <string name="l_nav">L shaped</string> | ||||
|     <string name="kindlish_nav">Kindle-ish</string> | ||||
|     <string name="edge_nav">Edge</string> | ||||
|     <string name="left_to_right_viewer">Left to right</string> | ||||
|     <string name="right_to_left_viewer">Right to left</string> | ||||
|     <string name="vertical_viewer">Vertical</string> | ||||
|     <string name="webtoon_viewer">Webtoon</string> | ||||
|     <string name="vertical_plus_viewer">Continuous vertical</string> | ||||
|     <string name="pager_viewer">Paged</string> | ||||
|     <string name="pref_viewer_nav">Navigation layout</string> | ||||
|     <string name="pref_image_decoder">Image decoder</string> | ||||
|     <string name="pref_image_scale_type">Scale type</string> | ||||
|     <string name="scale_type_fit_screen">Fit screen</string> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user