Skip to content

Commit

Permalink
Merge pull request #492 from wasky/PE-491
Browse files Browse the repository at this point in the history
Add arrow shape
  • Loading branch information
burhanrashid52 authored Jan 17, 2023
2 parents b781103 + 20c91e2 commit fed472b
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,19 @@ class ShapeBSFragment : BottomSheetDialogFragment(), SeekBar.OnSeekBarChangeList
shapeGroup.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
when (checkedId) {
R.id.lineRadioButton -> {
mProperties!!.onShapePicked(ShapeType.LINE)
mProperties!!.onShapePicked(ShapeType.Line)
}
R.id.arrowRadioButton -> {
mProperties!!.onShapePicked(ShapeType.Arrow())
}
R.id.ovalRadioButton -> {
mProperties!!.onShapePicked(ShapeType.OVAL)
mProperties!!.onShapePicked(ShapeType.Oval)
}
R.id.rectRadioButton -> {
mProperties!!.onShapePicked(ShapeType.RECTANGLE)
mProperties!!.onShapePicked(ShapeType.Rectangle)
}
else -> {
mProperties!!.onShapePicked(ShapeType.BRUSH)
mProperties!!.onShapePicked(ShapeType.Brush)
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/layout/fragment_bottom_shapes_dialog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
android:layout_height="wrap_content"
android:text="@string/label_line" />

<RadioButton
android:id="@+id/arrowRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_arrow" />

<RadioButton
android:id="@+id/ovalRadioButton"
android:layout_width="wrap_content"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="label_oval">Ovale</string>
<string name="label_rectangle">Rectangle</string>
<string name="label_line">Ligne</string>
<string name="label_arrow">Flèche</string>
<string name="label_emoji">Frimousses</string>
<string name="label_sticker">Autocollant</string>
<string name="label_eraser">Gomme</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="label_oval">Oval</string>
<string name="label_rectangle">Rectangle</string>
<string name="label_line">Line</string>
<string name="label_arrow">Arrow</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,21 @@ class DrawingView @JvmOverloads constructor(
if (isErasing) {
paint = createEraserPaint()
} else {
shape = when (currentShapeBuilder.shapeType){
ShapeType.OVAL -> {
OvalShape()
when (val shapeType = currentShapeBuilder.shapeType) {
ShapeType.Oval -> {
shape = OvalShape()
}
ShapeType.BRUSH -> {
BrushShape()
ShapeType.Brush -> {
shape = BrushShape()
}
ShapeType.RECTANGLE -> {
RectangleShape()
ShapeType.Rectangle -> {
shape = RectangleShape()
}
ShapeType.LINE -> {
LineShape()
ShapeType.Line -> {
shape = LineShape(context)
}
is ShapeType.Arrow -> {
shape = LineShape(context, shapeType.pointerLocation)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ja.burhanrashid52.photoeditor.shape

enum class ArrowPointerLocation { START, END, BOTH }
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
package ja.burhanrashid52.photoeditor.shape

import android.content.Context
import android.graphics.Path
import android.util.Log
import kotlin.math.PI
import kotlin.math.abs
import kotlin.math.atan2
import kotlin.math.cos
import kotlin.math.hypot
import kotlin.math.sin

class LineShape(
context: Context,
private val pointerLocation: ArrowPointerLocation? = null
) : AbstractShape("LineShape") {

private val maxArrowRadius = convertDpsToPixels(context, MAX_ARROW_RADIUS_DP).toFloat()

class LineShape : AbstractShape("LineShape") {
private var lastX = 0f
private var lastY = 0f

Expand All @@ -28,13 +40,64 @@ class LineShape : AbstractShape("LineShape") {

private fun createLinePath(): Path {
val path = Path()

if (pointerLocation == ArrowPointerLocation.BOTH || pointerLocation == ArrowPointerLocation.START) {
drawArrow(path, right, bottom, left, top)
}

if (pointerLocation == ArrowPointerLocation.BOTH || pointerLocation == ArrowPointerLocation.END) {
drawArrow(path, left, top, right, bottom)
}

path.moveTo(left, top)
path.lineTo(right, bottom)
path.close()

return path
}

private fun drawArrow(path: Path, fromX: Float, fromY: Float, toX: Float, toY: Float) {
// Based on: https://stackoverflow.com/a/41734848/1219654

val xDistance = toX - fromX
val yDistance = toY - fromY

val lineAngle = atan2(yDistance, xDistance)
val arrowRadius = (hypot(xDistance, yDistance) / 2.5f).coerceAtMost(maxArrowRadius)

val anglePointerA = lineAngle - ANGLE_RAD
val anglePointerB = lineAngle + ANGLE_RAD

path.moveTo(toX, toY)
path.lineTo(
(toX - arrowRadius * cos(anglePointerA)),
(toY - arrowRadius * sin(anglePointerA))
)

path.moveTo(toX, toY)
path.lineTo(
(toX - arrowRadius * cos(anglePointerB)),
(toY - arrowRadius * sin(anglePointerB))
)
}

override fun stopShape() {
Log.d(tag, "stopShape")
}

private companion object {

const val ARROW_ANGLE = 30.0
const val ANGLE_RAD = (PI * ARROW_ANGLE / 180.0).toFloat()
const val MAX_ARROW_RADIUS_DP = 32.0f

fun convertDpsToPixels(context: Context, sizeDp: Float): Int {
// Convert the dps to pixels
val scale = context.resources.displayMetrics.density
// Use sizePx as a size in pixels
return (sizeDp * scale + 0.5f).toInt()
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import androidx.annotation.ColorInt
*/
class ShapeBuilder {

var shapeType: ShapeType = ShapeType.BRUSH
var shapeType: ShapeType = ShapeType.Brush
private set

var shapeSize: Float = DEFAULT_SHAPE_SIZE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package ja.burhanrashid52.photoeditor.shape
/**
* The different kind of known Shapes.
*/
enum class ShapeType {
BRUSH,
OVAL,
RECTANGLE,
LINE
sealed interface ShapeType {

object Brush : ShapeType
object Oval : ShapeType
object Rectangle : ShapeType
object Line : ShapeType
class Arrow(val pointerLocation: ArrowPointerLocation = ArrowPointerLocation.START) : ShapeType

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ class EnumTest {
assertEquals(ViewType.values().size.toLong(), 4)
}

@Test
fun testNumberOfShapeTypes() {
assertEquals(ShapeType.values().size.toLong(), 4)
}

@Test
fun testNumberOfPhotoFilterTypes() {
assertEquals(PhotoFilter.values().size.toLong(), 24)
Expand Down

0 comments on commit fed472b

Please sign in to comment.