Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean code #560

Merged
merged 4 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,29 +68,27 @@ First we need to add `PhotoEditorView` in our xml layout
We can define our drawable or color resource directly using `app:photo_src`

We can set the image programmatically by getting source from `PhotoEditorView` which will return a `ImageView` so that we can load image from resources,file or (Picasso/Glide)
```java
PhotoEditorView mPhotoEditorView = findViewById(R.id.photoEditorView);
```kotlin
mPhotoEditorView = findViewById(R.id.photoEditorView)

mPhotoEditorView.getSource().setImageResource(R.drawable.got);
mPhotoEditorView.source.setImageResource(R.drawable.paris_tower)
```

## Building a PhotoEditor
To use the image editing feature we need to build a PhotoEditor which requires a Context and PhotoEditorView which we have to setup in our xml layout


```java
```Kotlin
//Use custom font using latest support library
Typeface mTextRobotoTf = ResourcesCompat.getFont(this, R.font.roboto_medium);

val mTextRobotoTf = ResourcesCompat.getFont(this, R.font.roboto_medium)
//loading font from asset
Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf");

mPhotoEditor = new PhotoEditor.Builder(this, mPhotoEditorView)
.setPinchTextScalable(true)
.setClipSourceImage(true)
.setDefaultTextTypeface(mTextRobotoTf)
.setDefaultEmojiTypeface(mEmojiTypeFace)
.build();
val mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf")

mPhotoEditor = PhotoEditor.Builder(this, mPhotoEditorView)
.setPinchTextScalable(pinchTextScalable) // set flag to make text scalable when pinch
.setDefaultTextTypeface(mTextRobotoTf)
.setDefaultEmojiTypeface(mEmojiTypeFace)
.build() // build photo editor sdk
```
We can customize the properties in the PhotoEditor as per our requirement

Expand Down Expand Up @@ -130,7 +128,7 @@ We can draw shapes from [v.1.5.0](https://github.com/burhanrashid52/PhotoEditor/
val shapeBuilder = ShapeBuilder()
.withShapeOpacity(100)
.withShapeType(ShapeType.Oval)
.withShapeSize(50f);
.withShapeSize(50f)

photoEditor.setShape(mShapeBuilder)
```
Expand All @@ -139,7 +137,7 @@ For more details check [ShapeBuilder](https://github.com/burhanrashid52/PhotoEdi
## Filter Effect
We can apply inbuild filter to the source images using

`mPhotoEditor.setFilterEffect(PhotoFilter.BRIGHTNESS);`
`mPhotoEditor.setFilterEffect(PhotoFilter.BRIGHTNESS)`

![](https://i.imgur.com/xXTGcVC.gif)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
package com.burhanrashid52.photoediting

import android.content.Context
import org.junit.runner.RunWith
import androidx.test.rule.ActivityTestRule
import junit.framework.TestCase
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.recyclerview.widget.RecyclerView
import kotlin.Throws
import android.content.Intent
import android.net.Uri
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.AndroidJUnit4
import junit.framework.TestCase.*
import org.hamcrest.Description
Expand All @@ -27,6 +24,7 @@ import org.junit.Assert.assertNotEquals
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@LargeTest
Expand All @@ -49,9 +47,9 @@ class EditImageActivityTest {
@Test
fun checkIfBrushIsEnabledWhenClickedOnBrushTool() {
val editImageActivity = mActivityRule.launchActivity(null)
assertEquals(editImageActivity.mPhotoEditor?.brushDrawableMode, false)
assertEquals(editImageActivity.mPhotoEditor.brushDrawableMode, false)
Espresso.onView(ViewMatchers.withText(R.string.label_shape)).perform(ViewActions.click())
assertEquals(editImageActivity.mPhotoEditor?.brushDrawableMode ,true)
assertEquals(editImageActivity.mPhotoEditor.brushDrawableMode,true)
}

@Test
Expand All @@ -67,7 +65,7 @@ class EditImageActivityTest {

@Test
fun checkIfShapeIsEnabledWhenClickedOnBrushTool() {
val editImageActivity = mActivityRule.launchActivity(null)
mActivityRule.launchActivity(null)
Espresso.onView(ViewMatchers.withText(R.string.label_shape)).perform(ViewActions.click())
Espresso.onView(ViewMatchers.withText(R.string.label_shape)).check(
ViewAssertions.matches(
Expand Down Expand Up @@ -108,15 +106,15 @@ class EditImageActivityTest {
@Ignore("Flacky test. Need to optimize")
fun checkIfDiscardDialogIsNotDisplayedWhenCacheIsEmpty() {
val editImageActivity = mActivityRule.launchActivity(null)
TestCase.assertTrue(editImageActivity.mPhotoEditor!!.isCacheEmpty)
assertTrue(editImageActivity.mPhotoEditor.isCacheEmpty)
Espresso.onView(ViewMatchers.withId(R.id.imgClose)).perform(ViewActions.click())
TestCase.assertTrue(editImageActivity.isDestroyed)
assertTrue(editImageActivity.isDestroyed)
}

@Test
fun checkIfDiscardDialogIsDisplayedWhenCacheIsNotEmpty() {
val editImageActivity = mActivityRule.launchActivity(null)
TestCase.assertTrue(editImageActivity.mPhotoEditor!!.isCacheEmpty)
assertTrue(editImageActivity.mPhotoEditor.isCacheEmpty)
Espresso.onView(ViewMatchers.withId(R.id.rvConstraintTools))
.perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
Expand Down Expand Up @@ -388,7 +386,7 @@ class EditImageActivityTest {
// Assert that the second emoji is selected (frame background is not null)
Espresso.onView(withIndex(ViewMatchers.withId(ja.burhanrashid52.photoeditor.R.id.frmBorder), 1))
.check { view: View, noViewFoundException: NoMatchingViewException? ->
TestCase.assertNotNull(
assertNotNull(
null,
view.background
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ class EditImageActivity : BaseActivity(), OnPhotoEditorListener, View.OnClickLis
// NOTE(lucianocheng): Used to set integration testing parameters to PhotoEditor
val pinchTextScalable = intent.getBooleanExtra(PINCH_TEXT_SCALABLE_INTENT_KEY, true)

//Typeface mTextRobotoTf = ResourcesCompat.getFont(this, R.font.roboto_medium);
//Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf");
// val mTextRobotoTf = ResourcesCompat.getFont(this, R.font.roboto_medium)
// val mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf")

mPhotoEditor = PhotoEditor.Builder(this, mPhotoEditorView)
.setPinchTextScalable(pinchTextScalable) // set flag to make text scalable when pinch
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.burhanrashid52.photoediting

import android.app.Application
import android.content.Context

/**
* Created by Burhanuddin Rashid on 1/23/2018.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class PropertiesBSFragment : BottomSheetDialogFragment(), SeekBar.OnSeekBarChang
}
}

override fun onStartTrackingTouch(seekBar: SeekBar) {}
override fun onStopTrackingTouch(seekBar: SeekBar) {}
override fun onStartTrackingTouch(seekBar: SeekBar) = Unit

override fun onStopTrackingTouch(seekBar: SeekBar) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class ShapeBSFragment : BottomSheetDialogFragment(), SeekBar.OnSeekBarChangeList
}
}

override fun onStartTrackingTouch(seekBar: SeekBar) {}
override fun onStopTrackingTouch(seekBar: SeekBar) {}
override fun onStartTrackingTouch(seekBar: SeekBar) = Unit

override fun onStopTrackingTouch(seekBar: SeekBar) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,20 @@ package com.burhanrashid52.photoediting
import android.annotation.SuppressLint
import android.app.Dialog
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
import com.google.android.material.bottomsheet.BottomSheetBehavior
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

class StickerBSFragment : BottomSheetDialogFragment() {
private var mStickerListener: StickerListener? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import android.view.WindowManager
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.material.snackbar.Snackbar

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package com.burhanrashid52.photoediting.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class DrawingView @JvmOverloads constructor(
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)

// apply shape builder parameters
currentShapeBuilder?.apply {
currentShapeBuilder.apply {
paint.strokeWidth = this.shapeSize
// 'paint.color' must be called before 'paint.alpha',
// otherwise 'paint.alpha' value will be overwritten.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ internal class MultiTouchListener(
private val deleteView: View?
private val photoEditImageView: ImageView?
private val photoEditorView: PhotoEditorView
private var onMultiTouchListener: OnMultiTouchListener? = null
private var mOnGestureControl: OnGestureControl? = null
private val mOnPhotoEditorListener: OnPhotoEditorListener?
private val viewState: PhotoEditorViewState

override fun onTouch(view: View, event: MotionEvent): Boolean {
mScaleGestureDetector.onTouchEvent(view, event)
mGestureListener.onTouchEvent(event)
Expand Down Expand Up @@ -83,9 +83,7 @@ internal class MultiTouchListener(
MotionEvent.ACTION_CANCEL -> mActivePointerId = INVALID_POINTER_ID
MotionEvent.ACTION_UP -> {
mActivePointerId = INVALID_POINTER_ID
if (deleteView != null && isViewInBounds(deleteView, x, y)) {
onMultiTouchListener?.onRemoveViewListener(view)
} else if (!isViewInBounds(photoEditImageView, x, y)) {
if (!isViewInBounds(photoEditImageView, x, y)) {
view.animate().translationY(0f).translationY(0f)
}
if (deleteView != null) {
Expand Down Expand Up @@ -126,10 +124,6 @@ internal class MultiTouchListener(
} ?: false
}

fun setOnMultiTouchListener(onMultiTouchListener: OnMultiTouchListener?) {
this.onMultiTouchListener = onMultiTouchListener
burhanrashid52 marked this conversation as resolved.
Show resolved Hide resolved
}

private inner class ScaleGestureListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
private var mPivotX = 0f
private var mPivotY = 0f
Expand Down Expand Up @@ -171,11 +165,6 @@ internal class MultiTouchListener(
var maximumScale = 0f
}

internal interface OnMultiTouchListener {
fun onEditTextClickListener(text: String, colorCode: Int)
fun onRemoveViewListener(removedView: View)
}

internal interface OnGestureControl {
fun onClick()
fun onLongClick()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ internal class PhotoEditorImpl @SuppressLint("ClickableViewAccessibility") const
}

override fun addText(text: String, styleBuilder: TextStyleBuilder?) {
drawingView?.enableDrawing(false)
drawingView.enableDrawing(false)
val multiTouchListener = getMultiTouchListener(isTextPinchScalable)
val textGraphic = Text(
photoEditorView,
Expand Down Expand Up @@ -112,7 +112,7 @@ internal class PhotoEditorImpl @SuppressLint("ClickableViewAccessibility") const
}

override fun addEmoji(emojiTypeface: Typeface?, emojiName: String) {
drawingView?.enableDrawing(false)
drawingView.enableDrawing(false)
val multiTouchListener = getMultiTouchListener(true)
val emoji = Emoji(
photoEditorView,
Expand Down Expand Up @@ -150,7 +150,7 @@ internal class PhotoEditorImpl @SuppressLint("ClickableViewAccessibility") const
}

override fun setBrushDrawingMode(brushDrawingMode: Boolean) {
drawingView?.enableDrawing(brushDrawingMode)
drawingView.enableDrawing(brushDrawingMode)
}

override val brushDrawableMode: Boolean
Expand All @@ -159,29 +159,29 @@ internal class PhotoEditorImpl @SuppressLint("ClickableViewAccessibility") const
override fun setOpacity(@IntRange(from = 0, to = 100) opacity: Int) {
var opacityValue = opacity
opacityValue = (opacityValue / 100.0 * 255.0).toInt()
drawingView?.currentShapeBuilder?.withShapeOpacity(opacityValue)
drawingView.currentShapeBuilder.withShapeOpacity(opacityValue)
}

override var brushSize: Float
get() = drawingView?.currentShapeBuilder?.shapeSize ?: 0f
get() = drawingView.currentShapeBuilder.shapeSize
set(size) {
drawingView?.currentShapeBuilder?.withShapeSize(size)
drawingView.currentShapeBuilder.withShapeSize(size)
}
override var brushColor: Int
get() = drawingView?.currentShapeBuilder?.shapeColor ?: 0
get() = drawingView.currentShapeBuilder.shapeColor
set(color) {
drawingView?.currentShapeBuilder?.withShapeColor(color)
drawingView.currentShapeBuilder.withShapeColor(color)
}

override fun setBrushEraserSize(brushEraserSize: Float) {
drawingView?.eraserSize = brushEraserSize
drawingView.eraserSize = brushEraserSize
}

override val eraserSize: Float
get() = drawingView?.eraserSize ?: 0f
get() = drawingView.eraserSize

override fun brushEraser() {
drawingView?.brushEraser()
drawingView.brushEraser()
}

override fun undo(): Boolean {
Expand Down Expand Up @@ -267,15 +267,11 @@ internal class PhotoEditorImpl @SuppressLint("ClickableViewAccessibility") const

// region Shape
override fun setShape(shapeBuilder: ShapeBuilder) {
drawingView?.currentShapeBuilder = shapeBuilder
drawingView.currentShapeBuilder = shapeBuilder
} // endregion

companion object {
private const val TAG = "PhotoEditor"
}

init {
drawingView?.setBrushViewChangeListener(mBrushDrawingStateListener)
drawingView.setBrushViewChangeListener(mBrushDrawingStateListener)
val mDetector = GestureDetector(
context,
PhotoEditorImageViewListener(
Expand All @@ -287,7 +283,7 @@ internal class PhotoEditorImpl @SuppressLint("ClickableViewAccessibility") const
}
)
)
imageView?.setOnTouchListener { _, event ->
imageView.setOnTouchListener { _, event ->
mOnPhotoEditorListener?.onTouchSourceImage(event)
mDetector.onTouchEvent(event)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,4 @@ internal class PhotoSaverTask(
return bitmap
}

companion object {
const val TAG = "PhotoSaverTask"
}

}
Loading
Loading