From 40f6dff470352c163ac9fe9e6ef89d7c4ad06191 Mon Sep 17 00:00:00 2001 From: HiFlii Date: Sun, 9 Feb 2025 15:49:14 -0500 Subject: [PATCH 1/2] fix: Grid size now rounds correctly Previously the grid would give an extra line if the placeables was evenly divisible by itemsPerLine. --- src/main/kotlin/com/mineinabyss/guiy/components/Grid.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/mineinabyss/guiy/components/Grid.kt b/src/main/kotlin/com/mineinabyss/guiy/components/Grid.kt index 3e74b2b..fd15199 100644 --- a/src/main/kotlin/com/mineinabyss/guiy/components/Grid.kt +++ b/src/main/kotlin/com/mineinabyss/guiy/components/Grid.kt @@ -5,6 +5,7 @@ import com.mineinabyss.guiy.layout.Layout import com.mineinabyss.guiy.layout.MeasurePolicy import com.mineinabyss.guiy.layout.MeasureResult import com.mineinabyss.guiy.modifiers.Modifier +import kotlin.math.ceil /** * A grid layout component that finds the largest child size, and then places children in a grid based on this size. @@ -47,22 +48,19 @@ fun gridMeasurePolicy(vertical: Boolean) = MeasurePolicy { measurables, constrai constraints.minWidth, constraints.minHeight ) {} - // Get width and height divisible by cellWidth, cellHeight val itemsPerLine = if (vertical) constraints.maxWidth / cellWidth else constraints.maxHeight / cellHeight - val (width, height) = if (vertical) { val w = itemsPerLine * cellWidth - val h = ((placeables.size / itemsPerLine) + 1) * cellHeight + val h = (ceil(placeables.size / itemsPerLine.toFloat()).toInt()) * cellHeight w to h } else { - val w = ((placeables.size / itemsPerLine) + 1) * cellWidth + val w = (ceil(placeables.size / itemsPerLine.toFloat()).toInt()) * cellWidth val h = itemsPerLine * cellHeight w to h } - MeasureResult(width, height) { var placeAtX = 0 var placeAtY = 0 From 72d1592c712eb8a5d9c6d2919f377e7479c25dc4 Mon Sep 17 00:00:00 2001 From: HiFlii Date: Sun, 9 Feb 2025 15:51:27 -0500 Subject: [PATCH 2/2] fix: Guild Member Lists & Guild Search lists are now clickable Previously, the guild member list menus had the rightmost and bottommost column/row (respectively) not be clickable. This occured because the contents (usually a Grid) was offset and the Box containing them was not. This has been resolved through and admitedly hacky solution where: 1) A box is rendered as before and used to fetch the size of the contents (Grid) 2) A box is rendered whose components are blank cells to clear out step (1) 3) The final box is rendered using fillMaxSize() to ensure that the contents fit inside it. This separates the size extraction and the content containing steps. This ensures that: - The 'itemsPerPage' or 'itemsPerLine' and 'totalLines' variables are of the size of the original contents instead of their enclosing Box. - The enclosing box for the contents is of sufficient size such that all the elements are clickable. Alternative solutions could include altering the spec for Scrollable and Paginated to take in an optional Size override. --- .../guiy/components/lists/Paginated.kt | 25 +++++++++++-- .../guiy/components/lists/Scrollable.kt | 36 ++++++++++++++----- .../com/mineinabyss/guiy/layout/Layout.kt | 2 +- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/com/mineinabyss/guiy/components/lists/Paginated.kt b/src/main/kotlin/com/mineinabyss/guiy/components/lists/Paginated.kt index ea19780..b34edaf 100644 --- a/src/main/kotlin/com/mineinabyss/guiy/components/lists/Paginated.kt +++ b/src/main/kotlin/com/mineinabyss/guiy/components/lists/Paginated.kt @@ -3,6 +3,7 @@ package com.mineinabyss.guiy.components.lists import androidx.compose.runtime.* import com.mineinabyss.guiy.components.Item import com.mineinabyss.guiy.components.Spacer +import com.mineinabyss.guiy.components.VerticalGrid import com.mineinabyss.guiy.jetpack.Alignment import com.mineinabyss.guiy.jetpack.Arrangement import com.mineinabyss.guiy.layout.Box @@ -35,7 +36,9 @@ fun Paginated( content: @Composable (page: List) -> Unit, ) { var size by remember { mutableStateOf(Size(0, 0)) } + var clearSize by remember { mutableStateOf(Size(0, 0)) } val itemsPerPage = size.width * size.height + Box(Modifier.fillMaxSize()) { val start = page * itemsPerPage val end = (page + 1) * itemsPerPage @@ -43,6 +46,23 @@ fun Paginated( if (start < 0) emptyList() else items.subList(start, end.coerceAtMost(items.size)) } + + // Extract original size of contents + Box(Modifier.onSizeChanged{ + size = it + }) { + content(pageItems) + } + + // Clear out the previous Box + Box(Modifier.onSizeChanged{ + clearSize = it + }.fillMaxSize()) { + VerticalGrid(){ + MutableList(clearSize.width * clearSize.height) {Item(null)} + } + } + NavbarLayout( position = navbarPosition, navbar = { @@ -54,9 +74,8 @@ fun Paginated( } }, content = { - Box(Modifier.onSizeChanged { - size = it - }) { + // Actually render the correct amount of items into a box that can fit them including offsets + Box(Modifier.fillMaxSize()) { content(pageItems) } } diff --git a/src/main/kotlin/com/mineinabyss/guiy/components/lists/Scrollable.kt b/src/main/kotlin/com/mineinabyss/guiy/components/lists/Scrollable.kt index 7ee0871..de517f6 100644 --- a/src/main/kotlin/com/mineinabyss/guiy/components/lists/Scrollable.kt +++ b/src/main/kotlin/com/mineinabyss/guiy/components/lists/Scrollable.kt @@ -1,12 +1,12 @@ package com.mineinabyss.guiy.components.lists import androidx.compose.runtime.* +import com.mineinabyss.guiy.components.Item import com.mineinabyss.guiy.components.Spacer +import com.mineinabyss.guiy.components.VerticalGrid import com.mineinabyss.guiy.layout.Box import com.mineinabyss.guiy.layout.Size -import com.mineinabyss.guiy.modifiers.Modifier -import com.mineinabyss.guiy.modifiers.fillMaxSize -import com.mineinabyss.guiy.modifiers.onSizeChanged +import com.mineinabyss.guiy.modifiers.* import com.mineinabyss.idofront.items.editItemMeta import org.bukkit.Material import org.bukkit.inventory.ItemStack @@ -36,15 +36,35 @@ fun Scrollable( content: @Composable (page: List) -> Unit, ) { var size by remember { mutableStateOf(Size(0, 0)) } + var clearSize by remember { mutableStateOf(Size(0, 0)) } + val itemsPerLine = if (scrollDirection == ScrollDirection.VERTICAL) size.width else size.height val totalLines = if (scrollDirection == ScrollDirection.VERTICAL) size.height else size.width - Box(Modifier.fillMaxSize()) { + + Box(Modifier.fillMaxSize().onSizeChanged {println("Exterior box size: $it")}) { val start = line * itemsPerLine val end = start + (itemsPerLine * totalLines) val pageItems = remember(items, start, end) { if (start < 0) emptyList() else items.subList(start, end.coerceAtMost(items.size)) } + + // Extract original size of contents + Box(Modifier.onSizeChanged{ + size = it + }) { + content(pageItems) + } + + // Clear out the previous Box + Box(Modifier.onSizeChanged{ + clearSize = it + }.fillMaxSize()) { + VerticalGrid(){ + MutableList(clearSize.width * clearSize.height) {Item(null)} + } + } + NavbarLayout( position = navbarPosition, navbar = { @@ -56,12 +76,12 @@ fun Scrollable( } }, content = { - Box(Modifier.onSizeChanged { - size = it - }) { + // Actually render the correct amount of items into a box that can fit them including offsets + Box(Modifier.fillMaxSize()) { content(pageItems) } } + ) } -} +} \ No newline at end of file diff --git a/src/main/kotlin/com/mineinabyss/guiy/layout/Layout.kt b/src/main/kotlin/com/mineinabyss/guiy/layout/Layout.kt index 04842a4..feb3215 100644 --- a/src/main/kotlin/com/mineinabyss/guiy/layout/Layout.kt +++ b/src/main/kotlin/com/mineinabyss/guiy/layout/Layout.kt @@ -24,7 +24,7 @@ inline fun Layout( set(measurePolicy) { this.measurePolicy = it } set(renderer) { this.renderer = it } //TODO dunno if this works - set(canvas) { this.canvas = it} + set(canvas) { this.canvas = it } set(modifier) { this.modifier = it } }, content = content,