### Install Zoomable Image with Coil Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Add the dependency for Coil 2.x or Coil 3.x to your project to use ZoomableAsyncImage. ```groovy implementation("me.saket.telephoto:zoomable-image-coil:{{ versions.telephoto }}") ``` ```groovy implementation("me.saket.telephoto:zoomable-image-coil3:{{ versions.telephoto }}") ``` -------------------------------- ### Install Zoomable Image with Glide Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Add the dependency for Glide to your project to use ZoomableGlideImage. ```groovy implementation("me.saket.telephoto:zoomable-image-glide:{{ versions.telephoto }}") ``` -------------------------------- ### Enable Keyboard Shortcuts with Coil Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Apply the focusRequester modifier to enable keyboard shortcuts for navigation. This example uses Coil. ```kotlin ZoomableAsyncImage( modifier = Modifier.focusRequester(focusRequester), model = "https://example.com/image.jpg", ) ``` -------------------------------- ### Set ContentScale with Coil Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Use ContentScale.Crop to make images fill the entire screen, suitable for wallpaper applications. This example uses Coil for image loading. ```kotlin ZoomableAsyncImage( modifier = Modifier.fillMaxSize(), model = "https://example.com/image.jpg", contentScale = ContentScale.Crop ) ``` -------------------------------- ### Set ContentScale with Glide Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Use ContentScale.Crop to make images fill the entire screen, suitable for wallpaper applications. This example uses Glide for image loading. ```kotlin ZoomableGlideImage( modifier = Modifier.fillMaxSize(), model = "https://example.com/image.jpg", contentScale = ContentScale.Crop ) ``` -------------------------------- ### Enable Keyboard Shortcuts with Glide Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Apply the focusRequester modifier to enable keyboard shortcuts for navigation. This example uses Glide. ```kotlin ZoomableGlideImage( modifier = Modifier.focusRequester(focusRequester), model = "https://example.com/image.jpg", ) ``` -------------------------------- ### ZoomableContentLocation.Companion Source: https://github.com/saket/telephoto/blob/trunk/zoomable/api/api.txt Factory methods for creating ZoomableContentLocation instances. ```APIDOC ## ZoomableContentLocation.Companion ### Description Companion object providing factory methods to create various ZoomableContentLocation instances, often used for scaling and alignment. ### Methods #### @androidx.compose.runtime.Stable me.saket.telephoto.zoomable.ZoomableContentLocation scaledInsideAndCenterAligned(Size? size) Creates a ZoomableContentLocation that scales the content to fit inside the given size while centering it. #### @Deprecated @androidx.compose.runtime.Stable me.saket.telephoto.zoomable.ZoomableContentLocation scaledToFitAndCenterAligned(Size? size) Creates a ZoomableContentLocation that scales the content to fit within the given size and centers it. This method is deprecated. #### @androidx.compose.runtime.Stable me.saket.telephoto.zoomable.ZoomableContentLocation unscaledAndTopLeftAligned(Size? size) Creates a ZoomableContentLocation that uses the content's original size and aligns it to the top-left corner. #### @Deprecated me.saket.telephoto.zoomable.ZoomableContentLocation unscaledAndTopStartAligned(Size? size) Creates a ZoomableContentLocation that uses the content's original size and aligns it to the top-start. This method is deprecated. ``` -------------------------------- ### Implement a Custom Image Source Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/sub-sampling.md Create a custom `SubSamplingImageSource` by implementing the `decoder` and providing a preview. ```kotlin class FooImageSource( override val preview: ImageBitmap? ) : SubSamplingImageSource { override suspend fun decoder(): ImageRegionDecoder.Factory { return ImageRegionDecoder.Factory { params -> TODO("Create an image decoder that can load images for your content") } } } ``` -------------------------------- ### ImageBitmapOptions Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/sub-sampling-image/api/api.txt Configuration options for creating an ImageBitmap. ```APIDOC ## ImageBitmapOptions ### Description Configuration options for creating an `ImageBitmap`. Allows specifying the configuration and color space. ### Constructors #### `ImageBitmapOptions(config: Int)` Deprecated constructor. #### `ImageBitmapOptions(config: Int = ..., colorSpace: ColorSpace? = null)` Primary constructor for `ImageBitmapOptions`. ### Properties - **config** (Int) - The configuration for the bitmap. - **colorSpace** (ColorSpace?) - The color space for the bitmap. ### Methods #### `getConfig(): Int` Returns the bitmap configuration. #### `getColorSpace(): ColorSpace?` Returns the color space of the bitmap. ### Companion Object #### `getDefault(): ImageBitmapOptions` Returns the default `ImageBitmapOptions`. ERROR HANDLING: - If no API documentation is found, return empty codeSnippets array - Must contain actual API documentation for something users can call directly - Extract API details only from explicitly documented interfaces users can call directly - Include only methods, parameters, and return values that are directly supported by the source - Do not infer or fabricate endpoints, parameters, methods, request fields, or response fields that are not explicitly present in the source. - If a section is not supported by the source text, omit that section instead of inventing placeholder content. - If the source does not clearly expose an API surface users can call directly, return an empty codeSnippets array. ``` -------------------------------- ### Override Double Click with Glide Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Customize the double-click behavior by providing a custom lambda to the onDoubleClick parameter. This example uses Glide. ```kotlin ZoomableGlideImage( model = "https://example.com/image.jpg", onDoubleClick = { state, centroid -> … }, ) ``` -------------------------------- ### Override Double Click with Coil Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Customize the double-click behavior by providing a custom lambda to the onDoubleClick parameter. This example uses Coil. ```kotlin ZoomableAsyncImage( model = "https://example.com/image.jpg", onDoubleClick = { state, centroid -> … }, ) ``` -------------------------------- ### Customize backdrop with a scrim Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomable-peek-overlay/index.md Customize the translucent scrim color behind the zoomable content by passing a ZoomablePeekOverlayBackdrop.scrim. ```kotlin Modifier.zoomablePeekOverlay( state = rememberZoomablePeekOverlayState(), backdrop = ZoomablePeekOverlayBackdrop.scrim(Color.Blue.copy(alpha = 0.4f)), ) ``` -------------------------------- ### Handle Clicks with Glide Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Detect clicks and long clicks using the onClick and onLongClick parameters, as Modifier.clickable() is incompatible. This example uses Glide. ```kotlin ZoomableGlideImage( modifier = Modifier.clickable { error("This will not work") }, model = "https://example.com/image.jpg", onClick = { … }, onLongClick = { … }, ) ``` -------------------------------- ### Enable keyboard and mouse shortcuts Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomable/index.md Use a FocusRequester to automatically request focus for the zoomable modifier, enabling keyboard and mouse shortcuts for panning and zooming. ```kotlin val focusRequester = remember { FocusRequester() } LaunchedEffect(Unit) { // Automatically request focus when the image is displayed. This assumes there // is only one zoomable image present in the hierarchy. If you're displaying // multiple images in a pager, apply this only for the active page. focusRequester.requestFocus() } Box( Modifier .focusRequester(focusRequester) .zoomable(), ) ``` -------------------------------- ### Handle Clicks with Coil Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Detect clicks and long clicks using the onClick and onLongClick parameters, as Modifier.clickable() is incompatible. This example uses Coil. ```kotlin ZoomableAsyncImage( modifier = Modifier.clickable { error("This will not work") }, model = "https://example.com/image.jpg", onClick = { … }, onLongClick = { … }, ) ``` -------------------------------- ### Publish Archives with Gradle Source: https://github.com/saket/telephoto/blob/trunk/docs/releasing.md Use this command to publish archives to Maven. It disables parallel execution and daemon usage for a cleaner build process. ```bash g clean publish --no-parallel --no-daemon ``` -------------------------------- ### Customize content appearance during zoom Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomable-peek-overlay/index.md Use ZoomablePeekOverlayState#isZoomedIn to apply effects to your content that are only visible during zoom gestures. This example animates corner rounding. ```kotlin val state = rememberZoomablePeekOverlayState() val cornerSize by animateDpAsState(if (state.isZoomedIn) 8.dp else 0.dp) AsyncImage( modifier = Modifier .zoomablePeekOverlay(state) .clip(RoundedCornerShape(cornerSize)), model = "https://example.com/image.jpg", contentDescription = "…", ) ``` -------------------------------- ### Download Full Resolution Image with Coil Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/recipes.md Obtain full-resolution images as files by loading them from cache using Coil. This is necessary for streaming images directly from disk. ```kotlin val state = rememberZoomableImageState() ZoomableAsyncImage( model = imageUrl, state = state, contentDescription = "…", ) if (state.isImageDisplayed) { Button(onClick = { downloadImage(context, imageUrl) }) { Text("Download image") } } ``` ```kotlin suspend fun downloadImage(context: Context, imageUrl: HttpUrl) { val result = context.imageLoader.execute( ImageRequest.Builder(context) .data(imageUrl) .build() ) if (result is SuccessResult) { val cacheKey = result.diskCacheKey ?: error("image wasn't saved to disk") val diskCache = context.imageLoader.diskCache!! diskCache.openSnapshot(cacheKey)!!.use { // TODO: copy to Downloads directory. } } } ``` -------------------------------- ### HardwareShortcutsSpec Source: https://github.com/saket/telephoto/blob/trunk/zoomable/api/api.txt Specifies the configuration for hardware shortcuts, including whether they are enabled and the detector to use. ```APIDOC ## HardwareShortcutsSpec ### Description Specifies the configuration for hardware shortcuts, including whether they are enabled and the detector to use. ### Constructor - `HardwareShortcutsSpec(enabled: Boolean = true, shortcutDetector: HardwareShortcutDetector? = null)`: Creates a new HardwareShortcutsSpec. ### Properties - `enabled`: Whether hardware shortcuts are enabled. - `shortcutDetector`: The hardware shortcut detector to use. ### Companion Object - `Companion.getDisabled()`: Returns a HardwareShortcutsSpec with disabled shortcuts. - `Companion.Disabled`: A property representing disabled hardware shortcuts. ``` -------------------------------- ### Share ZoomableState with Glide Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Hoist ZoomableState to share zoom gestures across different media types like images and videos. This example uses Glide for images. ```kotlin val zoomableState = rememberZoomableState() when (media) { is Image -> { ZoomableGlideImage( model = media.imageUrl, state = rememberZoomableImageState(zoomableState), ) } is Video -> { ZoomableVideoPlayer( model = media.videoUrl, state = rememberZoomableExoState(zoomableState), ) } } ``` -------------------------------- ### ZoomableImageSource.SubSamplingDelegate Constructor Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/core/api/api.txt Constructor for the SubSamplingDelegate, which manages a subsampling image source and its associated options. ```APIDOC ## ZoomableImageSource.SubSamplingDelegate(source, imageOptions) ### Description Initializes a new instance of the SubSamplingDelegate with a given image source and optional image options. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Method Constructor ### Endpoint N/A ### Request Example None ### Response None ``` -------------------------------- ### Share ZoomableState with Coil Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Hoist ZoomableState to share zoom gestures across different media types like images and videos. This example uses Coil for images. ```kotlin val zoomableState = rememberZoomableState() when (media) { is Image -> { ZoomableAsyncImage( model = media.imageUrl, state = rememberZoomableImageState(zoomableState), ) } is Video -> { ZoomableVideoPlayer( model = media.videoUrl, state = rememberZoomableExoState(zoomableState), ) } } ``` -------------------------------- ### ZoomableAsyncImage with Coil, DoubleClick Listener, Content Padding, and Interaction Source Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/coil/api/api.txt The most comprehensive overload, including double-click gestures, content padding, and an interaction source for advanced interaction handling. ```APIDOC ## ZoomableAsyncImage (Coil with Full Options) ### Description This is the most feature-rich overload of `ZoomableAsyncImage` using Coil. It supports double-click zoom, content padding, and provides an `InteractionSource` for detailed interaction tracking. ### Method `ZoomableAsyncImage` ### Parameters - **model** (Object?): The image data to display. - **contentDescription** (String?): A description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to apply to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state object to control zoomable image behavior. - **imageLoader** (optional coil.ImageLoader): An optional Coil ImageLoader instance. - **alpha** (optional Float): The alpha transparency of the composable. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): An optional color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): The alignment of the composable. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): The content scale of the image. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional Boolean): Whether to clip the content to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener): Listener for double-click events to trigger zoom. - **contentPadding** (optional androidx.compose.foundation.layout.PaddingValues): Padding values to apply around the image content. - **interactionSource** (optional androidx.compose.foundation.interaction.MutableInteractionSource?): The interaction source for tracking user interactions. ``` -------------------------------- ### Use Custom Image Source with SubSamplingImage Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/sub-sampling.md Integrate a custom image source with `SubSamplingImage` for displaying non-standard image content. ```kotlin val imageSource = FooImageSource(…) val zoomableState = rememberZoomableState() SubSamplingImage( modifier = Modifier .fillMaxSize() .zoomable(zoomableState), state = rememberSubSamplingImageState(imageSource, zoomableState), contentDescription = …, ) ``` -------------------------------- ### Draw custom backdrop Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomable-peek-overlay/index.md Provide a custom composable to draw the entire backdrop yourself. This allows for complete control over the visual appearance during zoom gestures. ```kotlin Modifier.zoomablePeekOverlay( state = rememberZoomablePeekOverlayState(), backdrop = ZoomablePeekOverlayBackdrop { Canvas(Modifier.fillMaxSize()) { // Go crazy here. } }, ) ``` -------------------------------- ### CoordinateSpace Companion Methods Source: https://github.com/saket/telephoto/blob/trunk/zoomable/api/api.txt Provides access to coordinate spaces for zoomable content. ```APIDOC ## CoordinateSpace Companion Methods ### Description Provides access to coordinate spaces for zoomable content. ### Methods - **getViewport(Companion)**: CoordinateSpace - Gets the viewport coordinate space. - **getZoomableContent(Companion)**: CoordinateSpace - Gets the zoomable content coordinate space. ``` -------------------------------- ### Replace AsyncImage with ZoomableAsyncImage (Coil) Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Swap out AsyncImage with ZoomableAsyncImage to enable zoomable functionality for Coil images. ```diff - AsyncImage( + ZoomableAsyncImage( model = "https://example.com/image.jpg", contentDescription = … ) ``` -------------------------------- ### HardwareShortcutDetector Source: https://github.com/saket/telephoto/blob/trunk/zoomable/api/api.txt Detects hardware shortcuts for zoom and pan actions based on key events or pointer events. ```APIDOC ## Interface HardwareShortcutDetector ### Description Detects hardware shortcuts for zoom and pan. ### Methods - `fun detectKey(event: KeyEvent): ShortcutEvent?` - `fun detectScroll(event: PointerEvent): ShortcutEvent?` ### Companion - `fun getDefault(): HardwareShortcutDetector` ``` -------------------------------- ### Load Image Requests with ZoomableGlideImage (Glide) Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Configure ZoomableGlideImage with a lambda for advanced Glide request options like listeners and transitions. ```kotlin ZoomableGlideImage( model = "https://example.com/image.jpg", contentDescription = … ) { it.addListener(object : RequestListener { override fun onResourceReady(…): Boolean = TODO() override fun onLoadFailed(…): Boolean = TODO() }) .transition(withCrossFade(1_000)) .skipMemoryCache(true) .disallowHardwareConfig() .timeout(30_000) } ``` -------------------------------- ### ZoomablePeekOverlayState Source: https://github.com/saket/telephoto/blob/trunk/zoomable-peek-overlay/api/api.txt Represents the state of the zoomable peek overlay. ```APIDOC ## ZoomablePeekOverlayState ### Description An interface representing the state of the zoomable peek overlay. It provides access to the underlying zoomable state and whether the content is currently zoomed in. ### Methods #### getZoomableState(): ZoomableState Returns the underlying ZoomableState. #### isZoomedIn(): Boolean Checks if the content is currently zoomed in. ``` -------------------------------- ### ZoomableContentLocation.SameAsLayoutBounds Source: https://github.com/saket/telephoto/blob/trunk/zoomable/api/api.txt Implementation of ZoomableContentLocation that matches the layout bounds. ```APIDOC ## ZoomableContentLocation.SameAsLayoutBounds ### Description An implementation of ZoomableContentLocation where the content's bounds are the same as the layout's bounds. ### Methods #### Rect location(long layoutSize, LayoutDirection direction) Returns the location of the content, which is the same as the layout bounds. #### long size(long layoutSize) Returns the size of the content, which is the same as the layout size. ### Fields #### INSTANCE Singleton instance of ZoomableContentLocation.SameAsLayoutBounds. ``` -------------------------------- ### Add zoomable-peek-overlay dependency Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomable-peek-overlay/index.md Add this dependency to your app's build.gradle file to use the zoomable-peek-overlay modifier. ```groovy implementation("me.saket.telephoto:zoomable-peek-overlay:{{ versions.telephoto }}") ``` -------------------------------- ### Await Dependency Availability Source: https://github.com/saket/telephoto/blob/trunk/docs/releasing.md This command waits for a specific dependency version to become available on Maven. Replace `{version}` with the actual version number. ```bash dependency-watch await me.saket.telephoto:zoomable:{version} ``` -------------------------------- ### Display an Image with Sub-sampling Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/sub-sampling.md Use `SubSamplingImage` to display an image from assets, enabling zoomable functionality. ```kotlin val zoomableState = rememberZoomableState() val imageState = rememberSubSamplingImageState( zoomableState = zoomableState, imageSource = SubSamplingImageSource.asset("fox.jpg") ) SubSamplingImage( modifier = Modifier .fillMaxSize() .zoomable(zoomableState), state = imageState, contentDescription = …, ) ``` -------------------------------- ### Use Placeholders with ZoomableAsyncImage (Coil) Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Configure placeholderMemoryCacheKey in ImageRequest.Builder for Coil to display a low-resolution placeholder while the high-resolution image loads. ```kotlin ZoomableAsyncImage( modifier = Modifier.fillMaxSize(), model = ImageRequest.Builder(LocalContext.current) .data("https://example.com/image.jpg") .placeholderMemoryCacheKey(…) .crossfade(1_000) .build(), contentDescription = … ) ``` -------------------------------- ### ZoomableAsyncImage (with InteractionSource) Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/coil3/api/api.txt Displays an image asynchronously with zoomable capabilities, including support for interaction sources. ```APIDOC ## ZoomableAsyncImage (with InteractionSource) ### Description Displays an image asynchronously with zoomable capabilities, including support for interaction sources. ### Parameters - **model** (Object?) - The image model to load. - **contentDescription** (String?) - Description of the image for accessibility. - **gestures** (int) - Controls the gesture behavior. - **modifier** (optional androidx.compose.ui.Modifier) - Modifier for the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState) - The state for the zoomable image. - **imageLoader** (optional coil3.ImageLoader) - The Coil image loader to use. - **alpha** (optional float) - The alpha transparency of the composable. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?) - Color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment) - Alignment of the composable. - **contentScale** (optional androidx.compose.ui.layout.ContentScale) - Content scale of the composable. - **onClick** (optional kotlin.jvm.functions.Function1?) - Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?) - Callback for long click events. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener) - Listener for double-tap to zoom gestures. - **clipToBounds** (optional boolean) - Whether to clip the content to its bounds. - **contentPadding** (optional androidx.compose.foundation.layout.PaddingValues) - Padding around the content. - **interactionSource** (optional androidx.compose.foundation.interaction.MutableInteractionSource?) - Interaction source for the composable. ``` -------------------------------- ### Load Image Requests with ZoomableAsyncImage (Coil) Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/index.md Use ZoomableAsyncImage with a detailed ImageRequest.Builder for advanced configurations like listeners and cache policies. ```kotlin ZoomableAsyncImage( model = ImageRequest.Builder(LocalContext.current) .data("https://example.com/image.jpg") .listener( onSuccess = { … }, onError = { … }, ) .crossfade(1_000) .memoryCachePolicy(CachePolicy.DISABLED) .build(), imageLoader = LocalContext.current.imageLoader, // Optional. contentDescription = … ) ``` -------------------------------- ### coil Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/coil3/api/api.txt Creates a ZoomableImageSource from a Coil image loader. ```APIDOC ## coil ### Description Creates a ZoomableImageSource from a Coil image loader. ### Parameters - **model** (Object?) - The image model to load. - **imageLoader** (optional coil3.ImageLoader) - The Coil image loader to use. ``` -------------------------------- ### ZoomableAsyncImage with Coil, DoubleClick Listener, and Content Padding Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/coil/api/api.txt This overload includes support for double-click gestures and content padding, offering more control over the image display area. ```APIDOC ## ZoomableAsyncImage (Coil with DoubleClick Listener and Content Padding) ### Description This version of `ZoomableAsyncImage` allows for custom double-click zoom behavior and specifies padding around the image content, providing enhanced layout flexibility. ### Method `ZoomableAsyncImage` ### Parameters - **model** (Object?): The image data to display. - **contentDescription** (String?): A description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to apply to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state object to control zoomable image behavior. - **imageLoader** (optional coil.ImageLoader): An optional Coil ImageLoader instance. - **alpha** (optional Float): The alpha transparency of the composable. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): An optional color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): The alignment of the composable. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): The content scale of the image. - **gesturesEnabled** (optional Boolean): Whether gestures are enabled for zooming and panning. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional Boolean): Whether to clip the content to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener): Listener for double-click events to trigger zoom. - **contentPadding** (optional androidx.compose.foundation.layout.PaddingValues): Padding values to apply around the image content. ``` -------------------------------- ### HardwareShortcutDetector.ShortcutEvent.Pan Source: https://github.com/saket/telephoto/blob/trunk/zoomable/api/api.txt Represents a pan shortcut event detected by HardwareShortcutDetector. ```APIDOC ## Class HardwareShortcutDetector.ShortcutEvent.Pan ### Description Represents a pan shortcut event. ``` -------------------------------- ### Download Full Resolution Image with Glide Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/recipes.md Obtain full-resolution images as files by loading them from cache using Glide. This is necessary for streaming images directly from disk. ```kotlin val state = rememberZoomableImageState() ZoomableGlideImage( model = imageUrl, state = state, contentDescription = "…", ) if (state.isImageDisplayed) { Button(onClick = { downloadImage(context, imageUrl) }) { Text("Download image") } } ``` ```kotlin fun downloadImage(context: Context, imageUrl: Uri) { Glide.with(context) .download(imageUrl) .into(object : CustomTarget() { override fun onResourceReady(resource: File, …) { // TODO: copy file to Downloads directory. } override fun onLoadCleared(placeholder: Drawable?) = Unit ) } ``` -------------------------------- ### rememberZoomablePeekOverlayState Source: https://github.com/saket/telephoto/blob/trunk/zoomable-peek-overlay/api/api.txt Creates and remembers a ZoomablePeekOverlayState for managing the overlay's state across recompositions. ```APIDOC ## rememberZoomablePeekOverlayState ### Description Creates and remembers a ZoomablePeekOverlayState for managing the overlay's state across recompositions. ### Signature ```kotlin @Composable public fun rememberZoomablePeekOverlayState(): ZoomablePeekOverlayState ``` ### Returns A new instance of ZoomablePeekOverlayState. ``` -------------------------------- ### ZoomableAsyncImage Overloads Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/coil3/api/api.txt Provides documentation for the different overloads of the ZoomableAsyncImage composable function. ```APIDOC ## ZoomableAsyncImage (Overload 1) ### Description Displays a zoomable image with basic customization options. ### Parameters - **model** (Object?): The image model to load. - **contentDescription** (String?): Description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to be applied to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state for the zoomable image. - **imageLoader** (optional coil3.ImageLoader): The Coil ImageLoader to use. - **alpha** (optional float): The alpha value for the image. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): Color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): Alignment of the image within its bounds. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): Scale of the image within its bounds. - **gesturesEnabled** (optional boolean): Whether gestures are enabled for zooming and panning. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional boolean): Whether to clip the image to its bounds. ## ZoomableAsyncImage (Overload 2) ### Description Displays a zoomable image with support for double-tap to zoom functionality. ### Parameters - **model** (Object?): The image model to load. - **contentDescription** (String?): Description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to be applied to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state for the zoomable image. - **imageLoader** (optional coil3.ImageLoader): The Coil ImageLoader to use. - **alpha** (optional float): The alpha value for the image. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): Color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): Alignment of the image within its bounds. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): Scale of the image within its bounds. - **gesturesEnabled** (optional boolean): Whether gestures are enabled for zooming and panning. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional boolean): Whether to clip the image to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener): Listener for double-click to zoom events. ## ZoomableAsyncImage (Overload 3) ### Description Displays a zoomable image with double-tap to zoom and content padding options. ### Parameters - **model** (Object?): The image model to load. - **contentDescription** (String?): Description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to be applied to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state for the zoomable image. - **imageLoader** (optional coil3.ImageLoader): The Coil ImageLoader to use. - **alpha** (optional float): The alpha value for the image. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): Color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): Alignment of the image within its bounds. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): Scale of the image within its bounds. - **gesturesEnabled** (optional boolean): Whether gestures are enabled for zooming and panning. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional boolean): Whether to clip the image to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener): Listener for double-click to zoom events. - **contentPadding** (optional androidx.compose.foundation.layout.PaddingValues): Padding to apply to the content. ## ZoomableAsyncImage (Overload 4) ### Description Displays a zoomable image with double-tap to zoom, content padding, and interaction source options. ### Parameters - **model** (Object?): The image model to load. - **contentDescription** (String?): Description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to be applied to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state for the zoomable image. - **imageLoader** (optional coil3.ImageLoader): The Coil ImageLoader to use. - **alpha** (optional float): The alpha value for the image. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): Color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): Alignment of the image within its bounds. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): Scale of the image within its bounds. - **gesturesEnabled** (optional boolean): Whether gestures are enabled for zooming and panning. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional boolean): Whether to clip the image to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener): Listener for double-click to zoom events. - **contentPadding** (optional androidx.compose.foundation.layout.PaddingValues): Padding to apply to the content. - **interactionSource** (optional androidx.compose.foundation.interaction.MutableInteractionSource?): The interaction source for the composable. ## ZoomableAsyncImage (Overload 5) ### Description Displays a zoomable image with double-tap to zoom, content padding, and without explicit gesture enablement. ### Parameters - **model** (Object?): The image model to load. - **contentDescription** (String?): Description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to be applied to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state for the zoomable image. - **imageLoader** (optional coil3.ImageLoader): The Coil ImageLoader to use. - **alpha** (optional float): The alpha value for the image. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): Color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): Alignment of the image within its bounds. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): Scale of the image within its bounds. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional boolean): Whether to clip the image to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener): Listener for double-click to zoom events. - **contentPadding** (optional androidx.compose.foundation.layout.PaddingValues): Padding to apply to the content. ``` -------------------------------- ### ZoomableGlideImage with optional parameters Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/glide/api/api.txt Displays an image with zoom and pan gestures. This overload provides a comprehensive set of optional parameters for customization. ```APIDOC ## ZoomableGlideImage ### Description Displays an image with zoom and pan gestures. This overload provides a comprehensive set of optional parameters for customization. ### Method Signature `public static void ZoomableGlideImage(Object? model, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional me.saket.telephoto.zoomable.ZoomableImageState state, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale, optional kotlin.jvm.functions.Function1? onClick, optional kotlin.jvm.functions.Function1? onLongClick, optional boolean clipToBounds, optional me.saket.telephoto.zoomable.DoubleClickToZoomListener onDoubleClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function1,? extends com.bumptech.glide.RequestBuilder> requestBuilderTransform)` ### Parameters - **model** (Object?) - The image model to load. - **contentDescription** (String?) - Description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier) - Modifier to be applied to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState) - The state for controlling zoomable image behavior. - **alpha** (optional float) - Alpha transparency for the image. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?) - Color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment) - Alignment of the image within its bounds. - **contentScale** (optional androidx.compose.ui.layout.ContentScale) - How the image should be scaled. - **onClick** (optional Function1?) - Callback for click events, providing the click offset. - **onLongClick** (optional Function1?) - Callback for long-click events, providing the long-click offset. - **clipToBounds** (optional boolean) - Whether to clip the image to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener) - Listener for double-tap to zoom gestures. - **contentPadding** (optional androidx.compose.foundation.layout.PaddingValues) - Padding to be applied to the content. - **interactionSource** (optional androidx.compose.foundation.interaction.MutableInteractionSource?) - Interaction source for managing interactions. - **requestBuilderTransform** (optional Function1,? extends com.bumptech.glide.RequestBuilder>?) - Transform to apply to the Glide request builder. ``` -------------------------------- ### ZoomableAsyncImage with Coil and DoubleClick Listener Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/coil/api/api.txt An overload that includes a listener for double-click gestures, allowing for custom double-tap zoom behavior. ```APIDOC ## ZoomableAsyncImage (Coil with DoubleClick Listener) ### Description This overload extends the basic `ZoomableAsyncImage` by adding support for a `DoubleClickToZoomListener`, enabling custom handling of double-tap gestures for zooming. ### Method `ZoomableAsyncImage` ### Parameters - **model** (Object?): The image data to display. - **contentDescription** (String?): A description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to apply to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state object to control zoomable image behavior. - **imageLoader** (optional coil.ImageLoader): An optional Coil ImageLoader instance. - **alpha** (optional Float): The alpha transparency of the composable. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): An optional color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): The alignment of the composable. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): The content scale of the image. - **gesturesEnabled** (optional Boolean): Whether gestures are enabled for zooming and panning. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional Boolean): Whether to clip the content to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener): Listener for double-click events to trigger zoom. ``` -------------------------------- ### ZoomableImage with DoubleClickToZoomListener, ContentPadding, and InteractionSource Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/core/api/api.txt Displays a zoomable image with double-tap to zoom, content padding, and interaction source. This is a deprecated overload. ```APIDOC ## ZoomableImage ### Description Displays a zoomable image with double-tap to zoom, content padding, and interaction source. ### Method Composable function ### Parameters - **image** (me.saket.telephoto.zoomable.ZoomableImageSource) - The source of the image to display. - **contentDescription** (String?) - Description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier) - Modifier for the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState) - State to control zoom and pan. - **alpha** (optional float) - Alpha transparency for the image. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?) - Color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment) - Alignment of the image within its bounds. - **contentScale** (optional androidx.compose.ui.layout.ContentScale) - How the image should be scaled. - **gesturesEnabled** (optional boolean) - Whether gestures are enabled for zooming and panning. - **onClick** (optional kotlin.jvm.functions.Function1?) - Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?) - Callback for long press events. - **clipToBounds** (optional boolean) - Whether to clip the image to its bounds. - **onDoubleClick** (optional me.saket.telephoto.zoomable.DoubleClickToZoomListener) - Listener for double-tap to zoom events. - **contentPadding** (optional androidx.compose.foundation.layout.PaddingValues) - Padding around the content. - **interactionSource** (optional androidx.compose.foundation.interaction.MutableInteractionSource?) - Source of interactions for the composable. ``` -------------------------------- ### coil Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/coil/api/api.txt Creates a ZoomableImageSource from a Coil model. ```APIDOC ## coil ### Description Creates a ZoomableImageSource from a Coil model, allowing it to be used with ZoomableAsyncImage. ### Parameters - **model** (Object?): The image model to load using Coil. - **imageLoader** (coil.ImageLoader, optional): Coil's ImageLoader instance to use. ``` -------------------------------- ### ZoomableAsyncImage with Coil Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/coil/api/api.txt Displays an image with zoom and pan gestures, using Coil for image loading. This is a basic overload. ```APIDOC ## ZoomableAsyncImage (Coil Basic Overload) ### Description This composable function displays an image fetched using Coil, with built-in support for zoom and pan gestures. It's a versatile option for integrating zoomable images into your UI. ### Method `ZoomableAsyncImage` ### Parameters - **model** (Object?): The image data to display (e.g., URL, resource ID). - **contentDescription** (String?): A description of the image for accessibility. - **modifier** (optional androidx.compose.ui.Modifier): Modifier to apply to the composable. - **state** (optional me.saket.telephoto.zoomable.ZoomableImageState): The state object to control zoomable image behavior. - **imageLoader** (optional coil.ImageLoader): An optional Coil ImageLoader instance. - **alpha** (optional Float): The alpha transparency of the composable. - **colorFilter** (optional androidx.compose.ui.graphics.ColorFilter?): An optional color filter to apply to the image. - **alignment** (optional androidx.compose.ui.Alignment): The alignment of the composable. - **contentScale** (optional androidx.compose.ui.layout.ContentScale): The content scale of the image. - **gesturesEnabled** (optional Boolean): Whether gestures are enabled for zooming and panning. - **onClick** (optional kotlin.jvm.functions.Function1?): Callback for click events. - **onLongClick** (optional kotlin.jvm.functions.Function1?): Callback for long-click events. - **clipToBounds** (optional Boolean): Whether to clip the content to its bounds. ``` -------------------------------- ### Create a Picasso ZoomableImage Composable Source: https://github.com/saket/telephoto/blob/trunk/docs/zoomableimage/custom-image-loaders.md This composable function integrates Picasso with ZoomableImage. It requires a Picasso instance and handles image loading. ```kotlin import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import com.squareup.picasso.Picasso import me.saket.telephoto.zoomable.ZoomableImage import me.saket.telephoto.zoomable.ZoomableImageSource @Composable fun ZoomablePicassoImage( model: Any?, contentDescription: String?, ) { ZoomableImage( image = ZoomableImageSource.picasso(model), contentDescription = contentDescription, ) } @Composable private fun ZoomableImageSource.Companion.picasso( model: Any?, picasso: Picasso = Picasso .Builder(LocalContext.current) .build(), ): ZoomableImageSource { return remember(model, picasso) { TODO("See ZoomableImageSource.coil() or glide() for an example.") } } ``` -------------------------------- ### ZoomableGlideImage (with DoubleClickToZoomListener) Source: https://github.com/saket/telephoto/blob/trunk/zoomable-image/glide/api/api.txt An overload that includes a DoubleClickToZoomListener for custom double-tap zoom behavior. ```APIDOC ## ZoomableGlideImage (with DoubleClickToZoomListener) ### Description An overload that includes a DoubleClickToZoomListener for custom double-tap zoom behavior. ### Signature public static void ZoomableGlideImage( Object? model, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional me.saket.telephoto.zoomable.ZoomableImageState state, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale, optional boolean gesturesEnabled, optional Function1? onClick, optional Function1? onLongClick, optional boolean clipToBounds, optional me.saket.telephoto.zoomable.DoubleClickToZoomListener onDoubleClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional Function1, ? extends RequestBuilder> requestBuilderTransform ) ```