From 0cf56ca335536b500a17a0018344fdb93fe0362b Mon Sep 17 00:00:00 2001 From: Jays2Kings Date: Fri, 16 Apr 2021 22:59:55 -0400 Subject: [PATCH] Using a seekbar to select grid size This is mostly the same amount of options for phones, but opens more for tablets There's also actual math now for setting the grid size and a float used (rounded to the nearest .25) I could just add back portrait/landscape per row....I could but This seeker also has a bubble tooltip to show the current value, might use elsewhere later --- .../java/eu/kanade/tachiyomi/Migrations.kt | 19 ++ .../data/preference/PreferenceKeys.kt | 2 +- .../data/preference/PreferencesHelper.kt | 2 +- .../tachiyomi/ui/library/LibraryController.kt | 15 +- .../ui/library/display/LibraryDisplayView.kt | 103 ++++++++++- .../display/TabbedLibraryDisplaySheet.kt | 1 - .../source/browse/BrowseSourceController.kt | 8 +- .../tachiyomi/util/view/ViewExtensions.kt | 16 ++ .../tachiyomi/widget/AutofitRecyclerView.kt | 13 ++ .../res/drawable/ic_rounded_tooltip_24dp.xml | 9 + .../res/layout/library_display_layout.xml | 174 ++++++++++-------- app/src/main/res/layout/tooltip_text_view.xml | 13 ++ app/src/main/res/values/strings.xml | 4 +- 13 files changed, 281 insertions(+), 98 deletions(-) create mode 100644 app/src/main/res/drawable/ic_rounded_tooltip_24dp.xml create mode 100644 app/src/main/res/layout/tooltip_text_view.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt index b4a97664e6..2ee8803f47 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt @@ -110,6 +110,25 @@ object Migrations { remove("enable_doh") } } + + val oldGridSize = prefs.getInt("grid_size", -1) + // Migrate to float for grid size + if (oldGridSize != -1) { + prefs.edit { + putFloat( + PreferenceKeys.gridSize, + when (oldGridSize) { + 4 -> 3f + 3 -> 1.5f + 2 -> 1f + 1 -> 0f + 0 -> -.5f + else -> .5f + } + ) + remove("grid_size") + } + } } return true } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index 58d97903c0..b91ce7e426 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -150,7 +150,7 @@ object PreferenceKeys { const val libraryLayout = "pref_display_library_layout" - const val gridSize = "grid_size" + const val gridSize = "grid_size_float" const val uniformGrid = "uniform_grid" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index ff18bb112f..8105ea5fdf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -242,7 +242,7 @@ class PreferencesHelper(val context: Context) { fun libraryLayout() = flowPrefs.getInt(Keys.libraryLayout, 2) - fun gridSize() = flowPrefs.getInt(Keys.gridSize, 2) + fun gridSize() = flowPrefs.getFloat(Keys.gridSize, 1f) fun uniformGrid() = flowPrefs.getBoolean(Keys.uniformGrid, true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index bb4e374b39..14271ed850 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -794,13 +794,7 @@ class LibraryController( end = 0 ) } else { - binding.libraryGridRecycler.recycler.columnWidth = when (preferences.gridSize().get()) { - 1 -> 1f - 2 -> 1.25f - 3 -> 1.66f - 4 -> 3f - else -> .75f - } + binding.libraryGridRecycler.recycler.setGridSize(preferences) binding.libraryGridRecycler.recycler.updatePaddingRelative( start = 5.dpToPx, end = 5.dpToPx @@ -809,7 +803,12 @@ class LibraryController( } private fun setPreferenceFlows() { - listOf(preferences.libraryLayout(), preferences.uniformGrid(), preferences.gridSize(), preferences.unreadBadgeType()).forEach { + listOf( + preferences.libraryLayout(), + preferences.uniformGrid(), + preferences.gridSize(), + preferences.unreadBadgeType() + ).forEach { it.asFlow() .drop(1) .onEach { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryDisplayView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryDisplayView.kt index 6dea5d8242..97b0b444f5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryDisplayView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryDisplayView.kt @@ -1,10 +1,24 @@ package eu.kanade.tachiyomi.ui.library.display +import android.animation.ValueAnimator import android.content.Context +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.style.ForegroundColorSpan import android.util.AttributeSet +import android.view.ViewTreeObserver +import android.widget.SeekBar +import androidx.core.animation.addListener +import androidx.core.view.isVisible +import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.LibraryDisplayLayoutBinding import eu.kanade.tachiyomi.util.bindToPreference +import eu.kanade.tachiyomi.util.system.dpToPx +import eu.kanade.tachiyomi.util.system.getResourceColor +import eu.kanade.tachiyomi.util.view.rowsForValue import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView +import eu.kanade.tachiyomi.widget.EndAnimatorListener +import kotlin.math.roundToInt class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : BaseLibraryDisplayView(context, attrs) { @@ -13,6 +27,93 @@ class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: Attr override fun initGeneralPreferences() { binding.displayGroup.bindToPreference(preferences.libraryLayout()) binding.uniformGrid.bindToPreference(preferences.uniformGrid()) - binding.gridSizeToggleGroup.bindToPreference(preferences.gridSize()) + binding.gridSeekbar.progress = ((preferences.gridSize().get() + .5f) * 2f).roundToInt() + binding.resetGridSize.setOnClickListener { + binding.gridSeekbar.progress = 3 + } + binding.root.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + if (binding.root.width > 0) { + setGridText(binding.gridSeekbar.progress) + binding.root.viewTreeObserver.removeOnGlobalLayoutListener(this) + } + } + }) + binding.gridSeekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { + if (seekBar != null && fromUser) { + alpha = 1f + isVisible = true + adjustSeekBarTip(seekBar, progress) + } + if (!fromUser) { + preferences.gridSize().set((progress / 2f) - .5f) + } + setGridText(progress) + } + + override fun onStartTrackingTouch(seekBar: SeekBar?) { + with(binding.seekBarTextView.root) { + alpha = 0f + isVisible = true + animate().alpha(1f).setDuration(250L).start() + seekBar?.post { + adjustSeekBarTip(seekBar, seekBar.progress) + } + } + } + + override fun onStopTrackingTouch(seekBar: SeekBar?) { + preferences.gridSize().set(((seekBar?.progress ?: 2) / 2f) - .5f) + with(binding.seekBarTextView.root) { + isVisible = true + alpha = 1f + post { + val anim = + ValueAnimator.ofFloat( + 1f, + 0f + ) // animate().alpha(0f).setDuration(250L) + anim.duration = 250 + anim.startDelay = 500 + anim.addUpdateListener { + alpha = it.animatedValue as Float + } + anim.addListener { + EndAnimatorListener { + isVisible = false + } + } + anim.start() + } + } + } + }) + } + + private fun setGridText(progress: Int) { + with(binding.gridSizeText) { + val rows = this@LibraryDisplayView.rowsForValue(progress) + val titleText = context.getString(R.string.grid_size) + val subtitleText = context.getString(R.string._per_row, rows) + val spannable = SpannableStringBuilder(titleText + "\n" + subtitleText) + spannable.setSpan( + ForegroundColorSpan(context.getResourceColor(android.R.attr.textColorSecondary)), + titleText.length + 1, + spannable.length, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + text = spannable + } + } + + private fun adjustSeekBarTip(seekBar: SeekBar, progress: Int) { + with(binding.seekBarTextView.root) { + val value = + (progress * (seekBar.width - 12.dpToPx - 2 * seekBar.thumbOffset)) / seekBar.max + text = this@LibraryDisplayView.rowsForValue(progress).toString() + x = seekBar.x + value + seekBar.thumbOffset / 2 + 5.dpToPx + y = seekBar.y + binding.gridSizeLayout.y - 6.dpToPx - height + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt index e40426b101..1b7d6fd881 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt @@ -11,7 +11,6 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.setting.SettingsLibraryController import eu.kanade.tachiyomi.util.view.compatToolTipText -import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.withFadeTransaction import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog import uy.kohesive.injekt.Injekt diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/source/browse/BrowseSourceController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/source/browse/BrowseSourceController.kt index 8d0ba18453..5d43242746 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/source/browse/BrowseSourceController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/source/browse/BrowseSourceController.kt @@ -167,13 +167,7 @@ open class BrowseSourceController(bundle: Bundle) : } } else { (binding.catalogueView.inflate(R.layout.manga_recycler_autofit) as AutofitRecyclerView).apply { - columnWidth = when (preferences.gridSize().get()) { - 1 -> 1f - 2 -> 1.25f - 3 -> 1.66f - 4 -> 3f - else -> .75f - } + setGridSize(preferences) (layoutManager as androidx.recyclerview.widget.GridLayoutManager).spanSizeLookup = object : androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt index 1d92e421b2..69d53c3875 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt @@ -37,8 +37,13 @@ import eu.kanade.tachiyomi.util.system.ThemeUtil import eu.kanade.tachiyomi.util.system.contextCompatColor import eu.kanade.tachiyomi.util.system.getPrefTheme import eu.kanade.tachiyomi.util.system.getResourceColor +import eu.kanade.tachiyomi.util.system.pxToDp +import eu.kanade.tachiyomi.widget.AutofitRecyclerView import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import kotlin.math.max +import kotlin.math.pow +import kotlin.math.roundToInt /** * Returns coordinates of view. @@ -338,6 +343,17 @@ fun RecyclerView.smoothScrollToTop() { } } +fun View.rowsForValue(value: Int): Int { + return rowsForValue((value / 2f) - .5f) +} + +fun View.rowsForValue(value: Float): Int { + val size = 1.5f.pow(value) + val trueSize = AutofitRecyclerView.MULTIPLE * ((size * 100 / AutofitRecyclerView.MULTIPLE).roundToInt()) / 100f + val dpWidth = (measuredWidth.pxToDp / 100f).roundToInt() + return max(1, (dpWidth / trueSize).roundToInt()) +} + var View.compatToolTipText: CharSequence? get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { tooltipText diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/AutofitRecyclerView.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/AutofitRecyclerView.kt index 11f054dbe1..516cc0757d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/AutofitRecyclerView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/AutofitRecyclerView.kt @@ -3,8 +3,10 @@ package eu.kanade.tachiyomi.widget import android.content.Context import android.util.AttributeSet import androidx.recyclerview.widget.GridLayoutManager +import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.util.system.pxToDp import kotlin.math.max +import kotlin.math.pow import kotlin.math.roundToInt class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : @@ -51,6 +53,12 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att setSpan() } + fun setGridSize(preferences: PreferencesHelper) { + val size = 1.5f.pow(preferences.gridSize().get()) + val trueSize = MULTIPLE * ((size * 100 / MULTIPLE).roundToInt()) / 100f + columnWidth = trueSize + } + private fun setSpan(force: Boolean = false) { if ((spanCount == 0 || force) && columnWidth > 0) { val dpWidth = (measuredWidth.pxToDp / 100f).roundToInt() @@ -58,4 +66,9 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att spanCount = count } } + + companion object { + private const val MULTIPLE_PERCENT = 0.25f + const val MULTIPLE = MULTIPLE_PERCENT * 100 + } } diff --git a/app/src/main/res/drawable/ic_rounded_tooltip_24dp.xml b/app/src/main/res/drawable/ic_rounded_tooltip_24dp.xml new file mode 100644 index 0000000000..36d0b4d437 --- /dev/null +++ b/app/src/main/res/drawable/ic_rounded_tooltip_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/library_display_layout.xml b/app/src/main/res/layout/library_display_layout.xml index 6ac64debad..25fe0c60ff 100644 --- a/app/src/main/res/layout/library_display_layout.xml +++ b/app/src/main/res/layout/library_display_layout.xml @@ -1,93 +1,111 @@ - - + android:layout_height="wrap_content"> - - - - - - - - - - + android:layout_height="match_parent"> - - - + android:orientation="vertical" + android:paddingStart="12dp" + android:paddingEnd="12dp"> - + + + + + + + + + + + + + + + + + - android:text="@string/small" /> - - - - - - - - - - + + \ No newline at end of file diff --git a/app/src/main/res/layout/tooltip_text_view.xml b/app/src/main/res/layout/tooltip_text_view.xml new file mode 100644 index 0000000000..bb65071b6b --- /dev/null +++ b/app/src/main/res/layout/tooltip_text_view.xml @@ -0,0 +1,13 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 49b8eefb29..ee2c302747 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -154,12 +154,14 @@ Hide start reading button Badges Uniform covers + Uniform grid covers + Grid size XS S M L XL - Grid options + %d per row Hide unread badges Show unread badges Show unread count