Chris Fillmore
05/30/2023, 2:57 PMModifier.scale
to scale down the drawing, and I have a function which provides a “scaled layout”, which, given a fixed size, gives you a Box with scale applied to that size, in which you can draw your scaled content.
More in 🧵Chris Fillmore
05/30/2023, 2:57 PM@Composable
fun ScaledLayout(
scale: Float,
width: Dp,
height: Dp,
content: @Composable () -> Unit,
) {
Box(
modifier = Modifier
.size(width = width * scale, height = height * scale)
.wrapContentSize(unbounded = true),
contentAlignment = Alignment.Center,
) {
content()
}
}
Chris Fillmore
05/30/2023, 2:58 PMChris Fillmore
05/30/2023, 2:59 PMChris Fillmore
05/30/2023, 3:01 PMChris Fillmore
05/30/2023, 3:04 PMSubcomposeLayout
to see if there’s something I can do there. However this seems like something to use if you want to measure children based on their siblings. But what I want to do is measure a parent based on the (scaled) size of its children.Chris Fillmore
05/30/2023, 7:05 PMSubcomposeLayout
, works well
private enum class ScaledSlot { Original, Scaled }
@Composable
fun RowScope.ScaledLayout(
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
SubcomposeLayout(modifier.weight(1f)) { constraints ->
val placeables = subcompose(ScaledSlot.Original, content).map {
it.measure(Constraints())
}
val maxWidthOfContent = placeables.maxByOrNull { it.measuredWidth }?.measuredWidth ?: 0
val heightOfContent = placeables.sumOf { it.measuredHeight }
val scale = constraints.maxWidth.toFloat() / maxWidthOfContent
val scaledHeight = (heightOfContent * scale).roundToInt()
val scaledBox = subcompose(ScaledSlot.Scaled) {
Box(
modifier = Modifier
.graphicsLayer(
scaleX = scale,
scaleY = scale,
transformOrigin = TransformOrigin(0.5f, 0f),
)
.wrapContentSize(unbounded = true),
) {
content()
}
}.first().measure(constraints)
layout(constraints.maxWidth, scaledHeight) {
scaledBox.placeRelative(0, 0)
}
}
}
Chris Fillmore
05/30/2023, 7:10 PMRowScope
because I need to know the direction from which the constraints are coming. I could build a similar thing for ColumnScope
but I don’t have need of it yet
• The transformOrigin
is important but I am not totally sure I understand how this interacts with placeRelative
(if at all). If I use TransformOrigin(0f, 0f)
, the content is drawn outside the bounds of the layout (to the left)Albert Chang
05/31/2023, 2:14 AMModifier.layout { measurable, constraints ->
val placeable = measurable.measure(Constraints())
val scale = constraints.maxWidth.toFloat() / placeable.width
val scaledHeight = (placeable.height * scale).roundToInt()
layout(constraints.maxWidth, scaledHeight) {
placeable.placeRelativeWithLayer(0, 0) {
scaleX = scale
scaleY = scale
transformOrigin = TransformOrigin(0.5f, 0f)
}
}
},
Chris Fillmore
05/31/2023, 3:36 AMplaceRelativeWithLayer