More binding for library (and some reader) views

This commit is contained in:
Jays2Kings 2021-03-29 01:50:10 -04:00
parent e5405ac381
commit 028ed3ea1e
18 changed files with 284 additions and 277 deletions

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.util.AttributeSet
import com.google.android.material.card.MaterialCardView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.UnreadDownloadBadgeBinding
import eu.kanade.tachiyomi.util.system.contextCompatColor
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.gone
@ -11,11 +12,17 @@ import eu.kanade.tachiyomi.util.view.isVisible
import eu.kanade.tachiyomi.util.view.setTextColorRes
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.unread_download_badge.view.*
class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
MaterialCardView(context, attrs) {
private lateinit var binding: UnreadDownloadBadgeBinding
override fun onFinishInflate() {
super.onFinishInflate()
binding = UnreadDownloadBadgeBinding.bind(this)
}
fun setUnreadDownload(unread: Int, downloads: Int, showTotalChapters: Boolean) {
// Update the unread count and its visibility.
@ -23,7 +30,7 @@ class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeS
if (showTotalChapters) R.color.total_badge else R.color.unread_badge
)
with(unread_text) {
with(binding.unreadText) {
visibleIf(unread > 0 || unread == -1 || showTotalChapters)
if (!isVisible()) {
return@with
@ -41,7 +48,7 @@ class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeS
}
// Update the download count or local status and its visibility.
with(download_text) {
with(binding.downloadText) {
visibleIf(downloads == -2 || downloads > 0)
if (!isVisible()) { return@with }
text = if (downloads == -2) {
@ -52,18 +59,18 @@ class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeS
}
// Show the badge card if unread or downloads exists
visibleIf(download_text.isVisible() || unread_text.isVisible())
visibleIf(binding.downloadText.isVisible() || binding.unreadText.isVisible())
// Show the angles divider if both unread and downloads exists
unread_angle.visibleIf(download_text.isVisible() && unread_text.isVisible())
binding.unreadAngle.visibleIf(binding.downloadText.isVisible() && binding.unreadText.isVisible())
unread_angle.setColorFilter(unreadBadgeBackground)
if (unread_angle.isVisible()) {
download_text.updatePaddingRelative(end = 8.dpToPx)
unread_text.updatePaddingRelative(start = 2.dpToPx)
binding.unreadAngle.setColorFilter(unreadBadgeBackground)
if (binding.unreadAngle.isVisible()) {
binding.downloadText.updatePaddingRelative(end = 8.dpToPx)
binding.unreadText.updatePaddingRelative(start = 2.dpToPx)
} else {
download_text.updatePaddingRelative(end = 5.dpToPx)
unread_text.updatePaddingRelative(start = 5.dpToPx)
binding.downloadText.updatePaddingRelative(end = 5.dpToPx)
binding.unreadText.updatePaddingRelative(start = 5.dpToPx)
}
}
@ -73,9 +80,9 @@ class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeS
fun setInLibrary(inLibrary: Boolean) {
this.visibleIf(inLibrary)
unread_angle.gone()
unread_text.updatePaddingRelative(start = 5.dpToPx)
unread_text.visibleIf(inLibrary)
unread_text.text = resources.getText(R.string.in_library)
binding.unreadAngle.gone()
binding.unreadText.updatePaddingRelative(start = 5.dpToPx)
binding.unreadText.visibleIf(inLibrary)
binding.unreadText.text = resources.getText(R.string.in_library)
}
}

View File

@ -9,10 +9,9 @@ import coil.size.Precision
import coil.size.Scale
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.image.coil.loadLibraryManga
import eu.kanade.tachiyomi.databinding.MangaGridItemBinding
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.manga_grid_item.*
import kotlinx.android.synthetic.main.unread_download_badge.*
/**
* Class used to hold the displayed data of a manga in the library, like the cover or the title.
@ -31,19 +30,20 @@ class LibraryGridHolder(
private var fixedSize: Boolean
) : LibraryHolder(view, adapter) {
private val binding = MangaGridItemBinding.bind(view)
init {
play_layout.setOnClickListener { playButtonClicked() }
binding.playLayout.setOnClickListener { playButtonClicked() }
if (compact) {
text_layout.gone()
binding.textLayout.gone()
} else {
compact_title.gone()
gradient.gone()
val playLayout = play_layout.layoutParams as FrameLayout.LayoutParams
val buttonLayout = play_button.layoutParams as FrameLayout.LayoutParams
binding.compactTitle.gone()
binding.gradient.gone()
val playLayout = binding.playLayout.layoutParams as FrameLayout.LayoutParams
val buttonLayout = binding.playButton.layoutParams as FrameLayout.LayoutParams
playLayout.gravity = Gravity.BOTTOM or Gravity.END
buttonLayout.gravity = Gravity.BOTTOM or Gravity.END
play_layout.layoutParams = playLayout
play_button.layoutParams = buttonLayout
binding.playLayout.layoutParams = playLayout
binding.playButton.layoutParams = buttonLayout
}
}
@ -55,19 +55,19 @@ class LibraryGridHolder(
*/
override fun onSetValues(item: LibraryItem) {
// Update the title and subtitle of the manga.
constraint_layout.visibleIf(!item.manga.isBlank())
title.text = item.manga.title
subtitle.text = item.manga.author?.trim()
binding.constraintLayout.visibleIf(!item.manga.isBlank())
binding.title.text = item.manga.title
binding.subtitle.text = item.manga.author?.trim()
compact_title.text = title.text
binding.compactTitle.text = binding.title.text
setUnreadBadge(badge_view, item)
setUnreadBadge(binding.unreadDownloadBadge.badgeView, item)
setReadingButton(item)
// Update the cover.
if (item.manga.thumbnail_url == null) cover_thumbnail.clear()
if (item.manga.thumbnail_url == null) binding.coverThumbnail.clear()
else {
if (cover_thumbnail.height == 0) {
if (binding.coverThumbnail.height == 0) {
val oldPos = flexibleAdapterPosition
adapter.recyclerView.post {
if (oldPos == flexibleAdapterPosition) {
@ -80,7 +80,7 @@ class LibraryGridHolder(
private fun setCover(manga: Manga) {
if ((adapter.recyclerView.context as? Activity)?.isDestroyed == true) return
cover_thumbnail.loadLibraryManga(manga) {
binding.coverThumbnail.loadLibraryManga(manga) {
if (!fixedSize) {
precision(Precision.INEXACT)
scale(Scale.FIT)
@ -95,14 +95,14 @@ class LibraryGridHolder(
override fun onActionStateChanged(position: Int, actionState: Int) {
super.onActionStateChanged(position, actionState)
if (actionState == 2) {
card.isDragged = true
badge_view.isDragged = true
binding.card.isDragged = true
binding.unreadDownloadBadge.badgeView.isDragged = true
}
}
override fun onItemReleased(position: Int) {
super.onItemReleased(position)
card.isDragged = false
badge_view.isDragged = false
binding.card.isDragged = false
binding.unreadDownloadBadge.badgeView.isDragged = false
}
}

View File

@ -4,9 +4,6 @@ import android.app.Activity
import android.graphics.Color
import android.util.TypedValue
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.github.florent37.viewtooltip.ViewTooltip
@ -15,6 +12,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.LibraryCategoryHeaderItemBinding
import eu.kanade.tachiyomi.source.icon
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
@ -25,39 +23,32 @@ import eu.kanade.tachiyomi.util.view.invisible
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.library_category_header_item.*
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAdapter) :
BaseFlexibleViewHolder(view, adapter, true) {
private val sectionText: TextView = view.findViewById(R.id.category_title)
private val sortText: TextView = view.findViewById(R.id.category_sort)
private val updateButton: ImageView = view.findViewById(R.id.update_button)
private val checkboxImage: ImageView = view.findViewById(R.id.checkbox)
private val expandImage: ImageView = view.findViewById(R.id.collapse_arrow)
private val catProgress: ProgressBar = view.findViewById(R.id.cat_progress)
private val binding = LibraryCategoryHeaderItemBinding.bind(view)
init {
category_header_layout.setOnClickListener { toggleCategory() }
updateButton.setOnClickListener { addCategoryToUpdate() }
sectionText.setOnLongClickListener {
binding.categoryHeaderLayout.setOnClickListener { toggleCategory() }
binding.updateButton.setOnClickListener { addCategoryToUpdate() }
binding.categoryTitle.setOnLongClickListener {
val category = (adapter.getItem(flexibleAdapterPosition) as? LibraryHeaderItem)?.category
adapter.libraryListener.manageCategory(flexibleAdapterPosition)
category?.isDynamic == false
}
sectionText.setOnClickListener { toggleCategory() }
sortText.setOnClickListener { it.post { showCatSortOptions() } }
checkboxImage.setOnClickListener { selectAll() }
updateButton.drawable.mutate()
binding.categoryTitle.setOnClickListener { toggleCategory() }
binding.categorySort.setOnClickListener { it.post { showCatSortOptions() } }
binding.checkbox.setOnClickListener { selectAll() }
binding.updateButton.drawable.mutate()
}
private fun toggleCategory() {
adapter.libraryListener.toggleCategoryVisibility(flexibleAdapterPosition)
val tutorial = Injekt.get<PreferencesHelper>().shownLongPressCategoryTutorial()
if (!tutorial.get()) {
ViewTooltip.on(itemView.context as? Activity, sectionText).autoHide(true, 5000L)
ViewTooltip.on(itemView.context as? Activity, binding.categoryTitle).autoHide(true, 5000L)
.align(ViewTooltip.ALIGN.START).position(ViewTooltip.Position.TOP)
.text(R.string.long_press_category)
.color(itemView.context.getResourceColor(R.attr.colorAccent))
@ -78,7 +69,7 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
false
}
val shorterMargin = adapter.headerItems.firstOrNull() == item
sectionText.updateLayoutParams<ConstraintLayout.LayoutParams> {
binding.categoryTitle.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = (
when {
shorterMargin -> 2
@ -90,21 +81,21 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
val category = item.category
if (category.isDynamic) {
category_header_layout.background = null
sectionText.background = null
binding.categoryHeaderLayout.background = null
binding.categoryTitle.background = null
} else {
category_header_layout.setBackgroundResource(R.drawable.list_item_selector)
sectionText.setBackgroundResource(R.drawable.square_ripple)
binding.categoryHeaderLayout.setBackgroundResource(R.drawable.list_item_selector)
binding.categoryTitle.setBackgroundResource(R.drawable.square_ripple)
}
if (category.isAlone && !category.isDynamic) sectionText.text = ""
else sectionText.text = category.name
if (category.isAlone && !category.isDynamic) binding.categoryTitle.text = ""
else binding.categoryTitle.text = category.name
if (category.sourceId != null) {
val icon = adapter.sourceManager.get(category.sourceId!!)?.icon()
icon?.setBounds(0, 0, 32.dpToPx, 32.dpToPx)
sectionText.setCompoundDrawablesRelative(icon, null, null, null)
binding.categoryTitle.setCompoundDrawablesRelative(icon, null, null, null)
} else {
sectionText.setCompoundDrawablesRelative(null, null, null, null)
binding.categoryTitle.setCompoundDrawablesRelative(null, null, null, null)
}
val isAscending = category.isAscending()
@ -115,45 +106,45 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
else -> R.drawable.ic_arrow_upward_24dp
}
sortText.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, sortDrawable, 0)
sortText.setText(category.sortRes())
expandImage.setImageResource(
binding.categorySort.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, sortDrawable, 0)
binding.categorySort.setText(category.sortRes())
binding.collapseArrow.setImageResource(
if (category.isHidden) R.drawable.ic_expand_more_24dp
else R.drawable.ic_expand_less_24dp
)
when {
adapter.mode == SelectableAdapter.Mode.MULTI -> {
checkboxImage.visibleIf(!category.isHidden)
expandImage.visibleIf(category.isHidden && !adapter.isSingleCategory && !category.isDynamic)
updateButton.gone()
catProgress.gone()
binding.checkbox.visibleIf(!category.isHidden)
binding.collapseArrow.visibleIf(category.isHidden && !adapter.isSingleCategory && !category.isDynamic)
binding.updateButton.gone()
binding.catProgress.gone()
setSelection()
}
category.id ?: -1 < 0 -> {
expandImage.gone()
checkboxImage.gone()
catProgress.gone()
updateButton.gone()
binding.collapseArrow.gone()
binding.checkbox.gone()
binding.catProgress.gone()
binding.updateButton.gone()
}
LibraryUpdateService.categoryInQueue(category.id) -> {
expandImage.visibleIf(!adapter.isSingleCategory && !category.isDynamic)
checkboxImage.gone()
catProgress.visible()
updateButton.invisible()
binding.collapseArrow.visibleIf(!adapter.isSingleCategory && !category.isDynamic)
binding.checkbox.gone()
binding.catProgress.visible()
binding.updateButton.invisible()
}
else -> {
expandImage.visibleIf(!adapter.isSingleCategory && !category.isDynamic)
catProgress.gone()
checkboxImage.gone()
updateButton.visibleIf(!adapter.isSingleCategory)
binding.collapseArrow.visibleIf(!adapter.isSingleCategory && !category.isDynamic)
binding.catProgress.gone()
binding.checkbox.gone()
binding.updateButton.visibleIf(!adapter.isSingleCategory)
}
}
}
private fun addCategoryToUpdate() {
if (adapter.libraryListener.updateCategory(flexibleAdapterPosition)) {
catProgress.visible()
updateButton.invisible()
binding.catProgress.visible()
binding.updateButton.invisible()
}
}
@ -278,7 +269,7 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
else R.color.gray_button
)
)
checkboxImage.setImageDrawable(tintedDrawable)
binding.checkbox.setImageDrawable(tintedDrawable)
}
override fun onLongClick(view: View?): Boolean {

View File

@ -5,22 +5,19 @@ import android.view.ViewGroup
import coil.api.clear
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.image.coil.loadLibraryManga
import eu.kanade.tachiyomi.databinding.MangaListItemBinding
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.manga_list_item.*
import kotlinx.android.synthetic.main.manga_list_item.view.*
import kotlinx.android.synthetic.main.unread_download_badge.*
/**
* Class used to hold the displayed data of a manga in the library, like the cover or the title.
* Class used to hold the displayed data of a manga in the library, like the cover or the binding.title.
* All the elements from the layout file "item_library_list" are available in this class.
*
* @param view the inflated view for this holder.
* @param adapter the adapter handling this holder.
* @param listener a listener to react to single tap and long tap events.
* @constructor creates a new library holder.
*/
@ -29,6 +26,8 @@ class LibraryListHolder(
adapter: LibraryCategoryAdapter
) : LibraryHolder(view, adapter) {
private val binding = MangaListItemBinding.bind(view)
/**
* Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this
* holder with the given manga.
@ -36,62 +35,62 @@ class LibraryListHolder(
* @param item the manga item to bind.
*/
override fun onSetValues(item: LibraryItem) {
title.visible()
constraint_layout.minHeight = 56.dpToPx
binding.title.visible()
binding.constraintLayout.minHeight = 56.dpToPx
if (item.manga.isBlank()) {
constraint_layout.minHeight = 0
constraint_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
binding.constraintLayout.minHeight = 0
binding.constraintLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = ViewGroup.MarginLayoutParams.WRAP_CONTENT
}
if (item.manga.status == -1) {
title.text = null
title.gone()
binding.title.text = null
binding.title.gone()
} else {
title.text = itemView.context.getString(R.string.category_is_empty)
binding.title.text = itemView.context.getString(R.string.category_is_empty)
}
title.textAlignment = View.TEXT_ALIGNMENT_CENTER
card.gone()
badge_view.gone()
padding.gone()
subtitle.gone()
binding.title.textAlignment = View.TEXT_ALIGNMENT_CENTER
binding.card.gone()
binding.unreadDownloadBadge.badgeView.gone()
binding.padding.gone()
binding.subtitle.gone()
return
}
constraint_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
binding.constraintLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = 52.dpToPx
}
padding.visible()
card.visible()
title.textAlignment = View.TEXT_ALIGNMENT_TEXT_START
binding.padding.visible()
binding.card.visible()
binding.title.textAlignment = View.TEXT_ALIGNMENT_TEXT_START
// Update the title of the manga.
title.text = item.manga.title
setUnreadBadge(badge_view, item)
// Update the binding.title of the manga.
binding.title.text = item.manga.title
setUnreadBadge(binding.unreadDownloadBadge.badgeView, item)
subtitle.text = item.manga.author?.trim()
title.post {
if (title?.text == item.manga.title) {
subtitle.visibleIf(title.lineCount == 1 && !item.manga.author.isNullOrBlank())
binding.subtitle.text = item.manga.author?.trim()
binding.title.post {
if (binding.title.text == item.manga.title) {
binding.subtitle.visibleIf(binding.title.lineCount == 1 && !item.manga.author.isNullOrBlank())
}
}
// Update the cover.
if (item.manga.thumbnail_url == null) {
cover_thumbnail.clear()
binding.coverThumbnail.clear()
} else {
val id = item.manga.id ?: return
cover_thumbnail.loadLibraryManga(item.manga)
item.manga.id ?: return
binding.coverThumbnail.loadLibraryManga(item.manga)
}
}
override fun onActionStateChanged(position: Int, actionState: Int) {
super.onActionStateChanged(position, actionState)
if (actionState == 2) {
view.card.isDragged = true
binding.card.isDragged = true
}
}
override fun onItemReleased(position: Int) {
super.onItemReleased(position)
view.card.isDragged = false
binding.card.isDragged = false
}
}

View File

@ -2,21 +2,23 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context
import android.util.AttributeSet
import eu.kanade.tachiyomi.databinding.LibraryBadgesLayoutBinding
import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView
import kotlinx.android.synthetic.main.library_badges_layout.view.*
class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseLibraryDisplayView(context, attrs) {
BaseLibraryDisplayView<LibraryBadgesLayoutBinding>(context, attrs) {
override fun inflateBinding() = LibraryBadgesLayoutBinding.bind(this)
override fun initGeneralPreferences() {
unread_badge_group.bindToPreference(preferences.unreadBadgeType()) {
binding.unreadBadgeGroup.bindToPreference(preferences.unreadBadgeType()) {
controller.presenter.requestUnreadBadgesUpdate()
}
hide_reading.bindToPreference(preferences.hideStartReadingButton()) {
binding.hideReading.bindToPreference(preferences.hideStartReadingButton()) {
controller.reattachAdapter()
}
download_badge.bindToPreference(preferences.downloadBadge()) {
binding.downloadBadge.bindToPreference(preferences.downloadBadge()) {
controller.presenter.requestDownloadBadgesUpdate()
}
}

View File

@ -2,29 +2,30 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context
import android.util.AttributeSet
import eu.kanade.tachiyomi.databinding.LibraryCategoryLayoutBinding
import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView
import kotlinx.android.synthetic.main.library_category_layout.view.*
class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseLibraryDisplayView(context, attrs) {
BaseLibraryDisplayView<LibraryCategoryLayoutBinding>(context, attrs) {
override fun inflateBinding() = LibraryCategoryLayoutBinding.bind(this)
override fun initGeneralPreferences() {
show_all.bindToPreference(preferences.showAllCategories()) {
binding.showAll.bindToPreference(preferences.showAllCategories()) {
controller.presenter.getLibrary()
category_show.isEnabled = it
binding.categoryShow.isEnabled = it
}
category_show.isEnabled = show_all.isChecked
category_show.bindToPreference(preferences.showCategoryInTitle()) {
binding.categoryShow.isEnabled = binding.showAll.isChecked
binding.categoryShow.bindToPreference(preferences.showCategoryInTitle()) {
controller.showMiniBar()
}
hide_hopper.bindToPreference(preferences.hideHopper()) {
binding.hideHopper.bindToPreference(preferences.hideHopper()) {
controller.hideHopper(it)
}
auto_hide_hopper.bindToPreference(preferences.autohideHopper()) {
binding.autoHideHopper.bindToPreference(preferences.autohideHopper()) {
controller.resetHopperY()
}
add_categories_button.setOnClickListener {
binding.addCategoriesButton.setOnClickListener {
controller.showCategoriesController()
}
}

View File

@ -2,21 +2,22 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context
import android.util.AttributeSet
import eu.kanade.tachiyomi.databinding.LibraryDisplayLayoutBinding
import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView
import kotlinx.android.synthetic.main.library_display_layout.view.*
class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseLibraryDisplayView(context, attrs) {
BaseLibraryDisplayView<LibraryDisplayLayoutBinding>(context, attrs) {
override fun inflateBinding() = LibraryDisplayLayoutBinding.bind(this)
override fun initGeneralPreferences() {
display_group.bindToPreference(preferences.libraryLayout()) {
binding.displayGroup.bindToPreference(preferences.libraryLayout()) {
controller.reattachAdapter()
}
uniform_grid.bindToPreference(preferences.uniformGrid()) {
binding.uniformGrid.bindToPreference(preferences.uniformGrid()) {
controller.reattachAdapter()
}
grid_size_toggle_group.bindToPreference(preferences.gridSize()) {
binding.gridSizeToggleGroup.bindToPreference(preferences.gridSize()) {
controller.reattachAdapter()
}
}

View File

@ -9,7 +9,6 @@ import eu.kanade.tachiyomi.ui.setting.SettingsLibraryController
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.withFadeTransaction
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
TabbedBottomSheetDialog(controller.activity!!) {
@ -22,17 +21,17 @@ open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
displayView.controller = controller
badgesView.controller = controller
categoryView.controller = controller
menu.visible()
binding.menu.visible()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
menu.tooltipText = context.getString(R.string.more_library_settings)
binding.menu.tooltipText = context.getString(R.string.more_library_settings)
}
menu.setImageDrawable(
binding.menu.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.ic_settings_24dp
)
)
menu.setOnClickListener {
binding.menu.setOnClickListener {
controller.router.pushController(SettingsLibraryController().withFadeTransaction())
dismiss()
}

View File

@ -18,11 +18,12 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.databinding.FilterBottomSheetBinding
import eu.kanade.tachiyomi.ui.library.LibraryController
import eu.kanade.tachiyomi.ui.library.LibraryGroup
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.view.activityBinding
import eu.kanade.tachiyomi.util.view.collapse
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.hide
@ -31,12 +32,6 @@ import eu.kanade.tachiyomi.util.view.isExpanded
import eu.kanade.tachiyomi.util.view.isHidden
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.filter_bottom_sheet.view.*
import kotlinx.android.synthetic.main.library_grid_recycler.*
import kotlinx.android.synthetic.main.library_list_controller.*
import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
import kotlinx.android.synthetic.main.track_item.*
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
@ -58,6 +53,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
*/
private val preferences: PreferencesHelper by injectLazy()
private lateinit var binding: FilterBottomSheetBinding
private val trackManager: TrackManager by injectLazy()
private val hasTracking
@ -100,23 +97,28 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
var controller: LibraryController? = null
var bottomBarHeight = 0
override fun onFinishInflate() {
super.onFinishInflate()
binding = FilterBottomSheetBinding.bind(this)
}
fun onCreate(controller: LibraryController) {
clearButton = clear_button
filter_layout.removeView(clearButton)
clearButton = binding.clearButton
binding.filterLayout.removeView(clearButton)
sheetBehavior = BottomSheetBehavior.from(this)
sheetBehavior?.isHideable = true
this.controller = controller
libraryRecyler = controller.recycler
libraryRecyler = controller.binding.libraryGridRecycler.recycler
libraryRecyler?.post {
bottomBarHeight = (this@FilterBottomSheet.controller?.activity as? MainActivity)?.bottom_nav?.height ?: 0
bottomBarHeight = controller.activityBinding?.bottomNav?.height ?: 0
}
val shadow2: View = controller.shadow2
val shadow: View = controller.shadow
val shadow2: View = controller.binding.shadow2
val shadow: View = controller.binding.shadow
sheetBehavior?.addBottomSheetCallback(
object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, progress: Float) {
this@FilterBottomSheet.controller?.updateFilterSheetY()
pill.alpha = (1 - max(0f, progress)) * 0.25f
binding.pill.alpha = (1 - max(0f, progress)) * 0.25f
shadow2.alpha = (1 - max(0f, progress)) * 0.25f
shadow.alpha = 1 + min(0f, progress)
updateRootPadding(progress)
@ -130,29 +132,26 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
)
post {
second_layout ?: return@post
first_layout ?: return@post
view_options ?: return@post
if (second_layout.width + first_layout.width + 20.dpToPx < width) {
second_layout.removeView(view_options)
second_layout.removeView(reorder_filters)
first_layout.addView(reorder_filters)
first_layout.addView(view_options)
second_layout.gone()
if (binding.secondLayout.width + binding.firstLayout.width + 20.dpToPx < width) {
binding.secondLayout.removeView(binding.viewOptions)
binding.secondLayout.removeView(binding.reorderFilters)
binding.firstLayout.addView(binding.reorderFilters)
binding.firstLayout.addView(binding.viewOptions)
binding.secondLayout.gone()
}
}
sheetBehavior?.hide()
expand_categories.setOnClickListener {
binding.expandCategories.setOnClickListener {
onGroupClicked(ACTION_EXPAND_COLLAPSE_ALL)
}
group_by.setOnClickListener {
binding.groupBy.setOnClickListener {
onGroupClicked(ACTION_GROUP_BY)
}
view_options.setOnClickListener {
binding.viewOptions.setOnClickListener {
onGroupClicked(ACTION_DISPLAY)
}
reorder_filters.setOnClickListener {
binding.reorderFilters.setOnClickListener {
manageFilterPopup()
}
@ -178,14 +177,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
fun setExpandText(expand: Boolean) {
expand_categories.setText(
binding.expandCategories.setText(
if (expand) {
R.string.expand_all_categories
} else {
R.string.collapse_all_categories
}
)
expand_categories.setIconResource(
binding.expandCategories.setIconResource(
if (expand) {
R.drawable.ic_expand_less_24dp
} else {
@ -195,14 +194,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
private fun stateChanged(state: Int) {
val shadow = controller?.shadow ?: return
val shadow = controller?.binding?.shadow ?: return
controller?.updateHopperY()
if (state == BottomSheetBehavior.STATE_COLLAPSED) {
shadow.alpha = 1f
libraryRecyler?.updatePaddingRelative(bottom = sheetBehavior?.peekHeight ?: 0 + 10.dpToPx + bottomBarHeight)
}
if (state == BottomSheetBehavior.STATE_EXPANDED) {
pill.alpha = 0f
binding.pill.alpha = 0f
}
if (state == BottomSheetBehavior.STATE_HIDDEN) {
onGroupClicked(ACTION_HIDE_FILTER_TIP)
@ -328,7 +327,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
serviceNames.getOrNull(2)
)
if (tracked?.isActivated == true) {
filter_layout.addView(trackers)
binding.filterLayout.addView(trackers)
filterItems.add(trackers!!)
trackers?.setState(FILTER_TRACKER)
reSortViews()
@ -457,15 +456,15 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
val hasFilters = hasActiveFilters()
if (hasFilters && clearButton.parent == null) {
filter_layout.addView(clearButton, 0)
binding.filterLayout.addView(clearButton, 0)
} else if (!hasFilters && clearButton.parent != null) {
filter_layout.removeView(clearButton)
binding.filterLayout.removeView(clearButton)
}
if (tracked?.isActivated == true && trackers != null && trackers?.parent == null) {
filter_layout.addView(trackers, filterItems.indexOf(tracked!!) + 2)
binding.filterLayout.addView(trackers, filterItems.indexOf(tracked!!) + 2)
filterItems.add(filterItems.indexOf(tracked!!) + 1, trackers!!)
} else if (tracked?.isActivated == false && trackers?.parent != null) {
filter_layout.removeView(trackers)
binding.filterLayout.removeView(trackers)
trackers?.reset()
FILTER_TRACKER = ""
filterItems.remove(trackers!!)
@ -473,8 +472,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
fun updateButtons(showExpand: Boolean, groupType: Int) {
expand_categories.visibleIf(showExpand && groupType == 0)
group_by.setIconResource(LibraryGroup.groupTypeDrawableRes(groupType))
binding.expandCategories.visibleIf(showExpand && groupType == 0)
binding.groupBy.setIconResource(LibraryGroup.groupTypeDrawableRes(groupType))
}
private fun clearFilters() {
@ -487,7 +486,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
val transition = androidx.transition.AutoTransition()
transition.duration = 150
androidx.transition.TransitionManager.beginDelayedTransition(filter_layout, transition)
androidx.transition.TransitionManager.beginDelayedTransition(binding.filterLayout, transition)
reorderFilters()
filterItems.forEach {
it.reset()
@ -500,17 +499,17 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
private fun reSortViews() {
filter_layout.removeAllViews()
binding.filterLayout.removeAllViews()
if (filterItems.any { it.isActivated }) {
filter_layout.addView(clearButton)
binding.filterLayout.addView(clearButton)
}
filterItems.filter { it.isActivated }.forEach {
filter_layout.addView(it)
binding.filterLayout.addView(it)
}
filterItems.filterNot { it.isActivated }.forEach {
filter_layout.addView(it)
binding.filterLayout.addView(it)
}
filter_scroll.scrollTo(0, 0)
binding.filterScroll.scrollTo(0, 0)
}
companion object {

View File

@ -6,9 +6,9 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.CategoriesItemBinding
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.util.view.gone
import kotlinx.android.synthetic.main.categories_item.*
/**
* Category item for a recycler view.
@ -74,15 +74,16 @@ class ManageFilterItem(val char: Char) : AbstractFlexibleItem<ManageFilterItem.H
class Holder(val view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) :
BaseFlexibleViewHolder(view, adapter, true) {
private val binding = CategoriesItemBinding.bind(view)
init {
image.gone()
edit_button.gone()
edit_text.isEnabled = false
setDragHandleView(reorder)
binding.image.gone()
binding.editButton.gone()
binding.editText.isEnabled = false
setDragHandleView(binding.reorder)
}
fun bind(char: Char) {
title.setText(
binding.title.setText(
when (char) {
'u' -> R.string.read_progress
'r' -> R.string.unread

View File

@ -4,21 +4,20 @@ import android.content.Context
import android.util.AttributeSet
import android.widget.SeekBar
import androidx.annotation.ColorInt
import eu.kanade.tachiyomi.databinding.ReaderColorFilterBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
import kotlinx.android.synthetic.main.reader_color_filter.*
import kotlinx.android.synthetic.main.reader_color_filter.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
class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView(context, attrs) {
BaseReaderSettingsView<ReaderColorFilterBinding>(context, attrs) {
override fun inflateBinding() = ReaderColorFilterBinding.bind(this)
override fun initGeneralPreferences() {
activity = context as ReaderActivity
activity = context as? ReaderActivity ?: return
preferences.colorFilter().asFlow()
.onEach { setColorFilter(it) }
.launchIn(activity.scope)
@ -38,33 +37,33 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
val argb = setValues(color)
// Set brightness value
txt_brightness_seekbar_value.text = brightness.toString()
brightness_seekbar.progress = brightness
binding.txtBrightnessSeekbarValue.text = brightness.toString()
binding.brightnessSeekbar.progress = brightness
// Initialize seekBar progress
seekbar_color_filter_alpha.progress = argb[0]
seekbar_color_filter_red.progress = argb[1]
seekbar_color_filter_green.progress = argb[2]
seekbar_color_filter_blue.progress = argb[3]
binding.seekbarColorFilterAlpha.progress = argb[0]
binding.seekbarColorFilterRed.progress = argb[1]
binding.seekbarColorFilterGreen.progress = argb[2]
binding.seekbarColorFilterBlue.progress = argb[3]
// Set listeners
switch_color_filter.isChecked = preferences.colorFilter().get()
switch_color_filter.setOnCheckedChangeListener { _, isChecked ->
binding.switchColorFilter.isChecked = preferences.colorFilter().get()
binding.switchColorFilter.setOnCheckedChangeListener { _, isChecked ->
preferences.colorFilter().set(isChecked)
}
custom_brightness.isChecked = preferences.customBrightness().get()
custom_brightness.setOnCheckedChangeListener { _, isChecked ->
binding.customBrightness.isChecked = preferences.customBrightness().get()
binding.customBrightness.setOnCheckedChangeListener { _, isChecked ->
preferences.customBrightness().set(isChecked)
}
color_filter_mode.bindToPreference(preferences.colorFilterMode())
seekbar_color_filter_alpha.setOnSeekBarChangeListener(
binding.colorFilterMode.bindToPreference(preferences.colorFilterMode())
binding.seekbarColorFilterAlpha.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
binding.seekbarColorFilterRed.isEnabled = value > 0 && binding.seekbarColorFilterAlpha.isEnabled
binding.seekbarColorFilterGreen.isEnabled = value > 0 && binding.seekbarColorFilterAlpha.isEnabled
binding.seekbarColorFilterBlue.isEnabled = value > 0 && binding.seekbarColorFilterAlpha.isEnabled
if (fromUser) {
setColorValue(value, ALPHA_MASK, 24)
}
@ -72,7 +71,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
}
)
seekbar_color_filter_red.setOnSeekBarChangeListener(
binding.seekbarColorFilterRed.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) {
@ -82,7 +81,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
}
)
seekbar_color_filter_green.setOnSeekBarChangeListener(
binding.seekbarColorFilterGreen.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) {
@ -92,7 +91,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
}
)
seekbar_color_filter_blue.setOnSeekBarChangeListener(
binding.seekbarColorFilterBlue.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) {
@ -102,7 +101,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
}
)
brightness_seekbar.setOnSeekBarChangeListener(
binding.brightnessSeekbar.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) {
@ -118,10 +117,10 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
* @param enabled determines if seekBar gets 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
binding.seekbarColorFilterRed.isEnabled = binding.seekbarColorFilterAlpha.progress > 0 && enabled
binding.seekbarColorFilterGreen.isEnabled = binding.seekbarColorFilterAlpha.progress > 0 && enabled
binding.seekbarColorFilterBlue.isEnabled = binding.seekbarColorFilterAlpha.progress > 0 && enabled
binding.seekbarColorFilterAlpha.isEnabled = enabled
}
/**
@ -129,7 +128,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
* @param enabled value which determines if seekBar gets enabled
*/
private fun setCustomBrightnessSeekBar(enabled: Boolean) {
brightness_seekbar.isEnabled = enabled
binding.brightnessSeekbar.isEnabled = enabled
}
/**
@ -143,10 +142,10 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
val blue = getBlueFromColor(color)
// Initialize values
txt_color_filter_alpha_value.text = alpha.toString()
txt_color_filter_red_value.text = red.toString()
txt_color_filter_green_value.text = green.toString()
txt_color_filter_blue_value.text = blue.toString()
binding.txtColorFilterAlphaValue.text = alpha.toString()
binding.txtColorFilterRedValue.text = red.toString()
binding.txtColorFilterGreenValue.text = green.toString()
binding.txtColorFilterBlueValue.text = blue.toString()
return arrayOf(alpha, red, green, blue)
}
@ -176,7 +175,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
private fun setCustomBrightnessValue(value: Int, isDisabled: Boolean = false) {
// Set black overlay visibility.
if (!isDisabled) {
txt_brightness_seekbar_value.text = value.toString()
binding.txtBrightnessSeekbarValue.text = value.toString()
}
}

View File

@ -2,17 +2,18 @@ package eu.kanade.tachiyomi.ui.reader.settings
import android.content.Context
import android.util.AttributeSet
import eu.kanade.tachiyomi.databinding.ReaderGeneralLayoutBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
import kotlinx.android.synthetic.main.reader_general_layout.view.*
class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView(context, attrs) {
BaseReaderSettingsView<ReaderGeneralLayoutBinding>(context, attrs) {
lateinit var sheet: TabbedReaderSettingsSheet
override fun inflateBinding() = ReaderGeneralLayoutBinding.bind(this)
override fun initGeneralPreferences() {
viewer_series.onItemSelectedListener = { position ->
binding.viewerSeries.onItemSelectedListener = { position ->
activity.presenter.setMangaViewer(position)
val mangaViewer = activity.presenter.getMangaViewer()
@ -22,13 +23,13 @@ class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: Attri
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())
binding.viewerSeries.setSelection((context as? ReaderActivity)?.presenter?.manga?.viewer ?: 0)
binding.rotationMode.bindToPreference(preferences.rotation(), 1)
binding.backgroundColor.bindToPreference(preferences.readerTheme(), 0)
binding.showPageNumber.bindToPreference(preferences.showPageNumber())
binding.fullscreen.bindToPreference(preferences.fullscreen())
binding.keepscreen.bindToPreference(preferences.keepScreenOn())
binding.alwaysShowChapterTransition.bindToPreference(preferences.alwaysShowChapterTransition())
}
/**

View File

@ -5,36 +5,37 @@ import android.content.Context
import android.util.AttributeSet
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.ReaderPagedLayoutBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.util.view.visibleIf
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
import kotlinx.android.synthetic.main.reader_paged_layout.view.*
class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView(context, attrs) {
BaseReaderSettingsView<ReaderPagedLayoutBinding>(context, attrs) {
override fun inflateBinding() = ReaderPagedLayoutBinding.bind(this)
override fun initGeneralPreferences() {
scale_type.bindToPreference(preferences.imageScaleType(), 1) {
binding.scaleType.bindToPreference(preferences.imageScaleType(), 1) {
val mangaViewer = (context as? ReaderActivity)?.presenter?.getMangaViewer() ?: 0
val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS
updatePagedGroup(!isWebtoonView)
}
zoom_start.bindToPreference(preferences.zoomStart(), 1)
crop_borders.bindToPreference(preferences.cropBorders())
page_transitions.bindToPreference(preferences.pageTransitions())
pager_nav.bindToPreference(preferences.navigationModePager())
pager_invert.bindToPreference(preferences.pagerNavInverted())
extend_past_cutout.bindToPreference(preferences.pagerCutoutBehavior())
binding.zoomStart.bindToPreference(preferences.zoomStart(), 1)
binding.cropBorders.bindToPreference(preferences.cropBorders())
binding.pageTransitions.bindToPreference(preferences.pageTransitions())
binding.pagerNav.bindToPreference(preferences.navigationModePager())
binding.pagerInvert.bindToPreference(preferences.pagerNavInverted())
binding.extendPastCutout.bindToPreference(preferences.pagerCutoutBehavior())
val mangaViewer = (context as? ReaderActivity)?.presenter?.getMangaViewer() ?: 0
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())
webtoon_nav.bindToPreference(preferences.navigationModeWebtoon())
webtoon_invert.bindToPreference(preferences.webtoonNavInverted())
binding.cropBordersWebtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon())
binding.webtoonSidePadding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
binding.webtoonEnableZoomOut.bindToPreference(preferences.webtoonEnableZoomOut())
binding.webtoonNav.bindToPreference(preferences.navigationModeWebtoon())
binding.webtoonInvert.bindToPreference(preferences.webtoonNavInverted())
updatePagedGroup(!isWebtoonView)
}
@ -43,13 +44,13 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
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())
binding.cropBordersWebtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon())
updatePagedGroup(!isWebtoonView)
}
private fun updatePagedGroup(show: Boolean) {
listOf(scale_type, zoom_start, crop_borders, page_transitions, pager_nav, pager_invert).forEach { it.visibleIf(show) }
listOf(crop_borders_webtoon, webtoon_side_padding, webtoon_enable_zoom_out, webtoon_nav, webtoon_invert).forEach { it.visibleIf(!show) }
listOf(binding.scaleType, binding.zoomStart, binding.cropBorders, binding.pageTransitions, binding.pagerNav, binding.pagerInvert).forEach { it.visibleIf(show) }
listOf(binding.cropBordersWebtoon, binding.webtoonSidePadding, binding.webtoonEnableZoomOut, binding.webtoonNav, binding.webtoonInvert).forEach { it.visibleIf(!show) }
val isFullFit = when (preferences.imageScaleType().get()) {
SubsamplingScaleImageView.SCALE_TYPE_FIT_HEIGHT,
SubsamplingScaleImageView.SCALE_TYPE_SMART_FIT,
@ -62,6 +63,6 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
} else {
false
}
extend_past_cutout.visibleIf(show && isFullFit && hasCutout)
binding.extendPastCutout.visibleIf(show && isFullFit && hasCutout)
}
}

View File

@ -3,35 +3,39 @@ package eu.kanade.tachiyomi.widget
import android.content.Context
import android.util.AttributeSet
import androidx.core.widget.NestedScrollView
import androidx.viewbinding.ViewBinding
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.library.LibraryController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import uy.kohesive.injekt.injectLazy
abstract class BaseTabbedScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
abstract class BaseTabbedScrollView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
NestedScrollView(context, attrs) {
protected lateinit var binding: VB
init {
clipToPadding = false
}
internal val preferences by injectLazy<PreferencesHelper>()
abstract fun initGeneralPreferences()
abstract fun inflateBinding(): VB
override fun onFinishInflate() {
super.onFinishInflate()
binding = inflateBinding()
setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
initGeneralPreferences()
}
}
abstract class BaseLibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseTabbedScrollView(context, attrs) {
abstract class BaseLibraryDisplayView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseTabbedScrollView<VB>(context, attrs) {
lateinit var controller: LibraryController
}
abstract class BaseReaderSettingsView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseTabbedScrollView(context, attrs) {
abstract class BaseReaderSettingsView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseTabbedScrollView<VB>(context, attrs) {
lateinit var activity: ReaderActivity
}

View File

@ -11,10 +11,10 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.tabs.TabLayout
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.TabbedBottomSheetBinding
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.expand
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
import kotlin.math.max
abstract class TabbedBottomSheetDialog(private val activity: Activity) :
@ -22,30 +22,29 @@ abstract class TabbedBottomSheetDialog(private val activity: Activity) :
(activity, R.style.BottomSheetDialogTheme) {
private var sheetBehavior: BottomSheetBehavior<*>
protected val binding = TabbedBottomSheetBinding.inflate(activity.layoutInflater)
open var offset = -1
init {
// Use activity theme for this layout
val view = activity.layoutInflater.inflate(R.layout.tabbed_bottom_sheet, null)
setContentView(view)
sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
setEdgeToEdge(activity, view)
setContentView(binding.root)
sheetBehavior = BottomSheetBehavior.from(binding.root.parent as ViewGroup)
setEdgeToEdge(activity, binding.root)
val height = activity.window.decorView.rootWindowInsets.systemWindowInsetTop
pager.maxHeight = activity.window.decorView.height - height - 125.dpToPx
binding.pager.maxHeight = activity.window.decorView.height - height - 125.dpToPx
val adapter = TabbedSheetAdapter()
pager.offscreenPageLimit = 2
pager.adapter = adapter
tabs.setupWithViewPager(pager)
binding.pager.offscreenPageLimit = 2
binding.pager.adapter = adapter
binding.tabs.setupWithViewPager(binding.pager)
}
override fun onStart() {
super.onStart()
sheetBehavior.skipCollapsed = true
sheetBehavior.expand()
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
binding.tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
val view = getTabViews()[tab?.position ?: 0] as? NestedScrollView
view?.isNestedScrollingEnabled = true
@ -95,8 +94,8 @@ class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: Attri
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var heightMeasureSpec = heightMeasureSpec
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
var heightSpec = heightMeasureSpec
super.onMeasure(widthMeasureSpec, heightSpec)
var height = 0
val childWidthSpec = MeasureSpec.makeMeasureSpec(
max(
@ -113,11 +112,11 @@ class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: Attri
if (h > height) height = h
}
if (height != 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
}
if (maxHeight < height + (rootWindowInsets?.systemWindowInsetBottom ?: 0)) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)
heightSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightSpec)
}
}

View File

@ -61,7 +61,7 @@
android:contentDescription="@string/start_reading"
android:padding="6dp"
android:src="@drawable/ic_start_reading_24dp"
android:tint="@android:color/white" />
app:tint="@android:color/white" />
</FrameLayout>
@ -110,6 +110,7 @@
<include
layout="@layout/unread_download_badge"
android:id="@+id/unread_download_badge"
android:layout_width="wrap_content"
android:layout_marginStart="1dp"
android:layout_height="wrap_content"

View File

@ -91,6 +91,7 @@
tools:text="Manga artist" />
<include layout="@layout/unread_download_badge"
android:id="@+id/unread_download_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"

View File

@ -20,6 +20,7 @@
android:id="@+id/spinner_end"
android:layout_width="16dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="parent" />
<!-- Color filter -->