Add brush width preview.
This commit is contained in:
parent
f86c1fe508
commit
bd4dd25460
4 changed files with 102 additions and 1 deletions
|
@ -39,4 +39,4 @@ internal class ImageEditorValues internal constructor(store: KeyValueStore) : Si
|
|||
fun getHighlighterWidthRange(): Pair<Float, Float> = Pair(0.03f, 0.08f)
|
||||
|
||||
fun getBlurWidthRange(): Pair<Float, Float> = Pair(0.052f, 0.092f)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,6 +68,7 @@ class ImageEditorHudV2 @JvmOverloads constructor(
|
|||
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 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)
|
||||
|
||||
|
@ -172,6 +173,7 @@ class ImageEditorHudV2 @JvmOverloads constructor(
|
|||
widthSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
|
||||
listener?.onBrushWidthChange()
|
||||
brushPreview.setThickness(getActiveBrushWidth())
|
||||
|
||||
when (currentMode) {
|
||||
Mode.DRAW -> SignalStore.imageEditorValues().setMarkerPercentage(progress)
|
||||
|
@ -188,8 +190,10 @@ class ImageEditorHudV2 @JvmOverloads constructor(
|
|||
widthSeekBar.setOnTouchListener { v, event ->
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
animateWidthSeekbarIn()
|
||||
brushPreview.show()
|
||||
} else if (event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL) {
|
||||
animateWidthSeekbarOut()
|
||||
brushPreview.hide()
|
||||
}
|
||||
|
||||
v.onTouchEvent(event)
|
||||
|
@ -449,6 +453,8 @@ class ImageEditorHudV2 @JvmOverloads constructor(
|
|||
private fun updateColorIndicator() {
|
||||
colorIndicator.drawable.colorFilter = SimpleColorFilter(drawSeekBar.getColor())
|
||||
colorIndicator.translationX = (drawSeekBar.thumb.bounds.left.toFloat() + ViewUtil.dpToPx(16))
|
||||
brushPreview.setColor(drawSeekBar.getColor())
|
||||
brushPreview.setBlur(currentMode == Mode.BLUR)
|
||||
}
|
||||
|
||||
private fun animateModeChange(
|
||||
|
|
|
@ -405,4 +405,12 @@
|
|||
|
||||
</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>
|
Loading…
Add table
Reference in a new issue