draft: switch to overlay for focus indicator

This commit is contained in:
Conny Duck 2022-09-05 12:56:54 +02:00
parent 8f08b1b678
commit d345e62e9f
3 changed files with 78 additions and 40 deletions

View File

@ -45,6 +45,7 @@ import com.bumptech.glide.util.Util
import com.github.chrisbanes.photoview.OnPhotoTapListener import com.github.chrisbanes.photoview.OnPhotoTapListener
import com.github.chrisbanes.photoview.PhotoView import com.github.chrisbanes.photoview.PhotoView
import com.keylesspalace.tusky.R import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.databinding.DialogFocusBinding
import com.keylesspalace.tusky.entity.Attachment.Focus import com.keylesspalace.tusky.entity.Attachment.Focus
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.nio.ByteBuffer import java.nio.ByteBuffer
@ -161,48 +162,15 @@ fun <T> T.makeFocusDialog(
previewUri: Uri, previewUri: Uri,
onUpdateFocus: suspend (Focus) -> Boolean onUpdateFocus: suspend (Focus) -> Boolean
) where T : Activity, T : LifecycleOwner { ) where T : Activity, T : LifecycleOwner {
var focus = existingFocus ?: Focus(0.0f, 0.0f) // Default to center val focus = existingFocus ?: Focus(0.0f, 0.0f) // Default to center
val dialogLayout = LinearLayout(this) val dialogBinding = DialogFocusBinding.inflate(layoutInflater)
val padding = Utils.dpToPx(this, 8)
dialogLayout.setPadding(padding, padding, padding, padding)
dialogLayout.orientation = LinearLayout.VERTICAL
val baseImageRequest = Glide.with(this) Glide.with(this)
.load(previewUri) .load(previewUri)
.downsample(DownsampleStrategy.CENTER_INSIDE) .downsample(DownsampleStrategy.CENTER_INSIDE)
.into(dialogBinding.imageView)
var imageView: PhotoView? = null
// Note all calls of this function are after imageView goes non-null
fun imageRequest() {
baseImageRequest.transform(HighlightFocus(focus))
.into(object : CustomTarget<Drawable>(4096, 4096) {
override fun onLoadCleared(placeholder: Drawable?) {
imageView!!.setImageDrawable(placeholder)
}
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
imageView!!.setImageDrawable(resource)
}
})
}
imageView = PhotoView(this).apply {
maximumScale = 6f
setOnPhotoTapListener(object : OnPhotoTapListener {
override fun onPhotoTap(view: ImageView, x: Float, y: Float) {
focus = Focus(x * 2 - 1, 1 - y * 2) // PhotoView range is 0..1 Y-down but Mastodon API range is -1..1 Y-up
imageRequest()
}
})
}
val margin = Utils.dpToPx(this, 4)
dialogLayout.addView(imageView)
(imageView.layoutParams as LinearLayout.LayoutParams).weight = 1f
imageView.layoutParams.height = 0
(imageView.layoutParams as LinearLayout.LayoutParams).setMargins(0, margin, 0, 0)
val okListener = { dialog: DialogInterface, _: Int -> val okListener = { dialog: DialogInterface, _: Int ->
lifecycleScope.launch { lifecycleScope.launch {
@ -214,7 +182,7 @@ fun <T> T.makeFocusDialog(
} }
val dialog = AlertDialog.Builder(this) val dialog = AlertDialog.Builder(this)
.setView(dialogLayout) .setView(dialogBinding.root)
.setPositiveButton(android.R.string.ok, okListener) .setPositiveButton(android.R.string.ok, okListener)
.setNegativeButton(android.R.string.cancel, null) .setNegativeButton(android.R.string.cancel, null)
.create() .create()
@ -226,8 +194,7 @@ fun <T> T.makeFocusDialog(
dialog.show() dialog.show()
// Load the image and manually set it into the ImageView because it doesn't have a fixed size.
imageRequest()
} }
private fun Activity.showFailedFocusMessage() { private fun Activity.showFailedFocusMessage() {

View File

@ -0,0 +1,54 @@
package com.keylesspalace.tusky.components.compose.view
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.entity.Attachment
class FocusIndicatorView
@JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private var focusDrawable: Drawable = AppCompatResources.getDrawable(context, R.drawable.spellcheck)!! // TODO: use an actual drawable suited as indicator
private var posX = 0f
private var posY = 0f
fun setFocus(focus: Attachment.Focus) {
// TODO
invalidate()
}
fun getFocus() {
// TODO
invalidate()
}
override fun onTouchEvent(event: MotionEvent): Boolean {
// TODO: only handle events if they are on top of the image below
// TODO: don't handle all event actions
posX = event.x
posY = event.y
invalidate()
return true
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
focusDrawable.setBounds(
posX.toInt() - focusDrawable.intrinsicWidth / 2,
posY.toInt() - focusDrawable.intrinsicHeight / 2,
posX.toInt() + focusDrawable.intrinsicWidth / 2,
posY.toInt() + focusDrawable.intrinsicHeight / 2
)
focusDrawable.draw(canvas)
}
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- todo add padding -->
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.keylesspalace.tusky.components.compose.view.FocusIndicatorView
android:id="@+id/focusIndicator"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>