From b916f0c6199956248d34c9443b24059bfd3f700f Mon Sep 17 00:00:00 2001 From: tibbi Date: Mon, 14 Jan 2019 23:48:52 +0100 Subject: [PATCH] adding initial Gif view zooming, not done yet --- .../gallery/pro/fragments/PhotoFragment.kt | 14 +- .../pro/views/MyZoomableGifTextureView.kt | 195 ++++++++++++++++++ app/src/main/res/layout/pager_photo_item.xml | 7 +- 3 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/gallery/pro/views/MyZoomableGifTextureView.kt diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt index 867c54936..caf20f36e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt @@ -2,10 +2,7 @@ package com.simplemobiletools.gallery.pro.fragments import android.content.Intent import android.content.res.Configuration -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.graphics.Color -import android.graphics.Matrix +import android.graphics.* import android.graphics.drawable.ColorDrawable import android.graphics.drawable.PictureDrawable import android.media.ExifInterface.* @@ -292,6 +289,7 @@ class PhotoFragment : ViewPagerFragment() { } private fun loadImage() { + checkScreenDimensions() mImageOrientation = getImageOrientation() when { mMedium.isGIF() -> loadGif() @@ -310,8 +308,11 @@ class PhotoFragment : ViewPagerFragment() { } mView.photo_view.beGone() - mView.gif_view.beVisible() - mView.gif_view.setInputSource(source) + val resolution = mMedium.path.getImageResolution() ?: Point(0, 0) + mView.gif_view.apply { + setInputSource(source) + setupSizes(resolution.x, resolution.y, mScreenWidth, mScreenHeight) + } } catch (e: Exception) { loadBitmap() } catch (e: OutOfMemoryError) { @@ -328,7 +329,6 @@ class PhotoFragment : ViewPagerFragment() { } private fun loadBitmap(degrees: Int = 0) { - checkScreenDimensions() var pathToLoad = if (mMedium.path.startsWith("content://")) mMedium.path else "file://${mMedium.path}" pathToLoad = pathToLoad.replace("%", "%25").replace("#", "%23") diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/views/MyZoomableGifTextureView.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/views/MyZoomableGifTextureView.kt new file mode 100644 index 000000000..5d2819909 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/views/MyZoomableGifTextureView.kt @@ -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 + } + } +} diff --git a/app/src/main/res/layout/pager_photo_item.xml b/app/src/main/res/layout/pager_photo_item.xml index 46ed641d6..bc3ec30e8 100644 --- a/app/src/main/res/layout/pager_photo_item.xml +++ b/app/src/main/res/layout/pager_photo_item.xml @@ -11,10 +11,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"/> -