From f86c1fe50837626f5557012002bdd88afef97e0f Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Wed, 8 Sep 2021 08:37:56 -0300 Subject: [PATCH] Support different width ranges for different brushes. --- .../securesms/keyvalue/ImageEditorValues.kt | 42 +++++++++++++++++++ .../securesms/keyvalue/SignalStore.java | 8 ++++ .../scribbles/ImageEditorFragment.java | 21 +++++----- .../securesms/scribbles/ImageEditorHudV2.kt | 31 ++++++++++---- 4 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/keyvalue/ImageEditorValues.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ImageEditorValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ImageEditorValues.kt new file mode 100644 index 000000000..b7579bd57 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ImageEditorValues.kt @@ -0,0 +1,42 @@ +package org.thoughtcrime.securesms.keyvalue + +internal class ImageEditorValues internal constructor(store: KeyValueStore) : SignalStoreValues(store) { + + companion object { + private const val KEY_IMAGE_EDITOR_MARKER_WIDTH = "image.editor.marker.width" + private const val KEY_IMAGE_EDITOR_HIGHLIGHTER_WIDTH = "image.editor.highlighter.width" + private const val KEY_IMAGE_EDITOR_BLUR_WIDTH = "image.editor.blur.width" + } + + public override fun onFirstEverAppLaunch() = Unit + + public override fun getKeysToIncludeInBackup(): List = listOf( + KEY_IMAGE_EDITOR_MARKER_WIDTH, + KEY_IMAGE_EDITOR_HIGHLIGHTER_WIDTH, + KEY_IMAGE_EDITOR_BLUR_WIDTH + ) + + fun setMarkerPercentage(markerPercentage: Int) { + putInteger(KEY_IMAGE_EDITOR_MARKER_WIDTH, markerPercentage) + } + + fun setHighlighterPercentage(highlighterPercentage: Int) { + putInteger(KEY_IMAGE_EDITOR_HIGHLIGHTER_WIDTH, highlighterPercentage) + } + + fun setBlurPercentage(blurPercentage: Int) { + putInteger(KEY_IMAGE_EDITOR_BLUR_WIDTH, blurPercentage) + } + + fun getMarkerPercentage(): Int = getInteger(KEY_IMAGE_EDITOR_MARKER_WIDTH, 0) + + fun getHighlighterPercentage(): Int = getInteger(KEY_IMAGE_EDITOR_HIGHLIGHTER_WIDTH, 0) + + fun getBlurPercentage(): Int = getInteger(KEY_IMAGE_EDITOR_BLUR_WIDTH, 0) + + fun getMarkerWidthRange(): Pair = Pair(0.01f, 0.05f) + + fun getHighlighterWidthRange(): Pair = Pair(0.03f, 0.08f) + + fun getBlurWidthRange(): Pair = Pair(0.052f, 0.092f) +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java index 2c3dfc088..1c197b866 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java @@ -37,6 +37,7 @@ public final class SignalStore { private final ProxyValues proxyValues; private final RateLimitValues rateLimitValues; private final ChatColorsValues chatColorsValues; + private final ImageEditorValues imageEditorValues; private SignalStore() { this.store = new KeyValueStore(ApplicationDependencies.getApplication()); @@ -59,6 +60,7 @@ public final class SignalStore { this.proxyValues = new ProxyValues(store); this.rateLimitValues = new RateLimitValues(store); this.chatColorsValues = new ChatColorsValues(store); + this.imageEditorValues = new ImageEditorValues(store); } public static void onFirstEverAppLaunch() { @@ -81,6 +83,7 @@ public final class SignalStore { proxy().onFirstEverAppLaunch(); rateLimit().onFirstEverAppLaunch(); chatColorsValues().onFirstEverAppLaunch(); + imageEditorValues().onFirstEverAppLaunch(); } public static List getKeysToIncludeInBackup() { @@ -104,6 +107,7 @@ public final class SignalStore { keys.addAll(proxy().getKeysToIncludeInBackup()); keys.addAll(rateLimit().getKeysToIncludeInBackup()); keys.addAll(chatColorsValues().getKeysToIncludeInBackup()); + keys.addAll(imageEditorValues().getKeysToIncludeInBackup()); return keys; } @@ -192,6 +196,10 @@ public final class SignalStore { return INSTANCE.chatColorsValues; } + public static @NonNull ImageEditorValues imageEditorValues() { + return INSTANCE.imageEditorValues; + } + public static @NonNull GroupsV2AuthorizationSignalStoreCache groupsV2AuthorizationCache() { return new GroupsV2AuthorizationSignalStoreCache(getStore()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java index 751cf16ec..333498f26 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorFragment.java @@ -43,6 +43,7 @@ import org.thoughtcrime.securesms.imageeditor.Renderer; import org.thoughtcrime.securesms.imageeditor.SelectableRenderer; import org.thoughtcrime.securesms.imageeditor.model.EditorElement; import org.thoughtcrime.securesms.imageeditor.model.EditorModel; +import org.thoughtcrime.securesms.imageeditor.renderers.BezierDrawingRenderer; import org.thoughtcrime.securesms.imageeditor.renderers.FaceBlurRenderer; import org.thoughtcrime.securesms.imageeditor.renderers.MultiLineTextRenderer; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -414,12 +415,12 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu case DRAW: case HIGHLIGHT: { - onBrushWidthChange(imageEditorHud.getActiveBrushWidth()); + onBrushWidthChange(); break; } case BLUR: { - onBrushWidthChange(imageEditorHud.getActiveBrushWidth()); + onBrushWidthChange(); imageEditorHud.setBlurFacesToggleEnabled(imageEditorView.getModel().hasFaceRenderer()); break; } @@ -479,15 +480,10 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu onColorChange(imageEditorHud.getActiveColor()); } - private static final float MINIMUM_DRAW_WIDTH = 0.01f; - private static final float MAXIMUM_DRAW_WIDTH = 0.05f; - @Override - public void onBrushWidthChange(int widthPercentage) { + public void onBrushWidthChange() { ImageEditorHudV2.Mode mode = imageEditorHud.getMode(); - - float interpolatedWidth = MINIMUM_DRAW_WIDTH + (MAXIMUM_DRAW_WIDTH - MINIMUM_DRAW_WIDTH) * (widthPercentage / 100f); - imageEditorView.startDrawing(interpolatedWidth, mode == ImageEditorHudV2.Mode.HIGHLIGHT ? Paint.Cap.SQUARE : Paint.Cap.ROUND, mode == ImageEditorHudV2.Mode.BLUR); + imageEditorView.startDrawing(imageEditorHud.getActiveBrushWidth(), mode == ImageEditorHudV2.Mode.HIGHLIGHT ? Paint.Cap.SQUARE : Paint.Cap.ROUND, mode == ImageEditorHudV2.Mode.BLUR); } @Override @@ -828,7 +824,12 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu return; } - setCurrentSelection(editorElement); + if (editorElement == null || editorElement.getRenderer() instanceof BezierDrawingRenderer) { + setCurrentSelection(null); + } else { + setCurrentSelection(editorElement); + } + if (imageEditorView.getMode() == ImageEditorView.Mode.MoveAndResize) { imageEditorHud.setMode(ImageEditorHudV2.Mode.DELETE); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorHudV2.kt b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorHudV2.kt index 580f2846b..c4952e422 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorHudV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorHudV2.kt @@ -14,7 +14,6 @@ import android.view.View import android.widget.FrameLayout import android.widget.ImageView import android.widget.SeekBar -import androidx.annotation.IntRange import androidx.appcompat.widget.AppCompatSeekBar import androidx.constraintlayout.widget.Guideline import androidx.core.animation.doOnEnd @@ -23,6 +22,7 @@ import com.airbnb.lottie.SimpleColorFilter import com.google.android.material.switchmaterial.SwitchMaterial import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.TooltipPopup +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.mediasend.v2.MediaAnimations import org.thoughtcrime.securesms.scribbles.HSVColorSlider.getColor import org.thoughtcrime.securesms.scribbles.HSVColorSlider.setColor @@ -171,7 +171,14 @@ class ImageEditorHudV2 @JvmOverloads constructor( widthSeekBar.thumb = HSVColorSlider.createThumbDrawable(Color.WHITE) widthSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { - listener?.onBrushWidthChange(progress) + listener?.onBrushWidthChange() + + when (currentMode) { + Mode.DRAW -> SignalStore.imageEditorValues().setMarkerPercentage(progress) + Mode.BLUR -> SignalStore.imageEditorValues().setBlurPercentage(progress) + Mode.HIGHLIGHT -> SignalStore.imageEditorValues().setHighlighterPercentage(progress) + else -> Unit + } } override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit @@ -187,8 +194,6 @@ class ImageEditorHudV2 @JvmOverloads constructor( v.onTouchEvent(event) } - - widthSeekBar.progress = 20 } private fun animateWidthSeekbarIn() { @@ -233,8 +238,9 @@ class ImageEditorHudV2 @JvmOverloads constructor( updateColorIndicator() } - fun getActiveBrushWidth(): Int { - return widthSeekBar.progress + fun getActiveBrushWidth(): Float { + val (minimum, maximum) = DRAW_WIDTH_BOUNDARIES[currentMode] ?: throw IllegalStateException("Cannot get width in mode $currentMode") + return minimum + (maximum - minimum) * (widthSeekBar.progress / 100f) } fun setBlurFacesToggleEnabled(enabled: Boolean) { @@ -377,6 +383,7 @@ class ImageEditorHudV2 @JvmOverloads constructor( private fun presentModeDraw() { drawButton.isSelected = true brushToggle.setImageResource(R.drawable.ic_draw_white_24) + widthSeekBar.progress = SignalStore.imageEditorValues().getMarkerPercentage() listener?.onColorChange(getActiveColor()) updateColorIndicator() animateModeChange( @@ -389,6 +396,7 @@ class ImageEditorHudV2 @JvmOverloads constructor( private fun presentModeHighlight() { drawButton.isSelected = true brushToggle.setImageResource(R.drawable.ic_marker_24) + widthSeekBar.progress = SignalStore.imageEditorValues().getHighlighterPercentage() listener?.onColorChange(getActiveColor()) updateColorIndicator() animateModeChange( @@ -400,6 +408,9 @@ class ImageEditorHudV2 @JvmOverloads constructor( private fun presentModeBlur() { blurButton.isSelected = true + widthSeekBar.progress = SignalStore.imageEditorValues().getBlurPercentage() + listener?.onColorChange(getActiveColor()) + updateColorIndicator() animateModeChange( inSet = drawButtonRow + blurTools, outSet = allModeTools @@ -535,6 +546,12 @@ class ImageEditorHudV2 @JvmOverloads constructor( private const val ANIMATION_DURATION = 250L + private val DRAW_WIDTH_BOUNDARIES: Map> = mapOf( + Mode.DRAW to SignalStore.imageEditorValues().getMarkerWidthRange(), + Mode.HIGHLIGHT to SignalStore.imageEditorValues().getHighlighterWidthRange(), + Mode.BLUR to SignalStore.imageEditorValues().getBlurWidthRange() + ) + private fun withHighlighterAlpha(color: Int): Int { return color and 0xFF000000.toInt().inv() or 0x60000000 } @@ -543,7 +560,7 @@ class ImageEditorHudV2 @JvmOverloads constructor( interface EventListener { fun onModeStarted(mode: Mode, previousMode: Mode) fun onColorChange(color: Int) - fun onBrushWidthChange(@IntRange(from = 0, to = 100) widthPercentage: Int) + fun onBrushWidthChange() fun onBlurFacesToggled(enabled: Boolean) fun onUndo() fun onClearAll()