From ada446767d534f0a7b417f2bed344976030b61ab Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Tue, 4 Jul 2023 14:55:36 -0600 Subject: [PATCH] image: make coverview respond to settings Make CoverView respond to all cover settings and the round mode setting. --- CHANGELOG.md | 5 +- .../java/org/oxycblt/auxio/image/CoverView.kt | 82 +++++++++++++------ .../org/oxycblt/auxio/image/ImageSettings.kt | 9 +- .../playback/system/MediaSessionComponent.kt | 2 +- .../oxycblt/auxio/widgets/WidgetComponent.kt | 2 +- 5 files changed, 69 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 788f25287..6024de838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,10 @@ - Menus have been refreshed with a cleaner look #### What's Fixed -- Fixed issue where one could not navigate to settings after navigating -elsewhere +- Fixed issue where one could not navigate to settings after navigating elsewhere - 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 - Unified navigation graph diff --git a/app/src/main/java/org/oxycblt/auxio/image/CoverView.kt b/app/src/main/java/org/oxycblt/auxio/image/CoverView.kt index 1ec38068e..41662f93a 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/CoverView.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/CoverView.kt @@ -76,14 +76,14 @@ import org.oxycblt.auxio.util.getInteger class CoverView @JvmOverloads 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 uiSettings: UISettings @Inject lateinit var imageSettings: ImageSettings private val image: ImageView - data class PlaybackIndicator( + private data class PlaybackIndicator( val view: ImageView, val playingDrawable: AnimationDrawable, val pausedDrawable: Drawable @@ -91,27 +91,30 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr private val playbackIndicator: PlaybackIndicator? private val selectionBadge: ImageView? + private val sizing: Int @DimenRes private val iconSizeRes: Int? - @DimenRes private val cornerRadiusRes: Int? + @DimenRes private var cornerRadiusRes: Int? private var fadeAnimator: ValueAnimator? = null private val indicatorMatrix = Matrix() private val indicatorMatrixSrc = RectF() private val indicatorMatrixDst = RectF() + private data class Cover( + val songs: Collection, + val desc: String, + @DrawableRes val errorRes: Int + ) + private var currentCover: Cover? = null + init { // Obtain some StyledImageView attributes to use later when theming the custom view. @SuppressLint("CustomViewStyleable") 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] - cornerRadiusRes = - if (uiSettings.roundMode) { - SIZING_CORNER_RADII[sizing] - } else { - null - } + cornerRadiusRes = getCornerRadiusRes() val playbackIndicatorEnabled = styledAttrs.getBoolean(R.styleable.CoverView_enablePlaybackIndicator, true) @@ -149,6 +152,9 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr } else { null } + + imageSettings.registerListener(this) + uiSettings.registerListener(this) } override fun onFinishInflate() { @@ -161,19 +167,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr playbackIndicator?.run { addView(view) } - // 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) - } - } - } + applyBackgroundsToChildren() // The selection badge has it's own background we don't want overridden, add it after // 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) { 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() { alpha = if (isEnabled || isSelected) 1f else 0.5f } @@ -401,6 +436,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr CoilUtils.dispose(image) imageLoader.enqueue(request.build()) contentDescription = desc + currentCover = Cover(songs, desc, errorRes) } /** diff --git a/app/src/main/java/org/oxycblt/auxio/image/ImageSettings.kt b/app/src/main/java/org/oxycblt/auxio/image/ImageSettings.kt index 1a9a01b24..232d903a1 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/ImageSettings.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/ImageSettings.kt @@ -39,7 +39,7 @@ interface ImageSettings : Settings { interface Listener { /** 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) { - if (key == getString(R.string.set_key_cover_mode)) { - logD("Dispatching cover mode setting change") - listener.onCoverModeChanged() + if (key == getString(R.string.set_key_cover_mode) || + key == getString(R.string.set_key_square_covers)) { + logD("Dispatching image setting change") + listener.onImageSettingsChanged() } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt index 9acbe82d0..369675f17 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt @@ -173,7 +173,7 @@ constructor( // --- SETTINGS OVERRIDES --- - override fun onCoverModeChanged() { + override fun onImageSettingsChanged() { // Need to reload the metadata cover. updateMediaMetadata(playbackManager.queue.currentSong, playbackManager.parent) } diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt index 451dcabd7..bb2e7b54f 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt @@ -144,7 +144,7 @@ constructor( // Respond to settings changes that will affect the widget 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.