Option to show page content past cutout in landscape

Closes #517

Before anyone gets ideas, the next person to ask for a feature every single day, I'm becoming a mod on the discord just to ban that person
This commit is contained in:
Jays2Kings 2023-08-02 20:39:04 -04:00
parent 19db2ebee5
commit 60fcbcc2a3
7 changed files with 93 additions and 6 deletions

View file

@ -114,6 +114,8 @@ class PreferencesHelper(val context: Context) {
fun pagerCutoutBehavior() = flowPrefs.getInt(Keys.pagerCutoutBehavior, 0)
fun landscapeCutoutBehavior() = flowPrefs.getInt("landscape_cutout_behavior", 0)
fun doubleTapAnimSpeed() = flowPrefs.getInt(Keys.doubleTapAnimationSpeed, 500)
fun showPageNumber() = flowPrefs.getBoolean(Keys.showPageNumber, true)

View file

@ -55,6 +55,7 @@ import androidx.core.view.children
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.core.view.updatePaddingRelative
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@ -295,7 +296,7 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
val a = obtainStyledAttributes(intArrayOf(android.R.attr.windowLightStatusBar))
val lightStatusBar = a.getBoolean(0, false)
a.recycle()
setNotchCutoutMode()
setCutoutMode()
wic.isAppearanceLightStatusBars = lightStatusBar
wic.isAppearanceLightNavigationBars = lightStatusBar
@ -924,6 +925,9 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
binding.readerLayout.doOnApplyWindowInsetsCompat { _, insets, _ ->
setNavColor(insets)
val systemInsets = insets.ignoredSystemInsets
val currentOrientation = resources.configuration.orientation
val isLandscapeFully = currentOrientation == Configuration.ORIENTATION_LANDSCAPE && preferences.landscapeCutoutBehavior().get() == 1
val cutOutInsets = if (isLandscapeFully) insets.displayCutout else null
val vis = insets.isVisible(statusBars())
val fullscreen = preferences.fullscreen().get() && !isSplitScreen
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@ -949,9 +953,21 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
rightMargin = systemInsets.right
height = 280.dpToPx + systemInsets.bottom
}
binding.toolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = cutOutInsets?.safeInsetLeft ?: 0
rightMargin = cutOutInsets?.safeInsetRight ?: 0
}
binding.chaptersSheet.topbarLayout.updatePadding(
left = cutOutInsets?.safeInsetLeft ?: 0,
right = cutOutInsets?.safeInsetRight ?: 0,
)
binding.chaptersSheet.chapterRecycler.updatePadding(
left = cutOutInsets?.safeInsetLeft ?: 0,
right = cutOutInsets?.safeInsetRight ?: 0,
)
binding.navLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = 12.dpToPx + systemInsets.left
rightMargin = 12.dpToPx + systemInsets.right
leftMargin = 12.dpToPx + max(systemInsets.left, cutOutInsets?.safeInsetLeft ?: 0)
rightMargin = 12.dpToPx + max(systemInsets.right, cutOutInsets?.safeInsetRight ?: 0)
}
binding.chaptersSheet.root.sheetBehavior?.peekHeight =
peek + if (fullscreen) {
@ -1779,14 +1795,18 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
/**
* Sets notch cutout mode to "NEVER", if mobile is in a landscape view
*/
private fun setNotchCutoutMode() {
private fun setCutoutMode() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val currentOrientation = resources.configuration.orientation
val params = window.attributes
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
params.layoutInDisplayCutoutMode =
if (preferences.landscapeCutoutBehavior().get() == 0) {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
} else {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}
} else {
params.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
@ -1867,6 +1887,11 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
preferences.showPageNumber().asImmediateFlowIn(scope) { setPageNumberVisibility(it) }
preferences.landscapeCutoutBehavior().asFlow()
.drop(1)
.onEach { setCutoutMode() }
.launchIn(scope)
preferences.trueColor().asImmediateFlowIn(scope) { setTrueColor(it) }
preferences.fullscreen().asImmediateFlowIn(scope) { setFullscreen(it) }

View file

@ -2,7 +2,12 @@ package eu.kanade.tachiyomi.ui.reader.settings
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.hardware.display.DisplayManager
import android.os.Build
import android.util.AttributeSet
import android.view.Display
import androidx.core.content.getSystemService
import androidx.core.view.isVisible
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import eu.kanade.tachiyomi.R
@ -15,6 +20,7 @@ import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView<ReaderPagedLayoutBinding>(context, attrs) {
var needsActivityRecreate = false
override fun inflateBinding() = ReaderPagedLayoutBinding.bind(this)
override fun initGeneralPreferences() {
with(binding) {
@ -32,6 +38,9 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
pagerNav.bindToPreference(preferences.navigationModePager())
pagerInvert.bindToPreference(preferences.pagerNavInverted())
extendPastCutout.bindToPreference(preferences.pagerCutoutBehavior())
extendPastCutoutLandscape.bindToPreference(preferences.landscapeCutoutBehavior()) {
needsActivityRecreate = true
}
pageLayout.bindToPreference(preferences.pageLayout()) {
val mangaViewer = (context as? ReaderActivity)?.viewModel?.getMangaReadingMode() ?: 0
val isWebtoonView = ReadingModeType.isWebtoonType(mangaViewer)
@ -97,13 +106,28 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
else -> false
}
val ogView = (context as? Activity)?.window?.decorView
val hasCutout = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
val hasCutout = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ogView?.rootWindowInsets?.displayCutout?.safeInsetTop != null || ogView?.rootWindowInsets?.displayCutout?.safeInsetBottom != null
} else {
false
}
val hasAnyCutout = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
context.getSystemService<DisplayManager>()
?.getDisplay(Display.DEFAULT_DISPLAY)?.cutout != null
} else {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
}
binding.landscapeZoom.isVisible = show && preferences.imageScaleType().get() == SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
binding.extendPastCutout.isVisible = show && isFullFit && hasCutout && preferences.fullscreen().get()
binding.extendPastCutoutLandscape.isVisible = hasAnyCutout && preferences.fullscreen().get() &&
ogView?.resources?.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE
if (binding.extendPastCutoutLandscape.isVisible) {
binding.filterLinearLayout.removeView(binding.extendPastCutoutLandscape)
binding.filterLinearLayout.addView(
binding.extendPastCutoutLandscape,
binding.filterLinearLayout.indexOfChild(if (show) binding.extendPastCutout else binding.webtoonPageLayout) + 1,
)
}
binding.invertDoublePages.isVisible = show && preferences.pageLayout().get() != PageLayout.SINGLE_PAGE.value
}
}

View file

@ -149,6 +149,9 @@ class TabbedReaderSettingsSheet(
override fun dismiss() {
super.dismiss()
readerActivity.binding.appBar.isVisible = true
if (pagedView.needsActivityRecreate) {
readerActivity.recreate()
}
}
fun updateTabs(isWebtoon: Boolean) {

View file

@ -1,6 +1,9 @@
package eu.kanade.tachiyomi.ui.setting
import android.hardware.display.DisplayManager
import android.os.Build
import android.view.Display
import androidx.core.content.getSystemService
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferenceValues
@ -121,6 +124,22 @@ class SettingsReaderController : SettingsController() {
titleRes = R.string.show_page_number
defaultValue = true
}
intListPreference(activity) {
bindTo(preferences.landscapeCutoutBehavior())
title = "${context.getString(R.string.cutout_area_behavior)} (${context.getString(R.string.landscape)})"
entriesRes = arrayOf(
R.string.pad_cutout_areas,
R.string.ignore_cutout_areas,
)
entryRange = 0..1
defaultValue = 0
isVisible = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
activity?.getSystemService<DisplayManager>()
?.getDisplay(Display.DEFAULT_DISPLAY)?.cutout != null
} else {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
}
}
}
preferenceCategory {

View file

@ -9,6 +9,7 @@
android:clipToPadding="false">
<LinearLayout
android:id="@+id/filter_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/material_component_dialogs_padding_around_content_area"
@ -72,6 +73,14 @@
app:title="@string/cutout_area_behavior"
android:entries="@array/cutout_behavior" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/extend_past_cutout_landscape"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:title="@string/cutout_area_behavior"
android:entries="@array/cutout_behavior_landscape" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/zoom_start"
android:layout_width="match_parent"

View file

@ -140,6 +140,11 @@
<item>@string/ignore_cutout_areas</item>
</string-array>
<string-array name="cutout_behavior_landscape">
<item>@string/pad_cutout_areas</item>
<item>@string/ignore_cutout_areas</item>
</string-array>
<string-array name="clean_up_downloads">
<item>@string/clean_orphaned_downloads</item>
<item>@string/clean_read_downloads</item>