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:
Jays2Kings 2021-03-24 17:10:31 -04:00
parent 6b06833fee
commit fe2543b9d5
35 changed files with 1082 additions and 1076 deletions

View File

@ -49,8 +49,6 @@ object PreferenceKeys {
const val readWithTapping = "reader_tap"
const val readWithLongTap = "reader_long_tap"
const val readWithVolumeKeys = "reader_volume_keys"
const val readWithVolumeKeysInverted = "reader_volume_keys_inverted"

View File

@ -126,8 +126,6 @@ class PreferencesHelper(val context: Context) {
fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true)
fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true)
fun readWithVolumeKeys() = flowPrefs.getBoolean(Keys.readWithVolumeKeys, false)
fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)

View File

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context
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.*
class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context
import android.util.AttributeSet
import eu.kanade.tachiyomi.util.bindToPreference
import kotlinx.android.synthetic.main.library_category_layout.view.*
class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context
import android.util.AttributeSet
import eu.kanade.tachiyomi.util.bindToPreference
import kotlinx.android.synthetic.main.library_display_layout.view.*
class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :

View File

@ -25,42 +25,4 @@ abstract class LibraryPreferenceView @JvmOverloads constructor(context: Context,
super.onFinishInflate()
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()
}
}
}

View File

@ -12,7 +12,7 @@ import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
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 badgesView: LibraryBadgesView = inflate(controller.activity!!, R.layout.library_badges_layout, null) as LibraryBadgesView

View File

@ -693,6 +693,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
const val SHORTCUT_BROWSE = "eu.kanade.tachiyomi.SHOW_BROWSE"
const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS"
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 INTENT_SEARCH = "eu.kanade.tachiyomi.SEARCH"

View File

@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
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.util.view.gone
import eu.kanade.tachiyomi.util.view.withFadeTransaction
@ -35,7 +36,7 @@ class SearchActivity : MainActivity() {
}
private fun popToRoot() {
if (intent.action == SHORTCUT_MANGA) {
if (intent.action == SHORTCUT_MANGA || intent.action == SHORTCUT_READER_SETTINGS) {
onBackPressed()
} else if (!router.handleBack()) {
val intent = Intent(this, MainActivity::class.java).apply {
@ -97,6 +98,13 @@ class SearchActivity : MainActivity() {
.popChangeHandler(FadeChangeHandler())
)
}
SHORTCUT_READER_SETTINGS -> {
router.replaceTopController(
RouterTransaction.with(SettingsReaderController())
.pushChangeHandler(SimpleSwapChangeHandler())
.popChangeHandler(FadeChangeHandler())
)
}
else -> return false
}
return true
@ -112,5 +120,14 @@ class SearchActivity : MainActivity() {
action = SHORTCUT_MANGA
putExtra(MangaDetailsController.MANGA_EXTRA, id)
}
fun openReaderSettings(context: Context) = Intent(
context,
SearchActivity::class
.java
)
.apply {
action = SHORTCUT_READER_SETTINGS
}
}
}

View File

@ -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.ReaderPage
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.pager.L2RPagerViewer
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
@ -279,21 +280,46 @@ class ReaderActivity :
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
* entries.
*/
override fun onOptionsItemSelected(item: MenuItem): Boolean {
coroutine?.cancel()
bottomSheet = when (item.itemId) {
R.id.action_settings -> ReaderSettingsSheet(this)
R.id.action_custom_filter -> ReaderColorFilterSheet(this)
when (item.itemId) {
R.id.action_display_settings -> TabbedReaderSettingsSheet(this).show()
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)
}
bottomSheet?.show()
if (chapters_bottom_sheet.sheetBehavior.isExpanded()) {
chapters_bottom_sheet.sheetBehavior?.collapse()
}
return true
}
@ -357,13 +383,6 @@ class ReaderActivity :
popToMain()
}
toolbar.setOnClickListener {
presenter.manga?.id?.let { id ->
val intent = SearchActivity.openMangaIntent(this, id)
startActivity(intent)
}
}
// Init listeners on bottom menu
page_seekbar.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() {
@ -477,6 +496,7 @@ class ReaderActivity :
val prevViewer = viewer
val noDefault = manga.viewer == -1
val mangaViewer = presenter.getMangaViewer()
invalidateOptionsMenu()
val newViewer = when (mangaViewer) {
RIGHT_TO_LEFT -> R2LPagerViewer(this)
VERTICAL -> VerticalPagerViewer(this)
@ -615,41 +635,6 @@ class ReaderActivity :
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
* the viewer is reaching the beginning or end of a chapter or the transition page is active.

View File

@ -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)
}
}

View File

@ -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()
}
}

View File

@ -1,74 +1,44 @@
package eu.kanade.tachiyomi.ui.reader
package eu.kanade.tachiyomi.ui.reader.settings
import android.graphics.Color
import android.os.Build
import android.view.View
import android.view.ViewGroup
import android.content.Context
import android.util.AttributeSet
import android.widget.SeekBar
import androidx.annotation.ColorInt
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
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.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
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.onEach
import kotlinx.coroutines.flow.sample
import uy.kohesive.injekt.injectLazy
import kotlin.math.abs
/**
* Color filter sheet to toggle custom filter and brightness overlay.
*/
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)
class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView(context, attrs) {
override fun initGeneralPreferences() {
activity = context as ReaderActivity
settings_scroll_view.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
preferences.colorFilter().asFlow()
.onEach { setColorFilter(it, view) }
.onEach { setColorFilter(it) }
.launchIn(activity.scope)
preferences.colorFilterMode().asFlow()
.onEach { setColorFilter(preferences.colorFilter().get(), view) }
.onEach { setColorFilter(preferences.colorFilter().get()) }
.launchIn(activity.scope)
preferences.customBrightness().asFlow()
.onEach { setCustomBrightness(it, view) }
.onEach { setCustomBrightness(it) }
.launchIn(activity.scope)
// Get color and update values
val color = preferences.colorFilterValue().get()
val brightness = preferences.customBrightnessValue().get()
val argb = setValues(color, view)
val argb = setValues(color)
// Set brightness value
txt_brightness_seekbar_value.text = brightness.toString()
@ -91,14 +61,13 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
preferences.customBrightness().set(isChecked)
}
color_filter_mode.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
preferences.colorFilterMode().set(position)
}
color_filter_mode.setSelection(preferences.colorFilterMode().get(), false)
color_filter_mode.bindToPreference(preferences.colorFilterMode())
seekbar_color_filter_alpha.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() {
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) {
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
* @param enabled determines if seekBar gets enabled
* @param view view of the dialog
*/
private fun setColorFilterSeekBar(enabled: Boolean, view: View) = with(view) {
seekbar_color_filter_red.isEnabled = enabled
seekbar_color_filter_green.isEnabled = enabled
seekbar_color_filter_blue.isEnabled = enabled
private fun setColorFilterSeekBar(enabled: Boolean) {
seekbar_color_filter_red.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled
seekbar_color_filter_green.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled
seekbar_color_filter_blue.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled
seekbar_color_filter_alpha.isEnabled = enabled
}
/**
* Set enabled status of seekBars belonging to custom brightness
* @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
}
/**
* Set the text value's of color filter
* @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 red = getRedFromColor(color)
val green = getGreenFromColor(color)
@ -197,18 +158,17 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
/**
* Manages the custom brightness value subscription
* @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) {
preferences.customBrightnessValue().asFlow()
.sample(100)
.onEach { setCustomBrightnessValue(it, view) }
.onEach { setCustomBrightnessValue(it) }
.launchIn(activity.scope)
} 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.
* 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.
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) {
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 view view of the dialog
*/
private fun setColorFilter(enabled: Boolean, view: View) {
private fun setColorFilter(enabled: Boolean) {
if (enabled) {
preferences.colorFilterValue().asFlow()
.sample(100)
.onEach { setColorFilterValue(it, view) }
.onEach { setColorFilterValue(it) }
.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
* @param color hex of color.
* @param view view of the dialog
*/
private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) {
color_overlay.visible()
color_overlay.setFilterColor(color, preferences.colorFilterMode().get())
setValues(color, view)
private fun setColorFilterValue(@ColorInt color: Int) {
setValues(color)
}
/**
@ -290,15 +237,6 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
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
* @param color color hex as int
@ -322,3 +260,12 @@ class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheet
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
}

View File

@ -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)
}
}

View File

@ -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) }
}
}

View File

@ -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
}
}

View File

@ -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()
}
}

View File

@ -18,7 +18,6 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
var imagePropertyChangedListener: (() -> Unit)? = null
var tappingEnabled = true
var longTapEnabled = true
var doubleTapAnimDuration = 500
var volumeKeysEnabled = false
var volumeKeysInverted = false
@ -28,9 +27,6 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
preferences.readWithTapping()
.register({ tappingEnabled = it })
preferences.readWithLongTap()
.register({ longTapEnabled = it })
preferences.doubleTapAnimSpeed()
.register({ doubleTapAnimDuration = it })

View File

@ -89,16 +89,6 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
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 = {
refreshAdapter()

View File

@ -106,20 +106,6 @@ class WebtoonViewer(val activity: ReaderActivity, val hasMargins: Boolean = fals
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 = {
refreshAdapter()

View File

@ -188,11 +188,6 @@ class SettingsReaderController : SettingsController() {
titleRes = R.string.tapping
defaultValue = true
}
switchPreference {
key = Keys.readWithLongTap
titleRes = R.string.long_tap_dialog
defaultValue = true
}
switchPreference {
key = Keys.readWithVolumeKeys
titleRes = R.string.volume_keys

View File

@ -1,6 +1,15 @@
package eu.kanade.tachiyomi.util
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.ExperimentalCoroutinesApi
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}")
}
}
/**
* 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)
}

View File

@ -1,27 +1,32 @@
package eu.kanade.tachiyomi.widget
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.viewpager.widget.ViewPager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import eu.kanade.tachiyomi.R
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.setEdgeToEdge
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import kotlinx.android.synthetic.main.library_list_controller.*
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
abstract class TabbedBottomSheetDialog(private val controller: BaseController) :
abstract class TabbedBottomSheetDialog(private val activity: Activity) :
BottomSheetDialog
(controller.activity!!, R.style.BottomSheetDialogTheme) {
(activity, R.style.BottomSheetDialogTheme) {
private var sheetBehavior: BottomSheetBehavior<*>
val activity = controller.activity!!
open var offset = -1
init {
// Use activity theme for this layout
val view = activity.layoutInflater.inflate(R.layout.tabbed_bottom_sheet, null)
@ -29,7 +34,9 @@ abstract class TabbedBottomSheetDialog(private val controller: BaseController) :
setContentView(view)
sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
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()
pager.offscreenPageLimit = 2
@ -41,6 +48,7 @@ abstract class TabbedBottomSheetDialog(private val controller: BaseController) :
super.onStart()
sheetBehavior.skipCollapsed = true
sheetBehavior.expand()
val height = activity.window.decorView.rootWindowInsets.systemWindowInsetTop
}
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) {
var maxHeight = 0
set(value) {
field = value
requestLayout()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var heightMeasureSpec = heightMeasureSpec
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
@ -84,6 +99,9 @@ class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: Attri
if (height != 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)
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

View File

@ -2,7 +2,8 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
android:viewportHeight="24.0"
android:tint="?attr/actionBarTintColor">
<path
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"/>

View File

@ -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>

View File

@ -1,236 +1,245 @@
<?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"
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_height="wrap_content"
android:padding="16dp">
android:background="@drawable/bottom_sheet_rounded_background"
android:forceDarkAllowed="false">
<androidx.legacy.widget.Space
android:id="@+id/spinner_end"
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"
<androidx.core.widget.NestedScrollView
android:id="@+id/settings_scroll_view"
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_text" />
android:clipToPadding="false"
android:layout_height="wrap_content">
<!-- 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
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.legacy.widget.Space
android:id="@+id/spinner_end"
android:layout_width="16dp"
android:layout_height="0dp"
app:layout_constraintStart_toEndOf="parent" />
<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" />
<!-- Color filter -->
<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.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" />
<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" />
<!-- Red filter -->
</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>

View File

@ -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>

View 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>

View 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>

View 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>

View File

@ -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>

View File

@ -1,18 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<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
android:id="@+id/action_custom_filter"
android:icon="@drawable/ic_brightness_night_24dp"
android:title="@string/custom_filter"
android:id="@+id/action_display_settings"
android:icon="@drawable/ic_tune_24dp"
android:title="@string/display_options"
app:showAsAction="ifRoom" />
<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:title="@string/settings"
app:showAsAction="ifRoom"
/>
android:title="@string/reader_settings"
app:showAsAction="never" />
</menu>

View File

@ -15,4 +15,10 @@
<attr name="readerBackground" format="color"/>
<attr name="tabBarIconColor" 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>

View File

@ -278,6 +278,11 @@
<!-- Reader -->
<string name="custom_filter">Custom filter</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="cover_updated">Cover updated</string>
<string name="page_">Page %1$d</string>