@@ -7,13 +7,16 @@ import androidx.compose.foundation.layout.Box
77import androidx.compose.foundation.layout.BoxScope
88import androidx.compose.foundation.layout.fillMaxSize
99import androidx.compose.foundation.layout.size
10+ import androidx.compose.foundation.shape.CircleShape
1011import androidx.compose.foundation.shape.GenericShape
12+ import androidx.compose.material.Icon
1113import androidx.compose.runtime.*
1214import androidx.compose.ui.Modifier
1315import androidx.compose.ui.draw.clipToBounds
1416import androidx.compose.ui.geometry.Offset
1517import androidx.compose.ui.geometry.Size
1618import androidx.compose.ui.graphics.Color
19+ import androidx.compose.ui.graphics.Shape
1720import androidx.compose.ui.graphics.graphicsLayer
1821import androidx.compose.ui.input.pointer.pointerInput
1922import androidx.compose.ui.platform.LocalDensity
@@ -30,21 +33,48 @@ import com.smarttoolfactory.image.util.update
3033import com.smarttoolfactory.image.zoom.rememberZoomState
3134import kotlinx.coroutines.launch
3235
36+ /* *
37+ * A composable that lays out and draws a given [beforeContent] and [afterContent]
38+ * based on [contentOrder]. This overload uses [DefaultOverlay] to draw vertical slider and thumb.
39+ *
40+ * @param enableProgressWithTouch flag to enable drag and change progress with touch
41+ * @param enableZoom when enabled images are zoomable and pannable
42+ * @param contentOrder order of composables to be drawn
43+ * @param verticalThumbMove when true thumb can move vertically based on user touch
44+ * @param lineColor color if divider line
45+ * @param thumbBackgroundColor background color of thumb [Icon]
46+ * @param thumbTintColor tint color of thumb [Icon]
47+ * @param thumbShape shape of thumb [Icon]
48+ * @param thumbElevation elevation of thumb [Icon]
49+ * @param thumbResource drawable resource that should be used with thumb
50+ * @param thumbSize size of the thumb in dp
51+ * @param thumbPositionPercent vertical position of thumb if [verticalThumbMove] is false.
52+ * It's between [0f-100f] to set thumb's vertical position in layout
53+ * @param beforeContent content to be drawn as before Composable
54+ * @param afterContent content to be drawn as after Composable
55+ * @param beforeLabel label for [beforeContent]. It's [BeforeLabel] by default
56+ * @param afterLabel label for [afterContent]. It's [AfterLabel] by default
57+ *
58+ */
3359@Composable
3460fun BeforeAfterLayout (
3561 modifier : Modifier = Modifier ,
3662 enableProgressWithTouch : Boolean = true,
3763 enableZoom : Boolean = true,
3864 contentOrder : ContentOrder = ContentOrder .BeforeAfter ,
39- verticalThumbMove : Boolean = false,
4065 lineColor : Color = Color .White ,
66+ verticalThumbMove : Boolean = false,
67+ thumbBackgroundColor : Color = Color .White ,
68+ thumbTintColor : Color = Color .Gray ,
69+ thumbShape : Shape = CircleShape ,
70+ thumbElevation : Dp = 2.dp,
4171 @DrawableRes thumbResource : Int = R .drawable.baseline_swap_horiz_24,
4272 thumbSize : Dp = 36.dp,
4373 @FloatRange(from = 0.0 , to = 100.0 ) thumbPositionPercent : Float = 85f,
4474 beforeContent : @Composable () -> Unit ,
4575 afterContent : @Composable () -> Unit ,
46- beforeLabel : @Composable BoxScope .() -> Unit = { BeforeLabel (contentOrder) },
47- afterLabel : @Composable BoxScope .() -> Unit = { AfterLabel (contentOrder) },
76+ beforeLabel : @Composable BoxScope .() -> Unit = { BeforeLabel (contentOrder = contentOrder ) },
77+ afterLabel : @Composable BoxScope .() -> Unit = { AfterLabel (contentOrder = contentOrder ) },
4878) {
4979 var progress by remember { mutableStateOf(50f ) }
5080
@@ -66,8 +96,12 @@ fun BeforeAfterLayout(
6696 width = dpSize.width,
6797 height = dpSize.height,
6898 position = offset,
69- verticalThumbMove = verticalThumbMove,
7099 lineColor = lineColor,
100+ verticalThumbMove = verticalThumbMove,
101+ thumbBackgroundColor = thumbBackgroundColor,
102+ thumbTintColor = thumbTintColor,
103+ thumbShape = thumbShape,
104+ thumbElevation = thumbElevation,
71105 thumbResource = thumbResource,
72106 thumbSize = thumbSize,
73107 thumbPositionPercent = thumbPositionPercent
@@ -76,23 +110,53 @@ fun BeforeAfterLayout(
76110 )
77111}
78112
113+ /* *
114+ * A composable that lays out and draws a given [beforeContent] and [afterContent]
115+ * based on [contentOrder]. This overload uses [DefaultOverlay] to draw vertical slider and thumb
116+ * and has [progress] and [onProgressChange] which makes it eligible to animate by changing
117+ * [progress] value.
118+ *
119+ * @param enableProgressWithTouch flag to enable drag and change progress with touch
120+ * @param enableZoom when enabled images are zoomable and pannable
121+ * @param contentOrder order of composables to be drawn
122+ * @param progress current position or progress of before/after
123+ * @param onProgressChange current position or progress of before/after
124+ * @param verticalThumbMove when true thumb can move vertically based on user touch
125+ * @param lineColor color if divider line
126+ * @param thumbBackgroundColor background color of thumb [Icon]
127+ * @param thumbTintColor tint color of thumb [Icon]
128+ * @param thumbShape shape of thumb [Icon]
129+ * @param thumbElevation elevation of thumb [Icon]
130+ * @param thumbResource drawable resource that should be used with thumb
131+ * @param thumbSize size of the thumb in dp
132+ * @param thumbPositionPercent vertical position of thumb if [verticalThumbMove] is false.
133+ * It's between [0f-100f] to set thumb's vertical position in layout
134+ * @param beforeContent content to be drawn as before Composable
135+ * @param afterContent content to be drawn as after Composable
136+ * @param beforeLabel label for [beforeContent]. It's [BeforeLabel] by default
137+ * @param afterLabel label for [afterContent]. It's [AfterLabel] by default
138+ */
79139@Composable
80140fun BeforeAfterLayout (
81141 modifier : Modifier = Modifier ,
82142 enableProgressWithTouch : Boolean = true,
83143 enableZoom : Boolean = true,
84144 contentOrder : ContentOrder = ContentOrder .BeforeAfter ,
85- verticalThumbMove : Boolean = false,
145+ @FloatRange(from = 0.0 , to = 100.0 ) progress : Float = 50f,
146+ onProgressChange : ((Float ) -> Unit )? = null,
86147 lineColor : Color = Color .White ,
148+ verticalThumbMove : Boolean = false,
149+ thumbBackgroundColor : Color = Color .White ,
150+ thumbTintColor : Color = Color .Gray ,
151+ thumbShape : Shape = CircleShape ,
152+ thumbElevation : Dp = 2.dp,
87153 @DrawableRes thumbResource : Int = R .drawable.baseline_swap_horiz_24,
88154 thumbSize : Dp = 36.dp,
89155 @FloatRange(from = 0.0 , to = 100.0 ) thumbPositionPercent : Float = 85f,
90- @FloatRange(from = 0.0 , to = 100.0 ) progress : Float = 50f,
91- onProgressChange : ((Float ) -> Unit )? = null,
92156 beforeContent : @Composable () -> Unit ,
93157 afterContent : @Composable () -> Unit ,
94- beforeLabel : @Composable BoxScope .() -> Unit = { BeforeLabel (contentOrder) },
95- afterLabel : @Composable BoxScope .() -> Unit = { AfterLabel (contentOrder) },
158+ beforeLabel : @Composable BoxScope .() -> Unit = { BeforeLabel (contentOrder = contentOrder ) },
159+ afterLabel : @Composable BoxScope .() -> Unit = { AfterLabel (contentOrder = contentOrder ) },
96160) {
97161
98162 Layout (
@@ -111,8 +175,12 @@ fun BeforeAfterLayout(
111175 width = dpSize.width,
112176 height = dpSize.height,
113177 position = offset,
114- verticalThumbMove = verticalThumbMove,
115178 lineColor = lineColor,
179+ verticalThumbMove = verticalThumbMove,
180+ thumbBackgroundColor = thumbBackgroundColor,
181+ thumbTintColor = thumbTintColor,
182+ thumbShape = thumbShape,
183+ thumbElevation = thumbElevation,
116184 thumbResource = thumbResource,
117185 thumbSize = thumbSize,
118186 thumbPositionPercent = thumbPositionPercent
@@ -121,6 +189,22 @@ fun BeforeAfterLayout(
121189 )
122190}
123191
192+ /* *
193+ * A composable that lays out and draws a given [beforeContent] and [afterContent]
194+ * based on [contentOrder].
195+ *
196+ * @param enableProgressWithTouch flag to enable drag and change progress with touch
197+ * @param enableZoom when enabled images are zoomable and pannable
198+ * @param contentOrder order of composables to be drawn
199+
200+ * It's between [0f-100f] to set thumb's vertical position in layout
201+ * @param beforeContent content to be drawn as before Composable
202+ * @param afterContent content to be drawn as after Composable
203+ * @param beforeLabel label for [beforeContent]. It's [BeforeLabel] by default
204+ * @param afterLabel label for [afterContent]. It's [AfterLabel] by default
205+ * @param overlay Composable for drawing overlay over this Composable. It returns dimensions
206+ * of ancestor and touch position
207+ */
124208@Composable
125209fun BeforeAfterLayout (
126210 modifier : Modifier = Modifier ,
@@ -129,8 +213,8 @@ fun BeforeAfterLayout(
129213 contentOrder : ContentOrder = ContentOrder .BeforeAfter ,
130214 beforeContent : @Composable () -> Unit ,
131215 afterContent : @Composable () -> Unit ,
132- beforeLabel : @Composable BoxScope .() -> Unit = { BeforeLabel (contentOrder) },
133- afterLabel : @Composable BoxScope .() -> Unit = { AfterLabel (contentOrder) },
216+ beforeLabel : @Composable BoxScope .() -> Unit = { BeforeLabel (contentOrder = contentOrder ) },
217+ afterLabel : @Composable BoxScope .() -> Unit = { AfterLabel (contentOrder = contentOrder ) },
134218 overlay : @Composable ((DpSize , Offset ) -> Unit )?
135219) {
136220 var progress by remember { mutableStateOf(50f ) }
@@ -152,6 +236,23 @@ fun BeforeAfterLayout(
152236 )
153237}
154238
239+ /* *
240+ * A composable that lays out and draws a given [beforeContent] and [afterContent]
241+ * based on [contentOrder].
242+ *
243+ * @param enableProgressWithTouch flag to enable drag and change progress with touch
244+ * @param enableZoom when enabled images are zoomable and pannable
245+ * @param contentOrder order of composables to be drawn
246+ * @param progress current position or progress of before/after
247+ * @param onProgressChange current position or progress of before/after
248+ * It's between [0f-100f] to set thumb's vertical position in layout
249+ * @param beforeContent content to be drawn as before Composable
250+ * @param afterContent content to be drawn as after Composable
251+ * @param beforeLabel label for [beforeContent]. It's [BeforeLabel] by default
252+ * @param afterLabel label for [afterContent]. It's [AfterLabel] by default
253+ * @param overlay Composable for drawing overlay over this Composable. It returns dimensions
254+ * of ancestor and touch position
255+ */
155256@Composable
156257fun BeforeAfterLayout (
157258 modifier : Modifier = Modifier ,
@@ -162,8 +263,8 @@ fun BeforeAfterLayout(
162263 contentOrder : ContentOrder = ContentOrder .BeforeAfter ,
163264 beforeContent : @Composable () -> Unit ,
164265 afterContent : @Composable () -> Unit ,
165- beforeLabel : @Composable BoxScope .() -> Unit = { BeforeLabel (contentOrder) },
166- afterLabel : @Composable BoxScope .() -> Unit = { AfterLabel (contentOrder) },
266+ beforeLabel : @Composable ( BoxScope .() -> Unit ) ? = { BeforeLabel (contentOrder = contentOrder) },
267+ afterLabel : @Composable ( BoxScope .() -> Unit ) ? = { AfterLabel (contentOrder = contentOrder) },
167268 overlay : @Composable ((DpSize , Offset ) -> Unit )?
168269) {
169270
@@ -192,8 +293,8 @@ private fun Layout(
192293 contentOrder : ContentOrder = ContentOrder .BeforeAfter ,
193294 beforeContent : @Composable () -> Unit ,
194295 afterContent : @Composable () -> Unit ,
195- beforeLabel : @Composable BoxScope .() -> Unit = { BeforeLabel (contentOrder) } ,
196- afterLabel : @Composable BoxScope .() -> Unit = { AfterLabel (contentOrder) } ,
296+ beforeLabel : @Composable ( BoxScope .() -> Unit ) ? ,
297+ afterLabel : @Composable ( BoxScope .() -> Unit ) ? ,
197298 overlay : @Composable ((DpSize , Offset ) -> Unit )?
198299) {
199300 DimensionSubcomposeLayout (
@@ -346,7 +447,7 @@ private fun Layout(
346447 this .shape = shapeAfter
347448 }
348449
349- BeforeAfterLayoutImpl (
450+ LayoutImpl (
350451 modifier = parentModifier,
351452 beforeModifier = beforeModifier,
352453 afterModifier = afterModifier,
@@ -356,6 +457,7 @@ private fun Layout(
356457 beforeLabel = beforeLabel,
357458 afterLabel = afterLabel,
358459 overlay = overlay,
460+ contentOrder = contentOrder,
359461 boxWidthInDp = boxWidthInDp,
360462 boxHeightInDp = boxHeightInDp,
361463 rawOffset = rawOffset
@@ -365,40 +467,53 @@ private fun Layout(
365467}
366468
367469@Composable
368- private fun BeforeAfterLayoutImpl (
470+ private fun LayoutImpl (
369471 modifier : Modifier ,
370472 beforeModifier : Modifier ,
371473 afterModifier : Modifier ,
372474 graphicsModifier : Modifier ,
373475 beforeContent : @Composable () -> Unit ,
374476 afterContent : @Composable () -> Unit ,
375- beforeLabel : @Composable BoxScope .() -> Unit ,
376- afterLabel : @Composable BoxScope .() -> Unit ,
477+ beforeLabel : @Composable ( BoxScope .() -> Unit ) ? = null ,
478+ afterLabel : @Composable ( BoxScope .() -> Unit ) ? = null ,
377479 overlay : @Composable ((DpSize , Offset ) -> Unit )? = null,
480+ contentOrder : ContentOrder ,
378481 boxWidthInDp : Dp ,
379482 boxHeightInDp : Dp ,
380483 rawOffset : Offset ,
381484) {
382485 Box (modifier = modifier) {
383486
384487 // BEFORE
385- Box (modifier = beforeModifier) {
386- Box (
387- modifier = Modifier .then(graphicsModifier)
388- ) {
389- beforeContent()
488+ val before = @Composable {
489+ Box (if (contentOrder == ContentOrder .BeforeAfter ) beforeModifier else afterModifier) {
490+ Box (
491+ modifier = Modifier .then(graphicsModifier)
492+ ) {
493+ beforeContent()
494+ }
495+ beforeLabel?.invoke(this )
390496 }
391- beforeLabel()
392497 }
393498
394499 // AFTER
395- Box (afterModifier) {
396- Box (
397- modifier = Modifier .then(graphicsModifier)
398- ) {
399- afterContent()
500+ val after = @Composable {
501+ Box (if (contentOrder == ContentOrder .BeforeAfter ) afterModifier else beforeModifier) {
502+ Box (
503+ modifier = Modifier .then(graphicsModifier)
504+ ) {
505+ afterContent()
506+ }
507+ afterLabel?.invoke(this )
400508 }
401- afterLabel()
509+ }
510+
511+ if (contentOrder == ContentOrder .BeforeAfter ) {
512+ before()
513+ after()
514+ } else {
515+ after()
516+ before()
402517 }
403518 }
404519
0 commit comments