image: make coverview respond to settings
Make CoverView respond to all cover settings and the round mode setting.
This commit is contained in:
parent
e490ff64c1
commit
ada446767d
5 changed files with 69 additions and 31 deletions
|
@ -6,9 +6,10 @@
|
||||||
- Menus have been refreshed with a cleaner look
|
- Menus have been refreshed with a cleaner look
|
||||||
|
|
||||||
#### What's Fixed
|
#### What's Fixed
|
||||||
- Fixed issue where one could not navigate to settings after navigating
|
- Fixed issue where one could not navigate to settings after navigating elsewhere
|
||||||
elsewhere
|
|
||||||
- Fixed the queue list being non-scrollable in certain cases
|
- Fixed the queue list being non-scrollable in certain cases
|
||||||
|
- Fixed notification album covers not updating after changing the cover
|
||||||
|
aspect ratio setting
|
||||||
|
|
||||||
#### Dev/Meta
|
#### Dev/Meta
|
||||||
- Unified navigation graph
|
- Unified navigation graph
|
||||||
|
|
|
@ -76,14 +76,14 @@ import org.oxycblt.auxio.util.getInteger
|
||||||
class CoverView
|
class CoverView
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
|
constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
|
||||||
FrameLayout(context, attrs, defStyleAttr) {
|
FrameLayout(context, attrs, defStyleAttr), ImageSettings.Listener, UISettings.Listener {
|
||||||
@Inject lateinit var imageLoader: ImageLoader
|
@Inject lateinit var imageLoader: ImageLoader
|
||||||
@Inject lateinit var uiSettings: UISettings
|
@Inject lateinit var uiSettings: UISettings
|
||||||
@Inject lateinit var imageSettings: ImageSettings
|
@Inject lateinit var imageSettings: ImageSettings
|
||||||
|
|
||||||
private val image: ImageView
|
private val image: ImageView
|
||||||
|
|
||||||
data class PlaybackIndicator(
|
private data class PlaybackIndicator(
|
||||||
val view: ImageView,
|
val view: ImageView,
|
||||||
val playingDrawable: AnimationDrawable,
|
val playingDrawable: AnimationDrawable,
|
||||||
val pausedDrawable: Drawable
|
val pausedDrawable: Drawable
|
||||||
|
@ -91,27 +91,30 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
private val playbackIndicator: PlaybackIndicator?
|
private val playbackIndicator: PlaybackIndicator?
|
||||||
private val selectionBadge: ImageView?
|
private val selectionBadge: ImageView?
|
||||||
|
|
||||||
|
private val sizing: Int
|
||||||
@DimenRes private val iconSizeRes: Int?
|
@DimenRes private val iconSizeRes: Int?
|
||||||
@DimenRes private val cornerRadiusRes: Int?
|
@DimenRes private var cornerRadiusRes: Int?
|
||||||
|
|
||||||
private var fadeAnimator: ValueAnimator? = null
|
private var fadeAnimator: ValueAnimator? = null
|
||||||
private val indicatorMatrix = Matrix()
|
private val indicatorMatrix = Matrix()
|
||||||
private val indicatorMatrixSrc = RectF()
|
private val indicatorMatrixSrc = RectF()
|
||||||
private val indicatorMatrixDst = RectF()
|
private val indicatorMatrixDst = RectF()
|
||||||
|
|
||||||
|
private data class Cover(
|
||||||
|
val songs: Collection<Song>,
|
||||||
|
val desc: String,
|
||||||
|
@DrawableRes val errorRes: Int
|
||||||
|
)
|
||||||
|
private var currentCover: Cover? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// Obtain some StyledImageView attributes to use later when theming the custom view.
|
// Obtain some StyledImageView attributes to use later when theming the custom view.
|
||||||
@SuppressLint("CustomViewStyleable")
|
@SuppressLint("CustomViewStyleable")
|
||||||
val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.CoverView)
|
val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.CoverView)
|
||||||
|
|
||||||
val sizing = styledAttrs.getIntOrThrow(R.styleable.CoverView_sizing)
|
sizing = styledAttrs.getIntOrThrow(R.styleable.CoverView_sizing)
|
||||||
iconSizeRes = SIZING_ICON_SIZE[sizing]
|
iconSizeRes = SIZING_ICON_SIZE[sizing]
|
||||||
cornerRadiusRes =
|
cornerRadiusRes = getCornerRadiusRes()
|
||||||
if (uiSettings.roundMode) {
|
|
||||||
SIZING_CORNER_RADII[sizing]
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val playbackIndicatorEnabled =
|
val playbackIndicatorEnabled =
|
||||||
styledAttrs.getBoolean(R.styleable.CoverView_enablePlaybackIndicator, true)
|
styledAttrs.getBoolean(R.styleable.CoverView_enablePlaybackIndicator, true)
|
||||||
|
@ -149,6 +152,9 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageSettings.registerListener(this)
|
||||||
|
uiSettings.registerListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFinishInflate() {
|
override fun onFinishInflate() {
|
||||||
|
@ -161,19 +167,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
|
|
||||||
playbackIndicator?.run { addView(view) }
|
playbackIndicator?.run { addView(view) }
|
||||||
|
|
||||||
// Add backgrounds to each child for visual consistency
|
applyBackgroundsToChildren()
|
||||||
for (child in children) {
|
|
||||||
child.apply {
|
|
||||||
// If there are rounded corners, we want to make sure view content will be cropped
|
|
||||||
// with it.
|
|
||||||
clipToOutline = this != image
|
|
||||||
background =
|
|
||||||
MaterialShapeDrawable().apply {
|
|
||||||
fillColor = context.getColorCompat(R.color.sel_cover_bg)
|
|
||||||
setCornerSize(cornerRadiusRes?.let(context::getDimen) ?: 0f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The selection badge has it's own background we don't want overridden, add it after
|
// The selection badge has it's own background we don't want overridden, add it after
|
||||||
// all other elements.
|
// all other elements.
|
||||||
|
@ -191,6 +185,24 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow()
|
||||||
|
imageSettings.unregisterListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onImageSettingsChanged() {
|
||||||
|
val cover = currentCover ?: return
|
||||||
|
bind(cover.songs, cover.desc, cover.errorRes)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRoundModeChanged() {
|
||||||
|
// TODO: Make this a recreate as soon as you can make the bottom sheet stop freaking out
|
||||||
|
cornerRadiusRes = getCornerRadiusRes()
|
||||||
|
applyBackgroundsToChildren()
|
||||||
|
val cover = currentCover ?: return
|
||||||
|
bind(cover.songs, cover.desc, cover.errorRes)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
|
|
||||||
|
@ -261,6 +273,29 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getCornerRadiusRes() =
|
||||||
|
if (uiSettings.roundMode) {
|
||||||
|
SIZING_CORNER_RADII[sizing]
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun applyBackgroundsToChildren() {
|
||||||
|
// Add backgrounds to each child for visual consistency
|
||||||
|
for (child in children) {
|
||||||
|
child.apply {
|
||||||
|
// If there are rounded corners, we want to make sure view content will be cropped
|
||||||
|
// with it.
|
||||||
|
clipToOutline = this != image
|
||||||
|
background =
|
||||||
|
MaterialShapeDrawable().apply {
|
||||||
|
fillColor = context.getColorCompat(R.color.sel_cover_bg)
|
||||||
|
setCornerSize(cornerRadiusRes?.let(context::getDimen) ?: 0f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun invalidateRootAlpha() {
|
private fun invalidateRootAlpha() {
|
||||||
alpha = if (isEnabled || isSelected) 1f else 0.5f
|
alpha = if (isEnabled || isSelected) 1f else 0.5f
|
||||||
}
|
}
|
||||||
|
@ -401,6 +436,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
CoilUtils.dispose(image)
|
CoilUtils.dispose(image)
|
||||||
imageLoader.enqueue(request.build())
|
imageLoader.enqueue(request.build())
|
||||||
contentDescription = desc
|
contentDescription = desc
|
||||||
|
currentCover = Cover(songs, desc, errorRes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,7 +39,7 @@ interface ImageSettings : Settings<ImageSettings.Listener> {
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
/** Called when [coverMode] changes. */
|
/** Called when [coverMode] changes. */
|
||||||
fun onCoverModeChanged() {}
|
fun onImageSettingsChanged() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,9 +77,10 @@ class ImageSettingsImpl @Inject constructor(@ApplicationContext context: Context
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSettingChanged(key: String, listener: ImageSettings.Listener) {
|
override fun onSettingChanged(key: String, listener: ImageSettings.Listener) {
|
||||||
if (key == getString(R.string.set_key_cover_mode)) {
|
if (key == getString(R.string.set_key_cover_mode) ||
|
||||||
logD("Dispatching cover mode setting change")
|
key == getString(R.string.set_key_square_covers)) {
|
||||||
listener.onCoverModeChanged()
|
logD("Dispatching image setting change")
|
||||||
|
listener.onImageSettingsChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ constructor(
|
||||||
|
|
||||||
// --- SETTINGS OVERRIDES ---
|
// --- SETTINGS OVERRIDES ---
|
||||||
|
|
||||||
override fun onCoverModeChanged() {
|
override fun onImageSettingsChanged() {
|
||||||
// Need to reload the metadata cover.
|
// Need to reload the metadata cover.
|
||||||
updateMediaMetadata(playbackManager.queue.currentSong, playbackManager.parent)
|
updateMediaMetadata(playbackManager.queue.currentSong, playbackManager.parent)
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ constructor(
|
||||||
|
|
||||||
// Respond to settings changes that will affect the widget
|
// Respond to settings changes that will affect the widget
|
||||||
override fun onRoundModeChanged() = update()
|
override fun onRoundModeChanged() = update()
|
||||||
override fun onCoverModeChanged() = update()
|
override fun onImageSettingsChanged() = update()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A condensed form of the playback state that is safe to use in AppWidgets.
|
* A condensed form of the playback state that is safe to use in AppWidgets.
|
||||||
|
|
Loading…
Reference in a new issue