Skip to content

Commit bdef818

Browse files
Merge branch 'feature/customize-shapes-paths'
2 parents 8b337c6 + a15080b commit bdef818

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3203
-576
lines changed

app/build.gradle

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,6 @@ dependencies {
6262
// Animated List
6363
implementation 'com.github.SmartToolFactory:Compose-AnimatedList:0.5.1'
6464

65-
// Snapper for lazy lists
66-
implementation "dev.chrisbanes.snapper:snapper:0.3.0"
67-
6865
implementation "androidx.compose.ui:ui:$compose_version"
6966
// Tooling support (Previews, etc.)
7067
implementation "androidx.compose.ui:ui-tooling:$compose_version"
@@ -76,12 +73,12 @@ dependencies {
7673
implementation "androidx.compose.material:material-icons-core:$compose_version"
7774
implementation "androidx.compose.material:material-icons-extended:$compose_version"
7875
// Integration with activities
79-
implementation 'androidx.activity:activity-compose:1.5.1'
76+
implementation 'androidx.activity:activity-compose:1.6.0'
8077
// Integration with ViewModels
8178
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1'
8279

8380
// Material Design 3 for Compose
84-
implementation "androidx.compose.material3:material3:1.0.0-beta02"
81+
implementation "androidx.compose.material3:material3:1.0.0-beta03"
8582

8683
def nav_compose_version = "2.5.2"
8784
implementation "androidx.navigation:navigation-compose:$nav_compose_version"

app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemo.kt

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ import com.smarttoolfactory.composecropper.R
3333
import com.smarttoolfactory.composecropper.preferences.CropStyleSelectionMenu
3434
import com.smarttoolfactory.composecropper.preferences.PropertySelectionSheet
3535
import com.smarttoolfactory.cropper.ImageCropper
36-
import com.smarttoolfactory.cropper.settings.CropDefaults
37-
import com.smarttoolfactory.cropper.settings.CropProperties
38-
import com.smarttoolfactory.cropper.settings.CropStyle
36+
import com.smarttoolfactory.cropper.model.OutlineType
37+
import com.smarttoolfactory.cropper.model.RectCropShape
38+
import com.smarttoolfactory.cropper.settings.*
3939
import kotlinx.coroutines.launch
4040

4141
internal enum class SelectionPage {
@@ -51,7 +51,30 @@ fun ImageCropDemo() {
5151
bottomSheetState = BottomSheetState(BottomSheetValue.Collapsed)
5252
)
5353

54-
var cropProperties by remember { mutableStateOf(CropDefaults.properties()) }
54+
val defaultImage1 = ImageBitmap.imageResource(id = R.drawable.squircle)
55+
val defaultImage2 = ImageBitmap.imageResource(id = R.drawable.cloud)
56+
val defaultImage3 = ImageBitmap.imageResource(id = R.drawable.sun)
57+
58+
val cropFrameFactory = remember {
59+
CropFrameFactory(
60+
listOf(
61+
defaultImage1,
62+
defaultImage2,
63+
defaultImage3
64+
)
65+
)
66+
}
67+
68+
var cropProperties by remember {
69+
mutableStateOf(
70+
CropDefaults.properties(
71+
cropOutlineProperty = CropOutlineProperty(
72+
OutlineType.Rect,
73+
RectCropShape(0, "")
74+
)
75+
)
76+
)
77+
}
5578
var cropStyle by remember { mutableStateOf(CropDefaults.style()) }
5679
val coroutineScope = rememberCoroutineScope()
5780

@@ -72,6 +95,7 @@ fun ImageCropDemo() {
7295

7396
if (selectionPage == SelectionPage.Properties) {
7497
PropertySelectionSheet(
98+
cropFrameFactory = cropFrameFactory,
7599
cropProperties = cropProperties,
76100
onCropPropertiesChange = {
77101
cropProperties = it
@@ -136,7 +160,9 @@ private fun MainContent(
136160
Column(modifier = Modifier.fillMaxSize()) {
137161

138162
ImageCropper(
139-
modifier = Modifier.fillMaxWidth().weight(1f),
163+
modifier = Modifier
164+
.fillMaxWidth()
165+
.weight(1f),
140166
imageBitmap = imageBitmap,
141167
contentDescription = "Image Cropper",
142168
cropStyle = cropStyle,

app/src/main/java/com/smarttoolfactory/composecropper/preferences/AspectRatioSelection.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ internal fun AnimatedAspectRatioSelection(
4040
}
4141
.width(width),
4242
color = color,
43-
cropShape = item
43+
cropAspectRatio = item
4444
)
4545

4646
if (currentIndex != selectedLocalIndex) {
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.smarttoolfactory.composecropper.preferences
2+
3+
import CropFrameListDialog
4+
import androidx.compose.foundation.layout.fillMaxWidth
5+
import androidx.compose.foundation.layout.padding
6+
import androidx.compose.foundation.layout.width
7+
import androidx.compose.runtime.*
8+
import androidx.compose.ui.Modifier
9+
import androidx.compose.ui.unit.Dp
10+
import androidx.compose.ui.unit.dp
11+
import com.smarttoolfactory.animatedlist.AnimatedInfiniteLazyRow
12+
import com.smarttoolfactory.animatedlist.model.AnimationProgress
13+
import com.smarttoolfactory.cropper.model.AspectRatio
14+
import com.smarttoolfactory.cropper.model.CropFrame
15+
import com.smarttoolfactory.cropper.model.OutlineType
16+
import com.smarttoolfactory.cropper.settings.CropFrameFactory
17+
import com.smarttoolfactory.cropper.settings.CropOutlineProperty
18+
import com.smarttoolfactory.cropper.widget.CropFrameDisplayCard
19+
20+
/**
21+
* Crop frame selection
22+
*/
23+
@Composable
24+
fun CropFrameSelection(
25+
aspectRatio: AspectRatio,
26+
cropFrameFactory: CropFrameFactory,
27+
cropOutlineProperty: CropOutlineProperty,
28+
conCropOutlinePropertyChange: (CropOutlineProperty) -> Unit
29+
) {
30+
31+
var showEditDialog by remember { mutableStateOf(false) }
32+
33+
var cropFrame by remember {
34+
mutableStateOf(
35+
cropFrameFactory.getCropFrame(cropOutlineProperty.outlineType)
36+
)
37+
}
38+
39+
if (showEditDialog) {
40+
CropFrameListDialog(
41+
aspectRatio = aspectRatio,
42+
cropFrame = cropFrame,
43+
onConfirm = {
44+
cropFrame = it
45+
cropFrameFactory.editCropFrame(cropFrame)
46+
47+
conCropOutlinePropertyChange(
48+
CropOutlineProperty(
49+
it.outlineType,
50+
it.cropOutlineContainer.selectedItem
51+
)
52+
)
53+
showEditDialog = false
54+
},
55+
onDismiss = {
56+
showEditDialog = false
57+
}
58+
)
59+
}
60+
61+
val initialIndex = remember {
62+
OutlineType.values().indexOfFirst {
63+
it == cropOutlineProperty.outlineType
64+
}
65+
}
66+
67+
CropFrameSelectionList(
68+
modifier = Modifier.fillMaxWidth(),
69+
cropFrames = cropFrameFactory.getCropFrames(),
70+
initialSelectedIndex = initialIndex,
71+
onClick = {
72+
cropFrame = it
73+
showEditDialog = true
74+
},
75+
onCropFrameChange = {
76+
conCropOutlinePropertyChange(
77+
CropOutlineProperty(
78+
it.outlineType,
79+
it.cropOutlineContainer.selectedItem
80+
)
81+
)
82+
}
83+
)
84+
}
85+
86+
/**
87+
* Animated list for selecting [CropFrame]
88+
*/
89+
@Composable
90+
private fun CropFrameSelectionList(
91+
modifier: Modifier = Modifier,
92+
initialSelectedIndex: Int = 2,
93+
cropFrames: List<CropFrame>,
94+
onClick: (CropFrame) -> Unit,
95+
onCropFrameChange: (CropFrame) -> Unit
96+
) {
97+
98+
var currentIndex by remember { mutableStateOf(initialSelectedIndex) }
99+
100+
AnimatedInfiniteLazyRow(
101+
modifier = modifier.padding(horizontal = 10.dp),
102+
items = cropFrames,
103+
inactiveItemPercent = 80,
104+
initialFirstVisibleIndex = initialSelectedIndex - 2,
105+
) { animationProgress: AnimationProgress, _, item: CropFrame, width: Dp ->
106+
107+
val scale = animationProgress.scale
108+
val color = animationProgress.color
109+
110+
val selectedLocalIndex = animationProgress.itemIndex
111+
val cropOutline = item.cropOutlineContainer.selectedItem
112+
113+
val editable = item.editable
114+
115+
CropFrameDisplayCard(
116+
modifier = Modifier.width(width),
117+
editable = editable,
118+
scale = scale,
119+
outlineColor = color,
120+
title = cropOutline.title,
121+
cropOutline = cropOutline
122+
) {
123+
onClick(item)
124+
}
125+
126+
if (currentIndex != selectedLocalIndex) {
127+
currentIndex = selectedLocalIndex
128+
onCropFrameChange(cropFrames[selectedLocalIndex])
129+
}
130+
}
131+
}

app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropPropertySelection.kt

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ import androidx.compose.runtime.remember
88
import androidx.compose.ui.Modifier
99
import androidx.compose.ui.unit.dp
1010
import androidx.compose.ui.unit.sp
11-
import com.smarttoolfactory.cropper.model.*
11+
import com.smarttoolfactory.cropper.model.AspectRatio
12+
import com.smarttoolfactory.cropper.model.CropAspectRatio
13+
import com.smarttoolfactory.cropper.model.aspectRatios
14+
import com.smarttoolfactory.cropper.settings.CropFrameFactory
1215
import com.smarttoolfactory.cropper.settings.CropProperties
1316
import com.smarttoolfactory.cropper.settings.CropType
1417
import kotlin.math.roundToInt
1518

1619

1720
@Composable
1821
internal fun CropPropertySelectionMenu(
22+
cropFrameFactory: CropFrameFactory,
1923
cropProperties: CropProperties,
2024
onCropPropertiesChange: (CropProperties) -> Unit
2125
) {
@@ -24,7 +28,7 @@ internal fun CropPropertySelectionMenu(
2428
val aspectRatio = cropProperties.aspectRatio
2529
val handleSize = cropProperties.handleSize
2630
val contentScale = cropProperties.contentScale
27-
val cropShape = cropProperties.cropShape
31+
val cropOutlineProperty = cropProperties.cropOutlineProperty
2832

2933
Title("Crop Type")
3034
CropTypeDialogSelection(
@@ -53,12 +57,14 @@ internal fun CropPropertySelectionMenu(
5357
}
5458
)
5559

56-
Title("Shape")
57-
ShapeSelection(
58-
cropShape = cropShape,
59-
onCropShapeChange = {
60+
Title("Frame")
61+
CropFrameSelection(
62+
aspectRatio = aspectRatio,
63+
cropFrameFactory = cropFrameFactory,
64+
cropOutlineProperty = cropOutlineProperty,
65+
conCropOutlinePropertyChange = {
6066
onCropPropertiesChange(
61-
cropProperties.copy(cropShape = it)
67+
cropProperties.copy(cropOutlineProperty = it)
6268
)
6369
}
6470
)
@@ -159,26 +165,6 @@ internal fun AspectRatioSelection(
159165
}
160166
}
161167

162-
@Composable
163-
internal fun ShapeSelection(
164-
cropShape: CropShape,
165-
onCropShapeChange: (CropShape) -> Unit
166-
) {
167-
168-
val initialSelectedIndex = remember {
169-
val shapes = shapes
170-
val currentModel = shapes.first { it == cropShape }
171-
shapes.indexOf(currentModel)
172-
}
173-
174-
AnimatedShapeSelection(
175-
modifier = Modifier.fillMaxWidth(),
176-
initialSelectedIndex = initialSelectedIndex
177-
) {
178-
onCropShapeChange(it)
179-
}
180-
}
181-
182168
@Composable
183169
internal fun FlingEnableSelection(
184170
flingEnabled: Boolean,

app/src/main/java/com/smarttoolfactory/composecropper/preferences/PropertySelectionSheet.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
package com.smarttoolfactory.composecropper.preferences
22

33
import androidx.compose.runtime.Composable
4+
import com.smarttoolfactory.cropper.settings.CropFrameFactory
45
import com.smarttoolfactory.cropper.settings.CropProperties
56

67
@Composable
78
internal fun PropertySelectionSheet(
9+
cropFrameFactory:CropFrameFactory,
810
cropProperties: CropProperties,
911
onCropPropertiesChange: (CropProperties) -> Unit
1012
) {
1113
BaseSheet {
1214
CropPropertySelectionMenu(
15+
cropFrameFactory =cropFrameFactory,
1316
cropProperties = cropProperties,
1417
onCropPropertiesChange = onCropPropertiesChange
1518
)

app/src/main/java/com/smarttoolfactory/composecropper/preferences/ShapeSelection.kt

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)