diff --git a/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/DrawScreen.kt b/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/DrawScreen.kt
index 9d1257a643..bb569872e2 100644
--- a/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/DrawScreen.kt
+++ b/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/DrawScreen.kt
@@ -82,6 +82,7 @@ import dev.olshevski.navigation.reimagined.hilt.hiltViewModel
import kotlinx.coroutines.launch
import ru.tech.imageresizershrinker.presentation.draw_screen.components.BlurRadiusSelector
import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawAlphaSelector
+import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawArrowsSelector
import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawBackgroundSelector
import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawBehavior
import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawColorSelector
@@ -295,6 +296,9 @@ fun DrawScreen(
var blurRadius by rememberSaveable(viewModel.drawBehavior, drawMode) {
mutableFloatStateOf(if (drawMode is DrawMode.Neon) 35f else 0f)
}
+ var drawArrowsEnabled by remember(viewModel.drawBehavior) {
+ mutableStateOf(false)
+ }
val controls = @Composable {
OpenColorPickerCard(
@@ -349,6 +353,17 @@ fun DrawScreen(
drawMode = drawMode,
onDrawModeChange = { drawMode = it }
)
+ AnimatedVisibility(!isEraserOn) {
+ DrawArrowsSelector(
+ modifier = Modifier.padding(
+ start = 16.dp,
+ end = 16.dp,
+ bottom = 16.dp
+ ),
+ checked = drawArrowsEnabled,
+ onCheckedChange = { drawArrowsEnabled = it }
+ )
+ }
SaveExifWidget(
modifier = Modifier.padding(horizontal = 16.dp),
selected = viewModel.saveExif,
@@ -434,6 +449,7 @@ fun DrawScreen(
onShare = { viewModel.shareBitmap { showConfetti() } },
paths = viewModel.paths,
isEraserOn = isEraserOn,
+ drawArrowsEnabled = drawArrowsEnabled,
drawMode = drawMode,
backgroundColor = backgroundColor,
drawColor = drawColor.copy(alpha),
diff --git a/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/BitmapDrawer.kt b/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/BitmapDrawer.kt
index 8beb78894b..dc0e755944 100644
--- a/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/BitmapDrawer.kt
+++ b/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/BitmapDrawer.kt
@@ -31,6 +31,7 @@ import androidx.compose.ui.graphics.ImageShader
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.PaintingStyle
import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.PathMeasure
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.asAndroidBitmap
@@ -53,6 +54,8 @@ import ru.tech.imageresizershrinker.presentation.erase_background_screen.compone
import ru.tech.imageresizershrinker.presentation.erase_background_screen.components.transparencyChecker
import ru.tech.imageresizershrinker.presentation.root.theme.outlineVariant
import ru.tech.imageresizershrinker.presentation.root.transformation.filter.StackBlurFilter
+import kotlin.math.cos
+import kotlin.math.sin
@Composable
@@ -66,6 +69,7 @@ fun BitmapDrawer(
isEraserOn: Boolean,
drawMode: DrawMode,
modifier: Modifier,
+ drawArrowsEnabled: Boolean,
onDraw: (Bitmap) -> Unit,
backgroundColor: Color,
zoomEnabled: Boolean,
@@ -128,7 +132,7 @@ fun BitmapDrawer(
LaunchedEffect(imageBitmap, drawBitmap) {
blurredBitmap = imageManager.transform(
image = drawImageBitmap.overlay(drawBitmap).asAndroidBitmap(),
- transformations = listOf(StackBlurFilter(context, 0.3f to 50))
+ transformations = listOf(StackBlurFilter(context, 0.3f to 20))
)?.asImageBitmap()
}
@@ -204,6 +208,35 @@ fun BitmapDrawer(
MotionEvent.Up -> {
drawPath.lineTo(currentPosition.x, currentPosition.y)
+
+ if (drawArrowsEnabled && !isEraserOn) {
+ val preLastPoint = PathMeasure().apply {
+ setPath(drawPath, false)
+ }.let {
+ it.getPosition(it.length - strokeWidth * 3f)
+ }
+ val lastPoint = currentPosition
+
+ val (x, y) = lastPoint - preLastPoint
+
+
+ val angle1 = 150.0
+ val rotatedX1 =
+ x * cos(Math.toRadians(angle1)) - y * sin(Math.toRadians(angle1))
+ val rotatedY1 =
+ x * sin(Math.toRadians(angle1)) + y * cos(Math.toRadians(angle1))
+
+ val angle2 = 210.0
+ val rotatedX2 =
+ x * cos(Math.toRadians(angle2)) - y * sin(Math.toRadians(angle2))
+ val rotatedY2 =
+ x * sin(Math.toRadians(angle2)) + y * cos(Math.toRadians(angle2))
+
+ drawPath.relativeLineTo(rotatedX1.toFloat(), rotatedY1.toFloat())
+ drawPath.moveTo(lastPoint.x, lastPoint.y)
+ drawPath.relativeLineTo(rotatedX2.toFloat(), rotatedY2.toFloat())
+ }
+
currentPosition = Offset.Unspecified
previousPosition = currentPosition
motionEvent = MotionEvent.Idle
diff --git a/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/DrawArrowsSelector.kt b/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/DrawArrowsSelector.kt
new file mode 100644
index 0000000000..796ae41376
--- /dev/null
+++ b/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/DrawArrowsSelector.kt
@@ -0,0 +1,61 @@
+package ru.tech.imageresizershrinker.presentation.draw_screen.components
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.defaultMinSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.rounded.ArrowCircleUp
+import androidx.compose.material3.Icon
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.Switch
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import ru.tech.imageresizershrinker.R
+import ru.tech.imageresizershrinker.presentation.root.utils.modifier.container
+
+@Composable
+fun DrawArrowsSelector(
+ modifier: Modifier,
+ checked: Boolean,
+ onCheckedChange: (Boolean) -> Unit
+) {
+ Row(
+ modifier = modifier
+ .container(shape = RoundedCornerShape(24.dp), resultPadding = 0.dp)
+ .clickable { onCheckedChange(!checked) }
+ .padding(horizontal = 16.dp, vertical = 8.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(Icons.Rounded.ArrowCircleUp, null, modifier = Modifier.defaultMinSize(24.dp, 24.dp))
+ Column(
+ modifier = Modifier
+ .weight(1f)
+ .padding(start = 16.dp, end = 16.dp, top = 6.dp, bottom = 8.dp)
+ ) {
+ Text(
+ text = stringResource(R.string.draw_arrows),
+ fontWeight = FontWeight.Medium
+ )
+ Text(
+ text = stringResource(R.string.draw_arrows_sub),
+ fontWeight = FontWeight.Normal,
+ color = LocalContentColor.current.copy(0.5f),
+ lineHeight = 12.sp,
+ fontSize = 12.sp
+ )
+ }
+ Switch(
+ checked = checked,
+ onCheckedChange = onCheckedChange
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/DrawHost.kt b/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/DrawHost.kt
index f2136a5f87..161120398f 100644
--- a/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/DrawHost.kt
+++ b/app/src/main/java/ru/tech/imageresizershrinker/presentation/draw_screen/components/DrawHost.kt
@@ -124,6 +124,7 @@ fun DrawHost(
drawColor: Color,
drawAlpha: Float,
strokeWidth: Float,
+ drawArrowsEnabled: Boolean,
bitmap: Bitmap,
blurRadius: Float,
addPath: (PathPaint) -> Unit,
@@ -160,6 +161,7 @@ fun DrawHost(
zoomEnabled = zoomEnabled,
onDraw = onDraw,
imageManager = imageManager,
+ drawArrowsEnabled = drawArrowsEnabled,
backgroundColor = backgroundColor
)
}
diff --git a/app/src/main/java/ru/tech/imageresizershrinker/presentation/single_edit_screen/components/DrawEditOption.kt b/app/src/main/java/ru/tech/imageresizershrinker/presentation/single_edit_screen/components/DrawEditOption.kt
index 327a245b29..dd95a47b64 100644
--- a/app/src/main/java/ru/tech/imageresizershrinker/presentation/single_edit_screen/components/DrawEditOption.kt
+++ b/app/src/main/java/ru/tech/imageresizershrinker/presentation/single_edit_screen/components/DrawEditOption.kt
@@ -50,6 +50,7 @@ import ru.tech.imageresizershrinker.domain.image.ImageManager
import ru.tech.imageresizershrinker.presentation.draw_screen.components.BitmapDrawer
import ru.tech.imageresizershrinker.presentation.draw_screen.components.BlurRadiusSelector
import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawAlphaSelector
+import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawArrowsSelector
import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawColorSelector
import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawMode
import ru.tech.imageresizershrinker.presentation.draw_screen.components.DrawModeSelector
@@ -132,6 +133,9 @@ fun DrawEditOption(
var blurRadius by rememberSaveable(drawMode) {
mutableFloatStateOf(if (drawMode is DrawMode.Neon) 35f else 0f)
}
+ var drawArrowsEnabled by remember {
+ mutableStateOf(false)
+ }
val secondaryControls = @Composable {
val border = BorderStroke(
@@ -234,6 +238,17 @@ fun DrawEditOption(
drawMode = drawMode,
onDrawModeChange = { drawMode = it }
)
+ AnimatedVisibility(!isEraserOn) {
+ DrawArrowsSelector(
+ modifier = Modifier.padding(
+ start = 16.dp,
+ end = 16.dp,
+ bottom = 16.dp
+ ),
+ checked = drawArrowsEnabled,
+ onCheckedChange = { drawArrowsEnabled = it }
+ )
+ }
},
fabButtons = null,
actions = {
@@ -299,6 +314,7 @@ fun DrawEditOption(
onDraw = {
stateBitmap = it
},
+ drawArrowsEnabled = drawArrowsEnabled,
backgroundColor = Color.Transparent
)
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9edb8c51b6..80cd255e6c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -378,6 +378,8 @@
Allow betas
Update checking will include beta app versions if enabled
Enables drawing shadows behind containers and buttons if borders are disabled
+ Draw Arrows
+ If enabled drawing path will be represented as pointing arrow
- Start
- Center