style: add basic black theme

Finally add black theme support to Auxio. This is abit of a janky
implementation since I had to add an extra set of accents, but it
shouldn't be as big of a problem after the styles refactoring.
Support for black android components is not implemented yet, but
will be eventually.
This commit is contained in:
OxygenCobalt 2021-06-11 09:08:04 -06:00
parent dc2157904a
commit 68bdd0d929
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
12 changed files with 232 additions and 25 deletions

View file

@ -15,6 +15,7 @@ import org.oxycblt.auxio.playback.system.PlaybackService
import org.oxycblt.auxio.settings.SettingsManager
import org.oxycblt.auxio.ui.Accent
import org.oxycblt.auxio.ui.isEdgeOn
import org.oxycblt.auxio.ui.isNight
/**
* The single [AppCompatActivity] for Auxio.
@ -25,11 +26,7 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val settingsManager = SettingsManager.getInstance()
val newAccent = Accent.set(settingsManager.accent)
AppCompatDelegate.setDefaultNightMode(settingsManager.theme)
setTheme(newAccent.theme)
setupTheme()
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(
this, R.layout.activity_main
@ -52,6 +49,22 @@ class MainActivity : AppCompatActivity() {
onNewIntent(intent)
}
private fun setupTheme() {
// Update the current accent and theme
val settingsManager = SettingsManager.getInstance()
AppCompatDelegate.setDefaultNightMode(settingsManager.theme)
val newAccent = Accent.set(settingsManager.accent)
// The black theme has a completely separate set of styles since style attributes cannot
// be modified at runtime.
if (isNight() && settingsManager.useBlackTheme) {
setTheme(newAccent.blackTheme)
} else {
setTheme(newAccent.theme)
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)

View file

@ -18,6 +18,7 @@ import org.oxycblt.auxio.settings.blacklist.BlacklistDialog
import org.oxycblt.auxio.settings.ui.IntListPrefDialog
import org.oxycblt.auxio.settings.ui.IntListPreference
import org.oxycblt.auxio.ui.Accent
import org.oxycblt.auxio.ui.isNight
import org.oxycblt.auxio.ui.showToast
/**
@ -82,6 +83,16 @@ class SettingsListFragment : PreferenceFragmentCompat() {
}
}
SettingsManager.KEY_BLACK_THEME -> {
onPreferenceClickListener = Preference.OnPreferenceClickListener {
if (requireContext().isNight()) {
requireActivity().recreate()
}
true
}
}
SettingsManager.KEY_ACCENT -> {
onPreferenceClickListener = Preference.OnPreferenceClickListener {
AccentDialog().show(childFragmentManager, AccentDialog.TAG)

View file

@ -32,6 +32,10 @@ class SettingsManager private constructor(context: Context) :
val theme: Int
get() = handleThemeCompat(sharedPrefs)
/** Whether the dark theme should be black or not */
val useBlackTheme: Boolean
get() = sharedPrefs.getBoolean(KEY_BLACK_THEME, false)
/** The current accent. */
var accent: Accent
get() = handleAccentCompat(sharedPrefs)
@ -195,6 +199,7 @@ class SettingsManager private constructor(context: Context) :
companion object {
const val KEY_THEME = "KEY_THEME2"
const val KEY_BLACK_THEME = "KEY_BLACK_THEME"
const val KEY_ACCENT = "KEY_ACCENT2"
const val KEY_LIB_DISPLAY_MODE = "KEY_LIB_MODE"

View file

@ -15,34 +15,85 @@ import org.oxycblt.auxio.R
* 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.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.red, R.style.Theme_Red, R.style.Theme_Red_Black, R.string.color_label_red),
Accent(R.color.pink, R.style.Theme_Pink, R.style.Theme_Pink_Black, R.string.color_label_pink),
Accent(
R.color.purple,
R.style.Theme_Purple,
R.style.Theme_Purple_Black,
R.string.color_label_purple
),
Accent(
R.color.deep_purple,
R.style.Theme_DeepPurple,
R.style.Theme_DeepPurple_Black,
R.string.color_label_deep_purple
),
Accent(
R.color.indigo,
R.style.Theme_Indigo,
R.style.Theme_Indigo_Black,
R.string.color_label_indigo
),
Accent(R.color.blue, R.style.Theme_Blue, R.style.Theme_Blue_Black, R.string.color_label_blue),
Accent(
R.color.light_blue,
R.style.Theme_LightBlue,
R.style.Theme_LightBlue_Black,
R.string.color_label_light_blue
),
Accent(R.color.cyan, R.style.Theme_Cyan, R.style.Theme_Cyan_Black, R.string.color_label_cyan),
Accent(R.color.teal, R.style.Theme_Teal, R.style.Theme_Teal_Black, R.string.color_label_teal),
Accent(R.color.green, R.style.Theme_Green, R.style.Theme_Green_Black, R.string.color_label_green),
Accent(
R.color.light_green,
R.style.Theme_LightGreen,
R.style.Theme_LightGreen_Black,
R.string.color_label_light_green
),
Accent(R.color.lime, R.style.Theme_Lime, R.style.Theme_Lime_Black, R.string.color_label_lime),
Accent(
R.color.yellow,
R.style.Theme_Yellow,
R.style.Theme_Yellow_Black,
R.string.color_label_yellow
),
Accent(
R.color.orange,
R.style.Theme_Orange,
R.style.Theme_Orange_Black,
R.string.color_label_orange
),
Accent(
R.color.deep_orange,
R.style.Theme_DeepOrange,
R.style.Theme_DeepOrange_Black,
R.string.color_label_deep_orange
),
Accent(R.color.brown, R.style.Theme_Brown, R.style.Theme_Brown_Black, R.string.color_label_brown),
Accent(R.color.grey, R.style.Theme_Grey, R.style.Theme_Grey_Black, R.string.color_label_grey),
Accent(
R.color.blue_grey,
R.style.Theme_BlueGrey,
R.style.Theme_BlueGrey_Black,
R.string.color_label_blue_grey
),
)
/**
* The data object for an accent.
* @property color The color resource for this accent
* @property theme The theme resource for this accent
* @property blackTheme The black theme resource for this accent
* @property name The name of this accent
* @author OxygenCobalt
*/
data class Accent(@ColorRes val color: Int, @StyleRes val theme: Int, @StringRes val name: Int) {
data class Accent(
@ColorRes val color: Int,
@StyleRes val theme: Int,
@StyleRes val blackTheme: Int,
@StringRes val name: Int
) {
/**
* Get a [ColorStateList] of the accent
*/

View file

@ -78,6 +78,15 @@ fun <T : Any> Context.getSystemServiceSafe(serviceClass: KClass<T>): T {
}
}
/**
* Returns whether the current UI is in night mode or not. This will work if the theme is
* automatic as well.
*/
fun Context.isNight(): Boolean {
return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
Configuration.UI_MODE_NIGHT_YES
}
/**
* Resolve a color.
* @param context [Context] required

View file

@ -79,6 +79,7 @@
android:layout_marginStart="@dimen/spacing_mid_large"
android:layout_marginEnd="@dimen/spacing_mid_large"
android:layout_marginBottom="@dimen/spacing_medium"
android:text="@{song.album.name}"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}"
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -7,6 +7,8 @@
<color name="control_color">#202020</color>
<color name="nav_color">#01fafafa</color>
<color name="background_black">#000000</color>
<color name="selection_color_black">#343434</color>
<!--
Base color set derived from Music Player GO.

View file

@ -63,6 +63,8 @@
<string name="setting_theme_day">Light</string>
<string name="setting_theme_night">Dark</string>
<string name="setting_accent">Accent</string>
<string name="setting_black_mode">Black night theme</string>
<string name="setting_black_mode_desc">Use a pure-black night theme</string>
<string name="setting_display">Display</string>
<string name="setting_lib_display">Library Items</string>

View file

@ -36,4 +36,9 @@
<item name="materialAlertDialogTheme">@style/Theme.CustomDialog</item>
<!-- @formatter:on -->
</style>
<style name="Theme.Base.Black" parent="Theme.Base">
<item name="colorSurface">@color/background_black</item>
<item name="colorControlHighlight">@color/selection_color_black</item>
</style>
</resources>

View file

@ -83,7 +83,7 @@
<item name="colorSecondary">@color/brown</item>
</style>
<style name="Theme.Gray" parent="Theme.Base">
<style name="Theme.Grey" parent="Theme.Base">
<item name="colorPrimary">@color/grey</item>
<item name="colorSecondary">@color/grey</item>
</style>

View file

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
All the base themes/accents for black mode.
-->
<style name="Theme.Red.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/red</item>
<item name="colorSecondary">@color/red</item>
</style>
<style name="Theme.Pink.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/pink</item>
<item name="colorSecondary">@color/pink</item>
</style>
<style name="Theme.Purple.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/purple</item>
<item name="colorSecondary">@color/purple</item>
</style>
<style name="Theme.DeepPurple.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/deep_purple</item>
<item name="colorSecondary">@color/deep_purple</item>
</style>
<style name="Theme.Indigo.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/indigo</item>
<item name="colorSecondary">@color/indigo</item>
</style>
<style name="Theme.Blue.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/blue</item>
<item name="colorSecondary">@color/blue</item>
</style>
<style name="Theme.LightBlue.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/light_blue</item>
<item name="colorSecondary">@color/light_blue</item>
</style>
<style name="Theme.Cyan.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/cyan</item>
<item name="colorSecondary">@color/cyan</item>
</style>
<style name="Theme.Teal.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/teal</item>
<item name="colorSecondary">@color/teal</item>
</style>
<style name="Theme.Green.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/green</item>
<item name="colorSecondary">@color/green</item>
</style>
<style name="Theme.LightGreen.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/light_green</item>
<item name="colorSecondary">@color/light_green</item>
</style>
<style name="Theme.Lime.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/lime</item>
<item name="colorSecondary">@color/lime</item>
</style>
<style name="Theme.Yellow.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/yellow</item>
<item name="colorSecondary">@color/yellow</item>
</style>
<style name="Theme.Orange.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/orange</item>
<item name="colorSecondary">@color/orange</item>
</style>
<style name="Theme.DeepOrange.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/deep_orange</item>
<item name="colorSecondary">@color/deep_orange</item>
</style>
<style name="Theme.Brown.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/brown</item>
<item name="colorSecondary">@color/brown</item>
</style>
<style name="Theme.Grey.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/grey</item>
<item name="colorSecondary">@color/grey</item>
</style>
<style name="Theme.BlueGrey.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/blue_grey</item>
<item name="colorSecondary">@color/blue_grey</item>
</style>
<style name="Theme.Neutral.Black" parent="Theme.Base.Black">
<item name="colorPrimary">@color/control_color</item>
<item name="colorSecondary">@color/control_color</item>
</style>
</resources>

View file

@ -20,6 +20,14 @@
app:summary="@string/color_label_blue"
app:title="@string/setting_accent" />
<SwitchPreferenceCompat
app:defaultValue="true"
app:iconSpaceReserved="false"
app:key="KEY_BLACK_THEME"
app:title="@string/setting_black_mode"
app:summary="@string/setting_black_mode_desc"
app:allowDividerBelow="false" />
</PreferenceCategory>
<PreferenceCategory