Skip to content

Commit f410470

Browse files
authored
Revert "Implement enter end exit animation for Dialog (#2374)" (#2537)
This reverts commit 8903902. (#2374) Fixes: https://youtrack.jetbrains.com/issue/CMP-9179 ## Release Notes N/A
1 parent 0ea0532 commit f410470

File tree

8 files changed

+17
-229
lines changed

8 files changed

+17
-229
lines changed

compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ImageComposeSceneTest.kt

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
2626
import androidx.compose.foundation.layout.padding
2727
import androidx.compose.foundation.layout.size
2828
import androidx.compose.material.ExtendedFloatingActionButton
29-
import androidx.compose.runtime.Composable
3029
import androidx.compose.runtime.getValue
3130
import androidx.compose.runtime.mutableStateOf
3231
import androidx.compose.runtime.setValue
@@ -39,7 +38,6 @@ import androidx.compose.ui.window.Dialog
3938
import kotlin.time.Duration.Companion.seconds
4039
import kotlin.time.ExperimentalTime
4140
import kotlinx.coroutines.runBlocking
42-
import org.jetbrains.skia.Image
4341
import org.jetbrains.skiko.MainUIDispatcher
4442
import org.junit.Ignore
4543
import org.junit.Rule
@@ -96,7 +94,7 @@ class ImageComposeSceneTest {
9694

9795
@Test
9896
fun `run dialog in center`() {
99-
val image = renderComposeSceneOnIdle(
97+
val image = renderComposeScene(
10098
width = 80,
10199
height = 40,
102100
) {
@@ -132,20 +130,4 @@ class ImageComposeSceneTest {
132130
scene.close()
133131
}
134132
}
135-
}
136-
137-
@OptIn(ExperimentalTime::class)
138-
private fun renderComposeSceneOnIdle(
139-
width: Int,
140-
height: Int,
141-
density: Density = Density(1f),
142-
content: @Composable () -> Unit
143-
): Image = ImageComposeScene(
144-
width = width,
145-
height = height,
146-
density = density,
147-
content = content
148-
).use {
149-
val time = it.runUntilIdle()
150-
it.render(time)
151133
}

compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/TestUtils.kt

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,6 @@ import java.awt.image.MultiResolutionImage
4141
import java.text.AttributedString
4242
import javax.swing.Icon
4343
import javax.swing.ImageIcon
44-
import kotlin.time.Duration
45-
import kotlin.time.Duration.Companion.milliseconds
46-
import kotlin.time.ExperimentalTime
4744
import kotlinx.coroutines.runBlocking
4845
import kotlinx.coroutines.yield
4946
import org.jetbrains.skiko.MainUIDispatcher
@@ -275,18 +272,4 @@ internal inline fun <R> ImageComposeScene.useInUiThread(
275272
crossinline block: (ImageComposeScene) -> R
276273
): R = runBlocking(MainUIDispatcher) {
277274
use(block)
278-
}
279-
280-
@OptIn(ExperimentalTime::class)
281-
internal fun ImageComposeScene.runUntilIdle(
282-
initialTime: Duration = Duration.ZERO,
283-
frameDuration: Duration = 16.milliseconds
284-
): Duration {
285-
var time = initialTime
286-
render(time)
287-
while (hasInvalidations()) {
288-
time += frameDuration
289-
render(time)
290-
}
291-
return time
292-
}
275+
}

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeUiFlags.skiko.kt

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,12 @@
1717
package androidx.compose.ui
1818

1919
import kotlin.jvm.JvmField
20+
import kotlin.jvm.JvmName
2021

2122
internal object SkikoComposeUiFlags {
2223
@Suppress("MutableBareField")
2324
@JvmField
2425
var useLegacyRenderNodeLayers: Boolean = false
25-
26-
@Suppress("MutableBareField")
27-
@JvmField
28-
var isDialogAnimationEnabled: Boolean = true
2926
}
3027

3128
/**
@@ -36,11 +33,3 @@ internal object SkikoComposeUiFlags {
3633
*/
3734
@ExperimentalComposeUiApi
3835
var ComposeUiFlags.useLegacyRenderNodeLayers by SkikoComposeUiFlags::useLegacyRenderNodeLayers
39-
40-
/**
41-
* When enabled the [androidx.compose.ui.window.Dialog] appear and disappear with animation.
42-
*
43-
* Note that it's a temporary flag, it will be removed in the future.
44-
*/
45-
@ExperimentalComposeUiApi
46-
var ComposeUiFlags.isDialogAnimationEnabled by SkikoComposeUiFlags::isDialogAnimationEnabled

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/animation/Animation.skiko.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,18 @@ internal fun easeInOutTimingFunction(progress: Float): Float = if (progress < 0.
2727
(-2f * progress * progress) + (4f * progress) - 1f
2828
}
2929

30-
internal fun easeOutTimingFunction(progress: Float): Float {
31-
return -progress * (progress - 2f)
32-
}
33-
3430
internal suspend fun withAnimationProgress(
3531
duration: Duration,
3632
timingFunction: (Float) -> Float = ::easeInOutTimingFunction,
3733
update: (Float) -> Unit
3834
) {
3935
update(0f)
4036

41-
var firstFrameTime: Long? = null
37+
var firstFrameTime = 0L
4238
var progressDuration = Duration.ZERO
4339
while (progressDuration < duration) {
4440
withFrameNanos { frameTime ->
45-
if (firstFrameTime == null) {
41+
if (firstFrameTime == 0L) {
4642
firstFrameTime = frameTime
4743
}
4844
progressDuration = (frameTime - firstFrameTime).nanoseconds

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneLayer.skiko.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ internal fun rememberComposeSceneLayer(
196196
layer.density = density
197197
layer.layoutDirection = layoutDirection
198198

199+
DisposableEffect(Unit) {
200+
onDispose {
201+
layer.close()
202+
}
203+
}
199204
return layer
200205
}
201206

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/window/Dialog.skiko.kt

Lines changed: 7 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,14 @@ import androidx.compose.runtime.DisposableEffect
2121
import androidx.compose.runtime.Immutable
2222
import androidx.compose.runtime.InternalComposeApi
2323
import androidx.compose.runtime.LaunchedEffect
24-
import androidx.compose.runtime.State
2524
import androidx.compose.runtime.getValue
26-
import androidx.compose.runtime.mutableStateOf
2725
import androidx.compose.runtime.remember
28-
import androidx.compose.runtime.rememberCompositionContext
2926
import androidx.compose.runtime.rememberUpdatedState
30-
import androidx.compose.runtime.setValue
31-
import androidx.compose.ui.ComposeUiFlags
3227
import androidx.compose.ui.Modifier
33-
import androidx.compose.ui.MotionDurationScale
34-
import androidx.compose.ui.animation.easeOutTimingFunction
35-
import androidx.compose.ui.animation.withAnimationProgress
3628
import androidx.compose.ui.graphics.BlendMode
3729
import androidx.compose.ui.graphics.Color
38-
import androidx.compose.ui.graphics.graphicsLayer
3930
import androidx.compose.ui.input.pointer.PointerButton
4031
import androidx.compose.ui.input.pointer.PointerEventType
41-
import androidx.compose.ui.isDialogAnimationEnabled
4232
import androidx.compose.ui.layout.Layout
4333
import androidx.compose.ui.platform.LocalPlatformWindowInsets
4434
import androidx.compose.ui.platform.LocalWindowInfo
@@ -54,25 +44,12 @@ import androidx.compose.ui.semantics.semantics
5444
import androidx.compose.ui.unit.IntRect
5545
import androidx.compose.ui.unit.IntSize
5646
import androidx.compose.ui.unit.center
57-
import kotlin.coroutines.CoroutineContext
58-
import kotlin.getValue
59-
import kotlin.setValue
60-
import kotlin.time.Duration.Companion.seconds
61-
import kotlinx.coroutines.CoroutineScope
62-
import kotlinx.coroutines.CoroutineStart
63-
import kotlinx.coroutines.Job
64-
import kotlinx.coroutines.launch
6547

6648
/**
6749
* The default scrim opacity.
6850
*/
6951
private const val DefaultScrimOpacity = 0.6f
7052
private val DefaultScrimColor = Color.Black.copy(alpha = DefaultScrimOpacity)
71-
private const val AnimatedLayerOffsetDp = 10f
72-
private const val AnimatedLayerInitialAlpha = 0.2f
73-
private const val AnimatedLayerScale = 0.05f
74-
private const val AnimatedLayerAppearanceDuration = 0.2
75-
private const val AnimatedLayerDisappearanceDuration = 0.1
7653

7754
/**
7855
* Properties used to customize the behavior of a [Dialog].
@@ -91,7 +68,7 @@ private const val AnimatedLayerDisappearanceDuration = 0.1
9168
* @property scrimColor Color of background fill.
9269
*/
9370
@Immutable
94-
actual class DialogProperties(
71+
actual class DialogProperties constructor(
9572
actual val dismissOnBackPress: Boolean = true,
9673
actual val dismissOnClickOutside: Boolean = true,
9774
actual val usePlatformDefaultWidth: Boolean = true,
@@ -189,20 +166,13 @@ private fun DialogLayout(
189166
content: @Composable () -> Unit
190167
) {
191168
val currentContent by rememberUpdatedState(content)
192-
val compositionContext = rememberCompositionContext()
193-
val layer = rememberComposeSceneLayer(focusable = true)
194-
layer.setOutsidePointerEventListener(onOutsidePointerEvent)
195-
196-
val animator = remember {
197-
DialogAppearanceController(layer = layer, coroutineContext = compositionContext.effectCoroutineContext)
198-
}
199-
animator.scrimColor = properties.scrimColor
200169

170+
val layer = rememberComposeSceneLayer(
171+
focusable = true
172+
)
173+
layer.scrimColor = properties.scrimColor
174+
layer.setOutsidePointerEventListener(onOutsidePointerEvent)
201175
layer.Content {
202-
LaunchedEffect(Unit) {
203-
animator.onDialogShown()
204-
}
205-
206176
val platformInsets = properties.platformInsets
207177
val containerSize = LocalWindowInfo.current.containerSize
208178
val measurePolicy = rememberDialogMeasurePolicy(
@@ -218,120 +188,11 @@ private fun DialogLayout(
218188
) {
219189
Layout(
220190
content = currentContent,
221-
modifier = animator.modifier.then(modifier),
191+
modifier = modifier,
222192
measurePolicy = measurePolicy
223193
)
224194
}
225195
}
226-
227-
DisposableEffect(Unit) {
228-
onDispose {
229-
animator.hideDialog()
230-
}
231-
}
232-
}
233-
234-
private interface DialogAppearanceController {
235-
var scrimColor: Color?
236-
val modifier: Modifier
237-
fun onDialogShown()
238-
fun hideDialog()
239-
}
240-
241-
private fun DialogAppearanceController(
242-
layer: ComposeSceneLayer,
243-
coroutineContext: CoroutineContext
244-
): DialogAppearanceController =
245-
if (ComposeUiFlags.isDialogAnimationEnabled) {
246-
AnimatedDialogAppearanceController(layer, coroutineContext)
247-
} else {
248-
NonAnimatedDialogAppearanceController(layer)
249-
}
250-
251-
private class AnimatedDialogAppearanceController(
252-
private val layer: ComposeSceneLayer,
253-
private val coroutineContext: CoroutineContext
254-
) : DialogAppearanceController {
255-
private val appearanceProgress = mutableStateOf(0f)
256-
private var appearAnimationJob: Job? = null
257-
258-
override var modifier by mutableStateOf(
259-
Modifier.animationLayerTransform(appearanceProgress)
260-
)
261-
private set
262-
263-
override var scrimColor: Color? = Color.Transparent
264-
set(value) {
265-
field = value
266-
updateScrimLayerColor()
267-
}
268-
269-
override fun onDialogShown() {
270-
appearAnimationJob =
271-
CoroutineScope(coroutineContext).launch(start = CoroutineStart.UNDISPATCHED) {
272-
withAnimationProgress(
273-
duration = (durationScale() * AnimatedLayerAppearanceDuration).seconds,
274-
timingFunction = ::easeOutTimingFunction
275-
) { progress ->
276-
appearanceProgress.value = progress
277-
updateScrimLayerColor()
278-
}
279-
280-
modifier = Modifier
281-
layer.scrimColor = scrimColor
282-
}
283-
}
284-
285-
override fun hideDialog() {
286-
appearAnimationJob?.cancel()
287-
CoroutineScope(coroutineContext).launch(start = CoroutineStart.UNDISPATCHED) {
288-
val initialProgress = appearanceProgress.value
289-
val duration =
290-
durationScale() * initialProgress * AnimatedLayerDisappearanceDuration
291-
modifier = Modifier.animationLayerTransform(appearanceProgress)
292-
293-
withAnimationProgress(
294-
duration = duration.seconds,
295-
timingFunction = ::easeOutTimingFunction
296-
) { progress ->
297-
appearanceProgress.value = (1f - progress) * initialProgress
298-
updateScrimLayerColor()
299-
}
300-
301-
layer.close()
302-
}
303-
}
304-
305-
private fun updateScrimLayerColor() {
306-
layer.scrimColor = scrimColor?.let {
307-
it.copy(it.alpha * contentAlpha(appearanceProgress.value))
308-
}
309-
}
310-
311-
private fun contentAlpha(progress: Float): Float =
312-
AnimatedLayerInitialAlpha + (1f - AnimatedLayerInitialAlpha) * progress
313-
314-
private fun durationScale(): Float =
315-
coroutineContext[MotionDurationScale]?.scaleFactor ?: 1f
316-
317-
private fun Modifier.animationLayerTransform(progress: State<Float>): Modifier =
318-
graphicsLayer {
319-
this.alpha = contentAlpha(progress.value)
320-
val reversedProgress = 1f - progress.value
321-
val scale = 1f - reversedProgress * AnimatedLayerScale
322-
this.scaleX = scale
323-
this.scaleY = scale
324-
this.translationY = AnimatedLayerOffsetDp * reversedProgress * density
325-
}
326-
}
327-
328-
private class NonAnimatedDialogAppearanceController(
329-
private val layer: ComposeSceneLayer
330-
) : DialogAppearanceController {
331-
override var scrimColor: Color? by layer::scrimColor
332-
override fun onDialogShown() {}
333-
override fun hideDialog() = layer.close()
334-
override val modifier = Modifier
335196
}
336197

337198
private val DialogProperties.platformInsets: PlatformInsets

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/window/Popup.skiko.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,6 @@ private fun PopupLayout(
472472
)
473473
}
474474
}
475-
476-
DisposableEffect(Unit) {
477-
onDispose {
478-
layer.close()
479-
}
480-
}
481475
}
482476

483477
private val PopupProperties.platformInsets: PlatformInsets

0 commit comments

Comments
 (0)