mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Add orientation toggle to bottom reader menu
This commit is contained in:
		@@ -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)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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].
 | 
			
		||||
         */
 | 
			
		||||
 
 | 
			
		||||
@@ -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() }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:width="24dp"
 | 
			
		||||
    android:height="24dp"
 | 
			
		||||
    android:viewportWidth="24"
 | 
			
		||||
    android:viewportHeight="24">
 | 
			
		||||
    <path
 | 
			
		||||
        android:fillColor="@android:color/black"
 | 
			
		||||
        android:pathData="M21,5L3,5c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,7c0,-1.1 -0.9,-2 -2,-2zM19,17L5,17L5,7h14v10zM10,16h4c0.55,0 1,-0.45 1,-1v-3c0,-0.55 -0.45,-1 -1,-1v-1c0,-1.11 -0.9,-2 -2,-2 -1.11,0 -2,0.9 -2,2v1c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1zM10.8,10c0,-0.66 0.54,-1.2 1.2,-1.2 0.66,0 1.2,0.54 1.2,1.2v1h-2.4v-1z" />
 | 
			
		||||
</vector>
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:width="24dp"
 | 
			
		||||
    android:height="24dp"
 | 
			
		||||
    android:viewportWidth="24"
 | 
			
		||||
    android:viewportHeight="24">
 | 
			
		||||
    <path
 | 
			
		||||
        android:fillColor="@android:color/black"
 | 
			
		||||
        android:pathData="M10,16h4c0.55,0 1,-0.45 1,-1v-3c0,-0.55 -0.45,-1 -1,-1v-1c0,-1.11 -0.9,-2 -2,-2 -1.11,0 -2,0.9 -2,2v1c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1zM10.8,10c0,-0.66 0.54,-1.2 1.2,-1.2 0.66,0 1.2,0.54 1.2,1.2v1h-2.4v-1zM17,1L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-2 -2,-2zM17,19L7,19L7,5h10v14z" />
 | 
			
		||||
</vector>
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:width="24dp"
 | 
			
		||||
    android:height="24dp"
 | 
			
		||||
    android:viewportWidth="24"
 | 
			
		||||
    android:viewportHeight="24">
 | 
			
		||||
    <path
 | 
			
		||||
        android:fillColor="@android:color/black"
 | 
			
		||||
        android:pathData="M23.25,12.77l-2.57,-2.57 -1.41,1.41 2.22,2.22 -5.66,5.66L4.51,8.17l5.66,-5.66 2.1,2.1 1.41,-1.41L11.23,0.75c-0.59,-0.59 -1.54,-0.59 -2.12,0L2.75,7.11c-0.59,0.59 -0.59,1.54 0,2.12l12.02,12.02c0.59,0.59 1.54,0.59 2.12,0l6.36,-6.36c0.59,-0.59 0.59,-1.54 0,-2.12zM8.47,20.48C5.2,18.94 2.86,15.76 2.5,12L1,12c0.51,6.16 5.66,11 11.95,11l0.66,-0.03 -3.81,-3.82 -1.33,1.33zM16,9h5c0.55,0 1,-0.45 1,-1L22,4c0,-0.55 -0.45,-1 -1,-1v-0.5C21,1.12 19.88,0 18.5,0S16,1.12 16,2.5L16,3c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1zM16.8,2.5c0,-0.94 0.76,-1.7 1.7,-1.7s1.7,0.76 1.7,1.7L20.2,3h-3.4v-0.5z" />
 | 
			
		||||
</vector>
 | 
			
		||||
							
								
								
									
										9
									
								
								app/src/main/res/drawable/ic_screen_rotation_24dp.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								app/src/main/res/drawable/ic_screen_rotation_24dp.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:width="24dp"
 | 
			
		||||
    android:height="24dp"
 | 
			
		||||
    android:viewportWidth="24"
 | 
			
		||||
    android:viewportHeight="24">
 | 
			
		||||
    <path
 | 
			
		||||
        android:fillColor="@android:color/black"
 | 
			
		||||
        android:pathData="M16.48,2.52c3.27,1.55 5.61,4.72 5.97,8.48h1.5C23.44,4.84 18.29,0 12,0l-0.66,0.03 3.81,3.81 1.33,-1.32zM10.23,1.75c-0.59,-0.59 -1.54,-0.59 -2.12,0L1.75,8.11c-0.59,0.59 -0.59,1.54 0,2.12l12.02,12.02c0.59,0.59 1.54,0.59 2.12,0l6.36,-6.36c0.59,-0.59 0.59,-1.54 0,-2.12L10.23,1.75zM14.83,21.19L2.81,9.17l6.36,-6.36 12.02,12.02 -6.36,6.36zM7.52,21.48C4.25,19.94 1.91,16.76 1.55,13L0.05,13C0.56,19.16 5.71,24 12,24l0.66,-0.03 -3.81,-3.81 -1.33,1.32z" />
 | 
			
		||||
</vector>
 | 
			
		||||
@@ -145,6 +145,33 @@
 | 
			
		||||
                android:layout_gravity="bottom"
 | 
			
		||||
                android:background="?attr/colorPrimary">
 | 
			
		||||
 | 
			
		||||
<!--                <ImageButton-->
 | 
			
		||||
<!--                    android:id="@+id/action_reader_mode"-->
 | 
			
		||||
<!--                    android:layout_width="wrap_content"-->
 | 
			
		||||
<!--                    android:layout_height="match_parent"-->
 | 
			
		||||
<!--                    android:background="?selectableItemBackgroundBorderless"-->
 | 
			
		||||
<!--                    android:contentDescription="@string/viewer"-->
 | 
			
		||||
<!--                    android:padding="@dimen/material_layout_keylines_screen_edge_margin"-->
 | 
			
		||||
<!--                    app:layout_constraintEnd_toStartOf="@id/action_rotation"-->
 | 
			
		||||
<!--                    app:layout_constraintStart_toStartOf="parent"-->
 | 
			
		||||
<!--                    app:layout_constraintTop_toTopOf="parent"-->
 | 
			
		||||
<!--                    app:srcCompat="@drawable/ic_book_24dp"-->
 | 
			
		||||
<!--                    app:tint="?attr/colorOnPrimary" />-->
 | 
			
		||||
 | 
			
		||||
                <!-- app:layout_constraintStart_toEndOf="@+id/action_reader_mode" -->
 | 
			
		||||
                <ImageButton
 | 
			
		||||
                    android:id="@+id/action_rotation"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="match_parent"
 | 
			
		||||
                    android:background="?selectableItemBackgroundBorderless"
 | 
			
		||||
                    android:contentDescription="@string/pref_rotation_type"
 | 
			
		||||
                    android:padding="@dimen/material_layout_keylines_screen_edge_margin"
 | 
			
		||||
                    app:layout_constraintEnd_toStartOf="@id/action_custom_filter"
 | 
			
		||||
                    app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
                    app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
                    app:srcCompat="@drawable/ic_screen_rotation_24dp"
 | 
			
		||||
                    app:tint="?attr/colorOnPrimary" />
 | 
			
		||||
 | 
			
		||||
                <ImageButton
 | 
			
		||||
                    android:id="@+id/action_custom_filter"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
@@ -153,7 +180,7 @@
 | 
			
		||||
                    android:contentDescription="@string/custom_filter"
 | 
			
		||||
                    android:padding="@dimen/material_layout_keylines_screen_edge_margin"
 | 
			
		||||
                    app:layout_constraintEnd_toStartOf="@id/action_settings"
 | 
			
		||||
                    app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
                    app:layout_constraintStart_toEndOf="@+id/action_rotation"
 | 
			
		||||
                    app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
                    app:srcCompat="@drawable/ic_brightness_4_24dp"
 | 
			
		||||
                    app:tint="?attr/colorOnPrimary" />
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user