Sfoglia il codice sorgente

Let users invert dual page split (#4470)

* Let users invert dual page split

* Use Activity lifecycleScope and cleanup invert logic
Andreas 4 anni fa
parent
commit
776610d0e6

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt

@@ -25,6 +25,8 @@ object PreferenceKeys {
 
     const val dualPageSplit = "pref_dual_page_split"
 
+    const val dualPageInvert = "pref_dual_page_invert"
+
     const val showReadingMode = "pref_show_reading_mode"
 
     const val trueColor = "pref_true_color_key"

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt

@@ -91,6 +91,8 @@ class PreferencesHelper(val context: Context) {
 
     fun dualPageSplit() = flowPrefs.getBoolean(Keys.dualPageSplit, false)
 
+    fun dualPageInvert() = flowPrefs.getBoolean(Keys.dualPageInvert, false)
+
     fun showReadingMode() = prefs.getBoolean(Keys.showReadingMode, true)
 
     fun trueColor() = flowPrefs.getBoolean(Keys.trueColor, false)

+ 9 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt

@@ -6,14 +6,17 @@ import android.widget.Spinner
 import androidx.annotation.ArrayRes
 import androidx.core.view.isVisible
 import androidx.core.widget.NestedScrollView
+import androidx.lifecycle.lifecycleScope
 import com.tfcporciuncula.flow.Preference
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import eu.kanade.tachiyomi.data.preference.asImmediateFlow
 import eu.kanade.tachiyomi.databinding.ReaderSettingsSheetBinding
 import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer
 import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
 import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
 import eu.kanade.tachiyomi.widget.sheet.BaseBottomSheetDialog
+import kotlinx.coroutines.flow.launchIn
 import uy.kohesive.injekt.injectLazy
 
 /**
@@ -71,6 +74,12 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BaseBottomShee
         binding.alwaysShowChapterTransition.bindToPreference(preferences.alwaysShowChapterTransition())
         binding.pageTransitions.bindToPreference(preferences.pageTransitions())
 
+        // Makes so that dual page invert gets hidden away when turning of dual page split
+        preferences.dualPageSplit()
+            .asImmediateFlow { binding.dualPageInvert.isVisible = it }
+            .launchIn(activity.lifecycleScope)
+        binding.dualPageInvert.bindToPreference(preferences.dualPageInvert())
+
         // If the preference is explicitly disabled, that means the setting was configured since there is a cutout
         if (activity.hasCutout || !preferences.cutoutShort().get()) {
             binding.cutoutShort.isVisible = true

+ 4 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt

@@ -25,6 +25,7 @@ abstract class ViewerConfig(preferences: PreferencesHelper, private val scope: C
     var trueColor = false
     var alwaysShowChapterTransition = true
     var dualPageSplit = false
+    var dualPageInvert = false
     var navigationMode = 0
         protected set
 
@@ -58,6 +59,9 @@ abstract class ViewerConfig(preferences: PreferencesHelper, private val scope: C
 
         preferences.dualPageSplit()
             .register({ dualPageSplit = it }, { imagePropertyChangedListener?.invoke() })
+
+        preferences.dualPageInvert()
+            .register({ dualPageInvert = it }, { imagePropertyChangedListener?.invoke() })
     }
 
     protected abstract fun defaultNavigation(): ViewerNavigation

+ 19 - 14
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt

@@ -264,24 +264,29 @@ class PagerPageHolder(
             else -> ImageUtil.isDoublePage(inputStream)
         }
         inputStream = stream
-        if (isDoublePage) {
-            val side = when {
-                viewer is L2RPagerViewer && page is InsertPage -> ImageUtil.Side.RIGHT
-                viewer is R2LPagerViewer && page is InsertPage -> ImageUtil.Side.LEFT
-                viewer is L2RPagerViewer && page !is InsertPage -> ImageUtil.Side.LEFT
-                viewer is R2LPagerViewer && page !is InsertPage -> ImageUtil.Side.RIGHT
-                viewer is VerticalPagerViewer && page !is InsertPage -> ImageUtil.Side.RIGHT
-                viewer is VerticalPagerViewer && page is InsertPage -> ImageUtil.Side.LEFT
-                else -> error("We should choose a side!")
-            }
 
-            if (page !is InsertPage) {
-                onPageSplit()
+        if (!isDoublePage) return inputStream
+
+        var side = when {
+            viewer is L2RPagerViewer && page is InsertPage -> ImageUtil.Side.RIGHT
+            (viewer is R2LPagerViewer || viewer is VerticalPagerViewer) && page is InsertPage -> ImageUtil.Side.LEFT
+            viewer is L2RPagerViewer && page !is InsertPage -> ImageUtil.Side.LEFT
+            (viewer is R2LPagerViewer || viewer is VerticalPagerViewer) && page !is InsertPage -> ImageUtil.Side.RIGHT
+            else -> error("We should choose a side!")
+        }
+
+        if (viewer.config.dualPageInvert) {
+            side = when (side) {
+                ImageUtil.Side.RIGHT -> ImageUtil.Side.LEFT
+                ImageUtil.Side.LEFT -> ImageUtil.Side.RIGHT
             }
+        }
 
-            inputStream = ImageUtil.splitInHalf(inputStream, side)
+        if (page !is InsertPage) {
+            onPageSplit()
         }
-        return inputStream
+
+        return ImageUtil.splitInHalf(inputStream, side)
     }
 
     private fun onPageSplit() {

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt

@@ -292,7 +292,8 @@ class WebtoonPageHolder(
                     openStream = if (!isDoublePage) {
                         stream
                     } else {
-                        ImageUtil.splitAndMerge(stream)
+                        val upperSide = if (viewer.config.dualPageInvert) ImageUtil.Side.LEFT else ImageUtil.Side.RIGHT
+                        ImageUtil.splitAndMerge(stream, upperSide)
                     }
                 }
                 if (!isAnimated) {

+ 7 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt

@@ -55,6 +55,13 @@ class SettingsReaderController : SettingsController() {
             titleRes = R.string.pref_dual_page_split
             defaultValue = false
         }
+        switchPreference {
+            key = Keys.dualPageInvert
+            titleRes = R.string.pref_dual_page_invert
+            summaryRes = R.string.pref_dual_page_invert_summary
+            defaultValue = false
+            preferences.dualPageSplit().asImmediateFlow { isVisible = it }.launchIn(viewScope)
+        }
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             switchPreference {
                 key = Keys.trueColor

+ 9 - 3
app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt

@@ -115,7 +115,7 @@ object ImageUtil {
     /**
      * Split the image into left and right parts, then merge them into a new image.
      */
-    fun splitAndMerge(imageStream: InputStream): InputStream {
+    fun splitAndMerge(imageStream: InputStream, upperSide: Side): InputStream {
         val imageBytes = imageStream.readBytes()
 
         val imageBitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
@@ -125,11 +125,17 @@ object ImageUtil {
         val result = Bitmap.createBitmap(width / 2, height * 2, Bitmap.Config.ARGB_8888)
         val canvas = Canvas(result)
         // right -> upper
-        val rightPart = Rect(width - width / 2, 0, width, height)
+        val rightPart = when (upperSide) {
+            Side.RIGHT -> Rect(width - width / 2, 0, width, height)
+            Side.LEFT -> Rect(0, 0, width / 2, height)
+        }
         val upperPart = Rect(0, 0, width / 2, height)
         canvas.drawBitmap(imageBitmap, rightPart, upperPart, null)
         // left -> bottom
-        val leftPart = Rect(0, 0, width / 2, height)
+        val leftPart = when (upperSide) {
+            Side.LEFT -> Rect(width - width / 2, 0, width, height)
+            Side.RIGHT -> Rect(0, 0, width / 2, height)
+        }
         val bottomPart = Rect(0, height, width / 2, height * 2)
         canvas.drawBitmap(imageBitmap, leftPart, bottomPart, null)
 

+ 11 - 1
app/src/main/res/layout/reader_settings_sheet.xml

@@ -159,6 +159,16 @@
         android:textColor="?android:attr/textColorSecondary"
         app:layout_constraintTop_toBottomOf="@id/fullscreen" />
 
+    <com.google.android.material.switchmaterial.SwitchMaterial
+        android:id="@+id/dual_page_invert"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/pref_dual_page_invert"
+        android:textColor="?android:attr/textColorSecondary"
+        android:visibility="gone"
+        app:layout_constraintTop_toBottomOf="@id/dual_page_split"
+        tools:visibility="visible" />
+
     <com.google.android.material.switchmaterial.SwitchMaterial
         android:id="@+id/cutout_short"
         android:layout_width="match_parent"
@@ -166,7 +176,7 @@
         android:text="@string/pref_cutout_short"
         android:textColor="?android:attr/textColorSecondary"
         android:visibility="gone"
-        app:layout_constraintTop_toBottomOf="@id/dual_page_split"
+        app:layout_constraintTop_toBottomOf="@id/dual_page_invert"
         tools:visibility="visible" />
 
     <com.google.android.material.switchmaterial.SwitchMaterial

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -251,6 +251,8 @@
       <!-- Reader section -->
     <string name="pref_fullscreen">Fullscreen</string>
     <string name="pref_dual_page_split">Dual page split (ALPHA)</string>
+    <string name="pref_dual_page_invert">Invert dual page split placement</string>
+    <string name="pref_dual_page_invert_summary">If the placement of the dual page split doesn\'t match reading direction</string>
     <string name="pref_cutout_short">Show content in cutout area</string>
     <string name="pref_lock_orientation">Lock orientation</string>
     <string name="pref_page_transitions">Animate page transitions</string>