Loading app/src/main/java/app/fedilab/android/activities/ComposeActivity.java +5 −0 Original line number Diff line number Diff line Loading @@ -109,12 +109,17 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana @Override public void onReceive(android.content.Context context, Intent intent) { String imgpath = intent.getStringExtra("imgpath"); float focusX = intent.getFloatExtra("focusX", -2); float focusY = intent.getFloatExtra("focusY", -2); if (imgpath != null) { int position = 0; for (Status status : statusList) { if (status.media_attachments != null && status.media_attachments.size() > 0) { for (Attachment attachment : status.media_attachments) { if (attachment.local_path.equalsIgnoreCase(imgpath)) { if (focusX != -2) { attachment.focus = focusX + "," + focusY; } composeAdapter.notifyItemChanged(position); break; } Loading app/src/main/java/app/fedilab/android/client/entities/api/Attachment.java +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public class Attachment implements Serializable { public String peertubeHost = null; public String peertubeId = null; public String focus = null; public static class Meta implements Serializable { @SerializedName("focus") Loading app/src/main/java/app/fedilab/android/helper/CirclesDrawingView.java 0 → 100644 +249 −0 Original line number Diff line number Diff line package app.fedilab.android.helper; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.SparseArray; import android.view.MotionEvent; import android.view.View; import androidx.core.content.res.ResourcesCompat; import java.util.HashSet; import java.util.Random; import app.fedilab.android.R; //Original work at https://stackoverflow.com/a/17830245 public class CirclesDrawingView extends View { // Radius limit in pixels private final static int RADIUS_LIMIT = 100; private static final int CIRCLES_LIMIT = 1; private final Random mRadiusGenerator = new Random(); /** * All available circles */ private final HashSet<CircleArea> mCircles = new HashSet<>(CIRCLES_LIMIT); private final SparseArray<CircleArea> mCirclePointer = new SparseArray<>(CIRCLES_LIMIT); /** * Paint to draw circles */ private Paint mCirclePaint; private CircleArea touchedCircle; /** * Default constructor * * @param ct {@link android.content.Context} */ public CirclesDrawingView(final Context ct) { super(ct); init(ct); } public CirclesDrawingView(final Context ct, final AttributeSet attrs) { super(ct, attrs); init(ct); } public CirclesDrawingView(final Context ct, final AttributeSet attrs, final int defStyle) { super(ct, attrs, defStyle); init(ct); } public CircleArea getTouchedCircle() { return this.touchedCircle; } private void init(final Context ct) { // Generate bitmap used for background mCirclePaint = new Paint(); mCirclePaint.setColor(ResourcesCompat.getColor(getContext().getResources(), R.color.cyanea_accent, getContext().getTheme())); mCirclePaint.setStrokeWidth(10); mCirclePaint.setStyle(Paint.Style.STROKE); } @Override public void onDraw(final Canvas canv) { // background bitmap to cover all area for (CircleArea circle : mCircles) { canv.drawCircle(circle.centerX, circle.centerY, circle.radius, mCirclePaint); } } @Override public boolean onTouchEvent(final MotionEvent event) { boolean handled = false; int xTouch; int yTouch; int pointerId; int actionIndex = event.getActionIndex(); // get touch event coordinates and make transparent circle from it switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: // it's the first pointer, so clear all existing pointers data clearCirclePointer(); xTouch = (int) event.getX(0); yTouch = (int) event.getY(0); // check if we've touched inside some circle touchedCircle = obtainTouchedCircle(xTouch, yTouch); touchedCircle.centerX = xTouch; touchedCircle.centerY = yTouch; mCirclePointer.put(event.getPointerId(0), touchedCircle); invalidate(); handled = true; break; case MotionEvent.ACTION_POINTER_DOWN: // It secondary pointers, so obtain their ids and check circles pointerId = event.getPointerId(actionIndex); xTouch = (int) event.getX(actionIndex); yTouch = (int) event.getY(actionIndex); // check if we've touched inside some circle touchedCircle = obtainTouchedCircle(xTouch, yTouch); mCirclePointer.put(pointerId, touchedCircle); touchedCircle.centerX = xTouch; touchedCircle.centerY = yTouch; invalidate(); handled = true; break; case MotionEvent.ACTION_MOVE: final int pointerCount = event.getPointerCount(); for (actionIndex = 0; actionIndex < pointerCount; actionIndex++) { // Some pointer has moved, search it by pointer id pointerId = event.getPointerId(actionIndex); xTouch = (int) event.getX(actionIndex); yTouch = (int) event.getY(actionIndex); touchedCircle = mCirclePointer.get(pointerId); if (null != touchedCircle) { touchedCircle.centerX = xTouch; touchedCircle.centerY = yTouch; } } invalidate(); handled = true; break; case MotionEvent.ACTION_UP: clearCirclePointer(); invalidate(); handled = true; break; case MotionEvent.ACTION_POINTER_UP: // not general pointer was up pointerId = event.getPointerId(actionIndex); mCirclePointer.remove(pointerId); invalidate(); handled = true; break; case MotionEvent.ACTION_CANCEL: handled = true; break; default: // do nothing break; } return super.onTouchEvent(event) || handled; } /** * Clears all CircleArea - pointer id relations */ private void clearCirclePointer() { mCirclePointer.clear(); } /** * Search and creates new (if needed) circle based on touch area * * @param xTouch int x of touch * @param yTouch int y of touch * @return obtained {@link CircleArea} */ private CircleArea obtainTouchedCircle(final int xTouch, final int yTouch) { CircleArea touchedCircle = getTouchedCircle(xTouch, yTouch); if (null == touchedCircle) { touchedCircle = new CircleArea(xTouch, yTouch, mRadiusGenerator.nextInt(RADIUS_LIMIT) + RADIUS_LIMIT); if (mCircles.size() == CIRCLES_LIMIT) { // remove first circle mCircles.clear(); } mCircles.add(touchedCircle); } return touchedCircle; } /** * Determines touched circle * * @param xTouch int x touch coordinate * @param yTouch int y touch coordinate * @return {@link CircleArea} touched circle or null if no circle has been touched */ private CircleArea getTouchedCircle(final int xTouch, final int yTouch) { CircleArea touched = null; for (CircleArea circle : mCircles) { if ((circle.centerX - xTouch) * (circle.centerX - xTouch) + (circle.centerY - yTouch) * (circle.centerY - yTouch) <= circle.radius * circle.radius) { touched = circle; break; } } return touched; } @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); new Rect(0, 0, getMeasuredWidth(), getMeasuredHeight()); } /** * Stores data about single circle */ public static class CircleArea { public int centerX; public int centerY; int radius; CircleArea(int centerX, int centerY, int radius) { this.radius = radius; this.centerX = centerX; this.centerY = centerY; } @Override public String toString() { return "Circle[" + centerX + ", " + centerY + ", " + radius + "]"; } } } No newline at end of file app/src/main/java/app/fedilab/android/imageeditor/EditImageActivity.java +49 −3 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; Loading Loading @@ -33,6 +34,7 @@ import java.io.InputStream; import app.fedilab.android.R; import app.fedilab.android.databinding.ActivityEditImageBinding; import app.fedilab.android.helper.CirclesDrawingView; import app.fedilab.android.helper.Helper; import app.fedilab.android.imageeditor.base.BaseActivity; import app.fedilab.android.imageeditor.filters.FilterListener; Loading @@ -58,7 +60,6 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList private static final int CAMERA_REQUEST = 52; private static final int PICK_REQUEST = 53; private final int STORE_REQUEST = 54; private final EditingToolsAdapter mEditingToolsAdapter = new EditingToolsAdapter(this); private final FilterViewAdapter mFilterViewAdapter = new FilterViewAdapter(this); private final ConstraintSet mConstraintSet = new ConstraintSet(); Loading Loading @@ -117,8 +118,6 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList binding.rvFilterView.setLayoutManager(llmFilters); binding.rvFilterView.setAdapter(mFilterViewAdapter); //Typeface mTextRobotoTf = ResourcesCompat.getFont(this, R.font.roboto_medium); //Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf"); Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf"); mPhotoEditor = new PhotoEditor.Builder(this, binding.photoEditorView) Loading Loading @@ -246,6 +245,49 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList if (exit) { Intent intentImage = new Intent(Helper.INTENT_SEND_MODIFIED_IMAGE); intentImage.putExtra("imgpath", imagePath); CirclesDrawingView.CircleArea circleArea = binding.focusCircle.getTouchedCircle(); if (circleArea != null) { //Dimension of the editor containing the image int pHeight = binding.photoEditorView.getHeight(); int pWidth = binding.photoEditorView.getWidth(); //Load the original image in a bitmap BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(new File(imagePath).getAbsolutePath(), options); //Get height and width of the original image int imageHeight = options.outHeight; int imageWidth = options.outWidth; //Evaluate the dimension of the image in the editor int imgHeightInEditor; int imgWidthInEditor; //If the original image has its height greater than width => heights are equals float focusX = -2, focusY = -2; if (imageHeight > imageWidth) { imgHeightInEditor = pHeight; float ratio = (float) pHeight / (float) imageHeight; imgWidthInEditor = (int) (pWidth * ratio); } else { //Otherwise widths are equals imgWidthInEditor = pWidth; float ratio = (float) pWidth / (float) imageWidth; imgHeightInEditor = (int) (pHeight * ratio); } focusY = (float) (circleArea.centerY * 2 - imgHeightInEditor / 2) / (float) imgHeightInEditor - 0.5f; focusX = (float) (circleArea.centerX * 2 - imgWidthInEditor / 2) / (float) imgWidthInEditor - 0.5f; if (focusX > 1) { focusX = 1; } else if (focusX < -1) { focusX = -1; } if (focusY > 1) { focusY = 1; } else if (focusY < -1) { focusY = -1; } intentImage.putExtra("focusX", focusX); intentImage.putExtra("focusY", focusY); } LocalBroadcastManager.getInstance(EditImageActivity.this).sendBroadcast(intentImage); finish(); } Loading Loading @@ -376,6 +418,7 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList @Override public void onToolSelected(ToolType toolType) { binding.focusCircle.setVisibility(View.GONE); switch (toolType) { case SHAPE: mPhotoEditor.setBrushDrawingMode(true); Loading Loading @@ -414,6 +457,9 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList CropImage.activity(uri) .start(this); break; case FOCUS: binding.focusCircle.setVisibility(View.VISIBLE); break; } } Loading app/src/main/java/app/fedilab/android/imageeditor/tools/EditingToolsAdapter.java +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ public class EditingToolsAdapter extends RecyclerView.Adapter<EditingToolsAdapte 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("Focus", R.drawable.ic_baseline_filter_center_focus_24, ToolType.FOCUS)); } @NonNull Loading Loading
app/src/main/java/app/fedilab/android/activities/ComposeActivity.java +5 −0 Original line number Diff line number Diff line Loading @@ -109,12 +109,17 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana @Override public void onReceive(android.content.Context context, Intent intent) { String imgpath = intent.getStringExtra("imgpath"); float focusX = intent.getFloatExtra("focusX", -2); float focusY = intent.getFloatExtra("focusY", -2); if (imgpath != null) { int position = 0; for (Status status : statusList) { if (status.media_attachments != null && status.media_attachments.size() > 0) { for (Attachment attachment : status.media_attachments) { if (attachment.local_path.equalsIgnoreCase(imgpath)) { if (focusX != -2) { attachment.focus = focusX + "," + focusY; } composeAdapter.notifyItemChanged(position); break; } Loading
app/src/main/java/app/fedilab/android/client/entities/api/Attachment.java +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public class Attachment implements Serializable { public String peertubeHost = null; public String peertubeId = null; public String focus = null; public static class Meta implements Serializable { @SerializedName("focus") Loading
app/src/main/java/app/fedilab/android/helper/CirclesDrawingView.java 0 → 100644 +249 −0 Original line number Diff line number Diff line package app.fedilab.android.helper; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.SparseArray; import android.view.MotionEvent; import android.view.View; import androidx.core.content.res.ResourcesCompat; import java.util.HashSet; import java.util.Random; import app.fedilab.android.R; //Original work at https://stackoverflow.com/a/17830245 public class CirclesDrawingView extends View { // Radius limit in pixels private final static int RADIUS_LIMIT = 100; private static final int CIRCLES_LIMIT = 1; private final Random mRadiusGenerator = new Random(); /** * All available circles */ private final HashSet<CircleArea> mCircles = new HashSet<>(CIRCLES_LIMIT); private final SparseArray<CircleArea> mCirclePointer = new SparseArray<>(CIRCLES_LIMIT); /** * Paint to draw circles */ private Paint mCirclePaint; private CircleArea touchedCircle; /** * Default constructor * * @param ct {@link android.content.Context} */ public CirclesDrawingView(final Context ct) { super(ct); init(ct); } public CirclesDrawingView(final Context ct, final AttributeSet attrs) { super(ct, attrs); init(ct); } public CirclesDrawingView(final Context ct, final AttributeSet attrs, final int defStyle) { super(ct, attrs, defStyle); init(ct); } public CircleArea getTouchedCircle() { return this.touchedCircle; } private void init(final Context ct) { // Generate bitmap used for background mCirclePaint = new Paint(); mCirclePaint.setColor(ResourcesCompat.getColor(getContext().getResources(), R.color.cyanea_accent, getContext().getTheme())); mCirclePaint.setStrokeWidth(10); mCirclePaint.setStyle(Paint.Style.STROKE); } @Override public void onDraw(final Canvas canv) { // background bitmap to cover all area for (CircleArea circle : mCircles) { canv.drawCircle(circle.centerX, circle.centerY, circle.radius, mCirclePaint); } } @Override public boolean onTouchEvent(final MotionEvent event) { boolean handled = false; int xTouch; int yTouch; int pointerId; int actionIndex = event.getActionIndex(); // get touch event coordinates and make transparent circle from it switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: // it's the first pointer, so clear all existing pointers data clearCirclePointer(); xTouch = (int) event.getX(0); yTouch = (int) event.getY(0); // check if we've touched inside some circle touchedCircle = obtainTouchedCircle(xTouch, yTouch); touchedCircle.centerX = xTouch; touchedCircle.centerY = yTouch; mCirclePointer.put(event.getPointerId(0), touchedCircle); invalidate(); handled = true; break; case MotionEvent.ACTION_POINTER_DOWN: // It secondary pointers, so obtain their ids and check circles pointerId = event.getPointerId(actionIndex); xTouch = (int) event.getX(actionIndex); yTouch = (int) event.getY(actionIndex); // check if we've touched inside some circle touchedCircle = obtainTouchedCircle(xTouch, yTouch); mCirclePointer.put(pointerId, touchedCircle); touchedCircle.centerX = xTouch; touchedCircle.centerY = yTouch; invalidate(); handled = true; break; case MotionEvent.ACTION_MOVE: final int pointerCount = event.getPointerCount(); for (actionIndex = 0; actionIndex < pointerCount; actionIndex++) { // Some pointer has moved, search it by pointer id pointerId = event.getPointerId(actionIndex); xTouch = (int) event.getX(actionIndex); yTouch = (int) event.getY(actionIndex); touchedCircle = mCirclePointer.get(pointerId); if (null != touchedCircle) { touchedCircle.centerX = xTouch; touchedCircle.centerY = yTouch; } } invalidate(); handled = true; break; case MotionEvent.ACTION_UP: clearCirclePointer(); invalidate(); handled = true; break; case MotionEvent.ACTION_POINTER_UP: // not general pointer was up pointerId = event.getPointerId(actionIndex); mCirclePointer.remove(pointerId); invalidate(); handled = true; break; case MotionEvent.ACTION_CANCEL: handled = true; break; default: // do nothing break; } return super.onTouchEvent(event) || handled; } /** * Clears all CircleArea - pointer id relations */ private void clearCirclePointer() { mCirclePointer.clear(); } /** * Search and creates new (if needed) circle based on touch area * * @param xTouch int x of touch * @param yTouch int y of touch * @return obtained {@link CircleArea} */ private CircleArea obtainTouchedCircle(final int xTouch, final int yTouch) { CircleArea touchedCircle = getTouchedCircle(xTouch, yTouch); if (null == touchedCircle) { touchedCircle = new CircleArea(xTouch, yTouch, mRadiusGenerator.nextInt(RADIUS_LIMIT) + RADIUS_LIMIT); if (mCircles.size() == CIRCLES_LIMIT) { // remove first circle mCircles.clear(); } mCircles.add(touchedCircle); } return touchedCircle; } /** * Determines touched circle * * @param xTouch int x touch coordinate * @param yTouch int y touch coordinate * @return {@link CircleArea} touched circle or null if no circle has been touched */ private CircleArea getTouchedCircle(final int xTouch, final int yTouch) { CircleArea touched = null; for (CircleArea circle : mCircles) { if ((circle.centerX - xTouch) * (circle.centerX - xTouch) + (circle.centerY - yTouch) * (circle.centerY - yTouch) <= circle.radius * circle.radius) { touched = circle; break; } } return touched; } @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); new Rect(0, 0, getMeasuredWidth(), getMeasuredHeight()); } /** * Stores data about single circle */ public static class CircleArea { public int centerX; public int centerY; int radius; CircleArea(int centerX, int centerY, int radius) { this.radius = radius; this.centerX = centerX; this.centerY = centerY; } @Override public String toString() { return "Circle[" + centerX + ", " + centerY + ", " + radius + "]"; } } } No newline at end of file
app/src/main/java/app/fedilab/android/imageeditor/EditImageActivity.java +49 −3 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; Loading Loading @@ -33,6 +34,7 @@ import java.io.InputStream; import app.fedilab.android.R; import app.fedilab.android.databinding.ActivityEditImageBinding; import app.fedilab.android.helper.CirclesDrawingView; import app.fedilab.android.helper.Helper; import app.fedilab.android.imageeditor.base.BaseActivity; import app.fedilab.android.imageeditor.filters.FilterListener; Loading @@ -58,7 +60,6 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList private static final int CAMERA_REQUEST = 52; private static final int PICK_REQUEST = 53; private final int STORE_REQUEST = 54; private final EditingToolsAdapter mEditingToolsAdapter = new EditingToolsAdapter(this); private final FilterViewAdapter mFilterViewAdapter = new FilterViewAdapter(this); private final ConstraintSet mConstraintSet = new ConstraintSet(); Loading Loading @@ -117,8 +118,6 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList binding.rvFilterView.setLayoutManager(llmFilters); binding.rvFilterView.setAdapter(mFilterViewAdapter); //Typeface mTextRobotoTf = ResourcesCompat.getFont(this, R.font.roboto_medium); //Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf"); Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf"); mPhotoEditor = new PhotoEditor.Builder(this, binding.photoEditorView) Loading Loading @@ -246,6 +245,49 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList if (exit) { Intent intentImage = new Intent(Helper.INTENT_SEND_MODIFIED_IMAGE); intentImage.putExtra("imgpath", imagePath); CirclesDrawingView.CircleArea circleArea = binding.focusCircle.getTouchedCircle(); if (circleArea != null) { //Dimension of the editor containing the image int pHeight = binding.photoEditorView.getHeight(); int pWidth = binding.photoEditorView.getWidth(); //Load the original image in a bitmap BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(new File(imagePath).getAbsolutePath(), options); //Get height and width of the original image int imageHeight = options.outHeight; int imageWidth = options.outWidth; //Evaluate the dimension of the image in the editor int imgHeightInEditor; int imgWidthInEditor; //If the original image has its height greater than width => heights are equals float focusX = -2, focusY = -2; if (imageHeight > imageWidth) { imgHeightInEditor = pHeight; float ratio = (float) pHeight / (float) imageHeight; imgWidthInEditor = (int) (pWidth * ratio); } else { //Otherwise widths are equals imgWidthInEditor = pWidth; float ratio = (float) pWidth / (float) imageWidth; imgHeightInEditor = (int) (pHeight * ratio); } focusY = (float) (circleArea.centerY * 2 - imgHeightInEditor / 2) / (float) imgHeightInEditor - 0.5f; focusX = (float) (circleArea.centerX * 2 - imgWidthInEditor / 2) / (float) imgWidthInEditor - 0.5f; if (focusX > 1) { focusX = 1; } else if (focusX < -1) { focusX = -1; } if (focusY > 1) { focusY = 1; } else if (focusY < -1) { focusY = -1; } intentImage.putExtra("focusX", focusX); intentImage.putExtra("focusY", focusY); } LocalBroadcastManager.getInstance(EditImageActivity.this).sendBroadcast(intentImage); finish(); } Loading Loading @@ -376,6 +418,7 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList @Override public void onToolSelected(ToolType toolType) { binding.focusCircle.setVisibility(View.GONE); switch (toolType) { case SHAPE: mPhotoEditor.setBrushDrawingMode(true); Loading Loading @@ -414,6 +457,9 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList CropImage.activity(uri) .start(this); break; case FOCUS: binding.focusCircle.setVisibility(View.VISIBLE); break; } } Loading
app/src/main/java/app/fedilab/android/imageeditor/tools/EditingToolsAdapter.java +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ public class EditingToolsAdapter extends RecyclerView.Adapter<EditingToolsAdapte 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("Focus", R.drawable.ic_baseline_filter_center_focus_24, ToolType.FOCUS)); } @NonNull Loading