@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.*
1212import androidx.compose.foundation.lazy.grid.GridCells
1313import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
1414import androidx.compose.foundation.lazy.grid.itemsIndexed
15+ import androidx.compose.foundation.shape.CircleShape
1516import androidx.compose.foundation.shape.RoundedCornerShape
1617import androidx.compose.material.icons.Icons
1718import androidx.compose.material.icons.filled.Add
@@ -21,6 +22,7 @@ import androidx.compose.material3.*
2122import androidx.compose.runtime.*
2223import androidx.compose.ui.Alignment
2324import androidx.compose.ui.Modifier
25+ import androidx.compose.ui.draw.clip
2426import androidx.compose.ui.draw.drawWithCache
2527import androidx.compose.ui.draw.shadow
2628import androidx.compose.ui.graphics.*
@@ -33,8 +35,8 @@ import androidx.compose.ui.unit.dp
3335import androidx.compose.ui.unit.sp
3436import com.google.modernstorage.photopicker.PhotoPicker
3537import com.smarttoolfactory.composecropper.preferences.frames.edit.CropFrameEditDialog
36- import com.smarttoolfactory.cropper.model.*
3738import com.smarttoolfactory.composecropper.preferences.frames.edit.CropShapeAddDialog
39+ import com.smarttoolfactory.cropper.model.*
3840import com.smarttoolfactory.cropper.util.buildOutline
3941import com.smarttoolfactory.cropper.util.scaleAndTranslatePath
4042
@@ -45,7 +47,8 @@ import com.smarttoolfactory.cropper.util.scaleAndTranslatePath
4547fun CropFrameListDialog (
4648 aspectRatio : AspectRatio ,
4749 cropFrame : CropFrame ,
48- onDismiss : (CropFrame ) -> Unit
50+ onDismiss : () -> Unit ,
51+ onConfirm : (CropFrame ) -> Unit
4952) {
5053 var updatedCropFrame by remember {
5154 mutableStateOf(cropFrame)
@@ -115,79 +118,117 @@ fun CropFrameListDialog(
115118 outlines = newOutlines
116119 )
117120 )
121+
122+ selectedIndex = updatedCropFrame.selectedIndex
118123 }
119124 }
120125 }
121126
122127 AlertDialog (
123- onDismissRequest = { onDismiss(updatedCropFrame) },
128+ onDismissRequest = {
129+ onDismiss()
130+ },
131+ title = {
132+ Row (
133+ modifier = Modifier .fillMaxWidth(),
134+ verticalAlignment = Alignment .CenterVertically
135+ ) {
136+ Text (
137+ text = " Frames" ,
138+ fontSize = 24 .sp,
139+ fontWeight = FontWeight .Bold ,
140+ color = MaterialTheme .colorScheme.primary
141+ )
142+ Spacer (modifier = Modifier .weight(1f ))
143+
144+ val enabled = selectedIndex != 0
145+
146+ Icon (
147+ modifier = Modifier
148+ .clip(CircleShape )
149+ .background(
150+ if (enabled) MaterialTheme .colorScheme.error
151+ else Color .LightGray
152+ )
153+ .size(28 .dp)
154+ .clickable(
155+ enabled = enabled,
156+ onClick = {
157+ val outlines = updatedCropFrame.outlines
158+ .toMutableList()
159+ .apply {
160+ removeAt(selectedIndex)
161+ }
162+ updatedCropFrame = updatedCropFrame.copy(
163+ cropOutlineContainer = getOutlineContainer(
164+ updatedCropFrame.outlineType,
165+ outlines.size - 1 ,
166+ outlines
167+ )
168+ )
169+
170+ selectedIndex = outlines.size - 1
171+ }
172+ )
173+ .padding(6 .dp),
174+
175+ imageVector = Icons .Default .Delete ,
176+ tint = if (enabled) Color .White else Color .Gray ,
177+ contentDescription = " Delete"
178+ )
179+
180+ Spacer (modifier = Modifier .width(12 .dp))
181+ Icon (
182+ modifier = Modifier
183+ .clip(CircleShape )
184+ .background(MaterialTheme .colorScheme.primary)
185+ .size(28 .dp)
186+ .clickable {
187+ showEditDialog = true
188+ }
189+ .padding(6 .dp),
190+ imageVector = Icons .Default .Edit ,
191+ tint = Color .White ,
192+ contentDescription = " Edit"
193+ )
194+ }
195+ },
124196 text = {
125197 CropOutlineGridList (
126198 modifier = Modifier
127199 .fillMaxWidth()
128- .heightIn(min = 280 .dp),
200+ .heightIn(min = 240 .dp),
129201 selectedIndex = selectedIndex,
130202 outlineType = updatedCropFrame.outlineType,
131203 outlines = updatedCropFrame.outlines,
132204 aspectRatio = aspectRatio,
133205 onItemClick = {
134-
135206 selectedIndex = it
136207 updatedCropFrame.selectedIndex = selectedIndex
137-
138- println (" Update cropFrame with index: $it , crop index: ${updatedCropFrame.selectedIndex} " )
139208 },
140209 onAddItemClick = {
141210 showAddDialog = true
142211 }
143212 )
144213 },
145214 dismissButton = {
146- FilledTonalButton (
147- enabled = selectedIndex != 0 ,
215+ TextButton (
148216 onClick = {
149- val outlines = updatedCropFrame.outlines
150- .toMutableList()
151- .apply {
152- removeAt(selectedIndex)
153- }
154- updatedCropFrame = updatedCropFrame.copy(
155- cropOutlineContainer = getOutlineContainer(
156- updatedCropFrame.outlineType,
157- outlines.size - 1 ,
158- outlines
159- )
160- )
161-
162- selectedIndex = outlines.size - 1
163- },
164- colors = ButtonDefaults .filledTonalButtonColors(
165- containerColor = MaterialTheme .colorScheme.error,
166- contentColor = MaterialTheme .colorScheme.onError
167- )
168-
217+ onDismiss()
218+ }
169219 ) {
170- Icon (
171- imageVector = Icons .Default .Delete ,
172- contentDescription = " Delete"
173- )
174- Text (" Delete" )
220+
221+ Text (" Cancel" )
175222 }
176223 },
177224 confirmButton = {
178- if (outlineType != OutlineType .ImageMask ) {
179- Button (
225+ TextButton (
180226 onClick = {
181- showEditDialog = true
227+ onConfirm(updatedCropFrame)
182228 }
183229 ) {
184- Icon (
185- imageVector = Icons .Default .Edit ,
186- contentDescription = " Edit"
187- )
188- Text (" Edit" )
230+ Text (" Accept" )
189231 }
190- }
191232 }
192233 )
193234}
@@ -296,7 +337,6 @@ private fun CropOutlineGridItem(
296337 .aspectRatio(1f ),
297338 cropOutline = cropOutline,
298339 aspectRatio,
299- selected,
300340 color
301341 )
302342
@@ -305,13 +345,13 @@ private fun CropOutlineGridItem(
305345 modifier = Modifier
306346 .align(Alignment .BottomStart )
307347 .fillMaxWidth()
308- .background(Color . White . copy(. 2f ))
309- .padding(horizontal = 5 .dp, vertical = 4 .dp),
348+ .background(MaterialTheme .colorScheme.primaryContainer. copy(alpha = . 7f ))
349+ .padding(horizontal = 8 .dp, vertical = 6 .dp),
310350 contentAlignment = Alignment .Center
311351 ) {
312352 Text (
313353 text = cropOutline.title,
314- color = color ,
354+ color = MaterialTheme .colorScheme.onPrimaryContainer ,
315355 fontSize = 12 .sp,
316356 maxLines = 1 ,
317357 fontWeight = FontWeight .Bold ,
@@ -326,7 +366,6 @@ private fun CropOutlineDisplay(
326366 modifier : Modifier ,
327367 cropOutline : CropOutline ,
328368 aspectRatio : AspectRatio ,
329- selected : Boolean ,
330369 color : Color
331370) {
332371
@@ -348,8 +387,8 @@ private fun CropOutlineDisplay(
348387 .drawWithCache {
349388 val coefficient = .8f
350389
351- val (left, top , outline) = buildOutline(
352- AspectRatio ( 1f ) ,
390+ val (offset , outline) = buildOutline(
391+ aspectRatio ,
353392 coefficient,
354393 cropOutline.shape,
355394 size,
@@ -359,8 +398,8 @@ private fun CropOutlineDisplay(
359398
360399 onDrawWithContent {
361400 translate(
362- left = left ,
363- top = top
401+ left = offset.x ,
402+ top = offset.y
364403 ) {
365404 drawOutline(
366405 outline = outline,
@@ -387,11 +426,14 @@ private fun CropOutlineDisplay(
387426 onDrawWithContent {
388427 drawPath(path, color)
389428 }
390- })
429+ }
430+ )
391431 }
392432 is CropImageMask -> {
393433 Box (
394- modifier = Modifier .matchParentSize(),
434+ modifier = Modifier
435+ .matchParentSize()
436+ .padding(4 .dp),
395437 contentAlignment = Alignment .Center
396438 ) {
397439 Image (bitmap = cropOutline.image, contentDescription = " ImageMask" )
0 commit comments