Yuito-app-android/app/src/main/java/com/keylesspalace/tusky/view/MediaPreviewImageView.kt

125 lines
4.5 KiB
Kotlin

/* Copyright 2018 Jochem Raat <jchmrt@riseup.net>
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.view
import android.content.Context
import android.graphics.Matrix
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
import com.keylesspalace.tusky.entity.Attachment
import com.keylesspalace.tusky.util.FocalPointUtil
import com.squareup.picasso.Callback
/**
* This is an extension of the standard android ImageView, which makes sure to update the custom
* matrix when its size changes if a focal point is set.
*
* If a focal point is set on this view, it will use the FocalPointUtil to update the image
* matrix each time the size of the view is changed. This is needed to ensure that the correct
* cropping is maintained.
*
* However if there is no focal point set (e.g. it is null), then this view should simply
* act exactly the same as an ordinary android ImageView.
*/
class MediaPreviewImageView
@JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr), Callback {
private var focus: Attachment.Focus? = null
private var focalMatrix: Matrix? = null
/**
* Set the focal point for this view.
*/
fun setFocalPoint(focus: Attachment.Focus) {
this.focus = focus
super.setScaleType(ScaleType.MATRIX)
if (focalMatrix == null) {
focalMatrix = Matrix()
}
}
/**
* Remove the focal point from this view (if there was one).
*/
fun removeFocalPoint() {
super.setScaleType(ScaleType.CENTER_CROP)
focus = null
}
/**
* Overridden getScaleType method which returns CENTER_CROP if we have a focal point set.
*
* This is necessary because the Android transitions framework tries to copy the scale type
* from this view to the PhotoView when animating between this view and the detailled view of
* the image. Since the PhotoView does not support a MATRIX scale type, the app would crash
* if we simply passed that on, so instead we pretend that CENTER_CROP is still used here
* even if we have a focus point set.
*/
override fun getScaleType(): ScaleType {
if (focus != null) {
return ScaleType.CENTER_CROP
} else {
return super.getScaleType()
}
}
/**
* Overridden setScaleType method which only accepts the new type if we don't have a focal
* point set.
*
*
*/
override fun setScaleType(type: ScaleType) {
if (focus != null) {
super.setScaleType(ScaleType.MATRIX)
} else {
super.setScaleType(type)
}
}
/**
* Called when the image is first succesfully loaded by Picasso, this function makes sure
* that the custom matrix of this image is initialized if a focus point is set.
*/
override fun onSuccess() {
onSizeChanged(width, height, width, height)
}
// We do not handle the error here, instead it will be handled higher up the call chain.
override fun onError() {
}
/**
* Called when the size of the view changes, it calls the FocalPointUtil to update the
* matrix if we have a set focal point. It then reassigns the matrix to this imageView.
*/
override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) {
if (drawable != null && focus != null && focalMatrix != null) {
scaleType = ScaleType.MATRIX
FocalPointUtil.updateFocalPointMatrix(width.toFloat(), height.toFloat(),
drawable.intrinsicWidth.toFloat(), drawable.intrinsicHeight.toFloat(),
focus as Attachment.Focus, focalMatrix as Matrix)
imageMatrix = focalMatrix
}
super.onSizeChanged(width, height, oldWidth, oldHeight)
}
}