Add orientation toggle to bottom reader menu

This commit is contained in:
arkon
2021-02-13 18:50:50 -05:00
parent a92b0e567b
commit 33992d80bf
8 changed files with 141 additions and 35 deletions

View File

@ -0,0 +1,39 @@
package eu.kanade.tachiyomi.ui.reader
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.content.res.Resources
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import eu.kanade.tachiyomi.R
import kotlin.math.max
enum class OrientationType(val prefValue: Int, val flag: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int) {
FREE(1, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, R.string.rotation_free, R.drawable.ic_screen_rotation_24dp),
LOCKED_PORTRAIT(2, ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT, R.string.rotation_lock, R.drawable.ic_screen_lock_rotation_24dp),
LOCKED_LANDSCAPE(2, ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE, R.string.rotation_lock, R.drawable.ic_screen_lock_rotation_24dp),
PORTRAIT(3, ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT, R.string.rotation_force_portrait, R.drawable.ic_screen_lock_portrait_24dp),
LANDSCAPE(4, ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE, R.string.rotation_force_landscape, R.drawable.ic_screen_lock_landscape_24dp);
companion object {
fun fromPreference(preference: Int, resources: Resources): OrientationType = when (preference) {
2 -> {
val currentOrientation = resources.configuration.orientation
if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
LOCKED_PORTRAIT
} else {
LOCKED_LANDSCAPE
}
}
3 -> PORTRAIT
4 -> LANDSCAPE
else -> FREE
}
fun getNextOrientation(preference: Int, resources: Resources): OrientationType {
// There's only 4 options (1 to 4)
val newOrientation = max(1, (preference + 1) % 5)
return fromPreference(newOrientation, resources)
}
}
}

View File

@ -6,8 +6,6 @@ import android.app.ProgressDialog
import android.content.ClipData
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Build
@ -21,6 +19,7 @@ import android.view.WindowManager
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.SeekBar
import android.widget.Toast
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
@ -111,6 +110,8 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
@Suppress("DEPRECATION")
private var progressDialog: ProgressDialog? = null
private var rotationToast: Toast? = null
companion object {
@Suppress("unused")
const val LEFT_TO_RIGHT = 1
@ -344,6 +345,21 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
}
}
binding.actionRotation.setOnClickListener {
val newOrientation = OrientationType.getNextOrientation(preferences.rotation().get(), resources)
preferences.rotation().set(newOrientation.prefValue)
setOrientation(newOrientation.flag)
rotationToast?.cancel()
rotationToast = toast(newOrientation.stringRes)
}
preferences.rotation().asImmediateFlow { updateRotationShortcut(it) }
.onEach {
updateRotationShortcut(it)
}
.launchIn(lifecycleScope)
binding.actionCustomFilter.setOnClickListener {
val sheet = ReaderColorFilterSheet(this)
// Remove dimmed backdrop so changes can be previewed
@ -363,6 +379,11 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
setMenuVisibility(menuVisible)
}
private fun updateRotationShortcut(preference: Int) {
val orientation = OrientationType.fromPreference(preference, resources)
binding.actionRotation.setImageResource(orientation.iconRes)
}
/**
* Sets the visibility of the menu according to [visible] and with an optional parameter to
* [animate] the views.
@ -382,7 +403,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
toolbarAnimation.setAnimationListener(
object : SimpleAnimationListener() {
override fun onAnimationStart(animation: Animation) {
// Fix status bar being translucent the first time it's opened.
// Fix status bar being translucent the first time it's opened.
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
}
}
@ -668,6 +689,16 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
)
}
/**
* Forces the user preferred [orientation] on the activity.
*/
private fun setOrientation(orientation: Int) {
val newOrientation = OrientationType.fromPreference(orientation, resources)
if (newOrientation.flag != requestedOrientation) {
requestedOrientation = newOrientation.flag
}
}
/**
* Class that handles the user preferences of the reader.
*/
@ -721,33 +752,6 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
.launchIn(lifecycleScope)
}
/**
* Forces the user preferred [orientation] on the activity.
*/
private fun setOrientation(orientation: Int) {
val newOrientation = when (orientation) {
// Lock in current orientation
2 -> {
val currentOrientation = resources.configuration.orientation
if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
} else {
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
}
}
// Lock in portrait
3 -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
// Lock in landscape
4 -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
// Rotation free
else -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
}
if (newOrientation != requestedOrientation) {
requestedOrientation = newOrientation
}
}
/**
* Sets the visibility of the bottom page indicator according to [visible].
*/

View File

@ -42,8 +42,8 @@ import kotlin.math.roundToInt
* @param resource the text resource.
* @param duration the duration of the toast. Defaults to short.
*/
fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, resource, duration).show()
fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT): Toast {
return Toast.makeText(this, resource, duration).also { it.show() }
}
/**
@ -52,8 +52,8 @@ fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT)
* @param text the text to display.
* @param duration the duration of the toast. Defaults to short.
*/
fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, text.orEmpty(), duration).show()
fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT): Toast {
return Toast.makeText(this, text.orEmpty(), duration).also { it.show() }
}
/**