From 8454d4f924847965a3f752aa86181bdda9aa3aec Mon Sep 17 00:00:00 2001 From: denizk0461 Date: Mon, 15 May 2023 22:10:58 +0200 Subject: [PATCH] Implemented settings for text size, text transparency, font style, highlight style, highlight transparency, and randomised entry order; fixed a bug in QuoteAdapter.onRowMoved() --- .../denizd/textbasic/adapter/QuoteAdapter.kt | 3 +- .../com/denizd/textbasic/db/QuoteStorage.kt | 55 ++++- .../textbasic/fragment/QuoteFragment.kt | 2 +- .../textbasic/fragment/SettingsFragment.kt | 2 +- .../textbasic/fragment/SettingsNewFragment.kt | 218 ++++++++++++++++++ .../textbasic/util/SettingsPreference.kt | 11 + .../com/denizd/textbasic/widget/CanvasText.kt | 2 +- .../main/res/drawable/double_arrow_left.xml | 6 + .../main/res/drawable/double_arrow_right.xml | 6 + .../drawable/selectable_item_background.xml | 4 + .../res/drawable/selectable_item_ripple.xml | 4 + .../main/res/layout/fragment_settings_new.xml | 200 +++++++++++++--- app/src/main/res/values-de/strings.xml | 7 +- app/src/main/res/values/strings.xml | 7 +- 14 files changed, 479 insertions(+), 48 deletions(-) create mode 100644 app/src/main/java/com/denizd/textbasic/util/SettingsPreference.kt create mode 100644 app/src/main/res/drawable/double_arrow_left.xml create mode 100644 app/src/main/res/drawable/double_arrow_right.xml create mode 100644 app/src/main/res/drawable/selectable_item_background.xml create mode 100644 app/src/main/res/drawable/selectable_item_ripple.xml diff --git a/app/src/main/java/com/denizd/textbasic/adapter/QuoteAdapter.kt b/app/src/main/java/com/denizd/textbasic/adapter/QuoteAdapter.kt index b16778a..e133962 100644 --- a/app/src/main/java/com/denizd/textbasic/adapter/QuoteAdapter.kt +++ b/app/src/main/java/com/denizd/textbasic/adapter/QuoteAdapter.kt @@ -11,6 +11,7 @@ import com.denizd.textbasic.R import com.google.android.material.button.MaterialButton import java.util.Collections + class QuoteAdapter( quotes: List, private val onDeleteListener: OnDeleteListener, @@ -73,7 +74,7 @@ class QuoteAdapter( override fun onRowMoved(from: Int, to: Int) { if (from < to) for (i in from until to) { Collections.swap(mutableQuotes, i, i + 1) - } else for (i in to downTo from - 1) { + } else for (i in from downTo to + 1) { Collections.swap(mutableQuotes, i, i - 1) } diff --git a/app/src/main/java/com/denizd/textbasic/db/QuoteStorage.kt b/app/src/main/java/com/denizd/textbasic/db/QuoteStorage.kt index 59d9291..8f8540a 100644 --- a/app/src/main/java/com/denizd/textbasic/db/QuoteStorage.kt +++ b/app/src/main/java/com/denizd/textbasic/db/QuoteStorage.kt @@ -5,22 +5,34 @@ import android.graphics.Color import android.graphics.Typeface import com.denizd.textbasic.util.ColorTransparentUtils import com.denizd.textbasic.R +import com.denizd.textbasic.util.SettingsPreference -class QuoteStorage(context: Context) { +class QuoteStorage private constructor(context: Context) { companion object { + private lateinit var storage: QuoteStorage + + fun getInstance(context: Context): QuoteStorage { + if (!::storage.isInitialized) { + synchronized(Object::class.java) { + storage = QuoteStorage(context) + } + } + return storage + } + const val PREF_NAME = "textbasicprefs" const val PREF_BACKUP_KEY = "textbasicprefskey" const val SEPARATOR = '\uFFFF' private const val KEY_QUOTES = "quotes" private const val KEY_QUOTE_COUNTER = "quotecounter" - private const val KEY_TEXT_SIZE = "textsize" + const val KEY_TEXT_SIZE = "textsize" private const val KEY_INVERTED = "inverted" private const val KEY_HIGH_CONTRAST = "hicontrast" - private const val KEY_TEXT_TRANSPARENCY = "transparency_text" - private const val KEY_BG_TRANSPARENCY = "transparency" + const val KEY_TEXT_TRANSPARENCY = "transparency_text" + const val KEY_BG_TRANSPARENCY = "transparency" private const val KEY_RANDOM = "random" private const val KEY_WIDGET_POSITION = "widgetposition" private const val KEY_BACKGROUND_TYPE = "backgroundtype" @@ -52,13 +64,43 @@ class QuoteStorage(context: Context) { } fun getTextSize() = prefs.getInt(KEY_TEXT_SIZE, 18) + fun setTextSize(newValue: Int) { + prefs.edit().putInt(KEY_TEXT_SIZE, newValue).apply() + } + + fun getInt( + pref: SettingsPreference, + defaultValue: Int = 0, + ): Int = prefs.getInt(pref.key, defaultValue) + fun setInt( + pref: SettingsPreference, + newValue: Int, + ) { + prefs.edit().putInt(pref.key, newValue).apply() + } fun isInvertedEnabled(): Boolean = prefs.getBoolean(KEY_INVERTED, false) fun getTextTransparency(): Int = prefs.getInt(KEY_TEXT_TRANSPARENCY, 100) + fun setTextTransparency(newValue: Int) { + prefs.edit().putInt(KEY_TEXT_TRANSPARENCY, newValue).apply() + } fun getBackgroundTransparency(): Int = prefs.getInt(KEY_BG_TRANSPARENCY, 100) + fun setBackgroundTransparency(newValue: Int) { + prefs.edit().putInt(KEY_BG_TRANSPARENCY, newValue).apply() + } fun isOrderRandom(): Boolean = prefs.getBoolean(KEY_RANDOM, false) + fun setIsOrderRandom(newValue: Boolean) { + prefs.edit().putBoolean(KEY_RANDOM, newValue).apply() + } + fun getWidgetGravity(): Int = prefs.getInt(KEY_WIDGET_POSITION, 1) - fun getBackgroundType(): Int = prefs.getInt(KEY_BACKGROUND_TYPE, 0) + fun setWidgetGravity(newValue: Int) { + prefs.edit().putInt(KEY_WIDGET_POSITION, newValue).apply() + } + fun getBackgroundType(): Int = prefs.getInt(KEY_BACKGROUND_TYPE, 3) // default none + fun setBackgroundType(newValue: Int) { + prefs.edit().putInt(KEY_BACKGROUND_TYPE, newValue).apply() + } fun getTypefaceIndex(): Int = prefs.getInt(KEY_TYPEFACE, 0) fun getTypeface(): Typeface = Typeface.create( when (getTypefaceIndex()) { @@ -69,6 +111,9 @@ class QuoteStorage(context: Context) { getTypefaceStyle() ) fun getTypefaceStyle(): Int = prefs.getInt(KEY_TYPEFACE_STYLE, 0) + fun setTypefaceStyle(newValue: Int) { + prefs.edit().putInt(KEY_TYPEFACE_STYLE, newValue).apply() + } fun getOutlineSize(): Float = prefs.getFloat(KEY_OUTLINE_SIZE, 8f) // Pair diff --git a/app/src/main/java/com/denizd/textbasic/fragment/QuoteFragment.kt b/app/src/main/java/com/denizd/textbasic/fragment/QuoteFragment.kt index acff126..cdb7a94 100644 --- a/app/src/main/java/com/denizd/textbasic/fragment/QuoteFragment.kt +++ b/app/src/main/java/com/denizd/textbasic/fragment/QuoteFragment.kt @@ -22,7 +22,7 @@ class QuoteFragment : BaseFragment(R.layout.fragment_quote), QuoteAdapter.OnDele override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - storage = QuoteStorage(context) + storage = QuoteStorage.getInstance(context) quoteAdapter = QuoteAdapter(storage.getAllQuotes(), this) binding.recyclerView.layoutManager = LinearLayoutManager(context) diff --git a/app/src/main/java/com/denizd/textbasic/fragment/SettingsFragment.kt b/app/src/main/java/com/denizd/textbasic/fragment/SettingsFragment.kt index 912ba7f..85caad8 100644 --- a/app/src/main/java/com/denizd/textbasic/fragment/SettingsFragment.kt +++ b/app/src/main/java/com/denizd/textbasic/fragment/SettingsFragment.kt @@ -47,7 +47,7 @@ class SettingsFragment : BaseFragment(R.layout.fragment_settings) { // TODO a lot of the buttons don't at all do what they're supposed to do! - storage = QuoteStorage(context) + storage = QuoteStorage.getInstance(context) gravityButtons = arrayOf( binding.buttonTopLeft, binding.buttonTopMiddle, binding.buttonTopRight, diff --git a/app/src/main/java/com/denizd/textbasic/fragment/SettingsNewFragment.kt b/app/src/main/java/com/denizd/textbasic/fragment/SettingsNewFragment.kt index 97c4219..ad9d59c 100644 --- a/app/src/main/java/com/denizd/textbasic/fragment/SettingsNewFragment.kt +++ b/app/src/main/java/com/denizd/textbasic/fragment/SettingsNewFragment.kt @@ -1,10 +1,228 @@ package com.denizd.textbasic.fragment +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.View +import android.widget.TextView +import com.denizd.textbasic.BuildConfig import com.denizd.textbasic.R import com.denizd.textbasic.databinding.FragmentSettingsNewBinding +import com.denizd.textbasic.db.QuoteStorage +import com.denizd.textbasic.util.SettingsPreference import com.denizd.textbasic.util.viewBinding +import com.google.android.material.button.MaterialButton class SettingsNewFragment : BaseFragment(R.layout.fragment_settings_new) { + private lateinit var storage: QuoteStorage + private val binding: FragmentSettingsNewBinding by viewBinding(FragmentSettingsNewBinding::bind) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + storage = QuoteStorage.getInstance(context) + + // --- font style --- // + binding.toggleGroupFont.apply { + check(when (storage.getTypefaceStyle()) { + 1 -> R.id.toggle_button_font_bold + 2 -> R.id.toggle_button_font_italic + 3 -> R.id.toggle_button_font_bold_italic + else -> R.id.toggle_button_font_default + }) + + addOnButtonCheckedListener { _, checkedId, isChecked -> + if (isChecked) { + storage.setTypefaceStyle(when (checkedId) { + R.id.toggle_button_font_bold -> 1 + R.id.toggle_button_font_italic -> 2 + R.id.toggle_button_font_bold_italic -> 3 + else -> 0 + }) + } + } + } + + // --- text size --- // + binding.textSize.text = storage.getInt(SettingsPreference.TEXT_SIZE, 18).toString() + + binding.buttonSizeDecreaseFast.setOnClickAction( + 4, + 256, + isPositive = false, + isFast = true, + binding.textSize, + SettingsPreference.TEXT_SIZE, + ) + binding.buttonSizeDecrease.setOnClickAction( + 4, + 256, + isPositive = false, + isFast = false, + binding.textSize, + SettingsPreference.TEXT_SIZE, + ) + binding.buttonSizeIncrease.setOnClickAction( + 4, + 256, + isPositive = true, + isFast = false, + binding.textSize, + SettingsPreference.TEXT_SIZE, + ) + binding.buttonSizeIncreaseFast.setOnClickAction( + 4, + 256, + isPositive = true, + isFast = true, + binding.textSize, + SettingsPreference.TEXT_SIZE, + ) + + // --- text transparency --- // + binding.textTransparency.text = storage.getInt(SettingsPreference.TEXT_TRANSPARENCY, 100).toString() + + binding.buttonTextTransparencyDecreaseFast.setOnClickAction( + 0, + 100, + isPositive = false, + isFast = true, + binding.textTransparency, + SettingsPreference.TEXT_TRANSPARENCY, + ) + binding.buttonTextTransparencyDecrease.setOnClickAction( + 0, + 100, + isPositive = false, + isFast = false, + binding.textTransparency, + SettingsPreference.TEXT_TRANSPARENCY, + ) + binding.buttonTextTransparencyIncrease.setOnClickAction( + 0, + 100, + isPositive = true, + isFast = false, + binding.textTransparency, + SettingsPreference.TEXT_TRANSPARENCY, + ) + binding.buttonTextTransparencyIncreaseFast.setOnClickAction( + 0, + 100, + isPositive = true, + isFast = true, + binding.textTransparency, + SettingsPreference.TEXT_TRANSPARENCY, + ) + + // --- highlight style --- // + binding.toggleGroupHighlightStyle.apply { + check(when (storage.getBackgroundType()) { + 0 -> R.id.toggle_button_highlight_background + 1 -> R.id.toggle_button_highlight_stroke + 2 -> R.id.toggle_button_highlight_shadow + else -> R.id.toggle_button_highlight_none // 3 + }) + + addOnButtonCheckedListener { _, checkedId, isChecked -> + if (isChecked) { + storage.setBackgroundType(when (checkedId) { + R.id.toggle_button_highlight_background -> 0 + R.id.toggle_button_highlight_stroke -> 1 + R.id.toggle_button_highlight_shadow -> 2 + else -> 3 // none + }) + } + } + } + + // --- text highlight transparency --- // + binding.textHighlightTransparency.text = storage.getInt(SettingsPreference.HIGHLIGHT_TRANSPARENCY, 100).toString() + + binding.buttonHighlightTransparencyDecreaseFast.setOnClickAction( + 0, + 100, + isPositive = false, + isFast = true, + binding.textHighlightTransparency, + SettingsPreference.HIGHLIGHT_TRANSPARENCY, + ) + binding.buttonHighlightTransparencyDecrease.setOnClickAction( + 0, + 100, + isPositive = false, + isFast = false, + binding.textHighlightTransparency, + SettingsPreference.HIGHLIGHT_TRANSPARENCY, + ) + binding.buttonHighlightTransparencyIncrease.setOnClickAction( + 0, + 100, + isPositive = true, + isFast = false, + binding.textHighlightTransparency, + SettingsPreference.HIGHLIGHT_TRANSPARENCY, + ) + binding.buttonHighlightTransparencyIncreaseFast.setOnClickAction( + 0, + 100, + isPositive = true, + isFast = true, + binding.textHighlightTransparency, + SettingsPreference.HIGHLIGHT_TRANSPARENCY, + ) + + // --- randomise order entries --- // + binding.switchOrderRandom.apply { + isChecked = storage.isOrderRandom() + + setOnCheckedChangeListener { _, isChecked -> + storage.setIsOrderRandom(isChecked) + } + } + + /* + * Display the app's version as set in the build.gradle. Also display if the app is a + * development version, and if so, display build timestamp. + */ + @SuppressLint("SetTextI18n") + binding.appVersionText.text = + "${BuildConfig.VERSION_NAME}-${if (BuildConfig.DEBUG) "dev" else "release"}" + } + + // TODO horrible, horrible, horrible function. but it works. fix this in the future. please. + private fun MaterialButton.setOnClickAction( + min: Int, + max: Int, + isPositive: Boolean, + isFast: Boolean, + textField: TextView, + pref: SettingsPreference, + ) { + setOnClickListener { + var value = storage.getInt(pref) + if (isFast) { + if (isPositive) { + if ((value + 10) > max) { + value = max + } else { + value += 10 + } + } else { + if ((value - 10) < min) { + value = min + } else { + value -= 10 + } + } + } else { + if (isPositive && (value != max)) value += 1 + if (!isPositive && (value != min)) value -= 1 + } + + storage.setInt(pref, value) + textField.text = value.toString() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/denizd/textbasic/util/SettingsPreference.kt b/app/src/main/java/com/denizd/textbasic/util/SettingsPreference.kt new file mode 100644 index 0000000..a78e752 --- /dev/null +++ b/app/src/main/java/com/denizd/textbasic/util/SettingsPreference.kt @@ -0,0 +1,11 @@ +package com.denizd.textbasic.util + +import com.denizd.textbasic.db.QuoteStorage + +enum class SettingsPreference(val key: String) { + TEXT_SIZE(QuoteStorage.KEY_TEXT_SIZE), + TEXT_TRANSPARENCY(QuoteStorage.KEY_TEXT_TRANSPARENCY), + HIGHLIGHT_INTENSITY(""), // TODO + HIGHLIGHT_TRANSPARENCY(QuoteStorage.KEY_BG_TRANSPARENCY), + ; +} \ No newline at end of file diff --git a/app/src/main/java/com/denizd/textbasic/widget/CanvasText.kt b/app/src/main/java/com/denizd/textbasic/widget/CanvasText.kt index 3fde5b0..d8fdb41 100644 --- a/app/src/main/java/com/denizd/textbasic/widget/CanvasText.kt +++ b/app/src/main/java/com/denizd/textbasic/widget/CanvasText.kt @@ -15,7 +15,7 @@ class CanvasText { val previewSize = 20f - val storage = QuoteStorage(context) + val storage = QuoteStorage.getInstance(context) size?.let { storage.setSize(size) diff --git a/app/src/main/res/drawable/double_arrow_left.xml b/app/src/main/res/drawable/double_arrow_left.xml new file mode 100644 index 0000000..007354c --- /dev/null +++ b/app/src/main/res/drawable/double_arrow_left.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/double_arrow_right.xml b/app/src/main/res/drawable/double_arrow_right.xml new file mode 100644 index 0000000..3562ff1 --- /dev/null +++ b/app/src/main/res/drawable/double_arrow_right.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/selectable_item_background.xml b/app/src/main/res/drawable/selectable_item_background.xml new file mode 100644 index 0000000..f1644cb --- /dev/null +++ b/app/src/main/res/drawable/selectable_item_background.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selectable_item_ripple.xml b/app/src/main/res/drawable/selectable_item_ripple.xml new file mode 100644 index 0000000..f96dabb --- /dev/null +++ b/app/src/main/res/drawable/selectable_item_ripple.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_settings_new.xml b/app/src/main/res/layout/fragment_settings_new.xml index b08cb10..ae6ef2e 100644 --- a/app/src/main/res/layout/fragment_settings_new.xml +++ b/app/src/main/res/layout/fragment_settings_new.xml @@ -189,7 +189,7 @@ + + + + @@ -276,6 +296,16 @@ android:orientation="horizontal" android:gravity="center"> + + + + @@ -434,6 +474,16 @@ android:orientation="horizontal" android:gravity="center"> + + + + @@ -486,6 +546,16 @@ android:orientation="horizontal" android:gravity="center"> + + + + @@ -551,10 +631,90 @@ android:layout_marginHorizontal="16dp" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -563,45 +723,15 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/mono_semibold_italic" - android:text="@string/settings_widget_order_title" + android:text="@string/settings_misc_app_version" android:textSize="16sp" /> - - - - - - - - diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 3d6b98e..d7344b9 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -46,12 +46,15 @@ Highlight-Transparenz Widget - Stelle Reihenfolge ein - Dies ist die Reihenfolge, in welcher deine Einträge angezeigt werden, wenn du auf das Widget klickst + Nutze zufällige Reihenfolge + Sonst wird die Reihenfolge der Liste genutzt; ändere sie durch D rag & Drop Standard Zufall Setze Position des Texts + Sonstiges + App-Version + Text bearbeiten Einträge Anleitung diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5bba7a2..f059231 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -45,12 +45,15 @@ Transparency Widget - Set entry order - This is the order in which your entries will be shown when you click on the widget + Randomise entry order + Order from the list is preserved otherwise; change by drag-and-drop Default Random Set position of the text + Miscellaneous + App Version + Edit Text Entries Guide