diff --git a/app/.gitignore b/app/.gitignore
deleted file mode 100644
index 42afabf..0000000
--- a/app/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
deleted file mode 100644
index f9aca38..0000000
--- a/app/build.gradle
+++ /dev/null
@@ -1,104 +0,0 @@
-plugins {
- id 'com.android.application'
- id 'org.jetbrains.kotlin.android'
-}
-
-android {
- namespace 'com.smarttoolfactory.composecropper'
- compileSdk 33
-
- defaultConfig {
- applicationId "com.smarttoolfactory.composecropper"
- minSdk 21
- targetSdk 33
- versionCode 1
- versionName "1.0"
-
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- vectorDrawables {
- useSupportLibrary true
- }
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
- kotlinOptions {
- jvmTarget = '1.8'
- }
- buildFeatures {
- compose true
- }
- composeOptions {
- kotlinCompilerExtensionVersion = "1.2.0-rc02"
- }
- packagingOptions {
- resources {
- excludes += '/META-INF/{AL2.0,LGPL2.1}'
- }
- }
-}
-
-dependencies {
-
- implementation project(':cropper')
-
- implementation 'androidx.core:core-ktx:1.9.0'
- implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
-
- // Colorful Customizable Sliders
- implementation 'com.github.SmartToolFactory:Compose-Colorful-Sliders:1.1.0'
- // Color picker
- implementation 'com.github.SmartToolFactory:Compose-Color-Picker-Bundle:1.0.1'
- // Gestures
- implementation 'com.github.SmartToolFactory:Compose-Extended-Gestures:2.1.0'
- // Animated List
- implementation 'com.github.SmartToolFactory:Compose-AnimatedList:0.5.1'
-
- implementation "androidx.compose.ui:ui:$compose_version"
- // Tooling support (Previews, etc.)
- implementation "androidx.compose.ui:ui-tooling:$compose_version"
- // Foundation (Border, Background, Box, Image, Scroll, shapes, animations, etc.)
- implementation "androidx.compose.foundation:foundation:$compose_version"
- // Material Design
- implementation "androidx.compose.material:material:$compose_version"
- // Material design icons
- implementation "androidx.compose.material:material-icons-core:$compose_version"
- implementation "androidx.compose.material:material-icons-extended:$compose_version"
- // Integration with activities
- implementation 'androidx.activity:activity-compose:1.6.1'
- // Integration with ViewModels
- implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1'
-
- // Material Design 3 for Compose
- implementation "androidx.compose.material3:material3:1.0.0"
-
- def nav_compose_version = "2.5.3"
- implementation "androidx.navigation:navigation-compose:$nav_compose_version"
-
- def accompanist_version = "0.25.0"
- // Accompanist
- implementation "com.google.accompanist:accompanist-systemuicontroller:$accompanist_version"
- implementation "com.google.accompanist:accompanist-pager:$accompanist_version"
- implementation "com.google.accompanist:accompanist-drawablepainter:$accompanist_version"
-
- // Coil
- implementation("io.coil-kt:coil-compose:2.1.0")
-
- // Photo Picker
- implementation("com.google.modernstorage:modernstorage-photopicker:1.0.0-alpha06")
-
- testImplementation 'junit:junit:4.13.2'
- androidTestImplementation 'androidx.test.ext:junit:1.1.3'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
- androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
- debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
- debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
-}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
deleted file mode 100644
index 481bb43..0000000
--- a/app/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/smarttoolfactory/composecropper/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/smarttoolfactory/composecropper/ExampleInstrumentedTest.kt
deleted file mode 100644
index 6a9f2db..0000000
--- a/app/src/androidTest/java/com/smarttoolfactory/composecropper/ExampleInstrumentedTest.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.smarttoolfactory.composecropper
-
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.ext.junit.runners.AndroidJUnit4
-
-import org.junit.Test
-import org.junit.runner.RunWith
-
-import org.junit.Assert.*
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-@RunWith(AndroidJUnit4::class)
-class ExampleInstrumentedTest {
- @Test
- fun useAppContext() {
- // Context of the app under test.
- val appContext = InstrumentationRegistry.getInstrumentation().targetContext
- assertEquals("com.smarttoolfactory.composecropper", appContext.packageName)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
deleted file mode 100644
index b842507..0000000
--- a/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/ImageSelectionButton.kt b/app/src/main/java/com/smarttoolfactory/composecropper/ImageSelectionButton.kt
deleted file mode 100644
index fc9e8c7..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/ImageSelectionButton.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.smarttoolfactory.composecropper
-
-import android.annotation.SuppressLint
-import android.graphics.Bitmap
-import android.graphics.ImageDecoder
-import android.os.Build
-import android.provider.MediaStore
-import androidx.activity.compose.rememberLauncherForActivityResult
-import androidx.compose.material.Icon
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Add
-import androidx.compose.material3.FloatingActionButton
-import androidx.compose.material3.FloatingActionButtonDefaults
-import androidx.compose.material3.FloatingActionButtonElevation
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.graphics.asImageBitmap
-import androidx.compose.ui.platform.LocalContext
-import com.google.modernstorage.photopicker.PhotoPicker
-
-@SuppressLint("UnsafeOptInUsageError")
-@Composable
-fun ImageSelectionButton(
- elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
- onImageSelected: (ImageBitmap) -> Unit
-) {
- val context = LocalContext.current
-
- val photoPicker =
- rememberLauncherForActivityResult(PhotoPicker()) { uris ->
- val uri = uris.firstOrNull() ?: return@rememberLauncherForActivityResult
-
- val bitmap: Bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- ImageDecoder.decodeBitmap(
- ImageDecoder.createSource(context.contentResolver, uri)
- ) { decoder, info, source ->
- decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
- decoder.isMutableRequired = true
- }
- } else {
- MediaStore.Images.Media.getBitmap(context.contentResolver, uri)
- }
-
- onImageSelected(bitmap.asImageBitmap())
-
- }
-
- FloatingActionButton(
- elevation = elevation,
- onClick = {
- photoPicker.launch(PhotoPicker.Args(PhotoPicker.Type.IMAGES_ONLY, 1))
- },
- ) {
- Icon(
- imageVector = Icons.Default.Add,
- contentDescription = null
- )
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/MainActivity.kt b/app/src/main/java/com/smarttoolfactory/composecropper/MainActivity.kt
deleted file mode 100644
index a6cb6ce..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/MainActivity.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.smarttoolfactory.composecropper
-
-import android.os.Bundle
-import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
-import androidx.compose.ui.Modifier
-import com.smarttoolfactory.composecropper.demo.ImageCropDemo
-import com.smarttoolfactory.composecropper.ui.theme.ComposeCropperTheme
-
-class MainActivity : ComponentActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContent {
- ComposeCropperTheme {
- // A surface container using the 'background' color from the theme
- Surface(
- modifier = Modifier.fillMaxSize(),
- color = MaterialTheme.colorScheme.background
- ) {
- Column {
- ImageCropDemo()
- }
- }
- }
- }
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/demo/CanvasDemo.kt b/app/src/main/java/com/smarttoolfactory/composecropper/demo/CanvasDemo.kt
deleted file mode 100644
index 772ad0e..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/demo/CanvasDemo.kt
+++ /dev/null
@@ -1,223 +0,0 @@
-package com.smarttoolfactory.composecropper.demo
-
-import android.graphics.Bitmap
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
-import androidx.compose.foundation.border
-import androidx.compose.foundation.layout.*
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.graphics.*
-import androidx.compose.ui.graphics.drawscope.Stroke
-import androidx.compose.ui.graphics.drawscope.translate
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.res.imageResource
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.composecropper.R
-
-@Composable
-fun CanvasDemo() {
-
- Column(modifier = Modifier.fillMaxSize()) {
-
- NativeCanvasSample1(
- modifier = Modifier
- .fillMaxWidth()
- .aspectRatio(4 / 3f)
- )
-
- NativeCanvasMaskSample()
-
- VectorSample()
- }
-
-}
-
-
-@Composable
-fun NativeCanvasMaskSample() {
-
-
- val cropMaskBitmap = ImageBitmap.imageResource(id = R.drawable.squircle)
-
- val imagePaint = remember {
- Paint().apply {
- blendMode = BlendMode.SrcIn
- }
- }
-
- val paint = remember {
- Paint()
- }
-
- val imageBitmap = ImageBitmap
- .imageResource(id = R.drawable.cinnamon)
- .asAndroidBitmap()
- .copy(Bitmap.Config.ARGB_8888, true)!!
- .asImageBitmap()
-
-
- Canvas(image = imageBitmap).apply {
-
- saveLayer(nativeCanvas.clipBounds.toComposeRect(), imagePaint)
- // Destination
-// drawCircle(center = Offset(400f, 400f), radius = 300f, paint)
-// drawImage(cropMaskBitmap, topLeftOffset = Offset.Zero, paint)
-
- val matrix = android.graphics.Matrix()
- matrix.postScale(30f, 30f)
- favoritePath.asAndroidPath().transform(matrix)
-
- val left = favoritePath.getBounds().left
- val top = favoritePath.getBounds().top
-
-
- drawPath(favoritePath, paint)
-
- // Source
- drawImage(imageBitmap, topLeftOffset = Offset.Zero, imagePaint)
-
- restore()
- }
-
- Image(
- modifier = Modifier
- .fillMaxWidth()
- .aspectRatio(4 / 3f)
- .border(1.dp, Color.Green),
- bitmap = imageBitmap,
- contentDescription = null
- )
-}
-
-@Composable
-fun NativeCanvasSample1(modifier: Modifier) {
-
- val imageBitmap = ImageBitmap
- .imageResource(id = R.drawable.cinnamon)
- .asAndroidBitmap()
- .copy(Bitmap.Config.ARGB_8888, true)!!
- .asImageBitmap()
-
- BoxWithConstraints(modifier) {
-
-
- val imageWidth = constraints.maxWidth
- val imageHeight = constraints.maxHeight
-
- val bitmapWidth = imageBitmap.width
- val bitmapHeight = imageBitmap.height
-
-
- val canvas = Canvas(imageBitmap)
-
- val imagePaint = remember {
- Paint().apply {
- blendMode = BlendMode.SrcIn
- }
- }
-
- val paint = remember {
- Paint().apply {
- color = Color(0xff29B6F6)
- }
- }
-
- canvas.apply {
- val nativeCanvas = this.nativeCanvas
- val canvasWidth = nativeCanvas.width.toFloat()
- val canvasHeight = nativeCanvas.height.toFloat()
-
- println(
- "🔥 Canvas Width: $canvasWidth, canvasHeight: $canvasHeight, " +
- "imageWidth: $imageWidth, imageHeight: $imageHeight\n" +
- "bitmapWidth: $bitmapWidth, bitmapHeight: $bitmapHeight\n" +
- "rect: ${nativeCanvas.clipBounds.toComposeRect()}"
- )
- saveLayer(nativeCanvas.clipBounds.toComposeRect(), imagePaint)
-
- drawCircle(
- center = Offset(canvasWidth / 2, canvasHeight / 2),
- radius = canvasHeight / 2,
- paint = paint
- )
- drawImage(image = imageBitmap, topLeftOffset = Offset.Zero, imagePaint)
- restore()
-
-
- }
-
- Image(
- modifier = Modifier
- .background(Color.LightGray)
- .border(2.dp, Color.Red),
- bitmap = imageBitmap,
- contentDescription = null,
- contentScale = ContentScale.FillBounds
- )
-
- }
-}
-
-@Composable
-private fun VectorSample() {
-
- androidx.compose.foundation.Canvas(
- modifier = Modifier
- .fillMaxWidth()
- .aspectRatio(4 / 3f)
- .border(3.dp,Color.Cyan)
- ) {
-
- val matrix = android.graphics.Matrix()
- matrix.postScale(30f, 30f)
- starPath.asAndroidPath().transform(matrix)
-
- val left = starPath.getBounds().left
- val top = starPath.getBounds().top
-
- translate(left = -left, top = -top) {
- drawPath(starPath, Color.Red)
- }
-
- drawRect(
- color = Color.Green,
- topLeft = starPath.getBounds().topLeft,
- size = starPath.getBounds().size,
- style = Stroke(2.dp.toPx())
- )
-
- }
-}
-
-
-
-
-val favoritePath = Path().apply {
- moveTo(12.0f, 21.35f)
- relativeLineTo(-1.45f, -1.32f)
- cubicTo(5.4f, 15.36f, 2.0f, 12.28f, 2.0f, 8.5f)
- cubicTo(2.0f, 5.42f, 4.42f, 3.0f, 7.5f, 3.0f)
- relativeCubicTo(1.74f, 0.0f, 3.41f, 0.81f, 4.5f, 2.09f)
- cubicTo(13.09f, 3.81f, 14.76f, 3.0f, 16.5f, 3.0f)
- cubicTo(19.58f, 3.0f, 22.0f, 5.42f, 22.0f, 8.5f)
- relativeCubicTo(0.0f, 3.78f, -3.4f, 6.86f, -8.55f, 11.54f)
- lineTo(12.0f, 21.35f)
- close()
-}
-
-val starPath = Path().apply {
- moveTo(12.0f, 17.27f)
- lineTo(18.18f, 21.0f)
- relativeLineTo(-1.64f, -7.03f)
- lineTo(22.0f, 9.24f)
- relativeLineTo(-7.19f, -0.61f)
- lineTo(12.0f, 2.0f)
- lineTo(9.19f, 8.63f)
- lineTo(2.0f, 9.24f)
- relativeLineTo(5.46f, 4.73f)
- lineTo(5.82f, 21.0f)
- close()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemo.kt b/app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemo.kt
deleted file mode 100644
index f6a83ef..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemo.kt
+++ /dev/null
@@ -1,293 +0,0 @@
-@file:OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialApi::class)
-
-package com.smarttoolfactory.composecropper.demo
-
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
-import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.*
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Brush
-import androidx.compose.material.icons.filled.Crop
-import androidx.compose.material.icons.filled.Settings
-import androidx.compose.material3.BottomAppBar
-import androidx.compose.material3.FloatingActionButtonDefaults
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
-import androidx.compose.material3.Text
-import androidx.compose.runtime.*
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.imageResource
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.colorpicker.widget.drawChecker
-import com.smarttoolfactory.composecropper.ImageSelectionButton
-import com.smarttoolfactory.composecropper.R
-import com.smarttoolfactory.composecropper.preferences.CropStyleSelectionMenu
-import com.smarttoolfactory.composecropper.preferences.PropertySelectionSheet
-import com.smarttoolfactory.composecropper.ui.theme.ComposeCropperTheme
-import com.smarttoolfactory.cropper.ImageCropper
-import com.smarttoolfactory.cropper.model.CornerRadiusProperties
-import com.smarttoolfactory.cropper.model.OutlineType
-import com.smarttoolfactory.cropper.model.RectCropShape
-import com.smarttoolfactory.cropper.model.RoundedCornerCropShape
-import com.smarttoolfactory.cropper.settings.*
-import kotlinx.coroutines.launch
-
-internal enum class SelectionPage {
- Properties, Style
-}
-
-@OptIn(ExperimentalMaterialApi::class)
-@Composable
-fun ImageCropDemo() {
-
- val bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(
- bottomSheetState = BottomSheetState(BottomSheetValue.Collapsed)
- )
-
- val defaultImage1 = ImageBitmap.imageResource(id = R.drawable.squircle)
- val defaultImage2 = ImageBitmap.imageResource(id = R.drawable.cloud)
- val defaultImage3 = ImageBitmap.imageResource(id = R.drawable.sun)
-
- val cropFrameFactory = remember {
- CropFrameFactory(
- listOf(
- defaultImage1,
- defaultImage2,
- defaultImage3
- )
- )
- }
-
- val handleSize = LocalDensity.current.run { 14.dp.toPx() }
- val cornerSize = LocalDensity.current.run { 8.dp.toPx() }
- val corner = CornerRadiusProperties(radius = cornerSize)
-
- var cropProperties by remember {
- mutableStateOf(
- CropDefaults.properties(
- cropOutlineProperty = CropOutlineProperty(
- outlineType = OutlineType.RoundedRect,
- cropOutline = RoundedCornerCropShape(0, "RoundRect", cornerRadius = corner)
- ),
- handleSize = handleSize
- )
- )
- }
- var cropStyle by remember { mutableStateOf(CropDefaults.style().copy(handleStrokeWidth = 4.dp)) }
- val coroutineScope = rememberCoroutineScope()
-
- var selectionPage by remember { mutableStateOf(SelectionPage.Properties) }
-
-
- val theme by remember {
- derivedStateOf {
- cropStyle.cropTheme
- }
- }
-
- ComposeCropperTheme(
- darkTheme = when(theme){
- CropTheme.Dark ->true
- CropTheme.Light->false
- else -> isSystemInDarkTheme()
- }
- ) {
- BottomSheetScaffold(
- scaffoldState = bottomSheetScaffoldState,
- sheetElevation = 16.dp,
- sheetShape = RoundedCornerShape(
- bottomStart = 0.dp,
- bottomEnd = 0.dp,
- topStart = 28.dp,
- topEnd = 28.dp
- ),
-
- sheetGesturesEnabled = true,
- sheetContent = {
-
- if (selectionPage == SelectionPage.Properties) {
- PropertySelectionSheet(
- cropFrameFactory = cropFrameFactory,
- cropProperties = cropProperties,
- onCropPropertiesChange = {
- cropProperties = it
- }
- )
- } else {
- CropStyleSelectionMenu(
- cropType = cropProperties.cropType,
- cropStyle = cropStyle,
- onCropStyleChange = {
- cropStyle = it
- }
- )
- }
- },
-
- // This is the height in collapsed state
- sheetPeekHeight = 0.dp
- ) {
- MainContent(
- cropProperties,
- cropStyle,
- ) {
- selectionPage = it
-
- coroutineScope.launch {
- if (bottomSheetScaffoldState.bottomSheetState.isExpanded) {
- bottomSheetScaffoldState.bottomSheetState.collapse()
- } else {
- bottomSheetScaffoldState.bottomSheetState.expand()
- }
- }
- }
- }
- }
-}
-
-@Composable
-private fun MainContent(
- cropProperties: CropProperties,
- cropStyle: CropStyle,
- onSelectionPageMenuClicked: (SelectionPage) -> Unit
-) {
-
- val imageBitmapLarge = ImageBitmap.imageResource(
- LocalContext.current.resources,
- R.drawable.landscape5
- )
-
- var imageBitmap by remember { mutableStateOf(imageBitmapLarge) }
- var croppedImage by remember { mutableStateOf(null) }
-
-
- var crop by remember { mutableStateOf(false) }
- var showDialog by remember { mutableStateOf(false) }
- var isCropping by remember { mutableStateOf(false) }
-
- Box(
- modifier = Modifier
- .fillMaxSize()
- .background(Color.DarkGray),
- contentAlignment = Alignment.Center
- ) {
- Column(modifier = Modifier.fillMaxSize()) {
-
- ImageCropper(
- modifier = Modifier
- .fillMaxWidth()
- .weight(1f),
- imageBitmap = imageBitmap,
- contentDescription = "Image Cropper",
- cropStyle = cropStyle,
- cropProperties = cropProperties,
- crop = crop,
- onCropStart = {
- isCropping = true
- }
- ) {
- croppedImage = it
- isCropping = false
- crop = false
- showDialog = true
- }
- }
-
- BottomAppBar(
- modifier = Modifier.align(Alignment.BottomStart),
- actions = {
-
-
- IconButton(
- onClick = {
- onSelectionPageMenuClicked(SelectionPage.Properties)
- }
- ) {
- Icon(
- Icons.Filled.Settings,
- contentDescription = "Settings",
- )
-
- }
- IconButton(
- onClick = {
- onSelectionPageMenuClicked(SelectionPage.Style)
- }
- ) {
- Icon(Icons.Filled.Brush, contentDescription = "Style")
- }
-
- IconButton(
- onClick = { crop = true }) {
- Icon(Icons.Filled.Crop, contentDescription = "Crop Image")
- }
- },
- floatingActionButton = {
- ImageSelectionButton(
- elevation = FloatingActionButtonDefaults.elevation(defaultElevation = 0.dp),
- onImageSelected = { bitmap: ImageBitmap ->
- imageBitmap = bitmap
- }
- )
- }
- )
-
- if (isCropping) {
- CircularProgressIndicator()
- }
- }
-
- if (showDialog) {
- croppedImage?.let {
- ShowCroppedImageDialog(imageBitmap = it) {
- showDialog = !showDialog
- croppedImage = null
- }
- }
- }
-}
-
-@Composable
-private fun ShowCroppedImageDialog(imageBitmap: ImageBitmap, onDismissRequest: () -> Unit) {
- androidx.compose.material3.AlertDialog(
- onDismissRequest = onDismissRequest,
- text = {
- Image(
- modifier = Modifier
- .drawChecker(RoundedCornerShape(8.dp))
- .fillMaxWidth()
- .aspectRatio(1f),
- contentScale = ContentScale.Fit,
- bitmap = imageBitmap,
- contentDescription = "result"
- )
- },
- confirmButton = {
- TextButton(
- onClick = {
- onDismissRequest()
- }
- ) {
- Text("Confirm")
- }
- },
- dismissButton = {
- TextButton(
- onClick = {
- onDismissRequest()
- }
- ) {
- Text("Dismiss")
- }
- }
- )
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemoSimple.kt b/app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemoSimple.kt
deleted file mode 100644
index 5d3ced3..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemoSimple.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.smarttoolfactory.composecropper.demo
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.imageResource
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.composecropper.R
-import com.smarttoolfactory.cropper.ImageCropper
-import com.smarttoolfactory.cropper.model.OutlineType
-import com.smarttoolfactory.cropper.model.RectCropShape
-import com.smarttoolfactory.cropper.settings.CropDefaults
-import com.smarttoolfactory.cropper.settings.CropOutlineProperty
-
-@Composable
-fun ImageCropDemoSimple() {
-
- val handleSize: Float = LocalDensity.current.run { 20.dp.toPx() }
-
- val cropProperties by remember {
- mutableStateOf(
- CropDefaults.properties(
- cropOutlineProperty = CropOutlineProperty(
- OutlineType.Rect,
- RectCropShape(0, "Rect")
- ),
- handleSize = handleSize
- )
- )
- }
- val cropStyle by remember { mutableStateOf(CropDefaults.style()) }
-
- val imageBitmapLarge = ImageBitmap.imageResource(
- LocalContext.current.resources,
- R.drawable.cinnamon
- )
-
- val imageBitmap by remember { mutableStateOf(imageBitmapLarge) }
- val crop by remember { mutableStateOf(false) }
-
-
- Box(
- modifier = Modifier
- .fillMaxSize()
- .background(Color.DarkGray),
- contentAlignment = Alignment.Center
- ) {
- Column(modifier = Modifier.fillMaxSize()) {
-
- ImageCropper(
- modifier = Modifier
- .fillMaxWidth()
- .weight(1f),
- imageBitmap = imageBitmap,
- contentDescription = "Image Cropper",
- cropStyle = cropStyle,
- cropProperties = cropProperties,
- crop = crop,
- onCropStart = {}
- ) {
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/AspectRatioSelection.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/AspectRatioSelection.kt
deleted file mode 100644
index 26d42fa..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/AspectRatioSelection.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.graphicsLayer
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.animatedlist.AnimatedInfiniteLazyRow
-import com.smarttoolfactory.animatedlist.model.AnimationProgress
-import com.smarttoolfactory.cropper.model.CropAspectRatio
-import com.smarttoolfactory.cropper.model.aspectRatios
-import com.smarttoolfactory.cropper.widget.AspectRatioSelectionCard
-
-@Composable
-internal fun AnimatedAspectRatioSelection(
- modifier: Modifier = Modifier,
- initialSelectedIndex: Int = 2,
- onAspectRatioChange: (CropAspectRatio) -> Unit
-) {
-
- var currentIndex by remember { mutableStateOf(initialSelectedIndex) }
-
- AnimatedInfiniteLazyRow(
- modifier = modifier.padding(horizontal = 10.dp),
- items = aspectRatios,
- inactiveItemPercent = 80,
- initialFirstVisibleIndex = initialSelectedIndex - 2
- ) { animationProgress: AnimationProgress, index: Int, item: CropAspectRatio, width: Dp ->
-
- val scale = animationProgress.scale
- val color = animationProgress.color
- val selectedLocalIndex = animationProgress.itemIndex
-
- AspectRatioSelectionCard(modifier = Modifier
- .graphicsLayer {
- scaleX = scale
- scaleY = scale
- }
- .width(width),
- contentColor = MaterialTheme.colorScheme.surface,
- color = color,
- cropAspectRatio = item
- )
-
- if (currentIndex != selectedLocalIndex) {
- currentIndex = selectedLocalIndex
- onAspectRatioChange(aspectRatios[selectedLocalIndex])
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/BaseSheet.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/BaseSheet.kt
deleted file mode 100644
index f51d905..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/BaseSheet.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
-
-@Composable
-internal fun BaseSheet(content: @Composable () -> Unit) {
- Surface {
- Column {
- Box(
- modifier = Modifier
- .padding(vertical = 16.dp)
- .fillMaxWidth(),
- contentAlignment = Alignment.Center
- ) {
- Box(
- modifier = Modifier
- .width(32.dp)
- .height(4.dp)
- .background(
- MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = .4f),
- RoundedCornerShape(50)
- )
- )
- }
-
- Column(
- modifier = Modifier
- .fillMaxWidth()
- .height(400.dp)
- .padding(horizontal = 16.dp, vertical = 8.dp)
- .verticalScroll(rememberScrollState())
- ) {
- content()
- }
- }
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/ContentScaleSelection.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/ContentScaleSelection.kt
deleted file mode 100644
index 9af5bf3..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/ContentScaleSelection.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.Text
-import androidx.compose.runtime.*
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-
-val contentScaleOptions =
- listOf("None", "Fit", "Crop", "FillBounds", "FillWidth", "FillHeight", "Inside")
-
-@Composable
-internal fun ContentScaleDialogSelection(
- contentScale: ContentScale,
- onContentScaleChanged: (ContentScale) -> Unit
-){
-
- var showDialog by remember { mutableStateOf(false) }
-
- val index = when (contentScale) {
- ContentScale.None -> 0
- ContentScale.Fit -> 1
- ContentScale.Crop -> 2
- ContentScale.FillBounds -> 3
- ContentScale.FillWidth -> 4
- ContentScale.FillHeight -> 5
- else -> 6
- }
-
- Text(
- text = contentScaleOptions[index],
- fontSize = 18.sp,
- modifier = Modifier
- .fillMaxWidth()
- .clickable {
- showDialog = true
- }
- .padding(8.dp)
- )
-
- if (showDialog) {
- DialogWithMultipleSelection(
- title = "Content Scale",
- options = contentScaleOptions,
- value = index,
- onDismiss = { showDialog = false },
- onConfirm = {
-
- val scale = when (it) {
- 0 -> ContentScale.None
- 1 -> ContentScale.Fit
- 2 -> ContentScale.Crop
- 3 -> ContentScale.FillBounds
- 4 -> ContentScale.FillWidth
- 5 -> ContentScale.FillHeight
- else -> ContentScale.Inside
- }
- onContentScaleChanged(scale)
- showDialog = false
- }
- )
- }
-}
-
-@Composable
-internal fun ContentScaleExposedSelection(
- contentScale: ContentScale,
- onContentScaleChanged: (ContentScale) -> Unit
-) {
- var index = when (contentScale) {
- ContentScale.None -> 0
- ContentScale.Fit -> 1
- ContentScale.Crop -> 2
- ContentScale.FillBounds -> 3
- ContentScale.FillWidth -> 4
- ContentScale.FillHeight -> 5
- else -> 6
- }
-
- Row(
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier
- .fillMaxWidth()
- .padding(2.dp)
- ) {
- ExposedSelectionMenu(
- modifier = Modifier.fillMaxWidth(),
- index = index,
- title = "ContentScale",
- options = contentScaleOptions,
- onSelected = {
- index = it
- val scale = when (index) {
- 0 -> ContentScale.None
- 1 -> ContentScale.Fit
- 2 -> ContentScale.Crop
- 3 -> ContentScale.FillBounds
- 4 -> ContentScale.FillWidth
- 5 -> ContentScale.FillHeight
- else -> ContentScale.Inside
- }
-
- onContentScaleChanged(scale)
- }
- )
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropFrameSelection.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropFrameSelection.kt
deleted file mode 100644
index d6488a4..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropFrameSelection.kt
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import CropFrameListDialog
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.animatedlist.AnimatedInfiniteLazyRow
-import com.smarttoolfactory.animatedlist.model.AnimationProgress
-import com.smarttoolfactory.cropper.model.AspectRatio
-import com.smarttoolfactory.cropper.model.CropFrame
-import com.smarttoolfactory.cropper.model.OutlineType
-import com.smarttoolfactory.cropper.settings.CropFrameFactory
-import com.smarttoolfactory.cropper.settings.CropOutlineProperty
-import com.smarttoolfactory.cropper.widget.CropFrameDisplayCard
-
-/**
- * Crop frame selection
- */
-@Composable
-fun CropFrameSelection(
- aspectRatio: AspectRatio,
- cropFrameFactory: CropFrameFactory,
- cropOutlineProperty: CropOutlineProperty,
- conCropOutlinePropertyChange: (CropOutlineProperty) -> Unit
-) {
-
- var showEditDialog by remember { mutableStateOf(false) }
-
- var cropFrame by remember {
- mutableStateOf(
- cropFrameFactory.getCropFrame(cropOutlineProperty.outlineType)
- )
- }
-
- if (showEditDialog) {
- CropFrameListDialog(
- aspectRatio = aspectRatio,
- cropFrame = cropFrame,
- onConfirm = {
- cropFrame = it
- cropFrameFactory.editCropFrame(cropFrame)
-
- conCropOutlinePropertyChange(
- CropOutlineProperty(
- it.outlineType,
- it.cropOutlineContainer.selectedItem
- )
- )
- showEditDialog = false
- },
- onDismiss = {
- showEditDialog = false
- }
- )
- }
-
- val initialIndex = remember {
- OutlineType.values().indexOfFirst {
- it == cropOutlineProperty.outlineType
- }
- }
-
- CropFrameSelectionList(
- modifier = Modifier.fillMaxWidth(),
- cropFrames = cropFrameFactory.getCropFrames(),
- initialSelectedIndex = initialIndex,
- onClick = {
- cropFrame = it
- showEditDialog = true
- },
- onCropFrameChange = {
- conCropOutlinePropertyChange(
- CropOutlineProperty(
- it.outlineType,
- it.cropOutlineContainer.selectedItem
- )
- )
- }
- )
-}
-
-/**
- * Animated list for selecting [CropFrame]
- */
-@Composable
-private fun CropFrameSelectionList(
- modifier: Modifier = Modifier,
- initialSelectedIndex: Int = 0,
- cropFrames: List,
- onClick: (CropFrame) -> Unit,
- onCropFrameChange: (CropFrame) -> Unit
-) {
-
- var currentIndex by remember { mutableStateOf(initialSelectedIndex) }
-
- AnimatedInfiniteLazyRow(
- modifier = modifier.padding(horizontal = 10.dp),
- items = cropFrames,
- inactiveItemPercent = 80,
- initialFirstVisibleIndex = initialSelectedIndex - 2,
- ) { animationProgress: AnimationProgress, index: Int, item: CropFrame, width: Dp ->
-
- val scale = animationProgress.scale
- val color = animationProgress.color
-
- val selectedLocalIndex = animationProgress.itemIndex
- val cropOutline = item.cropOutlineContainer.selectedItem
-
- val editable = item.editable
-
- CropFrameDisplayCard(
- modifier = Modifier.width(width),
- editable = editable,
- scale = scale,
- outlineColor = color,
- title = cropOutline.title,
- cropOutline = cropOutline
- ) {
- onClick(item)
- }
-
- if (currentIndex != selectedLocalIndex) {
- currentIndex = selectedLocalIndex
- onCropFrameChange(cropFrames[selectedLocalIndex])
- }
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropPropertySelection.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropPropertySelection.kt
deleted file mode 100644
index cc21fc4..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropPropertySelection.kt
+++ /dev/null
@@ -1,231 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import com.smarttoolfactory.cropper.model.AspectRatio
-import com.smarttoolfactory.cropper.model.CropAspectRatio
-import com.smarttoolfactory.cropper.model.aspectRatios
-import com.smarttoolfactory.cropper.settings.CropFrameFactory
-import com.smarttoolfactory.cropper.settings.CropProperties
-import com.smarttoolfactory.cropper.settings.CropType
-import kotlin.math.roundToInt
-
-
-@Composable
-internal fun CropPropertySelectionMenu(
- cropFrameFactory: CropFrameFactory,
- cropProperties: CropProperties,
- onCropPropertiesChange: (CropProperties) -> Unit
-) {
-
- val density = LocalDensity.current
-
- // Crop properties
- val cropType = cropProperties.cropType
- val aspectRatio = cropProperties.aspectRatio
-
- val handleSize = density.run { cropProperties.handleSize.toDp() }
- val contentScale = cropProperties.contentScale
- val cropOutlineProperty = cropProperties.cropOutlineProperty
- val overlayRatio = (cropProperties.overlayRatio * 100)
-
- Title("Crop Type")
- CropTypeDialogSelection(
- cropType = cropType,
- onCropTypeChange = { cropTypeChange ->
- onCropPropertiesChange(
- cropProperties.copy(cropType = cropTypeChange)
- )
- }
- )
-
- Title("Content Scale")
- ContentScaleDialogSelection(contentScale) {
- onCropPropertiesChange(
- cropProperties.copy(contentScale = it)
- )
- }
-
- Title("Aspect Ratio")
- AspectRatioSelection(
- aspectRatio = aspectRatio,
- onAspectRatioChange = {
- onCropPropertiesChange(
- cropProperties.copy(aspectRatio = it.aspectRatio)
- )
- }
- )
-
- Title("Frame")
- CropFrameSelection(
- aspectRatio = aspectRatio,
- cropFrameFactory = cropFrameFactory,
- cropOutlineProperty = cropOutlineProperty,
- conCropOutlinePropertyChange = {
- onCropPropertiesChange(
- cropProperties.copy(cropOutlineProperty = it)
- )
- }
- )
-
- Title("Overlay Ratio ${overlayRatio.toInt()}%")
- SliderSelection(
- value = overlayRatio, valueRange = 50f..100f
- ) {
- onCropPropertiesChange(
- cropProperties.copy(overlayRatio = (it.toInt() / 100f))
- )
- }
-
- // Handle size and overlay size applies only to Dynamic crop
- if (cropType == CropType.Dynamic) {
- Title("Handle Size")
- DpSliderSelection(
- value = handleSize,
- onValueChange = {
- onCropPropertiesChange(
- cropProperties.copy(handleSize = density.run { it.toPx() })
- )
- },
- lowerBound = 10.dp,
- upperBound = 40.dp
- )
- }
-}
-
-@Composable
-internal fun CropGestureSelectionMenu(
- cropProperties: CropProperties,
- onCropPropertiesChange: (CropProperties) -> Unit
-) {
- // Gestures
- val flingEnabled = cropProperties.fling
- val pannable = cropProperties.pannable
- val zoomable = cropProperties.zoomable
- val maxZoom = cropProperties.maxZoom
-
- Title("Pan Enabled")
- PanEnableSelection(
- panEnabled = pannable,
- onPanEnabledChange = {
- onCropPropertiesChange(
- cropProperties.copy(pannable = it)
- )
- }
- )
-
- Title("Fling")
- FlingEnableSelection(
- flingEnabled = flingEnabled,
- onFlingEnabledChange = {
- onCropPropertiesChange(
- cropProperties.copy(fling = it)
- )
- }
- )
-
- Title("Zoom Enabled")
- ZoomEnableSelection(
- zoomEnabled = zoomable,
- onZoomEnabledChange = {
- onCropPropertiesChange(
- cropProperties.copy(zoomable = it)
- )
- }
- )
-
- AnimatedVisibility(visible = zoomable) {
- Column {
-
- Title("Max Zoom ${maxZoom}x", fontSize = 16.sp)
- MaxZoomSelection(
- maxZoom = maxZoom,
- onMaxZoomChange = {
-
- val max = (it * 100f).roundToInt() / 100f
- onCropPropertiesChange(
- cropProperties.copy(maxZoom = max)
- )
- },
- valueRange = 1f..10f
- )
- }
- }
-}
-
-@Composable
-internal fun AspectRatioSelection(
- aspectRatio: AspectRatio,
- onAspectRatioChange: (CropAspectRatio) -> Unit
-) {
-
- val initialSelectedIndex = remember {
- val aspectRatios = aspectRatios
- val aspectRatioModel = aspectRatios.first { it.aspectRatio.value == aspectRatio.value }
- aspectRatios.indexOf(aspectRatioModel)
- }
-
- AnimatedAspectRatioSelection(
- modifier = Modifier.fillMaxWidth(),
- initialSelectedIndex = initialSelectedIndex
- ) {
- onAspectRatioChange(it)
- }
-}
-
-@Composable
-internal fun FlingEnableSelection(
- flingEnabled: Boolean,
- onFlingEnabledChange: (Boolean) -> Unit
-) {
- FullRowSwitch(
- label = "Enable fling gesture",
- state = flingEnabled,
- onStateChange = onFlingEnabledChange
- )
-
-}
-
-@Composable
-internal fun PanEnableSelection(
- panEnabled: Boolean,
- onPanEnabledChange: (Boolean) -> Unit
-) {
- FullRowSwitch(
- label = "Enable pan gesture",
- state = panEnabled,
- onStateChange = onPanEnabledChange
- )
-}
-
-@Composable
-internal fun ZoomEnableSelection(
- zoomEnabled: Boolean,
- onZoomEnabledChange: (Boolean) -> Unit
-) {
- FullRowSwitch(
- label = "Enable zoom gesture",
- state = zoomEnabled,
- onStateChange = onZoomEnabledChange
- )
-}
-
-@Composable
-internal fun MaxZoomSelection(
- maxZoom: Float,
- onMaxZoomChange: (Float) -> Unit,
- valueRange: ClosedFloatingPointRange
-) {
- SliderSelection(
- value = maxZoom,
- onValueChange = onMaxZoomChange,
- valueRange = valueRange
- )
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropStyleSelection.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropStyleSelection.kt
deleted file mode 100644
index 2071d7c..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropStyleSelection.kt
+++ /dev/null
@@ -1,168 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.foundation.background
-import androidx.compose.foundation.border
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.runtime.*
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import com.smarttoolfactory.colorpicker.dialog.ColorPickerRingDiamondHSLDialog
-import com.smarttoolfactory.cropper.settings.CropStyle
-import com.smarttoolfactory.cropper.settings.CropType
-
-/**
- * Crop style selection menu
- */
-@Composable
-internal fun CropStyleSelectionMenu(
- cropType: CropType,
- cropStyle: CropStyle,
- onCropStyleChange: (CropStyle) -> Unit
-) {
-
- BaseSheet {
- val drawOverlayEnabled = cropStyle.drawOverlay
- val overlayStrokeWidth = cropStyle.strokeWidth
- val overlayColor = cropStyle.overlayColor
- val handleColor = cropStyle.handleColor
- val backgroundColor = cropStyle.backgroundColor
- val drawGridEnabled = cropStyle.drawGrid
- val theme = cropStyle.cropTheme
-
- Title("Theme")
- CropThemeSelection(
- cropTheme = theme,
- onThemeChange = {
- onCropStyleChange(
- cropStyle.copy(cropTheme = it)
- )
- }
- )
-
-
- Title("Overlay")
- FullRowSwitch(
- label = "Draw overlay",
- state = drawOverlayEnabled,
- onStateChange = {
- onCropStyleChange(
- cropStyle.copy(drawOverlay = it)
- )
- }
- )
-
- AnimatedVisibility(
- visible = drawOverlayEnabled
- ) {
-
- Column {
- Title("StrokeWidth", fontSize = 16.sp)
- DpSliderSelection(
- value = overlayStrokeWidth,
- onValueChange = {
- onCropStyleChange(
- cropStyle.copy(strokeWidth = it)
- )
- },
- lowerBound = .5.dp,
- upperBound = 3.dp
- )
-
-
- ColorSelection(
- title = "Overlay Color",
- color = overlayColor,
- onColorChange = { color: Color ->
- onCropStyleChange(
- cropStyle.copy(overlayColor = color)
- )
- }
- )
-
- if(cropType== CropType.Dynamic){
- Spacer(modifier = Modifier.height(20.dp))
- ColorSelection(
- title = "Handle Color",
- color = handleColor,
- onColorChange = { color: Color ->
- onCropStyleChange(
- cropStyle.copy(handleColor = color)
- )
- }
- )
- }
-
- Spacer(modifier = Modifier.height(20.dp))
- ColorSelection(
- title = "Background Color",
- color = backgroundColor,
- onColorChange = { color: Color ->
- onCropStyleChange(
- cropStyle.copy(backgroundColor = color)
- )
- }
- )
-
- Title("Grid")
- FullRowSwitch(
- label = "Draw grid",
- state = drawGridEnabled,
- onStateChange = {
- onCropStyleChange(
- cropStyle.copy(drawGrid = it)
- )
- }
- )
- }
- }
- }
-}
-
-@Composable
-internal fun ColorSelection(
- title: String,
- color: Color,
- onColorChange: (Color) -> Unit
-) {
-
- var showColorDialog by remember { mutableStateOf(false) }
- Row(
- modifier = Modifier.fillMaxWidth(),
- verticalAlignment = Alignment.CenterVertically
- ) {
- Title(title, fontSize = 16.sp)
- Spacer(modifier = Modifier.weight(1f))
- Box(
- modifier = Modifier
- .clip(CircleShape)
- .size(40.dp)
- .border(
- 1.dp,
- MaterialTheme.colorScheme.primary,
- CircleShape
- )
- .background(color = color)
- .clickable {
- showColorDialog = true
- }
- )
- }
-
- if (showColorDialog) {
- ColorPickerRingDiamondHSLDialog(
- initialColor = color,
- onDismiss = { colorChange: Color, _: String ->
- showColorDialog = false
- onColorChange(colorChange)
- }
- )
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropThemeSelection.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropThemeSelection.kt
deleted file mode 100644
index 8eb0ca2..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropThemeSelection.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.Text
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import com.smarttoolfactory.cropper.settings.CropTheme
-
-@Composable
-fun CropThemeSelection(
- cropTheme: CropTheme,
- onThemeChange: (CropTheme) -> Unit
-) {
-
- val cropThemeOptions =
- remember {
- listOf(
- CropTheme.Light.toString(),
- CropTheme.Dark.toString(),
- CropTheme.System.toString()
- )
- }
-
- var showDialog by remember { mutableStateOf(false) }
-
- val index = when (cropTheme) {
- CropTheme.Light -> 0
- CropTheme.Dark -> 1
- else -> 2
- }
-
- Text(
- text = cropThemeOptions[index],
- fontSize = 18.sp,
- modifier = Modifier
- .fillMaxWidth()
- .clickable {
- showDialog = true
- }
- .padding(8.dp)
-
- )
-
- if (showDialog) {
- DialogWithMultipleSelection(
- title = "Theme",
- options = cropThemeOptions,
- value = index,
- onDismiss = { showDialog = false },
- onConfirm = {
-
- val cropThemeChange = when (it) {
- 0 -> CropTheme.Light
- 1 -> CropTheme.Dark
- else -> CropTheme.System
- }
- onThemeChange(cropThemeChange)
- showDialog = false
- }
- )
- }
-
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropTypeSelection.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropTypeSelection.kt
deleted file mode 100644
index 6fa115e..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropTypeSelection.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.foundation.border
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.Text
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import com.smarttoolfactory.cropper.settings.CropType
-
-@Composable
-internal fun CropTypeExposedSelection(
- cropType: CropType,
- onCropTypeChange: (CropType) -> Unit
-) {
- val cropTypeOptions =
- remember { listOf(CropType.Dynamic.toString(), CropType.Static.toString()) }
-
- val index = when (cropType) {
- CropType.Dynamic -> 0
- else -> 1
- }
-
- ExposedSelectionMenu(
- modifier = Modifier
- .fillMaxWidth()
- .border(2.dp, Color.Cyan),
- index = index,
- title = "Crop Type",
- options = cropTypeOptions,
- onSelected = {
- val newCropType = when (it) {
- 0 -> CropType.Dynamic
- else -> CropType.Static
- }
-
- onCropTypeChange(newCropType)
- }
- )
-}
-
-@Composable
-internal fun CropTypeDialogSelection(
- cropType: CropType,
- onCropTypeChange: (CropType) -> Unit
-) {
-
- val cropTypeOptions =
- remember { listOf(CropType.Dynamic.toString(), CropType.Static.toString()) }
-
- var showDialog by remember { mutableStateOf(false) }
-
- val index = when (cropType) {
- CropType.Dynamic -> 0
- else -> 1
- }
-
- Text(
- text = cropTypeOptions[index],
- fontSize = 18.sp,
- modifier = Modifier
- .fillMaxWidth()
- .clickable {
- showDialog = true
- }
- .padding(8.dp)
-
- )
-
- if (showDialog) {
- DialogWithMultipleSelection(
- title = "Crop Type",
- options = cropTypeOptions,
- value = index,
- onDismiss = { showDialog = false },
- onConfirm = {
-
- val cropTypeChange = when (it) {
- 0 -> CropType.Dynamic
- else -> CropType.Static
- }
- onCropTypeChange(cropTypeChange)
- showDialog = false
- }
- )
- }
-
-}
-
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/PropertySelectionSheet.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/PropertySelectionSheet.kt
deleted file mode 100644
index c00a4c7..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/PropertySelectionSheet.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.runtime.Composable
-import com.smarttoolfactory.cropper.settings.CropFrameFactory
-import com.smarttoolfactory.cropper.settings.CropProperties
-
-@Composable
-internal fun PropertySelectionSheet(
- cropFrameFactory:CropFrameFactory,
- cropProperties: CropProperties,
- onCropPropertiesChange: (CropProperties) -> Unit
-) {
- BaseSheet {
- CropPropertySelectionMenu(
- cropFrameFactory =cropFrameFactory,
- cropProperties = cropProperties,
- onCropPropertiesChange = onCropPropertiesChange
- )
-
- CropGestureSelectionMenu(
- cropProperties = cropProperties,
- onCropPropertiesChange = onCropPropertiesChange
- )
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/SelctionWidgets.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/SelctionWidgets.kt
deleted file mode 100644
index f8ecb4f..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/SelctionWidgets.kt
+++ /dev/null
@@ -1,321 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences
-
-import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.selection.selectable
-import androidx.compose.foundation.selection.selectableGroup
-import androidx.compose.material.RadioButton
-import androidx.compose.material3.*
-import androidx.compose.runtime.*
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.semantics.Role
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.TextUnit
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import com.smarttoolfactory.slider.ColorfulSlider
-import com.smarttoolfactory.slider.MaterialSliderColors
-import com.smarttoolfactory.slider.MaterialSliderDefaults
-import com.smarttoolfactory.slider.SliderBrushColor
-
-@Composable
-internal fun DpSliderSelection(
- value: Dp,
- onValueChange: (Dp) -> Unit,
- lowerBound: Dp,
- upperBound: Dp
-) {
-
- val density = LocalDensity.current
- val strokeWidthPx = density.run { value.toPx() }
- val lowerBoundPx = density.run { lowerBound.toPx() }
- val upperBoundPx = density.run { upperBound.toPx() }
-
- SliderSelection(
- value = strokeWidthPx,
- onValueChange = {
- onValueChange(
- density.run { it.toDp() }
- )
- },
- valueRange = lowerBoundPx..upperBoundPx
- )
-}
-
-@Composable
-internal fun SliderWithValueSelection(
- modifier: Modifier = Modifier,
- value: Float,
- title: String = "",
- text: String,
- onValueChange: (Float) -> Unit,
- valueRange: ClosedFloatingPointRange,
- colors: MaterialSliderColors = MaterialSliderDefaults.materialColors(
- activeTrackColor = SliderBrushColor(MaterialTheme.colorScheme.primary),
- inactiveTrackColor = SliderBrushColor(Color.Transparent),
- thumbColor = SliderBrushColor(MaterialTheme.colorScheme.inversePrimary)
- )
-) {
- Column {
-
- Text(
- text = if (title.isNotEmpty()) "$title $text" else text,
- fontSize = 12.sp,
- color = MaterialTheme.colorScheme.tertiary,
- fontWeight = FontWeight.Bold
- )
-
- Row(
- modifier = modifier,
- verticalAlignment = Alignment.CenterVertically
- ) {
- ColorfulSlider(
- modifier = Modifier.weight(1f),
- value = value,
- onValueChange = onValueChange,
- valueRange = valueRange,
- colors = colors,
- trackHeight = 10.dp,
- thumbRadius = 12.dp
- )
- }
- }
-}
-
-@Composable
-internal fun SliderSelection(
- modifier: Modifier = Modifier,
- value: Float,
- valueRange: ClosedFloatingPointRange,
- colors: MaterialSliderColors = MaterialSliderDefaults.materialColors(
- activeTrackColor = SliderBrushColor(MaterialTheme.colorScheme.primary),
- inactiveTrackColor = SliderBrushColor(Color.Transparent)
- ),
- onValueChangeFinished: (() -> Unit)? = null,
- onValueChange: (Float) -> Unit,
-) {
- ColorfulSlider(
- modifier = modifier,
- value = value,
- onValueChange = onValueChange,
- valueRange = valueRange,
- colors = colors,
- borderStroke = BorderStroke(2.dp, MaterialTheme.colorScheme.primary),
- trackHeight = 10.dp,
- thumbRadius = 12.dp,
- onValueChangeFinished = onValueChangeFinished
- )
-}
-
-@Composable
-internal fun Title(
- text: String,
- fontSize: TextUnit = 20.sp
-) {
- Text(
- modifier = Modifier.padding(vertical = 1.dp),
- text = text,
- color = MaterialTheme.colorScheme.primary,
- fontSize = fontSize,
- fontWeight = FontWeight.Bold
- )
-}
-
-
-@Composable
-internal fun FullRowSwitch(
- label: String,
- state: Boolean,
- onStateChange: (Boolean) -> Unit
-) {
-
- // Switch with text on right side
- Row(modifier = Modifier
- .fillMaxWidth()
- .clickable(
- interactionSource = remember { MutableInteractionSource() },
- indication = null,
- role = Role.Switch,
- onClick = {
- onStateChange(!state)
- }
- )
- .padding(8.dp),
- verticalAlignment = Alignment.CenterVertically
- ) {
-
- Text(text = label, modifier = Modifier.weight(1f))
-
- Switch(
- checked = state,
- onCheckedChange = null
- )
- }
-}
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-internal fun CropTextField(value: String, onValueChange: (String) -> Unit) {
- TextField(
- value = value,
- onValueChange = onValueChange,
- colors = TextFieldDefaults.textFieldColors(
- containerColor = Color.Transparent,
- focusedIndicatorColor = Color.Transparent,
- unfocusedIndicatorColor = Color.Transparent,
- disabledIndicatorColor = Color.Transparent
- )
- )
-}
-
-@Composable
-internal fun DialogWithMultipleSelection(
- title: String = "",
- options: List,
- value: Int,
- onDismiss: () -> Unit,
- onConfirm: (Int) -> Unit
-) {
-
- val (selectedOption: Int, onOptionSelected: (Int) -> Unit) = remember {
- mutableStateOf(value)
- }
-
- AlertDialog(
- onDismissRequest = { onDismiss() },
- title = {
- Text(
- title,
- fontSize = 18.sp,
- fontWeight = FontWeight.Bold,
- color = MaterialTheme.colorScheme.primary
- )
- },
- text = {
-
- // Note that Modifier.selectableGroup()
- // is essential to ensure correct accessibility behavior
- Column(Modifier.selectableGroup()) {
- options.forEachIndexed { index, text ->
- Row(
- Modifier
- .fillMaxWidth()
- .selectable(
- selected = (index == selectedOption),
- onClick = { onOptionSelected(index) },
- role = Role.RadioButton
- )
- .padding(horizontal = 4.dp, vertical = 8.dp),
- verticalAlignment = Alignment.CenterVertically
- ) {
- RadioButton(
- selected = (index == selectedOption),
- onClick = null
- )
- Spacer(modifier = Modifier.width(8.dp))
- Text(
- text = text,
- fontSize = 18.sp,
- )
- }
- }
- }
- },
- confirmButton = {
- TextButton(
- onClick = {
- onConfirm(selectedOption)
- }
- ) {
- Text(text = "Accept")
- }
- },
- dismissButton = {
- TextButton(
- onClick = {
- onDismiss()
- }
- ) {
- Text(text = "Cancel")
- }
- }
- )
-}
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-internal fun ExposedSelectionMenu(
- modifier: Modifier = Modifier,
- index: Int,
- title: String? = null,
- textStyle: TextStyle = TextStyle(
- fontWeight = FontWeight.W600,
- fontSize = 14.sp
- ),
- colors: TextFieldColors = ExposedDropdownMenuDefaults.textFieldColors(
- containerColor = Color.Transparent,
- focusedIndicatorColor = Color.Transparent,
- unfocusedIndicatorColor = Color.Transparent,
- disabledIndicatorColor = Color.Transparent
- ),
- options: List,
- onSelected: (Int) -> Unit
-) {
-
- var expanded by remember { mutableStateOf(false) }
- var selectedOptionText by remember { mutableStateOf(options[index]) }
-
- ExposedDropdownMenuBox(
- modifier = modifier,
- expanded = expanded,
- onExpandedChange = {
- expanded = !expanded
- }
- ) {
- TextField(
- modifier = modifier,
- readOnly = true,
- value = selectedOptionText,
- onValueChange = { },
- label = {
- title?.let {
- Text(it)
- }
- },
- trailingIcon = {
- ExposedDropdownMenuDefaults.TrailingIcon(
- expanded = expanded
- )
- },
- colors = colors,
- textStyle = textStyle
- )
- ExposedDropdownMenu(
- expanded = expanded,
- onDismissRequest = {
- expanded = false
-
- }
- ) {
- options.forEachIndexed { index: Int, selectionOption: String ->
- DropdownMenuItem(
- onClick = {
- selectedOptionText = selectionOption
- expanded = false
- onSelected(index)
- },
- text = {
- Text(text = selectionOption)
- }
- )
- }
- }
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CropFrameEditDialog.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CropFrameEditDialog.kt
deleted file mode 100644
index ee90b00..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CropFrameEditDialog.kt
+++ /dev/null
@@ -1,130 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences.frames.edit
-
-import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Text
-import androidx.compose.material3.TextButton
-import androidx.compose.runtime.*
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.res.imageResource
-import com.smarttoolfactory.cropper.R
-import com.smarttoolfactory.cropper.model.*
-
-@Composable
-fun CropFrameEditDialog(
- aspectRatio: AspectRatio,
- index: Int,
- cropFrame: CropFrame,
- onConfirm: (CropFrame) -> Unit,
- onDismiss: () -> Unit
-) {
-
- val dstBitmap = ImageBitmap.imageResource(id = R.drawable.landscape2)
-
- val outlineType = cropFrame.outlineType
-
- var outline: CropOutline by remember {
- mutableStateOf(cropFrame.outlines[index])
- }
-
- AlertDialog(
- onDismissRequest = onDismiss,
- text = {
- when (outlineType) {
- OutlineType.RoundedRect -> {
-
- val shape = outline as RoundedCornerCropShape
-
- RoundedCornerCropShapeEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- title = outline.title,
- roundedCornerCropShape = shape
- ) {
- outline = it
- }
- }
- OutlineType.CutCorner -> {
- val shape = outline as CutCornerCropShape
-
- CutCornerCropShapeEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- title = outline.title,
- cutCornerCropShape = shape
- ) {
- outline = it
- }
- }
- OutlineType.Oval -> {
-
- val shape = outline as OvalCropShape
-
- OvalCropShapeEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- title = outline.title,
- ovalCropShape = shape
- ) {
- outline = it
- }
- }
- OutlineType.Polygon -> {
-
- val shape = outline as PolygonCropShape
-
- PolygonCropShapeEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- title = outline.title,
- polygonCropShape = shape
- ) {
- outline = it
- }
- }
- OutlineType.ImageMask -> {
- val imageMaskOutline = outline as ImageMaskOutline
- ImageMaskEdit(imageMaskOutline) {
- outline = it
- }
- }
- OutlineType.Custom -> {
- val customPathOutline = outline as CustomPathOutline
- CustomPathEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- customPathOutline = customPathOutline,
- ) {
- outline = it
- }
- }
- else -> Unit
- }
- },
- confirmButton = {
- TextButton(
- onClick = {
- val newOutlines: List = cropFrame.outlines
- .toMutableList()
- .apply {
- set(index, outline)
- }
- .toList()
-
- val newCropFrame = cropFrame.copy(
- cropOutlineContainer = getOutlineContainer(outlineType, index, newOutlines)
- )
-
- onConfirm(newCropFrame)
- }) {
- Text("Accept")
- }
- },
- dismissButton = {
- TextButton(
- onClick = { onDismiss() }
- ) {
- Text(text = "Cancel")
- }
- }
- )
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CropShapeAddDialog.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CropShapeAddDialog.kt
deleted file mode 100644
index 633bd47..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CropShapeAddDialog.kt
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences.frames.edit
-
-import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Text
-import androidx.compose.material3.TextButton
-import androidx.compose.runtime.*
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.res.imageResource
-import com.smarttoolfactory.cropper.R
-import com.smarttoolfactory.cropper.model.*
-
-@Composable
-fun CropShapeAddDialog(
- aspectRatio: AspectRatio,
- cropFrame: CropFrame,
- onConfirm: (CropFrame) -> Unit,
- onDismiss: () -> Unit
-) {
-
- val dstBitmap = ImageBitmap.imageResource(id = R.drawable.landscape2)
-
- val outlineType = cropFrame.outlineType
-
- var outline: CropOutline by remember {
- mutableStateOf(cropFrame.copy().outlines[0])
- }
-
- AlertDialog(
- onDismissRequest = onDismiss,
- text = {
- when (outlineType) {
- OutlineType.RoundedRect -> {
-
- val shape = outline as RoundedCornerCropShape
-
- RoundedCornerCropShapeEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- title = outline.title,
- roundedCornerCropShape = shape
- ) {
- outline = it
- }
- }
- OutlineType.CutCorner -> {
- val shape = outline as CutCornerCropShape
-
- CutCornerCropShapeEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- title = outline.title,
- cutCornerCropShape = shape
- ) {
- outline = it
- }
- }
- OutlineType.Oval -> {
-
- val shape = outline as OvalCropShape
-
- OvalCropShapeEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- title = outline.title,
- ovalCropShape = shape
- ) {
- outline = it
- }
- }
- OutlineType.Polygon -> {
-
- val shape = outline as PolygonCropShape
-
- PolygonCropShapeEdit(
- aspectRatio = aspectRatio,
- dstBitmap = dstBitmap,
- title = outline.title,
- polygonCropShape = shape
- ) {
- outline = it
- }
- }
- else -> Unit
- }
- },
- confirmButton = {
- TextButton(onClick = {
-
- val newOutlines: List = cropFrame.outlines
- .toMutableList()
- .apply {
- add(outline)
- }
- .toList()
-
- val newCropFrame = cropFrame.copy(
- cropOutlineContainer = getOutlineContainer(
- outlineType = outlineType,
- index = newOutlines.size - 1,
- outlines = newOutlines
- )
- )
-
- onConfirm(newCropFrame)
- }) {
- Text("Accept")
- }
- },
- dismissButton = {
- TextButton(onClick = { onDismiss() }) {
- Text(text = "Cancel")
- }
- }
- )
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CustomPathEdit.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CustomPathEdit.kt
deleted file mode 100644
index a9cac2f..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CustomPathEdit.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences.frames.edit
-
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.aspectRatio
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clipToBounds
-import androidx.compose.ui.draw.drawWithCache
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.graphics.Path
-import com.smarttoolfactory.composecropper.preferences.CropTextField
-import com.smarttoolfactory.cropper.model.AspectRatio
-import com.smarttoolfactory.cropper.model.CustomPathOutline
-import com.smarttoolfactory.cropper.util.calculateSizeAndOffsetFromAspectRatio
-import com.smarttoolfactory.cropper.util.drawBlockWithCheckerAndLayer
-import com.smarttoolfactory.cropper.util.scaleAndTranslatePath
-
-@Composable
-internal fun CustomPathEdit(
- aspectRatio: AspectRatio,
- dstBitmap: ImageBitmap,
- customPathOutline: CustomPathOutline,
- onChange: (CustomPathOutline) -> Unit
-) {
- var newTitle by remember {
- mutableStateOf(customPathOutline.title)
- }
-
- Column {
-
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .clipToBounds()
- .aspectRatio(4 / 3f)
- .drawWithCache {
-
- val path = Path().apply {
- addPath(customPathOutline.path)
-
- val (newSize, offset) = calculateSizeAndOffsetFromAspectRatio(
- aspectRatio = aspectRatio,
- coefficient = 1f,
- size = size
- )
- scaleAndTranslatePath(newSize.width, newSize.height)
- translate(offset)
- }
-
- onDrawWithContent {
- drawBlockWithCheckerAndLayer(dstBitmap) {
- drawPath(path, Color.Red)
-
- }
- }
- }
-
- )
-
- CropTextField(
- value = newTitle,
- onValueChange = {
- newTitle = it
- onChange(
- customPathOutline.copy(
- title = newTitle
- )
- )
-
- }
- )
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CutCornerCropShapeEdit.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CutCornerCropShapeEdit.kt
deleted file mode 100644
index c7c288a..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/CutCornerCropShapeEdit.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences.frames.edit
-
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.shape.CutCornerShape
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clipToBounds
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.composecropper.preferences.CropTextField
-import com.smarttoolfactory.composecropper.preferences.SliderWithValueSelection
-import com.smarttoolfactory.cropper.model.AspectRatio
-import com.smarttoolfactory.cropper.model.CornerRadiusProperties
-import com.smarttoolfactory.cropper.model.CutCornerCropShape
-import com.smarttoolfactory.cropper.util.drawOutlineWithBlendModeAndChecker
-import kotlin.math.roundToInt
-
-@Composable
-internal fun CutCornerCropShapeEdit(
- aspectRatio: AspectRatio,
- dstBitmap: ImageBitmap,
- title: String,
- cutCornerCropShape: CutCornerCropShape,
- onChange: (CutCornerCropShape) -> Unit
-) {
-
- var newTitle by remember {
- mutableStateOf(title)
- }
-
- val cornerRadius = remember {
- cutCornerCropShape.cornerRadius
- }
-
- var topStart by remember {
- mutableStateOf(
- cornerRadius.topStart
- )
- }
-
- var topEnd by remember {
- mutableStateOf(
- cornerRadius.topEnd.toFloat()
- )
- }
-
- var bottomStart by remember {
- mutableStateOf(
- cornerRadius.bottomStart.toFloat()
- )
- }
-
- var bottomEnd by remember {
- mutableStateOf(
- cornerRadius.bottomEnd.toFloat()
- )
- }
-
- val shape by remember {
- derivedStateOf {
- CutCornerShape(
- topStart = topStart,
- topEnd = topEnd,
- bottomStart = bottomStart,
- bottomEnd = bottomEnd
- )
- }
- }
-
- onChange(
- cutCornerCropShape.copy(
- cornerRadius = CornerRadiusProperties(
- topStart = topStart,
- topEnd = topEnd,
- bottomStart = bottomStart,
- bottomEnd = bottomEnd
- ),
- title = newTitle,
- shape = shape
- )
- )
-
- Column {
-
- val density = LocalDensity.current
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .aspectRatio(4 / 3f)
- .clipToBounds()
- .drawOutlineWithBlendModeAndChecker(
- aspectRatio,
- shape,
- density,
- dstBitmap
- )
- )
-
- CropTextField(
- value = newTitle,
- onValueChange = { newTitle = it }
- )
-
- Spacer(modifier = Modifier.height(10.dp))
-
- SliderWithValueSelection(
- value = topStart,
- title = "Top Start",
- text = "${(topStart * 10f).roundToInt() / 10f}%",
- onValueChange = { topStart = it },
- valueRange = 0f..100f
- )
- SliderWithValueSelection(
- value = topEnd,
- title = "Top End",
- text = "${(topEnd * 10f).roundToInt() / 10f}%",
- onValueChange = { topEnd = it },
- valueRange = 0f..100f
- )
- SliderWithValueSelection(
- value = bottomStart,
- title = "Bottom Start",
- text = "${(bottomStart * 10f).roundToInt() / 10f}%",
- onValueChange = { bottomStart = it },
- valueRange = 0f..100f
- )
- SliderWithValueSelection(
- value = bottomEnd,
- title = "Bottom End",
- text = "${(bottomEnd * 10f).roundToInt() / 10f}%",
- onValueChange = { bottomEnd = it },
- valueRange = 0f..100f
- )
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/ImageMaskEdit.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/ImageMaskEdit.kt
deleted file mode 100644
index d80bd18..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/ImageMaskEdit.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences.frames.edit
-
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.runtime.*
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import com.smarttoolfactory.composecropper.preferences.CropTextField
-import com.smarttoolfactory.cropper.model.ImageMaskOutline
-
-@Composable
-internal fun ImageMaskEdit(
- imageMaskOutline: ImageMaskOutline,
- onChange: (ImageMaskOutline) -> Unit
-) {
-
- var newTitle by remember {
- mutableStateOf(imageMaskOutline.title)
- }
-
- Column {
-
- Box(
- modifier = Modifier.fillMaxWidth(),
- contentAlignment = Alignment.Center
- ) {
- Image(bitmap = imageMaskOutline.image, contentDescription = "ImageMask")
-
- }
- CropTextField(
- value = newTitle,
- onValueChange = {
- newTitle = it
- onChange(
- imageMaskOutline.copy(
- title = newTitle
- )
- )
-
- }
- )
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/OvalCropShapeEdit.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/OvalCropShapeEdit.kt
deleted file mode 100644
index 228516f..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/OvalCropShapeEdit.kt
+++ /dev/null
@@ -1,149 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences.frames.edit
-
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.shape.GenericShape
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clipToBounds
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.geometry.Rect
-import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.composecropper.preferences.CropTextField
-import com.smarttoolfactory.composecropper.preferences.SliderWithValueSelection
-import com.smarttoolfactory.cropper.model.AspectRatio
-import com.smarttoolfactory.cropper.model.OvalCropShape
-import com.smarttoolfactory.cropper.util.drawOutlineWithBlendModeAndChecker
-
-
-@Composable
-internal fun OvalCropShapeEdit(
- aspectRatio: AspectRatio,
- dstBitmap: ImageBitmap,
- title: String,
- ovalCropShape: OvalCropShape,
- onChange: (OvalCropShape) -> Unit
-) {
-
- var newTitle by remember {
- mutableStateOf(title)
- }
-
- val ovalProperties = remember {
- ovalCropShape.ovalProperties
- }
-
- var startAngle by remember {
- mutableStateOf(
- ovalProperties.startAngle
- )
- }
-
- var sweepAngle by remember {
- mutableStateOf(
- ovalProperties.sweepAngle
- )
- }
-
- var offsetX by remember {
- mutableStateOf(
- ovalProperties.offset.x
- )
- }
-
- var offsetY by remember {
- mutableStateOf(
- ovalProperties.offset.y
- )
- }
-
- val shape by remember(startAngle, sweepAngle) {
- derivedStateOf {
- GenericShape { size: Size, _: LayoutDirection ->
- val width = size.width
- val height = size.height
- val diameter = width.coerceAtMost(height)
- val left = (width - diameter) / 2
- val top = (height - diameter) / 2
-
- val rect = Rect(offset = Offset(left, top), size = Size(diameter, diameter))
-
- if (sweepAngle == 360f) {
- addOval(rect)
- } else {
- moveTo(size.width / 2, size.height / 2)
- arcTo(rect, startAngle, sweepAngle, false)
-
- }
-
- close()
- }
- }
- }
-
- onChange(
- ovalCropShape.copy(
- ovalProperties = ovalProperties.copy(
- startAngle = startAngle,
- sweepAngle = sweepAngle
- ),
- title = newTitle,
- shape = shape
- )
- )
-
- Column {
-
- val density = LocalDensity.current
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .aspectRatio(4 / 3f)
- .clipToBounds()
- .drawOutlineWithBlendModeAndChecker(
- aspectRatio,
- shape,
- density,
- dstBitmap
- )
- )
-
- CropTextField(
- value = newTitle,
- onValueChange = { newTitle = it }
- )
-
- Spacer(modifier = Modifier.height(10.dp))
-
- SliderWithValueSelection(
- value = startAngle,
- title = "Start Angle",
- text = "${startAngle.toInt()}°",
- onValueChange = { startAngle = it },
- valueRange = 0f..360f
- )
- SliderWithValueSelection(
- value = sweepAngle,
- title = "Sweep Angle",
- text = "${sweepAngle.toInt()}°",
- onValueChange = { sweepAngle = it },
- valueRange = 0f..360f
- )
-
- // TODO Add offset
-// Slider(
-// value = offsetX,
-// onValueChange = { offsetX = it },
-// valueRange = 0f..100f
-// )
-// Slider(
-// value = offsetY,
-// onValueChange = { offsetY = it },
-// valueRange = 0f..100f
-// )
-
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/PolygonCropShapeEdit.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/PolygonCropShapeEdit.kt
deleted file mode 100644
index ac9c87e..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/PolygonCropShapeEdit.kt
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences.frames.edit
-
-import androidx.compose.foundation.layout.*
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clipToBounds
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.composecropper.preferences.CropTextField
-import com.smarttoolfactory.composecropper.preferences.SliderWithValueSelection
-import com.smarttoolfactory.cropper.model.AspectRatio
-import com.smarttoolfactory.cropper.model.PolygonCropShape
-import com.smarttoolfactory.cropper.util.createPolygonShape
-import com.smarttoolfactory.cropper.util.drawOutlineWithBlendModeAndChecker
-
-@Composable
-internal fun PolygonCropShapeEdit(
- aspectRatio: AspectRatio,
- dstBitmap: ImageBitmap,
- title: String,
- polygonCropShape: PolygonCropShape,
- onChange: (PolygonCropShape) -> Unit
-) {
-
- var newTitle by remember {
- mutableStateOf(title)
- }
-
- val polygonProperties = remember {
- polygonCropShape.polygonProperties
- }
-
- var sides by remember {
- mutableStateOf(
- polygonProperties.sides
- )
- }
-
- var angle by remember {
- mutableStateOf(
- polygonProperties.angle
- )
- }
-
- var shape by remember {
- mutableStateOf(
- polygonCropShape.shape
- )
- }
-
- onChange(
- polygonCropShape.copy(
- polygonProperties = polygonProperties.copy(
- sides = sides,
- angle = angle
- ),
- title = newTitle,
- shape = shape
- )
- )
-
- Column {
-
- val density = LocalDensity.current
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .aspectRatio(4 / 3f)
- .clipToBounds()
- .drawOutlineWithBlendModeAndChecker(
- aspectRatio,
- shape,
- density,
- dstBitmap
- )
- )
-
- CropTextField(
- value = newTitle,
- onValueChange = { newTitle = it }
- )
-
- Spacer(modifier = Modifier.height(10.dp))
-
- SliderWithValueSelection(
- value = sides.toFloat(),
- title="Sides",
- text = "$sides",
- onValueChange = {
- sides = it.toInt()
- shape = createPolygonShape(sides = sides, angle)
- },
- valueRange = 3f..15f
- )
-
- SliderWithValueSelection(
- value = angle,
- title="Angle",
- text = "${angle.toInt()}°",
- onValueChange = {
- angle = it
- shape = createPolygonShape(sides = sides, degrees = angle)
- },
- valueRange = 0f..360f
- )
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/RoundedCornerCropShapeEdit.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/RoundedCornerCropShapeEdit.kt
deleted file mode 100644
index 30feee4..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/edit/RoundedCornerCropShapeEdit.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.smarttoolfactory.composecropper.preferences.frames.edit
-
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clipToBounds
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.unit.dp
-import com.smarttoolfactory.composecropper.preferences.CropTextField
-import com.smarttoolfactory.composecropper.preferences.SliderWithValueSelection
-import com.smarttoolfactory.cropper.model.AspectRatio
-import com.smarttoolfactory.cropper.model.CornerRadiusProperties
-import com.smarttoolfactory.cropper.model.RoundedCornerCropShape
-import com.smarttoolfactory.cropper.util.drawOutlineWithBlendModeAndChecker
-import kotlin.math.roundToInt
-
-@Composable
-internal fun RoundedCornerCropShapeEdit(
- aspectRatio: AspectRatio,
- dstBitmap: ImageBitmap,
- title: String,
- roundedCornerCropShape: RoundedCornerCropShape,
- onChange: (RoundedCornerCropShape) -> Unit
-) {
-
- var newTitle by remember {
- mutableStateOf(title)
- }
-
- val cornerRadius = remember {
- roundedCornerCropShape.cornerRadius
- }
-
- var topStart by remember {
- mutableStateOf(
- cornerRadius.topStart
- )
- }
-
- var topEnd by remember {
- mutableStateOf(
- cornerRadius.topEnd
- )
- }
-
- var bottomStart by remember {
- mutableStateOf(
- cornerRadius.bottomStart
- )
- }
-
- var bottomEnd by remember {
- mutableStateOf(
- cornerRadius.bottomEnd
- )
- }
-
- val shape by remember {
- derivedStateOf {
- RoundedCornerShape(
- topStart = topStart,
- topEnd = topEnd,
- bottomStart = bottomStart,
- bottomEnd = bottomEnd
- )
- }
- }
-
- onChange(
- roundedCornerCropShape.copy(
- cornerRadius = CornerRadiusProperties(
- topStart = topStart,
- topEnd = topEnd,
- bottomStart = bottomStart,
- bottomEnd = bottomEnd
- ),
- title = newTitle,
- shape = shape
- )
- )
-
- Column {
-
- val density = LocalDensity.current
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .aspectRatio(4 / 3f)
- .clipToBounds()
- .drawOutlineWithBlendModeAndChecker(
- aspectRatio,
- shape,
- density,
- dstBitmap
- )
- )
-
- CropTextField(
- value = newTitle,
- onValueChange = { newTitle = it }
- )
-
- Spacer(modifier=Modifier.height(10.dp))
-
- SliderWithValueSelection(
- value = topStart,
- title = "Top Start",
- text = "${(topStart * 10f).roundToInt() / 10f}%",
- onValueChange = { topStart = it },
- valueRange = 0f..100f
- )
- SliderWithValueSelection(
- value = topEnd,
- title = "Top End",
- text = "${(topEnd * 10f).roundToInt() / 10f}%",
- onValueChange = { topEnd = it },
- valueRange = 0f..100f
- )
- SliderWithValueSelection(
- value = bottomStart,
- title = "Bottom Start",
- text = "${(bottomStart * 10f).roundToInt() / 10f}%",
- onValueChange = { bottomStart = it },
- valueRange = 0f..100f
- )
- SliderWithValueSelection(
- value = bottomEnd,
- title = "Bottom End",
- text = "${(bottomEnd * 10f).roundToInt() / 10f}%",
- onValueChange = { bottomEnd = it },
- valueRange = 0f..100f
- )
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/list/CropFrameListDialog.kt b/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/list/CropFrameListDialog.kt
deleted file mode 100644
index 1c02b62..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/preferences/frames/list/CropFrameListDialog.kt
+++ /dev/null
@@ -1,474 +0,0 @@
-import android.annotation.SuppressLint
-import android.graphics.Bitmap
-import android.graphics.ImageDecoder
-import android.os.Build
-import android.provider.MediaStore
-import androidx.activity.compose.rememberLauncherForActivityResult
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
-import androidx.compose.foundation.border
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.lazy.grid.GridCells
-import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
-import androidx.compose.foundation.lazy.grid.itemsIndexed
-import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Add
-import androidx.compose.material.icons.filled.Delete
-import androidx.compose.material.icons.filled.Edit
-import androidx.compose.material3.*
-import androidx.compose.runtime.*
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.draw.drawWithCache
-import androidx.compose.ui.draw.shadow
-import androidx.compose.ui.graphics.*
-import androidx.compose.ui.graphics.drawscope.translate
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import com.google.modernstorage.photopicker.PhotoPicker
-import com.smarttoolfactory.composecropper.preferences.frames.edit.CropFrameEditDialog
-import com.smarttoolfactory.composecropper.preferences.frames.edit.CropShapeAddDialog
-import com.smarttoolfactory.cropper.model.*
-import com.smarttoolfactory.cropper.util.buildOutline
-import com.smarttoolfactory.cropper.util.scaleAndTranslatePath
-
-/**
- * Dialog for displaying selectable crop frames with edit, delete and new frame options
- */
-@Composable
-fun CropFrameListDialog(
- aspectRatio: AspectRatio,
- cropFrame: CropFrame,
- onDismiss: () -> Unit,
- onConfirm: (CropFrame) -> Unit
-) {
- var updatedCropFrame by remember {
- mutableStateOf(cropFrame)
- }
-
- var selectedIndex by remember {
- mutableStateOf(updatedCropFrame.selectedIndex)
- }
-
- val outlineType = cropFrame.outlineType
-
- var showEditDialog by remember { mutableStateOf(false) }
- var showAddDialog by remember { mutableStateOf(false) }
-
-
- if (showEditDialog) {
- CropFrameEditDialog(
- aspectRatio = aspectRatio,
- index = selectedIndex,
- cropFrame = updatedCropFrame,
- onConfirm = {
- updatedCropFrame = it
- selectedIndex = updatedCropFrame.selectedIndex
- showEditDialog = false
- },
- onDismiss = {
- showEditDialog = false
- }
- )
- }
-
- if (showAddDialog) {
-
- val outline = updatedCropFrame.cropOutlineContainer.selectedItem
- if (outline is CropShape) {
- CropShapeAddDialog(
- aspectRatio = aspectRatio,
- cropFrame = updatedCropFrame.copy(),
- onConfirm = {
- updatedCropFrame = it
- selectedIndex = updatedCropFrame.selectedIndex
- showAddDialog = false
- },
- onDismiss = {
- showAddDialog = false
- }
- )
- } else if (outline is CropImageMask) {
-
- PickImageMask {
-
- val id = updatedCropFrame.outlineCount
- val newOutline =
- ImageMaskOutline(id = updatedCropFrame.outlineCount, "ImageMask $id", it)
-
- val newOutlines: List = cropFrame.outlines
- .toMutableList()
- .apply {
- add(newOutline)
- }
- .toList()
-
- updatedCropFrame = cropFrame.copy(
- cropOutlineContainer = getOutlineContainer(
- outlineType = outlineType,
- index = newOutlines.size - 1,
- outlines = newOutlines
- )
- )
-
- selectedIndex = updatedCropFrame.selectedIndex
- }
- }
- }
-
- AlertDialog(
- onDismissRequest = {
- onDismiss()
- },
- title = {
- Row(
- modifier = Modifier.fillMaxWidth(),
- verticalAlignment = Alignment.CenterVertically
- ) {
- Text(
- text = "Frames",
- fontSize = 24.sp,
- fontWeight = FontWeight.Bold,
- color = MaterialTheme.colorScheme.primary
- )
- Spacer(modifier = Modifier.weight(1f))
-
- val enabled = selectedIndex != 0
-
- Icon(
- modifier = Modifier
- .clip(CircleShape)
- .background(
- if (enabled) MaterialTheme.colorScheme.error
- else Color.LightGray
- )
- .size(28.dp)
- .clickable(
- enabled = enabled,
- onClick = {
- val outlines = updatedCropFrame.outlines
- .toMutableList()
- .apply {
- removeAt(selectedIndex)
- }
- updatedCropFrame = updatedCropFrame.copy(
- cropOutlineContainer = getOutlineContainer(
- updatedCropFrame.outlineType,
- outlines.size - 1,
- outlines
- )
- )
-
- selectedIndex = outlines.size - 1
- }
- )
- .padding(6.dp),
-
- imageVector = Icons.Default.Delete,
- tint = if (enabled) Color.White else Color.Gray,
- contentDescription = "Delete"
- )
-
- Spacer(modifier = Modifier.width(12.dp))
- Icon(
- modifier = Modifier
- .clip(CircleShape)
- .background(MaterialTheme.colorScheme.primary)
- .size(28.dp)
- .clickable {
- showEditDialog = true
- }
- .padding(6.dp),
- imageVector = Icons.Default.Edit,
- tint = Color.White,
- contentDescription = "Edit"
- )
- }
- },
- text = {
- CropOutlineGridList(
- modifier = Modifier
- .fillMaxWidth()
- .heightIn(min = 240.dp),
- selectedIndex = selectedIndex,
- outlineType = updatedCropFrame.outlineType,
- outlines = updatedCropFrame.outlines,
- aspectRatio = aspectRatio,
- onItemClick = {
- selectedIndex = it
- updatedCropFrame.selectedIndex = selectedIndex
- },
- onAddItemClick = {
- showAddDialog = true
- }
- )
- },
- dismissButton = {
- TextButton(
- onClick = {
- onDismiss()
- }
- ) {
-
- Text("Cancel")
- }
- },
- confirmButton = {
- TextButton(
- onClick = {
- onConfirm(updatedCropFrame)
- }
- ) {
- Text("Accept")
- }
- }
- )
-}
-
-@Composable
-private fun CropOutlineGridList(
- modifier: Modifier = Modifier,
- selectedIndex: Int,
- outlineType: OutlineType,
- outlines: List,
- aspectRatio: AspectRatio,
- onItemClick: (Int) -> Unit,
- onAddItemClick: () -> Unit
-) {
-
- LazyVerticalGrid(
- modifier = modifier,
- contentPadding = PaddingValues(2.dp),
- columns = GridCells.Fixed(3),
- horizontalArrangement = Arrangement.spacedBy(14.dp),
- verticalArrangement = Arrangement.spacedBy(14.dp)
- ) {
-
- itemsIndexed(
- items = outlines
- ) { index, cropOutline ->
-
- val selected = index == selectedIndex
- CropOutlineGridItem(
- Modifier
- .fillMaxWidth()
- .aspectRatio(1f),
- cropOutline = cropOutline,
- selected = selected,
- color = if (selected) MaterialTheme.colorScheme.primary else Color.Gray,
- aspectRatio = aspectRatio
- ) {
- onItemClick(index)
- }
- }
-
- if (outlineType != OutlineType.Custom) {
- item {
- AddItemButton(
- Modifier
- .fillMaxWidth()
- .aspectRatio(1f)
- ) {
- onAddItemClick()
- }
- }
- }
- }
-}
-
-@Composable
-private fun AddItemButton(
- modifier: Modifier = Modifier,
- onClick: () -> Unit
-) {
- Box(
- modifier = modifier
- .clickable {
- onClick()
- }
- .padding(2.dp),
- contentAlignment = Alignment.Center
- ) {
-
- Icon(
- modifier = Modifier
- .fillMaxWidth(.7f)
- .aspectRatio(1f),
- imageVector = Icons.Default.Add,
- contentDescription = "Add Outline",
- tint = Color.Gray
- )
-
- }
-}
-
-@Composable
-private fun CropOutlineGridItem(
- modifier: Modifier = Modifier,
- cropOutline: CropOutline,
- selected: Boolean,
- color: Color,
- aspectRatio: AspectRatio,
- onClick: () -> Unit,
-) {
-
- Box(
- modifier = modifier
- .shadow(2.dp, RoundedCornerShape(20))
- .border(2.dp, if (selected) color else Color.Unspecified, RoundedCornerShape(20))
- .background(MaterialTheme.colorScheme.surface)
- .clickable {
- onClick()
- },
- contentAlignment = Alignment.TopEnd
- ) {
-
- CropOutlineDisplay(
- modifier = Modifier
- .fillMaxWidth()
- .aspectRatio(1f),
- cropOutline = cropOutline,
- aspectRatio,
- color
- )
-
-
- Box(
- modifier = Modifier
- .align(Alignment.BottomStart)
- .fillMaxWidth()
- .background(MaterialTheme.colorScheme.primaryContainer.copy(alpha = .7f))
- .padding(horizontal = 8.dp, vertical = 6.dp),
- contentAlignment = Alignment.Center
- ) {
- Text(
- text = cropOutline.title,
- color = MaterialTheme.colorScheme.onPrimaryContainer,
- fontSize = 12.sp,
- maxLines = 1,
- fontWeight = FontWeight.Bold,
- overflow = TextOverflow.Ellipsis
- )
- }
- }
-}
-
-@Composable
-private fun CropOutlineDisplay(
- modifier: Modifier,
- cropOutline: CropOutline,
- aspectRatio: AspectRatio,
- color: Color
-) {
-
- val density = LocalDensity.current
-
- Box(
- modifier = modifier
- .fillMaxWidth()
- .aspectRatio(1f),
- ) {
-
- when (cropOutline) {
-
- is CropShape -> {
-
- Box(
- Modifier
- .matchParentSize()
- .drawWithCache {
- val coefficient = .8f
-
- val (offset, outline) = buildOutline(
- aspectRatio,
- coefficient,
- cropOutline.shape,
- size,
- layoutDirection,
- density
- )
-
- onDrawWithContent {
- translate(
- left = offset.x,
- top = offset.y
- ) {
- drawOutline(
- outline = outline,
- color = color
- )
- }
- drawContent()
- }
- }
- )
- }
- is CropPath -> {
- Box(
- Modifier
- .matchParentSize()
- .padding(12.dp)
- .drawWithCache {
-
- val path = Path().apply {
- addPath(cropOutline.path)
- scaleAndTranslatePath(size.width, size.height)
- }
-
- onDrawWithContent {
- drawPath(path, color)
- }
- }
- )
- }
- is CropImageMask -> {
- Box(
- modifier = Modifier
- .matchParentSize()
- .padding(4.dp),
- contentAlignment = Alignment.Center
- ) {
- Image(bitmap = cropOutline.image, contentDescription = "ImageMask")
- }
- }
- }
- }
-}
-
-@SuppressLint("UnsafeOptInUsageError")
-@Composable
-private fun PickImageMask(
- onImageSelected: (ImageBitmap) -> Unit
-
-) {
- val context = LocalContext.current
-
- val photoPicker = rememberLauncherForActivityResult(PhotoPicker()) { uris ->
- val uri = uris.firstOrNull() ?: return@rememberLauncherForActivityResult
-
- val bitmap: Bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- ImageDecoder.decodeBitmap(
- ImageDecoder.createSource(context.contentResolver, uri)
- ) { decoder, info, source ->
- decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
- decoder.isMutableRequired = true
- }
- } else {
- MediaStore.Images.Media.getBitmap(context.contentResolver, uri)
- }
-
- onImageSelected(bitmap.asImageBitmap())
- }
-
- LaunchedEffect(key1 = Unit) {
- photoPicker.launch(PhotoPicker.Args(PhotoPicker.Type.IMAGES_ONLY, 1))
- }
-}
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Color.kt b/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Color.kt
deleted file mode 100644
index 11ffb2a..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Color.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.smarttoolfactory.composecropper.ui.theme
-
-import androidx.compose.ui.graphics.Color
-
-val Purple80 = Color(0xFFD0BCFF)
-val PurpleGrey80 = Color(0xFFCCC2DC)
-val Pink80 = Color(0xFFEFB8C8)
-
-val Purple40 = Color(0xFF6650a4)
-val PurpleGrey40 = Color(0xFF625b71)
-val Pink40 = Color(0xFF7D5260)
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Theme.kt b/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Theme.kt
deleted file mode 100644
index a486e93..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Theme.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.smarttoolfactory.composecropper.ui.theme
-
-import android.app.Activity
-import android.os.Build
-import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.darkColorScheme
-import androidx.compose.material3.dynamicDarkColorScheme
-import androidx.compose.material3.dynamicLightColorScheme
-import androidx.compose.material3.lightColorScheme
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.SideEffect
-import androidx.compose.ui.graphics.toArgb
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalView
-import androidx.core.view.ViewCompat
-
-private val DarkColorScheme = darkColorScheme(
- primary = Purple80,
- secondary = PurpleGrey80,
- tertiary = Pink80
-)
-
-private val LightColorScheme = lightColorScheme(
- primary = Purple40,
- secondary = PurpleGrey40,
- tertiary = Pink40
-
- /* Other default colors to override
- background = Color(0xFFFFFBFE),
- surface = Color(0xFFFFFBFE),
- onPrimary = Color.White,
- onSecondary = Color.White,
- onTertiary = Color.White,
- onBackground = Color(0xFF1C1B1F),
- onSurface = Color(0xFF1C1B1F),
- */
-)
-
-@Composable
-fun ComposeCropperTheme(
- darkTheme: Boolean = isSystemInDarkTheme(),
- // Dynamic color is available on Android 12+
- dynamicColor: Boolean = true,
- content: @Composable () -> Unit
-) {
- val colorScheme = when {
- dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
- val context = LocalContext.current
- if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
- }
- darkTheme -> DarkColorScheme
- else -> LightColorScheme
- }
- val view = LocalView.current
- if (!view.isInEditMode) {
- SideEffect {
- (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
- ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme
- }
- }
-
- MaterialTheme(
- colorScheme = colorScheme,
- typography = Typography,
- content = content
- )
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Type.kt b/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Type.kt
deleted file mode 100644
index 3d525f6..0000000
--- a/app/src/main/java/com/smarttoolfactory/composecropper/ui/theme/Type.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.smarttoolfactory.composecropper.ui.theme
-
-import androidx.compose.material3.Typography
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.FontFamily
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.unit.sp
-
-// Set of Material typography styles to start with
-val Typography = Typography(
- bodyLarge = TextStyle(
- fontFamily = FontFamily.Default,
- fontWeight = FontWeight.Normal,
- fontSize = 16.sp,
- lineHeight = 24.sp,
- letterSpacing = 0.5.sp
- )
- /* Other default text styles to override
- titleLarge = TextStyle(
- fontFamily = FontFamily.Default,
- fontWeight = FontWeight.Normal,
- fontSize = 22.sp,
- lineHeight = 28.sp,
- letterSpacing = 0.sp
- ),
- labelSmall = TextStyle(
- fontFamily = FontFamily.Default,
- fontWeight = FontWeight.Medium,
- fontSize = 11.sp,
- lineHeight = 16.sp,
- letterSpacing = 0.5.sp
- )
- */
-)
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 2b068d1..0000000
--- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/cinnamon.jpg b/app/src/main/res/drawable/cinnamon.jpg
deleted file mode 100755
index 40d9fc0..0000000
Binary files a/app/src/main/res/drawable/cinnamon.jpg and /dev/null differ
diff --git a/app/src/main/res/drawable/cloud.png b/app/src/main/res/drawable/cloud.png
deleted file mode 100644
index 961414d..0000000
Binary files a/app/src/main/res/drawable/cloud.png and /dev/null differ
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index 07d5da9..0000000
--- a/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/drawable/landscape1.jpeg b/app/src/main/res/drawable/landscape1.jpeg
deleted file mode 100644
index 0e06844..0000000
Binary files a/app/src/main/res/drawable/landscape1.jpeg and /dev/null differ
diff --git a/app/src/main/res/drawable/landscape5.jpg b/app/src/main/res/drawable/landscape5.jpg
deleted file mode 100644
index 308ca6a..0000000
Binary files a/app/src/main/res/drawable/landscape5.jpg and /dev/null differ
diff --git a/app/src/main/res/drawable/squircle.png b/app/src/main/res/drawable/squircle.png
deleted file mode 100644
index 411adec..0000000
Binary files a/app/src/main/res/drawable/squircle.png and /dev/null differ
diff --git a/app/src/main/res/drawable/sun.png b/app/src/main/res/drawable/sun.png
deleted file mode 100755
index 054071c..0000000
Binary files a/app/src/main/res/drawable/sun.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
deleted file mode 100644
index eca70cf..0000000
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index eca70cf..0000000
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
deleted file mode 100644
index c209e78..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
deleted file mode 100644
index b2dfe3d..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
deleted file mode 100644
index 4f0f1d6..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
deleted file mode 100644
index 62b611d..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
deleted file mode 100644
index 948a307..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
deleted file mode 100644
index 1b9a695..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
deleted file mode 100644
index 28d4b77..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
deleted file mode 100644
index 9287f50..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
deleted file mode 100644
index aa7d642..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
deleted file mode 100644
index 9126ae3..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
deleted file mode 100644
index f8c6127..0000000
--- a/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- #FFBB86FC
- #FF6200EE
- #FF3700B3
- #FF03DAC5
- #FF018786
- #FF000000
- #FFFFFFFF
-
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
deleted file mode 100644
index 789ea53..0000000
--- a/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Compose Cropper
-
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
deleted file mode 100644
index 2d35219..0000000
--- a/app/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
deleted file mode 100644
index fa0f996..0000000
--- a/app/src/main/res/xml/backup_rules.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
deleted file mode 100644
index 9ee9997..0000000
--- a/app/src/main/res/xml/data_extraction_rules.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/test/java/com/smarttoolfactory/composecropper/ExampleUnitTest.kt b/app/src/test/java/com/smarttoolfactory/composecropper/ExampleUnitTest.kt
deleted file mode 100644
index 585eb91..0000000
--- a/app/src/test/java/com/smarttoolfactory/composecropper/ExampleUnitTest.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.smarttoolfactory.composecropper
-
-import org.junit.Test
-
-import org.junit.Assert.*
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-class ExampleUnitTest {
- @Test
- fun addition_isCorrect() {
- assertEquals(4, 2 + 2)
- }
-}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index a25fc41..11782dd 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -14,5 +14,4 @@ dependencyResolutionManagement {
}
}
rootProject.name = "Compose Cropper"
-include ':app'
include ':cropper'