Skip to content

Commit

Permalink
Rename Modifier.zoomableOverlaidPeek() -> zoomablePeekOverlay()
Browse files Browse the repository at this point in the history
  • Loading branch information
saket committed Jan 3, 2025
1 parent 77fc043 commit c2410c3
Show file tree
Hide file tree
Showing 24 changed files with 52 additions and 55 deletions.
2 changes: 1 addition & 1 deletion sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ dependencies {
implementation(projects.flick)
implementation(projects.zoomableImage.coil)
implementation(projects.zoomableImage.glide)
implementation(projects.zoomableOverlaidPeek)
implementation(projects.zoomablePeekOverlay)

implementation(libs.androidx.appcompat)
implementation(libs.androidx.ktx.core)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import com.slack.circuit.runtime.Navigator
import me.saket.telephoto.sample.GalleryScreenKey
import me.saket.telephoto.sample.MediaViewerScreenKey
import me.saket.telephoto.sample.R
import me.saket.telephoto.zoomable.rememberZoomableOverlayState
import me.saket.telephoto.zoomable.zoomableOverlaidPeek
import me.saket.telephoto.zoomable.rememberZoomablePeekOverlayState
import me.saket.telephoto.zoomable.zoomablePeekOverlay

@Composable
@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -75,7 +75,7 @@ private fun AlbumGrid(
.height(280.dp)
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(4.dp))
.clickable { navigator.goTo(MediaViewerScreenKey(album, initialIndex = index)) }
.zoomableOverlaidPeek(rememberZoomableOverlayState()),
.zoomablePeekOverlay(rememberZoomablePeekOverlayState()),
contentAlignment = Alignment.BottomStart
) {
AsyncImage(
Expand Down
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ include(":zoomable-image:coil")
include(":zoomable-image:coil3")
include(":zoomable-image:glide")
include(":zoomable-image:sub-sampling-image")
include(":zoomable-overlaid-peek")
include(":zoomable-peek-overlay")
include(":sample")
include(":test-util")
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
POM_ARTIFACT_ID=zoomable-overlaid-peek
POM_NAME=Telephoto: Modifier.zoomableOverlaidPeek()
POM_ARTIFACT_ID=zoomable-peek-overlaid
POM_NAME=Telephoto: Modifier.zoomablePeekOverlay()
POM_DESCRIPTION=A Modifier for temporarily peeking content by zooming it on an overlay.
POM_PACKAGING=aar
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ class ZoomableOverlaidPeekTest {
}

@Test fun zoom_in_and_release() = runTest {
lateinit var state: ZoomableOverlaidPeekState
lateinit var state: ZoomablePeekOverlayState
rule.setContent {
Box(Modifier.fillMaxSize(), Alignment.Center) {
state = rememberZoomableOverlayState()
state = rememberZoomablePeekOverlayState()
Box(
Modifier
.size(200.dp)
.zoomableOverlaidPeek(state)
.zoomablePeekOverlay(state)
.background(Color.Green)
.testTag("content")
)
Expand Down Expand Up @@ -121,10 +121,10 @@ class ZoomableOverlaidPeekTest {
}

@Test fun custom_overlay_decoration() = runTest {
lateinit var state: ZoomableOverlaidPeekState
lateinit var state: ZoomablePeekOverlayState
rule.setContent {
Box(Modifier.fillMaxSize(), Alignment.Center) {
val overlayDecoration = ZoomableOverlaidPeekDecoration { _, innerContent ->
val overlayDecoration = ZoomablePeekOverlayDecoration { _, innerContent ->
Box(
Modifier
.fillMaxSize()
Expand All @@ -134,11 +134,11 @@ class ZoomableOverlaidPeekTest {
}
}

state = rememberZoomableOverlayState()
state = rememberZoomablePeekOverlayState()
Box(
Modifier
.size(200.dp)
.zoomableOverlaidPeek(state, overlayDecoration)
.zoomablePeekOverlay(state, overlayDecoration)
.background(Color.Yellow)
.testTag("content")
)
Expand Down Expand Up @@ -175,7 +175,7 @@ class ZoomableOverlaidPeekTest {
Box(
Modifier
.size(200.dp)
.zoomableOverlaidPeek(rememberZoomableOverlayState())
.zoomablePeekOverlay(rememberZoomablePeekOverlayState())
.background(Color.Yellow)
.combinedClickable(
onClick = { onClickCount++ },
Expand Down Expand Up @@ -203,7 +203,7 @@ class ZoomableOverlaidPeekTest {
}

@Test fun updates_to_content_are_reflected_in_the_zoomed_overlay() = runTest {
lateinit var state: ZoomableOverlaidPeekState
lateinit var state: ZoomablePeekOverlayState
var contentText by mutableStateOf("text set before zoom")
var contentAlignment by mutableStateOf(Alignment.TopCenter)

Expand All @@ -214,11 +214,11 @@ class ZoomableOverlaidPeekTest {
.padding(50.dp),
contentAlignment = contentAlignment,
) {
state = rememberZoomableOverlayState()
state = rememberZoomablePeekOverlayState()
Box(
Modifier
.size(100.dp)
.zoomableOverlaidPeek(state)
.zoomablePeekOverlay(state)
.background(Color.White)
.testTag("content")
) {
Expand Down Expand Up @@ -271,7 +271,7 @@ class ZoomableOverlaidPeekTest {
Modifier
.fillMaxWidth()
.height(300.dp)
.zoomableOverlaidPeek(rememberZoomableOverlayState())
.zoomablePeekOverlay(rememberZoomablePeekOverlayState())
.background(Color.Yellow)
)
}
Expand Down Expand Up @@ -302,14 +302,14 @@ class ZoomableOverlaidPeekTest {
}

@Test fun disable_overlay_when_canvas_is_software_accelerated() {
lateinit var state: ZoomableOverlaidPeekState
lateinit var state: ZoomablePeekOverlayState
rule.setContent {
Box(Modifier.fillMaxSize(), Alignment.Center) {
state = rememberZoomableOverlayState()
state = rememberZoomablePeekOverlayState()
Box(
Modifier
.size(200.dp)
.zoomableOverlaidPeek(state)
.zoomablePeekOverlay(state)
.background(Color.Yellow)
.testTag("content")
)
Expand Down Expand Up @@ -343,15 +343,15 @@ class ZoomableOverlaidPeekTest {
}

@Test fun disable_zooming_when_View_is_software_accelerated() = runTest {
lateinit var state: ZoomableOverlaidPeekState
lateinit var state: ZoomablePeekOverlayState
rule.setContent {
Box(Modifier.fillMaxSize(), Alignment.Center) {
SoftwareAcceleratedLayout {
state = rememberZoomableOverlayState()
state = rememberZoomablePeekOverlayState()
Box(
Modifier
.size(200.dp)
.zoomableOverlaidPeek(state)
.zoomablePeekOverlay(state)
.background(Color.Yellow)
.testTag("content")
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.round

@Stable
internal class RealZoomableOverlaidPeekState(
internal class RealZoomablePeekOverlayState(
override val zoomableState: ZoomableState,
val graphicsLayer: GraphicsLayer?,
) : ZoomableOverlaidPeekState {
) : ZoomablePeekOverlayState {

var coordinates: LayoutCoordinates? by mutableStateOf(null, neverEqualPolicy())
lateinit var overlayDecoration: ZoomableOverlaidPeekDecoration
lateinit var overlayDecoration: ZoomablePeekOverlayDecoration

override val isZoomedIn: Boolean by derivedStateOf {
zoomableState.contentTransformation.scaleMetadata.userZoom > 1f
Expand All @@ -56,7 +56,7 @@ internal class RealZoomableOverlaidPeekState(

boundsInWindow?.let { boundsInWindow ->
Box(Modifier.fillMaxSize()) {
overlayDecoration.Decorate(state = this@RealZoomableOverlaidPeekState) {
overlayDecoration.Decorate(state = this@RealZoomablePeekOverlayState) {
Canvas(
Modifier
.size(boundsInWindow.size.toDpSize())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,29 @@ import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.layout.onPlaced
import kotlinx.coroutines.flow.collectLatest

// todo:
// - settling animation does not resume if it's interrupted by a tap.
/**
* Adds a short-lived, overlaid zoom effect reminiscent of Instagram's "peek" feature.
* The content zooms in while the user interacts with it and, unlike [Modifier.zoomable][me.saket.telephoto.zoomable], automatically returns
* to its normal state once the gesture is released.
* The content zooms in while the user interacts with it and, unlike [Modifier.zoomable][me.saket.telephoto.zoomable],
* automatically returns to its normal state once the gesture is released.
*/
fun Modifier.zoomableOverlaidPeek(
state: ZoomableOverlaidPeekState,
overlayDecoration: ZoomableOverlaidPeekDecoration = ZoomableOverlaidPeekDecoration.scrim(),
fun Modifier.zoomablePeekOverlay(
state: ZoomablePeekOverlayState,
overlayDecoration: ZoomablePeekOverlayDecoration = ZoomablePeekOverlayDecoration.scrim(),
): Modifier {
check(state is RealZoomableOverlaidPeekState)
check(state is RealZoomablePeekOverlayState)
state.overlayDecoration = overlayDecoration
if (state.graphicsLayer == null) {
return this
}
return this
.drawWithContent {
if (isCanvasHardwareAccelerated()) {
state.graphicsLayer.record {
this@drawWithContent.drawContent()
}
state.graphicsLayer.record {
this@drawWithContent.drawContent()
}
if (!state.isZoomedIn) {
drawLayer(state.graphicsLayer)
}
drawLayer(state.graphicsLayer)
}
} else {
drawContent()
}
Expand All @@ -61,11 +59,11 @@ fun Modifier.zoomableOverlaidPeek(
}

/**
* Draws decoration around the zoomed content where [Modifier.zoomableOverlaidPeek] is used.
* Draws decoration around the zoomed content where [Modifier.zoomablePeekOverlay] is used.
* Inspired by [TextFieldDecorator].
*/
@Stable
fun interface ZoomableOverlaidPeekDecoration {
fun interface ZoomablePeekOverlayDecoration {
/**
* Allows you to render decorations around the inner (zoomed) content. [innerContent] must not
* be called more than once.
Expand All @@ -85,19 +83,19 @@ fun interface ZoomableOverlaidPeekDecoration {
* ```
*/
@Composable
fun Decorate(state: ZoomableOverlaidPeekState, innerContent: @Composable () -> Unit)
fun Decorate(state: ZoomablePeekOverlayState, innerContent: @Composable () -> Unit)

companion object {
/** Draws a scrim behind the zoomed content. */
@Stable
fun scrim(
color: Color = Color.Black.copy(alpha = 0.4f)
): ZoomableOverlaidPeekDecoration = Scrim(color)
): ZoomablePeekOverlayDecoration = Scrim(color)
}

private data class Scrim(val color: Color) : ZoomableOverlaidPeekDecoration {
private data class Scrim(val color: Color) : ZoomablePeekOverlayDecoration {
@Composable
override fun Decorate(state: ZoomableOverlaidPeekState, innerContent: @Composable () -> Unit) {
override fun Decorate(state: ZoomablePeekOverlayState, innerContent: @Composable () -> Unit) {
val animatedAlpha = remember { Animatable(initialValue = 0f) }
LaunchedEffect(state) {
snapshotFlow { state.zoomableState.isAnimationRunning }.collectLatest { isSettling ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.rememberGraphicsLayer
import androidx.compose.ui.platform.LocalView

// todo: fix this name (also find usages in code comments).
/**
* Create a [ZoomableOverlaidPeekState] that can be used with
* [Modifier.overlayZoomable][zoomableOverlaidPeek].
* Create a [ZoomablePeekOverlayState] that can be used with
* [Modifier.zoomablePeekOverlay][zoomablePeekOverlay].
*/
@Composable
fun rememberZoomableOverlayState(): ZoomableOverlaidPeekState {
fun rememberZoomablePeekOverlayState(): ZoomablePeekOverlayState {
val zoomableState = rememberZoomableState(
zoomSpec = ZoomSpec(
maximum = ZoomLimit(factor = 1f, overzoomEffect = OverzoomEffect.NoLimits),
Expand All @@ -26,7 +25,7 @@ fun rememberZoomableOverlayState(): ZoomableOverlaidPeekState {
null // GraphicsLayer does not support SW acceleration.
}
return remember(zoomableState, graphicsLayer) {
RealZoomableOverlaidPeekState(
RealZoomablePeekOverlayState(
zoomableState = zoomableState,
graphicsLayer = graphicsLayer,
)
Expand All @@ -35,9 +34,9 @@ fun rememberZoomableOverlayState(): ZoomableOverlaidPeekState {
}
}

/** State class for [Modifier.overlayZoomable][zoomableOverlaidPeek]. */
/** State class for [Modifier.zoomablePeekOverlay][zoomablePeekOverlay]. */
@Stable
sealed interface ZoomableOverlaidPeekState {
sealed interface ZoomablePeekOverlayState {
val zoomableState: ZoomableState

val isZoomedIn: Boolean
Expand Down

0 comments on commit c2410c3

Please sign in to comment.