Option to disable webtoon zooming
This concludes the ducc updates
This commit is contained in:
parent
8b09548099
commit
b3fbe31c8d
9 changed files with 52 additions and 10 deletions
|
@ -53,6 +53,8 @@ object PreferenceKeys {
|
||||||
|
|
||||||
const val webtoonSidePadding = "webtoon_side_padding"
|
const val webtoonSidePadding = "webtoon_side_padding"
|
||||||
|
|
||||||
|
const val webtoonDisableZoom = "webtoon_disable_zoom"
|
||||||
|
|
||||||
const val updateOnlyNonCompleted = "pref_update_only_non_completed_key"
|
const val updateOnlyNonCompleted = "pref_update_only_non_completed_key"
|
||||||
|
|
||||||
const val autoUpdateTrack = "pref_auto_update_manga_sync_key"
|
const val autoUpdateTrack = "pref_auto_update_manga_sync_key"
|
||||||
|
|
|
@ -99,6 +99,8 @@ class PreferencesHelper(val context: Context) {
|
||||||
|
|
||||||
fun webtoonSidePadding() = flowPrefs.getInt(Keys.webtoonSidePadding, 0)
|
fun webtoonSidePadding() = flowPrefs.getInt(Keys.webtoonSidePadding, 0)
|
||||||
|
|
||||||
|
fun webtoonDisableZoom() = flowPrefs.getBoolean(Keys.webtoonDisableZoom, false)
|
||||||
|
|
||||||
fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true)
|
fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true)
|
||||||
|
|
||||||
fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true)
|
fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true)
|
||||||
|
|
|
@ -150,6 +150,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) :
|
||||||
pager_prefs_group.gone()
|
pager_prefs_group.gone()
|
||||||
crop_borders_webtoon.bindToPreference(preferences.cropBordersWebtoon())
|
crop_borders_webtoon.bindToPreference(preferences.cropBordersWebtoon())
|
||||||
webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
|
webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
|
||||||
|
webtoon_disable_zoom.bindToPreference(preferences.webtoonDisableZoom())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,11 +16,18 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) : ViewerConfi
|
||||||
var sidePadding = 0
|
var sidePadding = 0
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var disableZoom = false
|
||||||
|
private set
|
||||||
|
var zoomPropertyChangedListener: ((Boolean) -> Unit)? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
preferences.cropBordersWebtoon()
|
preferences.cropBordersWebtoon()
|
||||||
.register({ imageCropBorders = it }, { imagePropertyChangedListener?.invoke() })
|
.register({ imageCropBorders = it }, { imagePropertyChangedListener?.invoke() })
|
||||||
|
|
||||||
preferences.webtoonSidePadding()
|
preferences.webtoonSidePadding()
|
||||||
.register({ sidePadding = it }, { imagePropertyChangedListener?.invoke() })
|
.register({ sidePadding = it }, { imagePropertyChangedListener?.invoke() })
|
||||||
|
|
||||||
|
preferences.webtoonDisableZoom()
|
||||||
|
.register({ disableZoom = it }, { zoomPropertyChangedListener?.invoke(it) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,12 @@ class WebtoonFrame(context: Context) : FrameLayout(context) {
|
||||||
*/
|
*/
|
||||||
private val flingDetector = GestureDetector(context, FlingListener())
|
private val flingDetector = GestureDetector(context, FlingListener())
|
||||||
|
|
||||||
|
var disableZoom = true
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
recycler?.canZoom = !value
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recycler view added in this frame.
|
* Recycler view added in this frame.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -32,6 +32,13 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
private var firstVisibleItemPosition = 0
|
private var firstVisibleItemPosition = 0
|
||||||
private var lastVisibleItemPosition = 0
|
private var lastVisibleItemPosition = 0
|
||||||
private var currentScale = DEFAULT_RATE
|
private var currentScale = DEFAULT_RATE
|
||||||
|
var canZoom = false
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
if (!value) {
|
||||||
|
zoom(currentScale, DEFAULT_RATE, x, 0f, y, 0f, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val listener = GestureListener()
|
private val listener = GestureListener()
|
||||||
private val detector = Detector()
|
private val detector = Detector()
|
||||||
|
@ -93,8 +100,10 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
fromX: Float,
|
fromX: Float,
|
||||||
toX: Float,
|
toX: Float,
|
||||||
fromY: Float,
|
fromY: Float,
|
||||||
toY: Float
|
toY: Float,
|
||||||
|
force: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
if (!canZoom && !force) return
|
||||||
isZooming = true
|
isZooming = true
|
||||||
val animatorSet = AnimatorSet()
|
val animatorSet = AnimatorSet()
|
||||||
val translationXAnimator = ValueAnimator.ofFloat(fromX, toX)
|
val translationXAnimator = ValueAnimator.ofFloat(fromX, toX)
|
||||||
|
@ -129,6 +138,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun zoomFling(velocityX: Int, velocityY: Int): Boolean {
|
fun zoomFling(velocityX: Int, velocityY: Int): Boolean {
|
||||||
|
if (!canZoom) return false
|
||||||
if (currentScale <= 1f) return false
|
if (currentScale <= 1f) return false
|
||||||
|
|
||||||
val distanceTimeFactor = 0.4f
|
val distanceTimeFactor = 0.4f
|
||||||
|
@ -157,6 +167,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun zoomScrollBy(dx: Int, dy: Int) {
|
private fun zoomScrollBy(dx: Int, dy: Int) {
|
||||||
|
if (!canZoom) return
|
||||||
if (dx != 0) {
|
if (dx != 0) {
|
||||||
x = getPositionX(x + dx)
|
x = getPositionX(x + dx)
|
||||||
}
|
}
|
||||||
|
@ -171,6 +182,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onScale(scaleFactor: Float) {
|
fun onScale(scaleFactor: Float) {
|
||||||
|
if (!canZoom) return
|
||||||
currentScale *= scaleFactor
|
currentScale *= scaleFactor
|
||||||
currentScale = currentScale.coerceIn(
|
currentScale = currentScale.coerceIn(
|
||||||
MIN_RATE,
|
MIN_RATE,
|
||||||
|
@ -193,13 +205,13 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onScaleBegin() {
|
fun onScaleBegin() {
|
||||||
if (detector.isDoubleTapping) {
|
if (detector.isDoubleTapping && canZoom) {
|
||||||
detector.isQuickScaling = true
|
detector.isQuickScaling = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onScaleEnd() {
|
fun onScaleEnd() {
|
||||||
if (scaleX < MIN_RATE) {
|
if (scaleX < MIN_RATE && canZoom) {
|
||||||
zoom(currentScale, MIN_RATE, x, 0f, y, 0f)
|
zoom(currentScale, MIN_RATE, x, 0f, y, 0f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +229,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onDoubleTapConfirmed(ev: MotionEvent) {
|
fun onDoubleTapConfirmed(ev: MotionEvent) {
|
||||||
if (!isZooming) {
|
if (!isZooming && canZoom) {
|
||||||
if (scaleX != DEFAULT_RATE) {
|
if (scaleX != DEFAULT_RATE) {
|
||||||
zoom(currentScale, DEFAULT_RATE, x, 0f, y, 0f)
|
zoom(currentScale, DEFAULT_RATE, x, 0f, y, 0f)
|
||||||
} else {
|
} else {
|
||||||
|
@ -250,7 +262,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
override fun onTouchEvent(ev: MotionEvent): Boolean {
|
override fun onTouchEvent(ev: MotionEvent): Boolean {
|
||||||
val action = ev.actionMasked
|
val action = ev.actionMasked
|
||||||
val actionIndex = ev.actionIndex
|
val actionIndex = ev.actionIndex
|
||||||
|
if (!canZoom) return super.onTouchEvent(ev)
|
||||||
when (action) {
|
when (action) {
|
||||||
MotionEvent.ACTION_DOWN -> {
|
MotionEvent.ACTION_DOWN -> {
|
||||||
scrollPointerId = ev.getPointerId(0)
|
scrollPointerId = ev.getPointerId(0)
|
||||||
|
@ -297,12 +309,12 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
startScroll = true
|
startScroll = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startScroll) {
|
if (startScroll && canZoom) {
|
||||||
isZoomDragging = true
|
isZoomDragging = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isZoomDragging) {
|
if (isZoomDragging && canZoom) {
|
||||||
zoomScrollBy(dx, dy)
|
zoomScrollBy(dx, dy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,10 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
|
||||||
refreshAdapter()
|
refreshAdapter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.zoomPropertyChangedListener = {
|
||||||
|
frame.disableZoom = it
|
||||||
|
}
|
||||||
|
|
||||||
frame.layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
frame.layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||||
frame.addView(recycler)
|
frame.addView(recycler)
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,6 @@
|
||||||
android:layout_marginTop="0dp"
|
android:layout_marginTop="0dp"
|
||||||
android:text="@string/page_transitions"
|
android:text="@string/page_transitions"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/crop_borders" />
|
app:layout_constraintTop_toBottomOf="@id/crop_borders" />
|
||||||
|
|
||||||
<!-- Webtoon preferences -->
|
<!-- Webtoon preferences -->
|
||||||
|
@ -259,12 +258,20 @@
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:entries="@array/webtoon_side_padding"
|
android:entries="@array/webtoon_side_padding"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
||||||
app:layout_constraintRight_toRightOf="@id/spinner_end"
|
app:layout_constraintRight_toRightOf="@id/spinner_end"
|
||||||
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
||||||
app:layout_constraintTop_toBottomOf="@id/crop_borders_webtoon" />
|
app:layout_constraintTop_toBottomOf="@id/crop_borders_webtoon" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/webtoon_disable_zoom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/disable_zoom"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/webtoon_side_padding" />
|
||||||
|
|
||||||
<!-- Groups of preferences -->
|
<!-- Groups of preferences -->
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Group
|
<androidx.constraintlayout.widget.Group
|
||||||
|
@ -282,7 +289,7 @@
|
||||||
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,
|
||||||
webtoon_side_padding_text,webtoon_side_padding" />
|
webtoon_side_padding_text,webtoon_side_padding,webtoon_disable_zoom" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
<androidx.constraintlayout.widget.Guideline
|
||||||
android:id="@+id/bottom_line"
|
android:id="@+id/bottom_line"
|
||||||
|
|
|
@ -282,6 +282,7 @@
|
||||||
<!-- Reader settings -->
|
<!-- Reader settings -->
|
||||||
<string name="fullscreen">Fullscreen</string>
|
<string name="fullscreen">Fullscreen</string>
|
||||||
<string name="page_transitions">Page transitions</string>
|
<string name="page_transitions">Page transitions</string>
|
||||||
|
<string name="disable_zoom">Disable zoom</string>
|
||||||
<string name="double_tap_anim_speed">Double tap animation speed</string>
|
<string name="double_tap_anim_speed">Double tap animation speed</string>
|
||||||
<string name="show_page_number">Show page number</string>
|
<string name="show_page_number">Show page number</string>
|
||||||
<string name="true_32bit_color">32-bit color</string>
|
<string name="true_32bit_color">32-bit color</string>
|
||||||
|
|
Reference in a new issue