Improve sizeToContents()

This commit is contained in:
DBotThePony 2025-01-05 16:35:21 +07:00
parent 057c97fae9
commit a09795ad74
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 114 additions and 21 deletions

View File

@ -34,6 +34,7 @@ import java.util.concurrent.CopyOnWriteArrayList
import java.util.function.Predicate
import java.util.random.RandomGenerator
import kotlin.collections.ArrayList
import kotlin.math.max
import kotlin.math.roundToInt
data class ScreenPos(val x: Float, val y: Float)
@ -1385,24 +1386,66 @@ open class EditablePanel<out S : Screen>(
/**
* Attempts to tightly fit dimensions to all children
*
* Performs layout if required
*/
open fun sizeToContents(performLayout: Boolean = true) {
if (layoutInvalidated && performLayout) {
performLayout()
open fun sizeToContents() {
if (visibleChildrenInternal.isEmpty() || visibleChildrenInternal.any { it.dock == Dock.FILL }) {
// nothing to size against OR there is "fill" children
return
}
var width = 1f
var height = 1f
visibleChildrenInternal.forEach { it.sizeToContents() }
var accumulatedWidth = 0f
var accumulatedHeight = 0f
var height = 0f
var width = 0f
var previousDock = 0
for (child in visibleChildrenInternal) {
width = width.coerceAtLeast(child.x + child.width)
height = height.coerceAtLeast(child.y + child.height)
when (child.dock) {
Dock.NONE, Dock.FILL -> {} // do nothing
Dock.LEFT, Dock.RIGHT -> {
if (previousDock != 1) {
previousDock = 1
width += accumulatedWidth
height = max(height, accumulatedHeight)
accumulatedWidth = 0f
accumulatedHeight = 0f
}
accumulatedWidth += child.dockLeft + child.dockRight + child.width
accumulatedHeight = max(accumulatedHeight, child.dockTop + child.dockBottom + child.height)
}
Dock.TOP, Dock.BOTTOM -> {
if (previousDock != 2) {
previousDock = 2
height += accumulatedHeight
width = max(width, accumulatedWidth)
accumulatedWidth = 0f
accumulatedHeight = 0f
}
accumulatedHeight += child.dockTop + child.dockBottom + child.height
accumulatedWidth = max(accumulatedWidth, child.dockLeft + child.dockRight + child.width)
}
}
}
this.width = width
this.height = height
if (previousDock == 1) {
height += accumulatedHeight
width = max(width, accumulatedWidth)
} else if (previousDock == 2) {
width += accumulatedWidth
height = max(height, accumulatedHeight)
}
this.width = width + dockPadding.left + dockPadding.right
this.height = height + dockPadding.top + dockPadding.bottom
performLayout()
}
protected open fun visibilityChanges(new: Boolean, old: Boolean) {

View File

@ -60,9 +60,7 @@ open class Label<out S : Screen>(
}
}
override fun sizeToContents(performLayout: Boolean) {
super.sizeToContents(performLayout)
override fun sizeToContents() {
val w = font.width(text)
val h = font.lineHeight + 2

View File

@ -12,6 +12,7 @@ import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets15
import ru.dbotthepony.mc.otm.client.render.Widgets8
import java.util.function.IntConsumer
import kotlin.math.max
import kotlin.math.min
/**
@ -140,14 +141,65 @@ abstract class ButtonPanel<out S : Screen>(
}
}
override fun sizeToContents(performLayout: Boolean) {
super.sizeToContents(performLayout)
override fun sizeToContents() {
when (iconSpaceReservation) {
SpaceReservation.DEFAULT -> {
val icon = icon
val label = label
val label = label
if (label == null && icon == null) {
// i have no idea what you want me to do
width = 18f
height = 18f
} else {
var width = 2f
var height = 2f
if (label != null) {
height = height.coerceAtLeast(HEIGHT).coerceAtLeast(font.lineHeight.toFloat() + 2f)
width = width.coerceAtLeast(HEIGHT).coerceAtLeast(font.width(label) + 4f)
if (icon != null) {
width = icon.width
height = icon.height
}
if (label != null) {
if (icon != null) {
width += 2f
height = max(height, font.lineHeight.toFloat() + 2f)
} else {
height = 18f
}
width += font.width(label) + 2f
}
this.width = width
this.height = height
}
}
SpaceReservation.ICON_AND_TEXT -> {
var height = icon?.height ?: 18f
var width = icon?.width ?: 18f
width += 2f
val label = label
if (label != null) {
height = max(height, font.lineHeight.toFloat() + 2f)
width += font.width(label) + 2f
}
this.width = width
this.height = height
}
SpaceReservation.ICON_ONLY -> {
val height = icon?.height ?: 18f
val width = icon?.width ?: 18f
val min = min(width, height)
this.height = min
this.width = min
}
}
}

View File

@ -13,7 +13,7 @@ class HorizontalStripPanel<out S : Screen>(
width: Float = 0f,
height: Float = 0f,
) : EditablePanel<S>(screen, parent, x, y, width, height) {
override fun sizeToContents(performLayout: Boolean) {
override fun sizeToContents() {
var w = 0f
var h = 0f