Browse Source

Added zoom/drag feature to desktop imageviewer. Added image navigation support via shortcuts.

pull/45/head
Roman Sedaikin 4 years ago
parent
commit
a35596ff03
  1. 1
      examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/view/Scalable.kt
  2. 5
      examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/utils/GraphicsMath.kt
  3. 33
      examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/FullImageScreen.kt
  4. 49
      examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/Zoomable.kt

1
examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/view/Scalable.kt

@ -1,7 +1,6 @@
package example.imageviewer.view
import androidx.compose.runtime.Composable
import androidx.compose.runtime.onDispose
import androidx.compose.ui.gesture.RawScaleObserver
import androidx.compose.ui.gesture.doubleTapGestureFilter
import androidx.compose.ui.gesture.rawScaleGestureFilter

5
examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/utils/GraphicsMath.kt

@ -131,10 +131,7 @@ fun toByteArray(bitmap: BufferedImage) : ByteArray {
}
fun cropImage(bitmap: BufferedImage, crop: Rectangle) : BufferedImage {
val result = BufferedImage(crop.width, crop.height, bitmap.type)
val graphics = result.createGraphics()
graphics.drawImage(bitmap, crop.x, crop.y, crop.width, crop.height, null)
return result
return bitmap.getSubimage(crop.x, crop.y, crop.width, crop.height)
}
fun getPreferredWindowSize(desiredWidth: Int, desiredHeight: Int): IntSize {

33
examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/FullImageScreen.kt

@ -59,7 +59,9 @@ import kotlin.math.pow
import kotlin.math.roundToInt
import org.jetbrains.skija.Image
import org.jetbrains.skija.IRect
import java.awt.event.KeyEvent
import java.awt.Rectangle
import androidx.compose.ui.input.key.*
@Composable
fun setImageFullScreen(
@ -203,6 +205,9 @@ fun getFilterImage(type: FilterType, content: ContentState): ImageAsset {
}
}
@OptIn(
ExperimentalKeyInput::class
)
@Composable
fun setImage(content: ContentState) {
val drag = DragHandler()
@ -213,7 +218,18 @@ fun setImage(content: ContentState) {
modifier = Modifier.fillMaxSize()
) {
Draggable(onDrag = drag, modifier = Modifier.fillMaxSize()) {
Scalable(onScale = scale, modifier = Modifier.fillMaxSize()) {
Zoomable(
onScale = scale,
modifier = Modifier.fillMaxSize()
.shortcuts {
on(Key(KeyEvent.VK_LEFT)) {
content.swipePrevious()
}
on(Key(KeyEvent.VK_RIGHT)) {
content.swipeNext()
}
}
) {
val bitmap = imageByGesture(content, scale, drag)
Image(
asset = bitmap.asImageAsset(),
@ -231,20 +247,7 @@ fun imageByGesture(
drag: DragHandler
): Image {
val bitmap = cropBitmapByScale(content.getSelectedImage(), scale.factor.value, drag)
val image = Image.makeFromEncoded(toByteArray(bitmap))
if (scale.factor.value > 1f)
return image
if (abs(drag.getDistance().x) > displayWidth() / 10) {
if (drag.getDistance().x < 0) {
content.swipeNext()
} else {
content.swipePrevious()
}
drag.onCancel()
}
return image
return Image.makeFromEncoded(toByteArray(bitmap))
}
private fun cropBitmapByScale(bitmap: BufferedImage, scale: Float, drag: DragHandler): BufferedImage {

49
examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/view/Zoomable.kt

@ -0,0 +1,49 @@
package example.imageviewer.view
import androidx.compose.foundation.clickable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.material.Surface
import androidx.compose.runtime.remember
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.focus
import androidx.compose.ui.focus.ExperimentalFocus
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focusRequester
import androidx.compose.ui.input.key.*
import androidx.compose.ui.Modifier
import example.imageviewer.style.Transparent
@OptIn(
ExperimentalKeyInput::class,
ExperimentalFocus::class
)
@Composable
fun Zoomable(
onScale: ScaleHandler,
modifier: Modifier = Modifier,
children: @Composable() () -> Unit
) {
val focusRequester = remember { FocusRequester() }
Surface(
color = Transparent,
modifier = modifier.shortcuts {
on(Key.I) {
onScale.onScale(1.2f)
}
on(Key.O) {
onScale.onScale(0.8f)
}
on(Key.R) {
onScale.resetFactor()
}
}
.focusRequester(focusRequester)
.focus()
.clickable(indication = null) { focusRequester.requestFocus() }
) {
children()
}
}
Loading…
Cancel
Save