UI improvements
parent
7c4b254f08
commit
265fbc9f63
@ -0,0 +1,126 @@
|
||||
package org.koitharu.kotatsu.details.ui
|
||||
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.slider.LabelFormatter
|
||||
import com.google.android.material.slider.Slider
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet
|
||||
import org.koitharu.kotatsu.core.util.ext.setValueRounded
|
||||
import org.koitharu.kotatsu.core.util.progress.IntPercentLabelFormatter
|
||||
import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesSheet.Companion.TAB_CHAPTERS
|
||||
import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesSheet.Companion.TAB_PAGES
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class ChapterPagesMenuProvider(
|
||||
private val viewModel: DetailsViewModel,
|
||||
private val sheet: BaseAdaptiveSheet<*>,
|
||||
private val pager: ViewPager2,
|
||||
private val settings: AppSettings,
|
||||
) : OnBackPressedCallback(false), MenuProvider, SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener,
|
||||
Slider.OnChangeListener {
|
||||
|
||||
private var expandedItemRef: WeakReference<MenuItem>? = null
|
||||
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
val tab = getCurrentTab()
|
||||
when (tab) {
|
||||
TAB_CHAPTERS -> {
|
||||
menuInflater.inflate(R.menu.opt_chapters, menu)
|
||||
menu.findItem(R.id.action_search)?.run {
|
||||
setOnActionExpandListener(this@ChapterPagesMenuProvider)
|
||||
(actionView as? SearchView)?.setupChaptersSearchView()
|
||||
}
|
||||
menu.findItem(R.id.action_search)?.isVisible = viewModel.isChaptersEmpty.value == false
|
||||
menu.findItem(R.id.action_reversed)?.isChecked = viewModel.isChaptersReversed.value == true
|
||||
menu.findItem(R.id.action_grid_view)?.isChecked = viewModel.isChaptersInGridView.value == true
|
||||
}
|
||||
|
||||
TAB_PAGES -> {
|
||||
menuInflater.inflate(R.menu.opt_pages, menu)
|
||||
menu.findItem(R.id.action_grid_size)?.run {
|
||||
setOnActionExpandListener(this@ChapterPagesMenuProvider)
|
||||
(actionView as? Slider)?.setupPagesSizeSlider()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) {
|
||||
R.id.action_reversed -> {
|
||||
viewModel.setChaptersReversed(!menuItem.isChecked)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_grid_view -> {
|
||||
viewModel.setChaptersInGridView(!menuItem.isChecked)
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
override fun handleOnBackPressed() {
|
||||
expandedItemRef?.get()?.collapseActionView()
|
||||
}
|
||||
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||
expandedItemRef = WeakReference(item)
|
||||
sheet.expandAndLock()
|
||||
isEnabled = true
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||
expandedItemRef = null
|
||||
isEnabled = false
|
||||
(item.actionView as? SearchView)?.setQuery("", false)
|
||||
viewModel.performChapterSearch(null)
|
||||
sheet.unlock()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextSubmit(query: String?): Boolean = false
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
viewModel.performChapterSearch(newText)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
settings.gridSizePages = value.toInt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun SearchView.setupChaptersSearchView() {
|
||||
setOnQueryTextListener(this@ChapterPagesMenuProvider)
|
||||
setIconifiedByDefault(false)
|
||||
queryHint = context.getString(R.string.search_chapters)
|
||||
}
|
||||
|
||||
private fun Slider.setupPagesSizeSlider() {
|
||||
valueFrom = 50f
|
||||
valueTo = 150f
|
||||
stepSize = 5f
|
||||
isTickVisible = false
|
||||
labelBehavior = LabelFormatter.LABEL_FLOATING
|
||||
setLabelFormatter(IntPercentLabelFormatter(context))
|
||||
setValueRounded(settings.gridSizePages.toFloat())
|
||||
addOnChangeListener(this@ChapterPagesMenuProvider)
|
||||
}
|
||||
|
||||
private fun getCurrentTab(): Int {
|
||||
var page = pager.currentItem
|
||||
if (page > 0 && pager.adapter?.itemCount == 2) { // no Pages page
|
||||
page++ // shift
|
||||
}
|
||||
return page
|
||||
}
|
||||
}
|
||||
@ -1,75 +0,0 @@
|
||||
package org.koitharu.kotatsu.details.ui
|
||||
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.view.MenuProvider
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class ChaptersMenuProvider2(
|
||||
private val viewModel: DetailsViewModel,
|
||||
private val sheet: BaseAdaptiveSheet<*>,
|
||||
) : OnBackPressedCallback(false), MenuProvider, SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener {
|
||||
|
||||
private var searchItemRef: WeakReference<MenuItem>? = null
|
||||
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.opt_chapters, menu)
|
||||
val searchMenuItem = menu.findItem(R.id.action_search)
|
||||
searchMenuItem.setOnActionExpandListener(this)
|
||||
val searchView = searchMenuItem.actionView as SearchView
|
||||
searchView.setOnQueryTextListener(this)
|
||||
searchView.setIconifiedByDefault(false)
|
||||
searchView.queryHint = searchMenuItem.title
|
||||
searchItemRef = WeakReference(searchMenuItem)
|
||||
}
|
||||
|
||||
override fun onPrepareMenu(menu: Menu) {
|
||||
menu.findItem(R.id.action_search)?.isVisible = viewModel.isChaptersEmpty.value == false
|
||||
menu.findItem(R.id.action_reversed)?.isChecked = viewModel.isChaptersReversed.value == true
|
||||
menu.findItem(R.id.action_grid_view)?.isChecked = viewModel.isChaptersInGridView.value == true
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) {
|
||||
R.id.action_reversed -> {
|
||||
viewModel.setChaptersReversed(!menuItem.isChecked)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_grid_view -> {
|
||||
viewModel.setChaptersInGridView(!menuItem.isChecked)
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
override fun handleOnBackPressed() {
|
||||
searchItemRef?.get()?.collapseActionView()
|
||||
}
|
||||
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||
sheet.expandAndLock()
|
||||
isEnabled = true
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||
isEnabled = false
|
||||
(item.actionView as? SearchView)?.setQuery("", false)
|
||||
viewModel.performChapterSearch(null)
|
||||
sheet.unlock()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextSubmit(query: String?): Boolean = false
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
viewModel.performChapterSearch(newText)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package org.koitharu.kotatsu.details.ui.pager.pages
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.koitharu.kotatsu.R
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class PagesGridSpanResolver(
|
||||
resources: Resources,
|
||||
) : View.OnLayoutChangeListener {
|
||||
|
||||
var spanCount = 3
|
||||
private set
|
||||
|
||||
private val gridWidth = resources.getDimension(R.dimen.preferred_grid_width)
|
||||
private val spacing = resources.getDimension(R.dimen.grid_spacing)
|
||||
private var cellWidth = -1f
|
||||
|
||||
override fun onLayoutChange(
|
||||
v: View?,
|
||||
left: Int,
|
||||
top: Int,
|
||||
right: Int,
|
||||
bottom: Int,
|
||||
oldLeft: Int,
|
||||
oldTop: Int,
|
||||
oldRight: Int,
|
||||
oldBottom: Int,
|
||||
) {
|
||||
if (cellWidth <= 0f) {
|
||||
return
|
||||
}
|
||||
val rv = v as? RecyclerView ?: return
|
||||
val width = abs(right - left)
|
||||
if (width == 0) {
|
||||
return
|
||||
}
|
||||
resolveGridSpanCount(width)
|
||||
(rv.layoutManager as? GridLayoutManager)?.spanCount = spanCount
|
||||
}
|
||||
|
||||
fun setGridSize(scaleFactor: Float, rv: RecyclerView) {
|
||||
cellWidth = (gridWidth * scaleFactor) + spacing
|
||||
val lm = rv.layoutManager as? GridLayoutManager ?: return
|
||||
val innerWidth = lm.width - lm.paddingEnd - lm.paddingStart
|
||||
if (innerWidth > 0) {
|
||||
resolveGridSpanCount(innerWidth)
|
||||
lm.spanCount = spanCount
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveGridSpanCount(width: Int) {
|
||||
val estimatedCount = (width / cellWidth).roundToInt()
|
||||
spanCount = estimatedCount.coerceAtLeast(2)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M12 18.88A1 1 0 0 1 11.71 19.71A1 1 0 0 1 10.3 19.71L6.3 15.71A1 1 0 0 1 6 14.87V9.75L1.21 3.62A1 1 0 0 1 1.38 2.22A1 1 0 0 1 2 2H16A1 1 0 0 1 16.62 2.22A1 1 0 0 1 16.79 3.62L12 9.75V18.88M4 4L8 9.06V14.58L10 16.58V9.05L14 4M13 16L18 21L23 16Z" />
|
||||
</vector>
|
||||
@ -0,0 +1,14 @@
|
||||
<?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">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_grid_size"
|
||||
android:icon="@drawable/ic_size_large"
|
||||
android:orderInCategory="10"
|
||||
android:title="@string/grid_size"
|
||||
app:actionViewClass="com.google.android.material.slider.Slider"
|
||||
app:showAsAction="ifRoom|collapseActionView" />
|
||||
|
||||
</menu>
|
||||
Loading…
Reference in New Issue