2019-05-30 15:19:02 +02:00
|
|
|
package app.fedilab.android.activities;
|
|
|
|
/* Copyright 2017 Thomas Schneider
|
|
|
|
*
|
|
|
|
* This file is a part of Fedilab
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
|
|
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
|
|
* Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
|
|
|
* see <http://www.gnu.org/licenses>. */
|
|
|
|
|
2019-11-15 16:32:25 +01:00
|
|
|
import android.Manifest;
|
2019-05-30 15:19:02 +02:00
|
|
|
import android.annotation.SuppressLint;
|
2019-11-15 16:32:25 +01:00
|
|
|
import android.content.Intent;
|
2019-05-30 15:19:02 +02:00
|
|
|
import android.content.SharedPreferences;
|
2020-06-19 17:27:59 +02:00
|
|
|
import android.content.pm.PackageManager;
|
2019-11-15 16:32:25 +01:00
|
|
|
import android.graphics.Bitmap;
|
|
|
|
import android.graphics.Typeface;
|
2019-05-30 15:19:02 +02:00
|
|
|
import android.net.Uri;
|
|
|
|
import android.os.Bundle;
|
2019-11-15 16:32:25 +01:00
|
|
|
import android.provider.MediaStore;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.animation.AnticipateOvershootInterpolator;
|
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.TextView;
|
2019-09-06 17:55:14 +02:00
|
|
|
|
2019-06-11 19:38:26 +02:00
|
|
|
import androidx.annotation.NonNull;
|
2019-11-15 16:32:25 +01:00
|
|
|
import androidx.appcompat.app.AlertDialog;
|
|
|
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
|
|
|
import androidx.constraintlayout.widget.ConstraintSet;
|
2020-06-19 17:27:59 +02:00
|
|
|
import androidx.core.app.ActivityCompat;
|
|
|
|
import androidx.core.content.ContextCompat;
|
2019-08-04 11:22:49 +02:00
|
|
|
import androidx.exifinterface.media.ExifInterface;
|
2019-06-11 19:38:26 +02:00
|
|
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
2019-11-15 16:32:25 +01:00
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
import androidx.transition.ChangeBounds;
|
|
|
|
import androidx.transition.TransitionManager;
|
2019-08-04 11:22:49 +02:00
|
|
|
|
2019-11-15 16:32:25 +01:00
|
|
|
import com.theartofdev.edmodo.cropper.CropImage;
|
2019-05-30 15:19:02 +02:00
|
|
|
|
2019-11-15 16:32:25 +01:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
2019-05-30 15:19:02 +02:00
|
|
|
|
|
|
|
import app.fedilab.android.R;
|
|
|
|
import app.fedilab.android.helper.Helper;
|
|
|
|
import app.fedilab.android.imageeditor.EmojiBSFragment;
|
|
|
|
import app.fedilab.android.imageeditor.PropertiesBSFragment;
|
|
|
|
import app.fedilab.android.imageeditor.StickerBSFragment;
|
|
|
|
import app.fedilab.android.imageeditor.TextEditorDialogFragment;
|
|
|
|
import app.fedilab.android.imageeditor.filters.FilterListener;
|
|
|
|
import app.fedilab.android.imageeditor.filters.FilterViewAdapter;
|
|
|
|
import app.fedilab.android.imageeditor.tools.EditingToolsAdapter;
|
|
|
|
import app.fedilab.android.imageeditor.tools.ToolType;
|
2020-04-25 11:18:42 +02:00
|
|
|
import es.dmoral.toasty.Toasty;
|
2019-11-15 16:32:25 +01:00
|
|
|
import ja.burhanrashid52.photoeditor.OnPhotoEditorListener;
|
2019-05-30 15:19:02 +02:00
|
|
|
import ja.burhanrashid52.photoeditor.PhotoEditor;
|
|
|
|
import ja.burhanrashid52.photoeditor.PhotoEditorView;
|
|
|
|
import ja.burhanrashid52.photoeditor.PhotoFilter;
|
|
|
|
import ja.burhanrashid52.photoeditor.SaveSettings;
|
|
|
|
import ja.burhanrashid52.photoeditor.ViewType;
|
|
|
|
|
|
|
|
|
2019-09-06 17:55:14 +02:00
|
|
|
public class PhotoEditorActivity extends BaseActivity implements OnPhotoEditorListener,
|
2019-05-30 15:19:02 +02:00
|
|
|
View.OnClickListener,
|
|
|
|
PropertiesBSFragment.Properties,
|
|
|
|
EmojiBSFragment.EmojiListener,
|
|
|
|
StickerBSFragment.StickerListener, EditingToolsAdapter.OnItemSelected, FilterListener {
|
|
|
|
|
|
|
|
|
|
|
|
private static final int CAMERA_REQUEST = 52;
|
|
|
|
private static final int PICK_REQUEST = 53;
|
2020-06-19 17:27:59 +02:00
|
|
|
private final int STORE_REQUEST = 54;
|
2019-05-30 15:19:02 +02:00
|
|
|
private PhotoEditor mPhotoEditor;
|
|
|
|
private PhotoEditorView mPhotoEditorView;
|
|
|
|
private PropertiesBSFragment mPropertiesBSFragment;
|
|
|
|
private EmojiBSFragment mEmojiBSFragment;
|
|
|
|
private StickerBSFragment mStickerBSFragment;
|
|
|
|
private TextView mTxtCurrentTool;
|
|
|
|
private RecyclerView mRvTools, mRvFilters;
|
|
|
|
private EditingToolsAdapter mEditingToolsAdapter = new EditingToolsAdapter(this);
|
|
|
|
private FilterViewAdapter mFilterViewAdapter = new FilterViewAdapter(this);
|
|
|
|
private ConstraintLayout mRootView;
|
|
|
|
private ConstraintSet mConstraintSet = new ConstraintSet();
|
|
|
|
private boolean mIsFilterVisible;
|
2019-05-30 16:37:49 +02:00
|
|
|
private Uri uri;
|
|
|
|
private boolean exit;
|
2019-05-30 15:19:02 +02:00
|
|
|
|
2019-11-15 16:32:25 +01:00
|
|
|
private static int exifToDegrees(int exifOrientation) {
|
|
|
|
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
|
|
|
|
return 90;
|
|
|
|
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
|
|
|
|
return 180;
|
|
|
|
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
|
|
|
|
return 270;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-05-30 15:19:02 +02:00
|
|
|
@SuppressLint("MissingPermission")
|
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
|
|
|
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
2019-09-06 17:55:14 +02:00
|
|
|
switch (theme) {
|
2019-05-30 15:19:02 +02:00
|
|
|
case Helper.THEME_LIGHT:
|
2019-11-09 15:47:38 +01:00
|
|
|
setTheme(R.style.AppTheme_Fedilab);
|
2019-05-30 15:19:02 +02:00
|
|
|
break;
|
|
|
|
case Helper.THEME_BLACK:
|
|
|
|
setTheme(R.style.AppThemeBlack);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
setTheme(R.style.AppThemeDark);
|
|
|
|
}
|
|
|
|
|
|
|
|
Bundle b = getIntent().getExtras();
|
2019-09-06 17:55:14 +02:00
|
|
|
if (getSupportActionBar() != null)
|
2019-05-30 15:19:02 +02:00
|
|
|
getSupportActionBar().hide();
|
|
|
|
String path = null;
|
2019-09-06 17:55:14 +02:00
|
|
|
if (b != null)
|
2019-05-30 15:19:02 +02:00
|
|
|
path = b.getString("imageUri", null);
|
2019-09-06 17:55:14 +02:00
|
|
|
if (path == null) {
|
2019-05-30 15:19:02 +02:00
|
|
|
finish();
|
|
|
|
}
|
2019-05-30 16:37:49 +02:00
|
|
|
uri = Uri.parse(path);
|
2019-05-30 15:19:02 +02:00
|
|
|
|
|
|
|
|
2019-05-30 16:37:49 +02:00
|
|
|
exit = false;
|
2019-05-30 15:19:02 +02:00
|
|
|
|
|
|
|
setContentView(R.layout.activity_photoeditor);
|
|
|
|
|
|
|
|
initViews();
|
|
|
|
|
|
|
|
|
|
|
|
mPropertiesBSFragment = new PropertiesBSFragment();
|
|
|
|
mEmojiBSFragment = new EmojiBSFragment();
|
|
|
|
mStickerBSFragment = new StickerBSFragment();
|
|
|
|
mStickerBSFragment.setStickerListener(this);
|
|
|
|
mEmojiBSFragment.setEmojiListener(this);
|
|
|
|
mPropertiesBSFragment.setPropertiesChangeListener(this);
|
|
|
|
|
|
|
|
LinearLayoutManager llmTools = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
|
|
|
|
mRvTools.setLayoutManager(llmTools);
|
|
|
|
mRvTools.setAdapter(mEditingToolsAdapter);
|
|
|
|
|
|
|
|
LinearLayoutManager llmFilters = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
|
|
|
|
mRvFilters.setLayoutManager(llmFilters);
|
|
|
|
mRvFilters.setAdapter(mFilterViewAdapter);
|
|
|
|
|
|
|
|
|
|
|
|
Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf");
|
|
|
|
|
|
|
|
mPhotoEditor = new PhotoEditor.Builder(this, mPhotoEditorView)
|
|
|
|
.setPinchTextScalable(true) // set flag to make text scalable when pinch
|
|
|
|
.setDefaultEmojiTypeface(mEmojiTypeFace)
|
|
|
|
.build(); // build photo editor sdk
|
2019-05-30 19:09:36 +02:00
|
|
|
|
|
|
|
|
2019-05-30 15:19:02 +02:00
|
|
|
mPhotoEditor.setOnPhotoEditorListener(this);
|
|
|
|
|
|
|
|
//Set Image Dynamically
|
2020-04-25 11:18:42 +02:00
|
|
|
try {
|
|
|
|
mPhotoEditorView.getSource().setImageURI(uri);
|
2020-04-25 19:20:42 +02:00
|
|
|
} catch (Exception e) {
|
2020-04-25 11:18:42 +02:00
|
|
|
Toasty.error(PhotoEditorActivity.this, getString(R.string.error)).show();
|
|
|
|
}
|
2019-05-30 16:37:49 +02:00
|
|
|
|
2019-09-06 17:55:14 +02:00
|
|
|
if (uri != null) {
|
2019-08-04 11:22:49 +02:00
|
|
|
try (InputStream inputStream = getContentResolver().openInputStream(uri)) {
|
|
|
|
assert inputStream != null;
|
|
|
|
ExifInterface exif = new ExifInterface(inputStream);
|
|
|
|
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
|
|
|
|
int rotationInDegrees = exifToDegrees(rotation);
|
|
|
|
mPhotoEditorView.getSource().setRotation(rotationInDegrees);
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-30 16:37:49 +02:00
|
|
|
Button send = findViewById(R.id.send);
|
|
|
|
|
2019-11-19 19:10:52 +01:00
|
|
|
send.setOnClickListener(v -> {
|
|
|
|
exit = true;
|
|
|
|
saveImage();
|
2019-05-30 16:37:49 +02:00
|
|
|
});
|
2019-05-30 15:19:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void initViews() {
|
|
|
|
ImageView imgUndo;
|
|
|
|
ImageView imgRedo;
|
|
|
|
ImageView imgCamera;
|
|
|
|
ImageView imgGallery;
|
|
|
|
ImageView imgSave;
|
|
|
|
ImageView imgClose;
|
|
|
|
|
|
|
|
mPhotoEditorView = findViewById(R.id.photoEditorView);
|
|
|
|
mTxtCurrentTool = findViewById(R.id.txtCurrentTool);
|
|
|
|
mRvTools = findViewById(R.id.rvConstraintTools);
|
|
|
|
mRvFilters = findViewById(R.id.rvFilterView);
|
|
|
|
mRootView = findViewById(R.id.rootView);
|
|
|
|
|
|
|
|
imgUndo = findViewById(R.id.imgUndo);
|
|
|
|
imgUndo.setOnClickListener(this);
|
|
|
|
|
|
|
|
imgRedo = findViewById(R.id.imgRedo);
|
|
|
|
imgRedo.setOnClickListener(this);
|
|
|
|
|
|
|
|
imgCamera = findViewById(R.id.imgCamera);
|
|
|
|
imgCamera.setOnClickListener(this);
|
|
|
|
|
|
|
|
imgGallery = findViewById(R.id.imgGallery);
|
|
|
|
imgGallery.setOnClickListener(this);
|
|
|
|
|
|
|
|
imgSave = findViewById(R.id.imgSave);
|
|
|
|
imgSave.setOnClickListener(this);
|
|
|
|
|
|
|
|
imgClose = findViewById(R.id.imgClose);
|
|
|
|
imgClose.setOnClickListener(this);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onEditTextChangeListener(final View rootView, String text, int colorCode) {
|
|
|
|
TextEditorDialogFragment textEditorDialogFragment =
|
|
|
|
TextEditorDialogFragment.show(this, text, colorCode);
|
2020-04-08 13:01:28 +02:00
|
|
|
textEditorDialogFragment.setOnTextEditorListener((inputText, colorCode1) -> {
|
|
|
|
mPhotoEditor.editText(rootView, inputText, colorCode1);
|
|
|
|
mTxtCurrentTool.setText(R.string.label_text);
|
2019-05-30 15:19:02 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onAddViewListener(ViewType viewType, int numberOfAddedViews) {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onRemoveViewListener(ViewType viewType, int numberOfAddedViews) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStartViewChangeListener(ViewType viewType) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStopViewChangeListener(ViewType viewType) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
switch (view.getId()) {
|
|
|
|
|
|
|
|
case R.id.imgUndo:
|
|
|
|
mPhotoEditor.undo();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case R.id.imgRedo:
|
|
|
|
mPhotoEditor.redo();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case R.id.imgSave:
|
|
|
|
saveImage();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case R.id.imgClose:
|
|
|
|
onBackPressed();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case R.id.imgCamera:
|
|
|
|
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
|
|
|
|
startActivityForResult(cameraIntent, CAMERA_REQUEST);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case R.id.imgGallery:
|
|
|
|
Intent intent = new Intent();
|
|
|
|
intent.setType("image/*");
|
|
|
|
intent.setAction(Intent.ACTION_GET_CONTENT);
|
2019-05-30 15:55:09 +02:00
|
|
|
startActivityForResult(Intent.createChooser(intent, getString(R.string.toot_select_image)), PICK_REQUEST);
|
2019-05-30 15:19:02 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-19 19:10:52 +01:00
|
|
|
|
2019-05-30 15:19:02 +02:00
|
|
|
private void saveImage() {
|
|
|
|
if (requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
2019-05-30 15:55:09 +02:00
|
|
|
showLoading(getString(R.string.saving));
|
2019-05-30 16:37:49 +02:00
|
|
|
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
2019-06-23 18:18:20 +02:00
|
|
|
String myDir = sharedpreferences.getString(Helper.SET_FOLDER_RECORD, getCacheDir().getAbsolutePath());
|
2019-09-06 17:55:14 +02:00
|
|
|
String filename = System.currentTimeMillis() + "_" + Helper.getFileName(PhotoEditorActivity.this, uri);
|
2019-05-30 16:37:49 +02:00
|
|
|
|
2019-09-06 17:55:14 +02:00
|
|
|
File file = new File(myDir + "/" + filename);
|
2019-05-30 15:19:02 +02:00
|
|
|
try {
|
2020-04-08 13:01:28 +02:00
|
|
|
//noinspection ResultOfMethodCallIgnored
|
2019-05-30 15:19:02 +02:00
|
|
|
file.createNewFile();
|
|
|
|
|
|
|
|
SaveSettings saveSettings = new SaveSettings.Builder()
|
|
|
|
.setClearViewsEnabled(true)
|
|
|
|
.setTransparencyEnabled(true)
|
|
|
|
.build();
|
2020-06-19 17:27:59 +02:00
|
|
|
if (ContextCompat.checkSelfPermission(PhotoEditorActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
|
|
|
|
PackageManager.PERMISSION_GRANTED) {
|
|
|
|
ActivityCompat.requestPermissions(PhotoEditorActivity.this,
|
|
|
|
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
|
|
|
STORE_REQUEST);
|
|
|
|
return;
|
|
|
|
}
|
2019-05-30 15:19:02 +02:00
|
|
|
mPhotoEditor.saveAsFile(file.getAbsolutePath(), saveSettings, new PhotoEditor.OnSaveListener() {
|
|
|
|
@Override
|
|
|
|
public void onSuccess(@NonNull String imagePath) {
|
|
|
|
hideLoading();
|
2019-05-30 15:55:09 +02:00
|
|
|
showSnackbar(getString(R.string.image_saved));
|
2019-05-30 15:19:02 +02:00
|
|
|
mPhotoEditorView.getSource().setImageURI(Uri.fromFile(new File(imagePath)));
|
2019-09-06 17:55:14 +02:00
|
|
|
if (exit) {
|
2019-05-30 16:37:49 +02:00
|
|
|
Intent intentImage = new Intent(Helper.INTENT_SEND_MODIFIED_IMAGE);
|
|
|
|
intentImage.putExtra("imgpath", imagePath);
|
2020-04-08 12:42:15 +02:00
|
|
|
LocalBroadcastManager.getInstance(PhotoEditorActivity.this).sendBroadcast(intentImage);
|
2019-05-30 16:37:49 +02:00
|
|
|
finish();
|
|
|
|
}
|
2019-05-30 15:19:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFailure(@NonNull Exception exception) {
|
|
|
|
hideLoading();
|
2019-05-30 15:55:09 +02:00
|
|
|
showSnackbar(getString(R.string.save_image_failed));
|
2019-05-30 15:19:02 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
hideLoading();
|
2019-11-19 19:10:52 +01:00
|
|
|
if (e.getMessage() != null) {
|
|
|
|
showSnackbar(e.getMessage());
|
|
|
|
}
|
2019-05-30 15:19:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-19 17:27:59 +02:00
|
|
|
@Override
|
|
|
|
public void onRequestPermissionsResult(int requestCode,
|
|
|
|
@NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
|
|
if (requestCode == STORE_REQUEST) {// If request is cancelled, the result arrays are empty.
|
|
|
|
if (grantResults.length > 0
|
|
|
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
|
|
// We have the permission.
|
|
|
|
saveImage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-30 15:19:02 +02:00
|
|
|
@Override
|
|
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
2019-10-28 18:09:40 +01:00
|
|
|
super.onActivityResult(requestCode, resultCode, data);
|
2019-05-30 15:19:02 +02:00
|
|
|
if (resultCode == RESULT_OK) {
|
2019-11-19 19:10:52 +01:00
|
|
|
ExifInterface exif;
|
|
|
|
int rotation;
|
2019-08-04 11:22:49 +02:00
|
|
|
int rotationInDegrees = 0;
|
2019-09-06 17:55:14 +02:00
|
|
|
if (data != null && data.getData() != null) {
|
2019-08-04 11:22:49 +02:00
|
|
|
try (InputStream inputStream = getContentResolver().openInputStream(data.getData())) {
|
|
|
|
assert inputStream != null;
|
|
|
|
exif = new androidx.exifinterface.media.ExifInterface(inputStream);
|
|
|
|
rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
|
|
|
|
rotationInDegrees = exifToDegrees(rotation);
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
2019-11-19 19:10:52 +01:00
|
|
|
|
2019-05-30 15:19:02 +02:00
|
|
|
switch (requestCode) {
|
|
|
|
case CAMERA_REQUEST:
|
2020-03-08 10:29:06 +01:00
|
|
|
if (data != null && data.getExtras() != null) {
|
2019-05-30 15:19:02 +02:00
|
|
|
mPhotoEditor.clearAllViews();
|
2019-11-19 19:10:52 +01:00
|
|
|
Bitmap photo = (Bitmap) data.getExtras().get("data");
|
|
|
|
mPhotoEditorView.getSource().setImageBitmap(photo);
|
2019-08-04 11:22:49 +02:00
|
|
|
mPhotoEditorView.getSource().setRotation(rotationInDegrees);
|
2019-11-19 19:10:52 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PICK_REQUEST:
|
2020-03-08 10:29:06 +01:00
|
|
|
if (data != null && data.getData() != null) {
|
2019-11-19 19:10:52 +01:00
|
|
|
try {
|
|
|
|
mPhotoEditor.clearAllViews();
|
|
|
|
Uri uri = data.getData();
|
|
|
|
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
|
|
|
|
mPhotoEditorView.getSource().setImageBitmap(bitmap);
|
|
|
|
mPhotoEditorView.getSource().setRotation(rotationInDegrees);
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2019-05-30 15:19:02 +02:00
|
|
|
}
|
|
|
|
break;
|
2019-08-24 16:39:53 +02:00
|
|
|
case CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE:
|
2019-11-19 19:10:52 +01:00
|
|
|
|
2019-08-24 16:39:53 +02:00
|
|
|
CropImage.ActivityResult result = CropImage.getActivityResult(data);
|
2019-11-19 19:10:52 +01:00
|
|
|
if (result != null) {
|
|
|
|
Uri resultUri = result.getUri();
|
|
|
|
if (resultUri != null) {
|
|
|
|
mPhotoEditorView.getSource().setImageURI(resultUri);
|
|
|
|
mPhotoEditorView.getSource().setRotation(rotationInDegrees);
|
|
|
|
if (uri != null && uri.getPath() != null) {
|
|
|
|
File fdelete = new File(uri.getPath());
|
|
|
|
if (fdelete.exists()) {
|
|
|
|
//noinspection ResultOfMethodCallIgnored
|
|
|
|
fdelete.delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uri = resultUri;
|
2019-05-30 19:09:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2019-05-30 15:19:02 +02:00
|
|
|
}
|
|
|
|
}
|
2019-11-19 19:10:52 +01:00
|
|
|
|
2019-05-30 15:19:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onColorChanged(int colorCode) {
|
|
|
|
mPhotoEditor.setBrushColor(colorCode);
|
|
|
|
mTxtCurrentTool.setText(R.string.label_brush);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onOpacityChanged(int opacity) {
|
|
|
|
mPhotoEditor.setOpacity(opacity);
|
|
|
|
mTxtCurrentTool.setText(R.string.label_brush);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onBrushSizeChanged(int brushSize) {
|
|
|
|
mPhotoEditor.setBrushSize(brushSize);
|
|
|
|
mTxtCurrentTool.setText(R.string.label_brush);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onEmojiClick(String emojiUnicode) {
|
|
|
|
mPhotoEditor.addEmoji(emojiUnicode);
|
|
|
|
mTxtCurrentTool.setText(R.string.label_emoji);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStickerClick(Bitmap bitmap) {
|
|
|
|
mPhotoEditor.addImage(bitmap);
|
|
|
|
mTxtCurrentTool.setText(R.string.label_sticker);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void isPermissionGranted(boolean isGranted, String permission) {
|
|
|
|
if (isGranted) {
|
|
|
|
saveImage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void showSaveDialog() {
|
2019-06-09 10:48:18 +02:00
|
|
|
int style;
|
|
|
|
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
|
|
|
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
|
|
|
if (theme == Helper.THEME_DARK) {
|
|
|
|
style = R.style.DialogDark;
|
2019-09-06 17:55:14 +02:00
|
|
|
} else if (theme == Helper.THEME_BLACK) {
|
2019-06-09 10:48:18 +02:00
|
|
|
style = R.style.DialogBlack;
|
2019-09-06 17:55:14 +02:00
|
|
|
} else {
|
2019-06-09 10:48:18 +02:00
|
|
|
style = R.style.Dialog;
|
|
|
|
}
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this, style);
|
2019-09-06 17:55:14 +02:00
|
|
|
builder.setMessage(getString(R.string.confirm_exit_editing));
|
2020-04-08 13:01:28 +02:00
|
|
|
builder.setPositiveButton(R.string.save, (dialog, which) -> saveImage());
|
|
|
|
builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
2019-05-30 15:19:02 +02:00
|
|
|
|
2020-04-08 13:01:28 +02:00
|
|
|
builder.setNegativeButton(R.string.discard, (dialog, which) -> finish());
|
2019-05-30 15:19:02 +02:00
|
|
|
builder.create().show();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFilterSelected(PhotoFilter photoFilter) {
|
|
|
|
mPhotoEditor.setFilterEffect(photoFilter);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onToolSelected(ToolType toolType) {
|
|
|
|
switch (toolType) {
|
|
|
|
case BRUSH:
|
|
|
|
mPhotoEditor.setBrushDrawingMode(true);
|
|
|
|
mTxtCurrentTool.setText(R.string.label_brush);
|
|
|
|
mPropertiesBSFragment.show(getSupportFragmentManager(), mPropertiesBSFragment.getTag());
|
|
|
|
break;
|
|
|
|
case TEXT:
|
|
|
|
TextEditorDialogFragment textEditorDialogFragment = TextEditorDialogFragment.show(this);
|
2020-04-08 13:01:28 +02:00
|
|
|
textEditorDialogFragment.setOnTextEditorListener((inputText, colorCode) -> {
|
|
|
|
mPhotoEditor.addText(inputText, colorCode);
|
|
|
|
mTxtCurrentTool.setText(R.string.label_text);
|
2019-05-30 15:19:02 +02:00
|
|
|
});
|
|
|
|
break;
|
|
|
|
case ERASER:
|
|
|
|
mPhotoEditor.brushEraser();
|
|
|
|
mTxtCurrentTool.setText(R.string.label_eraser);
|
|
|
|
break;
|
|
|
|
case FILTER:
|
|
|
|
mTxtCurrentTool.setText(R.string.label_filter);
|
|
|
|
showFilter(true);
|
|
|
|
break;
|
|
|
|
case EMOJI:
|
|
|
|
mEmojiBSFragment.show(getSupportFragmentManager(), mEmojiBSFragment.getTag());
|
|
|
|
break;
|
|
|
|
case STICKER:
|
|
|
|
mStickerBSFragment.show(getSupportFragmentManager(), mStickerBSFragment.getTag());
|
|
|
|
break;
|
2019-05-30 19:09:36 +02:00
|
|
|
case CROP:
|
2019-08-24 16:39:53 +02:00
|
|
|
CropImage.activity(uri)
|
|
|
|
.start(this);
|
2019-05-30 19:09:36 +02:00
|
|
|
break;
|
2019-05-30 15:19:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void showFilter(boolean isVisible) {
|
|
|
|
mIsFilterVisible = isVisible;
|
|
|
|
mConstraintSet.clone(mRootView);
|
|
|
|
|
|
|
|
if (isVisible) {
|
|
|
|
mConstraintSet.clear(mRvFilters.getId(), ConstraintSet.START);
|
|
|
|
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.START,
|
|
|
|
ConstraintSet.PARENT_ID, ConstraintSet.START);
|
|
|
|
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.END,
|
|
|
|
ConstraintSet.PARENT_ID, ConstraintSet.END);
|
|
|
|
} else {
|
|
|
|
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.START,
|
|
|
|
ConstraintSet.PARENT_ID, ConstraintSet.END);
|
|
|
|
mConstraintSet.clear(mRvFilters.getId(), ConstraintSet.END);
|
|
|
|
}
|
|
|
|
|
|
|
|
ChangeBounds changeBounds = new ChangeBounds();
|
|
|
|
changeBounds.setDuration(350);
|
|
|
|
changeBounds.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
|
|
|
|
TransitionManager.beginDelayedTransition(mRootView, changeBounds);
|
|
|
|
|
|
|
|
mConstraintSet.applyTo(mRootView);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onBackPressed() {
|
|
|
|
if (mIsFilterVisible) {
|
|
|
|
showFilter(false);
|
|
|
|
mTxtCurrentTool.setText(R.string.app_name);
|
|
|
|
} else if (!mPhotoEditor.isCacheEmpty()) {
|
|
|
|
showSaveDialog();
|
|
|
|
} else {
|
|
|
|
super.onBackPressed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|