Add tools for editing photo

This commit is contained in:
tom79 2019-05-30 15:19:02 +02:00
parent 3d4b3fe706
commit afafb3ccb4
66 changed files with 2129 additions and 73 deletions

View File

@ -102,4 +102,5 @@ dependencies {
implementation 'com.github.stom79:horizontalbargraph:1.5'
implementation 'jp.wasabeef:glide-transformations:4.0.0'
playstoreImplementation "io.github.kobakei:ratethisapp:$ratethisappLibraryVersion"
implementation 'ja.burhanrashid52:photoeditor:0.3.3'
}

View File

@ -161,6 +161,10 @@
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"
/>
<activity android:name="app.fedilab.android.activities.PhotoEditorActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"
/>
<activity android:name="app.fedilab.android.activities.WebviewActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

@ -1,15 +1,26 @@
package app.fedilab.android.activities;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import com.franmontiel.localechanger.LocaleChanger;
import com.vanniktech.emoji.EmojiManager;
import com.vanniktech.emoji.one.EmojiOneProvider;
import app.fedilab.android.helper.Helper;
import es.dmoral.toasty.Toasty;
/**
* Created by Thomas on 12/12/2017.
@ -18,6 +29,11 @@ import app.fedilab.android.helper.Helper;
@SuppressLint("Registered")
public class BaseActivity extends AppCompatActivity {
public static final int READ_WRITE_STORAGE = 52;
private ProgressDialog mProgressDialog;
static {
Helper.installProvider();
EmojiManager.install(new EmojiOneProvider());
@ -34,4 +50,56 @@ public class BaseActivity extends AppCompatActivity {
newBase = LocaleChanger.configureBaseContext(newBase);
super.attachBaseContext(newBase);
}
public boolean requestPermission(String permission) {
boolean isGranted = ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED;
if (!isGranted) {
ActivityCompat.requestPermissions(
this,
new String[]{permission},
READ_WRITE_STORAGE);
}
return isGranted;
}
public void isPermissionGranted(boolean isGranted, String permission) {
}
public void makeFullScreen() {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case READ_WRITE_STORAGE:
isPermissionGranted(grantResults[0] == PackageManager.PERMISSION_GRANTED, permissions[0]);
break;
}
}
protected void showLoading(@NonNull String message) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage(message);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
protected void hideLoading() {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
}
protected void showSnackbar(@NonNull String message) {
View view = findViewById(android.R.id.content);
if (view != null) {
Snackbar.make(view, message, Snackbar.LENGTH_SHORT).show();
} else {
Toasty.info(this, message, Toast.LENGTH_SHORT).show();
}
}
}

View File

@ -0,0 +1,474 @@
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>. */
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.content.res.ResourcesCompat;
import android.view.Window;
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;
import ja.burhanrashid52.photoeditor.PhotoEditor;
import ja.burhanrashid52.photoeditor.PhotoEditorView;
import ja.burhanrashid52.photoeditor.PhotoFilter;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.provider.MediaStore;
import android.support.constraint.ConstraintLayout;
import android.support.constraint.ConstraintSet;
import android.support.transition.ChangeBounds;
import android.support.transition.TransitionManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.animation.AnticipateOvershootInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.File;
import java.io.IOException;
import ja.burhanrashid52.photoeditor.OnPhotoEditorListener;
import ja.burhanrashid52.photoeditor.SaveSettings;
import ja.burhanrashid52.photoeditor.ViewType;
public class PhotoEditorActivity extends BaseActivity implements OnPhotoEditorListener,
View.OnClickListener,
PropertiesBSFragment.Properties,
EmojiBSFragment.EmojiListener,
StickerBSFragment.StickerListener, EditingToolsAdapter.OnItemSelected, FilterListener {
public static final String EXTRA_IMAGE_PATHS = "extra_image_paths";
private static final int CAMERA_REQUEST = 52;
private static final int PICK_REQUEST = 53;
private PhotoEditor mPhotoEditor;
private PhotoEditorView mPhotoEditorView;
private PropertiesBSFragment mPropertiesBSFragment;
private EmojiBSFragment mEmojiBSFragment;
private StickerBSFragment mStickerBSFragment;
private TextView mTxtCurrentTool;
private Typeface mWonderFont;
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;
@SuppressLint("MissingPermission")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
switch (theme){
case Helper.THEME_LIGHT:
setTheme(R.style.AppTheme);
break;
case Helper.THEME_DARK:
setTheme(R.style.AppThemeDark);
break;
case Helper.THEME_BLACK:
setTheme(R.style.AppThemeBlack);
break;
default:
setTheme(R.style.AppThemeDark);
}
Bundle b = getIntent().getExtras();
if( getSupportActionBar() != null)
getSupportActionBar().hide();
String path = null;
if(b != null)
path = b.getString("imageUri", null);
if( path == null) {
finish();
}
Uri uri = Uri.parse(path);
// makeFullScreen();
setContentView(R.layout.activity_photoeditor);
initViews();
mWonderFont = Typeface.createFromAsset(getAssets(), "beyond_wonderland.ttf");
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
mPhotoEditor.setOnPhotoEditorListener(this);
//Set Image Dynamically
mPhotoEditorView.getSource().setImageURI(uri);
}
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);
textEditorDialogFragment.setOnTextEditorListener(new TextEditorDialogFragment.TextEditor() {
@Override
public void onDone(String inputText, int colorCode) {
mPhotoEditor.editText(rootView, inputText, colorCode);
mTxtCurrentTool.setText(R.string.label_text);
}
});
}
@Override
public void onAddViewListener(ViewType viewType, int numberOfAddedViews) {
Log.d(Helper.TAG, "onAddViewListener() called with: viewType = [" + viewType + "], numberOfAddedViews = [" + numberOfAddedViews + "]");
}
@Override
public void onRemoveViewListener(int numberOfAddedViews) {
Log.d(Helper.TAG, "onRemoveViewListener() called with: numberOfAddedViews = [" + numberOfAddedViews + "]");
}
@Override
public void onRemoveViewListener(ViewType viewType, int numberOfAddedViews) {
Log.d(Helper.TAG, "onRemoveViewListener() called with: viewType = [" + viewType + "], numberOfAddedViews = [" + numberOfAddedViews + "]");
}
@Override
public void onStartViewChangeListener(ViewType viewType) {
Log.d(Helper.TAG, "onStartViewChangeListener() called with: viewType = [" + viewType + "]");
}
@Override
public void onStopViewChangeListener(ViewType viewType) {
Log.d(Helper.TAG, "onStopViewChangeListener() called with: 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);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_REQUEST);
break;
}
}
@SuppressLint("MissingPermission")
private void saveImage() {
if (requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showLoading("Saving...");
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + ""
+ System.currentTimeMillis() + ".png");
try {
file.createNewFile();
SaveSettings saveSettings = new SaveSettings.Builder()
.setClearViewsEnabled(true)
.setTransparencyEnabled(true)
.build();
mPhotoEditor.saveAsFile(file.getAbsolutePath(), saveSettings, new PhotoEditor.OnSaveListener() {
@Override
public void onSuccess(@NonNull String imagePath) {
hideLoading();
showSnackbar("Image Saved Successfully");
mPhotoEditorView.getSource().setImageURI(Uri.fromFile(new File(imagePath)));
}
@Override
public void onFailure(@NonNull Exception exception) {
hideLoading();
showSnackbar("Failed to save Image");
}
});
} catch (IOException e) {
e.printStackTrace();
hideLoading();
showSnackbar(e.getMessage());
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case CAMERA_REQUEST:
mPhotoEditor.clearAllViews();
Bitmap photo = (Bitmap) data.getExtras().get("data");
mPhotoEditorView.getSource().setImageBitmap(photo);
break;
case PICK_REQUEST:
try {
mPhotoEditor.clearAllViews();
Uri uri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
mPhotoEditorView.getSource().setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
@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() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you want to exit without saving image ?");
builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
saveImage();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.setNeutralButton("Discard", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
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);
textEditorDialogFragment.setOnTextEditorListener(new TextEditorDialogFragment.TextEditor() {
@Override
public void onDone(String inputText, int colorCode) {
mPhotoEditor.addText(inputText, colorCode);
mTxtCurrentTool.setText(R.string.label_text);
}
});
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;
}
}
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();
}
}
}

View File

@ -27,6 +27,7 @@ import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@ -154,6 +155,9 @@ import app.fedilab.android.interfaces.OnRetrieveAttachmentInterface;
import app.fedilab.android.interfaces.OnRetrieveEmojiInterface;
import app.fedilab.android.interfaces.OnRetrieveSearcAccountshInterface;
import app.fedilab.android.interfaces.OnRetrieveSearchInterface;
import ja.burhanrashid52.photoeditor.PhotoEditor;
import ja.burhanrashid52.photoeditor.PhotoEditorView;
import static app.fedilab.android.helper.Helper.changeDrawableColor;
import static app.fedilab.android.helper.Helper.countWithEmoji;
@ -231,7 +235,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(getApplicationContext()));
final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
switch (theme){
switch (theme) {
case Helper.THEME_LIGHT:
setTheme(R.style.AppTheme);
break;
@ -246,21 +250,21 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
if (theme == Helper.THEME_DARK) {
style = R.style.DialogDark;
} else if (theme == Helper.THEME_BLACK){
} else if (theme == Helper.THEME_BLACK) {
style = R.style.DialogBlack;
}else {
} else {
style = R.style.Dialog;
}
filesMap = new HashMap<>();
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA){
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) {
max_media_count = 9999;
}else{
} else {
max_media_count = 4;
}
autocomplete = false;
setContentView(R.layout.activity_toot);
ActionBar actionBar = getSupportActionBar();
if( actionBar != null ) {
if (actionBar != null) {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
assert inflater != null;
@SuppressLint("InflateParams") View view = inflater.inflate(R.layout.toot_action_bar, null);
@ -277,7 +281,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
finish();
}
});
if (theme == Helper.THEME_LIGHT){
if (theme == Helper.THEME_LIGHT) {
Toolbar toolbar = actionBar.getCustomView().findViewById(R.id.toolbar);
Helper.colorizeToolbar(toolbar, R.color.black, TootActivity.this);
}
@ -297,7 +301,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
Button toot_cw = findViewById(R.id.toot_cw);
toot_space_left = findViewById(R.id.toot_space_left);
toot_visibility = findViewById(R.id.toot_visibility);
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA)
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA)
toot_visibility.setVisibility(View.GONE);
toot_picture = findViewById(R.id.toot_picture);
toot_picture_container = findViewById(R.id.toot_picture_container);
@ -311,7 +315,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
ImageButton toot_emoji = findViewById(R.id.toot_emoji);
poll_action = findViewById(R.id.poll_action);
isScheduled = false;
if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, true)) {
if (sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, true)) {
final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(drawer_layout).build(toot_content);
toot_emoji.setOnClickListener(new View.OnClickListener() {
@ -320,7 +324,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
emojiPopup.toggle(); // Toggles visibility of the Popup.
}
});
}else {
} else {
toot_emoji.setVisibility(View.GONE);
}
@ -334,7 +338,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
params.height = (int) Helper.convertDpToPixel(50, getApplicationContext());
params.width = (int) Helper.convertDpToPixel(50, getApplicationContext());
toot_picture_container.setLayoutParams(params);
}else {
} else {
ViewGroup.LayoutParams params = toot_picture_container.getLayoutParams();
params.height = (int) Helper.convertDpToPixel(100, getApplicationContext());
params.width = (int) Helper.convertDpToPixel(100, getApplicationContext());
@ -347,13 +351,13 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
ArrayList<Uri> sharedUri = new ArrayList<>();
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
restored = -1;
if(b != null) {
if (b != null) {
tootReply = b.getParcelable("tootReply");
scheduledstatus = b.getParcelable("storedStatus");
String accountReplyToken = b.getString("accountReplyToken", null);
accountReply = null;
if( accountReplyToken != null){
accountReply = new AccountDAO(getApplicationContext(),db).getAccountByToken(accountReplyToken);
if (accountReplyToken != null) {
accountReply = new AccountDAO(getApplicationContext(), db).getAccountByToken(accountReplyToken);
}
tootMention = b.getString("tootMention", null);
urlMention = b.getString("urlMention", null);
@ -362,7 +366,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
sharedContentIni = b.getString("sharedContent", null);
sharedSubject = b.getString("sharedSubject", null);
mentionAccount = b.getString("mentionAccount", null);
idRedirect = b.getParcelable("idRedirect");
idRedirect = b.getParcelable("idRedirect");
removed = b.getBoolean("removed");
visibility = b.getString("visibility", null);
restoredScheduled = b.getBoolean("restoredScheduled", false);
@ -374,7 +378,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
}
// ACTION_SEND_MULTIPLE route
else if( b.getInt("uriNumberMast", 0) > 1) {
else if (b.getInt("uriNumberMast", 0) > 1) {
ArrayList<Uri> fileUri = b.getParcelableArrayList("sharedUri");
if (fileUri != null) {
@ -383,42 +387,42 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
restored = b.getLong("restored", -1);
}
if( scheduledstatus != null)
if (scheduledstatus != null)
toot_it.setText(R.string.modify);
if(restoredScheduled){
if (restoredScheduled) {
toot_it.setVisibility(View.GONE);
invalidateOptionsMenu();
}
String userIdReply;
if( accountReply == null)
if (accountReply == null)
userIdReply = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
else
userIdReply = accountReply.getId();
if( accountReply == null)
account = new AccountDAO(getApplicationContext(),db).getAccountByID(userIdReply);
if (accountReply == null)
account = new AccountDAO(getApplicationContext(), db).getAccountByID(userIdReply);
else
account = accountReply;
if( MainActivity.social == null){
if (MainActivity.social == null) {
//Update the static variable which manages account type
if( account.getSocial() == null || account.getSocial().equals("MASTODON"))
if (account.getSocial() == null || account.getSocial().equals("MASTODON"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.MASTODON;
else if( account.getSocial().equals("PEERTUBE"))
else if (account.getSocial().equals("PEERTUBE"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE;
else if( account.getSocial().equals("PIXELFED"))
else if (account.getSocial().equals("PIXELFED"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED;
else if( account.getSocial().equals("PLEROMA"))
else if (account.getSocial().equals("PLEROMA"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA;
else if( account.getSocial().equals("GNU"))
else if (account.getSocial().equals("GNU"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.GNU;
else if( account.getSocial().equals("FRIENDICA"))
else if (account.getSocial().equals("FRIENDICA"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA;
}
switch (MainActivity.social){
switch (MainActivity.social) {
case GNU:
toot_it.setText(getText(R.string.queet_it));
break;
@ -432,18 +436,17 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_it.setText(getText(R.string.toot_it));
}
if( tootReply != null) {
if (tootReply != null) {
tootReply();
}else {
if( title != null) {
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU)
} else {
if (title != null) {
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU)
title.setText(getString(R.string.queet_title));
else
title.setText(getString(R.string.toot_title));
}
else {
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU)
} else {
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU)
setTitle(R.string.queet_title);
else
setTitle(R.string.toot_title);
@ -451,12 +454,12 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
toot_content.requestFocus();
if( mentionAccount != null){
if (mentionAccount != null) {
toot_content.setText(String.format("@%s\n", mentionAccount));
toot_content.setSelection(toot_content.getText().length());
toot_space_left.setText(String.valueOf(countLength()));
}
if( tootMention != null && urlMention != null) {
if (tootMention != null && urlMention != null) {
if (fileMention != null) {
Bitmap pictureMention = BitmapFactory.decodeFile(getCacheDir() + "/" + fileMention);
AsyncTask.execute(new Runnable() {
@ -488,20 +491,19 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
initialContent = toot_content.getText().toString();
String url = account.getAvatar();
if( url.startsWith("/") ){
if (url.startsWith("/")) {
url = Helper.getLiveInstanceWithProtocol(getApplicationContext()) + account.getAvatar();
}
Helper.loadGiF(getApplicationContext(), url, pp_actionBar);
if( sharedContent != null ){ //Shared content
if (sharedContent != null) { //Shared content
if( sharedSubject != null){
if (sharedSubject != null) {
sharedContent = sharedSubject + "\n\n" + sharedContent;
}
if( b != null) {
if (b != null) {
final String image = b.getString("image");
String title = b.getString("title");
String description = b.getString("description");
@ -537,8 +539,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
if( tootReply == null) {
if( visibility == null) {
if (tootReply == null) {
if (visibility == null) {
String defaultVisibility = account.isLocked() ? "private" : "public";
visibility = sharedpreferences.getString(Helper.SET_TOOT_VISIBILITY + "@" + account.getAcct() + "@" + account.getInstance(), defaultVisibility);
}
@ -568,10 +570,10 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_cw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(toot_cw_content.getVisibility() == View.GONE) {
if (toot_cw_content.getVisibility() == View.GONE) {
toot_cw_content.setVisibility(View.VISIBLE);
toot_cw_content.requestFocus();
}else {
} else {
toot_cw_content.setVisibility(View.GONE);
toot_cw_content.setText("");
toot_content.requestFocus();
@ -593,7 +595,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
});
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA)
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA)
toot_it.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
@ -602,7 +604,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
.inflate(R.menu.main_content_type, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
switch (item.getItemId()) {
case R.id.action_plain_text:
contentType = "text/plain";
break;
@ -648,14 +650,14 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
String[] mimetypes = {"image/*", "video/*"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivityForResult(intent, PICK_IMAGE);
}else {
} else {
intent.setType("image/* video/*");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent chooserIntent = Intent.createChooser(intent, getString(R.string.toot_select_image));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent});
startActivityForResult(chooserIntent, PICK_IMAGE);
}
@ -672,9 +674,13 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_cw_content.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
toot_space_left.setText(String.valueOf(countLength()));
@ -788,15 +794,14 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_space_left.setText(String.valueOf(totalChar));
}
};
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA)
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA)
toot_content.addTextChangedListener(textWatcher);
if( scheduledstatus != null)
if (scheduledstatus != null)
restoreServerSchedule(scheduledstatus.getStatus());
if( restored != -1 ){
if (restored != -1) {
restoreToot(restored);
}
@ -811,7 +816,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
@Override
public void onDestroy(){
public void onDestroy() {
super.onDestroy();
}
@ -831,7 +836,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
}
}
public void showAToast (String message){
public void showAToast(String message) {
if (mToast != null) {
mToast.cancel();
}
@ -844,7 +850,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
public void uploadSharedImage(ArrayList<Uri> uri) {
if (!uri.isEmpty()) {
int count = 0;
for(Uri fileUri: uri) {
for (Uri fileUri : uri) {
if (fileUri != null) {
if (count == max_media_count) {
break;
@ -855,12 +861,12 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
count++;
} catch (Exception e) {
e.printStackTrace();
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
toot_picture.setEnabled(true);
toot_it.setEnabled(true);
}
} else {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
}
}
}
@ -878,7 +884,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
try {
photoFile = createImageFile();
} catch (IOException ignored) {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();}
Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
}
// Continue only if the File was successfully created
if (photoFile != null) {
photoFileUri = FileProvider.getUriForFile(this,
@ -911,17 +918,17 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE && resultCode == RESULT_OK) {
picture_scrollview.setVisibility(View.VISIBLE);
if (data == null){
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
if (data == null) {
Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
return;
}
ClipData clipData = data.getClipData();
if (data.getData() == null && clipData == null) {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
return;
}
if( clipData != null ){
if (clipData != null) {
ArrayList<Uri> mArrayUri = new ArrayList<>();
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
@ -929,16 +936,71 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
mArrayUri.add(uri);
}
uploadSharedImage(mArrayUri);
}else{
} else {
try {
String filename = Helper.getFileName(TootActivity.this, data.getData());
String filename = Helper.getFileName(TootActivity.this, data.getData());
ContentResolver cr = getContentResolver();
String mime = cr.getType(data.getData());
if(mime != null && (mime.toLowerCase().contains("video") || mime.toLowerCase().contains("gif")) ) {
if (mime != null && (mime.toLowerCase().contains("video") || mime.toLowerCase().contains("gif"))) {
InputStream inputStream = getContentResolver().openInputStream(data.getData());
new HttpsConnection(TootActivity.this, instance).upload(inputStream, filename, account, TootActivity.this);
} else if(mime != null && mime.toLowerCase().contains("image")) {
new asyncPicture(TootActivity.this, account, data.getData()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else if (mime != null && mime.toLowerCase().contains("image")) {
Intent intent = new Intent(TootActivity.this, PhotoEditorActivity.class);
Bundle b = new Bundle();
intent.putExtra("imageUri", data.getData().toString());
intent.putExtras(b);
startActivity(intent);
/* AlertDialog.Builder alertMedia = new AlertDialog.Builder(TootActivity.this, style);
alertMedia.setTitle(R.string.edit_media);
View view = getLayoutInflater().inflate(R.layout.popup_picture, null);
alertMedia.setView(view);
PhotoEditorView mPhotoEditorView = view.findViewById(R.id.photoEditorView);
mPhotoEditorView.getSource().setImageURI(data.getData());
PhotoEditor mPhotoEditor = new PhotoEditor.Builder(this, mPhotoEditorView)
.setPinchTextScalable(true)
.build();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
return;
}
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
String myDir = sharedpreferences.getString(Helper.SET_FOLDER_RECORD, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath());
filename = Helper.getFileName(TootActivity.this, data.getData());
mPhotoEditor.saveAsFile(myDir + "/"+ filename, new PhotoEditor.OnSaveListener() {
@Override
public void onSuccess(@NonNull String imagePath) {
new asyncPicture(TootActivity.this, account, Uri.fromFile(new File(imagePath))).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
public void onFailure(@NonNull Exception exception) {
}
});
alertMedia.setNeutralButton(R.string.delete, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if( poll != null)
poll = null;
poll_action.setVisibility(View.GONE);
toot_picture.setVisibility(View.VISIBLE);
if( attachments != null && attachments.size() > 0)
picture_scrollview.setVisibility(View.VISIBLE);
dialog.dismiss();
}
});
alertMedia.setPositiveButton(R.string.done, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
alertMedia.show();*/
}else {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
}

View File

@ -0,0 +1,123 @@
package app.fedilab.android.imageeditor;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
/**
* Created by Ahmed Adel on 5/8/17.
*/
public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.ViewHolder> {
private Context context;
private LayoutInflater inflater;
private List<Integer> colorPickerColors;
private OnColorPickerClickListener onColorPickerClickListener;
ColorPickerAdapter(@NonNull Context context, @NonNull List<Integer> colorPickerColors) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.colorPickerColors = colorPickerColors;
}
ColorPickerAdapter(@NonNull Context context) {
this(context, getDefaultColors(context));
this.context = context;
this.inflater = LayoutInflater.from(context);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.color_picker_item_list, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.colorPickerView.setBackgroundColor(colorPickerColors.get(position));
}
@Override
public int getItemCount() {
return colorPickerColors.size();
}
private void buildColorPickerView(View view, int colorCode) {
view.setVisibility(View.VISIBLE);
ShapeDrawable biggerCircle = new ShapeDrawable(new OvalShape());
biggerCircle.setIntrinsicHeight(20);
biggerCircle.setIntrinsicWidth(20);
biggerCircle.setBounds(new Rect(0, 0, 20, 20));
biggerCircle.getPaint().setColor(colorCode);
ShapeDrawable smallerCircle = new ShapeDrawable(new OvalShape());
smallerCircle.setIntrinsicHeight(5);
smallerCircle.setIntrinsicWidth(5);
smallerCircle.setBounds(new Rect(0, 0, 5, 5));
smallerCircle.getPaint().setColor(Color.WHITE);
smallerCircle.setPadding(10, 10, 10, 10);
Drawable[] drawables = {smallerCircle, biggerCircle};
LayerDrawable layerDrawable = new LayerDrawable(drawables);
view.setBackgroundDrawable(layerDrawable);
}
public void setOnColorPickerClickListener(OnColorPickerClickListener onColorPickerClickListener) {
this.onColorPickerClickListener = onColorPickerClickListener;
}
class ViewHolder extends RecyclerView.ViewHolder {
View colorPickerView;
public ViewHolder(View itemView) {
super(itemView);
colorPickerView = itemView.findViewById(R.id.color_picker_view);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onColorPickerClickListener != null)
onColorPickerClickListener.onColorPickerClickListener(colorPickerColors.get(getAdapterPosition()));
}
});
}
}
public interface OnColorPickerClickListener {
void onColorPickerClickListener(int colorCode);
}
public static List<Integer> getDefaultColors(Context context) {
ArrayList<Integer> colorPickerColors = new ArrayList<>();
colorPickerColors.add(ContextCompat.getColor(context, R.color.blue_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.brown_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.green_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.orange_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.red_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.black));
colorPickerColors.add(ContextCompat.getColor(context, R.color.red_orange_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.sky_blue_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.violet_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.white));
colorPickerColors.add(ContextCompat.getColor(context, R.color.yellow_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.yellow_green_color_picker));
return colorPickerColors;
}
}

View File

@ -0,0 +1,113 @@
package app.fedilab.android.imageeditor;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialogFragment;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import app.fedilab.android.R;
import ja.burhanrashid52.photoeditor.PhotoEditor;
public class EmojiBSFragment extends BottomSheetDialogFragment {
public EmojiBSFragment() {
// Required empty public constructor
}
private EmojiListener mEmojiListener;
public interface EmojiListener {
void onEmojiClick(String emojiUnicode);
}
private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
};
@SuppressLint("RestrictedApi")
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.fragment_bottom_sticker_emoji_dialog, null);
dialog.setContentView(contentView);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
if (behavior != null && behavior instanceof BottomSheetBehavior) {
((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
}
((View) contentView.getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));
RecyclerView rvEmoji = contentView.findViewById(R.id.rvEmoji);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 5);
rvEmoji.setLayoutManager(gridLayoutManager);
EmojiAdapter emojiAdapter = new EmojiAdapter();
rvEmoji.setAdapter(emojiAdapter);
}
public void setEmojiListener(EmojiListener emojiListener) {
mEmojiListener = emojiListener;
}
public class EmojiAdapter extends RecyclerView.Adapter<EmojiAdapter.ViewHolder> {
ArrayList<String> emojisList = PhotoEditor.getEmojis(getActivity());
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_emoji, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.txtEmoji.setText(emojisList.get(position));
}
@Override
public int getItemCount() {
return emojisList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView txtEmoji;
ViewHolder(View itemView) {
super(itemView);
txtEmoji = itemView.findViewById(R.id.txtEmoji);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mEmojiListener != null) {
mEmojiListener.onEmojiClick(emojisList.get(getLayoutPosition()));
}
dismiss();
}
});
}
}
}
}

View File

@ -0,0 +1,97 @@
package app.fedilab.android.imageeditor;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetDialogFragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import app.fedilab.android.R;
public class PropertiesBSFragment extends BottomSheetDialogFragment implements SeekBar.OnSeekBarChangeListener {
public PropertiesBSFragment() {
// Required empty public constructor
}
private Properties mProperties;
public interface Properties {
void onColorChanged(int colorCode);
void onOpacityChanged(int opacity);
void onBrushSizeChanged(int brushSize);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_bottom_properties_dialog, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RecyclerView rvColor = view.findViewById(R.id.rvColors);
SeekBar sbOpacity = view.findViewById(R.id.sbOpacity);
SeekBar sbBrushSize = view.findViewById(R.id.sbSize);
sbOpacity.setOnSeekBarChangeListener(this);
sbBrushSize.setOnSeekBarChangeListener(this);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
rvColor.setLayoutManager(layoutManager);
rvColor.setHasFixedSize(true);
ColorPickerAdapter colorPickerAdapter = new ColorPickerAdapter(getActivity());
colorPickerAdapter.setOnColorPickerClickListener(new ColorPickerAdapter.OnColorPickerClickListener() {
@Override
public void onColorPickerClickListener(int colorCode) {
if (mProperties != null) {
dismiss();
mProperties.onColorChanged(colorCode);
}
}
});
rvColor.setAdapter(colorPickerAdapter);
}
public void setPropertiesChangeListener(Properties properties) {
mProperties = properties;
}
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
switch (seekBar.getId()) {
case R.id.sbOpacity:
if (mProperties != null) {
mProperties.onOpacityChanged(i);
}
break;
case R.id.sbSize:
if (mProperties != null) {
mProperties.onBrushSizeChanged(i);
}
break;
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}

View File

@ -0,0 +1,137 @@
package app.fedilab.android.imageeditor;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialogFragment;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import app.fedilab.android.R;
public class StickerBSFragment extends BottomSheetDialogFragment {
public StickerBSFragment() {
// Required empty public constructor
}
private StickerListener mStickerListener;
public void setStickerListener(StickerListener stickerListener) {
mStickerListener = stickerListener;
}
public interface StickerListener {
void onStickerClick(Bitmap bitmap);
}
private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
};
@SuppressLint("RestrictedApi")
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.fragment_bottom_sticker_emoji_dialog, null);
dialog.setContentView(contentView);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
if (behavior != null && behavior instanceof BottomSheetBehavior) {
((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
}
((View) contentView.getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));
RecyclerView rvEmoji = contentView.findViewById(R.id.rvEmoji);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
rvEmoji.setLayoutManager(gridLayoutManager);
StickerAdapter stickerAdapter = new StickerAdapter();
rvEmoji.setAdapter(stickerAdapter);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
public class StickerAdapter extends RecyclerView.Adapter<StickerAdapter.ViewHolder> {
int[] stickerList = new int[]{R.drawable.aa, R.drawable.bb};
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_sticker, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.imgSticker.setImageResource(stickerList[position]);
}
@Override
public int getItemCount() {
return stickerList.length;
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView imgSticker;
ViewHolder(View itemView) {
super(itemView);
imgSticker = itemView.findViewById(R.id.imgSticker);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mStickerListener != null) {
mStickerListener.onStickerClick(
BitmapFactory.decodeResource(getResources(),
stickerList[getLayoutPosition()]));
}
dismiss();
}
});
}
}
}
private String convertEmoji(String emoji) {
String returnedEmoji = "";
try {
int convertEmojiToInt = Integer.parseInt(emoji.substring(2), 16);
returnedEmoji = getEmojiByUnicode(convertEmojiToInt);
} catch (NumberFormatException e) {
returnedEmoji = "";
}
return returnedEmoji;
}
private String getEmojiByUnicode(int unicode) {
return new String(Character.toChars(unicode));
}
}

View File

@ -0,0 +1,130 @@
package app.fedilab.android.imageeditor;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import app.fedilab.android.R;
/**
* Created by Burhanuddin Rashid on 1/16/2018.
*/
public class TextEditorDialogFragment extends DialogFragment {
public static final String TAG = TextEditorDialogFragment.class.getSimpleName();
public static final String EXTRA_INPUT_TEXT = "extra_input_text";
public static final String EXTRA_COLOR_CODE = "extra_color_code";
private EditText mAddTextEditText;
private TextView mAddTextDoneTextView;
private InputMethodManager mInputMethodManager;
private int mColorCode;
private TextEditor mTextEditor;
public interface TextEditor {
void onDone(String inputText, int colorCode);
}
//Show dialog with provide text and text color
public static TextEditorDialogFragment show(@NonNull AppCompatActivity appCompatActivity,
@NonNull String inputText,
@ColorInt int colorCode) {
Bundle args = new Bundle();
args.putString(EXTRA_INPUT_TEXT, inputText);
args.putInt(EXTRA_COLOR_CODE, colorCode);
TextEditorDialogFragment fragment = new TextEditorDialogFragment();
fragment.setArguments(args);
fragment.show(appCompatActivity.getSupportFragmentManager(), TAG);
return fragment;
}
//Show dialog with default text input as empty and text color white
public static TextEditorDialogFragment show(@NonNull AppCompatActivity appCompatActivity) {
return show(appCompatActivity,
"", ContextCompat.getColor(appCompatActivity, R.color.white));
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
//Make dialog full screen with transparent background
if (dialog != null) {
int width = ViewGroup.LayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setLayout(width, height);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.add_text_dialog, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mAddTextEditText = view.findViewById(R.id.add_text_edit_text);
mInputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
mAddTextDoneTextView = view.findViewById(R.id.add_text_done_tv);
//Setup the color picker for text color
RecyclerView addTextColorPickerRecyclerView = view.findViewById(R.id.add_text_color_picker_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
addTextColorPickerRecyclerView.setLayoutManager(layoutManager);
addTextColorPickerRecyclerView.setHasFixedSize(true);
ColorPickerAdapter colorPickerAdapter = new ColorPickerAdapter(getActivity());
//This listener will change the text color when clicked on any color from picker
colorPickerAdapter.setOnColorPickerClickListener(new ColorPickerAdapter.OnColorPickerClickListener() {
@Override
public void onColorPickerClickListener(int colorCode) {
mColorCode = colorCode;
mAddTextEditText.setTextColor(colorCode);
}
});
addTextColorPickerRecyclerView.setAdapter(colorPickerAdapter);
mAddTextEditText.setText(getArguments().getString(EXTRA_INPUT_TEXT));
mColorCode = getArguments().getInt(EXTRA_COLOR_CODE);
mAddTextEditText.setTextColor(mColorCode);
mInputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
//Make a callback on activity when user is done with text editing
mAddTextDoneTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mInputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
dismiss();
String inputText = mAddTextEditText.getText().toString();
if (!TextUtils.isEmpty(inputText) && mTextEditor != null) {
mTextEditor.onDone(inputText, mColorCode);
}
}
});
}
//Callback to listener if user is done with text editing
public void setOnTextEditorListener(TextEditor textEditor) {
mTextEditor = textEditor;
}
}

View File

@ -0,0 +1,7 @@
package app.fedilab.android.imageeditor.filters;
import ja.burhanrashid52.photoeditor.PhotoFilter;
public interface FilterListener {
void onFilterSelected(PhotoFilter photoFilter);
}

View File

@ -0,0 +1,115 @@
package app.fedilab.android.imageeditor.filters;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
import ja.burhanrashid52.photoeditor.PhotoFilter;
/**
* @author <a href="https://github.com/burhanrashid52">Burhanuddin Rashid</a>
* @version 0.1.2
* @since 5/23/2018
*/
public class FilterViewAdapter extends RecyclerView.Adapter<FilterViewAdapter.ViewHolder> {
private FilterListener mFilterListener;
private List<Pair<String, PhotoFilter>> mPairList = new ArrayList<>();
public FilterViewAdapter(FilterListener filterListener) {
mFilterListener = filterListener;
setupFilters();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_filter_view, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Pair<String, PhotoFilter> filterPair = mPairList.get(position);
Bitmap fromAsset = getBitmapFromAsset(holder.itemView.getContext(), filterPair.first);
holder.mImageFilterView.setImageBitmap(fromAsset);
holder.mTxtFilterName.setText(filterPair.second.name().replace("_", " "));
}
@Override
public int getItemCount() {
return mPairList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView mImageFilterView;
TextView mTxtFilterName;
ViewHolder(View itemView) {
super(itemView);
mImageFilterView = itemView.findViewById(R.id.imgFilterView);
mTxtFilterName = itemView.findViewById(R.id.txtFilterName);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mFilterListener.onFilterSelected(mPairList.get(getLayoutPosition()).second);
}
});
}
}
private Bitmap getBitmapFromAsset(Context context, String strName) {
AssetManager assetManager = context.getAssets();
InputStream istr = null;
try {
istr = assetManager.open(strName);
return BitmapFactory.decodeStream(istr);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private void setupFilters() {
mPairList.add(new Pair<>("filters/original.jpg", PhotoFilter.NONE));
mPairList.add(new Pair<>("filters/auto_fix.png", PhotoFilter.AUTO_FIX));
mPairList.add(new Pair<>("filters/brightness.png", PhotoFilter.BRIGHTNESS));
mPairList.add(new Pair<>("filters/contrast.png", PhotoFilter.CONTRAST));
mPairList.add(new Pair<>("filters/documentary.png", PhotoFilter.DOCUMENTARY));
mPairList.add(new Pair<>("filters/dual_tone.png", PhotoFilter.DUE_TONE));
mPairList.add(new Pair<>("filters/fill_light.png", PhotoFilter.FILL_LIGHT));
mPairList.add(new Pair<>("filters/fish_eye.png", PhotoFilter.FISH_EYE));
mPairList.add(new Pair<>("filters/grain.png", PhotoFilter.GRAIN));
mPairList.add(new Pair<>("filters/gray_scale.png", PhotoFilter.GRAY_SCALE));
mPairList.add(new Pair<>("filters/lomish.png", PhotoFilter.LOMISH));
mPairList.add(new Pair<>("filters/negative.png", PhotoFilter.NEGATIVE));
mPairList.add(new Pair<>("filters/posterize.png", PhotoFilter.POSTERIZE));
mPairList.add(new Pair<>("filters/saturate.png", PhotoFilter.SATURATE));
mPairList.add(new Pair<>("filters/sepia.png", PhotoFilter.SEPIA));
mPairList.add(new Pair<>("filters/sharpen.png", PhotoFilter.SHARPEN));
mPairList.add(new Pair<>("filters/temprature.png", PhotoFilter.TEMPERATURE));
mPairList.add(new Pair<>("filters/tint.png", PhotoFilter.TINT));
mPairList.add(new Pair<>("filters/vignette.png", PhotoFilter.VIGNETTE));
mPairList.add(new Pair<>("filters/cross_process.png", PhotoFilter.CROSS_PROCESS));
mPairList.add(new Pair<>("filters/b_n_w.png", PhotoFilter.BLACK_WHITE));
mPairList.add(new Pair<>("filters/flip_horizental.png", PhotoFilter.FLIP_HORIZONTAL));
mPairList.add(new Pair<>("filters/flip_vertical.png", PhotoFilter.FLIP_VERTICAL));
mPairList.add(new Pair<>("filters/rotate.png", PhotoFilter.ROTATE));
}
}

View File

@ -0,0 +1,91 @@
package app.fedilab.android.imageeditor.tools;
import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
/**
* @author <a href="https://github.com/burhanrashid52">Burhanuddin Rashid</a>
* @version 0.1.2
* @since 5/23/2018
*/
public class EditingToolsAdapter extends RecyclerView.Adapter<EditingToolsAdapter.ViewHolder> {
private List<ToolModel> mToolList = new ArrayList<>();
private OnItemSelected mOnItemSelected;
public EditingToolsAdapter(OnItemSelected onItemSelected) {
mOnItemSelected = onItemSelected;
mToolList.add(new ToolModel("Brush", R.drawable.ic_brush_edit, ToolType.BRUSH));
mToolList.add(new ToolModel("Text", R.drawable.ic_text, ToolType.TEXT));
mToolList.add(new ToolModel("Eraser", R.drawable.ic_eraser, ToolType.ERASER));
mToolList.add(new ToolModel("Filter", R.drawable.ic_photo_filter, ToolType.FILTER));
mToolList.add(new ToolModel("Emoji", R.drawable.ic_insert_emoticon, ToolType.EMOJI));
mToolList.add(new ToolModel("Sticker", R.drawable.ic_sticker, ToolType.STICKER));
}
public interface OnItemSelected {
void onToolSelected(ToolType toolType);
}
class ToolModel {
private String mToolName;
private int mToolIcon;
private ToolType mToolType;
ToolModel(String toolName, int toolIcon, ToolType toolType) {
mToolName = toolName;
mToolIcon = toolIcon;
mToolType = toolType;
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_editing_tools, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ToolModel item = mToolList.get(position);
holder.txtTool.setText(item.mToolName);
holder.imgToolIcon.setImageResource(item.mToolIcon);
}
@Override
public int getItemCount() {
return mToolList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView imgToolIcon;
TextView txtTool;
ViewHolder(View itemView) {
super(itemView);
imgToolIcon = itemView.findViewById(R.id.imgToolIcon);
txtTool = itemView.findViewById(R.id.txtTool);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnItemSelected.onToolSelected(mToolList.get(getLayoutPosition()).mToolType);
}
});
}
}
}

View File

@ -0,0 +1,15 @@
package app.fedilab.android.imageeditor.tools;
/**
* @author <a href="https://github.com/burhanrashid52">Burhanuddin Rashid</a>
* @version 0.1.2
* @since 5/23/2018
*/
public enum ToolType {
BRUSH,
TEXT,
ERASER,
FILTER,
EMOJI,
STICKER
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M7,14c-1.66,0 -3,1.34 -3,3 0,1.31 -1.16,2 -2,2 0.92,1.22 2.49,2 4,2 2.21,0 4,-1.79 4,-4 0,-1.66 -1.34,-3 -3,-3zM20.71,4.63l-1.34,-1.34c-0.39,-0.39 -1.02,-0.39 -1.41,0L9,12.25 11.75,15l8.96,-8.96c0.39,-0.39 0.39,-1.02 0,-1.41z"/>
</vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
<path
android:fillColor="#606984"
android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M19.02,10v9L5,19L5,5h9L14,3L5.02,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-9h-2zM17,10l0.94,-2.06L20,7l-2.06,-0.94L17,4l-0.94,2.06L14,7l2.06,0.94zM13.25,10.75L12,8l-1.25,2.75L8,12l2.75,1.25L12,16l1.25,-2.75L16,12z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M18.4,10.6C16.55,8.99 14.15,8 11.5,8c-4.65,0 -8.58,3.03 -9.96,7.22L3.9,16c1.05,-3.19 4.05,-5.5 7.6,-5.5 1.95,0 3.73,0.72 5.12,1.88L13,16h9V7l-3.6,3.6z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M17.63,5.84C17.27,5.33 16.67,5 16,5L5,5.01C3.9,5.01 3,5.9 3,7v10c0,1.1 0.9,1.99 2,1.99L16,19c0.67,0 1.27,-0.33 1.63,-0.84L22,12l-4.37,-6.16z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M2.5,4v3h5v12h3L10.5,7h5L15.5,4h-13zM21.5,9h-9v3h3v7h3v-7h3L21.5,9z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M12.5,8c-2.65,0 -5.05,0.99 -6.9,2.6L2,7v9h9l-3.62,-3.62c1.39,-1.16 3.16,-1.88 5.12,-1.88 3.54,0 6.55,2.31 7.6,5.5l2.37,-0.78C21.08,11.03 17.15,8 12.5,8z"/>
</vector>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="2dp"
android:color="#FFFFFF" />
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<corners android:radius="50dp" />
</shape>

View File

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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>.
-->
<android.support.constraint.ConstraintLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="?attr/actionBarSize" />
<ja.burhanrashid52.photoeditor.PhotoEditorView
android:id="@+id/photoEditorView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<ImageView
android:id="@+id/imgUndo"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@drawable/ic_undo"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintEnd_toStartOf="@+id/imgRedo"
android:contentDescription="@string/undo" />
<ImageView
android:id="@+id/imgRedo"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@drawable/ic_redo"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintEnd_toEndOf="parent"
android:contentDescription="@string/redo" />
<ImageView
android:id="@+id/imgGallery"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@drawable/ic_gallery"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintStart_toStartOf="parent"
android:contentDescription="@string/gallery"/>
<ImageView
android:id="@+id/imgCamera"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@drawable/ic_camera"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintStart_toEndOf="@id/imgGallery"
android:contentDescription="@string/camera"
/>
<ImageView
android:id="@+id/imgClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_margin="8dp"
android:src="@drawable/ic_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:contentDescription="@string/close"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rvConstraintTools"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="4dp"
android:paddingTop="4dp"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:listitem="@layout/row_editing_tools" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rvFilterView"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="@+id/rvConstraintTools"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/rvConstraintTools"
tools:listitem="@layout/row_filter_view" />
<TextView
android:id="@+id/txtCurrentTool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
<ImageView
android:id="@+id/imgSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:src="@drawable/ic_save_gallery"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:contentDescription="@string/save"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#B3000000"
android:orientation="vertical">
<TextView
android:id="@+id/add_text_done_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_margin="20dp"
android:background="@drawable/rounded_border_text_view"
android:padding="10dp"
android:text="@string/done"
android:textAllCaps="false"
android:textColor="@color/white"
android:textSize="15sp" />
<EditText
android:id="@+id/add_text_edit_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/add_text_color_picker_relative_layout"
android:layout_below="@+id/add_text_done_tv"
android:background="@null"
android:gravity="center"
android:inputType="textMultiLine"
android:textSize="40sp" />
<RelativeLayout
android:id="@+id/add_text_color_picker_relative_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<android.support.v7.widget.RecyclerView
android:id="@+id/add_text_color_picker_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:background="@android:color/black"
tools:listitem="@layout/color_picker_item_list" />
</RelativeLayout>
</RelativeLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<View
android:id="@+id/color_picker_view"
android:layout_width="40dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:background="@android:color/white"
tools:text="" />
</RelativeLayout>

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvColors"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sbOpacity"
tools:background="@android:color/black"
tools:listitem="@layout/color_picker_item_list"
android:layout_alignParentRight="true" />
<SeekBar
android:id="@+id/sbOpacity"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:progress="100"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtOpacity" />
<TextView
android:id="@+id/txtOpacity"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:text="Opacity"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sbSize" />
<SeekBar
android:id="@+id/sbSize"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:progress="25"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtBrushSize" />
<TextView
android:id="@+id/txtBrushSize"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Brush"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp">
<TextView
android:id="@+id/txtClose"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:layout_marginStart="8dp"
android:gravity="center"
android:text="@string/close"
android:textAppearance="@style/TextAppearance.AppCompat.Large.Inverse"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="8dp" />
<View
android:id="@+id/lineView"
android:layout_width="match_parent"
android:layout_height="2px"
android:background="@android:color/white"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/txtClose"
tools:ignore="PxUsage" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rvEmoji"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_behavior="@string/bottom_sheet_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/lineView" />
<TextView
android:id="@+id/txtDone"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="8dp"
android:gravity="center"
android:text="@string/done"
android:textAppearance="@style/TextAppearance.AppCompat.Large.Inverse"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginRight="8dp" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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>.
-->
<ja.burhanrashid52.photoeditor.PhotoEditorView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/photoEditorView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="4dp"
tools:background="@android:color/black">
<ImageView
android:id="@+id/imgToolIcon"
android:layout_width="@dimen/editor_size"
android:layout_height="@dimen/editor_size"
android:layout_margin="4dp"
android:layout_marginBottom="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:src="@drawable/ic_brush_edit"
android:contentDescription="@string/label_brush" />
<TextView
android:id="@+id/txtTool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@android:color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imgToolIcon"
tools:text="@string/label_brush" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txtEmoji"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:padding="2dp"
android:textColor="#FFFFFF"
android:textSize="35sp"
tools:android="Burhanuddin" />
</LinearLayout>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="2dp">
<ImageView
android:id="@+id/imgFilterView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/backgrounds/scenic" />
<TextView
android:id="@+id/txtFilterName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#90000000"
android:gravity="center"
android:padding="4dp"
android:textColor="@android:color/white"
android:textSize="8dp"
app:layout_constraintBottom_toBottomOf="@+id/imgFilterView"
app:layout_constraintEnd_toEndOf="@+id/imgFilterView"
app:layout_constraintStart_toStartOf="@+id/imgFilterView"
tools:text="@tools:sample/full_names" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp">
<ImageView
android:id="@+id/imgSticker"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

View File

@ -122,4 +122,17 @@
<color name="console_marker">#CC6666</color>
<color name="bot_background">#B3808080</color>
<!-- COLOR PICKER -->
<color name="blue_color_picker">#0066FF</color>
<color name="brown_color_picker">#AF593E</color>
<color name="green_color_picker">#01A368</color>
<color name="orange_color_picker">#FF861F</color>
<color name="red_color_picker">#ED0A3F</color>
<color name="red_orange_color_picker">#FF3F34</color>
<color name="sky_blue_color_picker">#76D7EA</color>
<color name="violet_color_picker">#8359A3</color>
<color name="yellow_color_picker">#FBE870</color>
<color name="yellow_green_color_picker">#C5E17A</color>
<color name="tool_bg">#151414</color>
</resources>

View File

@ -16,4 +16,5 @@
<dimen name="settings_category_label_margin">2dp</dimen>
<dimen name="activity_vertical_margin_login">50dp</dimen>
<dimen name="badge_count_textsize">12sp</dimen>
<dimen name="editor_size">35dp</dimen>
</resources>

View File

@ -960,7 +960,16 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<plurals name="number_of_vote">
<item quantity="one">%d vote</item>
<item quantity="other">%d votes</item>