Skip to content

Commit 3611a3b

Browse files
authored
Merge pull request #28 from Konyaco/remove_composed
Remove `Modifier.composed`
2 parents d827701 + c40b482 commit 3611a3b

File tree

7 files changed

+84
-78
lines changed

7 files changed

+84
-78
lines changed

fluent/src/commonMain/kotlin/com/konyaco/fluent/background/Layer.kt

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@ import androidx.compose.foundation.BorderStroke
44
import androidx.compose.foundation.background
55
import androidx.compose.foundation.border
66
import androidx.compose.foundation.layout.Box
7-
import androidx.compose.foundation.layout.padding
87
import androidx.compose.foundation.shape.CircleShape
98
import androidx.compose.foundation.shape.RoundedCornerShape
109
import androidx.compose.runtime.Composable
1110
import androidx.compose.runtime.CompositionLocalProvider
1211
import androidx.compose.runtime.Stable
1312
import androidx.compose.runtime.remember
1413
import androidx.compose.ui.Modifier
15-
import androidx.compose.ui.composed
1614
import androidx.compose.ui.draw.clip
1715
import androidx.compose.ui.draw.shadow
1816
import androidx.compose.ui.graphics.Color
19-
import androidx.compose.ui.graphics.RectangleShape
2017
import androidx.compose.ui.graphics.Shape
21-
import androidx.compose.ui.platform.LocalDensity
18+
import androidx.compose.ui.layout.layout
2219
import androidx.compose.ui.unit.Density
2320
import androidx.compose.ui.unit.Dp
21+
import androidx.compose.ui.unit.constrainHeight
22+
import androidx.compose.ui.unit.constrainWidth
2423
import androidx.compose.ui.unit.dp
24+
import androidx.compose.ui.unit.offset
2525
import com.konyaco.fluent.FluentTheme
2626
import com.konyaco.fluent.LocalContentColor
2727
import com.konyaco.fluent.ProvideTextStyle
@@ -59,14 +59,20 @@ fun Layer(
5959
}
6060

6161
private fun Modifier.layer(elevation: Dp, shape: Shape, border: BorderStroke?, outsideBorder: Boolean, circular: Boolean, color: Color, innerShape: Shape) = this.shadow(elevation, shape, clip = false)
62-
.composed { if (border != null) border(border, shape) else this }
63-
.composed {
62+
.then(if (border != null) Modifier.border(border, shape) else Modifier)
63+
.layout { measurable, constraints ->
6464
// TODO: A better way to implement outside border
65-
val density = LocalDensity.current
66-
if (outsideBorder) {
67-
if (circular) padding(calcCircularPadding(density))
68-
else padding(calcPadding(density))
69-
} else this
65+
val paddingValue = when {
66+
outsideBorder && circular -> calcCircularPadding(this)
67+
outsideBorder -> calcPadding(this)
68+
else -> 0.dp
69+
}.roundToPx()
70+
val placeable = measurable.measure(constraints.offset(-paddingValue * 2, -paddingValue * 2))
71+
val width = constraints.constrainWidth(placeable.width + paddingValue * 2)
72+
val height = constraints.constrainHeight(placeable.height + paddingValue * 2)
73+
layout(width, height) {
74+
placeable.place(paddingValue, paddingValue)
75+
}
7076
}
7177
.background(color = color, shape = innerShape)
7278
.clip(shape = innerShape)

fluent/src/commonMain/kotlin/com/konyaco/fluent/component/Button.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
1212
import androidx.compose.runtime.*
1313
import androidx.compose.ui.Alignment
1414
import androidx.compose.ui.Modifier
15-
import androidx.compose.ui.composed
1615
import androidx.compose.ui.graphics.Brush
1716
import androidx.compose.ui.graphics.Color
1817
import androidx.compose.ui.graphics.SolidColor
@@ -132,10 +131,7 @@ private fun Button(
132131
interactionSource = interaction,
133132
indication = null
134133
)
135-
.composed {
136-
if (iconOnly) this
137-
else padding(horizontal = 12.dp)
138-
},
134+
.then(if (iconOnly) Modifier else Modifier.padding(horizontal = 12.dp)),
139135
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
140136
verticalAlignment = Alignment.CenterVertically,
141137
content = content

fluent/src/commonMain/kotlin/com/konyaco/fluent/component/CheckBox.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
88
import androidx.compose.foundation.interaction.collectIsHoveredAsState
99
import androidx.compose.foundation.interaction.collectIsPressedAsState
1010
import androidx.compose.foundation.layout.*
11-
import androidx.compose.foundation.shape.CircleShape
1211
import androidx.compose.foundation.shape.RoundedCornerShape
1312
import androidx.compose.runtime.Composable
1413
import androidx.compose.runtime.getValue
1514
import androidx.compose.runtime.remember
1615
import androidx.compose.ui.Alignment
1716
import androidx.compose.ui.Modifier
18-
import androidx.compose.ui.composed
1917
import androidx.compose.ui.graphics.Color
2018
import androidx.compose.ui.semantics.Role
2119
import androidx.compose.ui.unit.dp
@@ -40,10 +38,10 @@ fun CheckBox(
4038
val pressed by interactionSource.collectIsPressedAsState()
4139

4240
Row(
43-
modifier = modifier.composed {
41+
modifier = modifier.then(
4442
if (label != null) Modifier.defaultMinSize(minWidth = 120.dp)
4543
else Modifier
46-
}.clickable(
44+
).clickable(
4745
role = Role.Checkbox,
4846
indication = null,
4947
interactionSource = interactionSource

fluent/src/commonMain/kotlin/com/konyaco/fluent/component/RadioButton.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import androidx.compose.runtime.getValue
1515
import androidx.compose.runtime.remember
1616
import androidx.compose.ui.Alignment
1717
import androidx.compose.ui.Modifier
18-
import androidx.compose.ui.composed
1918
import androidx.compose.ui.unit.dp
2019
import com.konyaco.fluent.FluentTheme
2120
import com.konyaco.fluent.animation.FluentDuration
@@ -35,10 +34,10 @@ fun RadioButton(
3534
val hovered by interactionSource.collectIsHoveredAsState()
3635
val pressed by interactionSource.collectIsPressedAsState()
3736

38-
Row(modifier.composed {
39-
if (label != null) defaultMinSize(minWidth = 120.dp)
40-
else this
41-
}.clickable(interactionSource, null) {
37+
Row(modifier.then(
38+
if (label != null) Modifier.defaultMinSize(minWidth = 120.dp)
39+
else Modifier
40+
).clickable(interactionSource, null) {
4241
onClick?.invoke()
4342
}) {
4443
val fillColor by animateColorAsState(
@@ -90,7 +89,10 @@ fun RadioButton(
9089
Layer(
9190
modifier = Modifier.size(if (size == 0.dp || !selected) size else size + 2.dp), // TODO: Remove this 2dp if outside border is provided
9291
color = FluentTheme.colors.text.onAccent.primary,
93-
border = if (selected) BorderStroke(1.dp, FluentTheme.colors.borders.circle) else null,
92+
border = if (selected) BorderStroke(
93+
1.dp,
94+
FluentTheme.colors.borders.circle
95+
) else null,
9496
shape = CircleShape,
9597
outsideBorder = true,
9698
content = {}

fluent/src/commonMain/kotlin/com/konyaco/fluent/component/SideNav.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import androidx.compose.foundation.verticalScroll
2020
import androidx.compose.runtime.*
2121
import androidx.compose.ui.Alignment
2222
import androidx.compose.ui.Modifier
23-
import androidx.compose.ui.composed
2423
import androidx.compose.ui.focus.FocusRequester
2524
import androidx.compose.ui.focus.focusRequester
2625
import androidx.compose.ui.graphics.graphicsLayer
@@ -327,12 +326,13 @@ private fun Indicator(modifier: Modifier, display: Boolean) {
327326
Box(modifier.width(3.dp).then(animationModifier).background(FluentTheme.colors.fillAccent.default, CircleShape))
328327
}
329328

329+
@Composable
330330
private fun Modifier.indicatorOffsetAnimation(
331331
size: Dp,
332332
indicatorState: MutableTransitionState<Boolean>,
333333
selectedPosition: MutableTransitionState<Float>,
334334
isVertical: Boolean = true
335-
) = composed {
335+
): Modifier {
336336
val fraction by updateTransition(indicatorState).animateFloat(
337337
transitionSpec = {
338338
tween(FluentDuration.VeryLongDuration , easing = FluentEasing.PointToPointEasing)
@@ -348,7 +348,7 @@ private fun Modifier.indicatorOffsetAnimation(
348348
)
349349
}) { it }
350350
}
351-
layout { measurable, constraints ->
351+
return layout { measurable, constraints ->
352352
val stickSize = size.toPx()
353353
val containerSize = if (isVertical) {
354354
constraints.maxHeight

fluent/src/commonMain/kotlin/com/konyaco/fluent/component/Slider.kt

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import androidx.compose.runtime.rememberUpdatedState
3232
import androidx.compose.runtime.setValue
3333
import androidx.compose.ui.Alignment
3434
import androidx.compose.ui.Modifier
35-
import androidx.compose.ui.composed
3635
import androidx.compose.ui.geometry.Offset
3736
import androidx.compose.ui.input.pointer.pointerInput
3837
import androidx.compose.ui.platform.LocalDensity
@@ -94,33 +93,35 @@ private fun Slider(
9493
return valueToFraction(offset.x, radius, constraints.minWidth - radius).coerceIn(0f, 1f)
9594
}
9695

97-
Box(Modifier.composed {
98-
var offset by remember { mutableStateOf(Offset.Zero) }
99-
draggable(
100-
state = rememberDraggableState {
101-
offset = Offset(x = offset.x + it, y = offset.y)
102-
currentOnProgressChange(calcProgress(offset))
103-
},
104-
interactionSource = interactionSource,
105-
onDragStarted = {
96+
var offset by remember { mutableStateOf(Offset.Zero) }
97+
Box(
98+
modifier = Modifier
99+
.draggable(
100+
state = rememberDraggableState {
101+
offset = Offset(x = offset.x + it, y = offset.y)
102+
currentOnProgressChange(calcProgress(offset))
103+
},
104+
interactionSource = interactionSource,
105+
onDragStarted = {
106+
dragging = true
107+
offset = it
108+
},
109+
onDragStopped = {
110+
dragging = false
111+
onValueChangeFinished?.invoke()
112+
},
113+
orientation = Orientation.Horizontal
114+
)
115+
.pointerInput(Unit) {
116+
awaitEachGesture {
117+
val down = awaitFirstDown()
106118
dragging = true
107-
offset = it
108-
},
109-
onDragStopped = {
119+
currentOnProgressChange(calcProgress(down.position))
120+
waitForUpOrCancellation()
110121
dragging = false
111-
onValueChangeFinished?.invoke()
112-
},
113-
orientation = Orientation.Horizontal
114-
)
115-
}.pointerInput(Unit) {
116-
awaitEachGesture {
117-
val down = awaitFirstDown()
118-
dragging = true
119-
currentOnProgressChange(calcProgress(down.position))
120-
waitForUpOrCancellation()
121-
dragging = false
122-
}
123-
}, contentAlignment = Alignment.CenterStart) {
122+
}
123+
}, contentAlignment = Alignment.CenterStart
124+
) {
124125
Rail()
125126
Track(progress, width)
126127
Thumb(width, progress, dragging)
@@ -129,7 +130,8 @@ private fun Slider(
129130
}
130131

131132
@Stable
132-
private fun fractionToValue(fraction: Float, start: Float, end: Float): Float = (end - start) * fraction + start
133+
private fun fractionToValue(fraction: Float, start: Float, end: Float): Float =
134+
(end - start) * fraction + start
133135

134136
@Stable
135137
private fun valueToFraction(

fluent/src/commonMain/kotlin/com/konyaco/fluent/component/TextField.kt

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import androidx.compose.runtime.remember
1717
import androidx.compose.runtime.rememberUpdatedState
1818
import androidx.compose.ui.Alignment
1919
import androidx.compose.ui.Modifier
20-
import androidx.compose.ui.composed
2120
import androidx.compose.ui.draw.clip
2221
import androidx.compose.ui.draw.drawWithContent
2322
import androidx.compose.ui.geometry.Offset
@@ -57,26 +56,7 @@ fun TextField(
5756
}
5857
BasicTextField(
5958
modifier = modifier.defaultMinSize(160.dp, 32.dp)
60-
.clip(RoundedCornerShape(4.dp))
61-
.composed {
62-
if (enabled) {
63-
val height by rememberUpdatedState(with(LocalDensity.current) {
64-
(if (focused) 2.dp else 1.dp).toPx()
65-
})
66-
val fillColor by rememberUpdatedState(
67-
if (focused) FluentTheme.colors.fillAccent.default
68-
else FluentTheme.colors.stroke.controlStrong.default
69-
)
70-
drawWithContent {
71-
drawContent()
72-
drawRect(
73-
color = fillColor,
74-
topLeft = Offset(0f, size.height - height),
75-
size = Size(size.width, height)
76-
)
77-
}
78-
} else this
79-
},
59+
.clip(RoundedCornerShape(4.dp)),
8060
value = value,
8161
onValueChange = onValueChange,
8262
textStyle = LocalTextStyle.current.copy(
@@ -94,7 +74,8 @@ fun TextField(
9474
interactionSource = interactionSource,
9575
decorationBox = { innerTextField ->
9676
Layer(
97-
modifier = Modifier.hoverable(interactionSource),
77+
modifier = Modifier.hoverable(interactionSource)
78+
.drawBottomLine(enabled) { focused },
9879
shape = RoundedCornerShape(4.dp),
9980
border = BorderStroke(
10081
1.dp,
@@ -118,4 +99,25 @@ fun TextField(
11899
}
119100
)
120101
}
102+
}
103+
104+
@Composable
105+
private fun Modifier.drawBottomLine(enabled: Boolean, focused: () -> Boolean): Modifier {
106+
return if (enabled) {
107+
val height by rememberUpdatedState(with(LocalDensity.current) {
108+
(if (focused()) 2.dp else 1.dp).toPx()
109+
})
110+
val fillColor by rememberUpdatedState(
111+
if (focused()) FluentTheme.colors.fillAccent.default
112+
else FluentTheme.colors.stroke.controlStrong.default
113+
)
114+
drawWithContent {
115+
drawContent()
116+
drawRect(
117+
color = fillColor,
118+
topLeft = Offset(0f, size.height - height),
119+
size = Size(size.width, height)
120+
)
121+
}
122+
} else this
121123
}

0 commit comments

Comments
 (0)