Improve trash can using in-renderer object.

This commit is contained in:
Alex Hart
2021-09-08 14:32:01 -03:00
committed by Greyson Parrelli
parent e7833df539
commit 1f7b1d91c4
7 changed files with 250 additions and 100 deletions

View File

@@ -12,6 +12,7 @@ import android.graphics.Point;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Bundle;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -131,6 +132,8 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
private ImageEditorHudV2 imageEditorHud;
private ImageEditorView imageEditorView;
private boolean hasMadeAnEditThisSession;
private boolean wasInTrashHitZone;
public static ImageEditorFragment newInstanceForAvatarCapture(@NonNull Uri imageUri) {
ImageEditorFragment fragment = newInstance(imageUri);
@@ -407,6 +410,12 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
imageEditorView.getModel().doneCrop();
}
imageEditorView.getModel()
.getTrash()
.getFlags()
.setVisible(mode == ImageEditorHudV2.Mode.DELETE)
.persist();
switch (mode) {
case CROP: {
imageEditorView.getModel().startCrop();
@@ -838,27 +847,39 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
}
@Override
public void onDragMoved(@Nullable EditorElement editorElement, @NonNull MotionEvent event) {
public void onDragMoved(@Nullable EditorElement editorElement, boolean isInTrashHitZone) {
if (imageEditorHud.getMode() == ImageEditorHudV2.Mode.CROP || editorElement == null) {
return;
}
imageEditorHud.onMoved(event);
if (imageEditorHud.isInDeleteRect()) {
deleteFadeDebouncer.publish(() -> editorElement.animatePartialFadeOut(imageEditorView::invalidate));
if (isInTrashHitZone) {
deleteFadeDebouncer.publish(() -> {
if (!wasInTrashHitZone) {
wasInTrashHitZone = true;
if (imageEditorHud.isHapticFeedbackEnabled()) {
imageEditorHud.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
}
}
editorElement.animatePartialFadeOut(imageEditorView::invalidate);
});
} else {
deleteFadeDebouncer.publish(() -> editorElement.animatePartialFadeIn(imageEditorView::invalidate));
deleteFadeDebouncer.publish(() -> {
wasInTrashHitZone = false;
editorElement.animatePartialFadeIn(imageEditorView::invalidate);
});
}
}
@Override
public void onDragEnded(@Nullable EditorElement editorElement) {
public void onDragEnded(@Nullable EditorElement editorElement, boolean isInTrashHitZone) {
wasInTrashHitZone = false;
imageEditorHud.animate().alpha(1f);
if (imageEditorHud.getMode() == ImageEditorHudV2.Mode.CROP) {
return;
}
if (imageEditorHud.isInDeleteRect()) {
if (isInTrashHitZone) {
deleteFadeDebouncer.clear();
onDelete();
setCurrentSelection(null);

View File

@@ -6,9 +6,7 @@ import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.Rect
import android.util.AttributeSet
import android.view.HapticFeedbackConstants
import android.view.MotionEvent
import android.view.View
import android.widget.FrameLayout
@@ -28,7 +26,6 @@ import org.thoughtcrime.securesms.scribbles.HSVColorSlider.getColor
import org.thoughtcrime.securesms.scribbles.HSVColorSlider.setColor
import org.thoughtcrime.securesms.scribbles.HSVColorSlider.setUpForColor
import org.thoughtcrime.securesms.util.Debouncer
import org.thoughtcrime.securesms.util.ThrottledDebouncer
import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.visible
@@ -65,8 +62,6 @@ class ImageEditorHudV2 @JvmOverloads constructor(
private val blurToast: View = findViewById(R.id.image_editor_hud_blur_toast)
private val blurHelpText: View = findViewById(R.id.image_editor_hud_blur_help_text)
private val colorIndicator: ImageView = findViewById(R.id.image_editor_hud_color_indicator)
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)
@@ -78,23 +73,15 @@ class ImageEditorHudV2 @JvmOverloads constructor(
private val drawButtonRow: Set<View> = setOf(cancelButton, doneButton, drawButton, textButton, stickerButton, blurButton)
private val cropButtonRow: Set<View> = setOf(cancelButton, doneButton, cropRotateButton, cropFlipButton, cropAspectLockButton)
private val allModeTools: Set<View> = drawTools + blurTools + drawButtonRow + cropButtonRow + delete
private val allModeTools: Set<View> = drawTools + blurTools + drawButtonRow + cropButtonRow
private val viewsToSlide: Set<View> = drawButtonRow + cropButtonRow
private val toastDebouncer = Debouncer(3000)
private var colorIndicatorAlphaAnimator: Animator? = null
private val deleteDebouncer = ThrottledDebouncer(500)
private val rect = Rect()
private var modeAnimatorSet: AnimatorSet? = null
private var undoAnimatorSet: AnimatorSet? = null
private var deleteSizeAnimatorSet: AnimatorSet? = null
var isInDeleteRect: Boolean = false
private set
init {
initializeViews()
@@ -287,47 +274,6 @@ class ImageEditorHudV2 @JvmOverloads constructor(
fun getMode(): Mode = currentMode
fun onMoved(motionEvent: MotionEvent) {
delete.getHitRect(rect)
if (rect.contains(motionEvent.x.toInt(), motionEvent.y.toInt())) {
isInDeleteRect = true
deleteDebouncer.publish { scaleDeleteUp() }
} else {
isInDeleteRect = false
deleteDebouncer.publish { scaleDeleteDown() }
}
}
private fun scaleDeleteUp() {
if (delete.isHapticFeedbackEnabled && deleteBackground.scaleX < 1.365f) {
delete.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
}
deleteSizeAnimatorSet?.cancel()
deleteSizeAnimatorSet = AnimatorSet().apply {
playTogether(
ObjectAnimator.ofFloat(deleteBackground, "scaleX", deleteBackground.scaleX, 1.365f),
ObjectAnimator.ofFloat(deleteBackground, "scaleY", deleteBackground.scaleY, 1.365f),
)
duration = ANIMATION_DURATION
interpolator = MediaAnimations.interpolator
start()
}
}
private fun scaleDeleteDown() {
deleteSizeAnimatorSet?.cancel()
deleteSizeAnimatorSet = AnimatorSet().apply {
playTogether(
ObjectAnimator.ofFloat(deleteBackground, "scaleX", deleteBackground.scaleX, 1f),
ObjectAnimator.ofFloat(deleteBackground, "scaleY", deleteBackground.scaleY, 1f),
)
duration = ANIMATION_DURATION
interpolator = MediaAnimations.interpolator
start()
}
}
fun setUndoAvailability(undoAvailability: Boolean) {
this.undoAvailability = undoAvailability
@@ -440,7 +386,6 @@ class ImageEditorHudV2 @JvmOverloads constructor(
private fun presentModeDelete() {
animateModeChange(
inSet = setOf(delete),
outSet = allModeTools
)
animateOutUndoTools()