Skip to content

Commit b7a2670

Browse files
committed
Use ShapeSpec in shape implementations of "tool-draw" (BrushShape, LineShape, OvalShape, RectangleShape)
1 parent 06aad24 commit b7a2670

10 files changed

Lines changed: 100 additions & 214 deletions

File tree

quickedit-core-engine/src/main/java/io/github/abizerr/quickedit/engine/drawspec/ShapeSpec.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,29 @@ package io.github.abizerr.quickedit.engine.drawspec
33
import androidx.annotation.FloatRange
44

55
sealed interface ShapeSpec {
6+
7+
companion object {
8+
val defaultOffset = Pair(Float.NaN, Float.NaN)
9+
}
610
val argb: Int
711
val alpha: Float // 0f..1f
812
val widthPx: Float
913
val isEraser: Boolean get() = false
1014

1115
data class Brush(
12-
val points: List<Pair<Float, Float>>,
16+
val points: MutableList<Pair<Float, Float>> = mutableListOf(),
1317
override val argb: Int,
14-
override val alpha: Float,
18+
@FloatRange(from = 0.0, to = 1.0) override val alpha: Float,
1519
override val widthPx: Float,
1620
override val isEraser: Boolean = false
1721
) : ShapeSpec
1822

1923
data class Shape(
2024
val shapeType: ShapeType,
21-
val startOffset: Pair<Float, Float>,
22-
val endOffset: Pair<Float, Float>,
25+
var startOffset: Pair<Float, Float> = defaultOffset,
26+
var endOffset: Pair<Float, Float> = defaultOffset,
2327
override val argb: Int,
24-
override val alpha: Float,
28+
@FloatRange(from = 0.0, to = 1.0) override val alpha: Float,
2529
override val widthPx: Float,
2630
) : ShapeSpec
2731
}

quickedit-tool-draw/src/main/java/io/github/abizerr/quickedit/tool/draw/models/DrawToolItem.kt

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package io.github.abizerr.quickedit.tool.draw.models
22

33
import androidx.compose.ui.graphics.Color
4-
import io.github.abizerr.quickedit.tool.draw.models.shapes.AbstractShape
4+
import androidx.compose.ui.graphics.toArgb
5+
import io.github.abizerr.quickedit.engine.drawspec.ShapeSpec
6+
import io.github.abizerr.quickedit.engine.drawspec.ShapeType
7+
import io.github.abizerr.quickedit.tool.draw.models.shapes.BaseShape
58
import io.github.abizerr.quickedit.tool.draw.models.shapes.BrushShape
69
import io.github.abizerr.quickedit.tool.draw.models.shapes.LineShape
710
import io.github.abizerr.quickedit.tool.draw.models.shapes.OvalShape
811
import io.github.abizerr.quickedit.tool.draw.models.shapes.RectangleShape
9-
import io.github.abizerr.quickedit.engine.drawspec.ShapeType
10-
import io.github.abizerr.quickedit.tool.draw.util.DrawingConstants
1112

1213
sealed class DrawToolItem {
1314
object NONE: DrawToolItem()
@@ -22,48 +23,59 @@ sealed class DrawToolItem {
2223
fun DrawToolItem.getShape(
2324
selectedColor: Color,
2425
scale: Float = 1f,
25-
): AbstractShape {
26+
): BaseShape? {
2627
return when (val toolbarItem = this) {
2728
is DrawToolItem.BrushTool -> {
2829
BrushShape(
29-
color = selectedColor,
30-
width = toolbarItem.width / scale,
31-
alpha = toolbarItem.opacity / 100f
30+
shapeSpec = ShapeSpec.Brush(
31+
argb = selectedColor.toArgb(),
32+
widthPx = toolbarItem.width / scale,
33+
alpha = toolbarItem.opacity / 100f
34+
)
35+
)
36+
}
37+
38+
is DrawToolItem.EraserTool -> {
39+
BrushShape(
40+
shapeSpec = ShapeSpec.Brush(
41+
argb = selectedColor.toArgb(),
42+
widthPx = toolbarItem.width / scale,
43+
alpha = 1f,
44+
isEraser = true
45+
)
3246
)
3347
}
3448

3549
is DrawToolItem.ShapeTool -> when (toolbarItem.shapeType) {
3650
ShapeType.LINE -> LineShape(
37-
color = selectedColor,
38-
width = toolbarItem.width / scale,
39-
alpha = toolbarItem.opacity / 100f
51+
shapeSpec = ShapeSpec.Shape(
52+
shapeType = ShapeType.LINE,
53+
argb = selectedColor.toArgb(),
54+
widthPx = toolbarItem.width / scale,
55+
alpha = toolbarItem.opacity / 100f
56+
)
4057
)
4158

4259
ShapeType.OVAL -> OvalShape(
43-
color = selectedColor,
44-
width = toolbarItem.width / scale,
45-
alpha = toolbarItem.opacity / 100f
60+
shapeSpec = ShapeSpec.Shape(
61+
shapeType = ShapeType.OVAL,
62+
argb = selectedColor.toArgb(),
63+
widthPx = toolbarItem.width / scale,
64+
alpha = toolbarItem.opacity / 100f
65+
)
4666
)
4767

4868
ShapeType.RECTANGLE -> RectangleShape(
49-
color = selectedColor,
50-
width = toolbarItem.width / scale,
51-
alpha = toolbarItem.opacity / 100f
69+
shapeSpec = ShapeSpec.Shape(
70+
shapeType = ShapeType.RECTANGLE,
71+
argb = selectedColor.toArgb(),
72+
widthPx = toolbarItem.width / scale,
73+
alpha = toolbarItem.opacity / 100f
74+
)
5275
)
5376
}
5477

55-
else -> {
56-
/**
57-
* this else block represents the EraserTool, as any other item (ColorItem, PanItem) won't be sent here
58-
*/
59-
val width =
60-
if (toolbarItem is DrawToolItem.EraserTool) toolbarItem.width
61-
else DrawingConstants.DEFAULT_STROKE_WIDTH
62-
BrushShape(
63-
isEraser = true,
64-
width = width / scale
65-
)
66-
}
78+
else -> null
6779
}
6880
}
6981

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package io.github.abizerr.quickedit.tool.draw.models
22

3-
import io.github.abizerr.quickedit.tool.draw.models.shapes.AbstractShape
3+
import io.github.abizerr.quickedit.tool.draw.models.shapes.BaseShape
44

55
data class PathDetails(
6-
val drawingShape: AbstractShape,
6+
val drawingShape: BaseShape,
77
)
Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
package io.github.abizerr.quickedit.tool.draw.models.shapes
22

33
import androidx.compose.ui.graphics.Color
4+
import io.github.abizerr.quickedit.engine.drawspec.ShapeSpec
45
import io.github.abizerr.quickedit.tool.draw.util.DrawingConstants
56

67
abstract class AbstractShape: BaseShape {
7-
var mColor: Color = Color.White
8-
var mWidth: Float = DrawingConstants.DEFAULT_STROKE_WIDTH
9-
var mAlpha: Float = DrawingConstants.DEFAULT_STROKE_ALPHA
8+
abstract var shapeSpec: ShapeSpec
9+
// var mColor: Color = Color.White
10+
// var mWidth: Float = DrawingConstants.DEFAULT_STROKE_WIDTH
11+
// var mAlpha: Float = DrawingConstants.DEFAULT_STROKE_ALPHA
1012

11-
fun updatePaintValues(
12-
color: Color? = null,
13-
width: Float? = null,
14-
alpha: Float? = null
15-
) {
16-
color?.let { mColor = it }
17-
width?.let { mWidth = it }
18-
alpha?.let { mAlpha = it }
19-
}
2013
}

quickedit-tool-draw/src/main/java/io/github/abizerr/quickedit/tool/draw/models/shapes/BrushShape.kt

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,27 @@ package io.github.abizerr.quickedit.tool.draw.models.shapes
22

33
import android.graphics.Canvas
44
import android.graphics.Paint
5-
import androidx.compose.ui.geometry.Offset
6-
import androidx.compose.ui.graphics.BlendMode
7-
import androidx.compose.ui.graphics.Color
8-
import androidx.compose.ui.graphics.Path
9-
import androidx.compose.ui.graphics.SolidColor
10-
import androidx.compose.ui.graphics.StrokeCap
11-
import androidx.compose.ui.graphics.StrokeJoin
12-
import androidx.compose.ui.graphics.drawscope.DrawScope
13-
import androidx.compose.ui.graphics.drawscope.Stroke
14-
import androidx.compose.ui.graphics.toArgb
15-
import io.github.abizerr.quickedit.engine.drawspec.PaintSpec
165
import io.github.abizerr.quickedit.engine.drawspec.ShapeSpec
176
import io.github.abizerr.quickedit.engine.drawspec.toPaintSpec
187
import io.github.abizerr.quickedit.engine.util.applySpec
198
import io.github.abizerr.quickedit.engine.util.drawOn
209

2110
class BrushShape(
22-
private val isEraser: Boolean = false,
23-
color: Color? = null,
24-
width: Float? = null,
25-
alpha: Float? = null
26-
): AbstractShape() {
27-
28-
init {
29-
updatePaintValues(color, width, alpha)
30-
}
31-
32-
private var path = Path()
33-
private var prevOffSet = Offset.Zero
34-
35-
private val points = arrayListOf<Pair<Float, Float>>()
11+
private val shapeSpec: ShapeSpec.Brush
12+
): BaseShape {
3613

3714
override fun drawOnAndroidCanvas(canvas: Canvas) {
38-
val shapeSpec = ShapeSpec.Brush(
39-
points = points,
40-
argb = mColor.toArgb(),
41-
alpha = mAlpha,
42-
widthPx = mWidth,
43-
isEraser = isEraser
44-
)
4515
val paintSpec = shapeSpec.toPaintSpec()
4616
val paint = Paint().applySpec(paintSpec)
4717
shapeSpec.drawOn(canvas, paint)
4818
}
4919

5020
override fun initShape(startX: Float, startY: Float) {
51-
path = Path()
52-
path.moveTo(startX, startY)
53-
prevOffSet = Offset(startX, startY)
54-
points.add(Pair(startX, startY))
21+
shapeSpec.points.add(Pair(startX, startY))
5522
}
5623

5724
override fun moveShape(endX: Float, endY: Float) {
58-
/**
59-
* Following this answer for SO:
60-
* https://stackoverflow.com/a/71090112/23198795
61-
*/
62-
path.quadraticBezierTo(
63-
x1 = prevOffSet.x,
64-
y1 = prevOffSet.y,
65-
x2 = (prevOffSet.x + endX) / 2,
66-
y2 = (prevOffSet.y + endY) / 2,
67-
)
68-
prevOffSet = Offset(endX, endY)
69-
points.add(Pair(endX, endY))
25+
shapeSpec.points.add(Pair(endX, endY))
7026
}
7127

7228
override fun shouldDraw(): Boolean {

quickedit-tool-draw/src/main/java/io/github/abizerr/quickedit/tool/draw/models/shapes/LineShape.kt

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,31 @@ package io.github.abizerr.quickedit.tool.draw.models.shapes
22

33
import android.graphics.Canvas
44
import android.graphics.Paint
5-
import androidx.compose.ui.geometry.Offset
6-
import androidx.compose.ui.graphics.Color
7-
import androidx.compose.ui.graphics.SolidColor
8-
import androidx.compose.ui.graphics.StrokeCap
9-
import androidx.compose.ui.graphics.drawscope.DrawScope
10-
import androidx.compose.ui.graphics.toArgb
115
import io.github.abizerr.quickedit.engine.drawspec.ShapeSpec
12-
import io.github.abizerr.quickedit.engine.drawspec.ShapeType
136
import io.github.abizerr.quickedit.engine.drawspec.toPaintSpec
147
import io.github.abizerr.quickedit.engine.util.applySpec
158
import io.github.abizerr.quickedit.engine.util.drawOn
169

1710
class LineShape(
18-
color: Color? = null,
19-
width: Float? = null,
20-
alpha: Float? = null
21-
) : AbstractShape() {
22-
23-
init {
24-
updatePaintValues(color, width, alpha)
25-
}
26-
27-
private var startOffset: Offset = Offset.Unspecified
28-
private var endOffset: Offset = Offset.Unspecified
11+
private val shapeSpec: ShapeSpec.Shape
12+
) : BaseShape {
2913

3014
override fun drawOnAndroidCanvas(canvas: Canvas) {
31-
val shapeSpec = ShapeSpec.Shape(
32-
shapeType = ShapeType.LINE,
33-
startOffset = Pair(startOffset.x, startOffset.y),
34-
endOffset = Pair(endOffset.x, endOffset.y),
35-
argb = mColor.toArgb(),
36-
alpha = mAlpha,
37-
widthPx = mWidth,
38-
39-
)
4015
val paintSpec = shapeSpec.toPaintSpec()
4116
val paint = Paint().applySpec(paintSpec)
4217
shapeSpec.drawOn(canvas, paint)
4318
}
4419

4520
override fun initShape(startX: Float, startY: Float) {
46-
startOffset = Offset(startX, startY)
21+
shapeSpec.startOffset = Pair(startX, startY)
4722
}
4823

4924
override fun moveShape(endX: Float, endY: Float) {
50-
endOffset = Offset(endX, endY)
25+
shapeSpec.endOffset = Pair(endX, endY)
5126
}
5227

5328
override fun shouldDraw(): Boolean {
54-
return startOffset != Offset.Unspecified && endOffset != Offset.Unspecified
29+
return shapeSpec.startOffset != ShapeSpec.defaultOffset
30+
&& shapeSpec.endOffset != ShapeSpec.defaultOffset
5531
}
5632
}

quickedit-tool-draw/src/main/java/io/github/abizerr/quickedit/tool/draw/models/shapes/OvalShape.kt

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,31 @@ package io.github.abizerr.quickedit.tool.draw.models.shapes
22

33
import android.graphics.Canvas
44
import android.graphics.Paint
5-
import androidx.compose.ui.geometry.Offset
6-
import androidx.compose.ui.geometry.Size
7-
import androidx.compose.ui.graphics.Color
8-
import androidx.compose.ui.graphics.SolidColor
9-
import androidx.compose.ui.graphics.StrokeCap
10-
import androidx.compose.ui.graphics.StrokeJoin
11-
import androidx.compose.ui.graphics.drawscope.DrawScope
12-
import androidx.compose.ui.graphics.drawscope.Stroke
13-
import androidx.compose.ui.graphics.toArgb
145
import io.github.abizerr.quickedit.engine.drawspec.ShapeSpec
15-
import io.github.abizerr.quickedit.engine.drawspec.ShapeType
166
import io.github.abizerr.quickedit.engine.drawspec.toPaintSpec
177
import io.github.abizerr.quickedit.engine.util.applySpec
188
import io.github.abizerr.quickedit.engine.util.drawOn
199

2010
class OvalShape(
21-
color: Color? = null,
22-
width: Float? = null,
23-
alpha: Float? = null
24-
) : AbstractShape() {
25-
26-
init {
27-
updatePaintValues(color, width, alpha)
28-
}
29-
30-
private var startOffset: Offset = Offset.Unspecified
31-
private var endOffset: Offset = Offset.Unspecified
11+
private val shapeSpec: ShapeSpec.Shape
12+
) : BaseShape {
3213

3314
override fun drawOnAndroidCanvas(canvas: Canvas) {
34-
val shapeSpec = ShapeSpec.Shape(
35-
shapeType = ShapeType.OVAL,
36-
startOffset = Pair(startOffset.x, startOffset.y),
37-
endOffset = Pair(endOffset.x, endOffset.y),
38-
argb = mColor.toArgb(),
39-
alpha = mAlpha,
40-
widthPx = mWidth,
41-
)
4215
val paintSpec = shapeSpec.toPaintSpec()
4316
val paint = Paint().applySpec(paintSpec)
4417
shapeSpec.drawOn(canvas, paint)
4518
}
4619

4720
override fun initShape(startX: Float, startY: Float) {
48-
startOffset = Offset(startX, startY)
21+
shapeSpec.startOffset = Pair(startX, startY)
4922
}
5023

5124
override fun moveShape(endX: Float, endY: Float) {
52-
endOffset = Offset(endX, endY)
25+
shapeSpec.endOffset = Pair(endX, endY)
5326
}
5427

5528
override fun shouldDraw(): Boolean {
56-
return startOffset != Offset.Unspecified && endOffset != Offset.Unspecified
29+
return shapeSpec.startOffset != ShapeSpec.defaultOffset
30+
&& shapeSpec.endOffset != ShapeSpec.defaultOffset
5731
}
5832
}

0 commit comments

Comments
 (0)