mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-07 20:31:02 -05:00
Add support for margins in Webtoon view
On larger tablets, matching the page width to the screen width in webtoon mode causes eye strain due to the image looking so magnified. Adding a page margin to the image can resolve this by effectively scaling the image down.
This commit is contained in:
parent
80ea9001b3
commit
5b9f362925
12 changed files with 110 additions and 2 deletions
|
@ -51,6 +51,8 @@ object PreferenceKeys {
|
||||||
|
|
||||||
const val readWithVolumeKeysInverted = "reader_volume_keys_inverted"
|
const val readWithVolumeKeysInverted = "reader_volume_keys_inverted"
|
||||||
|
|
||||||
|
const val webtoonMarginRatio = "margin_ratio"
|
||||||
|
|
||||||
const val portraitColumns = "pref_library_columns_portrait_key"
|
const val portraitColumns = "pref_library_columns_portrait_key"
|
||||||
|
|
||||||
const val landscapeColumns = "pref_library_columns_landscape_key"
|
const val landscapeColumns = "pref_library_columns_landscape_key"
|
||||||
|
|
|
@ -79,6 +79,8 @@ class PreferencesHelper(val context: Context) {
|
||||||
|
|
||||||
fun readWithVolumeKeysInverted() = rxPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
|
fun readWithVolumeKeysInverted() = rxPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
|
||||||
|
|
||||||
|
fun marginRatio() = rxPrefs.getInteger(Keys.webtoonMarginRatio, 0)
|
||||||
|
|
||||||
fun portraitColumns() = rxPrefs.getInteger(Keys.portraitColumns, 0)
|
fun portraitColumns() = rxPrefs.getInteger(Keys.portraitColumns, 0)
|
||||||
|
|
||||||
fun landscapeColumns() = rxPrefs.getInteger(Keys.landscapeColumns, 0)
|
fun landscapeColumns() = rxPrefs.getInteger(Keys.landscapeColumns, 0)
|
||||||
|
|
|
@ -82,6 +82,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia
|
||||||
private fun initWebtoonPreferences() {
|
private fun initWebtoonPreferences() {
|
||||||
webtoon_prefs_group.visible()
|
webtoon_prefs_group.visible()
|
||||||
crop_borders_webtoon.bindToPreference(preferences.cropBordersWebtoon())
|
crop_borders_webtoon.bindToPreference(preferences.cropBordersWebtoon())
|
||||||
|
margin_ratio_webtoon.bindToPreference(preferences.marginRatio())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,6 +34,9 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) {
|
||||||
var doubleTapAnimDuration = 500
|
var doubleTapAnimDuration = 500
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var marginRatio = 0f
|
||||||
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
preferences.readWithTapping()
|
preferences.readWithTapping()
|
||||||
.register({ tappingEnabled = it })
|
.register({ tappingEnabled = it })
|
||||||
|
@ -52,6 +55,23 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) {
|
||||||
|
|
||||||
preferences.readWithVolumeKeysInverted()
|
preferences.readWithVolumeKeysInverted()
|
||||||
.register({ volumeKeysInverted = it })
|
.register({ volumeKeysInverted = it })
|
||||||
|
|
||||||
|
preferences.marginRatio()
|
||||||
|
.register({ marginFromPreference(it) }, { imagePropertyChangedListener?.invoke() })
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun marginFromPreference(position: Int) {
|
||||||
|
marginRatio = when (position) {
|
||||||
|
1 -> PageMargin.TEN_PERCENT
|
||||||
|
2 -> PageMargin.TWENTY_FIVE_PERCENT
|
||||||
|
else -> PageMargin.NO_MARGIN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object PageMargin {
|
||||||
|
const val NO_MARGIN = 0f
|
||||||
|
const val TEN_PERCENT = 0.1f
|
||||||
|
const val TWENTY_FIVE_PERCENT = 0.25f
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unsubscribe() {
|
fun unsubscribe() {
|
||||||
|
|
|
@ -2,11 +2,13 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.support.v7.widget.AppCompatButton
|
import android.support.v7.widget.AppCompatButton
|
||||||
import android.support.v7.widget.AppCompatImageView
|
import android.support.v7.widget.AppCompatImageView
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
|
@ -111,7 +113,7 @@ class WebtoonPageHolder(
|
||||||
private var readImageHeaderSubscription: Subscription? = null
|
private var readImageHeaderSubscription: Subscription? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
frame.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
|
refreshLayoutParams()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,6 +122,15 @@ class WebtoonPageHolder(
|
||||||
fun bind(page: ReaderPage) {
|
fun bind(page: ReaderPage) {
|
||||||
this.page = page
|
this.page = page
|
||||||
observeStatus()
|
observeStatus()
|
||||||
|
refreshLayoutParams()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshLayoutParams() {
|
||||||
|
frame.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
|
||||||
|
val margin = Resources.getSystem().displayMetrics.widthPixels * viewer.config.marginRatio
|
||||||
|
marginEnd = margin.toInt()
|
||||||
|
marginStart = margin.toInt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -110,6 +110,8 @@ class WebtoonViewer(val activity: ReaderActivity) : BaseViewer {
|
||||||
|
|
||||||
frame.layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
frame.layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||||
frame.addView(recycler)
|
frame.addView(recycler)
|
||||||
|
|
||||||
|
config.imagePropertyChangedListener = { adapter.notifyDataSetChanged() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.setting
|
||||||
import android.support.graphics.drawable.VectorDrawableCompat
|
import android.support.graphics.drawable.VectorDrawableCompat
|
||||||
import android.support.v4.graphics.drawable.DrawableCompat
|
import android.support.v4.graphics.drawable.DrawableCompat
|
||||||
import android.support.v7.preference.*
|
import android.support.v7.preference.*
|
||||||
|
import eu.kanade.tachiyomi.widget.preference.FloatListPreference
|
||||||
import eu.kanade.tachiyomi.widget.preference.IntListPreference
|
import eu.kanade.tachiyomi.widget.preference.IntListPreference
|
||||||
|
|
||||||
@DslMarker
|
@DslMarker
|
||||||
|
@ -37,6 +38,10 @@ inline fun PreferenceGroup.intListPreference(block: (@DSL IntListPreference).()
|
||||||
return initThenAdd(IntListPreference(context), block).also(::initDialog)
|
return initThenAdd(IntListPreference(context), block).also(::initDialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun PreferenceGroup.floatListPreference(block: (@DSL FloatListPreference).() -> Unit): FloatListPreference {
|
||||||
|
return initThenAdd(FloatListPreference(context), block).also(::initDialog)
|
||||||
|
}
|
||||||
|
|
||||||
inline fun PreferenceGroup.multiSelectListPreference(block: (@DSL MultiSelectListPreference).() -> Unit): MultiSelectListPreference {
|
inline fun PreferenceGroup.multiSelectListPreference(block: (@DSL MultiSelectListPreference).() -> Unit): MultiSelectListPreference {
|
||||||
return initThenAdd(MultiSelectListPreference(context), block).also(::initDialog)
|
return initThenAdd(MultiSelectListPreference(context), block).also(::initDialog)
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,16 @@ class SettingsReaderController : SettingsController() {
|
||||||
titleRes = R.string.pref_crop_borders
|
titleRes = R.string.pref_crop_borders
|
||||||
defaultValue = false
|
defaultValue = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
floatListPreference {
|
||||||
|
key = Keys.webtoonMarginRatio
|
||||||
|
titleRes = R.string.pref_reader_theme
|
||||||
|
entriesRes = arrayOf(R.string.webtoon_margin_ratio_0,
|
||||||
|
R.string.webtoon_margin_ratio_10, R.string.webtoon_margin_ratio_25)
|
||||||
|
entryValues = arrayOf("0", "1", "2")
|
||||||
|
defaultValue = "0"
|
||||||
|
summary = "%s"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
preferenceCategory {
|
preferenceCategory {
|
||||||
titleRes = R.string.pref_reader_navigation
|
titleRes = R.string.pref_reader_navigation
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package eu.kanade.tachiyomi.widget.preference
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.support.v7.preference.ListPreference
|
||||||
|
import android.util.AttributeSet
|
||||||
|
|
||||||
|
class FloatListPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
|
ListPreference(context, attrs) {
|
||||||
|
|
||||||
|
override fun persistString(value: String?): Boolean {
|
||||||
|
return value != null && persistFloat(value.toFloat())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPersistedString(defaultReturnValue: String?): String? {
|
||||||
|
// When the underlying preference is using a PreferenceDataStore, there's no way (for now)
|
||||||
|
// to check if a value is in the store, so we use a most likely unused value as workaround
|
||||||
|
val defaultIntValue = Float.NEGATIVE_INFINITY
|
||||||
|
|
||||||
|
val value = getPersistedFloat(defaultIntValue)
|
||||||
|
return if (value != defaultIntValue) {
|
||||||
|
value.toString()
|
||||||
|
} else {
|
||||||
|
defaultReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -240,6 +240,25 @@
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
app:layout_constraintTop_toBottomOf="@id/webtoon_prefs" />
|
app:layout_constraintTop_toBottomOf="@id/webtoon_prefs" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/margin_ratio_text"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/pref_reader_margin"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toLeftOf="@id/verticalcenter"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@id/margin_ratio_webtoon"/>
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatSpinner
|
||||||
|
android:id="@+id/margin_ratio_webtoon"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:entries="@array/margin_ratio"
|
||||||
|
app:layout_constraintLeft_toRightOf="@id/verticalcenter"
|
||||||
|
app:layout_constraintRight_toRightOf="@id/spinner_end"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/crop_borders_webtoon"/>
|
||||||
|
|
||||||
<!-- Groups of preferences -->
|
<!-- Groups of preferences -->
|
||||||
|
|
||||||
<android.support.constraint.Group
|
<android.support.constraint.Group
|
||||||
|
@ -255,7 +274,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:constraint_referenced_ids="webtoon_prefs,crop_borders_webtoon" />
|
app:constraint_referenced_ids="webtoon_prefs,crop_borders_webtoon,margin_ratio_text,margin_ratio_webtoon" />
|
||||||
|
|
||||||
<android.support.constraint.Guideline
|
<android.support.constraint.Guideline
|
||||||
android:id="@+id/verticalcenter"
|
android:id="@+id/verticalcenter"
|
||||||
|
|
|
@ -53,6 +53,12 @@
|
||||||
<item>@string/scale_type_smart_fit</item>
|
<item>@string/scale_type_smart_fit</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="margin_ratio">
|
||||||
|
<item>@string/webtoon_margin_ratio_0</item>
|
||||||
|
<item>@string/webtoon_margin_ratio_10</item>
|
||||||
|
<item>@string/webtoon_margin_ratio_25</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="image_scale_type_values">
|
<string-array name="image_scale_type_values">
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
|
|
|
@ -196,6 +196,7 @@
|
||||||
<string name="pref_read_with_tapping">Tapping</string>
|
<string name="pref_read_with_tapping">Tapping</string>
|
||||||
<string name="pref_read_with_long_tap">Long tap dialog</string>
|
<string name="pref_read_with_long_tap">Long tap dialog</string>
|
||||||
<string name="pref_reader_theme">Background color</string>
|
<string name="pref_reader_theme">Background color</string>
|
||||||
|
<string name="pref_reader_margin">Margin ratio</string>
|
||||||
<string name="white_background">White</string>
|
<string name="white_background">White</string>
|
||||||
<string name="black_background">Black</string>
|
<string name="black_background">Black</string>
|
||||||
<string name="pref_viewer_type">Default viewer</string>
|
<string name="pref_viewer_type">Default viewer</string>
|
||||||
|
@ -230,6 +231,9 @@
|
||||||
<string name="color_filter_g_value">G</string>
|
<string name="color_filter_g_value">G</string>
|
||||||
<string name="color_filter_b_value">B</string>
|
<string name="color_filter_b_value">B</string>
|
||||||
<string name="color_filter_a_value">A</string>
|
<string name="color_filter_a_value">A</string>
|
||||||
|
<string name="webtoon_margin_ratio_0">No margin</string>
|
||||||
|
<string name="webtoon_margin_ratio_10">10%</string>
|
||||||
|
<string name="webtoon_margin_ratio_25">25%</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- Downloads section -->
|
<!-- Downloads section -->
|
||||||
|
|
Loading…
Reference in a new issue