diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index 9e1f69e71..eb8031187 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -11,7 +11,7 @@ import androidx.databinding.DataBindingUtil import org.oxycblt.auxio.databinding.ActivityMainBinding import org.oxycblt.auxio.playback.PlaybackService import org.oxycblt.auxio.settings.SettingsManager -import org.oxycblt.auxio.ui.accent +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.isEdgeOn /** @@ -30,10 +30,10 @@ class MainActivity : AppCompatActivity() { AppCompatDelegate.setDefaultNightMode(settingsManager.theme) - accent = settingsManager.accent + val accent = Accent.set(settingsManager.accent) // Apply the theme - setTheme(accent.second) + setTheme(accent.theme) if (isEdgeOn()) { doEdgeToEdgeSetup(binding) diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index 5ad725b40..788a1fc94 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import androidx.core.graphics.ColorUtils import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.NavController @@ -17,8 +18,7 @@ import org.oxycblt.auxio.detail.DetailViewModel import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel -import org.oxycblt.auxio.ui.accent -import org.oxycblt.auxio.ui.getTransparentAccent +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.isLandscape import org.oxycblt.auxio.ui.toColor @@ -45,10 +45,8 @@ class MainFragment : Fragment() { return null } - val colorActive = accent.first.toColor(requireContext()) - val colorInactive = getTransparentAccent( - requireContext(), accent.first, 150 - ) + val colorActive = Accent.get().color.toColor(requireContext()) + val colorInactive = ColorUtils.setAlphaComponent(colorActive, 150) // Set up the tints for the navigation icons + text val navTints = ColorStateList( diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt index 08ef57590..9a585d245 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt @@ -16,7 +16,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.recycler.DiffCallback import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder import org.oxycblt.auxio.recycler.viewholders.Highlightable -import org.oxycblt.auxio.ui.accent +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.applyAccents import org.oxycblt.auxio.ui.disable import org.oxycblt.auxio.ui.setTextColorResource @@ -138,8 +138,10 @@ class AlbumDetailAdapter( override fun setHighlighted(isHighlighted: Boolean) { if (isHighlighted) { - binding.songName.setTextColorResource(accent.first) - binding.songTrack.setTextColorResource(accent.first) + val accent = Accent.get() + + binding.songName.setTextColorResource(accent.color) + binding.songTrack.setTextColorResource(accent.color) } else { binding.songName.setTextColor(normalTextColor) binding.songTrack.setTextColor(inactiveTextColor) diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt index 9bdfd5d8c..846b5c5a2 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt @@ -16,7 +16,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.recycler.DiffCallback import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder import org.oxycblt.auxio.recycler.viewholders.Highlightable -import org.oxycblt.auxio.ui.accent +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.applyAccents import org.oxycblt.auxio.ui.disable import org.oxycblt.auxio.ui.setTextColorResource @@ -137,7 +137,7 @@ class ArtistDetailAdapter( override fun setHighlighted(isHighlighted: Boolean) { if (isHighlighted) { - binding.albumName.setTextColorResource(accent.first) + binding.albumName.setTextColorResource(Accent.get().color) } else { binding.albumName.setTextColor(normalTextColor) } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt index 697cc13a5..f2a4cffc6 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt @@ -16,7 +16,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.recycler.DiffCallback import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder import org.oxycblt.auxio.recycler.viewholders.Highlightable -import org.oxycblt.auxio.ui.accent +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.applyAccents import org.oxycblt.auxio.ui.disable import org.oxycblt.auxio.ui.setTextColorResource @@ -138,7 +138,7 @@ class GenreDetailAdapter( override fun setHighlighted(isHighlighted: Boolean) { if (isHighlighted) { - binding.songName.setTextColorResource(accent.first) + binding.songName.setTextColorResource(Accent.get().color) } else { binding.songName.setTextColor(normalTextColor) } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt index e18469e7a..e2e91ca2a 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt @@ -17,7 +17,7 @@ import org.oxycblt.auxio.databinding.FragmentPlaybackBinding import org.oxycblt.auxio.detail.DetailViewModel import org.oxycblt.auxio.logD import org.oxycblt.auxio.playback.state.LoopMode -import org.oxycblt.auxio.ui.accent +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.memberBinding import org.oxycblt.auxio.ui.toColor @@ -36,7 +36,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener { // Colors private val accentColor: ColorStateList by lazy { - ColorStateList.valueOf(accent.first.toColor(requireContext())) + Accent.get().getStateList(requireContext()) } private val controlColor: ColorStateList by lazy { diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/NoLeakThumbView.kt b/app/src/main/java/org/oxycblt/auxio/recycler/NoLeakThumbView.kt index d20e4a0c3..2de39edf9 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/NoLeakThumbView.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/NoLeakThumbView.kt @@ -22,7 +22,7 @@ import androidx.dynamicanimation.animation.SpringForce import com.reddit.indicatorfastscroll.FastScrollItemIndicator import com.reddit.indicatorfastscroll.FastScrollerView import org.oxycblt.auxio.R -import org.oxycblt.auxio.ui.accent +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.toColor /** @@ -40,7 +40,7 @@ class NoLeakThumbView @JvmOverloads constructor( ) : ConstraintLayout(context, attrs, defStyleAttr), FastScrollerView.ItemIndicatorSelectedCallback { - private val thumbColor = ColorStateList.valueOf(accent.first.toColor(context)) + private val thumbColor = Accent.get().getStateList(context) private val iconColor = R.color.background.toColor(context) private val textAppearanceRes = R.style.TextAppearance_ThumbIndicator private val textColor = R.color.background.toColor(context) diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt index 31f68ff15..77ad6fbbe 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt @@ -5,7 +5,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.graphics.toColor import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels @@ -23,8 +22,8 @@ import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Header import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.ActionMenu -import org.oxycblt.auxio.ui.accent import org.oxycblt.auxio.ui.fixAnimationInfoMemoryLeak import org.oxycblt.auxio.ui.getLandscapeSpans import org.oxycblt.auxio.ui.isLandscape @@ -51,7 +50,7 @@ class SearchFragment : Fragment() { // Apply the accents manually. Not going through the mess of converting my app's // styling to Material given all the second-and-third-order effects it has. - val accent = accent.first.toColor(requireContext()) + val accent = Accent.get().color.toColor(requireContext()) val searchAdapter = SearchAdapter(::onItemSelection) { view, data -> ActionMenu(requireCompatActivity(), view, data, ActionMenu.FLAG_NONE) diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt index 682183de0..c844c78f0 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt @@ -20,9 +20,8 @@ import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.recycler.DisplayMode import org.oxycblt.auxio.settings.ui.AccentAdapter import org.oxycblt.auxio.ui.ACCENTS -import org.oxycblt.auxio.ui.accent +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.createToast -import org.oxycblt.auxio.ui.getDetailedAccentSummary /** * The actual fragment containing the settings menu. Inherits [PreferenceFragmentCompat]. @@ -84,7 +83,7 @@ class SettingsListFragment : PreferenceFragmentCompat() { true } - summary = getDetailedAccentSummary(requireActivity(), accent) + summary = Accent.get().getDetailedSummary(context) } SettingsManager.Keys.KEY_EDGE_TO_EDGE -> { @@ -153,7 +152,7 @@ class SettingsListFragment : PreferenceFragmentCompat() { // This is why I hate using third party libraries. val recycler = RecyclerView(requireContext()).apply { adapter = AccentAdapter { - if (it.first != accent.first) { + if (it != Accent.get()) { SettingsManager.getInstance().accent = it requireActivity().recreate() @@ -169,7 +168,7 @@ class SettingsListFragment : PreferenceFragmentCompat() { (layoutManager as LinearLayoutManager) .scrollToPositionWithOffset( - ACCENTS.indexOf(accent), + ACCENTS.indexOf(Accent.get()), (width / 2) - childWidth ) } diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt index 2b7fdf183..19f48ef03 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt @@ -7,6 +7,7 @@ import org.oxycblt.auxio.playback.state.PlaybackMode import org.oxycblt.auxio.recycler.DisplayMode import org.oxycblt.auxio.recycler.SortMode import org.oxycblt.auxio.ui.ACCENTS +import org.oxycblt.auxio.ui.Accent /** * Wrapper around the [SharedPreferences] class that writes & reads values without a context. @@ -31,12 +32,10 @@ class SettingsManager private constructor(context: Context) : /** * The current accent. */ - var accent: Pair + var accent: Accent get() { - val accentIndex = sharedPrefs.getInt(Keys.KEY_ACCENT, 5) - // Accent is stored as an index [to be efficient], so retrieve it when done. - return ACCENTS[accentIndex] + return ACCENTS[sharedPrefs.getInt(Keys.KEY_ACCENT, 5)] } set(value) { val accentIndex = ACCENTS.indexOf(value) @@ -200,14 +199,14 @@ class SettingsManager private constructor(context: Context) : companion object { @Volatile - private lateinit var INSTANCE: SettingsManager + private var INSTANCE: SettingsManager? = null /** * Init the single instance of [SettingsManager]. Done so that every object * can have access to it regardless of if it has a context. */ fun init(context: Context): SettingsManager { - if (!::INSTANCE.isInitialized) { + if (INSTANCE == null) { synchronized(this) { INSTANCE = SettingsManager(context) } @@ -220,10 +219,13 @@ class SettingsManager private constructor(context: Context) : * Get the single instance of [SettingsManager]. */ fun getInstance(): SettingsManager { - check(::INSTANCE.isInitialized) { - "SettingsManager must be initialized with init() before getting its instance." + val instance = INSTANCE + + if (instance != null) { + return instance } - return INSTANCE + + error("SettingsManager must be initialized with init() before getting its instance.") } } diff --git a/app/src/main/java/org/oxycblt/auxio/settings/ui/AccentAdapter.kt b/app/src/main/java/org/oxycblt/auxio/settings/ui/AccentAdapter.kt index ea12a1fe8..cbc7e0ecf 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/ui/AccentAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/ui/AccentAdapter.kt @@ -7,8 +7,7 @@ import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.ItemAccentBinding import org.oxycblt.auxio.ui.ACCENTS -import org.oxycblt.auxio.ui.accent -import org.oxycblt.auxio.ui.getAccentItemSummary +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.toColor /** @@ -17,7 +16,7 @@ import org.oxycblt.auxio.ui.toColor * @param doOnAccentConfirm What to do when an accent is confirmed. */ class AccentAdapter( - private val doOnAccentConfirm: (accent: Pair) -> Unit + private val doOnAccentConfirm: (accent: Accent) -> Unit ) : RecyclerView.Adapter() { override fun getItemCount(): Int = ACCENTS.size @@ -33,31 +32,25 @@ class AccentAdapter( private val binding: ItemAccentBinding ) : RecyclerView.ViewHolder(binding.root) { - fun bind(accentData: Pair) { + fun bind(accent: Accent) { binding.accent.apply { - contentDescription = getAccentItemSummary(context, accentData) + contentDescription = accent.getDetailedSummary(context) setOnClickListener { - doOnAccentConfirm(accentData) + doOnAccentConfirm(accent) } - imageTintList = if (accentData.first == accent.first) { + imageTintList = if (accent == Accent.get()) { isEnabled = false - ColorStateList.valueOf( - R.color.background.toColor(context) - ) + ColorStateList.valueOf(R.color.background.toColor(context)) } else { isEnabled = true - ColorStateList.valueOf( - android.R.color.transparent.toColor(context) - ) + ColorStateList.valueOf(android.R.color.transparent.toColor(context)) } - backgroundTintList = ColorStateList.valueOf( - accentData.first.toColor(context) - ) + backgroundTintList = accent.getStateList(context) } } } diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt index 15907443f..525c84dad 100644 --- a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt @@ -1,6 +1,5 @@ package org.oxycblt.auxio.songs -import android.content.res.ColorStateList import android.os.Build import android.os.Bundle import android.util.TypedValue @@ -18,12 +17,11 @@ import org.oxycblt.auxio.databinding.FragmentSongsBinding import org.oxycblt.auxio.logD import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.playback.PlaybackViewModel +import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.ActionMenu -import org.oxycblt.auxio.ui.accent import org.oxycblt.auxio.ui.getLandscapeSpans import org.oxycblt.auxio.ui.isLandscape import org.oxycblt.auxio.ui.requireCompatActivity -import org.oxycblt.auxio.ui.toColor import kotlin.math.ceil /** @@ -109,7 +107,7 @@ class SongsFragment : Fragment() { // API 22 and below don't support the state color, so just use the accent. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) { - textColor = ColorStateList.valueOf(accent.first.toColor(requireContext())) + textColor = Accent.get().getStateList(requireContext()) } setupWithRecyclerView( diff --git a/app/src/main/java/org/oxycblt/auxio/ui/Accent.kt b/app/src/main/java/org/oxycblt/auxio/ui/Accent.kt new file mode 100644 index 000000000..bcee6fd9d --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/ui/Accent.kt @@ -0,0 +1,111 @@ +package org.oxycblt.auxio.ui + +import android.annotation.SuppressLint +import android.content.Context +import android.content.res.ColorStateList +import android.text.Spanned +import androidx.annotation.ColorRes +import androidx.annotation.StringRes +import androidx.annotation.StyleRes +import androidx.core.text.toSpanned +import org.oxycblt.auxio.R +import org.oxycblt.auxio.settings.SettingsManager +import java.util.Locale + +/** + * A list of all possible accents. + * TODO: Add custom accents + */ +val ACCENTS = arrayOf( + Accent(R.color.red, R.style.Theme_Red, R.string.color_label_red), + Accent(R.color.pink, R.style.Theme_Pink, R.string.color_label_pink), + Accent(R.color.purple, R.style.Theme_Purple, R.string.color_label_purple), + Accent(R.color.deep_purple, R.style.Theme_DeepPurple, R.string.color_label_deep_purple), + Accent(R.color.indigo, R.style.Theme_Indigo, R.string.color_label_indigo), + Accent(R.color.blue, R.style.Theme_Blue, R.string.color_label_blue), + Accent(R.color.light_blue, R.style.Theme_LightBlue, R.string.color_label_light_blue), + Accent(R.color.cyan, R.style.Theme_Cyan, R.string.color_label_cyan), + Accent(R.color.teal, R.style.Theme_Teal, R.string.color_label_teal), + Accent(R.color.green, R.style.Theme_Green, R.string.color_label_green), + Accent(R.color.light_green, R.style.Theme_LightGreen, R.string.color_label_light_green), + Accent(R.color.lime, R.style.Theme_Lime, R.string.color_label_lime), + Accent(R.color.yellow, R.style.Theme_Yellow, R.string.color_label_yellow), + Accent(R.color.amber, R.style.Theme_Amber, R.string.color_label_amber), + Accent(R.color.orange, R.style.Theme_Orange, R.string.color_label_orange), + Accent(R.color.deep_orange, R.style.Theme_DeepOrange, R.string.color_label_deep_orange), + Accent(R.color.brown, R.style.Theme_Brown, R.string.color_label_brown), + Accent(R.color.grey, R.style.Theme_Gray, R.string.color_label_grey), + Accent(R.color.blue_grey, R.style.Theme_BlueGrey, R.string.color_label_blue_grey), + Accent(R.color.control_color, R.style.Theme_Neutral, R.string.color_label_neutral) +) + +/** + * The data object for an accent. + * @property color The color resource for this accent + * @property theme The theme resource for this accent + * @property name The name of this accent + */ +data class Accent( + @ColorRes val color: Int, + @StyleRes val theme: Int, + @StringRes val name: Int +) { + /** + * Get a [ColorStateList] of the accent + */ + fun getStateList(context: Context): ColorStateList { + return ColorStateList.valueOf(color.toColor(context)) + } + + /** + * Get the name (in bold) and the hex value of a accent. + * @param context [Context] required + * @return A rendered span with the name in bold + the hex value of the accent. + */ + @SuppressLint("ResourceType") + fun getDetailedSummary(context: Context): Spanned { + val name = context.getString(name) + val hex = context.getString(color).toUpperCase(Locale.getDefault()) + + return context.getString( + R.string.format_accent_summary, + name, hex + ).toSpanned().render() + } + + companion object { + @Volatile + private var current: Accent? = null + + /** + * Get the current accent, will default to whatever is stored in [SettingsManager] + * if there isnt one. + * @return The current accent + */ + fun get(): Accent { + val cur = current + + if (cur != null) { + return cur + } + + synchronized(this) { + val newCur = SettingsManager.getInstance().accent + current = newCur + return newCur + } + } + + /** + * Set the current accent. + * @return The new accent + */ + fun set(accent: Accent): Accent { + synchronized(this) { + current = accent + } + + return accent + } + } +} diff --git a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt index 6fe9badf7..a324c2a56 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt @@ -14,9 +14,11 @@ import android.view.WindowManager import android.widget.ImageButton import android.widget.TextView import android.widget.Toast +import androidx.annotation.ColorInt import androidx.annotation.ColorRes import androidx.annotation.PluralsRes import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat import androidx.core.text.HtmlCompat import androidx.fragment.app.Fragment import com.google.android.material.button.MaterialButton @@ -51,7 +53,7 @@ fun TextView.setTextColorResource(@ColorRes color: Int) { * Required because you cant determine a style of a view before API 29 */ fun MaterialButton.applyAccents(highlighted: Boolean) { - val accent = accent.first.toColor(context) + val accent = Accent.get().color.toColor(context) if (highlighted) { backgroundTintList = ColorStateList.valueOf(accent) @@ -103,6 +105,23 @@ fun Spanned.render(): Spanned { ) } +/** + * Resolve a color. + * @param context [Context] required + * @return The resolved color, black if the resolving process failed. + */ +@ColorInt +fun Int.toColor(context: Context): Int { + return try { + ContextCompat.getColor(context, this) + } catch (e: Resources.NotFoundException) { + logE("Attempted color load failed.") + + // Default to the emergency color [Black] if the loading fails. + ContextCompat.getColor(context, android.R.color.black) + } +} + // --- CONFIGURATION --- /** @@ -177,8 +196,9 @@ private fun isSystemBarOnBottom(activity: Activity): Boolean { // --- HACKY NIGHTMARES --- /** - * Use R E F L E C T I O N to fix a memory leak where mAnimationInfo will keep a reference to + * Use ***R E F L E C T I O N*** to fix a memory leak where mAnimationInfo will keep a reference to * its focused view. + * * I can't believe I have to do this. */ fun Fragment.fixAnimationInfoMemoryLeak() { diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt deleted file mode 100644 index 3ac363f08..000000000 --- a/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt +++ /dev/null @@ -1,125 +0,0 @@ -package org.oxycblt.auxio.ui - -import android.content.Context -import android.content.res.Resources -import android.text.Spanned -import androidx.annotation.ColorInt -import androidx.annotation.ColorRes -import androidx.core.content.ContextCompat -import androidx.core.graphics.ColorUtils -import androidx.core.text.toSpanned -import org.oxycblt.auxio.R -import org.oxycblt.auxio.logE -import java.util.Locale - -// Functions for managing colors/accents. - -/** - * An array of the base accents and their respective themes. - */ -val ACCENTS = arrayOf( - Pair(R.color.red, R.style.Theme_Red), // 0 - Pair(R.color.pink, R.style.Theme_Pink), // 1 - Pair(R.color.purple, R.style.Theme_Purple), // 2 - Pair(R.color.deep_purple, R.style.Theme_DeepPurple), // 3 - Pair(R.color.indigo, R.style.Theme_Indigo), // 4 - Pair(R.color.blue, R.style.Theme_Blue), // 5 - Default! - Pair(R.color.light_blue, R.style.Theme_LightBlue), // 6 - Pair(R.color.cyan, R.style.Theme_Cyan), // 7 - Pair(R.color.teal, R.style.Theme_Teal), // 8 - Pair(R.color.green, R.style.Theme_Green), // 9 - Pair(R.color.light_green, R.style.Theme_LightGreen), // 10 - Pair(R.color.lime, R.style.Theme_Lime), // 11 - Pair(R.color.yellow, R.style.Theme_Yellow), // 12 - Pair(R.color.amber, R.style.Theme_Amber), // 13 - Pair(R.color.orange, R.style.Theme_Orange), // 14 - Pair(R.color.deep_orange, R.style.Theme_DeepOrange), // 15 - Pair(R.color.brown, R.style.Theme_Brown), // 16 - Pair(R.color.grey, R.style.Theme_Gray), // 17 - Pair(R.color.blue_grey, R.style.Theme_BlueGrey), // 18 - Pair(R.color.control_color, R.style.Theme_Neutral) -) - -/** - * An array of strings for each accent, use these instead of [Resources.getResourceName] so that - * the accent names are translated. - */ -private val ACCENT_NAMES = arrayOf( - R.string.color_label_red, R.string.color_label_pink, - R.string.color_label_purple, R.string.color_label_deep_purple, - R.string.color_label_indigo, R.string.color_label_blue, - R.string.color_label_light_blue, R.string.color_label_cyan, - R.string.color_label_teal, R.string.color_label_green, - R.string.color_label_light_green, R.string.color_label_lime, - R.string.color_label_yellow, R.string.color_label_amber, - R.string.color_label_orange, R.string.color_label_deep_orange, - R.string.color_label_brown, R.string.color_label_grey, - R.string.color_label_blue_grey, R.string.color_label_neutral -) - -/** - * The programmatically accessible accent, reflects the currently set accent. - */ -lateinit var accent: Pair - -/** - * Gets the transparent form of a color. - * @param context [Context] required to create the color - * @param color The RESOURCE ID for the color - * @param alpha The new alpha that wants to be applied - * @return The new, resolved transparent color - */ -@ColorInt -fun getTransparentAccent(context: Context, @ColorRes color: Int, alpha: Int): Int { - return ColorUtils.setAlphaComponent( - color.toColor(context), - alpha - ) -} - -/** - * Resolve a color. - * @param context [Context] required - * @return The resolved color, black if the resolving process failed. - */ -@ColorInt -fun Int.toColor(context: Context): Int { - return try { - ContextCompat.getColor(context, this) - } catch (e: Resources.NotFoundException) { - logE("Attempted color load failed.") - - // Default to the emergency color [Black] if the loading fails. - ContextCompat.getColor(context, android.R.color.black) - } -} - -/** - * Get the name of an accent. - * @param context [Context] required - * @param newAccent The accent the name should be given for. - * @return The accent name according to the strings for this specific locale. - */ -fun getAccentItemSummary(context: Context, newAccent: Pair): String { - val accentIndex = ACCENTS.indexOf(newAccent) - - check(accentIndex != -1) { "Invalid accent given" } - - return context.getString(ACCENT_NAMES[accentIndex]) -} - -/** - * Get the name (in bold) and the hex value of a accent. - * @param context [Context] required - * @param newAccent Accent to get the information for - * @return A rendered span with the name in bold + the hex value of the accent. - */ -fun getDetailedAccentSummary(context: Context, newAccent: Pair): Spanned { - val name = getAccentItemSummary(context, newAccent) - val hex = context.getString(accent.first).toUpperCase(Locale.getDefault()) - - return context.getString( - R.string.format_accent_summary, - name, hex - ).toSpanned().render() -}