mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-16 14:07:28 +01:00
Added dual page split setting (#4252)
* Add DualPageSplit option * remove extra line * Split double-page into two pages * Remove !isAnimated check and add (ALPHA) to the label * Fix missing insert pages * Pager cleanup * Add dual split to Webtoon and fix Vertical * Fix L2R/R2L * Add comments and refactor code in ImageUtil * Use a simpler split solution in webtoon mode Co-authored-by: weng <> Co-authored-by: Andreas E <andreas.everos@gmail.com>
This commit is contained in:
@@ -65,6 +65,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BaseBottomShee
|
||||
binding.backgroundColor.bindToIntPreference(preferences.readerTheme(), R.array.reader_themes_values)
|
||||
binding.showPageNumber.bindToPreference(preferences.showPageNumber())
|
||||
binding.fullscreen.bindToPreference(preferences.fullscreen())
|
||||
binding.dualPageSplit.bindToPreference(preferences.dualPageSplit())
|
||||
binding.keepscreen.bindToPreference(preferences.keepScreenOn())
|
||||
binding.longTap.bindToPreference(preferences.readWithLongTap())
|
||||
binding.alwaysShowChapterTransition.bindToPreference(preferences.alwaysShowChapterTransition())
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package eu.kanade.tachiyomi.ui.reader.model
|
||||
|
||||
class InsertPage(val parent: ReaderPage) : ReaderPage(parent.index, parent.url, parent.imageUrl) {
|
||||
|
||||
override var chapter: ReaderChapter = parent.chapter
|
||||
|
||||
init {
|
||||
stream = parent.stream
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@ package eu.kanade.tachiyomi.ui.reader.model
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import java.io.InputStream
|
||||
|
||||
class ReaderPage(
|
||||
open class ReaderPage(
|
||||
index: Int,
|
||||
url: String = "",
|
||||
imageUrl: String? = null,
|
||||
var stream: (() -> InputStream)? = null
|
||||
) : Page(index, url, imageUrl, null) {
|
||||
|
||||
lateinit var chapter: ReaderChapter
|
||||
open lateinit var chapter: ReaderChapter
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ abstract class ViewerConfig(preferences: PreferencesHelper, private val scope: C
|
||||
var volumeKeysInverted = false
|
||||
var trueColor = false
|
||||
var alwaysShowChapterTransition = true
|
||||
var dualPageSplit = false
|
||||
var navigationMode = 0
|
||||
protected set
|
||||
|
||||
@@ -54,6 +55,9 @@ abstract class ViewerConfig(preferences: PreferencesHelper, private val scope: C
|
||||
|
||||
preferences.alwaysShowChapterTransition()
|
||||
.register({ alwaysShowChapterTransition = it })
|
||||
|
||||
preferences.dualPageSplit()
|
||||
.register({ dualPageSplit = it }, { imagePropertyChangedListener?.invoke() })
|
||||
}
|
||||
|
||||
protected abstract fun defaultNavigation(): ViewerNavigation
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.github.chrisbanes.photoview.PhotoView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressBar
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.ZoomType
|
||||
@@ -241,6 +242,9 @@ class PagerPageHolder(
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext { isAnimated ->
|
||||
if (viewer.config.dualPageSplit) {
|
||||
openStream = processDualPageSplit(openStream!!)
|
||||
}
|
||||
if (!isAnimated) {
|
||||
initSubsamplingImageView().setImage(ImageSource.inputStream(openStream!!))
|
||||
} else {
|
||||
@@ -253,6 +257,38 @@ class PagerPageHolder(
|
||||
.subscribe({}, {})
|
||||
}
|
||||
|
||||
private fun processDualPageSplit(openStream: InputStream): InputStream {
|
||||
var inputStream = openStream
|
||||
val (isDoublePage, stream) = when (page) {
|
||||
is InsertPage -> Pair(true, inputStream)
|
||||
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()
|
||||
}
|
||||
|
||||
inputStream = ImageUtil.splitInHalf(inputStream, side)
|
||||
}
|
||||
return inputStream
|
||||
}
|
||||
|
||||
private fun onPageSplit() {
|
||||
val newPage = InsertPage(page)
|
||||
viewer.onPageSplit(page, newPage)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page has an error.
|
||||
*/
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.viewpager.widget.ViewPager
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
|
||||
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
||||
@@ -371,4 +372,8 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun onPageSplit(currentPage: ReaderPage, newPage: InsertPage) {
|
||||
adapter.onPageSplit(currentPage, newPage, this::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
|
||||
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||
@@ -18,7 +19,7 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
|
||||
/**
|
||||
* List of currently set items.
|
||||
*/
|
||||
var items: List<Any> = emptyList()
|
||||
var items: MutableList<Any> = mutableListOf()
|
||||
private set
|
||||
|
||||
var nextTransition: ChapterTransition.Next? = null
|
||||
@@ -80,6 +81,9 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
|
||||
}
|
||||
}
|
||||
|
||||
// Resets double-page splits, else insert pages get misplaced
|
||||
items.filterIsInstance<InsertPage>().also { items.removeAll(it) }
|
||||
|
||||
if (viewer is R2LPagerViewer) {
|
||||
newItems.reverse()
|
||||
}
|
||||
@@ -120,4 +124,31 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
|
||||
}
|
||||
return POSITION_NONE
|
||||
}
|
||||
|
||||
fun onPageSplit(current: Any?, newPage: InsertPage, clazz: Class<out PagerViewer>) {
|
||||
if (current !is ReaderPage) return
|
||||
|
||||
val currentIndex = items.indexOf(current)
|
||||
|
||||
val placeAtIndex = when {
|
||||
clazz.isAssignableFrom(L2RPagerViewer::class.java) -> currentIndex + 1
|
||||
clazz.isAssignableFrom(VerticalPagerViewer::class.java) -> currentIndex + 1
|
||||
clazz.isAssignableFrom(R2LPagerViewer::class.java) -> currentIndex
|
||||
else -> currentIndex
|
||||
}
|
||||
|
||||
// It will enter a endless cycle of insert pages
|
||||
if (clazz.isAssignableFrom(R2LPagerViewer::class.java) && items[placeAtIndex - 1] is InsertPage) {
|
||||
return
|
||||
}
|
||||
|
||||
// Same here it will enter a endless cycle of insert pages
|
||||
if (items[placeAtIndex] is InsertPage) {
|
||||
return
|
||||
}
|
||||
|
||||
items.add(placeAtIndex, newPage)
|
||||
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +287,14 @@ class WebtoonPageHolder(
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext { isAnimated ->
|
||||
if (viewer.config.dualPageSplit) {
|
||||
val (isDoublePage, stream) = ImageUtil.isDoublePage(openStream!!)
|
||||
openStream = if (!isDoublePage) {
|
||||
stream
|
||||
} else {
|
||||
ImageUtil.splitAndMerge(stream)
|
||||
}
|
||||
}
|
||||
if (!isAnimated) {
|
||||
val subsamplingView = initSubsamplingImageView()
|
||||
subsamplingView.isVisible = true
|
||||
|
||||
@@ -50,6 +50,11 @@ class SettingsReaderController : SettingsController() {
|
||||
summaryRes = R.string.pref_show_reading_mode_summary
|
||||
defaultValue = true
|
||||
}
|
||||
switchPreference {
|
||||
key = Keys.dualPageSplit
|
||||
titleRes = R.string.pref_dual_page_split
|
||||
defaultValue = false
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
switchPreference {
|
||||
key = Keys.trueColor
|
||||
|
||||
Reference in New Issue
Block a user