Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f637fe86 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Android (Google) Code Review
Browse files

Merge changes from topic "stl-move-offset-effect" into main

* changes:
  Move OffsetOverscrollEffect and others to PlatformComposeCore (1/2)
  Extract internal GestureEffect out of ContentOverscrollEffect
parents 1ac357ab d77e2885
Loading
Loading
Loading
Loading
+1 −54
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.compose.animation.scene.effect
package com.android.compose.gesture.effect

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationSpec
@@ -118,56 +118,3 @@ open class BaseContentOverscrollEffect(
        }
    }
}

/** An overscroll effect that ensures only a single fling animation is triggered. */
internal class GestureEffect(private val delegate: ContentOverscrollEffect) :
    ContentOverscrollEffect by delegate {
    private var shouldFling = false

    override fun applyToScroll(
        delta: Offset,
        source: NestedScrollSource,
        performScroll: (Offset) -> Offset,
    ): Offset {
        shouldFling = true
        return delegate.applyToScroll(delta, source, performScroll)
    }

    override suspend fun applyToFling(
        velocity: Velocity,
        performFling: suspend (Velocity) -> Velocity,
    ) {
        if (!shouldFling) {
            performFling(velocity)
            return
        }
        shouldFling = false
        delegate.applyToFling(velocity, performFling)
    }

    suspend fun ensureApplyToFlingIsCalled() {
        applyToFling(Velocity.Zero) { Velocity.Zero }
    }
}

/**
 * An overscroll effect that only applies visual effects and does not interfere with the actual
 * scrolling or flinging behavior.
 */
internal class VisualEffect(private val delegate: ContentOverscrollEffect) :
    ContentOverscrollEffect by delegate {
    override fun applyToScroll(
        delta: Offset,
        source: NestedScrollSource,
        performScroll: (Offset) -> Offset,
    ): Offset {
        return performScroll(delta)
    }

    override suspend fun applyToFling(
        velocity: Velocity,
        performFling: suspend (Velocity) -> Velocity,
    ) {
        performFling(velocity)
    }
}
+34 −3
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.compose.animation.scene.effect
package com.android.compose.gesture.effect

import androidx.annotation.VisibleForTesting
import androidx.compose.animation.core.AnimationSpec
@@ -34,7 +34,6 @@ import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.ProgressConverter
import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope

@@ -80,7 +79,7 @@ class OffsetOverscrollEffect(
            )

        @VisibleForTesting
        internal fun computeOffset(density: Density, overscrollDistance: Float): Int {
        fun computeOffset(density: Density, overscrollDistance: Float): Int {
            val maxDistancePx = with(density) { MaxDistance.toPx() }
            val progress = ProgressConverter.Default.convert(overscrollDistance / maxDistancePx)
            return (progress * maxDistancePx).roundToInt()
@@ -98,3 +97,35 @@ fun rememberOffsetOverscrollEffect(
        OffsetOverscrollEffect(orientation, animationScope, animationSpec)
    }
}

/** This converter lets you change a linear progress into a function of your choice. */
fun interface ProgressConverter {
    fun convert(progress: Float): Float

    companion object {
        /** Starts linearly with some resistance and slowly approaches to 0.2f */
        val Default = tanh(maxProgress = 0.2f, tilt = 3f)

        /**
         * The scroll stays linear, with [factor] you can control how much resistance there is.
         *
         * @param factor If you choose a value between 0f and 1f, the progress will grow more
         *   slowly, like there's resistance. A value of 1f means there's no resistance.
         */
        fun linear(factor: Float = 1f) = ProgressConverter { it * factor }

        /**
         * This function starts linear and slowly approaches [maxProgress].
         *
         * See a [visual representation](https://www.desmos.com/calculator/usgvvf0z1u) of this
         * function.
         *
         * @param maxProgress is the maximum progress value.
         * @param tilt behaves similarly to the factor in the [linear] function, and allows you to
         *   control how quickly you get to the [maxProgress].
         */
        fun tanh(maxProgress: Float, tilt: Float = 1f) = ProgressConverter {
            maxProgress * kotlin.math.tanh(x = it / (maxProgress * tilt))
        }
    }
}
+0 −0

File moved.

+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.compose.animation.scene.effect
package com.android.compose.gesture.effect

import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.rememberScrollableState
+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexContentPicker
import com.android.compose.animation.scene.effect.rememberOffsetOverscrollEffect
import com.android.compose.gesture.effect.rememberOffsetOverscrollEffect
import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.systemui.res.R

Loading