From 14c114756dbcc9d952790918c0a47b2bdc2dbade Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 27 Mar 2021 16:28:49 -0400 Subject: [PATCH] Clean up reader sheet spinner preferences Based on https://github.com/Jays2Kings/tachiyomiJ2K/commit/fe2543b9d5da176b1dbb95058d1bfc54400fd47a Co-Authored-By: Jays2Kings --- .../setting/ReaderReadingModeSettings.kt | 5 +- .../ui/reader/setting/SpinnerPreference.kt | 171 ++++++++++++++++++ .../res/layout/reader_general_settings.xml | 83 ++------- .../main/res/layout/reader_pager_settings.xml | 102 ++--------- .../layout/reader_reading_mode_settings.xml | 48 +---- .../res/layout/reader_webtoon_settings.xml | 85 ++------- .../main/res/layout/spinner_preference.xml | 61 +++++++ app/src/main/res/values/attrs.xml | 6 + 8 files changed, 299 insertions(+), 262 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/SpinnerPreference.kt create mode 100644 app/src/main/res/layout/spinner_preference.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt index 27f2350e3..eebb46157 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt @@ -15,7 +15,6 @@ import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer import eu.kanade.tachiyomi.util.preference.bindToIntPreference import eu.kanade.tachiyomi.util.preference.bindToPreference -import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener import kotlinx.coroutines.flow.launchIn import uy.kohesive.injekt.injectLazy @@ -44,7 +43,7 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr * Init general reader preferences. */ private fun initGeneralPreferences() { - binding.viewer.onItemSelectedListener = IgnoreFirstSpinnerListener { position -> + binding.viewer.onItemSelectedListener = { position -> (context as ReaderActivity).presenter.setMangaViewer(position) val mangaViewer = (context as ReaderActivity).presenter.getMangaViewer() @@ -54,7 +53,7 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr initPagerPreferences() } } - binding.viewer.setSelection((context as ReaderActivity).presenter.manga?.viewer ?: 0, false) + binding.viewer.setSelection((context as ReaderActivity).presenter.manga?.viewer ?: 0) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/SpinnerPreference.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/SpinnerPreference.kt new file mode 100644 index 000000000..53a1306e8 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/SpinnerPreference.kt @@ -0,0 +1,171 @@ +package eu.kanade.tachiyomi.ui.reader.setting + +import android.content.Context +import android.util.AttributeSet +import android.view.Gravity +import android.view.LayoutInflater +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 eu.kanade.tachiyomi.databinding.SpinnerPreferenceBinding + +class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + FrameLayout(context, attrs) { + + private var entries = emptyList() + private var selectedPosition = 0 + private var pref: Preference? = null + private var prefOffset = 0 + private var popup: PopupMenu? = null + + var onItemSelectedListener: ((Int) -> Unit)? = null + set(value) { + field = value + if (value != null) { + popup = makeSettingsPopup() + setOnTouchListener(popup?.dragToOpenListener) + setOnClickListener { + popup?.show() + } + } + } + + private val binding = SpinnerPreferenceBinding.inflate(LayoutInflater.from(context), this, false) + + init { + addView(binding.root) + + val a = context.obtainStyledAttributes(attrs, R.styleable.SpinnerPreference, 0, 0) + + val str = a.getString(R.styleable.SpinnerPreference_title) ?: "" + binding.title.text = str + + val entries = (a.getTextArray(R.styleable.SpinnerPreference_android_entries) ?: emptyArray()).map { it.toString() } + this.entries = entries + + binding.details.text = entries.firstOrNull().orEmpty() + + a.recycle() + } + + fun setSelection(selection: Int) { + popup?.menu?.get(selectedPosition)?.isCheckable = false + popup?.menu?.get(selectedPosition)?.isChecked = false + selectedPosition = selection + binding.details.text = entries.getOrNull(selection).orEmpty() + popup?.menu?.get(selectedPosition)?.isCheckable = true + popup?.menu?.get(selectedPosition)?.isChecked = true + } + + fun bindToPreference(pref: Preference, offset: Int = 0, block: ((Int) -> Unit)? = null) { + setSelection(pref.get() - offset) + this.pref = pref + prefOffset = offset + popup = makeSettingsPopup(pref, prefOffset, block) + setOnTouchListener(popup?.dragToOpenListener) + setOnClickListener { + popup?.show() + } + } + + inline fun > bindToPreference(pref: Preference) { + val enumConstants = T::class.java.enumConstants + enumConstants?.indexOf(pref.get())?.let { setSelection(it) } + val popup = makeSettingsPopup(pref) + setOnTouchListener(popup.dragToOpenListener) + setOnClickListener { + popup.show() + } + } + + fun bindToIntPreference(pref: Preference, @ArrayRes intValuesResource: Int, block: ((Int) -> Unit)? = null) { + setSelection(pref.get()) + this.pref = pref + prefOffset = 0 + val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() } + popup = makeSettingsPopup(pref, intValues, block) + setOnTouchListener(popup?.dragToOpenListener) + setOnClickListener { + popup?.show() + } + } + + inline fun > makeSettingsPopup(preference: Preference): 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 + } + // Set a listener so we are notified if a menu item is clicked + popup.setOnMenuItemClickListener { menuItem -> + val enumConstants = T::class.java.enumConstants + val pos = popup.menuClicked(menuItem) + enumConstants?.get(pos)?.let { preference.set(it) } + true + } + return popup + } + + private fun makeSettingsPopup(preference: Preference, intValues: List, 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, 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 + } + + 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 + } + + fun popup(): PopupMenu { + val popup = PopupMenu(context, this, Gravity.END, R.attr.actionOverflowMenuStyle, 0) + entries.forEachIndexed { index, entry -> + popup.menu.add(0, index, 0, entry) + } + popup.menu[selectedPosition].isCheckable = true + popup.menu[selectedPosition].isChecked = true + return popup + } +} diff --git a/app/src/main/res/layout/reader_general_settings.xml b/app/src/main/res/layout/reader_general_settings.xml index 503c86b01..daffe4d2b 100644 --- a/app/src/main/res/layout/reader_general_settings.xml +++ b/app/src/main/res/layout/reader_general_settings.xml @@ -7,120 +7,69 @@ android:clipToPadding="false" android:padding="16dp"> - + android:layout_height="match_parent" + android:orientation="vertical"> - - - + app:title="@string/pref_rotation_type" /> - - - + app:title="@string/pref_reader_theme" /> + android:text="@string/pref_show_page_number" /> + android:text="@string/pref_fullscreen" /> + android:text="@string/pref_keep_screen_on" /> + android:text="@string/pref_read_with_long_tap" /> + android:text="@string/pref_always_show_chapter_transition" /> + android:text="@string/pref_page_transitions" /> - - - - - + diff --git a/app/src/main/res/layout/reader_pager_settings.xml b/app/src/main/res/layout/reader_pager_settings.xml index 594b2e995..15d7c5f79 100644 --- a/app/src/main/res/layout/reader_pager_settings.xml +++ b/app/src/main/res/layout/reader_pager_settings.xml @@ -1,13 +1,14 @@ - + android:layout_height="match_parent" + android:orientation="vertical"> - - - + app:title="@string/pref_viewer_nav" /> - - - + app:title="@string/pref_read_with_tapping_inverted" /> - - - + app:title="@string/pref_image_scale_type" /> - - - + app:title="@string/pref_zoom_start" /> @@ -124,20 +72,6 @@ android:id="@+id/tapping_prefs_group" android:layout_width="wrap_content" android:layout_height="wrap_content" - app:constraint_referenced_ids="pager_nav_text,pager_nav,tapping_inverted_text,tapping_inverted,dual_page_split,dual_page_invert" /> + app:constraint_referenced_ids="pager_nav,tapping_inverted,dual_page_split,dual_page_invert" /> - - - - - + diff --git a/app/src/main/res/layout/reader_reading_mode_settings.xml b/app/src/main/res/layout/reader_reading_mode_settings.xml index aee06f38d..24a413b88 100644 --- a/app/src/main/res/layout/reader_reading_mode_settings.xml +++ b/app/src/main/res/layout/reader_reading_mode_settings.xml @@ -7,36 +7,23 @@ android:clipToPadding="false" android:padding="16dp"> - + android:layout_height="match_parent" + android:orientation="vertical"> - - - - - + app:title="@string/pref_category_for_this_series" /> - - - - - - - + diff --git a/app/src/main/res/layout/reader_webtoon_settings.xml b/app/src/main/res/layout/reader_webtoon_settings.xml index 5b71d8e3c..d331a37ec 100644 --- a/app/src/main/res/layout/reader_webtoon_settings.xml +++ b/app/src/main/res/layout/reader_webtoon_settings.xml @@ -1,13 +1,14 @@ - + android:layout_height="match_parent" + android:orientation="vertical"> - - - + app:title="@string/pref_viewer_nav" /> - - - + app:title="@string/pref_read_with_tapping_inverted" /> - - - + app:title="@string/pref_webtoon_side_padding" /> @@ -106,20 +65,6 @@ android:id="@+id/tapping_prefs_group" android:layout_width="wrap_content" android:layout_height="wrap_content" - app:constraint_referenced_ids="webtoon_nav_text,webtoon_nav,tapping_inverted_text,tapping_inverted,dual_page_split,dual_page_invert" /> + app:constraint_referenced_ids="webtoon_nav,tapping_inverted,dual_page_split,dual_page_invert" /> - - - - - + diff --git a/app/src/main/res/layout/spinner_preference.xml b/app/src/main/res/layout/spinner_preference.xml new file mode 100644 index 000000000..05716fd81 --- /dev/null +++ b/app/src/main/res/layout/spinner_preference.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 5c0a006ca..1a9012fe4 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -11,6 +11,12 @@ + + + + + +