mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-25 14:21:50 +01:00
Reworking Reader Activity Menus
Reader settings sheet now in a tabbed layout Reader settings sheet also contains filter options Reader menu now holds the long tap options (Share, Save, Set as cover) Reader menu also has option to go to manga details (was on toolbar tap) Also has the option to jump straight to reader settings Removing long tap gesture on Reader since no longer needed
This commit is contained in:
parent
6b06833fee
commit
fe2543b9d5
@ -49,8 +49,6 @@ object PreferenceKeys {
|
|||||||
|
|
||||||
const val readWithTapping = "reader_tap"
|
const val readWithTapping = "reader_tap"
|
||||||
|
|
||||||
const val readWithLongTap = "reader_long_tap"
|
|
||||||
|
|
||||||
const val readWithVolumeKeys = "reader_volume_keys"
|
const val readWithVolumeKeys = "reader_volume_keys"
|
||||||
|
|
||||||
const val readWithVolumeKeysInverted = "reader_volume_keys_inverted"
|
const val readWithVolumeKeysInverted = "reader_volume_keys_inverted"
|
||||||
|
@ -126,8 +126,6 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true)
|
fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true)
|
||||||
|
|
||||||
fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true)
|
|
||||||
|
|
||||||
fun readWithVolumeKeys() = flowPrefs.getBoolean(Keys.readWithVolumeKeys, false)
|
fun readWithVolumeKeys() = flowPrefs.getBoolean(Keys.readWithVolumeKeys, false)
|
||||||
|
|
||||||
fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
|
fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
|
||||||
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
import eu.kanade.tachiyomi.util.bindToPreference
|
||||||
import kotlinx.android.synthetic.main.library_badges_layout.view.*
|
import kotlinx.android.synthetic.main.library_badges_layout.view.*
|
||||||
|
|
||||||
class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import eu.kanade.tachiyomi.util.bindToPreference
|
||||||
import kotlinx.android.synthetic.main.library_category_layout.view.*
|
import kotlinx.android.synthetic.main.library_category_layout.view.*
|
||||||
|
|
||||||
class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import eu.kanade.tachiyomi.util.bindToPreference
|
||||||
import kotlinx.android.synthetic.main.library_display_layout.view.*
|
import kotlinx.android.synthetic.main.library_display_layout.view.*
|
||||||
|
|
||||||
class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
|
@ -25,42 +25,4 @@ abstract class LibraryPreferenceView @JvmOverloads constructor(context: Context,
|
|||||||
super.onFinishInflate()
|
super.onFinishInflate()
|
||||||
initGeneralPreferences()
|
initGeneralPreferences()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds a checkbox or switch view with a boolean preference.
|
|
||||||
*/
|
|
||||||
internal fun CompoundButton.bindToPreference(pref: Preference<Boolean>, block: (() -> Unit)? = null) {
|
|
||||||
isChecked = pref.getOrDefault()
|
|
||||||
setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
pref.set(isChecked)
|
|
||||||
block?.invoke()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds a checkbox or switch view with a boolean preference.
|
|
||||||
*/
|
|
||||||
internal fun CompoundButton.bindToPreference(
|
|
||||||
pref: com.tfcporciuncula.flow
|
|
||||||
.Preference<Boolean>,
|
|
||||||
block: ((Boolean) -> Unit)? = null
|
|
||||||
) {
|
|
||||||
isChecked = pref.get()
|
|
||||||
setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
pref.set(isChecked)
|
|
||||||
block?.invoke(isChecked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds a radio group with a int preference.
|
|
||||||
*/
|
|
||||||
internal fun RadioGroup.bindToPreference(pref: Preference<Int>, block: (() -> Unit)? = null) {
|
|
||||||
(getChildAt(pref.getOrDefault()) as RadioButton).isChecked = true
|
|
||||||
setOnCheckedChangeListener { _, checkedId ->
|
|
||||||
val index = indexOfChild(findViewById(checkedId))
|
|
||||||
pref.set(index)
|
|
||||||
block?.invoke()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -12,7 +12,7 @@ import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
|||||||
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
||||||
|
|
||||||
open class TabbedLibraryDisplaySheet(controller: LibraryController):
|
open class TabbedLibraryDisplaySheet(controller: LibraryController):
|
||||||
TabbedBottomSheetDialog(controller) {
|
TabbedBottomSheetDialog(controller.activity!!) {
|
||||||
|
|
||||||
private val displayView: LibraryDisplayView = inflate(controller.activity!!, R.layout.library_display_layout, null) as LibraryDisplayView
|
private val displayView: LibraryDisplayView = inflate(controller.activity!!, R.layout.library_display_layout, null) as LibraryDisplayView
|
||||||
private val badgesView: LibraryBadgesView = inflate(controller.activity!!, R.layout.library_badges_layout, null) as LibraryBadgesView
|
private val badgesView: LibraryBadgesView = inflate(controller.activity!!, R.layout.library_badges_layout, null) as LibraryBadgesView
|
||||||
|
@ -693,6 +693,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
const val SHORTCUT_BROWSE = "eu.kanade.tachiyomi.SHOW_BROWSE"
|
const val SHORTCUT_BROWSE = "eu.kanade.tachiyomi.SHOW_BROWSE"
|
||||||
const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS"
|
const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS"
|
||||||
const val SHORTCUT_MANGA = "eu.kanade.tachiyomi.SHOW_MANGA"
|
const val SHORTCUT_MANGA = "eu.kanade.tachiyomi.SHOW_MANGA"
|
||||||
|
const val SHORTCUT_READER_SETTINGS = "eu.kanade.tachiyomi.READER_SETTINGS"
|
||||||
const val SHORTCUT_EXTENSIONS = "eu.kanade.tachiyomi.EXTENSIONS"
|
const val SHORTCUT_EXTENSIONS = "eu.kanade.tachiyomi.EXTENSIONS"
|
||||||
|
|
||||||
const val INTENT_SEARCH = "eu.kanade.tachiyomi.SEARCH"
|
const val INTENT_SEARCH = "eu.kanade.tachiyomi.SEARCH"
|
||||||
|
@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
|||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||||
|
import eu.kanade.tachiyomi.ui.setting.SettingsReaderController
|
||||||
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
|
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||||
@ -35,7 +36,7 @@ class SearchActivity : MainActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun popToRoot() {
|
private fun popToRoot() {
|
||||||
if (intent.action == SHORTCUT_MANGA) {
|
if (intent.action == SHORTCUT_MANGA || intent.action == SHORTCUT_READER_SETTINGS) {
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
} else if (!router.handleBack()) {
|
} else if (!router.handleBack()) {
|
||||||
val intent = Intent(this, MainActivity::class.java).apply {
|
val intent = Intent(this, MainActivity::class.java).apply {
|
||||||
@ -97,6 +98,13 @@ class SearchActivity : MainActivity() {
|
|||||||
.popChangeHandler(FadeChangeHandler())
|
.popChangeHandler(FadeChangeHandler())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
SHORTCUT_READER_SETTINGS -> {
|
||||||
|
router.replaceTopController(
|
||||||
|
RouterTransaction.with(SettingsReaderController())
|
||||||
|
.pushChangeHandler(SimpleSwapChangeHandler())
|
||||||
|
.popChangeHandler(FadeChangeHandler())
|
||||||
|
)
|
||||||
|
}
|
||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -112,5 +120,14 @@ class SearchActivity : MainActivity() {
|
|||||||
action = SHORTCUT_MANGA
|
action = SHORTCUT_MANGA
|
||||||
putExtra(MangaDetailsController.MANGA_EXTRA, id)
|
putExtra(MangaDetailsController.MANGA_EXTRA, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun openReaderSettings(context: Context) = Intent(
|
||||||
|
context,
|
||||||
|
SearchActivity::class
|
||||||
|
.java
|
||||||
|
)
|
||||||
|
.apply {
|
||||||
|
action = SHORTCUT_READER_SETTINGS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Success
|
|||||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.settings.TabbedReaderSettingsSheet
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.L2RPagerViewer
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.L2RPagerViewer
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
|
||||||
@ -279,21 +280,46 @@ class ReaderActivity :
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
|
||||||
|
val detailsItem = menu?.findItem(R.id.action_manga_details)
|
||||||
|
if (presenter.manga?.mangaType(this) != null) {
|
||||||
|
detailsItem?.title = getString(R.string._details,
|
||||||
|
presenter.manga?.mangaType(this)?.capitalize(Locale.ROOT) ?: "")
|
||||||
|
} else {
|
||||||
|
detailsItem?.title = getString(R.string.details)
|
||||||
|
}
|
||||||
|
return super.onPrepareOptionsMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when an item of the options menu was clicked. Used to handle clicks on our menu
|
* Called when an item of the options menu was clicked. Used to handle clicks on our menu
|
||||||
* entries.
|
* entries.
|
||||||
*/
|
*/
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
coroutine?.cancel()
|
coroutine?.cancel()
|
||||||
bottomSheet = when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_settings -> ReaderSettingsSheet(this)
|
R.id.action_display_settings -> TabbedReaderSettingsSheet(this).show()
|
||||||
R.id.action_custom_filter -> ReaderColorFilterSheet(this)
|
R.id.action_manga_details -> {
|
||||||
|
presenter.manga?.id?.let { id ->
|
||||||
|
val intent = SearchActivity.openMangaIntent(this, id)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R.id.action_share_page, R.id.action_set_page_as_cover, R.id.action_save_page -> {
|
||||||
|
val currentChapter = presenter.getCurrentChapter() ?: return true
|
||||||
|
val page = currentChapter.pages?.getOrNull(page_seekbar.progress) ?: return true
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.action_share_page -> shareImage(page)
|
||||||
|
R.id.action_set_page_as_cover -> showSetCoverPrompt(page)
|
||||||
|
R.id.action_save_page -> saveImage(page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R.id.action_reader_settings -> {
|
||||||
|
val intent = SearchActivity.openReaderSettings(this)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
else -> return super.onOptionsItemSelected(item)
|
else -> return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
bottomSheet?.show()
|
|
||||||
if (chapters_bottom_sheet.sheetBehavior.isExpanded()) {
|
|
||||||
chapters_bottom_sheet.sheetBehavior?.collapse()
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,13 +383,6 @@ class ReaderActivity :
|
|||||||
popToMain()
|
popToMain()
|
||||||
}
|
}
|
||||||
|
|
||||||
toolbar.setOnClickListener {
|
|
||||||
presenter.manga?.id?.let { id ->
|
|
||||||
val intent = SearchActivity.openMangaIntent(this, id)
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init listeners on bottom menu
|
// Init listeners on bottom menu
|
||||||
page_seekbar.setOnSeekBarChangeListener(
|
page_seekbar.setOnSeekBarChangeListener(
|
||||||
object : SimpleSeekBarListener() {
|
object : SimpleSeekBarListener() {
|
||||||
@ -477,6 +496,7 @@ class ReaderActivity :
|
|||||||
val prevViewer = viewer
|
val prevViewer = viewer
|
||||||
val noDefault = manga.viewer == -1
|
val noDefault = manga.viewer == -1
|
||||||
val mangaViewer = presenter.getMangaViewer()
|
val mangaViewer = presenter.getMangaViewer()
|
||||||
|
invalidateOptionsMenu()
|
||||||
val newViewer = when (mangaViewer) {
|
val newViewer = when (mangaViewer) {
|
||||||
RIGHT_TO_LEFT -> R2LPagerViewer(this)
|
RIGHT_TO_LEFT -> R2LPagerViewer(this)
|
||||||
VERTICAL -> VerticalPagerViewer(this)
|
VERTICAL -> VerticalPagerViewer(this)
|
||||||
@ -615,41 +635,6 @@ class ReaderActivity :
|
|||||||
page_seekbar.progress = page.index
|
page_seekbar.progress = page.index
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called from the viewer whenever a [page] is long clicked. A bottom sheet with a list of
|
|
||||||
* actions to perform is shown.
|
|
||||||
*/
|
|
||||||
fun onPageLongTap(page: ReaderPage) {
|
|
||||||
val items = listOf(
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
0,
|
|
||||||
R.drawable.ic_photo_24dp,
|
|
||||||
R.string.set_as_cover
|
|
||||||
),
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
1,
|
|
||||||
R.drawable.ic_share_24dp,
|
|
||||||
R.string.share
|
|
||||||
),
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
2,
|
|
||||||
R.drawable.ic_save_24dp,
|
|
||||||
R.string.save
|
|
||||||
)
|
|
||||||
)
|
|
||||||
MaterialMenuSheet(this, items) { _, item ->
|
|
||||||
when (item) {
|
|
||||||
0 -> showSetCoverPrompt(page)
|
|
||||||
1 -> shareImage(page)
|
|
||||||
2 -> saveImage(page)
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}.show()
|
|
||||||
if (chapters_bottom_sheet.sheetBehavior.isExpanded()) {
|
|
||||||
chapters_bottom_sheet.sheetBehavior?.collapse()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the viewer when the given [chapter] should be preloaded. It should be called when
|
* Called from the viewer when the given [chapter] should be preloaded. It should be called when
|
||||||
* the viewer is reaching the beginning or end of a chapter or the transition page is active.
|
* the viewer is reaching the beginning or end of a chapter or the transition page is active.
|
||||||
|
@ -1,194 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.ui.reader
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.CompoundButton
|
|
||||||
import android.widget.Spinner
|
|
||||||
import androidx.annotation.ArrayRes
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
|
||||||
import com.tfcporciuncula.flow.Preference
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
|
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
|
||||||
import eu.kanade.tachiyomi.util.system.hasSideNavBar
|
|
||||||
import eu.kanade.tachiyomi.util.system.isInNightMode
|
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
|
||||||
import eu.kanade.tachiyomi.util.view.setBottomEdge
|
|
||||||
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
|
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
|
||||||
import eu.kanade.tachiyomi.util.view.visibleIf
|
|
||||||
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
|
|
||||||
import kotlinx.android.synthetic.main.reader_settings_sheet.*
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import kotlin.math.max
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sheet to show reader and viewer preferences.
|
|
||||||
*/
|
|
||||||
class ReaderSettingsSheet(private val activity: ReaderActivity) :
|
|
||||||
BottomSheetDialog(activity, R.style.BottomSheetDialogTheme) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preferences helper.
|
|
||||||
*/
|
|
||||||
private val preferences by injectLazy<PreferencesHelper>()
|
|
||||||
|
|
||||||
private var sheetBehavior: BottomSheetBehavior<*>
|
|
||||||
|
|
||||||
init {
|
|
||||||
// Use activity theme for this layout
|
|
||||||
val view = activity.layoutInflater.inflate(R.layout.reader_settings_sheet, null)
|
|
||||||
setContentView(view)
|
|
||||||
|
|
||||||
sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
|
|
||||||
setEdgeToEdge(
|
|
||||||
activity,
|
|
||||||
view,
|
|
||||||
if (context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
|
|
||||||
0 else -1
|
|
||||||
)
|
|
||||||
window?.navigationBarColor = Color.TRANSPARENT
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
|
|
||||||
!context.isInNightMode() &&
|
|
||||||
!activity.window.decorView.rootWindowInsets.hasSideNavBar()
|
|
||||||
) {
|
|
||||||
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
|
||||||
}
|
|
||||||
|
|
||||||
val height = activity.window.decorView.rootWindowInsets.systemWindowInsetBottom
|
|
||||||
sheetBehavior.peekHeight = 550.dpToPx + height
|
|
||||||
|
|
||||||
sheetBehavior.addBottomSheetCallback(
|
|
||||||
object : BottomSheetBehavior.BottomSheetCallback() {
|
|
||||||
override fun onSlide(bottomSheet: View, progress: Float) {
|
|
||||||
if (progress.isNaN())
|
|
||||||
pill.alpha = 0f
|
|
||||||
else
|
|
||||||
pill.alpha = (1 - max(0f, progress)) * 0.25f
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStateChanged(p0: View, state: Int) {
|
|
||||||
if (state == BottomSheetBehavior.STATE_EXPANDED) {
|
|
||||||
sheetBehavior.skipCollapsed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the sheet is created. It initializes the listeners and values of the preferences.
|
|
||||||
*/
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
|
|
||||||
initGeneralPreferences()
|
|
||||||
|
|
||||||
when (val view = activity.viewer) {
|
|
||||||
is PagerViewer -> initPagerPreferences()
|
|
||||||
is WebtoonViewer -> initWebtoonPreferences(view.hasMargins)
|
|
||||||
}
|
|
||||||
|
|
||||||
setBottomEdge(constraint_layout, activity)
|
|
||||||
|
|
||||||
close_button.setOnClickListener {
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
settings_scroll_view.viewTreeObserver.addOnGlobalLayoutListener {
|
|
||||||
val isScrollable =
|
|
||||||
settings_scroll_view.height < constraint_layout.height +
|
|
||||||
settings_scroll_view.paddingTop + settings_scroll_view.paddingBottom
|
|
||||||
close_button.visibleIf(isScrollable)
|
|
||||||
pill.visibleIf(!isScrollable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init general reader preferences.
|
|
||||||
*/
|
|
||||||
private fun initGeneralPreferences() {
|
|
||||||
viewer.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
|
|
||||||
activity.presenter.setMangaViewer(position)
|
|
||||||
|
|
||||||
val mangaViewer = activity.presenter.getMangaViewer()
|
|
||||||
if (mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS) {
|
|
||||||
initWebtoonPreferences(mangaViewer == ReaderActivity.VERTICAL_PLUS)
|
|
||||||
} else {
|
|
||||||
initPagerPreferences()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewer.setSelection(activity.presenter.manga?.viewer ?: 0, false)
|
|
||||||
|
|
||||||
rotation_mode.bindToPreference(preferences.rotation(), 1)
|
|
||||||
background_color.bindToPreference(preferences.readerTheme(), 0)
|
|
||||||
show_page_number.bindToPreference(preferences.showPageNumber())
|
|
||||||
fullscreen.bindToPreference(preferences.fullscreen())
|
|
||||||
keepscreen.bindToPreference(preferences.keepScreenOn())
|
|
||||||
always_show_chapter_transition.bindToPreference(preferences.alwaysShowChapterTransition())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init the preferences for the pager reader.
|
|
||||||
*/
|
|
||||||
private fun initPagerPreferences() {
|
|
||||||
pager_prefs_group.visible()
|
|
||||||
webtoon_prefs_group.gone()
|
|
||||||
scale_type.bindToPreference(preferences.imageScaleType(), 1)
|
|
||||||
zoom_start.bindToPreference(preferences.zoomStart(), 1)
|
|
||||||
crop_borders.bindToPreference(preferences.cropBorders())
|
|
||||||
page_transitions.bindToPreference(preferences.pageTransitions())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init the preferences for the webtoon reader.
|
|
||||||
*/
|
|
||||||
private fun initWebtoonPreferences(hasMargins: Boolean) {
|
|
||||||
webtoon_prefs_group.visible()
|
|
||||||
pager_prefs_group.gone()
|
|
||||||
crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon())
|
|
||||||
webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
|
|
||||||
webtoon_enable_zoom_out.bindToPreference(preferences.webtoonEnableZoomOut())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds a checkbox or switch view with a boolean preference.
|
|
||||||
*/
|
|
||||||
private fun CompoundButton.bindToPreference(pref: Preference<Boolean>) {
|
|
||||||
setOnCheckedChangeListener(null)
|
|
||||||
isChecked = pref.get()
|
|
||||||
setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds a spinner to an int preference with an optional offset for the value.
|
|
||||||
*/
|
|
||||||
private fun Spinner.bindToPreference(
|
|
||||||
pref: Preference<Int>,
|
|
||||||
offset: Int = 0
|
|
||||||
) {
|
|
||||||
onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
|
|
||||||
pref.set(position + offset)
|
|
||||||
}
|
|
||||||
setSelection(pref.get() - offset, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds a spinner to an int preference. The position of the spinner item must
|
|
||||||
* correlate with the [intValues] resource item (in arrays.xml), which is a <string-array>
|
|
||||||
* of int values that will be parsed here and applied to the preference.
|
|
||||||
*/
|
|
||||||
private fun Spinner.bindToIntPreference(pref: Preference<Int>, @ArrayRes intValuesResource: Int) {
|
|
||||||
val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() }
|
|
||||||
onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
|
|
||||||
pref.set(intValues[position] ?: 0)
|
|
||||||
}
|
|
||||||
setSelection(intValues.indexOf(pref.get()), false)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,25 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.reader.settings
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
|
abstract class BaseReaderSettingsView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
|
FrameLayout(context, attrs) {
|
||||||
|
|
||||||
|
internal val preferences by injectLazy<PreferencesHelper>()
|
||||||
|
lateinit var activity: ReaderActivity
|
||||||
|
|
||||||
|
abstract fun initGeneralPreferences()
|
||||||
|
|
||||||
|
override fun onFinishInflate() {
|
||||||
|
super.onFinishInflate()
|
||||||
|
initGeneralPreferences()
|
||||||
|
}
|
||||||
|
}
|
@ -1,74 +1,44 @@
|
|||||||
package eu.kanade.tachiyomi.ui.reader
|
package eu.kanade.tachiyomi.ui.reader.settings
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.util.system.hasSideNavBar
|
|
||||||
import eu.kanade.tachiyomi.util.system.isInNightMode
|
|
||||||
import eu.kanade.tachiyomi.util.view.expand
|
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
|
||||||
import eu.kanade.tachiyomi.util.view.setBottomEdge
|
|
||||||
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
|
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
|
||||||
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
|
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
|
||||||
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
|
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
|
||||||
import kotlinx.android.synthetic.main.reader_color_filter.*
|
import kotlinx.android.synthetic.main.reader_color_filter.*
|
||||||
import kotlinx.android.synthetic.main.reader_color_filter_sheet.*
|
import kotlinx.android.synthetic.main.reader_color_filter.view.*
|
||||||
|
import kotlinx.android.synthetic.main.reader_color_filter.view.settings_scroll_view
|
||||||
|
import kotlinx.android.synthetic.main.reader_general_layout.view.*
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.sample
|
import kotlinx.coroutines.flow.sample
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import kotlin.math.abs
|
|
||||||
|
|
||||||
/**
|
class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
* Color filter sheet to toggle custom filter and brightness overlay.
|
BaseReaderSettingsView(context, attrs) {
|
||||||
*/
|
|
||||||
class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheetDialog
|
|
||||||
(activity, R.style.BottomSheetDialogTheme) {
|
|
||||||
|
|
||||||
private val preferences by injectLazy<PreferencesHelper>()
|
|
||||||
|
|
||||||
private var sheetBehavior: BottomSheetBehavior<*>? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
val view = activity.layoutInflater.inflate(R.layout.reader_color_filter_sheet, null)
|
|
||||||
setContentView(view)
|
|
||||||
|
|
||||||
setEdgeToEdge(activity, view, 0)
|
|
||||||
window?.navigationBarColor = Color.TRANSPARENT
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
|
|
||||||
!context.isInNightMode() &&
|
|
||||||
!activity.window.decorView.rootWindowInsets.hasSideNavBar()
|
|
||||||
)
|
|
||||||
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
|
||||||
setBottomEdge(brightness_seekbar, activity)
|
|
||||||
|
|
||||||
sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
|
|
||||||
|
|
||||||
|
override fun initGeneralPreferences() {
|
||||||
|
activity = context as ReaderActivity
|
||||||
|
settings_scroll_view.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
||||||
preferences.colorFilter().asFlow()
|
preferences.colorFilter().asFlow()
|
||||||
.onEach { setColorFilter(it, view) }
|
.onEach { setColorFilter(it) }
|
||||||
.launchIn(activity.scope)
|
.launchIn(activity.scope)
|
||||||
|
|
||||||
preferences.colorFilterMode().asFlow()
|
preferences.colorFilterMode().asFlow()
|
||||||
.onEach { setColorFilter(preferences.colorFilter().get(), view) }
|
.onEach { setColorFilter(preferences.colorFilter().get()) }
|
||||||
.launchIn(activity.scope)
|
.launchIn(activity.scope)
|
||||||
|
|
||||||
preferences.customBrightness().asFlow()
|
preferences.customBrightness().asFlow()
|
||||||
.onEach { setCustomBrightness(it, view) }
|
.onEach { setCustomBrightness(it) }
|
||||||
.launchIn(activity.scope)
|
.launchIn(activity.scope)
|
||||||
|
|
||||||
// Get color and update values
|
// Get color and update values
|
||||||
val color = preferences.colorFilterValue().get()
|
val color = preferences.colorFilterValue().get()
|
||||||
val brightness = preferences.customBrightnessValue().get()
|
val brightness = preferences.customBrightnessValue().get()
|
||||||
|
|
||||||
val argb = setValues(color, view)
|
val argb = setValues(color)
|
||||||
|
|
||||||
// Set brightness value
|
// Set brightness value
|
||||||
txt_brightness_seekbar_value.text = brightness.toString()
|
txt_brightness_seekbar_value.text = brightness.toString()
|
||||||
@ -91,14 +61,13 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
|
|||||||
preferences.customBrightness().set(isChecked)
|
preferences.customBrightness().set(isChecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
color_filter_mode.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
|
color_filter_mode.bindToPreference(preferences.colorFilterMode())
|
||||||
preferences.colorFilterMode().set(position)
|
|
||||||
}
|
|
||||||
color_filter_mode.setSelection(preferences.colorFilterMode().get(), false)
|
|
||||||
|
|
||||||
seekbar_color_filter_alpha.setOnSeekBarChangeListener(
|
seekbar_color_filter_alpha.setOnSeekBarChangeListener(
|
||||||
object : SimpleSeekBarListener() {
|
object : SimpleSeekBarListener() {
|
||||||
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
|
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
|
||||||
|
seekbar_color_filter_red.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled
|
||||||
|
seekbar_color_filter_green.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled
|
||||||
|
seekbar_color_filter_blue.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled
|
||||||
if (fromUser) {
|
if (fromUser) {
|
||||||
setColorValue(value, ALPHA_MASK, 24)
|
setColorValue(value, ALPHA_MASK, 24)
|
||||||
}
|
}
|
||||||
@ -147,39 +116,31 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
sheetBehavior?.skipCollapsed = true
|
|
||||||
sheetBehavior?.expand()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set enabled status of seekBars belonging to color filter
|
* Set enabled status of seekBars belonging to color filter
|
||||||
* @param enabled determines if seekBar gets enabled
|
* @param enabled determines if seekBar gets enabled
|
||||||
* @param view view of the dialog
|
|
||||||
*/
|
*/
|
||||||
private fun setColorFilterSeekBar(enabled: Boolean, view: View) = with(view) {
|
private fun setColorFilterSeekBar(enabled: Boolean) {
|
||||||
seekbar_color_filter_red.isEnabled = enabled
|
seekbar_color_filter_red.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled
|
||||||
seekbar_color_filter_green.isEnabled = enabled
|
seekbar_color_filter_green.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled
|
||||||
seekbar_color_filter_blue.isEnabled = enabled
|
seekbar_color_filter_blue.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled
|
||||||
seekbar_color_filter_alpha.isEnabled = enabled
|
seekbar_color_filter_alpha.isEnabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set enabled status of seekBars belonging to custom brightness
|
* Set enabled status of seekBars belonging to custom brightness
|
||||||
* @param enabled value which determines if seekBar gets enabled
|
* @param enabled value which determines if seekBar gets enabled
|
||||||
* @param view view of the dialog
|
|
||||||
*/
|
*/
|
||||||
private fun setCustomBrightnessSeekBar(enabled: Boolean, view: View) = with(view) {
|
private fun setCustomBrightnessSeekBar(enabled: Boolean) {
|
||||||
brightness_seekbar.isEnabled = enabled
|
brightness_seekbar.isEnabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the text value's of color filter
|
* Set the text value's of color filter
|
||||||
* @param color integer containing color information
|
* @param color integer containing color information
|
||||||
* @param view view of the dialog
|
|
||||||
*/
|
*/
|
||||||
fun setValues(color: Int, view: View): Array<Int> {
|
private fun setValues(color: Int): Array<Int> {
|
||||||
val alpha = getAlphaFromColor(color)
|
val alpha = getAlphaFromColor(color)
|
||||||
val red = getRedFromColor(color)
|
val red = getRedFromColor(color)
|
||||||
val green = getGreenFromColor(color)
|
val green = getGreenFromColor(color)
|
||||||
@ -197,18 +158,17 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
|
|||||||
/**
|
/**
|
||||||
* Manages the custom brightness value subscription
|
* Manages the custom brightness value subscription
|
||||||
* @param enabled determines if the subscription get (un)subscribed
|
* @param enabled determines if the subscription get (un)subscribed
|
||||||
* @param view view of the dialog
|
|
||||||
*/
|
*/
|
||||||
private fun setCustomBrightness(enabled: Boolean, view: View) {
|
private fun setCustomBrightness(enabled: Boolean) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
preferences.customBrightnessValue().asFlow()
|
preferences.customBrightnessValue().asFlow()
|
||||||
.sample(100)
|
.sample(100)
|
||||||
.onEach { setCustomBrightnessValue(it, view) }
|
.onEach { setCustomBrightnessValue(it) }
|
||||||
.launchIn(activity.scope)
|
.launchIn(activity.scope)
|
||||||
} else {
|
} else {
|
||||||
setCustomBrightnessValue(0, view, true)
|
setCustomBrightnessValue(0, true)
|
||||||
}
|
}
|
||||||
setCustomBrightnessSeekBar(enabled, view)
|
setCustomBrightnessSeekBar(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,16 +177,8 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
|
|||||||
* From 1 to 100 it sets that value as brightness.
|
* From 1 to 100 it sets that value as brightness.
|
||||||
* 0 sets system brightness and hides the overlay.
|
* 0 sets system brightness and hides the overlay.
|
||||||
*/
|
*/
|
||||||
private fun setCustomBrightnessValue(value: Int, view: View, isDisabled: Boolean = false) = with(view) {
|
private fun setCustomBrightnessValue(value: Int, isDisabled: Boolean = false) {
|
||||||
// Set black overlay visibility.
|
// Set black overlay visibility.
|
||||||
if (value < 0) {
|
|
||||||
brightness_overlay.visible()
|
|
||||||
val alpha = (abs(value) * 2.56).toInt()
|
|
||||||
brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0))
|
|
||||||
} else {
|
|
||||||
brightness_overlay.gone()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDisabled) {
|
if (!isDisabled) {
|
||||||
txt_brightness_seekbar_value.text = value.toString()
|
txt_brightness_seekbar_value.text = value.toString()
|
||||||
}
|
}
|
||||||
@ -237,27 +189,22 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
|
|||||||
* @param enabled determines if the subscription get (un)subscribed
|
* @param enabled determines if the subscription get (un)subscribed
|
||||||
* @param view view of the dialog
|
* @param view view of the dialog
|
||||||
*/
|
*/
|
||||||
private fun setColorFilter(enabled: Boolean, view: View) {
|
private fun setColorFilter(enabled: Boolean) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
preferences.colorFilterValue().asFlow()
|
preferences.colorFilterValue().asFlow()
|
||||||
.sample(100)
|
.sample(100)
|
||||||
.onEach { setColorFilterValue(it, view) }
|
.onEach { setColorFilterValue(it) }
|
||||||
.launchIn(activity.scope)
|
.launchIn(activity.scope)
|
||||||
} else {
|
|
||||||
color_overlay.gone()
|
|
||||||
}
|
}
|
||||||
setColorFilterSeekBar(enabled, view)
|
setColorFilterSeekBar(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the color filter overlay of the screen. Determined by HEX of integer
|
* Sets the color filter overlay of the screen. Determined by HEX of integer
|
||||||
* @param color hex of color.
|
* @param color hex of color.
|
||||||
* @param view view of the dialog
|
|
||||||
*/
|
*/
|
||||||
private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) {
|
private fun setColorFilterValue(@ColorInt color: Int) {
|
||||||
color_overlay.visible()
|
setValues(color)
|
||||||
color_overlay.setFilterColor(color, preferences.colorFilterMode().get())
|
|
||||||
setValues(color, view)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,15 +237,6 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
|
|||||||
return color shr 16 and 0xFF
|
return color shr 16 and 0xFF
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the green value from the Color Hex
|
|
||||||
* @param color color hex as int
|
|
||||||
* @return green of color
|
|
||||||
*/
|
|
||||||
fun getGreenFromColor(color: Int): Int {
|
|
||||||
return color shr 8 and 0xFF
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the blue value from the Color Hex
|
* Returns the blue value from the Color Hex
|
||||||
* @param color color hex as int
|
* @param color color hex as int
|
||||||
@ -322,3 +260,12 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
|
|||||||
const val BLUE_MASK: Long = 0x000000FF
|
const val BLUE_MASK: Long = 0x000000FF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the green value from the Color Hex
|
||||||
|
* @param color color hex as int
|
||||||
|
* @return green of color
|
||||||
|
*/
|
||||||
|
fun ReaderFilterView.getGreenFromColor(color: Int): Int {
|
||||||
|
return color shr 8 and 0xFF
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.reader.settings
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
|
import eu.kanade.tachiyomi.util.bindToPreference
|
||||||
|
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
||||||
|
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
|
||||||
|
import kotlinx.android.synthetic.main.reader_general_layout.view.*
|
||||||
|
|
||||||
|
class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
|
BaseReaderSettingsView(context, attrs) {
|
||||||
|
|
||||||
|
lateinit var sheet: TabbedReaderSettingsSheet
|
||||||
|
override fun initGeneralPreferences() {
|
||||||
|
settings_scroll_view.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
||||||
|
viewer_series.onItemSelectedListener = { position ->
|
||||||
|
activity.presenter.setMangaViewer(position)
|
||||||
|
|
||||||
|
val mangaViewer = activity.presenter.getMangaViewer()
|
||||||
|
if (mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS) {
|
||||||
|
initWebtoonPreferences()
|
||||||
|
} else {
|
||||||
|
initPagerPreferences()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewer_series.setSelection((context as? ReaderActivity)?.presenter?.manga?.viewer ?: 0)
|
||||||
|
rotation_mode.bindToPreference(preferences.rotation(), 1)
|
||||||
|
background_color.bindToPreference(preferences.readerTheme(), 0)
|
||||||
|
show_page_number.bindToPreference(preferences.showPageNumber())
|
||||||
|
fullscreen.bindToPreference(preferences.fullscreen())
|
||||||
|
keepscreen.bindToPreference(preferences.keepScreenOn())
|
||||||
|
always_show_chapter_transition.bindToPreference(preferences.alwaysShowChapterTransition())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init the preferences for the webtoon reader.
|
||||||
|
*/
|
||||||
|
private fun initWebtoonPreferences() {
|
||||||
|
sheet.updateTabs(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initPagerPreferences() {
|
||||||
|
sheet.updateTabs(false)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.reader.settings
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
|
import eu.kanade.tachiyomi.util.bindToIntPreference
|
||||||
|
import eu.kanade.tachiyomi.util.bindToPreference
|
||||||
|
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
||||||
|
import eu.kanade.tachiyomi.util.view.visibleIf
|
||||||
|
import kotlinx.android.synthetic.main.reader_paged_layout.view.*
|
||||||
|
import kotlinx.android.synthetic.main.reader_paged_layout.view.crop_borders_webtoon
|
||||||
|
import kotlinx.android.synthetic.main.reader_paged_layout.view.settings_scroll_view
|
||||||
|
import kotlinx.android.synthetic.main.reader_paged_layout.view.webtoon_enable_zoom_out
|
||||||
|
import kotlinx.android.synthetic.main.reader_paged_layout.view.webtoon_side_padding
|
||||||
|
|
||||||
|
class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
|
BaseReaderSettingsView(context, attrs) {
|
||||||
|
|
||||||
|
override fun initGeneralPreferences() {
|
||||||
|
scale_type.bindToPreference(preferences.imageScaleType(), 1)
|
||||||
|
zoom_start.bindToPreference(preferences.zoomStart(), 1)
|
||||||
|
crop_borders.bindToPreference(preferences.cropBorders())
|
||||||
|
page_transitions.bindToPreference(preferences.pageTransitions())
|
||||||
|
|
||||||
|
settings_scroll_view.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
||||||
|
val mangaViewer = (context as ReaderActivity).presenter.getMangaViewer()
|
||||||
|
val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS
|
||||||
|
val hasMargins = mangaViewer == ReaderActivity.VERTICAL_PLUS
|
||||||
|
crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon())
|
||||||
|
webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
|
||||||
|
webtoon_enable_zoom_out.bindToPreference(preferences.webtoonEnableZoomOut())
|
||||||
|
|
||||||
|
updatePagedGroup(!isWebtoonView)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updatePrefs() {
|
||||||
|
val mangaViewer = activity.presenter.getMangaViewer()
|
||||||
|
val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS
|
||||||
|
val hasMargins = mangaViewer == ReaderActivity.VERTICAL_PLUS
|
||||||
|
crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon())
|
||||||
|
updatePagedGroup(!isWebtoonView)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updatePagedGroup(show: Boolean) {
|
||||||
|
listOf(scale_type, zoom_start, crop_borders, page_transitions).forEach { it.visibleIf(show) }
|
||||||
|
listOf(crop_borders_webtoon, webtoon_side_padding, webtoon_enable_zoom_out).forEach { it.visibleIf(!show) }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,134 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.reader.settings
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import androidx.annotation.ArrayRes
|
||||||
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.core.view.get
|
||||||
|
import com.tfcporciuncula.flow.Preference
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import kotlinx.android.synthetic.main.reader_preference.view.*
|
||||||
|
|
||||||
|
|
||||||
|
class ReaderPreferenceView @JvmOverloads constructor(context: Context, attrs: AttributeSet?) :
|
||||||
|
FrameLayout(context, attrs) {
|
||||||
|
|
||||||
|
|
||||||
|
private var entries = emptyList<String>()
|
||||||
|
private var selectedPosition = 0
|
||||||
|
private var pref: Preference<Int>? = null
|
||||||
|
private var prefOffset = 0
|
||||||
|
var onItemSelectedListener: ((Int) -> Unit)? = null
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
if (value != null) {
|
||||||
|
val popup = makeSettingsPopup()
|
||||||
|
setOnTouchListener(popup.dragToOpenListener)
|
||||||
|
setOnClickListener {
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
inflate(context, R.layout.reader_preference, this)
|
||||||
|
val a = context.obtainStyledAttributes(attrs, R.styleable.ReaderPreferenceView, 0, 0)
|
||||||
|
|
||||||
|
val str = a.getString(R.styleable.ReaderPreferenceView_title) ?: ""
|
||||||
|
title_view.text = str
|
||||||
|
|
||||||
|
val entries = (a.getTextArray(R.styleable.ReaderPreferenceView_android_entries) ?: emptyArray()).map { it.toString() }
|
||||||
|
this.entries = entries
|
||||||
|
|
||||||
|
detail_view.text = entries.firstOrNull().orEmpty()
|
||||||
|
|
||||||
|
a.recycle()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSelection(selection: Int) {
|
||||||
|
selectedPosition = selection
|
||||||
|
detail_view.text = entries.getOrNull(selection).orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bindToPreference(pref: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null) {
|
||||||
|
setSelection(pref.get() - offset)
|
||||||
|
this.pref = pref
|
||||||
|
prefOffset = offset
|
||||||
|
val popup = makeSettingsPopup(pref, prefOffset, block)
|
||||||
|
setOnTouchListener(popup.dragToOpenListener)
|
||||||
|
setOnClickListener {
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bindToIntPreference(pref: Preference<Int>, @ArrayRes intValuesResource: Int, block: ((Int) -> Unit)? = null) {
|
||||||
|
setSelection(pref.get())
|
||||||
|
this.pref = pref
|
||||||
|
prefOffset = 0
|
||||||
|
val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() }
|
||||||
|
val popup = makeSettingsPopup(pref, intValues, block)
|
||||||
|
setOnTouchListener(popup.dragToOpenListener)
|
||||||
|
setOnClickListener {
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeSettingsPopup(preference: Preference<Int>, intValues: List<Int?>, block: ((Int) -> Unit)? = null): PopupMenu {
|
||||||
|
val popup = popup()
|
||||||
|
// Set a listener so we are notified if a menu item is clicked
|
||||||
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
|
val pos = popup.menuClicked(menuItem)
|
||||||
|
preference.set(intValues[pos] ?: 0)
|
||||||
|
block?.invoke(pos)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
return popup
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeSettingsPopup(preference: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null): PopupMenu {
|
||||||
|
val popup = popup()
|
||||||
|
// Set a listener so we are notified if a menu item is clicked
|
||||||
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
|
val pos = popup.menuClicked(menuItem)
|
||||||
|
preference.set(pos + offset)
|
||||||
|
block?.invoke(pos)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
return popup
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeSettingsPopup(): PopupMenu {
|
||||||
|
val popup = popup()
|
||||||
|
|
||||||
|
// Set a listener so we are notified if a menu item is clicked
|
||||||
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
|
val pos = popup.menuClicked(menuItem)
|
||||||
|
onItemSelectedListener?.invoke(pos)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
return popup
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PopupMenu.menuClicked(menuItem: MenuItem): Int {
|
||||||
|
val pos = menuItem.itemId
|
||||||
|
menu[selectedPosition].isCheckable = false
|
||||||
|
menu[selectedPosition].isChecked = false
|
||||||
|
setSelection(pos)
|
||||||
|
menu[pos].isCheckable = true
|
||||||
|
menu[pos].isChecked = true
|
||||||
|
return pos
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun popup(): PopupMenu {
|
||||||
|
val popup = PopupMenu(context, this, Gravity.END)
|
||||||
|
entries.forEachIndexed { index, entry ->
|
||||||
|
popup.menu.add(0, index, 0, entry)
|
||||||
|
}
|
||||||
|
popup.menu[selectedPosition].isCheckable = true
|
||||||
|
popup.menu[selectedPosition].isChecked = true
|
||||||
|
return popup
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.reader.settings
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.ui.library.display.LibraryBadgesView
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
|
import eu.kanade.tachiyomi.util.view.visInvisIf
|
||||||
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
|
import eu.kanade.tachiyomi.util.view.visibleIf
|
||||||
|
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
||||||
|
import kotlinx.android.synthetic.main.reader_activity.*
|
||||||
|
import kotlinx.android.synthetic.main.reader_color_filter.view.*
|
||||||
|
import kotlinx.android.synthetic.main.recycler_with_scroller.view.*
|
||||||
|
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
||||||
|
|
||||||
|
class TabbedReaderSettingsSheet(val readerActivity: ReaderActivity): TabbedBottomSheetDialog(
|
||||||
|
readerActivity
|
||||||
|
) {
|
||||||
|
private val generalView: ReaderGeneralView = View.inflate(
|
||||||
|
readerActivity,
|
||||||
|
R.layout.reader_general_layout,
|
||||||
|
null
|
||||||
|
) as ReaderGeneralView
|
||||||
|
private val pagedView: ReaderPagedView = View.inflate(
|
||||||
|
readerActivity,
|
||||||
|
R.layout.reader_paged_layout,
|
||||||
|
null
|
||||||
|
) as ReaderPagedView
|
||||||
|
private val filterView: ReaderFilterView = View.inflate(
|
||||||
|
readerActivity,
|
||||||
|
R.layout.reader_color_filter,
|
||||||
|
null
|
||||||
|
) as ReaderFilterView
|
||||||
|
|
||||||
|
var showWebview: Boolean = {
|
||||||
|
val mangaViewer = readerActivity.presenter.getMangaViewer()
|
||||||
|
mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS
|
||||||
|
}()
|
||||||
|
|
||||||
|
override var offset = 0
|
||||||
|
|
||||||
|
override fun getTabViews(): List<View> = listOf(
|
||||||
|
generalView,
|
||||||
|
pagedView,
|
||||||
|
filterView
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getTabTitles(): List<Int> = listOf(
|
||||||
|
R.string.general,
|
||||||
|
if (showWebview) R.string.webtoon else R.string.paged,
|
||||||
|
R.string.filter
|
||||||
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
generalView.activity = readerActivity
|
||||||
|
pagedView.activity = readerActivity
|
||||||
|
filterView.activity = readerActivity
|
||||||
|
generalView.sheet = this
|
||||||
|
|
||||||
|
menu.gone()
|
||||||
|
val attrs = window?.attributes
|
||||||
|
val ogDim = attrs?.dimAmount ?: 0.25f
|
||||||
|
pager.adapter?.notifyDataSetChanged()
|
||||||
|
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||||
|
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||||
|
window?.setDimAmount(if (tab?.position == 2) 0f else ogDim)
|
||||||
|
val view = getTabViews()[tab?.position ?: 0]
|
||||||
|
view.settings_scroll_view?.isNestedScrollingEnabled = true
|
||||||
|
view.settings_scroll_view?.requestLayout()
|
||||||
|
readerActivity.appbar.visInvisIf(tab?.position != 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabUnselected(tab: TabLayout.Tab?) {
|
||||||
|
val view = getTabViews()[tab?.position ?: 0]
|
||||||
|
view.settings_scroll_view?.isNestedScrollingEnabled = false
|
||||||
|
view.settings_scroll_view?.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabReselected(tab: TabLayout.Tab?) {
|
||||||
|
val view = getTabViews()[tab?.position ?: 0]
|
||||||
|
view.settings_scroll_view?.isNestedScrollingEnabled = true
|
||||||
|
view.settings_scroll_view?.requestLayout()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dismiss() {
|
||||||
|
super.dismiss()
|
||||||
|
readerActivity.appbar.visible()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateTabs(isWebtoon: Boolean) {
|
||||||
|
showWebview = isWebtoon
|
||||||
|
pager.adapter?.notifyDataSetChanged()
|
||||||
|
pagedView.updatePrefs()
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,6 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
|
|||||||
var imagePropertyChangedListener: (() -> Unit)? = null
|
var imagePropertyChangedListener: (() -> Unit)? = null
|
||||||
|
|
||||||
var tappingEnabled = true
|
var tappingEnabled = true
|
||||||
var longTapEnabled = true
|
|
||||||
var doubleTapAnimDuration = 500
|
var doubleTapAnimDuration = 500
|
||||||
var volumeKeysEnabled = false
|
var volumeKeysEnabled = false
|
||||||
var volumeKeysInverted = false
|
var volumeKeysInverted = false
|
||||||
@ -28,9 +27,6 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
|
|||||||
preferences.readWithTapping()
|
preferences.readWithTapping()
|
||||||
.register({ tappingEnabled = it })
|
.register({ tappingEnabled = it })
|
||||||
|
|
||||||
preferences.readWithLongTap()
|
|
||||||
.register({ longTapEnabled = it })
|
|
||||||
|
|
||||||
preferences.doubleTapAnimSpeed()
|
preferences.doubleTapAnimSpeed()
|
||||||
.register({ doubleTapAnimDuration = it })
|
.register({ doubleTapAnimDuration = it })
|
||||||
|
|
||||||
|
@ -89,16 +89,6 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
|
|||||||
else -> activity.toggleMenu()
|
else -> activity.toggleMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pager.longTapListener = f@{
|
|
||||||
if (activity.menuVisible || config.longTapEnabled) {
|
|
||||||
val item = adapter.items.getOrNull(pager.currentItem)
|
|
||||||
if (item is ReaderPage) {
|
|
||||||
activity.onPageLongTap(item)
|
|
||||||
return@f true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
config.imagePropertyChangedListener = {
|
config.imagePropertyChangedListener = {
|
||||||
refreshAdapter()
|
refreshAdapter()
|
||||||
|
@ -106,20 +106,6 @@ class WebtoonViewer(val activity: ReaderActivity, val hasMargins: Boolean = fals
|
|||||||
else -> activity.toggleMenu()
|
else -> activity.toggleMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recycler.longTapListener = f@{ event ->
|
|
||||||
if (activity.menuVisible || config.longTapEnabled) {
|
|
||||||
val child = recycler.findChildViewUnder(event.x, event.y)
|
|
||||||
if (child != null) {
|
|
||||||
val position = recycler.getChildAdapterPosition(child)
|
|
||||||
val item = adapter.items.getOrNull(position)
|
|
||||||
if (item is ReaderPage) {
|
|
||||||
activity.onPageLongTap(item)
|
|
||||||
return@f true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
config.imagePropertyChangedListener = {
|
config.imagePropertyChangedListener = {
|
||||||
refreshAdapter()
|
refreshAdapter()
|
||||||
|
@ -188,11 +188,6 @@ class SettingsReaderController : SettingsController() {
|
|||||||
titleRes = R.string.tapping
|
titleRes = R.string.tapping
|
||||||
defaultValue = true
|
defaultValue = true
|
||||||
}
|
}
|
||||||
switchPreference {
|
|
||||||
key = Keys.readWithLongTap
|
|
||||||
titleRes = R.string.long_tap_dialog
|
|
||||||
defaultValue = true
|
|
||||||
}
|
|
||||||
switchPreference {
|
switchPreference {
|
||||||
key = Keys.readWithVolumeKeys
|
key = Keys.readWithVolumeKeys
|
||||||
titleRes = R.string.volume_keys
|
titleRes = R.string.volume_keys
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
package eu.kanade.tachiyomi.util
|
package eu.kanade.tachiyomi.util
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.widget.CompoundButton
|
||||||
|
import android.widget.RadioButton
|
||||||
|
import android.widget.RadioGroup
|
||||||
|
import android.widget.Spinner
|
||||||
|
import androidx.annotation.ArrayRes
|
||||||
|
import androidx.appcompat.widget.AppCompatSpinner
|
||||||
|
import com.f2prateek.rx.preferences.Preference
|
||||||
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
@ -40,3 +49,68 @@ inline fun <reified T> SharedPreferences.getItem(key: String, default: T): T {
|
|||||||
else -> throw IllegalArgumentException("Generic type not handled: ${T::class.java.name}")
|
else -> throw IllegalArgumentException("Generic type not handled: ${T::class.java.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a checkbox or switch view with a boolean preference.
|
||||||
|
*/
|
||||||
|
fun CompoundButton.bindToPreference(pref: Preference<Boolean>, block: (() -> Unit)? = null) {
|
||||||
|
isChecked = pref.getOrDefault()
|
||||||
|
setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
pref.set(isChecked)
|
||||||
|
block?.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a checkbox or switch view with a boolean preference.
|
||||||
|
*/
|
||||||
|
fun CompoundButton.bindToPreference(
|
||||||
|
pref: com.tfcporciuncula.flow
|
||||||
|
.Preference<Boolean>,
|
||||||
|
block: ((Boolean) -> Unit)? = null
|
||||||
|
) {
|
||||||
|
isChecked = pref.get()
|
||||||
|
setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
pref.set(isChecked)
|
||||||
|
block?.invoke(isChecked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a radio group with a int preference.
|
||||||
|
*/
|
||||||
|
fun RadioGroup.bindToPreference(pref: Preference<Int>, block: (() -> Unit)? = null) {
|
||||||
|
(getChildAt(pref.getOrDefault()) as RadioButton).isChecked = true
|
||||||
|
setOnCheckedChangeListener { _, checkedId ->
|
||||||
|
val index = indexOfChild(findViewById(checkedId))
|
||||||
|
pref.set(index)
|
||||||
|
block?.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a spinner to an int preference with an optional offset for the value.
|
||||||
|
*/
|
||||||
|
fun Spinner.bindToPreference(
|
||||||
|
pref: com.tfcporciuncula.flow.Preference<Int>,
|
||||||
|
offset: Int = 0
|
||||||
|
) {
|
||||||
|
onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
|
||||||
|
pref.set(position + offset)
|
||||||
|
}
|
||||||
|
setSelection(pref.get() - offset, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a spinner to an int preference. The position of the spinner item must
|
||||||
|
* correlate with the [intValues] resource item (in arrays.xml), which is a <string-array>
|
||||||
|
* of int values that will be parsed here and applied to the preference.
|
||||||
|
*/
|
||||||
|
fun Spinner.bindToIntPreference(pref: com.tfcporciuncula.flow.Preference<Int>, @ArrayRes intValuesResource: Int) {
|
||||||
|
val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() }
|
||||||
|
onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
|
||||||
|
pref.set(intValues[position] ?: 0)
|
||||||
|
}
|
||||||
|
setSelection(intValues.indexOf(pref.get()), false)
|
||||||
|
}
|
@ -1,27 +1,32 @@
|
|||||||
package eu.kanade.tachiyomi.widget
|
package eu.kanade.tachiyomi.widget
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||||
|
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||||
import eu.kanade.tachiyomi.util.view.expand
|
import eu.kanade.tachiyomi.util.view.expand
|
||||||
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
|
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
|
||||||
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
|
import kotlinx.android.synthetic.main.library_list_controller.*
|
||||||
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
|
||||||
|
|
||||||
|
|
||||||
abstract class TabbedBottomSheetDialog(private val controller: BaseController) :
|
abstract class TabbedBottomSheetDialog(private val activity: Activity) :
|
||||||
BottomSheetDialog
|
BottomSheetDialog
|
||||||
(controller.activity!!, R.style.BottomSheetDialogTheme) {
|
(activity, R.style.BottomSheetDialogTheme) {
|
||||||
|
|
||||||
private var sheetBehavior: BottomSheetBehavior<*>
|
private var sheetBehavior: BottomSheetBehavior<*>
|
||||||
|
|
||||||
val activity = controller.activity!!
|
open var offset = -1
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// Use activity theme for this layout
|
// Use activity theme for this layout
|
||||||
val view = activity.layoutInflater.inflate(R.layout.tabbed_bottom_sheet, null)
|
val view = activity.layoutInflater.inflate(R.layout.tabbed_bottom_sheet, null)
|
||||||
@ -29,7 +34,9 @@ abstract class TabbedBottomSheetDialog(private val controller: BaseController) :
|
|||||||
setContentView(view)
|
setContentView(view)
|
||||||
sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
|
sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
|
||||||
setEdgeToEdge(activity, view)
|
setEdgeToEdge(activity, view)
|
||||||
val height = activity.window.decorView.rootWindowInsets.systemWindowInsetBottom
|
|
||||||
|
val height = activity.window.decorView.rootWindowInsets.systemWindowInsetTop
|
||||||
|
pager.maxHeight = activity.window.decorView.height - height - 125.dpToPx
|
||||||
|
|
||||||
val adapter = TabbedSheetAdapter()
|
val adapter = TabbedSheetAdapter()
|
||||||
pager.offscreenPageLimit = 2
|
pager.offscreenPageLimit = 2
|
||||||
@ -41,6 +48,7 @@ abstract class TabbedBottomSheetDialog(private val controller: BaseController) :
|
|||||||
super.onStart()
|
super.onStart()
|
||||||
sheetBehavior.skipCollapsed = true
|
sheetBehavior.skipCollapsed = true
|
||||||
sheetBehavior.expand()
|
sheetBehavior.expand()
|
||||||
|
val height = activity.window.decorView.rootWindowInsets.systemWindowInsetTop
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun getTabViews(): List<View>
|
abstract fun getTabViews(): List<View>
|
||||||
@ -64,6 +72,13 @@ abstract class TabbedBottomSheetDialog(private val controller: BaseController) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null): ViewPager(context, attrs) {
|
class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null): ViewPager(context, attrs) {
|
||||||
|
|
||||||
|
var maxHeight = 0
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
var heightMeasureSpec = heightMeasureSpec
|
var heightMeasureSpec = heightMeasureSpec
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
@ -84,6 +99,9 @@ class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
if (height != 0) {
|
if (height != 0) {
|
||||||
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) + (rootWindowInsets?.systemWindowInsetBottom ?: 0)
|
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) + (rootWindowInsets?.systemWindowInsetBottom ?: 0)
|
||||||
}
|
}
|
||||||
|
if (maxHeight < height) {
|
||||||
|
heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST) + (rootWindowInsets?.systemWindowInsetBottom ?: 0)
|
||||||
|
}
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 76 KiB |
@ -2,7 +2,8 @@
|
|||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0"
|
||||||
|
android:tint="?attr/actionBarTintColor">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FF000000"
|
android:fillColor="#FF000000"
|
||||||
android:pathData="M18,2H6c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zM6,4h5v8l-2.5,-1.5L6,12V4z"/>
|
android:pathData="M18,2H6c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zM6,4h5v8l-2.5,-1.5L6,12V4z"/>
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?android:colorBackground"
|
|
||||||
android:baselineAligned="false"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/frame"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/scroll"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/scroll"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/scroll">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:src="@drawable/filter_mock" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/brightness_overlay"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView
|
|
||||||
android:id="@+id/color_overlay"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:id="@+id/scroll"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/frame">
|
|
||||||
|
|
||||||
<include layout="@layout/reader_color_filter" />
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,236 +1,245 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderFilterView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/constraint_layout"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/filter_bottom_sheet"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="16dp">
|
android:background="@drawable/bottom_sheet_rounded_background"
|
||||||
|
android:forceDarkAllowed="false">
|
||||||
|
|
||||||
<androidx.legacy.widget.Space
|
<androidx.core.widget.NestedScrollView
|
||||||
android:id="@+id/spinner_end"
|
android:id="@+id/settings_scroll_view"
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:layout_constraintStart_toEndOf="parent" />
|
|
||||||
|
|
||||||
<!-- Color filter -->
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
|
||||||
android:id="@+id/switch_color_filter"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/use_custom_color_filter"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<!-- Red filter -->
|
|
||||||
|
|
||||||
<SeekBar
|
|
||||||
android:id="@+id/seekbar_color_filter_red"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:max="255"
|
|
||||||
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/txt_color_filter_red_value"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/txt_color_filter_red_symbol"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/switch_color_filter" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txt_color_filter_red_symbol"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/red_initial"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_red"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_red" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txt_color_filter_red_value"
|
|
||||||
android:layout_width="30dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_red"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_red" />
|
|
||||||
|
|
||||||
<!-- Green filter -->
|
|
||||||
|
|
||||||
<SeekBar
|
|
||||||
android:id="@+id/seekbar_color_filter_green"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:max="255"
|
|
||||||
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/txt_color_filter_green_value"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/txt_color_filter_green_symbol"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_red" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txt_color_filter_green_symbol"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/green_initial"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_green"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_green" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txt_color_filter_green_value"
|
|
||||||
android:layout_width="30dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_green"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_green" />
|
|
||||||
|
|
||||||
<!-- Blue filter -->
|
|
||||||
|
|
||||||
<SeekBar
|
|
||||||
android:id="@+id/seekbar_color_filter_blue"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:max="255"
|
|
||||||
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/txt_color_filter_blue_value"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/txt_color_filter_blue_symbol"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_green" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txt_color_filter_blue_symbol"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/blue_initial"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_blue"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_blue" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txt_color_filter_blue_value"
|
|
||||||
android:layout_width="30dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_blue"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_blue" />
|
|
||||||
|
|
||||||
<!-- Alpha filter -->
|
|
||||||
|
|
||||||
<SeekBar
|
|
||||||
android:id="@+id/seekbar_color_filter_alpha"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:max="255"
|
|
||||||
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/txt_color_filter_alpha_value"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/txt_color_filter_alpha_symbol"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_blue" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txt_color_filter_alpha_symbol"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/alpha_initial"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_alpha"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_alpha" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txt_color_filter_alpha_value"
|
|
||||||
android:layout_width="30dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_alpha"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_alpha" />
|
|
||||||
|
|
||||||
<!-- Filter mode -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/color_filter_mode_text"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/color_filter_blend_mode"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/color_filter_mode"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/color_filter_mode"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/color_filter_mode"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:entries="@array/color_filter_modes"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_alpha" />
|
|
||||||
|
|
||||||
<!-- Brightness -->
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
|
||||||
android:id="@+id/custom_brightness"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:clipToPadding="false"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_height="wrap_content">
|
||||||
android:text="@string/use_custom_brightness"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/color_filter_mode_text" />
|
|
||||||
|
|
||||||
<!-- Brightness value -->
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraint_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="@dimen/material_component_dialogs_padding_around_content_area"
|
||||||
|
android:paddingTop="0dp"
|
||||||
|
android:paddingEnd="@dimen/material_component_dialogs_padding_around_content_area">
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.widget.NegativeSeekBar
|
<androidx.legacy.widget.Space
|
||||||
android:id="@+id/brightness_seekbar"
|
android:id="@+id/spinner_end"
|
||||||
android:layout_width="0dp"
|
android:layout_width="16dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_marginStart="8dp"
|
app:layout_constraintStart_toEndOf="parent" />
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/txt_brightness_seekbar_value"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/txt_brightness_seekbar_icon"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/custom_brightness"
|
|
||||||
app:max_seek="100"
|
|
||||||
app:min_seek="-75" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<!-- Color filter -->
|
||||||
android:id="@+id/txt_brightness_seekbar_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
|
||||||
android:tint="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/brightness_seekbar"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/brightness_seekbar"
|
|
||||||
app:srcCompat="@drawable/ic_brightness_day_24dp" />
|
|
||||||
|
|
||||||
<TextView
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
android:id="@+id/txt_brightness_seekbar_value"
|
android:id="@+id/switch_color_filter"
|
||||||
android:layout_width="30dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
android:text="@string/use_custom_color_filter"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/brightness_seekbar"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/brightness_seekbar" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
<!-- Red filter -->
|
||||||
android:id="@+id/bottom_line"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_percent="0.5" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
<SeekBar
|
||||||
|
android:id="@+id/seekbar_color_filter_red"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:max="255"
|
||||||
|
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/txt_color_filter_red_value"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/txt_color_filter_red_symbol"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/switch_color_filter" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_color_filter_red_symbol"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/red_initial"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_red"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_red" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_color_filter_red_value"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_red"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_red" />
|
||||||
|
|
||||||
|
<!-- Green filter -->
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekbar_color_filter_green"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:max="255"
|
||||||
|
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/txt_color_filter_green_value"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/txt_color_filter_green_symbol"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_red" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_color_filter_green_symbol"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/green_initial"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_green"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_color_filter_green_value"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_green"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_green" />
|
||||||
|
|
||||||
|
<!-- Blue filter -->
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekbar_color_filter_blue"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:max="255"
|
||||||
|
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/txt_color_filter_blue_value"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/txt_color_filter_blue_symbol"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_color_filter_blue_symbol"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/blue_initial"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_blue"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_blue" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_color_filter_blue_value"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_blue"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_blue" />
|
||||||
|
|
||||||
|
<!-- Alpha filter -->
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekbar_color_filter_alpha"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:max="255"
|
||||||
|
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/txt_color_filter_alpha_value"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/txt_color_filter_alpha_symbol"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_blue" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_color_filter_alpha_symbol"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/alpha_initial"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_alpha"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_alpha" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_color_filter_alpha_value"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_alpha"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/seekbar_color_filter_alpha" />
|
||||||
|
|
||||||
|
<!-- Filter mode -->
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPreferenceView
|
||||||
|
android:id="@+id/color_filter_mode"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:title="@string/color_filter_blend_mode"
|
||||||
|
android:entries="@array/color_filter_modes"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_alpha"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/spinner_end" />
|
||||||
|
|
||||||
|
<!-- Brightness -->
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
|
android:id="@+id/custom_brightness"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/use_custom_brightness"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/color_filter_mode" />
|
||||||
|
|
||||||
|
<!-- Brightness value -->
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.widget.NegativeSeekBar
|
||||||
|
android:id="@+id/brightness_seekbar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/txt_brightness_seekbar_value"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/txt_brightness_seekbar_icon"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/custom_brightness"
|
||||||
|
app:max_seek="100"
|
||||||
|
app:min_seek="-75" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/txt_brightness_seekbar_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
android:tint="?android:attr/textColorSecondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/brightness_seekbar"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/brightness_seekbar"
|
||||||
|
app:srcCompat="@drawable/ic_brightness_day_24dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txt_brightness_seekbar_value"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/brightness_seekbar"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/brightness_seekbar" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/bottom_line"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent="0.5" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</eu.kanade.tachiyomi.ui.reader.settings.ReaderFilterView>
|
@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
style="@style/BottomSheetDialogTheme"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@drawable/bottom_sheet_rounded_background"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="200dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:src="@drawable/filter_mock" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/brightness_overlay"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView
|
|
||||||
android:id="@+id/color_overlay"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<include layout="@layout/reader_color_filter" />
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
86
app/src/main/res/layout/reader_general_layout.xml
Normal file
86
app/src/main/res/layout/reader_general_layout.xml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderGeneralView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/filter_bottom_sheet"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bottom_sheet_rounded_background"
|
||||||
|
android:forceDarkAllowed="false">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/settings_scroll_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/constraint_layout"
|
||||||
|
style="@style/BottomSheetDialogTheme"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingStart="@dimen/material_component_dialogs_padding_around_content_area"
|
||||||
|
android:paddingTop="0dp"
|
||||||
|
android:paddingEnd="@dimen/material_component_dialogs_padding_around_content_area">
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPreferenceView
|
||||||
|
android:id="@+id/viewer_series"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
app:title="@string/viewer_for_this_series"
|
||||||
|
android:entries="@array/viewers_selector" />
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPreferenceView
|
||||||
|
android:id="@+id/rotation_mode"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
app:title="@string/rotation"
|
||||||
|
android:entries="@array/rotation_type" />
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPreferenceView
|
||||||
|
android:id="@+id/background_color"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
app:title="@string/background_color"
|
||||||
|
android:entries="@array/reader_themes" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/show_page_number"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/show_page_number"
|
||||||
|
android:textColor="?android:attr/textColorPrimary" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/fullscreen"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/fullscreen"
|
||||||
|
android:textColor="?android:attr/textColorPrimary" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/keepscreen"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/keep_screen_on"
|
||||||
|
android:textColor="?android:attr/textColorPrimary" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/always_show_chapter_transition"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/always_show_chapter_transition"
|
||||||
|
android:textColor="?android:attr/textColorPrimary" />
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</eu.kanade.tachiyomi.ui.reader.settings.ReaderGeneralView>
|
104
app/src/main/res/layout/reader_paged_layout.xml
Normal file
104
app/src/main/res/layout/reader_paged_layout.xml
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPagedView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/filter_bottom_sheet"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bottom_sheet_rounded_background"
|
||||||
|
android:forceDarkAllowed="false">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/settings_scroll_view"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="@dimen/material_component_dialogs_padding_around_content_area"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="0dp"
|
||||||
|
android:paddingEnd="@dimen/material_component_dialogs_padding_around_content_area">
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPreferenceView
|
||||||
|
android:id="@+id/scale_type"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
app:title="@string/scale_type"
|
||||||
|
android:entries="@array/image_scale_type" />
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPreferenceView
|
||||||
|
android:id="@+id/zoom_start"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
app:title="@string/zoom_start_position"
|
||||||
|
android:entries="@array/zoom_start" />
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/crop_borders"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/crop_borders"
|
||||||
|
android:textColor="?android:attr/textColorPrimary" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/page_transitions"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="0dp"
|
||||||
|
android:text="@string/page_transitions"
|
||||||
|
android:textColor="?android:attr/textColorPrimary" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Webtoon Prefs -->
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPreferenceView
|
||||||
|
android:id="@+id/webtoon_side_padding"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
app:title="@string/pref_webtoon_side_padding"
|
||||||
|
android:entries="@array/webtoon_side_padding" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/crop_borders_webtoon"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/crop_borders"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/webtoon_enable_zoom_out"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/enable_zoom_out"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/webtoon_side_padding" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Group
|
||||||
|
android:id="@+id/pager_prefs_group"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:constraint_referenced_ids="scale_type,zoom_start,crop_borders,page_transitions"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Group
|
||||||
|
android:id="@+id/webtoon_prefs_group"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:constraint_referenced_ids="crop_borders_webtoon,webtoon_side_padding,webtoon_enable_zoom_out" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</eu.kanade.tachiyomi.ui.reader.settings.ReaderPagedView>
|
61
app/src/main/res/layout/reader_preference.xml
Normal file
61
app/src/main/res/layout/reader_preference.xml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/square_ripple"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/title_view"
|
||||||
|
style="@style/TextAppearance.MaterialComponents.Body2"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
tools:text="Title"
|
||||||
|
android:maxLines="1" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/detail_view"
|
||||||
|
style="@style/TextAppearance.MaterialComponents.Body2"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLines="1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/start_barrier"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Details" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="1dp"
|
||||||
|
app:tint="?android:attr/textColorSecondary"
|
||||||
|
android:src="@drawable/ic_expand_more_24dp"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/detail_view"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/detail_view"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/detail_view"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Barrier
|
||||||
|
android:id="@+id/start_barrier"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:barrierDirection="right"
|
||||||
|
app:constraint_referenced_ids="bottom_line,title_view" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/bottom_line"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent="0.5" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,328 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/filter_bottom_sheet"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/bottom_sheet_rounded_background"
|
|
||||||
android:forceDarkAllowed="false">
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:id="@+id/settings_scroll_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/constraint_layout"
|
|
||||||
style="@style/BottomSheetDialogTheme"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingStart="@dimen/material_component_dialogs_padding_around_content_area"
|
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingEnd="@dimen/material_component_dialogs_padding_around_content_area">
|
|
||||||
|
|
||||||
<!-- General preferences -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/general_prefs"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/general"
|
|
||||||
android:textColor="?attr/colorAccent"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<androidx.legacy.widget.Space
|
|
||||||
android:id="@+id/spinner_end"
|
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_constraintStart_toEndOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/viewer_for_this_series"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/viewer"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/bottom_line"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/viewer"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:entries="@array/viewers_selector"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/general_prefs" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/rotation"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/rotation_mode"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/bottom_line"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/rotation_mode"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:entries="@array/rotation_type"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/viewer" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/background_color_label"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/background_color"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/background_color"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/background_color"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/background_color"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:entries="@array/reader_themes"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/rotation_mode" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/show_page_number"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/show_page_number"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/background_color" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/true_color"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="0dp"
|
|
||||||
android:text="@string/true_32bit_color"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/show_page_number"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/fullscreen"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="0dp"
|
|
||||||
android:text="@string/fullscreen"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/true_color" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/keepscreen"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="0dp"
|
|
||||||
android:text="@string/keep_screen_on"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/fullscreen" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/always_show_chapter_transition"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/always_show_chapter_transition"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/keepscreen" />
|
|
||||||
|
|
||||||
<androidx.legacy.widget.Space
|
|
||||||
android:id="@+id/end_general_preferences"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/always_show_chapter_transition" />
|
|
||||||
|
|
||||||
<!-- Pager preferences -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pager_prefs"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/paged"
|
|
||||||
android:textColor="?attr/colorAccent"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/end_general_preferences" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/zoom_start_text"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/scale_type"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/scale_type"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/bottom_line"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/scale_type"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:entries="@array/image_scale_type"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/pager_prefs" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/scale_type_text"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/zoom_start_position"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/zoom_start"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/bottom_line"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/zoom_start"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:entries="@array/zoom_start"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/scale_type" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/crop_borders"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/crop_borders"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/zoom_start" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/page_transitions"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="0dp"
|
|
||||||
android:text="@string/page_transitions"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/crop_borders" />
|
|
||||||
|
|
||||||
<!-- Webtoon preferences -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/webtoon_prefs"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/webtoon"
|
|
||||||
android:textColor="?attr/colorAccent"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/end_general_preferences" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/crop_borders_webtoon"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/crop_borders"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/webtoon_prefs" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/webtoon_side_padding_text"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/pref_webtoon_side_padding"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/webtoon_side_padding"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/bottom_line"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/webtoon_side_padding"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:entries="@array/webtoon_side_padding"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/spinner_end"
|
|
||||||
app:layout_constraintRight_toRightOf="@id/spinner_end"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/bottom_line"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/crop_borders_webtoon" />
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/webtoon_enable_zoom_out"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/enable_zoom_out"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/webtoon_side_padding" />
|
|
||||||
|
|
||||||
<!-- Groups of preferences -->
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Group
|
|
||||||
android:id="@+id/pager_prefs_group"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:constraint_referenced_ids="pager_prefs,scale_type,scale_type_text,
|
|
||||||
zoom_start_text,zoom_start,crop_borders,page_transitions,background_color,background_color_label,background_color_label,background_color"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Group
|
|
||||||
android:id="@+id/webtoon_prefs_group"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:constraint_referenced_ids="webtoon_prefs,crop_borders_webtoon,
|
|
||||||
webtoon_side_padding_text,webtoon_side_padding,webtoon_enable_zoom_out" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
|
||||||
android:id="@+id/bottom_line"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintGuide_percent="0.5" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/pill"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center|top"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
android:alpha="0.25"
|
|
||||||
android:contentDescription="@string/drag_handle"
|
|
||||||
android:src="@drawable/draggable_pill"
|
|
||||||
android:tint="?android:attr/textColorPrimary" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/close_button"
|
|
||||||
android:layout_width="32dp"
|
|
||||||
android:layout_height="32dp"
|
|
||||||
android:layout_gravity="end"
|
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:layout_marginEnd="12dp"
|
|
||||||
android:background="@drawable/round_ripple"
|
|
||||||
android:clickable="true"
|
|
||||||
android:contentDescription="@string/close"
|
|
||||||
android:focusable="true"
|
|
||||||
android:src="@drawable/ic_close_24dp"
|
|
||||||
android:tint="@color/gray_button" />
|
|
||||||
</FrameLayout>
|
|
@ -1,18 +1,42 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_custom_filter"
|
android:id="@+id/action_display_settings"
|
||||||
android:icon="@drawable/ic_brightness_night_24dp"
|
android:icon="@drawable/ic_tune_24dp"
|
||||||
android:title="@string/custom_filter"
|
android:title="@string/display_options"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_manga_details"
|
||||||
|
android:icon="@drawable/ic_book_24dp"
|
||||||
|
android:title="@string/details"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_share_page"
|
||||||
|
android:icon="@drawable/ic_share_24dp"
|
||||||
|
android:title="@string/share_page"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_save_page"
|
||||||
|
android:icon="@drawable/ic_save_24dp"
|
||||||
|
android:title="@string/save_page"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_set_page_as_cover"
|
||||||
|
android:icon="@drawable/ic_photo_24dp"
|
||||||
|
android:title="@string/set_page_as_cover"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_reader_settings"
|
||||||
android:icon="@drawable/ic_settings_24dp"
|
android:icon="@drawable/ic_settings_24dp"
|
||||||
android:title="@string/settings"
|
android:title="@string/reader_settings"
|
||||||
app:showAsAction="ifRoom"
|
app:showAsAction="never" />
|
||||||
/>
|
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -15,4 +15,10 @@
|
|||||||
<attr name="readerBackground" format="color"/>
|
<attr name="readerBackground" format="color"/>
|
||||||
<attr name="tabBarIconColor" format="reference|integer"/>
|
<attr name="tabBarIconColor" format="reference|integer"/>
|
||||||
<attr name="tabBarIconInactive" format="reference|integer"/>
|
<attr name="tabBarIconInactive" format="reference|integer"/>
|
||||||
|
|
||||||
|
<declare-styleable name="ReaderPreferenceView">
|
||||||
|
<attr name="title" format="reference|string"/>
|
||||||
|
<attr name="android:entries"/>
|
||||||
|
<attr name="summary" format="reference|string" />
|
||||||
|
</declare-styleable>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -278,6 +278,11 @@
|
|||||||
<!-- Reader -->
|
<!-- Reader -->
|
||||||
<string name="custom_filter">Custom filter</string>
|
<string name="custom_filter">Custom filter</string>
|
||||||
<string name="set_as_cover">Set as cover</string>
|
<string name="set_as_cover">Set as cover</string>
|
||||||
|
<string name="set_page_as_cover">Set page as cover</string>
|
||||||
|
<string name="share_page">Share page</string>
|
||||||
|
<string name="save_page">Save page</string>
|
||||||
|
<string name="_details">%1$s details</string>
|
||||||
|
<string name="reader_settings">Reader settings</string>
|
||||||
<string name="set_as_default_for_all">Set as default for all</string>
|
<string name="set_as_default_for_all">Set as default for all</string>
|
||||||
<string name="cover_updated">Cover updated</string>
|
<string name="cover_updated">Cover updated</string>
|
||||||
<string name="page_">Page %1$d</string>
|
<string name="page_">Page %1$d</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user