From ef51a33dfa22c5df81e1d8d2eb9564d79a7a76db Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Mon, 20 Nov 2023 16:50:21 +0100 Subject: [PATCH] Optimize Modifier.constrainedAspectRatio --- .../com/theoplayer/android/ui/Modifiers.kt | 57 +++++++++++++------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/ui/src/main/java/com/theoplayer/android/ui/Modifiers.kt b/ui/src/main/java/com/theoplayer/android/ui/Modifiers.kt index 8980264..0ca2542 100644 --- a/ui/src/main/java/com/theoplayer/android/ui/Modifiers.kt +++ b/ui/src/main/java/com/theoplayer/android/ui/Modifiers.kt @@ -30,8 +30,8 @@ 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.node.ModifierNodeElement import androidx.compose.ui.platform.InspectorInfo -import androidx.compose.ui.platform.InspectorValueInfo import androidx.compose.ui.platform.debugInspectorInfo import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.IntSize @@ -183,7 +183,7 @@ internal fun Modifier.constrainedAspectRatio( ratio: Float, matchHeightConstraintsFirst: Boolean = false ): Modifier = this.then( - ConstrainedAspectRatioModifier( + ConstrainedAspectRatioElement( ratio, matchHeightConstraintsFirst, debugInspectorInfo { @@ -194,11 +194,46 @@ internal fun Modifier.constrainedAspectRatio( ) ) -private class ConstrainedAspectRatioModifier( +private class ConstrainedAspectRatioElement( val aspectRatio: Float, val matchHeightConstraintsFirst: Boolean, - inspectorInfo: InspectorInfo.() -> Unit -) : LayoutModifier, InspectorValueInfo(inspectorInfo) { + val inspectorInfo: InspectorInfo.() -> Unit +) : ModifierNodeElement() { + init { + require(aspectRatio > 0) { "aspectRatio $aspectRatio must be > 0" } + } + + override fun create(): ConstrainedAspectRatioNode { + return ConstrainedAspectRatioNode( + aspectRatio, + matchHeightConstraintsFirst + ) + } + + override fun update(node: ConstrainedAspectRatioNode) { + node.aspectRatio = aspectRatio + node.matchHeightConstraintsFirst = matchHeightConstraintsFirst + } + + override fun InspectorInfo.inspectableProperties() { + inspectorInfo() + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + val otherModifier = other as? ConstrainedAspectRatioElement ?: return false + return aspectRatio == otherModifier.aspectRatio && + matchHeightConstraintsFirst == other.matchHeightConstraintsFirst + } + + override fun hashCode(): Int = + aspectRatio.hashCode() * 31 + matchHeightConstraintsFirst.hashCode() +} + +private class ConstrainedAspectRatioNode( + var aspectRatio: Float, + var matchHeightConstraintsFirst: Boolean +) : LayoutModifier, Modifier.Node() { init { require(aspectRatio > 0) { "aspectRatio $aspectRatio must be > 0" } } @@ -321,16 +356,4 @@ private class ConstrainedAspectRatioModifier( } return IntSize.Zero } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - val otherModifier = other as? ConstrainedAspectRatioModifier ?: return false - return aspectRatio == otherModifier.aspectRatio && - matchHeightConstraintsFirst == other.matchHeightConstraintsFirst - } - - override fun hashCode(): Int = - aspectRatio.hashCode() * 31 + matchHeightConstraintsFirst.hashCode() - - override fun toString(): String = "ConstrainedAspectRatioModifier(aspectRatio=$aspectRatio)" }