Skip to content

Commit 050e9ac

Browse files
committed
feat(layout): Implement grid padding and enhance grid layout features
- Modifies `applyBaseModifier` to handle padding differently for `ScopedModifier.Grid`. - Adds `toComposePaddingValue` to `PaddingValues` for conversion to Compose `PaddingValues`. - Updates `HorizontalGrid` to accept `isFillMaxWidth` to determine item width. - Updates `VerticalGrid` to add content padding from `ScopedModifier.Grid`. - Updates `ScopedModifier.Grid` to take content padding for horizontal list. - Updates `HorizontalGrid` to take items with `RowScope` and handle padding using `contentPadding` parameter - Updates `ScopedModifier.Grid` to use weight parameter for item width calculation
1 parent 6bb4395 commit 050e9ac

File tree

3 files changed

+70
-19
lines changed

3 files changed

+70
-19
lines changed

compose-remote-layout/src/commonMain/kotlin/com/utsman/composeremote/DynamicLayout.kt

+33-4
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ import androidx.compose.foundation.layout.Arrangement
77
import androidx.compose.foundation.layout.Box
88
import androidx.compose.foundation.layout.Column
99
import androidx.compose.foundation.layout.IntrinsicSize
10+
import androidx.compose.foundation.layout.PaddingValues
1011
import androidx.compose.foundation.layout.Row
12+
import androidx.compose.foundation.layout.RowScope
1113
import androidx.compose.foundation.layout.Spacer
1214
import androidx.compose.foundation.layout.fillMaxHeight
1315
import androidx.compose.foundation.layout.height
16+
import androidx.compose.foundation.layout.padding
1417
import androidx.compose.foundation.layout.width
18+
import androidx.compose.foundation.layout.wrapContentWidth
1519
import androidx.compose.foundation.lazy.LazyRow
1620
import androidx.compose.foundation.lazy.rememberLazyListState
1721
import androidx.compose.foundation.rememberScrollState
@@ -438,10 +442,14 @@ private fun RenderGrid(
438442
}
439443
} ?: Arrangement.SpaceAround
440444

445+
val padding = scopedMod?.base?.padding ?: com.utsman.composeremote.PaddingValues()
446+
val contentPadding = padding.toComposePaddingValue()
447+
441448
if (orientation == "horizontal") {
442449
val gridModifier =
443450
if (scopedMod.base.height != null) {
444-
modifier.height(scopedMod.base.height.dp)
451+
modifier
452+
.height(scopedMod.base.height.dp)
445453
} else {
446454
modifier
447455
}
@@ -455,6 +463,7 @@ private fun RenderGrid(
455463
horizontalArrangement = horizontalArrangement,
456464
verticalArrangement = verticalArrangement,
457465
enableSnap = enableSnap,
466+
contentPadding = contentPadding,
458467
path = path,
459468
) { index, wrapper ->
460469
ChildDynamicLayout(
@@ -467,11 +476,17 @@ private fun RenderGrid(
467476
)
468477
}
469478
} else {
479+
val paddingModifier = gridModifier.then(
480+
Modifier.padding(contentPadding),
481+
)
482+
483+
val isFillMaxWidth = scopedMod.base.fillMaxWidth
470484
HorizontalGrid(
471485
items = component.children.orEmpty(),
472486
rows = scopedMod.rows ?: 1,
473-
modifier = gridModifier,
487+
modifier = paddingModifier,
474488
horizontalArrangement = horizontalArrangement,
489+
isFillMaxWidth = isFillMaxWidth ?: false,
475490
verticalArrangement = verticalArrangement,
476491
) { index, wrapper ->
477492
ChildDynamicLayout(
@@ -524,10 +539,14 @@ private fun RenderGrid(
524539
modifier
525540
}
526541

542+
val paddingModifier = gridModifier.then(
543+
Modifier.padding(contentPadding),
544+
)
545+
527546
VerticalGrid(
528547
items = component.children.orEmpty(),
529548
columns = scopedMod?.columns ?: 1,
530-
modifier = gridModifier,
549+
modifier = paddingModifier,
531550
verticalArrangement = verticalArrangement,
532551
horizontalArrangement = horizontalArrangement,
533552
) { index, wrapper ->
@@ -892,16 +911,23 @@ private fun <T> HorizontalGrid(
892911
modifier: Modifier = Modifier,
893912
horizontalArrangement: Arrangement.Horizontal,
894913
verticalArrangement: Arrangement.Vertical,
895-
itemContent: @Composable (Int, T) -> Unit,
914+
isFillMaxWidth: Boolean,
915+
itemContent: @Composable RowScope.(Int, T) -> Unit,
896916
) {
897917
val columns = (items.size + rows - 1) / rows
898918

899919
Row(
900920
modifier = modifier,
901921
horizontalArrangement = horizontalArrangement,
902922
) {
923+
val itemMod = if (isFillMaxWidth) {
924+
Modifier.weight(1f / rows)
925+
} else {
926+
Modifier.wrapContentWidth()
927+
}
903928
for (columnIndex in 0 until columns) {
904929
Column(
930+
modifier = itemMod,
905931
verticalArrangement = verticalArrangement,
906932
) {
907933
for (rowIndex in 0 until rows) {
@@ -911,6 +937,7 @@ private fun <T> HorizontalGrid(
911937
contentAlignment = Alignment.Center,
912938
) {
913939
itemContent(
940+
this@Row,
914941
itemIndex,
915942
items[itemIndex],
916943
)
@@ -937,6 +964,7 @@ private fun <T> ScrollableHorizontalGrid(
937964
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
938965
enableSnap: Boolean,
939966
path: String,
967+
contentPadding: PaddingValues = PaddingValues(),
940968
itemContent: @Composable (Int, T) -> Unit,
941969
) {
942970
val columns = (items.size + rows - 1) / rows
@@ -976,6 +1004,7 @@ private fun <T> ScrollableHorizontalGrid(
9761004
modifier = modifier,
9771005
horizontalArrangement = horizontalArrangement,
9781006
flingBehavior = flingBehavior,
1007+
contentPadding = contentPadding,
9791008
) {
9801009
items(columns) { columnIndex ->
9811010
Column(

compose-remote-layout/src/commonMain/kotlin/com/utsman/composeremote/Models.kt

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.utsman.composeremote
22

3+
import androidx.compose.ui.unit.dp
34
import kotlinx.serialization.SerialName
45
import kotlinx.serialization.Serializable
56

@@ -159,6 +160,7 @@ sealed class ScopedModifier {
159160
val columns: Int? = null,
160161
val rows: Int? = null,
161162
val orientation: String? = null,
163+
val weight: Int? = 1,
162164
val enableSnapHorizontal: Boolean? = false,
163165
val horizontalArrangement: String? = null,
164166
val verticalArrangement: String? = null,
@@ -248,7 +250,23 @@ data class PaddingValues(
248250
val top: Int? = null,
249251
val end: Int? = null,
250252
val bottom: Int? = null,
251-
)
253+
) {
254+
fun toComposePaddingValue(): androidx.compose.foundation.layout.PaddingValues = if (horizontal != null && vertical != null) {
255+
androidx.compose.foundation.layout.PaddingValues(
256+
horizontal = horizontal.dp,
257+
vertical = vertical.dp,
258+
)
259+
} else if (all != null) {
260+
androidx.compose.foundation.layout.PaddingValues(all.dp)
261+
} else {
262+
androidx.compose.foundation.layout.PaddingValues(
263+
start = start?.dp ?: 0.dp,
264+
top = top?.dp ?: 0.dp,
265+
end = end?.dp ?: 0.dp,
266+
bottom = bottom?.dp ?: 0.dp,
267+
)
268+
}
269+
}
252270

253271
@Serializable
254272
data class MarginValues(

compose-remote-layout/src/commonMain/kotlin/com/utsman/composeremote/Modifiers.kt

+18-14
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fun applyJsonModifier(
3535
): Modifier {
3636
if (scopedModifier == null) return base
3737

38-
var mod = applyBaseModifier(base, scopedModifier.base, onClickHandler)
38+
var mod = applyBaseModifier(base, scopedModifier, onClickHandler)
3939

4040
mod =
4141
when (scopedModifier) {
@@ -51,9 +51,11 @@ fun applyJsonModifier(
5151

5252
private fun applyBaseModifier(
5353
mod: Modifier,
54-
base: BaseModifier,
54+
scopedModifier: ScopedModifier,
5555
onClickHandler: (String) -> Unit,
5656
): Modifier {
57+
val base = scopedModifier.base
58+
5759
val modifierOrder = ModifierOrderTracker.getCurrentOrder()
5860
val modifierMap = mutableMapOf<String, Modifier>()
5961

@@ -164,18 +166,20 @@ private fun applyBaseModifier(
164166
)
165167
}
166168

167-
base.padding?.let { padding ->
168-
modifierMap["padding"] =
169-
when {
170-
padding.horizontal != null -> Modifier.padding(horizontal = padding.horizontal.dp)
171-
padding.vertical != null -> Modifier.padding(vertical = padding.vertical.dp)
172-
padding.start != null -> Modifier.padding(start = padding.start.dp)
173-
padding.top != null -> Modifier.padding(top = padding.top.dp)
174-
padding.end != null -> Modifier.padding(end = padding.end.dp)
175-
padding.bottom != null -> Modifier.padding(bottom = padding.bottom.dp)
176-
padding.all != null -> Modifier.padding(padding.all.dp)
177-
else -> Modifier
178-
}
169+
if (scopedModifier !is ScopedModifier.Grid) {
170+
base.padding?.let { padding ->
171+
modifierMap["padding"] =
172+
when {
173+
padding.horizontal != null -> Modifier.padding(horizontal = padding.horizontal.dp)
174+
padding.vertical != null -> Modifier.padding(vertical = padding.vertical.dp)
175+
padding.start != null -> Modifier.padding(start = padding.start.dp)
176+
padding.top != null -> Modifier.padding(top = padding.top.dp)
177+
padding.end != null -> Modifier.padding(end = padding.end.dp)
178+
padding.bottom != null -> Modifier.padding(bottom = padding.bottom.dp)
179+
padding.all != null -> Modifier.padding(padding.all.dp)
180+
else -> Modifier
181+
}
182+
}
179183
}
180184

181185
base.margin?.let { margin ->

0 commit comments

Comments
 (0)