From 61dbfe31857a7d83688e36e1f3d27af4792e966b Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Wed, 23 Feb 2022 17:36:17 -0700 Subject: [PATCH] coil: make rounded images more nuanced Create a custom view for rounded images, making them more nuanced in the process. The previous method for applying rounded images in-app was generally clunky and fragile. Introduce a new custom view that actually takes a cornerRadius attribute from the ImageView itself that then applies it whenever the user enables the setting. This also allows rounded images to be more nuanced, as typical 8dp elevation can be used for small views and a more fitting 16dp radius can be used for large views. --- CHANGELOG.md | 1 + .../java/org/oxycblt/auxio/MainFragment.kt | 4 -- .../java/org/oxycblt/auxio/coil/CoilUtils.kt | 16 -------- .../oxycblt/auxio/coil/RoundableImageView.kt | 41 +++++++++++++++++++ .../org/oxycblt/auxio/home/HomeFragment.kt | 12 +++--- .../main/res/drawable/ui_rounded_cutout.xml | 5 --- .../main/res/layout-h600dp/item_detail.xml | 2 +- .../res/layout-land/fragment_playback.xml | 2 +- app/src/main/res/layout-land/item_detail.xml | 2 +- .../layout-sw600dp-land/fragment_playback.xml | 2 +- .../res/layout-sw600dp/fragment_playback.xml | 2 +- .../main/res/layout-sw600dp/item_detail.xml | 2 +- .../res/layout-sw640dp/view_playback_bar.xml | 2 +- .../main/res/layout-sw840dp/item_detail.xml | 2 +- .../layout-w600dp-land/fragment_playback.xml | 2 +- .../res/layout-w600dp/view_playback_bar.xml | 2 +- app/src/main/res/layout/fragment_playback.xml | 2 +- app/src/main/res/layout/item_album.xml | 2 +- app/src/main/res/layout/item_album_song.xml | 1 - app/src/main/res/layout/item_artist.xml | 2 +- app/src/main/res/layout/item_artist_album.xml | 2 +- app/src/main/res/layout/item_artist_song.xml | 2 +- app/src/main/res/layout/item_detail.xml | 2 +- app/src/main/res/layout/item_genre.xml | 2 +- app/src/main/res/layout/item_genre_song.xml | 2 +- app/src/main/res/layout/item_queue_song.xml | 2 +- app/src/main/res/layout/item_song.xml | 2 +- app/src/main/res/layout/view_playback_bar.xml | 2 +- app/src/main/res/values/attrs.xml | 4 ++ app/src/main/res/values/dimens.xml | 4 +- app/src/main/res/values/styles_ui.xml | 6 +++ 31 files changed, 83 insertions(+), 53 deletions(-) create mode 100644 app/src/main/java/org/oxycblt/auxio/coil/RoundableImageView.kt delete mode 100644 app/src/main/res/drawable/ui_rounded_cutout.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a43bb930..7e5b20bdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## dev [v2.2.2 or 2.3.0] #### What's Improved +- Rounded images are more nuanced - Shuffle and Repeat mode buttons now have more contrast when they are turned on #### What's Changed diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index a19d45c0a..b61c315c8 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -79,10 +79,6 @@ class MainFragment : Fragment() { // but for some insane reason google decided to cripple the window APIs one could use // to limit it's size. So, we just have our own special layout that is shown whenever // the screen is too small because of course we have to. - // Another fun fact: smallestScreenWidthDp is completely bugged and uses the total - // screen size, even when the window is smaller. This basically borks split screen - // even more than it already does. Fun! - if (requireActivity().isInMultiWindowMode) { val config = resources.configuration diff --git a/app/src/main/java/org/oxycblt/auxio/coil/CoilUtils.kt b/app/src/main/java/org/oxycblt/auxio/coil/CoilUtils.kt index 85464857d..c65aff867 100644 --- a/app/src/main/java/org/oxycblt/auxio/coil/CoilUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/coil/CoilUtils.kt @@ -35,7 +35,6 @@ import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Song -import org.oxycblt.auxio.settings.SettingsManager // --- BINDING ADAPTERS --- @@ -66,21 +65,6 @@ fun ImageView.bindGenreImage(genre: Genre?) = load(genre, R.drawable.ic_genre) fun ImageView.load(music: T?, @DrawableRes error: Int) { dispose() - // We don't round album covers by default as it desecrates album artwork, but we do provide - // an option if one wants it. - // As for why we use clipToOutline instead of coils RoundedCornersTransformation, the radii - // of an image's corners is dependent on the actual dimensions of the image, which would force - // us to resize all images to a fixed size. clipToOutline is pretty much always cheaper as long - // as we have a perfectly-square image. - val settingsManager = SettingsManager.getInstance() - if (settingsManager.roundCovers && background == null) { - setBackgroundResource(R.drawable.ui_rounded_cutout) - clipToOutline = true - } else if (!settingsManager.roundCovers && background != null) { - background = null - clipToOutline = false - } - load(music) { error(error) transformations(SquareFrameTransform()) diff --git a/app/src/main/java/org/oxycblt/auxio/coil/RoundableImageView.kt b/app/src/main/java/org/oxycblt/auxio/coil/RoundableImageView.kt new file mode 100644 index 000000000..61ff16ac3 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/coil/RoundableImageView.kt @@ -0,0 +1,41 @@ +package org.oxycblt.auxio.coil + +import android.content.Context +import android.util.AttributeSet +import androidx.annotation.AttrRes +import androidx.appcompat.widget.AppCompatImageView +import com.google.android.material.shape.MaterialShapeDrawable +import org.oxycblt.auxio.R +import org.oxycblt.auxio.settings.SettingsManager +import org.oxycblt.auxio.util.getColorSafe +import org.oxycblt.auxio.util.stateList + +class RoundableImageView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + @AttrRes defStyleAttr: Int = 0 +) : AppCompatImageView(context, attrs, defStyleAttr) { + init { + val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.RoundableImageView) + val cornerRadius = styledAttrs.getDimension(R.styleable.RoundableImageView_cornerRadius, 0.0f) + styledAttrs.recycle() + + background = MaterialShapeDrawable().apply { + setCornerSize(cornerRadius) + fillColor = context.getColorSafe(android.R.color.transparent).stateList + } + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + + // We don't round album covers by default as it desecrates album artwork, but we do + // provide an option if one wants it. + // As for why we use clipToOutline instead of coils RoundedCornersTransformation, the radii + // of an image's corners is dependent on the actual dimensions of the image, which would + // force us to resize all images to a fixed size. clipToOutline is pretty much always + // cheaper as long as we have a perfectly-square image. + val settingsManager = SettingsManager.getInstance() + clipToOutline = settingsManager.roundCovers + } +} diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt index f5fe3f216..c89ccb972 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt @@ -159,7 +159,9 @@ class HomeFragment : Fragment() { ).attach() } - binding.homeShuffleFab.setup(playbackModel) + binding.homeFab.setOnClickListener { + playbackModel.shuffleAll() + } // --- VIEWMODEL SETUP --- @@ -169,12 +171,12 @@ class HomeFragment : Fragment() { musicModel.loaderResponse.observe(viewLifecycleOwner) { response -> // Handle the loader response. when (response) { - is MusicStore.Response.Ok -> binding.homeShuffleFab.show() + is MusicStore.Response.Ok -> binding.homeFab.show() // While loading or during an error, make sure we keep the shuffle fab hidden so // that any kind of playback is impossible. PlaybackStateManager also relies on this // invariant, so please don't change it. - else -> binding.homeShuffleFab.hide() + else -> binding.homeFab.hide() } } @@ -186,9 +188,9 @@ class HomeFragment : Fragment() { } if (scrolling) { - binding.homeShuffleFab.hide() + binding.homeFab.hide() } else { - binding.homeShuffleFab.show() + binding.homeFab.show() } } diff --git a/app/src/main/res/drawable/ui_rounded_cutout.xml b/app/src/main/res/drawable/ui_rounded_cutout.xml deleted file mode 100644 index 00d969fd3..000000000 --- a/app/src/main/res/drawable/ui_rounded_cutout.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/layout-h600dp/item_detail.xml b/app/src/main/res/layout-h600dp/item_detail.xml index 21e2f021a..02a1eff41 100644 --- a/app/src/main/res/layout-h600dp/item_detail.xml +++ b/app/src/main/res/layout-h600dp/item_detail.xml @@ -10,7 +10,7 @@ android:layout_height="match_parent" android:padding="@dimen/spacing_medium"> - - - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index f29dcde96..270cf530d 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,7 +1,6 @@ - 4dp 8dp 16dp 24dp @@ -17,6 +16,9 @@ 192dp 256dp + 8dp + 16dp + 32dp 32dp diff --git a/app/src/main/res/values/styles_ui.xml b/app/src/main/res/values/styles_ui.xml index ae84084c5..413acece4 100644 --- a/app/src/main/res/values/styles_ui.xml +++ b/app/src/main/res/values/styles_ui.xml @@ -26,32 +26,38 @@