Update blur UI.
This commit is contained in:
parent
66f021d01a
commit
da33ba0ed5
6 changed files with 92 additions and 48 deletions
|
@ -7,7 +7,6 @@ import org.whispersystems.signalservice.api.storage.StorageKey;
|
||||||
public class TooltipValues {
|
public class TooltipValues {
|
||||||
|
|
||||||
private static final String BLUR_HUD_ICON = "tooltip.blur_hud_icon";
|
private static final String BLUR_HUD_ICON = "tooltip.blur_hud_icon";
|
||||||
private static final String AUTO_BLUR_FACES = "tooltip.auto_blur_faces";
|
|
||||||
|
|
||||||
private final KeyValueStore store;
|
private final KeyValueStore store;
|
||||||
|
|
||||||
|
@ -25,12 +24,4 @@ public class TooltipValues {
|
||||||
public void markBlurHudIconTooltipSeen() {
|
public void markBlurHudIconTooltipSeen() {
|
||||||
store.beginWrite().putBoolean(BLUR_HUD_ICON, true).apply();
|
store.beginWrite().putBoolean(BLUR_HUD_ICON, true).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSeenAutoBlurFacesTooltip() {
|
|
||||||
return store.getBoolean(AUTO_BLUR_FACES, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void markAutoBlurFacesTooltipSeen() {
|
|
||||||
store.beginWrite().putBoolean(AUTO_BLUR_FACES, true).apply();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,12 +306,8 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||||
}
|
}
|
||||||
|
|
||||||
case BLUR: {
|
case BLUR: {
|
||||||
imageEditorView.startDrawing(0.055f, Paint.Cap.ROUND, true);
|
imageEditorView.startDrawing(0.052f, Paint.Cap.ROUND, true);
|
||||||
imageEditorHud.setBlurFacesToggleEnabled(imageEditorView.getModel().hasFaceRenderer());
|
imageEditorHud.setBlurFacesToggleEnabled(imageEditorView.getModel().hasFaceRenderer());
|
||||||
if (!SignalStore.tooltips().hasSeenAutoBlurFacesTooltip()) {
|
|
||||||
imageEditorHud.showAutoBlurFacesTooltip();
|
|
||||||
SignalStore.tooltips().markAutoBlurFacesTooltipSeen();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,11 +344,13 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||||
EditorModel model = imageEditorView.getModel();
|
EditorModel model = imageEditorView.getModel();
|
||||||
EditorElement mainImage = model.getMainImage();
|
EditorElement mainImage = model.getMainImage();
|
||||||
if (mainImage == null) {
|
if (mainImage == null) {
|
||||||
|
imageEditorHud.hideBlurToast();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
model.clearFaceRenderers();
|
model.clearFaceRenderers();
|
||||||
|
imageEditorHud.hideBlurToast();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,6 +359,7 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||||
if (cachedFaceDetection != null) {
|
if (cachedFaceDetection != null) {
|
||||||
if (cachedFaceDetection.first().equals(getUri()) && cachedFaceDetection.second().position.equals(inverseCropPosition)) {
|
if (cachedFaceDetection.first().equals(getUri()) && cachedFaceDetection.second().position.equals(inverseCropPosition)) {
|
||||||
renderFaceBlurs(cachedFaceDetection.second());
|
renderFaceBlurs(cachedFaceDetection.second());
|
||||||
|
imageEditorHud.showBlurToast();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
cachedFaceDetection = null;
|
cachedFaceDetection = null;
|
||||||
|
@ -392,6 +391,7 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||||
mainImage.getFlags().reset();
|
mainImage.getFlags().reset();
|
||||||
renderFaceBlurs(result);
|
renderFaceBlurs(result);
|
||||||
progress.dismiss();
|
progress.dismiss();
|
||||||
|
imageEditorHud.showBlurToast();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
@ -19,6 +19,8 @@ import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.components.TooltipPopup;
|
import org.thoughtcrime.securesms.components.TooltipPopup;
|
||||||
import org.thoughtcrime.securesms.scribbles.widget.ColorPaletteAdapter;
|
import org.thoughtcrime.securesms.scribbles.widget.ColorPaletteAdapter;
|
||||||
import org.thoughtcrime.securesms.scribbles.widget.VerticalSlideColorPicker;
|
import org.thoughtcrime.securesms.scribbles.widget.VerticalSlideColorPicker;
|
||||||
|
import org.thoughtcrime.securesms.util.Debouncer;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -46,11 +48,13 @@ public final class ImageEditorHud extends LinearLayout {
|
||||||
private View deleteButton;
|
private View deleteButton;
|
||||||
private View confirmButton;
|
private View confirmButton;
|
||||||
private View doneButton;
|
private View doneButton;
|
||||||
private View blurToggleContainer;
|
private View blurToggleHud;
|
||||||
private Switch blurToggle;
|
private Switch blurToggle;
|
||||||
|
private View blurToast;
|
||||||
private VerticalSlideColorPicker colorPicker;
|
private VerticalSlideColorPicker colorPicker;
|
||||||
private RecyclerView colorPalette;
|
private RecyclerView colorPalette;
|
||||||
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private EventListener eventListener = NULL_EVENT_LISTENER;
|
private EventListener eventListener = NULL_EVENT_LISTENER;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -58,6 +62,7 @@ public final class ImageEditorHud extends LinearLayout {
|
||||||
|
|
||||||
private final Map<Mode, Set<View>> visibilityModeMap = new HashMap<>();
|
private final Map<Mode, Set<View>> visibilityModeMap = new HashMap<>();
|
||||||
private final Set<View> allViews = new HashSet<>();
|
private final Set<View> allViews = new HashSet<>();
|
||||||
|
private final Debouncer toastDebouncer = new Debouncer(3000);
|
||||||
|
|
||||||
private Mode currentMode;
|
private Mode currentMode;
|
||||||
private boolean undoAvailable;
|
private boolean undoAvailable;
|
||||||
|
@ -81,24 +86,25 @@ public final class ImageEditorHud extends LinearLayout {
|
||||||
inflate(getContext(), R.layout.image_editor_hud, this);
|
inflate(getContext(), R.layout.image_editor_hud, this);
|
||||||
setOrientation(VERTICAL);
|
setOrientation(VERTICAL);
|
||||||
|
|
||||||
cropButton = findViewById(R.id.scribble_crop_button);
|
cropButton = findViewById(R.id.scribble_crop_button);
|
||||||
cropFlipButton = findViewById(R.id.scribble_crop_flip);
|
cropFlipButton = findViewById(R.id.scribble_crop_flip);
|
||||||
cropRotateButton = findViewById(R.id.scribble_crop_rotate);
|
cropRotateButton = findViewById(R.id.scribble_crop_rotate);
|
||||||
cropAspectLock = findViewById(R.id.scribble_crop_aspect_lock);
|
cropAspectLock = findViewById(R.id.scribble_crop_aspect_lock);
|
||||||
colorPalette = findViewById(R.id.scribble_color_palette);
|
colorPalette = findViewById(R.id.scribble_color_palette);
|
||||||
drawButton = findViewById(R.id.scribble_draw_button);
|
drawButton = findViewById(R.id.scribble_draw_button);
|
||||||
highlightButton = findViewById(R.id.scribble_highlight_button);
|
highlightButton = findViewById(R.id.scribble_highlight_button);
|
||||||
blurButton = findViewById(R.id.scribble_blur_button);
|
blurButton = findViewById(R.id.scribble_blur_button);
|
||||||
textButton = findViewById(R.id.scribble_text_button);
|
textButton = findViewById(R.id.scribble_text_button);
|
||||||
stickerButton = findViewById(R.id.scribble_sticker_button);
|
stickerButton = findViewById(R.id.scribble_sticker_button);
|
||||||
undoButton = findViewById(R.id.scribble_undo_button);
|
undoButton = findViewById(R.id.scribble_undo_button);
|
||||||
saveButton = findViewById(R.id.scribble_save_button);
|
saveButton = findViewById(R.id.scribble_save_button);
|
||||||
deleteButton = findViewById(R.id.scribble_delete_button);
|
deleteButton = findViewById(R.id.scribble_delete_button);
|
||||||
confirmButton = findViewById(R.id.scribble_confirm_button);
|
confirmButton = findViewById(R.id.scribble_confirm_button);
|
||||||
colorPicker = findViewById(R.id.scribble_color_picker);
|
colorPicker = findViewById(R.id.scribble_color_picker);
|
||||||
doneButton = findViewById(R.id.scribble_done_button);
|
doneButton = findViewById(R.id.scribble_done_button);
|
||||||
blurToggleContainer = findViewById(R.id.scribble_blur_toggle_container);
|
blurToggleHud = findViewById(R.id.scribble_blur_toggle_hud);
|
||||||
blurToggle = findViewById(R.id.scribble_blur_toggle);
|
blurToggle = findViewById(R.id.scribble_blur_toggle);
|
||||||
|
blurToast = findViewById(R.id.scribble_blur_toast);
|
||||||
|
|
||||||
cropAspectLock.setOnClickListener(v -> {
|
cropAspectLock.setOnClickListener(v -> {
|
||||||
eventListener.onCropAspectLock(!eventListener.isCropAspectLocked());
|
eventListener.onCropAspectLock(!eventListener.isCropAspectLocked());
|
||||||
|
@ -121,7 +127,7 @@ public final class ImageEditorHud extends LinearLayout {
|
||||||
|
|
||||||
setVisibleViewsWhenInMode(Mode.HIGHLIGHT, confirmButton, undoButton, colorPicker, colorPalette);
|
setVisibleViewsWhenInMode(Mode.HIGHLIGHT, confirmButton, undoButton, colorPicker, colorPalette);
|
||||||
|
|
||||||
setVisibleViewsWhenInMode(Mode.BLUR, confirmButton, undoButton, blurToggleContainer);
|
setVisibleViewsWhenInMode(Mode.BLUR, confirmButton, undoButton, blurToggleHud);
|
||||||
|
|
||||||
setVisibleViewsWhenInMode(Mode.TEXT, confirmButton, deleteButton, colorPicker, colorPalette);
|
setVisibleViewsWhenInMode(Mode.TEXT, confirmButton, deleteButton, colorPicker, colorPalette);
|
||||||
|
|
||||||
|
@ -208,18 +214,22 @@ public final class ImageEditorHud extends LinearLayout {
|
||||||
|
|
||||||
public void showBlurHudTooltip() {
|
public void showBlurHudTooltip() {
|
||||||
TooltipPopup.forTarget(blurButton)
|
TooltipPopup.forTarget(blurButton)
|
||||||
.setText(R.string.ImageEditorHud_new_auto_blur_faces_and_blur_brush)
|
.setText(R.string.ImageEditorHud_new_blur_faces_or_draw_anywhere_to_blur)
|
||||||
.setBackgroundTint(ContextCompat.getColor(getContext(), R.color.core_ultramarine))
|
.setBackgroundTint(ContextCompat.getColor(getContext(), R.color.core_ultramarine))
|
||||||
.setTextColor(ContextCompat.getColor(getContext(), R.color.core_white))
|
.setTextColor(ContextCompat.getColor(getContext(), R.color.core_white))
|
||||||
.show(TooltipPopup.POSITION_BELOW);
|
.show(TooltipPopup.POSITION_BELOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showAutoBlurFacesTooltip() {
|
public void showBlurToast() {
|
||||||
TooltipPopup.forTarget(blurToggleContainer)
|
blurToast.clearAnimation();
|
||||||
.setText(R.string.ImageEditorHud_draw_to_blur_or_try_auto_blur)
|
blurToast.setVisibility(View.VISIBLE);
|
||||||
.setBackgroundTint(ContextCompat.getColor(getContext(), R.color.core_ultramarine))
|
toastDebouncer.publish(() -> blurToast.setVisibility(GONE));
|
||||||
.setTextColor(ContextCompat.getColor(getContext(), R.color.core_white))
|
}
|
||||||
.show(TooltipPopup.POSITION_ABOVE);
|
|
||||||
|
public void hideBlurToast() {
|
||||||
|
blurToast.clearAnimation();
|
||||||
|
blurToast.setVisibility(View.GONE);
|
||||||
|
toastDebouncer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEventListener(@Nullable EventListener eventListener) {
|
public void setEventListener(@Nullable EventListener eventListener) {
|
||||||
|
@ -239,6 +249,7 @@ public final class ImageEditorHud extends LinearLayout {
|
||||||
updateButtonVisibility(mode);
|
updateButtonVisibility(mode);
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
case NONE: presentModeNone(); break;
|
||||||
case CROP: presentModeCrop(); break;
|
case CROP: presentModeCrop(); break;
|
||||||
case DRAW: presentModeDraw(); break;
|
case DRAW: presentModeDraw(); break;
|
||||||
case HIGHLIGHT: presentModeHighlight(); break;
|
case HIGHLIGHT: presentModeHighlight(); break;
|
||||||
|
@ -264,6 +275,10 @@ public final class ImageEditorHud extends LinearLayout {
|
||||||
(button != undoButton || undoAvailable);
|
(button != undoButton || undoAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void presentModeNone() {
|
||||||
|
blurToast.setVisibility(GONE);
|
||||||
|
}
|
||||||
|
|
||||||
private void presentModeCrop() {
|
private void presentModeCrop() {
|
||||||
updateCropAspectLockImage(eventListener.isCropAspectLocked());
|
updateCropAspectLockImage(eventListener.isCropAspectLocked());
|
||||||
}
|
}
|
||||||
|
|
5
app/src/main/res/drawable/scribble_toast_background.xml
Normal file
5
app/src/main/res/drawable/scribble_toast_background.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
|
||||||
|
<corners android:radius="5dp" />
|
||||||
|
<solid android:color="@color/core_grey_90"/>
|
||||||
|
</shape>
|
|
@ -173,18 +173,32 @@
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/scribble_blur_toast"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
android:text="@string/ImageEditorHud_draw_to_blur_additional_faces_or_areas"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/scribble_blur_toggle_container"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:background="@drawable/scribble_toast_background"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/scribble_blur_toggle_container"
|
android:id="@+id/scribble_blur_toggle_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="42dp"
|
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingBottom="8dp"
|
android:paddingBottom="8dp"
|
||||||
android:paddingStart="12dp"
|
android:paddingStart="12dp"
|
||||||
android:paddingEnd="12dp"
|
android:paddingEnd="12dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:background="@drawable/transparent_black_pill"
|
android:background="@drawable/transparent_black_pill"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toTopOf="@id/scribble_blur_help_text"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent">
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
@ -192,7 +206,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="6dp"
|
android:layout_marginEnd="6dp"
|
||||||
android:text="@string/ImageEditorHud_auto_blur_faces"
|
android:text="@string/ImageEditorHud_blur_faces"
|
||||||
android:textColor="@color/core_white"/>
|
android:textColor="@color/core_white"/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
|
@ -203,6 +217,24 @@
|
||||||
android:saveEnabled="false"/>
|
android:saveEnabled="false"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/scribble_blur_help_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/ImageEditorHud_draw_anywhere_to_blur"
|
||||||
|
android:padding="14dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/core_white"
|
||||||
|
android:shadowColor="@color/black"
|
||||||
|
android:shadowRadius="15"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Group
|
||||||
|
android:id="@+id/scribble_blur_toggle_hud"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:constraint_referenced_ids="scribble_blur_toggle_container, scribble_blur_help_text" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</merge>
|
</merge>
|
|
@ -562,9 +562,10 @@
|
||||||
<string name="ImageEditorFragment_no_faces_detected">No faces detected</string>
|
<string name="ImageEditorFragment_no_faces_detected">No faces detected</string>
|
||||||
|
|
||||||
<!-- ImageEditorHud -->
|
<!-- ImageEditorHud -->
|
||||||
<string name="ImageEditorHud_auto_blur_faces">Auto-blur faces</string>
|
<string name="ImageEditorHud_blur_faces">Blur faces</string>
|
||||||
<string name="ImageEditorHud_new_auto_blur_faces_and_blur_brush">New: Auto-blur faces and blur brush</string>
|
<string name="ImageEditorHud_new_blur_faces_or_draw_anywhere_to_blur">New: Blur faces or draw anywhere to blur</string>
|
||||||
<string name="ImageEditorHud_draw_to_blur_or_try_auto_blur">Draw to blur, or try auto-blur</string>
|
<string name="ImageEditorHud_draw_anywhere_to_blur">Draw anywhere to blur</string>
|
||||||
|
<string name="ImageEditorHud_draw_to_blur_additional_faces_or_areas">Draw to blur additional faces or areas</string>
|
||||||
|
|
||||||
<!-- InputPanel -->
|
<!-- InputPanel -->
|
||||||
<string name="InputPanel_tap_and_hold_to_record_a_voice_message_release_to_send">Tap and hold to record a voice message, release to send</string>
|
<string name="InputPanel_tap_and_hold_to_record_a_voice_message_release_to_send">Tap and hold to record a voice message, release to send</string>
|
||||||
|
|
Loading…
Add table
Reference in a new issue