Skip to content

Commit

Permalink
Migrate ContentPainterModifier to implement Modifier.Node. (#2115)
Browse files Browse the repository at this point in the history
* Migrate ContentPainterModifier to implement Modifier.Node.

* private

* Formatting.
  • Loading branch information
colinrtwhite authored Feb 11, 2024
1 parent d74c1ba commit f0aa7aa
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import coil3.compose.AsyncImagePainter.Companion.DefaultTransform
import coil3.compose.AsyncImagePainter.State
import coil3.compose.internal.AsyncImageState
import coil3.compose.internal.ConstraintsSizeResolver
import coil3.compose.internal.ContentPainterModifier
import coil3.compose.internal.ContentPainterElement
import coil3.compose.internal.contentDescription
import coil3.compose.internal.onStateOf
import coil3.compose.internal.requestOfWithSizeResolver
Expand Down Expand Up @@ -207,7 +207,7 @@ private fun Content(
.contentDescription(contentDescription)
.run { if (clipToBounds) clipToBounds() else this }
.then(
ContentPainterModifier(
ContentPainterElement(
painter = painter,
alignment = alignment,
contentScale = contentScale,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import coil3.compose.AsyncImagePainter.Companion.DefaultTransform
import coil3.compose.AsyncImagePainter.State
import coil3.compose.internal.AsyncImageState
import coil3.compose.internal.ConstraintsSizeResolver
import coil3.compose.internal.ContentPainterModifier
import coil3.compose.internal.ContentPainterElement
import coil3.compose.internal.contentDescription
import coil3.compose.internal.onStateOf
import coil3.compose.internal.requestOfWithSizeResolver
Expand Down Expand Up @@ -282,13 +282,13 @@ fun SubcomposeAsyncImageScope.SubcomposeAsyncImageContent(
.contentDescription(contentDescription)
.run { if (clipToBounds) clipToBounds() else this }
.then(
ContentPainterModifier(
ContentPainterElement(
painter = painter,
alignment = alignment,
contentScale = contentScale,
alpha = alpha,
colorFilter = colorFilter
)
colorFilter = colorFilter,
),
),
measurePolicy = { _, constraints ->
layout(constraints.minWidth, constraints.minHeight) {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")

package coil3.compose.internal

import androidx.compose.ui.Alignment
import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.paint
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.isSpecified
Expand All @@ -15,40 +13,81 @@ import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
import androidx.compose.ui.layout.LayoutModifier
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.layout.times
import androidx.compose.ui.platform.InspectorValueInfo
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.invalidateDraw
import androidx.compose.ui.node.invalidateMeasurement
import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.constrainHeight
import androidx.compose.ui.unit.constrainWidth
import coil3.annotation.Data
import coil3.compose.Content
import coil3.compose.AsyncImage
import coil3.compose.SubcomposeAsyncImage
import kotlin.math.roundToInt

/**
* A custom [paint] modifier used by [Content].
* A custom [paint] modifier used by [AsyncImage] and [SubcomposeAsyncImage].
*/
@Data
internal class ContentPainterModifier(
internal data class ContentPainterElement(
private val painter: Painter,
private val alignment: Alignment,
private val contentScale: ContentScale,
private val alpha: Float,
private val colorFilter: ColorFilter?,
) : LayoutModifier, DrawModifier, InspectorValueInfo(
debugInspectorInfo {
) : ModifierNodeElement<ContentPainterNode>() {

override fun create(): ContentPainterNode {
return ContentPainterNode(
painter = painter,
alignment = alignment,
contentScale = contentScale,
alpha = alpha,
colorFilter = colorFilter,
)
}

override fun update(node: ContentPainterNode) {
val intrinsicsChanged = node.painter.intrinsicSize != painter.intrinsicSize

node.painter = painter
node.alignment = alignment
node.contentScale = contentScale
node.alpha = alpha
node.colorFilter = colorFilter

// Only remeasure if intrinsics have changed.
if (intrinsicsChanged) {
node.invalidateMeasurement()
}

// Redraw because one of the node properties has changed.
node.invalidateDraw()
}

override fun InspectorInfo.inspectableProperties() {
name = "content"
properties["painter"] = painter
properties["alignment"] = alignment
properties["contentScale"] = contentScale
properties["alpha"] = alpha
properties["colorFilter"] = colorFilter
},
) {
}
}

internal class ContentPainterNode(
var painter: Painter,
var alignment: Alignment,
var contentScale: ContentScale,
var alpha: Float,
var colorFilter: ColorFilter?,
) : Modifier.Node(), DrawModifierNode, LayoutModifierNode {

override val shouldAutoInvalidate get() = false

override fun MeasureScope.measure(
measurable: Measurable,
Expand Down

0 comments on commit f0aa7aa

Please sign in to comment.