mirror of
https://github.com/FossifyOrg/Gallery.git
synced 2024-11-30 00:17:58 +01:00
adding initial Gif view zooming, not done yet
This commit is contained in:
parent
6c019c8edc
commit
b916f0c619
3 changed files with 206 additions and 10 deletions
|
@ -2,10 +2,7 @@ package com.simplemobiletools.gallery.pro.fragments
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.Bitmap
|
import android.graphics.*
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.Matrix
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.graphics.drawable.PictureDrawable
|
import android.graphics.drawable.PictureDrawable
|
||||||
import android.media.ExifInterface.*
|
import android.media.ExifInterface.*
|
||||||
|
@ -292,6 +289,7 @@ class PhotoFragment : ViewPagerFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadImage() {
|
private fun loadImage() {
|
||||||
|
checkScreenDimensions()
|
||||||
mImageOrientation = getImageOrientation()
|
mImageOrientation = getImageOrientation()
|
||||||
when {
|
when {
|
||||||
mMedium.isGIF() -> loadGif()
|
mMedium.isGIF() -> loadGif()
|
||||||
|
@ -310,8 +308,11 @@ class PhotoFragment : ViewPagerFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
mView.photo_view.beGone()
|
mView.photo_view.beGone()
|
||||||
mView.gif_view.beVisible()
|
val resolution = mMedium.path.getImageResolution() ?: Point(0, 0)
|
||||||
mView.gif_view.setInputSource(source)
|
mView.gif_view.apply {
|
||||||
|
setInputSource(source)
|
||||||
|
setupSizes(resolution.x, resolution.y, mScreenWidth, mScreenHeight)
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
loadBitmap()
|
loadBitmap()
|
||||||
} catch (e: OutOfMemoryError) {
|
} catch (e: OutOfMemoryError) {
|
||||||
|
@ -328,7 +329,6 @@ class PhotoFragment : ViewPagerFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadBitmap(degrees: Int = 0) {
|
private fun loadBitmap(degrees: Int = 0) {
|
||||||
checkScreenDimensions()
|
|
||||||
var pathToLoad = if (mMedium.path.startsWith("content://")) mMedium.path else "file://${mMedium.path}"
|
var pathToLoad = if (mMedium.path.startsWith("content://")) mMedium.path else "file://${mMedium.path}"
|
||||||
pathToLoad = pathToLoad.replace("%", "%25").replace("#", "%23")
|
pathToLoad = pathToLoad.replace("%", "%25").replace("#", "%23")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
package com.simplemobiletools.gallery.pro.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Matrix
|
||||||
|
import android.graphics.RectF
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.ScaleGestureDetector
|
||||||
|
import android.widget.ImageView
|
||||||
|
import com.simplemobiletools.commons.extensions.beVisible
|
||||||
|
import com.simplemobiletools.gallery.pro.helpers.*
|
||||||
|
import pl.droidsonroids.gif.GifTextureView
|
||||||
|
|
||||||
|
// allow horizontal swipes through the layout, else it can cause glitches at zoomed in images
|
||||||
|
class MyZoomableGifTextureView(context: Context, attrs: AttributeSet) : GifTextureView(context, attrs) {
|
||||||
|
private var mSaveScale = 1f
|
||||||
|
private var mRight = 0f
|
||||||
|
private var mBottom = 0f
|
||||||
|
private var mLastTouchX = 0f
|
||||||
|
private var mLastTouchY = 0f
|
||||||
|
private var mTouchDownTime = 0L
|
||||||
|
private var mTouchDownX = 0f
|
||||||
|
private var mTouchDownY = 0f
|
||||||
|
private var mGifWidth = 0f
|
||||||
|
private var mGifHeight = 0f
|
||||||
|
private var mScreenWidth = 0f
|
||||||
|
private var mScreenHeight = 0f
|
||||||
|
private var mLastFocusX = 0f
|
||||||
|
private var mLastFocusY = 0f
|
||||||
|
private var mCurrZoomMode = ZOOM_MODE_NONE
|
||||||
|
|
||||||
|
private var mScaleDetector: ScaleGestureDetector? = null
|
||||||
|
private var mMatrices = FloatArray(9)
|
||||||
|
private val mMatrix = Matrix()
|
||||||
|
private var mOrigRect = RectF()
|
||||||
|
private var mWantedRect = RectF()
|
||||||
|
|
||||||
|
init {
|
||||||
|
mScaleDetector = ScaleGestureDetector(context, ScaleListener())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setupSizes(gifWidth: Int, gifHeight: Int, screenWidth: Int, screenHeight: Int) {
|
||||||
|
// if we don't know the gifs' resolution, just display it and disable zooming
|
||||||
|
if (gifWidth == 0 || gifHeight == 0) {
|
||||||
|
scaleType = ImageView.ScaleType.FIT_CENTER
|
||||||
|
mScaleDetector = null
|
||||||
|
beVisible()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mGifWidth = gifWidth.toFloat()
|
||||||
|
mGifHeight = gifHeight.toFloat()
|
||||||
|
mScreenWidth = screenWidth.toFloat()
|
||||||
|
mScreenHeight = screenHeight.toFloat()
|
||||||
|
|
||||||
|
// we basically want scaleType fitCenter, but we have to use matrices to reach that
|
||||||
|
mOrigRect = RectF(0f, 0f, mGifWidth, mGifHeight)
|
||||||
|
mWantedRect = RectF(0f, 0f, mScreenWidth, mScreenHeight)
|
||||||
|
mMatrix.setRectToRect(mOrigRect, mWantedRect, Matrix.ScaleToFit.CENTER)
|
||||||
|
setTransform(mMatrix)
|
||||||
|
invalidate()
|
||||||
|
beVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||||
|
mScaleDetector?.onTouchEvent(event)
|
||||||
|
|
||||||
|
mMatrix.getValues(mMatrices)
|
||||||
|
mMatrix.setRectToRect(mOrigRect, mWantedRect, Matrix.ScaleToFit.CENTER)
|
||||||
|
mMatrix.postScale(mSaveScale, mSaveScale, mLastFocusX, mLastFocusY)
|
||||||
|
|
||||||
|
val x = mMatrices[Matrix.MTRANS_X]
|
||||||
|
val y = mMatrices[Matrix.MTRANS_Y]
|
||||||
|
|
||||||
|
when (event.actionMasked) {
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
mTouchDownTime = System.currentTimeMillis()
|
||||||
|
mCurrZoomMode = ZOOM_MODE_DRAG
|
||||||
|
mLastTouchX = event.x
|
||||||
|
mLastTouchY = event.y
|
||||||
|
|
||||||
|
mTouchDownX = event.x
|
||||||
|
mTouchDownY = event.y
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_UP -> {
|
||||||
|
mCurrZoomMode = ZOOM_MODE_NONE
|
||||||
|
if (System.currentTimeMillis() - mTouchDownTime < CLICK_MAX_DURATION) {
|
||||||
|
performClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_POINTER_DOWN -> {
|
||||||
|
mLastTouchX = event.x
|
||||||
|
mLastTouchY = event.y
|
||||||
|
mCurrZoomMode = ZOOM_MODE_ZOOM
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
if (mCurrZoomMode == ZOOM_MODE_ZOOM || mCurrZoomMode == ZOOM_MODE_DRAG && mSaveScale > MIN_VIDEO_ZOOM_SCALE) {
|
||||||
|
var diffX = event.x - mLastTouchX
|
||||||
|
var diffY = event.y - mLastTouchY
|
||||||
|
if (y + diffY > 0) {
|
||||||
|
diffY = -y
|
||||||
|
} else if (y + diffY < -mBottom) {
|
||||||
|
diffY = -(y + mBottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x + diffX > 0) {
|
||||||
|
diffX = -x
|
||||||
|
} else if (x + diffX < -mRight) {
|
||||||
|
diffX = -(x + mRight)
|
||||||
|
}
|
||||||
|
|
||||||
|
mMatrix.postTranslate(diffX, diffY)
|
||||||
|
mLastTouchX = event.x
|
||||||
|
mLastTouchY = event.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_POINTER_UP -> {
|
||||||
|
mCurrZoomMode = ZOOM_MODE_NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTransform(mMatrix)
|
||||||
|
invalidate()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// taken from https://github.com/Manuiq/ZoomableTextureView
|
||||||
|
private inner class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||||
|
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
|
||||||
|
mCurrZoomMode = ZOOM_MODE_ZOOM
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||||
|
mLastFocusX = detector.focusX
|
||||||
|
mLastFocusY = detector.focusY
|
||||||
|
var scaleFactor = detector.scaleFactor
|
||||||
|
val origScale = mSaveScale
|
||||||
|
mSaveScale *= scaleFactor
|
||||||
|
|
||||||
|
if (mSaveScale > MAX_VIDEO_ZOOM_SCALE) {
|
||||||
|
mSaveScale = MAX_VIDEO_ZOOM_SCALE
|
||||||
|
scaleFactor = MAX_VIDEO_ZOOM_SCALE / origScale
|
||||||
|
} else if (mSaveScale < MIN_VIDEO_ZOOM_SCALE) {
|
||||||
|
mSaveScale = MIN_VIDEO_ZOOM_SCALE
|
||||||
|
scaleFactor = MIN_VIDEO_ZOOM_SCALE / origScale
|
||||||
|
}
|
||||||
|
|
||||||
|
mRight = width * mSaveScale - width
|
||||||
|
mBottom = height * mSaveScale - height
|
||||||
|
if (0 <= width || 0 <= height) {
|
||||||
|
mMatrix.postScale(scaleFactor, scaleFactor, detector.focusX, detector.focusY)
|
||||||
|
if (scaleFactor < 1) {
|
||||||
|
mMatrix.getValues(mMatrices)
|
||||||
|
val x = mMatrices[Matrix.MTRANS_X]
|
||||||
|
val y = mMatrices[Matrix.MTRANS_Y]
|
||||||
|
if (scaleFactor < 1) {
|
||||||
|
if (0 < width) {
|
||||||
|
if (y < -mBottom) {
|
||||||
|
mMatrix.postTranslate(0f, -(y + mBottom))
|
||||||
|
} else if (y > 0) {
|
||||||
|
mMatrix.postTranslate(0f, -y)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (x < -mRight) {
|
||||||
|
mMatrix.postTranslate(-(x + mRight), 0f)
|
||||||
|
} else if (x > 0) {
|
||||||
|
mMatrix.postTranslate(-x, 0f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mMatrix.postScale(scaleFactor, scaleFactor, detector.focusX, detector.focusY)
|
||||||
|
mMatrix.getValues(mMatrices)
|
||||||
|
val x = mMatrices[Matrix.MTRANS_X]
|
||||||
|
val y = mMatrices[Matrix.MTRANS_Y]
|
||||||
|
if (scaleFactor < 1) {
|
||||||
|
if (x < -mRight) {
|
||||||
|
mMatrix.postTranslate(-(x + mRight), 0f)
|
||||||
|
} else if (x > 0) {
|
||||||
|
mMatrix.postTranslate(-x, 0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < -mBottom) {
|
||||||
|
mMatrix.postTranslate(0f, -(y + mBottom))
|
||||||
|
} else if (y > 0) {
|
||||||
|
mMatrix.postTranslate(0f, -y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,10 +11,11 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
<pl.droidsonroids.gif.GifTextureView
|
<com.simplemobiletools.gallery.pro.views.MyZoomableGifTextureView
|
||||||
android:id="@+id/gif_view"
|
android:id="@+id/gif_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
|
android:scaleType="matrix"
|
||||||
android:visibility="gone"/>
|
android:visibility="gone"/>
|
||||||
|
|
||||||
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||||
|
|
Loading…
Reference in a new issue