diff --git a/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt b/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt
index e25d0d739..de1195df2 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt
@@ -199,8 +199,6 @@ class DetailViewModel(application: Application) :
null
}
- // Ensure that we don't include the functionally useless
- // "audio/raw" mime type
MimeType(song.mimeType.fromExtension, formatMimeType)
}
diff --git a/app/src/main/java/org/oxycblt/auxio/image/BaseStyledImageView.kt b/app/src/main/java/org/oxycblt/auxio/image/BaseStyledImageView.kt
deleted file mode 100644
index 7d8e800ad..000000000
--- a/app/src/main/java/org/oxycblt/auxio/image/BaseStyledImageView.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2022 Auxio Project
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.oxycblt.auxio.image
-
-import android.content.Context
-import android.graphics.Canvas
-import android.graphics.ColorFilter
-import android.graphics.PixelFormat
-import android.graphics.drawable.Drawable
-import android.util.AttributeSet
-import androidx.annotation.AttrRes
-import androidx.annotation.DrawableRes
-import androidx.appcompat.widget.AppCompatImageView
-import androidx.core.graphics.drawable.DrawableCompat
-import coil.dispose
-import coil.load
-import com.google.android.material.shape.MaterialShapeDrawable
-import org.oxycblt.auxio.R
-import org.oxycblt.auxio.music.Album
-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.util.getColorStateListSafe
-import org.oxycblt.auxio.util.getDrawableSafe
-
-/**
- * The base class for Auxio's images. Do not use this class outside of this module.
- *
- * Default behavior includes the addition of a tonal background and automatic icon sizing. Other
- * behavior is implemented by [StyledImageView] and [ImageGroup].
- *
- * @author OxygenCobalt
- */
-open class BaseStyledImageView
-@JvmOverloads
-constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
- AppCompatImageView(context, attrs, defStyleAttr) {
- private var staticIcon = 0
-
- init {
- val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StyledImageView)
- staticIcon = styledAttrs.getResourceId(R.styleable.StyledImageView_staticIcon, -1)
- styledAttrs.recycle()
-
- if (staticIcon > -1) {
- @Suppress("LeakingThis")
- setImageDrawable(StyledDrawable(context, context.getDrawableSafe(staticIcon)))
- }
-
- background =
- MaterialShapeDrawable().apply {
- fillColor = context.getColorStateListSafe(R.color.sel_cover_bg)
- }
- }
-
- /** Bind the album cover for a [song]. */
- open fun bind(song: Song) = loadImpl(song, R.drawable.ic_song)
-
- /** Bind the album cover for an [album]. */
- open fun bind(album: Album) = loadImpl(album, R.drawable.ic_album)
-
- /** Bind the image for an [artist] */
- open fun bind(artist: Artist) = loadImpl(artist, R.drawable.ic_artist)
-
- /** Bind the image for a [genre] */
- open fun bind(genre: Genre) = loadImpl(genre, R.drawable.ic_genre)
-
- private fun loadImpl(music: T, @DrawableRes error: Int) {
- if (staticIcon > -1) {
- throw IllegalStateException("Static StyledImageViews cannot bind new images")
- }
-
- dispose()
- load(music) {
- error(StyledDrawable(context, error))
- transformations(SquareFrameTransform.INSTANCE)
- }
- }
-
- /**
- * A companion drawable that can be used with the style that [StyledImageView] provides.
- * @author OxygenCobalt
- */
- class StyledDrawable(context: Context, private val src: Drawable) : Drawable() {
- constructor(
- context: Context,
- @DrawableRes res: Int
- ) : this(context, context.getDrawableSafe(res))
-
- init {
- // Re-tint the drawable to something that will play along with the background
- DrawableCompat.setTintList(src, context.getColorStateListSafe(R.color.sel_on_cover_bg))
- }
-
- override fun draw(canvas: Canvas) {
- src.bounds.set(canvas.clipBounds)
- val adjustWidth = src.bounds.width() / 4
- val adjustHeight = src.bounds.height() / 4
- src.bounds.set(
- adjustWidth,
- adjustHeight,
- src.bounds.width() - adjustWidth,
- src.bounds.height() - adjustHeight)
- src.draw(canvas)
- }
-
- override fun setAlpha(alpha: Int) {
- src.alpha = alpha
- }
-
- override fun setColorFilter(colorFilter: ColorFilter?) {
- src.colorFilter = colorFilter
- }
-
- override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
- }
-}
diff --git a/app/src/main/java/org/oxycblt/auxio/image/ImageGroup.kt b/app/src/main/java/org/oxycblt/auxio/image/ImageGroup.kt
index 905f0a3b9..7432903f9 100644
--- a/app/src/main/java/org/oxycblt/auxio/image/ImageGroup.kt
+++ b/app/src/main/java/org/oxycblt/auxio/image/ImageGroup.kt
@@ -29,7 +29,6 @@ import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song
-import org.oxycblt.auxio.settings.SettingsManager
import org.oxycblt.auxio.util.getColorStateListSafe
import org.oxycblt.auxio.util.getDrawableSafe
@@ -52,13 +51,9 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
FrameLayout(context, attrs, defStyleAttr) {
private val cornerRadius: Float
- private val inner = BaseStyledImageView(context, attrs)
+ private val inner: StyledImageView
private var customView: View? = null
- private val indicator =
- BaseStyledImageView(context).apply {
- setImageDrawable(
- StyledDrawable(context, context.getDrawableSafe(R.drawable.ic_equalizer)))
- }
+ private val indicator: StyledImageView
init {
// Android wants you to make separate attributes for each view type, but will
@@ -68,23 +63,14 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
cornerRadius = styledAttrs.getDimension(R.styleable.StyledImageView_cornerRadius, 0f)
styledAttrs.recycle()
- addView(inner)
-
- // Use clipToOutline and a background drawable to crop images. While Coil's transformation
- // could theoretically be used to round corners, the corner radius is dependent on the
- // dimensions of the image, which will result in inconsistent corners across different
- // album covers unless we resize all covers to be the same size. clipToOutline is both
- // cheaper and more elegant. As a side-note, this also allows us to re-use the same
- // background for both the tonal background color and the corner rounding.
- background = MaterialShapeDrawable()
- clipToOutline = true
-
- if (!isInEditMode) {
- val settingsManager = SettingsManager.getInstance()
- if (settingsManager.roundCovers) {
- (background as MaterialShapeDrawable).setCornerSize(cornerRadius)
+ inner = StyledImageView(context, attrs)
+ indicator =
+ StyledImageView(context).apply {
+ cornerRadius = this@ImageGroup.cornerRadius
+ staticIcon = context.getDrawableSafe(R.drawable.ic_equalizer)
}
- }
+
+ addView(inner)
}
override fun onFinishInflate() {
@@ -99,6 +85,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
background =
MaterialShapeDrawable().apply {
fillColor = context.getColorStateListSafe(R.color.sel_cover_bg)
+ setCornerSize(cornerRadius)
}
}
diff --git a/app/src/main/java/org/oxycblt/auxio/image/StyledImageView.kt b/app/src/main/java/org/oxycblt/auxio/image/StyledImageView.kt
index 87dde24b3..bc90edb2e 100644
--- a/app/src/main/java/org/oxycblt/auxio/image/StyledImageView.kt
+++ b/app/src/main/java/org/oxycblt/auxio/image/StyledImageView.kt
@@ -18,16 +18,25 @@
package org.oxycblt.auxio.image
import android.content.Context
+import android.graphics.drawable.Drawable
import android.util.AttributeSet
import androidx.annotation.AttrRes
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
import androidx.appcompat.widget.AppCompatImageView
+import androidx.core.content.res.ResourcesCompat
+import coil.dispose
+import coil.load
import com.google.android.material.shape.MaterialShapeDrawable
import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.Album
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
+import org.oxycblt.auxio.util.getColorStateListSafe
+import org.oxycblt.auxio.util.getDrawableSafe
/**
* An [AppCompatImageView] that applies many of the stylistic choices that Auxio uses regarding
@@ -41,14 +50,27 @@ import org.oxycblt.auxio.settings.SettingsManager
class StyledImageView
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
- BaseStyledImageView(context, attrs, defStyleAttr) {
- private var cornerRadius = 0f
+ AppCompatImageView(context, attrs, defStyleAttr) {
+ var cornerRadius = 0f
+ set(value) {
+ field = value
+ (background as? MaterialShapeDrawable)?.let { bg ->
+ if (!isInEditMode && SettingsManager.getInstance().roundCovers) {
+ bg.setCornerSize(value)
+ } else {
+ bg.setCornerSize(0f)
+ }
+ }
+ }
+
+ var staticIcon: Drawable? = null
+ set(value) {
+ val wrapped = value?.let { StyledDrawable(context, it) }
+ field = wrapped
+ setImageDrawable(field)
+ }
init {
- val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StyledImageView)
- cornerRadius = styledAttrs.getDimension(R.styleable.StyledImageView_cornerRadius, 0f)
- styledAttrs.recycle()
-
// Use clipToOutline and a background drawable to crop images. While Coil's transformation
// could theoretically be used to round corners, the corner radius is dependent on the
// dimensions of the image, which will result in inconsistent corners across different
@@ -56,36 +78,47 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
// cheaper and more elegant. As a side-note, this also allows us to re-use the same
// background for both the tonal background color and the corner rounding.
clipToOutline = true
-
- if (!isInEditMode) {
- val settingsManager = SettingsManager.getInstance()
- if (settingsManager.roundCovers) {
- (background as MaterialShapeDrawable).setCornerSize(cornerRadius)
+ background =
+ MaterialShapeDrawable().apply {
+ fillColor = context.getColorStateListSafe(R.color.sel_cover_bg)
+ setCornerSize(cornerRadius)
}
+
+ val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StyledImageView)
+ val staticIconRes =
+ styledAttrs.getResourceId(
+ R.styleable.StyledImageView_staticIcon, ResourcesCompat.ID_NULL)
+ if (staticIconRes != ResourcesCompat.ID_NULL) {
+ staticIcon = context.getDrawableSafe(staticIconRes)
+ }
+
+ cornerRadius = styledAttrs.getDimension(R.styleable.StyledImageView_cornerRadius, 0f)
+ styledAttrs.recycle()
+ }
+
+ /** Bind the album cover for a [song]. */
+ fun bind(song: Song) = loadImpl(song, R.drawable.ic_song, R.string.desc_album_cover)
+
+ /** Bind the album cover for an [album]. */
+ fun bind(album: Album) = loadImpl(album, R.drawable.ic_album, R.string.desc_album_cover)
+
+ /** Bind the image for an [artist] */
+ fun bind(artist: Artist) = loadImpl(artist, R.drawable.ic_artist, R.string.desc_artist_image)
+
+ /** Bind the image for a [genre] */
+ fun bind(genre: Genre) = loadImpl(genre, R.drawable.ic_genre, R.string.desc_genre_image)
+
+ private fun loadImpl(music: T, @DrawableRes error: Int, @StringRes desc: Int) {
+ if (staticIcon != null) {
+ error("Static StyledImageViews cannot bind new images")
+ }
+
+ contentDescription = context.getString(desc, music.resolveName(context))
+
+ dispose()
+ load(music) {
+ error(StyledDrawable(context, context.getDrawableSafe(error)))
+ transformations(SquareFrameTransform.INSTANCE)
}
}
-
- override fun bind(song: Song) {
- super.bind(song)
- contentDescription =
- context.getString(R.string.desc_album_cover, song.album.resolveName(context))
- }
-
- override fun bind(album: Album) {
- super.bind(album)
- contentDescription =
- context.getString(R.string.desc_album_cover, album.resolveName(context))
- }
-
- override fun bind(artist: Artist) {
- super.bind(artist)
- contentDescription =
- context.getString(R.string.desc_artist_image, artist.resolveName(context))
- }
-
- override fun bind(genre: Genre) {
- super.bind(genre)
- contentDescription =
- context.getString(R.string.desc_genre_image, genre.resolveName(context))
- }
}