From d07268578152c3b1cb49c68661edebf91fb885b4 Mon Sep 17 00:00:00 2001 From: Cheon Jaeung Date: Sat, 11 Oct 2025 13:11:05 +0900 Subject: [PATCH 1/5] Add SimpleGridCells.FixedSize --- grid/api/android/grid.api | 10 + grid/api/jvm/grid.api | 10 + .../compose/grid/SimpleGridCells.kt | 59 +++ .../cheonjaeung/compose/grid/BoxGridTest.kt | 450 ++++++++++++++++++ .../compose/grid/HorizontalGridTest.kt | 135 ++++++ .../compose/grid/VerticalGridTest.kt | 115 +++++ ...st_testAdaptiveRowsAndFixedSizeColumns.png | Bin 0 -> 4569 bytes ...veRowsAndFixedSizeColumnsWithFillFalse.png | Bin 0 -> 4569 bytes ...dTest_testFixedRowsAndFixedSizeColumns.png | Bin 0 -> 5140 bytes ...edRowsAndFixedSizeColumnsWithFillFalse.png | Bin 0 -> 4057 bytes ...t_testFixedSizeRowsAndFixedSizeColumns.png | Bin 0 -> 4492 bytes ...zeRowsAndFixedSizeColumnsWithFillFalse.png | Bin 0 -> 4492 bytes ...d_HorizontalGridTest_testFixedSizeRows.png | Bin 0 -> 4406 bytes ...ridTest_testFixedSizeRowsWithFillFalse.png | Bin 0 -> 4237 bytes ..._VerticalGridTest_testFixedSizeColumns.png | Bin 0 -> 4041 bytes ...Test_testFixedSizeColumnsWithFillFalse.png | Bin 0 -> 4344 bytes 16 files changed, 779 insertions(+) create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumns.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumnsWithFillFalse.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedRowsAndFixedSizeColumns.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedRowsAndFixedSizeColumnsWithFillFalse.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedSizeRowsAndFixedSizeColumns.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedSizeRowsAndFixedSizeColumnsWithFillFalse.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_HorizontalGridTest_testFixedSizeRows.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_HorizontalGridTest_testFixedSizeRowsWithFillFalse.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_VerticalGridTest_testFixedSizeColumns.png create mode 100644 grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_VerticalGridTest_testFixedSizeColumnsWithFillFalse.png diff --git a/grid/api/android/grid.api b/grid/api/android/grid.api index 1143dcc..b6c4c92 100644 --- a/grid/api/android/grid.api +++ b/grid/api/android/grid.api @@ -91,3 +91,13 @@ public final class com/cheonjaeung/compose/grid/SimpleGridCells$Fixed : com/cheo public fun hashCode ()I } +public final class com/cheonjaeung/compose/grid/SimpleGridCells$FixedSize : com/cheonjaeung/compose/grid/SimpleGridCells { + public static final field $stable I + public synthetic fun (FZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (FZLkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun calculateCrossAxisCellSizes (Landroidx/compose/ui/unit/Density;II)Ljava/util/List; + public fun equals (Ljava/lang/Object;)Z + public fun fillCellSize ()Z + public fun hashCode ()I +} + diff --git a/grid/api/jvm/grid.api b/grid/api/jvm/grid.api index 1143dcc..b6c4c92 100644 --- a/grid/api/jvm/grid.api +++ b/grid/api/jvm/grid.api @@ -91,3 +91,13 @@ public final class com/cheonjaeung/compose/grid/SimpleGridCells$Fixed : com/cheo public fun hashCode ()I } +public final class com/cheonjaeung/compose/grid/SimpleGridCells$FixedSize : com/cheonjaeung/compose/grid/SimpleGridCells { + public static final field $stable I + public synthetic fun (FZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (FZLkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun calculateCrossAxisCellSizes (Landroidx/compose/ui/unit/Density;II)Ljava/util/List; + public fun equals (Ljava/lang/Object;)Z + public fun fillCellSize ()Z + public fun hashCode ()I +} + diff --git a/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt b/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt index 48dbbb7..df55531 100644 --- a/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt +++ b/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt @@ -134,4 +134,63 @@ interface SimpleGridCells { return hash } } + + /** + * Make grid to have as many rows or columns as possible and each cell has exactly [size]. + * If [size] is bigger than container's size, the cell will have the same size to the container. + * + * For example, `FixedSize(20.dp)` for `VerticalGrid(Modifier.width(66.dp)` means that there + * will be 3 columns and each cell will have 20dp width and 6dp is remained. + * + * In other case, `FixedSize(150.dp)` for `VerticalGrid(Modifier.width(100.dp)` means that there + * will be only one column and the cell will have 100dp width. + * + * @param size The size which each cell should have. + * @param fill When `true`, item composable fill cell's width or height. + */ + @ExperimentalGridApi + class FixedSize( + private val size: Dp, + private val fill: Boolean = true, + ) : SimpleGridCells { + init { + if (size <= 0.dp) { + throw IllegalArgumentException("FixedSize size must be a positive, but $size") + } + } + + override fun Density.calculateCrossAxisCellSizes( + availableSize: Int, + spacing: Int + ): List { + val cellSize = size.roundToPx() + val availableSizeWithSpacing = availableSize + spacing + val cellSizeWithSpacing = cellSize + spacing + + return if (cellSizeWithSpacing < availableSizeWithSpacing) { + val count = availableSizeWithSpacing / cellSizeWithSpacing + return List(count) { cellSize } + } else { + List(1) { availableSize } + } + } + + override fun fillCellSize(): Boolean { + return fill + } + + override fun equals(other: Any?): Boolean { + if (other !is FixedSize) return false + if (this.size != other.size) return false + if (this.fill != other.fill) return false + return true + } + + override fun hashCode(): Int { + var hash = 1 + hash = hash * 31 + size.hashCode() + hash = hash * 31 + fill.hashCode() + return hash + } + } } diff --git a/grid/src/test/java/com/cheonjaeung/compose/grid/BoxGridTest.kt b/grid/src/test/java/com/cheonjaeung/compose/grid/BoxGridTest.kt index d16b83d..2e0207a 100644 --- a/grid/src/test/java/com/cheonjaeung/compose/grid/BoxGridTest.kt +++ b/grid/src/test/java/com/cheonjaeung/compose/grid/BoxGridTest.kt @@ -711,6 +711,456 @@ class BoxGridTest { } } + @Test + fun testFixedRowsAndFixedSizeColumns() { + paparazzi.snapshot { + Column { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + rows = SimpleGridCells.Fixed(2), + columns = SimpleGridCells.FixedSize(80.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + rows = SimpleGridCells.Fixed(2), + columns = SimpleGridCells.FixedSize(80.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + } + } + } + } + + @Test + fun testFixedRowsAndFixedSizeColumnsWithFillFalse() { + paparazzi.snapshot { + Column { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + rows = SimpleGridCells.Fixed(2, fill = false), + columns = SimpleGridCells.FixedSize(80.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + rows = SimpleGridCells.Fixed(2, fill = false), + columns = SimpleGridCells.FixedSize(80.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + } + } + } + } + + @Test + fun testAdaptiveRowsAndFixedSizeColumns() { + paparazzi.snapshot { + Column { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + rows = SimpleGridCells.Adaptive(60.dp), + columns = SimpleGridCells.FixedSize(80.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + rows = SimpleGridCells.Adaptive(60.dp), + columns = SimpleGridCells.FixedSize(80.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + } + } + } + } + + @Test + fun testAdaptiveRowsAndFixedSizeColumnsWithFillFalse() { + paparazzi.snapshot { + Column { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + rows = SimpleGridCells.Adaptive(60.dp, fill = false), + columns = SimpleGridCells.FixedSize(80.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + rows = SimpleGridCells.Adaptive(60.dp, fill = false), + columns = SimpleGridCells.FixedSize(80.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + } + } + } + } + + @Test + fun testFixedSizeRowsAndFixedSizeColumns() { + paparazzi.snapshot { + Column { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + rows = SimpleGridCells.FixedSize(60.dp), + columns = SimpleGridCells.FixedSize(80.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + rows = SimpleGridCells.FixedSize(60.dp), + columns = SimpleGridCells.FixedSize(80.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + } + } + } + } + + @Test + fun testFixedSizeRowsAndFixedSizeColumnsWithFillFalse() { + paparazzi.snapshot { + Column { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + rows = SimpleGridCells.FixedSize(60.dp, fill = false), + columns = SimpleGridCells.FixedSize(80.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + BoxGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + rows = SimpleGridCells.FixedSize(60.dp, fill = false), + columns = SimpleGridCells.FixedSize(80.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 1, column = 1) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 2, column = 2) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .position(row = 3, column = 1) + .background(Color.Red) + ) + } + } + } + } + } + @Test fun testSpacing() { val colors = listOf( diff --git a/grid/src/test/java/com/cheonjaeung/compose/grid/HorizontalGridTest.kt b/grid/src/test/java/com/cheonjaeung/compose/grid/HorizontalGridTest.kt index 4e5c22b..a361fec 100644 --- a/grid/src/test/java/com/cheonjaeung/compose/grid/HorizontalGridTest.kt +++ b/grid/src/test/java/com/cheonjaeung/compose/grid/HorizontalGridTest.kt @@ -17,6 +17,7 @@ import app.cash.paparazzi.Paparazzi import org.junit.Rule import org.junit.Test +@OptIn(ExperimentalGridApi::class) class HorizontalGridTest { @get:Rule val paparazzi = Paparazzi( @@ -307,6 +308,140 @@ class HorizontalGridTest { } } + @Test + fun testFixedSizeRows() { + paparazzi.snapshot { + Column { + HorizontalGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + rows = SimpleGridCells.FixedSize(100.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Red) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + HorizontalGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + rows = SimpleGridCells.FixedSize(100.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Red) + ) + } + } + } + } + } + + @Test + fun testFixedSizeRowsWithFillFalse() { + paparazzi.snapshot { + Column { + HorizontalGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + rows = SimpleGridCells.FixedSize(100.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(80.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(80.dp) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(80.dp) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(80.dp) + .background(Color.Red) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + HorizontalGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + rows = SimpleGridCells.FixedSize(100.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(80.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(80.dp) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(80.dp) + .background(Color.Yellow) + ) + Box( + modifier = Modifier + .size(80.dp) + .background(Color.Red) + ) + } + } + } + } + } + @Test fun testBreakDownToNextLine() { val colors = listOf( diff --git a/grid/src/test/java/com/cheonjaeung/compose/grid/VerticalGridTest.kt b/grid/src/test/java/com/cheonjaeung/compose/grid/VerticalGridTest.kt index 38cc52a..2fb8762 100644 --- a/grid/src/test/java/com/cheonjaeung/compose/grid/VerticalGridTest.kt +++ b/grid/src/test/java/com/cheonjaeung/compose/grid/VerticalGridTest.kt @@ -17,6 +17,7 @@ import app.cash.paparazzi.Paparazzi import org.junit.Rule import org.junit.Test +@OptIn(ExperimentalGridApi::class) class VerticalGridTest { @get:Rule val paparazzi = Paparazzi( @@ -287,6 +288,120 @@ class VerticalGridTest { } } + @Test + fun testFixedSizeColumns() { + paparazzi.snapshot { + Column { + VerticalGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + columns = SimpleGridCells.FixedSize(120.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Yellow) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + VerticalGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + columns = SimpleGridCells.FixedSize(120.dp) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Yellow) + ) + } + } + } + } + } + + @Test + fun testFixedSizeColumnsWithFillFalse() { + paparazzi.snapshot { + Column { + VerticalGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.LightGray), + columns = SimpleGridCells.FixedSize(120.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Yellow) + ) + } + + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + VerticalGrid( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.Gray), + columns = SimpleGridCells.FixedSize(120.dp, fill = false) + ) { + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Blue) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Green) + ) + Box( + modifier = Modifier + .size(100.dp) + .background(Color.Yellow) + ) + } + } + } + } + } + @Test fun testBreakDownToNextLine() { val colors = listOf( diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumns.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumns.png new file mode 100644 index 0000000000000000000000000000000000000000..9017eeeeb899cc3451ad0d15490920e187e13fe1 GIT binary patch literal 4569 zcmdUzT}YEr7{|}vhMbLzGaY0fn8(x>mb5Zgp)pUZZJ4@QWKg0JNc4G8L4?R!?{Zye zV;8#+!WMm82vadjZ%R`{v1n=`mQq6Df}{wgB+{O>Q<(^(qOAJN;UoSut^I(Fq3s;REKV5gk zJ#_ZG`)FGJ?siP~7cGCH?C$;cs*;L4xA4<|SQ_#$e617ufKO-`q?25h!yp)NHjITx zW=ablj$4S-d@mkvS}}bk1@8xa=QTJu@+n=!%mV`H+ZFMas)bbM8ev^*it35gG8VT}25fZr%zv0CHF&}B3f2jV%Z&2k@$79Zz0njT!GxxtMW z%NMFY-0tUNdbT+H1zUhnEy(rw!o zBM}_UfG()Wf=u=n`_IzYx+XWT$Xvl?j(qd`vB;(zg2ae4I*ui&#($OWUk|eYm4sTG aYtO|zd;g`dV&_%(%LbYE<{5mf#QqDFnz*k3 literal 0 HcmV?d00001 diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumnsWithFillFalse.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumnsWithFillFalse.png new file mode 100644 index 0000000000000000000000000000000000000000..9017eeeeb899cc3451ad0d15490920e187e13fe1 GIT binary patch literal 4569 zcmdUzT}YEr7{|}vhMbLzGaY0fn8(x>mb5Zgp)pUZZJ4@QWKg0JNc4G8L4?R!?{Zye zV;8#+!WMm82vadjZ%R`{v1n=`mQq6Df}{wgB+{O>Q<(^(qOAJN;UoSut^I(Fq3s;REKV5gk zJ#_ZG`)FGJ?siP~7cGCH?C$;cs*;L4xA4<|SQ_#$e617ufKO-`q?25h!yp)NHjITx zW=ablj$4S-d@mkvS}}bk1@8xa=QTJu@+n=!%mV`H+ZFMas)bbM8ev^*it35gG8VT}25fZr%zv0CHF&}B3f2jV%Z&2k@$79Zz0njT!GxxtMW z%NMFY-0tUNdbT+H1zUhnEy(rw!o zBM}_UfG()Wf=u=n`_IzYx+XWT$Xvl?j(qd`vB;(zg2ae4I*ui&#($OWUk|eYm4sTG aYtO|zd;g`dV&_%(%LbYE<{5mf#QqDFnz*k3 literal 0 HcmV?d00001 diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedRowsAndFixedSizeColumns.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedRowsAndFixedSizeColumns.png new file mode 100644 index 0000000000000000000000000000000000000000..eccc73de36636dee9ae4b80d8ecbd4f28d1a2c34 GIT binary patch literal 5140 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygYa!n7srr_TW_y9@-is$ zxE}0s=8h6LCMbL3MV7*BA->7;4G)-AN(;`s@}l;66n8^=YXYZYgMd;CgHwk96NjP` zhe8VnWdaKYtc(~GMVuH~0yr22oD^9cI9de;NWg)E)tiH{ML>~7z^O&RfkV)VLD7W* z0g$%_iPymHpvW^A0isxv!r-LQ!oaamfJvdniK9V)OL2e%fL2eVQhEfZX^^*oxQ}N5 z6C+B>5pcRFL}6k?j=um7SxMSQSAmFAf57th^Ab~wlYzDYlL;`XZ~==8N|_2Ra*n`K z0+>mGWd<-&(}pSH1kAg@1aP4RXp^FeA`8$qU!Z*=PQo-1ZoSaU2uyUKG8LNsC}TDV zRB?cPAP6i~frT2#Gt_4Wa6I**VW1!f_#Fuh*I_QtywYXQzQ$eEolCRDe2jSW>ls(@r5!&3ggdelr2L zOnkvLfH1X%&DB~!Nd{Eg1G}w*kGW8w3Nw&E)e@++Mx!u6HyhY!m?6LfY!h)P0vlMs zj{V?cVzz`E1Wru_Myx`M8n`LP3G7`sWdI%CATW#C!aEJYZGS;fs~=eW0Tb;YW42yU zhBRr>+s8Br3>*P1uxs!Kk~2mif%>B~OgI=}MZe57=Lds|eUpJ)$Br1_Xdi>8tDnm{ Hr-UW|8SNpn literal 0 HcmV?d00001 diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedRowsAndFixedSizeColumnsWithFillFalse.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedRowsAndFixedSizeColumnsWithFillFalse.png new file mode 100644 index 0000000000000000000000000000000000000000..fab3254c6d252aa60fcf21556da2f5bc0b46b357 GIT binary patch literal 4057 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzly1OEa~7srr_TW_yA^0pWV zv|W^X942{ZRtPtfK_kB(3oD1hju}@swBIZ#kN;=G{8lAiQ?*HE@BPAg>I}@dj6bQ5ey){_8266|6Xa1?TeE!2?dF^Xa3d7>|3(5=%ErS$sEOcjZ;9wk_ zNWh7Ke&|sCh4*qtFFiX3$|#`33Cb@NGaWc=n*_KNfmwQ?0245S(}t?G+NYXBFwc=ni-hzTY>o*ninZ#Dt-|F`#`A$=ypXKF&7G)no7e! zK@RYphIm7!K;ZS(V}H)56ec$aFcFCqTI3iR6j=r*0w!}71}Ba|h#CZ{SQuIaC`D}C z4>##B9(X=QNM&Vd{eOEIRbX~gWB{gA22joh<~k1Q3QVJBTL9Fa-~u`m=u|F}nTtVX zA?=zF4jioBSgKHrI+a)f%8G5w7E+PVWyeX^%<$$sVDe`gglQk*Br4?q%JUFb6Yz#B z8HJr&(03_NE#4vkOtrvuyd^TOk8n3(f+!7}RJY z46Mb4oj_d!MHXOXE;tC8kaj*w+d{x;rx36>YPkSvcq^I!qt}7M7w888Ct+#}n}Zuq zzz!KOqLe`GC{!lTqFmi&$x5BTK%_}CwPjHE8x$Eh1|@QOA&5OTeuV136uTttH;wH# Qu*=Ti>FVdQ&MBb@00Lmnh5!Hn literal 0 HcmV?d00001 diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedSizeRowsAndFixedSizeColumns.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedSizeRowsAndFixedSizeColumns.png new file mode 100644 index 0000000000000000000000000000000000000000..ef8350868c8fdf73418d5007f4414448d6693736 GIT binary patch literal 4492 zcmdT|T}V_x6du<#XE%&lGy4(6SuOV=(#%{Ft=;kWDl3v@^iXQ0`I0DsL>ex3w=~oi zjeV9Kz+i02oONMtCYUJQw;*o82vG++z)PXPmVOU5oDp-RF;V!#@P zXzUyTb21+4?cHxZck@Wq%g*Y+&F$?18`ivkZ1TPL=v4O`g!%|tD!U?-N#Fzj{~_S1=LWC^P!A6F>81rlz79{5)n(*Ndw_l*fZVSG|0 zTzhVL7{c)Db$!$72R&geJ~7w`JBS3nZd@R+34Ses{xd=!Is(!U7#LedN`b$a&V&+a zUGIR@SdaD>`rkx-y-8()5)i=F^rfqL z*Tbj-8fayL4x>Qf)v~F5%u~MzQ}mY$h7}^rNtf6igZxEjTv$p#2JGUTi?EZ(Occ(! z?5gLOdrU-aimSOUEy;TR(v!jIqKG7!-N9OWq$)Ha3ex3w=~oi zjeV9Kz+i02oONMtCYUJQw;*o82vG++z)PXPmVOU5oDp-RF;V!#@P zXzUyTb21+4?cHxZck@Wq%g*Y+&F$?18`ivkZ1TPL=v4O`g!%|tD!U?-N#Fzj{~_S1=LWC^P!A6F>81rlz79{5)n(*Ndw_l*fZVSG|0 zTzhVL7{c)Db$!$72R&geJ~7w`JBS3nZd@R+34Ses{xd=!Is(!U7#LedN`b$a&V&+a zUGIR@SdaD>`rkx-y-8()5)i=F^rfqL z*Tbj-8fayL4x>Qf)v~F5%u~MzQ}mY$h7}^rNtf6igZxEjTv$p#2JGUTi?EZ(Occ(! z?5gLOdrU-aimSOUEy;TR(v!jIqKG7!-N9OWq$)Ha3H zXuG)b&8vU{Q;on^Aqobo4m2t!&XE#daO7m+%!3P#d@MDLn_BQmP1&|?FI!)ty@=q< zD@J|Z=RWf|uq)~~aVWHKC^iTvwJaVau5X|ynKEEHf;XmR2o zQGjFNhQa7Ha1cAas942Op5?U1{xd!iY0qcO1%SX6>YX3pBgkx9~{Fw{%J0mlnN{@NG~x^vCfN+{*1|NeW)wE34$eq{Q>wXmO|L4av+ zB83(^CI%-C?5JGg(BX#@82;Qh@R6Jt@|X(MT&pXhjvG8_lscs>uw^r7+FU55ET}Pv zt=YA~sKx)h*pG53I;*a5^YNrAh!^kqoMw$~6sA30z3$xZdqL;qm#iy~@lPwk>ju42mp+6FG3$GBG%D z&LHs@SClY%3{}kD@L1SoQ3^ zU#%kO)NqXVvB1$!&jww54)2!0sj1MWK)+wz+#?@v8hW+}G_2zUHiOB}zz4+My{kKt z_PJNZiQ~eKLK&q+6F`OQU}@lqfU_x8>x}@8!Pd(8yKCRQ{^`?YCjql(EHDYT2#}2$ zbmyE;+h}8<&?&%Vk|)#F5##~toeXR@3DK720`}FY-f0?)Eu38?cC(Le3Zp`dlARQY m(x~`_gZvr+e{E7Tx1Ph?gXz0hx;k)}fx*+&&t;ucLK6TO+ZSK} literal 0 HcmV?d00001 diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_VerticalGridTest_testFixedSizeColumns.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_VerticalGridTest_testFixedSizeColumns.png new file mode 100644 index 0000000000000000000000000000000000000000..30a1bfce9dccd740381a3516f520f0fdba29b6da GIT binary patch literal 4041 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzly1OEh17srr_TW_y!%su2F z(f06mt6)%cQVY+6Cc_sFUXLv^jF?4DOr}jQcs`GDUrZjutp%qS`=4j{{(8ywDU%$E zZ!e#5b?$11uQhckk<-?RGCFYhatJyJI0-wo2q=m`C=)QpL{WqhC}yJQ!qGZPQ5XcQ z4B&ut1c!D@0Fw_e&|5CF1TYAID1p&%rcxS%1TZu?Bhv9de~#mY+$R0O$8uX@R`ISX zwf!c4=$ zV;r20qe8G9ux=}uwd_kyY`G`blbD%X?|#?(8ttIm!m*H3(Me;JB0C6}z#-TnFbf!t za8iJa0mKn#5>RSU0|xFWMRpKyD1bsx5jB(rxWIu84POPq$@fP0>#xS2Z5;NkVyvr` zH{vlix!W$l5GUxw&>}EMkzxtUAaxlq$P`OB2C3r)d9V%UIAvi_9E`|;LzZ!Hx(w(l ipyQaR>$nE{Pt3VYX75UCDtdukbOujXKbLh*2~7Yrnfqn{ literal 0 HcmV?d00001 diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_VerticalGridTest_testFixedSizeColumnsWithFillFalse.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_VerticalGridTest_testFixedSizeColumnsWithFillFalse.png new file mode 100644 index 0000000000000000000000000000000000000000..1c7d840e5f982df50fb905545cfa529c1a81320a GIT binary patch literal 4344 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygTQ`I7srr_TW_x#dNBuz zv|ZfZd8KiU;@c&gJZ7@;ED=}}G!k2??6DJ%ycIus#-T|kN zn&)Ne{H%{YHH`PtY}$0?tKzlSU;Cx^@hL|JzTW?J^Pbkf|8#a;cT3!Md$-Q}hx@$` zDYZChfKi74*FrE-gbHZ1a4h5m3n{gzwSW|M2+R@~mJ~1qGJw7V2LLCs|Dj<54P~d9IFU)HdrArra;afeiYDCYCvzn0{|K*Sc26_ zBL`cE;nqNushEmDp^WJql=!HyQT+2`Wze)`l_x$)r1fuJ!EefHS#Nj#lUUjA)fOf9 zm+Q=FLgzv1xIrFlgE>wW891no z{?u_i|6KXO)VEkru=CKGF!jiL&hM9Auf6Ma>p|v(r@B3Exl7*d43tO|c2X1pBNvX= z05B4O3WzwhKm-Cf1SwUdC?bZ<)J%xME*!p4n@u1JTQ0PKTrvD8pr?eP!Rm`QR242RtXV5|uk9oYxhbesP;< zYown4<~{8n-&(AC_j^imk@3k-V#_YSUa@N0Az+So_vK&|aAFvosO5s-Aaxlqyjm_O z4pPSr@?aaxaVo&jGANN^3CkdL88EyQOE{?PxPK?C(+?OjP5W@M4>+R1;OXk;vd$@? F2>{8}(2f8A literal 0 HcmV?d00001 From 5fb71c1c1152045ec4556c236808923fcbf9e867 Mon Sep 17 00:00:00 2001 From: Cheon Jaeung Date: Sat, 11 Oct 2025 20:10:47 +0900 Subject: [PATCH 2/5] Update documentation for FixedSize --- README.md | 2 +- docs/cell-strategy.md | 48 ++++++++++++++++++++++++++++-- docs/images/fixedsize-example.png | Bin 0 -> 15850 bytes docs/index.md | 2 +- 4 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 docs/images/fixedsize-example.png diff --git a/README.md b/README.md index ae98482..6cdcc1b 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This library can be simpler solution for small grid UI. There are benefits of this library: - **Similar API to LazyGrid**: The GridLayout's APIs are designed to provide similar development experience to LazyGrid. -- **Easy to implement adaptive grid**: There are _"Fixed"_ and _"Adaptive"_ for grid layout management like LazyGrid. +- **Easy to implement various grid**: There are _"Fixed"_, _"Adaptive"_ and _"FixedSize"_ for grid layout management like LazyGrid. Like LazyGrid, it eliminates dealing with different screen sizes. - **Simple to use as a part of LazyList**: The GridLayout is not lazy layout. It can be simply placed in lazy layouts. If only a portion of the full layout is grid, No need to use LazyGrid with span size for full layout. diff --git a/docs/cell-strategy.md b/docs/cell-strategy.md index ad669ee..b2d7af5 100644 --- a/docs/cell-strategy.md +++ b/docs/cell-strategy.md @@ -3,8 +3,8 @@ All grid layout composables take a cell strategy parameter called `SimpleGridCells`. `SimpleGridCells` defines the number of cells and the size of each cell. -There are 2 types of cell strategy, `Fixed` and `Adaptive`. -They are similar to LazyGrid's `Fixed` and `Adaptive`. +There are several types of cell strategy, `Fixed`, `Adaptive` and `FixedSize`. +They are similar to LazyGrid's `GridCells.Fixed`, `GridCells.Adaptive` and `GridCells.FixedSize`. ## Fixed @@ -94,9 +94,51 @@ And each cells will have 1/3 of 400dp (about 133.333dp) width or height. If the grid size is expanded to 600dp, the number of cells on each line will be changed to 5 and each cell's size will be 120dp. +## FixedSize + +`SimpleGridCells.FixedSize` is a cell strategy for as many cells as possible with exact size. + +The API of `FixedSize` looks like this: + +```kotlin +class FixedSize( + private val size: Dp, + private val fill: Boolean = true +) : SimpleGridCells +``` + +There is a parameter called `size`. This is the size of each cell should have. +The `size` must be a positive size. If the size is 0 or below, it occurs an exception. +If the `size` is bigger than container's size, the cell will have the same size to the container. + +!!! note + For information about `fill` parameter, read [Fill Option](#fill-option) section. + +For example, a grid has 400dp width or height and `FixedSize(120.dp)` is applied. + +```kotlin +HorizontalGrid( + rows = SimpleGridCells.FixedSize(120.dp), + modifier = Modifier.height(400.dp) +) { /* content */ } + +VerticalGrid( + columns = SimpleGridCells.FixedSize(120.dp), + modifier = Modifier.width(400.dp) +) { /* content */ } +``` + +![fixed-size-example](./images/fixedsize-example.png) + +The grid will have 3 cells on each line and the remaining space will not be used. +If the grid size is expanded to 600dp, the number of cells on each line will be changed to 5. + +In other case, `FixedSize(300.dp)` for `VerticalGrid(Modifier.width(200.dp))` means that there +will be only one column and the cell will have 200dp width. + ## Fill Option -Both `Fixed` and `Adaptive` have a optional parameter named `fill`. +All cell strategy classes have a optional parameter named `fill`. The `fill` parameter determines that grid's item composable should fill grid cell's size. When `fill` is true, grid layout forces item composable to have width or height to fit cell's maximum width or height. diff --git a/docs/images/fixedsize-example.png b/docs/images/fixedsize-example.png new file mode 100644 index 0000000000000000000000000000000000000000..fab1b7b6269fc57f6735fcf92e2d78f53ce058c8 GIT binary patch literal 15850 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 Date: Wed, 15 Oct 2025 20:44:52 +0900 Subject: [PATCH 3/5] Change item size for more clear testing --- .../cheonjaeung/compose/grid/BoxGridTest.kt | 64 +++++++++--------- ...veRowsAndFixedSizeColumnsWithFillFalse.png | Bin 4569 -> 4223 bytes ...zeRowsAndFixedSizeColumnsWithFillFalse.png | Bin 4492 -> 4240 bytes 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/grid/src/test/java/com/cheonjaeung/compose/grid/BoxGridTest.kt b/grid/src/test/java/com/cheonjaeung/compose/grid/BoxGridTest.kt index 2e0207a..037ff04 100644 --- a/grid/src/test/java/com/cheonjaeung/compose/grid/BoxGridTest.kt +++ b/grid/src/test/java/com/cheonjaeung/compose/grid/BoxGridTest.kt @@ -875,24 +875,24 @@ class BoxGridTest { ) { Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .background(Color.Blue) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 1, column = 1) .background(Color.Green) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 2, column = 2) .background(Color.Yellow) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 3, column = 1) .background(Color.Red) ) @@ -909,24 +909,24 @@ class BoxGridTest { ) { Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .background(Color.Blue) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 1, column = 1) .background(Color.Green) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 2, column = 2) .background(Color.Yellow) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 3, column = 1) .background(Color.Red) ) @@ -950,24 +950,24 @@ class BoxGridTest { ) { Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .background(Color.Blue) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 1, column = 1) .background(Color.Green) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 2, column = 2) .background(Color.Yellow) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 3, column = 1) .background(Color.Red) ) @@ -984,24 +984,24 @@ class BoxGridTest { ) { Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .background(Color.Blue) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 1, column = 1) .background(Color.Green) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 2, column = 2) .background(Color.Yellow) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 3, column = 1) .background(Color.Red) ) @@ -1025,24 +1025,24 @@ class BoxGridTest { ) { Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .background(Color.Blue) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 1, column = 1) .background(Color.Green) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 2, column = 2) .background(Color.Yellow) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 3, column = 1) .background(Color.Red) ) @@ -1059,24 +1059,24 @@ class BoxGridTest { ) { Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .background(Color.Blue) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 1, column = 1) .background(Color.Green) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 2, column = 2) .background(Color.Yellow) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 3, column = 1) .background(Color.Red) ) @@ -1100,24 +1100,24 @@ class BoxGridTest { ) { Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .background(Color.Blue) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 1, column = 1) .background(Color.Green) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 2, column = 2) .background(Color.Yellow) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 3, column = 1) .background(Color.Red) ) @@ -1134,24 +1134,24 @@ class BoxGridTest { ) { Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .background(Color.Blue) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 1, column = 1) .background(Color.Green) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 2, column = 2) .background(Color.Yellow) ) Box( modifier = Modifier - .size(100.dp) + .size(50.dp) .position(row = 3, column = 1) .background(Color.Red) ) diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumnsWithFillFalse.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumnsWithFillFalse.png index 9017eeeeb899cc3451ad0d15490920e187e13fe1..dbf0b16893e8baac453b836fc04878d60706fe63 100644 GIT binary patch literal 4223 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygMgc-i(^Q|t+!V9XAd9mZ2bQJ;QA>-69YqYlXk{19SC#fU=(mtWO3kV6<|;labjo*7%~DE z4lr;iVnI$CEevl8IO^Gz7oU8xypiz*-$G>ug%*;~pTd1s{THjIT>5%;YcHc>%I;t5 z`X+rjoB!O5twlhQMZl>=z=1>1i9ykYgAr9g1Q?pY5CsM$5DyV%%LPGDyaPScDgg8v z>C9Xn4n-#pg_bQdYG)t)^4nzTvt=6%Nepse{Ctq%=g$w0T7Unxc#FU;*C|uXW}n)p z(4x@NAkZYhF`mlfZ>en4XLA&Ojhs7R;A}AmkoH_)UAkhgE&;W+6LJKHg0r3!F zax7E^Mj#W=GhDzFLk9Df1SFSdeti5!$1HT}rR%G;rJ0>L7zP402v{)EXk4MHU9!$bmza5mUNC(p|nksear1Nwuv43xfB* zboc!AMjKlxiBxO?ode_n!xmIq(U0l$0u+b9*aXHX7bt$|%Dfd0X$xhP+t~K~3Z4rJ zFjDKKxFauLdaenp){Kn_F>~W+e5*D&(PhdMvF^rRK_>?eM_?m`MUkaNpas}Y5kM6H zHd`EluoWmb%$SNLpcW;tr3q|Nf;^7IlvZwW2aNpIQ`)&gv> z5LQGBi-|FlP#VJ04Wo}1V39Xqb`$iW(+h#Y;mb5Zgp)pUZZJ4@QWKg0JNc4G8L4?R!?{Zye zV;8#+!WMm82vadjZ%R`{v1n=`mQq6Df}{wgB+{O>Q<(^(qOAJN;UoSut^I(Fq3s;REKV5gk zJ#_ZG`)FGJ?siP~7cGCH?C$;cs*;L4xA4<|SQ_#$e617ufKO-`q?25h!yp)NHjITx zW=ablj$4S-d@mkvS}}bk1@8xa=QTJu@+n=!%mV`H+ZFMas)bbM8ev^*it35gG8VT}25fZr%zv0CHF&}B3f2jV%Z&2k@$79Zz0njT!GxxtMW z%NMFY-0tUNdbT+H1zUhnEy(rw!o zBM}_UfG()Wf=u=n`_IzYx+XWT$Xvl?j(qd`vB;(zg2ae4I*ui&#($OWUk|eYm4sTG aYtO|zd;g`dV&_%(%LbYE<{5mf#QqDFnz*k3 diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedSizeRowsAndFixedSizeColumnsWithFillFalse.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedSizeRowsAndFixedSizeColumnsWithFillFalse.png index ef8350868c8fdf73418d5007f4414448d6693736..2ee1bf47fc5bc531b8ed40d7cf11eb1e813ee2eb 100644 GIT binary patch literal 4240 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygFv{ai(^Q|t+!V z1sv-9`saD){O8^u{?!HEMC zH3)DiGFZzT+MbXSa(zE9&w*zGR!o@6kVH=W-}S#xe!G2saMcX^8xjIe*H*`^*6_Ul zqcA7gfdd#qiY^?CEdq)x0!}RgXab<{0%DNdP+>Z7$T|X}8t55d!~?xXGV{W*1_7lO z2B#BT)A#Ew{=Iy5ka2zv4~HTHUQ{z@`t&-l^XJ3Au`0HlRr2yW{j{;xk;4(_1{Ot@ z7J(L^iv*k;PzA_!A}*gfa>z0Q;|XLF$kxHh{M{tbB*5gvk*y=Pc*?wa`)-Q22r%G7 z1=6~1i!0Wyn)1vy8JJ=t-|I>QdU^Ff-q;I@UtCESl$Kk80R;@>)}h2yECIzEC?A57 z4H-;nW~UATCJsgIGqaz?8yIcUS7>1vD1$_GwoQx z9@@R=zJ2%Jy_sHf&-Ds0HQ+`HEqx3*ix=y=7ykHap!%Cj@qpXfOl_}A>G4=w07y*& zU|9sJ#Xw~)9ho9d?w~f@0F~hv_JM+$L-9b?)lkvj_rC{kT8}$u!J&RgOp4F{@w<1y zUgF}h(#kCds!H#6cTBpJa%r2P69L^^|kx?QcscvM}I9KP=4W`uW^?JLQdb3xl+8^xBS~ zAW+nBC_>^3(u4!og9rgoMgfNSLSXZbo=mQV%4m5ODf`l#nE}n$30pT$p1h*JpKuDs zS9%aASnx;>tkgg?fC$>l0ZbeO6%CXEj)l&H)Nw=w+k`{${i}O=PtFv&3mj=+@O1Ta JS?83{1OPfMK$HLg literal 4492 zcmdT|T}V_x6du<#XE%&lGy4(6SuOV=(#%{Ft=;kWDl3v@^iXQ0`I0DsL>ex3w=~oi zjeV9Kz+i02oONMtCYUJQw;*o82vG++z)PXPmVOU5oDp-RF;V!#@P zXzUyTb21+4?cHxZck@Wq%g*Y+&F$?18`ivkZ1TPL=v4O`g!%|tD!U?-N#Fzj{~_S1=LWC^P!A6F>81rlz79{5)n(*Ndw_l*fZVSG|0 zTzhVL7{c)Db$!$72R&geJ~7w`JBS3nZd@R+34Ses{xd=!Is(!U7#LedN`b$a&V&+a zUGIR@SdaD>`rkx-y-8()5)i=F^rfqL z*Tbj-8fayL4x>Qf)v~F5%u~MzQ}mY$h7}^rNtf6igZxEjTv$p#2JGUTi?EZ(Occ(! z?5gLOdrU-aimSOUEy;TR(v!jIqKG7!-N9OWq$)Ha3 Date: Wed, 15 Oct 2025 20:47:38 +0900 Subject: [PATCH 4/5] Fix item X position when using FixedSize in RTL --- .../compose/grid/BoxGridMeasurePolicy.kt | 14 +++++++++++--- ...st_testAdaptiveRowsAndFixedSizeColumns.png | Bin 4569 -> 4549 bytes ...veRowsAndFixedSizeColumnsWithFillFalse.png | Bin 4223 -> 4206 bytes ...dTest_testFixedRowsAndFixedSizeColumns.png | Bin 5140 -> 5086 bytes ...edRowsAndFixedSizeColumnsWithFillFalse.png | Bin 4057 -> 4031 bytes ...t_testFixedSizeRowsAndFixedSizeColumns.png | Bin 4492 -> 4470 bytes ...zeRowsAndFixedSizeColumnsWithFillFalse.png | Bin 4240 -> 4223 bytes 7 files changed, 11 insertions(+), 3 deletions(-) diff --git a/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/BoxGridMeasurePolicy.kt b/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/BoxGridMeasurePolicy.kt index fc100cf..b2d59a7 100644 --- a/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/BoxGridMeasurePolicy.kt +++ b/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/BoxGridMeasurePolicy.kt @@ -189,14 +189,22 @@ private class BoxGridMeasureHelper( val horizontalSpacingPx = horizontalSpacing.roundToPx() val verticalSpacingPx = verticalSpacing.roundToPx() - var currentX = 0 - var currentY = 0 + var currentX = if (layoutDirection == LayoutDirection.Rtl) { + val horizontalSpacingCount = (columnCount - 1).coerceAtLeast(0) + val horizontalSpacingSumPx = horizontalSpacingPx * horizontalSpacingCount + val contentWidth = cellWidthConstraintList.sum() + horizontalSpacingSumPx + measureResult.layoutSize.width.roundToInt() - contentWidth + } else { + 0 + } val xPositions = IntArray(columnCount) - val yPositions = IntArray(rowCount) for (i in 0 until columnCount) { xPositions[i] = currentX currentX += cellWidthConstraintList[i] + horizontalSpacingPx } + + var currentY = 0 + val yPositions = IntArray(rowCount) for (i in 0 until rowCount) { yPositions[i] = currentY currentY += cellHeightConstraintList[i] + verticalSpacingPx diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumns.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumns.png index 9017eeeeb899cc3451ad0d15490920e187e13fe1..5cba6f1aced6ea7313064e3357b4807a21a44f0a 100644 GIT binary patch literal 4549 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygJ6%Ri(^Q|t+&?=y_f?< z+AeNiqLb96qsaI={J5631jjZp#n!b;xP8*?Q>{7^1W&)*)b?7(u|%)u$%kUIg38C@ z-kO3>R+M&p{>gKoNA#eO6N91)2V;wXB8z}ii+}@%AcX>oUrsQz1aL44I4QC?aI^|A zD2g}@lz^g$4z;}1BJiNTrC{eCR?AnPqqoHCde$5`prTmPVpF;zP$&1EghGpxMhgQF zJ8@9XY=3-iCWmx}EDe>Gju><~;(3?i~FQuV~q} zuqv5D5omuC5OOIF73MUcYn57nu2lpk3CfvDEq$Qy!e$=VLi09y1kJtfh1WjjdntCB zvr#EEK+==b3l8+ufRr$(!~`Z^Q0~-dX;KAc8bxq+QKAtO7$ejUA_43{BwX=+*AE*R zk4L?XP8+00{uC2G#K#z#2>mSmSp9>oZ^pK#_n(i<~4iy>;MkM0xfklm6ck zI(8mPEeBM(macs%ov-uxtraK;so7BB1eJst-~we9Fk%#d?FdkDNNr(YfeSJm6xu+$ zIB3b#Xz2qbEo!t-8e(vV!=X8I{P+uZ>UeB=6{d1?PfpEYCyx5-{rguX|0(t5%jZ#K z0XCckfDp(S5=vn%V)*`?_ z9#SmfAX6uK_7Sg3v4mxix(w)t!R|qqlBWOw literal 4569 zcmdUzT}YEr7{|}vhMbLzGaY0fn8(x>mb5Zgp)pUZZJ4@QWKg0JNc4G8L4?R!?{Zye zV;8#+!WMm82vadjZ%R`{v1n=`mQq6Df}{wgB+{O>Q<(^(qOAJN;UoSut^I(Fq3s;REKV5gk zJ#_ZG`)FGJ?siP~7cGCH?C$;cs*;L4xA4<|SQ_#$e617ufKO-`q?25h!yp)NHjITx zW=ablj$4S-d@mkvS}}bk1@8xa=QTJu@+n=!%mV`H+ZFMas)bbM8ev^*it35gG8VT}25fZr%zv0CHF&}B3f2jV%Z&2k@$79Zz0njT!GxxtMW z%NMFY-0tUNdbT+H1zUhnEy(rw!o zBM}_UfG()Wf=u=n`_IzYx+XWT$Xvl?j(qd`vB;(zg2ae4I*ui&#($OWUk|eYm4sTG aYtO|zd;g`dV&_%(%LbYE<{5mf#QqDFnz*k3 diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumnsWithFillFalse.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testAdaptiveRowsAndFixedSizeColumnsWithFillFalse.png index dbf0b16893e8baac453b836fc04878d60706fe63..b8cdd70ae9fc67e3577543fc2a781e6455aec947 100644 GIT binary patch literal 4206 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygMg{0i(^Q|t+!V{? z!HEMCH3)DiGE~bPia&TF!|s1#0>dxo7n}?niX@@^v1{~`HqBg8Qd*mu?7(qz?Y^~( zRrVe|d+1n$fKm&CQ-=T(hoTdQLJNl?nt+oAP+Fq}BsWx;4FXk7z(50fW}yHR&}*bK zdl?m7I2cEe!%qK-Y0Nai9v2<6OMHnKGxP}tb=>;b+0zsJ*lw!zWf)cPIi-40= zjlFeuZs^i4sXMnADzq>R2m&U`fw7nv-;!9il2i~=q!^e6DAG?;k2$>%q?6l31D9vc^LxC&(&Oci!y9{B1roM@tdUWD*{kPnCg#KduHC?;L5qL`2e8eAEC6gf z0V_XX!>L7pET-ZY4q(#@*a!nQ#9D#I4+&J>c%Iycx4s|T6*IKS&>>I-sxXy+^$!=YnMe(0t)SC_ z<3&G>EDFeE0!z1{*KW8K z0nCKJZ2sayo>6C+fyc|s7bgPC0#ci?Q1!rkO{Pw=VwVKF6u+>LpqkdMK{J1FJC2N& nHa)aBaM&^;_W>GgKMI!xcRyS8B{UW|j=gTe~DWM4f?%`%$ literal 4223 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygMgc-i(^Q|t+!V9XAd9mZ2bQJ;QA>-69YqYlXk{19SC#fU=(mtWO3kV6<|;labjo*7%~DE z4lr;iVnI$CEevl8IO^Gz7oU8xypiz*-$G>ug%*;~pTd1s{THjIT>5%;YcHc>%I;t5 z`X+rjoB!O5twlhQMZl>=z=1>1i9ykYgAr9g1Q?pY5CsM$5DyV%%LPGDyaPScDgg8v z>C9Xn4n-#pg_bQdYG)t)^4nzTvt=6%Nepse{Ctq%=g$w0T7Unxc#FU;*C|uXW}n)p z(4x@NAkZYhF`mlfZ>en4XLA&Ojhs7R;A}AmkoH_)UAkhgE&;W+6LJKHg0r3!F zax7E^Mj#W=GhDzFLk9Df1SFSdeti5!$1HT}rR%G;rJ0>L7zP402v{)EXk4MHU9!$bmza5mUNC(p|nksear1Nwuv43xfB* zboc!AMjKlxiBxO?ode_n!xmIq(U0l$0u+b9*aXHX7bt$|%Dfd0X$xhP+t~K~3Z4rJ zFjDKKxFauLdaenp){Kn_F>~W+e5*D&(PhdMvF^rRK_>?eM_?m`MUkaNpas}Y5kM6H zHd`EluoWmb%$SNLpcW;tr3q|Nf;^7IlvZwW2aNpIQ`)&gv> z5LQGBi-|FlP#VJ04Wo}1V39Xqb`$iW(+h#Y;%(T+kxPa9~ctgdg59NI=_if)kHg40u66 zlM=jemXn+y%%l4S@awdVumlMU+iFrL>y}N_%zuDbK|Vz}GmFHhz-$h}B}S7H!mX;} zqvW)WZDA)Mo{8_zq@HDLMFo2qcf&fWMYVGB~Bb8KirBSxx|+c}snqIvW_9+?w8sFozqljij|T9Jt% zu8u<2dUQe(I~&coyap@ij#dEt_<`Kb$ZbGF=!bb#_J7sn>ZeZwE4tLD6`2^~emJZQ ir14Ffv5kXt_;+f@tJ#CUJ}&IT?{-ic8Fd!<#o2#=U<1Ga literal 5140 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygYa!n7srr_TW_y9@-is$ zxE}0s=8h6LCMbL3MV7*BA->7;4G)-AN(;`s@}l;66n8^=YXYZYgMd;CgHwk96NjP` zhe8VnWdaKYtc(~GMVuH~0yr22oD^9cI9de;NWg)E)tiH{ML>~7z^O&RfkV)VLD7W* z0g$%_iPymHpvW^A0isxv!r-LQ!oaamfJvdniK9V)OL2e%fL2eVQhEfZX^^*oxQ}N5 z6C+B>5pcRFL}6k?j=um7SxMSQSAmFAf57th^Ab~wlYzDYlL;`XZ~==8N|_2Ra*n`K z0+>mGWd<-&(}pSH1kAg@1aP4RXp^FeA`8$qU!Z*=PQo-1ZoSaU2uyUKG8LNsC}TDV zRB?cPAP6i~frT2#Gt_4Wa6I**VW1!f_#Fuh*I_QtywYXQzQ$eEolCRDe2jSW>ls(@r5!&3ggdelr2L zOnkvLfH1X%&DB~!Nd{Eg1G}w*kGW8w3Nw&E)e@++Mx!u6HyhY!m?6LfY!h)P0vlMs zj{V?cVzz`E1Wru_Myx`M8n`LP3G7`sWdI%CATW#C!aEJYZGS;fs~=eW0Tb;YW42yU zhBRr>+s8Br3>*P1uxs!Kk~2mif%>B~OgI=}MZe57=Lds|eUpJ)$Br1_Xdi>8tDnm{ Hr-UW|8SNpn diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedRowsAndFixedSizeColumnsWithFillFalse.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedRowsAndFixedSizeColumnsWithFillFalse.png index fab3254c6d252aa60fcf21556da2f5bc0b46b357..8c5a3bad9569ae546e0bc67760e3b2a70b923a30 100644 GIT binary patch literal 4031 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzly1Am*Ri(^Q|t+!VXavo6- zaSfC%PM3VglI_W8HqmYq*GdJ}mY0wGMVl1ck7qtmzBeU^rTELgBc-tnIy#)w1eiD! zoj4R)I20QMlv)^^Iw%z2TIkNE(Bj0=Ai$-_;H1&Qz_Cz(X@CSc7A9~~$y=bH(ExgD zfP8}0T8v2hFjwH(FYad&kH4K@2;*O<%%IRRND;@NcAO#u2i?#^=`YLOH)Vc4#-J$T zq{t%R1f(cuI&jE3axCAeO^POpEI`|Qf%b_w3DZQl z^@21r(27<8pq)T}QO;B>;Q;$U5E$|;0yJUvDOV}uocUz2M&FU%2L0oAcPcVS8Gcc>M0Hav|R7wn# z0MKesS=9o}iGsl5$_1Di1t=5{aq8z8Xm7!SSHS6@5S6?I4;n0ymcYCA?ZnR~Rh&2u zEawEamN*6{Y7nqu8k{Zzx(etx7P>i3=jY5DTc$3qNOs}?HfxnyK#g3QGPxEy!`q#} zwlu5>N)|I5sJlU67SPEGEo#7~EXP7lVAI?wgEqnfRdfiXh1*|)IvPN40HcEo*wm+# zNso{LhdQt?0g4UW$!Cqy{F$D&?(H#DWMLo+0h@qKAAD=9B5ThVUQE ZI^mb3-I}@dj6bQ5ey){_8266|6Xa1?TeE!2?dF^Xa3d7>|3(5=%ErS$sEOcjZ;9wk_ zNWh7Ke&|sCh4*qtFFiX3$|#`33Cb@NGaWc=n*_KNfmwQ?0245S(}t?G+NYXBFwc=ni-hzTY>o*ninZ#Dt-|F`#`A$=ypXKF&7G)no7e! zK@RYphIm7!K;ZS(V}H)56ec$aFcFCqTI3iR6j=r*0w!}71}Ba|h#CZ{SQuIaC`D}C z4>##B9(X=QNM&Vd{eOEIRbX~gWB{gA22joh<~k1Q3QVJBTL9Fa-~u`m=u|F}nTtVX zA?=zF4jioBSgKHrI+a)f%8G5w7E+PVWyeX^%<$$sVDe`gglQk*Br4?q%JUFb6Yz#B z8HJr&(03_NE#4vkOtrvuyd^TOk8n3(f+!7}RJY z46Mb4oj_d!MHXOXE;tC8kaj*w+d{x;rx36>YPkSvcq^I!qt}7M7w888Ct+#}n}Zuq zzz!KOqLe`GC{!lTqFmi&$x5BTK%_}CwPjHE8x$Eh1|@QOA&5OTeuV136uTttH;wH# Qu*=Ti>FVdQ&MBb@00Lmnh5!Hn diff --git a/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedSizeRowsAndFixedSizeColumns.png b/grid/src/test/snapshots/images/com.cheonjaeung.compose.grid_BoxGridTest_testFixedSizeRowsAndFixedSizeColumns.png index ef8350868c8fdf73418d5007f4414448d6693736..5c3f5022ba7eb09d5bbc3673d00e6248073a1414 100644 GIT binary patch literal 4470 zcmdT{T}YEr7(UY>$E9%86`@uh`(dDjhMHib?YPi|t|eZGH)-}uSRrL43TnsFC^uJR zT2M>ENR(-y;YDVe5jr#qvQ}t%Gcj*O=~wMNnh@Rix6$YJj_=ufaem&P=Y761qandp z5vV{2`RWsODG14)BjoACUf@Z#P47a;Pp#K!Q_p`Gd)JuE_A6h0j+3jyB09tRHAxRo zC2NP#7VaBi-I}_-s>ou9w3^4yraLxh6AG{2`##>=^2~l=+IGWVTb}OdAIn7_ZJ}ul zhj2^_Nhn9Glz3peLWhc%`)F_pK~%{QH)0uKRQ{hFgthxKM0Hrk36&GZi3a;E;27M^ zZH_5L&fCkCX>ASqAy2Oce`Ye*Hb-B1V813~DlP&9542)fNb=+mC2=MyhZDL78gU6^ z0TvH{ol5#RfrLcCeny<^7Ppe^^uku6fSOWRp`extGh5&P4F9pIz!GcEF;wS|eQ$8uR0h z{EgZ5hmOC>iR~%qz_c=Mrm;LFai~l5w&*8#tQ=~vx)`bjSO}^G?&BT^ZL8vU zE5UT|AG--Mr%OVV)N-JHD7MPn3ABUJ;!JP~;zXiGCkVn+ipHFNh%kv7@7s(*xI}G9 z`TW&R47G32U~aTMX0LZs><%f&1ffpg2UBwKGGSpMA%<;*OpqGz4F>9=LNTC)9c^8v zEKAh6-q$1f79B3CQ{8Mn;&{^7`K&G#PM5zpsJv}g>+?>jEk1WIJfn<; zRLC|0UjVBD>O^%5;nD67rxsNXLd0(l>abdj-B2#x0~mGzRB@Mth@a^`JXJ>Zflc8j zCVkh?)1&v5mOEL_u2~5Sq8^gqR_F?KGpCQZ(I#GnAm}9^zug6ART(V)>6Rex3w=~oi zjeV9Kz+i02oONMtCYUJQw;*o82vG++z)PXPmVOU5oDp-RF;V!#@P zXzUyTb21+4?cHxZck@Wq%g*Y+&F$?18`ivkZ1TPL=v4O`g!%|tD!U?-N#Fzj{~_S1=LWC^P!A6F>81rlz79{5)n(*Ndw_l*fZVSG|0 zTzhVL7{c)Db$!$72R&geJ~7w`JBS3nZd@R+34Ses{xd=!Is(!U7#LedN`b$a&V&+a zUGIR@SdaD>`rkx-y-8()5)i=F^rfqL z*Tbj-8fayL4x>Qf)v~F5%u~MzQ}mY$h7}^rNtf6igZxEjTv$p#2JGUTi?EZ(Occ(! z?5gLOdrU-aimSOUEy;TR(v!jIqKG7!-N9OWq$)Ha3JeZFzRoL0ReMz;S zjLf0g?fuW$?*0F8dtZ>3i`(9NTF*XPGHlUu;%E@yQe<$_Xkp-3D8Qu9GIRvk*c><* zF_D0iB1=NQ^A0{Yx5XFbnVC1(w)8PH2r%JBpQ5(g=Rf{+z0~V_ceOOLlgI8?OS>k0 z@s(d@#?~UB$Rgm>BH+Lw=)|Dt!oi3tAOf@uXrTyDZpbiOE(o>+a4-Tr(<%V;8tKej z9u7q(4uzJSf}g*Q{Qk{baz#f97;GF2cv1fIpF90tzI?g5){!G|cgLhlSywmfb0~5s zDzqrHGzc^aFgbBJai9ux0Mn*I3n*baQHRN~P#KiOflvcz>)>Q�xkHI5}`EJX&Pw z_wwV%-M|3DlFpG*e)+{Bo4)C*yfQDE08{LQveyYNnwqvg%SV$hw)728z8f-T{Xcl( z#6H|51D-;II#LQP41*H^Gs+-!88Ey!7CH}7#|`RWdsEH9-t5TWFxxL(Y^jSMp8C@P zST%rZGzL)Z0IE=jiU2b+FnMgac=6(P3yT>`RazL{n1URSv-m8#dh~d=#owA)mu@aM zmgZJ;*!^#Xyz0x>_eyhhS{Q(p4iluR<4|l6P(l>|RvtiUU_An=!N_1by$}F4y?|94 zuzKSH8b2hMw;~`dpc@P1t`+`xY_RmP{&6!gCk6q0=!R=}`1{Atp2d27bLD7Uo3`1{ zWy+K{-PkI8q!z&7tejDr4Zz$EYCQv6EenCEgBr|R;)*OS0xbeJa%}zyO!k~QsTSDm z#2dH`=EiGY?|5AnJS$}124SZLUAMn=z}kOpaz-+qmMbVf18oWbwra^|0?P)V39Z1k zaqEy_UN{D7xpF8vc=Mb;A1rlkYb~&(Yat6MmT-`%lRW!~*QHp(GDuwp^uyqG91DZu mU_=favWyhEtl{ow{?$Kw`u@GIJ`NmMVDNPHb6Mw<&;$Vgq=2FT literal 4240 zcmeAS@N?(olHy`uVBq!ia0y~yU_8XY!2E)P4JhKf;hzlygFv{ai(^Q|t+!V z1sv-9`saD){O8^u{?!HEMC zH3)DiGFZzT+MbXSa(zE9&w*zGR!o@6kVH=W-}S#xe!G2saMcX^8xjIe*H*`^*6_Ul zqcA7gfdd#qiY^?CEdq)x0!}RgXab<{0%DNdP+>Z7$T|X}8t55d!~?xXGV{W*1_7lO z2B#BT)A#Ew{=Iy5ka2zv4~HTHUQ{z@`t&-l^XJ3Au`0HlRr2yW{j{;xk;4(_1{Ot@ z7J(L^iv*k;PzA_!A}*gfa>z0Q;|XLF$kxHh{M{tbB*5gvk*y=Pc*?wa`)-Q22r%G7 z1=6~1i!0Wyn)1vy8JJ=t-|I>QdU^Ff-q;I@UtCESl$Kk80R;@>)}h2yECIzEC?A57 z4H-;nW~UATCJsgIGqaz?8yIcUS7>1vD1$_GwoQx z9@@R=zJ2%Jy_sHf&-Ds0HQ+`HEqx3*ix=y=7ykHap!%Cj@qpXfOl_}A>G4=w07y*& zU|9sJ#Xw~)9ho9d?w~f@0F~hv_JM+$L-9b?)lkvj_rC{kT8}$u!J&RgOp4F{@w<1y zUgF}h(#kCds!H#6cTBpJa%r2P69L^^|kx?QcscvM}I9KP=4W`uW^?JLQdb3xl+8^xBS~ zAW+nBC_>^3(u4!og9rgoMgfNSLSXZbo=mQV%4m5ODf`l#nE}n$30pT$p1h*JpKuDs zS9%aASnx;>tkgg?fC$>l0ZbeO6%CXEj)l&H)Nw=w+k`{${i}O=PtFv&3mj=+@O1Ta JS?83{1OPfMK$HLg From 7e189d808075cc92d4cc05b8d4b7b14b637f8150 Mon Sep 17 00:00:00 2001 From: Cheon Jaeung Date: Wed, 15 Oct 2025 20:58:05 +0900 Subject: [PATCH 5/5] Fix divide by zero bug in FixedSize --- .../kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt b/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt index df55531..7a9b532 100644 --- a/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt +++ b/grid/src/commonMain/kotlin/com/cheonjaeung/compose/grid/SimpleGridCells.kt @@ -168,7 +168,11 @@ interface SimpleGridCells { val cellSizeWithSpacing = cellSize + spacing return if (cellSizeWithSpacing < availableSizeWithSpacing) { - val count = availableSizeWithSpacing / cellSizeWithSpacing + val count = if (cellSizeWithSpacing != 0) { + availableSizeWithSpacing / cellSizeWithSpacing + } else { + 1 + } return List(count) { cellSize } } else { List(1) { availableSize }