Add brush width preview.

This commit is contained in:
Alex Hart 2021-09-08 09:48:43 -03:00 committed by Greyson Parrelli
parent f86c1fe508
commit bd4dd25460
4 changed files with 102 additions and 1 deletions

View file

@ -0,0 +1,87 @@
package org.thoughtcrime.securesms.scribbles
import android.animation.Animator
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View
import androidx.annotation.ColorInt
import androidx.core.animation.doOnEnd
import org.thoughtcrime.securesms.imageeditor.Bounds
import org.thoughtcrime.securesms.mediasend.v2.MediaAnimations
import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.visible
class BrushWidthPreviewView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val tmpRect = Rect()
private var animator: Animator? = null
private val backdropPaint = Paint().apply {
isAntiAlias = true
style = Paint.Style.FILL
color = Color.WHITE
}
private val brushPaint = Paint().apply {
isAntiAlias = true
style = Paint.Style.FILL
color = Color.WHITE
}
private var radius: Float = (0.03f * Bounds.FULL_BOUNDS.width() / 2f)
private var isBlur: Boolean = false
fun setBlur(blur: Boolean) {
isBlur = blur
invalidate()
}
fun setColor(@ColorInt color: Int) {
brushPaint.color = color
invalidate()
}
fun setThickness(thickness: Float) {
radius = (thickness * Bounds.FULL_BOUNDS.width()) / 2f
invalidate()
}
fun show() {
visible = true
animator?.cancel()
animator = ObjectAnimator.ofFloat(this, "alpha", 1f).apply {
interpolator = MediaAnimations.interpolator
duration = 150L
start()
}
}
fun hide() {
animator?.cancel()
animator = ObjectAnimator.ofFloat(this, "alpha", 0f).apply {
interpolator = MediaAnimations.interpolator
duration = 150L
doOnEnd { visible = false }
start()
}
}
override fun onDraw(canvas: Canvas) {
canvas.getClipBounds(tmpRect)
canvas.drawCircle(tmpRect.exactCenterX(), tmpRect.exactCenterY(), radius + ViewUtil.dpToPx(1), backdropPaint)
if (!isBlur) {
canvas.drawCircle(tmpRect.exactCenterX(), tmpRect.exactCenterY(), radius, brushPaint)
}
}
}

View file

@ -68,6 +68,7 @@ class ImageEditorHudV2 @JvmOverloads constructor(
private val delete: FrameLayout = findViewById(R.id.image_editor_hud_delete) private val delete: FrameLayout = findViewById(R.id.image_editor_hud_delete)
private val deleteBackground: View = findViewById(R.id.image_editor_hud_delete_bg) private val deleteBackground: View = findViewById(R.id.image_editor_hud_delete_bg)
private val bottomGuideline: Guideline = findViewById(R.id.image_editor_bottom_guide) private val bottomGuideline: Guideline = findViewById(R.id.image_editor_bottom_guide)
private val brushPreview: BrushWidthPreviewView = findViewById(R.id.image_editor_hud_brush_preview)
private val selectableSet: Set<View> = setOf(drawButton, textButton, stickerButton, blurButton) private val selectableSet: Set<View> = setOf(drawButton, textButton, stickerButton, blurButton)
@ -172,6 +173,7 @@ class ImageEditorHudV2 @JvmOverloads constructor(
widthSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { widthSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
listener?.onBrushWidthChange() listener?.onBrushWidthChange()
brushPreview.setThickness(getActiveBrushWidth())
when (currentMode) { when (currentMode) {
Mode.DRAW -> SignalStore.imageEditorValues().setMarkerPercentage(progress) Mode.DRAW -> SignalStore.imageEditorValues().setMarkerPercentage(progress)
@ -188,8 +190,10 @@ class ImageEditorHudV2 @JvmOverloads constructor(
widthSeekBar.setOnTouchListener { v, event -> widthSeekBar.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN) { if (event.action == MotionEvent.ACTION_DOWN) {
animateWidthSeekbarIn() animateWidthSeekbarIn()
brushPreview.show()
} else if (event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL) { } else if (event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL) {
animateWidthSeekbarOut() animateWidthSeekbarOut()
brushPreview.hide()
} }
v.onTouchEvent(event) v.onTouchEvent(event)
@ -449,6 +453,8 @@ class ImageEditorHudV2 @JvmOverloads constructor(
private fun updateColorIndicator() { private fun updateColorIndicator() {
colorIndicator.drawable.colorFilter = SimpleColorFilter(drawSeekBar.getColor()) colorIndicator.drawable.colorFilter = SimpleColorFilter(drawSeekBar.getColor())
colorIndicator.translationX = (drawSeekBar.thumb.bounds.left.toFloat() + ViewUtil.dpToPx(16)) colorIndicator.translationX = (drawSeekBar.thumb.bounds.left.toFloat() + ViewUtil.dpToPx(16))
brushPreview.setColor(drawSeekBar.getColor())
brushPreview.setBlur(currentMode == Mode.BLUR)
} }
private fun animateModeChange( private fun animateModeChange(

View file

@ -405,4 +405,12 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<org.thoughtcrime.securesms.scribbles.BrushWidthPreviewView
android:id="@+id/image_editor_hud_brush_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible"
android:alpha="0"
tools:alpha="1" />
</merge> </merge>