mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Let users invert dual page split (#4470)
* Let users invert dual page split * Use Activity lifecycleScope and cleanup invert logic
This commit is contained in:
		| @@ -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" | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|             inputStream = ImageUtil.splitInHalf(inputStream, side) | ||||
|         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!") | ||||
|         } | ||||
|         return inputStream | ||||
|  | ||||
|         if (viewer.config.dualPageInvert) { | ||||
|             side = when (side) { | ||||
|                 ImageUtil.Side.RIGHT -> ImageUtil.Side.LEFT | ||||
|                 ImageUtil.Side.LEFT -> ImageUtil.Side.RIGHT | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (page !is InsertPage) { | ||||
|             onPageSplit() | ||||
|         } | ||||
|  | ||||
|         return ImageUtil.splitInHalf(inputStream, side) | ||||
|     } | ||||
|  | ||||
|     private fun onPageSplit() { | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user