Skip to content

Commit

Permalink
Make CrossfadePainter public API.
Browse files Browse the repository at this point in the history
  • Loading branch information
colinrtwhite committed Nov 1, 2024
1 parent 0582d75 commit 0903b01
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 16 deletions.
7 changes: 7 additions & 0 deletions coil-compose-core/api/android/coil-compose-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ public final class coil3/compose/ConstraintsSizeResolverKt {
public static final fun rememberConstraintsSizeResolver (Landroidx/compose/runtime/Composer;I)Lcoil3/compose/ConstraintsSizeResolver;
}

public final class coil3/compose/CrossfadePainter : androidx/compose/ui/graphics/painter/Painter {
public static final field $stable I
public synthetic fun <init> (Landroidx/compose/ui/graphics/painter/Painter;Landroidx/compose/ui/graphics/painter/Painter;Landroidx/compose/ui/layout/ContentScale;JZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Landroidx/compose/ui/graphics/painter/Painter;Landroidx/compose/ui/graphics/painter/Painter;Landroidx/compose/ui/layout/ContentScale;JZZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getIntrinsicSize-NH-jbRc ()J
}

public abstract interface class coil3/compose/DrawScopeSizeResolver : coil3/size/SizeResolver {
public abstract fun connect (Lkotlinx/coroutines/flow/Flow;)V
}
Expand Down
11 changes: 9 additions & 2 deletions coil-compose-core/api/coil-compose-core.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ final class coil3.compose/ConstraintsSizeResolver : androidx.compose.ui.layout/L
final suspend fun size(): coil3.size/Size // coil3.compose/ConstraintsSizeResolver.size|size(){}[0]
}

final class coil3.compose/CrossfadePainter : androidx.compose.ui.graphics.painter/Painter { // coil3.compose/CrossfadePainter|null[0]
constructor <init>(androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.layout/ContentScale = ..., kotlin.time/Duration = ..., kotlin/Boolean = ..., kotlin/Boolean = ...) // coil3.compose/CrossfadePainter.<init>|<init>(androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.layout.ContentScale;kotlin.time.Duration;kotlin.Boolean;kotlin.Boolean){}[0]

final val intrinsicSize // coil3.compose/CrossfadePainter.intrinsicSize|{}intrinsicSize[0]
final fun <get-intrinsicSize>(): androidx.compose.ui.geometry/Size // coil3.compose/CrossfadePainter.intrinsicSize.<get-intrinsicSize>|<get-intrinsicSize>(){}[0]
}

final class coil3.compose/EqualityDelegateKt { // coil3.compose/EqualityDelegateKt|null[0]
constructor <init>() // coil3.compose/EqualityDelegateKt.<init>|<init>(){}[0]

Expand All @@ -175,7 +182,6 @@ final class coil3.compose/ImagePainter : androidx.compose.ui.graphics.painter/Pa
final val coil3.compose.internal/coil3_compose_internal_AsyncImageState$stableprop // coil3.compose.internal/coil3_compose_internal_AsyncImageState$stableprop|#static{}coil3_compose_internal_AsyncImageState$stableprop[0]
final val coil3.compose.internal/coil3_compose_internal_ContentPainterElement$stableprop // coil3.compose.internal/coil3_compose_internal_ContentPainterElement$stableprop|#static{}coil3_compose_internal_ContentPainterElement$stableprop[0]
final val coil3.compose.internal/coil3_compose_internal_ContentPainterNode$stableprop // coil3.compose.internal/coil3_compose_internal_ContentPainterNode$stableprop|#static{}coil3_compose_internal_ContentPainterNode$stableprop[0]
final val coil3.compose.internal/coil3_compose_internal_CrossfadePainter$stableprop // coil3.compose.internal/coil3_compose_internal_CrossfadePainter$stableprop|#static{}coil3_compose_internal_CrossfadePainter$stableprop[0]
final val coil3.compose/DefaultModelEqualityDelegate // coil3.compose/DefaultModelEqualityDelegate|{}DefaultModelEqualityDelegate[0]
final fun <get-DefaultModelEqualityDelegate>(): coil3.compose/EqualityDelegate // coil3.compose/DefaultModelEqualityDelegate.<get-DefaultModelEqualityDelegate>|<get-DefaultModelEqualityDelegate>(){}[0]
final val coil3.compose/LocalAsyncImageModelEqualityDelegate // coil3.compose/LocalAsyncImageModelEqualityDelegate|{}LocalAsyncImageModelEqualityDelegate[0]
Expand All @@ -191,6 +197,7 @@ final val coil3.compose/coil3_compose_AsyncImagePainter_State_Error$stableprop /
final val coil3.compose/coil3_compose_AsyncImagePainter_State_Loading$stableprop // coil3.compose/coil3_compose_AsyncImagePainter_State_Loading$stableprop|#static{}coil3_compose_AsyncImagePainter_State_Loading$stableprop[0]
final val coil3.compose/coil3_compose_AsyncImagePainter_State_Success$stableprop // coil3.compose/coil3_compose_AsyncImagePainter_State_Success$stableprop|#static{}coil3_compose_AsyncImagePainter_State_Success$stableprop[0]
final val coil3.compose/coil3_compose_ConstraintsSizeResolver$stableprop // coil3.compose/coil3_compose_ConstraintsSizeResolver$stableprop|#static{}coil3_compose_ConstraintsSizeResolver$stableprop[0]
final val coil3.compose/coil3_compose_CrossfadePainter$stableprop // coil3.compose/coil3_compose_CrossfadePainter$stableprop|#static{}coil3_compose_CrossfadePainter$stableprop[0]
final val coil3.compose/coil3_compose_EqualityDelegateKt$stableprop // coil3.compose/coil3_compose_EqualityDelegateKt$stableprop|#static{}coil3_compose_EqualityDelegateKt$stableprop[0]
final val coil3.compose/coil3_compose_ImagePainter$stableprop // coil3.compose/coil3_compose_ImagePainter$stableprop|#static{}coil3_compose_ImagePainter$stableprop[0]

Expand All @@ -199,7 +206,6 @@ final fun (coil3/Image).coil3.compose/asPainter(coil3/PlatformContext, androidx.
final fun coil3.compose.internal/coil3_compose_internal_AsyncImageState$stableprop_getter(): kotlin/Int // coil3.compose.internal/coil3_compose_internal_AsyncImageState$stableprop_getter|coil3_compose_internal_AsyncImageState$stableprop_getter(){}[0]
final fun coil3.compose.internal/coil3_compose_internal_ContentPainterElement$stableprop_getter(): kotlin/Int // coil3.compose.internal/coil3_compose_internal_ContentPainterElement$stableprop_getter|coil3_compose_internal_ContentPainterElement$stableprop_getter(){}[0]
final fun coil3.compose.internal/coil3_compose_internal_ContentPainterNode$stableprop_getter(): kotlin/Int // coil3.compose.internal/coil3_compose_internal_ContentPainterNode$stableprop_getter|coil3_compose_internal_ContentPainterNode$stableprop_getter(){}[0]
final fun coil3.compose.internal/coil3_compose_internal_CrossfadePainter$stableprop_getter(): kotlin/Int // coil3.compose.internal/coil3_compose_internal_CrossfadePainter$stableprop_getter|coil3_compose_internal_CrossfadePainter$stableprop_getter(){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, coil3.compose/EqualityDelegate?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;coil3.compose.EqualityDelegate?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
final fun coil3.compose/AsyncImage(kotlin/Any?, kotlin/String?, coil3/ImageLoader, androidx.compose.ui/Modifier?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, coil3.compose/AsyncImagePainter.State>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State, kotlin/Unit>?, androidx.compose.ui/Alignment?, androidx.compose.ui.layout/ContentScale?, kotlin/Float, androidx.compose.ui.graphics/ColorFilter?, androidx.compose.ui.graphics/FilterQuality, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // coil3.compose/AsyncImage|AsyncImage(kotlin.Any?;kotlin.String?;coil3.ImageLoader;androidx.compose.ui.Modifier?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,coil3.compose.AsyncImagePainter.State>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State,kotlin.Unit>?;androidx.compose.ui.Alignment?;androidx.compose.ui.layout.ContentScale?;kotlin.Float;androidx.compose.ui.graphics.ColorFilter?;androidx.compose.ui.graphics.FilterQuality;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0]
Expand All @@ -216,6 +222,7 @@ final fun coil3.compose/coil3_compose_AsyncImagePainter_State_Error$stableprop_g
final fun coil3.compose/coil3_compose_AsyncImagePainter_State_Loading$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_AsyncImagePainter_State_Loading$stableprop_getter|coil3_compose_AsyncImagePainter_State_Loading$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_AsyncImagePainter_State_Success$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_AsyncImagePainter_State_Success$stableprop_getter|coil3_compose_AsyncImagePainter_State_Success$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_ConstraintsSizeResolver$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_ConstraintsSizeResolver$stableprop_getter|coil3_compose_ConstraintsSizeResolver$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_CrossfadePainter$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_CrossfadePainter$stableprop_getter|coil3_compose_CrossfadePainter$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_EqualityDelegateKt$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_EqualityDelegateKt$stableprop_getter|coil3_compose_EqualityDelegateKt$stableprop_getter(){}[0]
final fun coil3.compose/coil3_compose_ImagePainter$stableprop_getter(): kotlin/Int // coil3.compose/coil3_compose_ImagePainter$stableprop_getter|coil3_compose_ImagePainter$stableprop_getter(){}[0]
final fun coil3.compose/rememberAsyncImagePainter(kotlin/Any?, coil3/ImageLoader, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, androidx.compose.ui.graphics.painter/Painter?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Loading, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Success, kotlin/Unit>?, kotlin/Function1<coil3.compose/AsyncImagePainter.State.Error, kotlin/Unit>?, androidx.compose.ui.layout/ContentScale?, androidx.compose.ui.graphics/FilterQuality, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): coil3.compose/AsyncImagePainter // coil3.compose/rememberAsyncImagePainter|rememberAsyncImagePainter(kotlin.Any?;coil3.ImageLoader;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;androidx.compose.ui.graphics.painter.Painter?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Loading,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Success,kotlin.Unit>?;kotlin.Function1<coil3.compose.AsyncImagePainter.State.Error,kotlin.Unit>?;androidx.compose.ui.layout.ContentScale?;androidx.compose.ui.graphics.FilterQuality;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
Expand Down
7 changes: 7 additions & 0 deletions coil-compose-core/api/jvm/coil-compose-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ public final class coil3/compose/ConstraintsSizeResolverKt {
public static final fun rememberConstraintsSizeResolver (Landroidx/compose/runtime/Composer;I)Lcoil3/compose/ConstraintsSizeResolver;
}

public final class coil3/compose/CrossfadePainter : androidx/compose/ui/graphics/painter/Painter {
public static final field $stable I
public synthetic fun <init> (Landroidx/compose/ui/graphics/painter/Painter;Landroidx/compose/ui/graphics/painter/Painter;Landroidx/compose/ui/layout/ContentScale;JZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Landroidx/compose/ui/graphics/painter/Painter;Landroidx/compose/ui/graphics/painter/Painter;Landroidx/compose/ui/layout/ContentScale;JZZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getIntrinsicSize-NH-jbRc ()J
}

public abstract interface class coil3/compose/DrawScopeSizeResolver : coil3/size/SizeResolver {
public abstract fun connect (Lkotlinx/coroutines/flow/Flow;)V
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package coil3.compose

import android.graphics.drawable.Drawable
import androidx.compose.ui.layout.ContentScale
import coil3.compose.internal.CrossfadePainter
import coil3.request.ImageRequest
import coil3.request.SuccessResult
import coil3.request.lifecycle
import coil3.request.transitionFactory
import coil3.transition.CrossfadeTransition
import coil3.transition.TransitionTarget
import kotlin.time.Duration.Companion.milliseconds

internal actual fun validateRequestProperties(request: ImageRequest) {
require(request.target == null) { "request.target must be null." }
Expand All @@ -35,7 +35,7 @@ internal actual fun maybeNewCrossfadePainter(
start = previous.painter.takeIf { previous is AsyncImagePainter.State.Loading },
end = current.painter,
contentScale = contentScale,
durationMillis = transition.durationMillis,
duration = transition.durationMillis.milliseconds,
fadeStart = result !is SuccessResult || !result.isPlaceholderCached,
preferExactIntrinsicSize = transition.preferExactIntrinsicSize,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import coil3.compose.AsyncImagePainter.Companion.DefaultTransform
import coil3.compose.AsyncImagePainter.Input
import coil3.compose.AsyncImagePainter.State
import coil3.compose.internal.AsyncImageState
import coil3.compose.internal.CrossfadePainter
import coil3.compose.internal.onStateOf
import coil3.compose.internal.requestOf
import coil3.compose.internal.safeImmediateMainDispatcher
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package coil3.compose.internal
package coil3.compose

import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
Expand All @@ -16,22 +16,34 @@ import androidx.compose.ui.graphics.drawscope.inset
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.times
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.TimeSource

/**
* A [Painter] that crossfades from [start] to [end].
*
* NOTE: The animation can only be executed once as the [start] painter is dereferenced at
* the end of the transition.
* NOTE: The animation can only be executed once as the [start]
* painter is dereferenced at the end of the transition.
*
* @param start The [Painter] to crossfade from.
* @param end The [Painter] to crossfade to.
* @param contentScale The scaling algorithm for [start] and [end].
* @param duration The duration of the crossfade animation.
* @param fadeStart If false, the start drawable will not fade out while the end drawable fades in.
* @param preferExactIntrinsicSize If true, this drawable's intrinsic width/height will only be -1
* if [start] **and** [end] return -1 for that dimension. If false, the intrinsic width/height will
* be -1 if [start] **or** [end] return -1 for that dimension. This is useful for views that
* require an exact intrinsic size to scale the drawable.
*/
@Stable
internal class CrossfadePainter(
class CrossfadePainter(
private var start: Painter?,
private val end: Painter?,
private val contentScale: ContentScale,
private val durationMillis: Int,
private val fadeStart: Boolean,
private val preferExactIntrinsicSize: Boolean,
private val contentScale: ContentScale = ContentScale.Fit,
private val duration: Duration = 200.milliseconds,
private val fadeStart: Boolean = true,
private val preferExactIntrinsicSize: Boolean = false,
) : Painter() {

private var invalidateTick by mutableIntStateOf(0)
Expand All @@ -51,7 +63,7 @@ internal class CrossfadePainter(

// Initialize startTime the first time we're drawn.
val startTime = startTime ?: TimeSource.Monotonic.markNow().also { startTime = it }
val percent = startTime.elapsedNow().inWholeMilliseconds / durationMillis.toFloat()
val percent = startTime.elapsedNow().inWholeMilliseconds / duration.inWholeMilliseconds.toFloat()
val endAlpha = percent.coerceIn(0f, 1f) * maxAlpha
val startAlpha = if (fadeStart) maxAlpha - endAlpha else maxAlpha
isDone = percent >= 1f
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package coil3.compose

import androidx.compose.ui.layout.ContentScale
import coil3.compose.internal.CrossfadePainter
import coil3.decode.DataSource
import coil3.request.ImageRequest
import coil3.request.SuccessResult
import coil3.request.crossfadeMillis
import kotlin.time.Duration.Companion.milliseconds

internal actual fun validateRequestProperties(request: ImageRequest) {
require(request.target == null) { "request.target must be null." }
Expand Down Expand Up @@ -40,7 +40,7 @@ internal actual fun maybeNewCrossfadePainter(
start = previous.painter.takeIf { previous is AsyncImagePainter.State.Loading },
end = current.painter,
contentScale = contentScale,
durationMillis = crossfadeMillis,
duration = crossfadeMillis.milliseconds,
fadeStart = !result.isPlaceholderCached,
preferExactIntrinsicSize = false,
)
Expand Down

0 comments on commit 0903b01

Please sign in to comment.