diff --git a/src/main/kotlin/net/shadowfacts/asmr/TestCacaoScreen.kt b/src/main/kotlin/net/shadowfacts/asmr/TestCacaoScreen.kt index 2f5a506..4b045dd 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/TestCacaoScreen.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/TestCacaoScreen.kt @@ -45,9 +45,9 @@ class TestCacaoScreen: CacaoScreen() { }) solver.dsl { - stack.topAnchor equalTo 50 - stack.leftAnchor equalTo 50 - stack.rightAnchor equalTo 150 + stack.topAnchor equalTo 0 + stack.centerXAnchor equalTo this@apply.centerXAnchor + stack.widthAnchor equalTo 100 purple.centerXAnchor equalTo blue.centerXAnchor purple.centerYAnchor equalTo blue.centerYAnchor // purple.widthAnchor equalTo 50 diff --git a/src/main/kotlin/net/shadowfacts/cacao/CacaoScreen.kt b/src/main/kotlin/net/shadowfacts/cacao/CacaoScreen.kt index 3e1fbae..288f718 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/CacaoScreen.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/CacaoScreen.kt @@ -1,11 +1,13 @@ package net.shadowfacts.cacao +import net.minecraft.client.MinecraftClient import net.minecraft.client.gui.screen.Screen import net.minecraft.network.chat.TextComponent import net.minecraft.sound.SoundEvents import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.util.RenderHelper +import net.shadowfacts.kiwidsl.dsl import java.util.* /** @@ -46,6 +48,14 @@ open class CacaoScreen: Screen(TextComponent("CacaoScreen")) { _windows.remove(window) } + override fun init() { + super.init() + + windows.forEach { + it.resize(width, height) + } + } + override fun render(mouseX: Int, mouseY: Int, delta: Float) { if (minecraft != null) { // workaround this.minecraft sometimes being null causing a crash diff --git a/src/main/kotlin/net/shadowfacts/cacao/Window.kt b/src/main/kotlin/net/shadowfacts/cacao/Window.kt index ad61b09..69ae2c9 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/Window.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/Window.kt @@ -3,7 +3,10 @@ package net.shadowfacts.cacao import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.view.View +import net.shadowfacts.kiwidsl.dsl +import no.birkett.kiwi.Constraint import no.birkett.kiwi.Solver +import no.birkett.kiwi.Variable import java.util.* /** @@ -22,8 +25,49 @@ class Window { */ lateinit var screen: CacaoScreen + /** + * The constraint solver used by this window and all its views and subviews. + */ var solver = Solver() + /** + * Layout anchor for the left edge of this view in the window's coordinate system. + */ + val leftAnchor = Variable("left") + /** + * Layout anchor for the right edge of this view in the window's coordinate system. + */ + val rightAnchor = Variable("right") + /** + * Layout anchor for the top edge of this view in the window's coordinate system. + */ + val topAnchor = Variable("top") + /** + * Layout anchor for the bottom edge of this view in the window's coordinate system. + */ + val bottomAnchor = Variable("bottom") + /** + * Layout anchor for the width of this view in the window's coordinate system. + */ + val widthAnchor = Variable("width") + /** + * Layout anchor for the height of this view in the window's coordinate system. + */ + val heightAnchor = Variable("height") + /** + * Layout anchor for the center X position of this view in the window's coordinate system. + */ + val centerXAnchor = Variable("centerX") + /** + * Layout anchor for the center Y position of this view in the window's coordinate system. + */ + val centerYAnchor = Variable("centerY") + + // internal constraints that specify the window size based on the MC screen size + // stored so that they can be removed when the screen is resized + private var widthConstraint: Constraint? = null + private var heightConstraint: Constraint? = null + // _views is the internal, mutable object, since we only want it to be mutated by the add/removeView methods private val _views = LinkedList() /** @@ -34,6 +78,40 @@ class Window { private var viewsSortedByZIndex: List = listOf() + init { + createInternalConstraints() + } + + /** + * Creates the internal constraints used by the window. + * If overridden, the super-class method must be called. + */ + protected open fun createInternalConstraints() { + solver.dsl { + leftAnchor equalTo 0 + topAnchor equalTo 0 + + rightAnchor equalTo (leftAnchor + widthAnchor) + bottomAnchor equalTo (topAnchor + heightAnchor) + centerXAnchor equalTo (leftAnchor + widthAnchor / 2) + centerYAnchor equalTo (topAnchor + heightAnchor / 2) + } + } + + /** + * Called by the window's [screen] when the Minecraft screen is resized. + * Used to update the window's width and height constraints and re-layout views. + */ + internal fun resize(width: Int, height: Int) { + if (widthConstraint != null) solver.removeConstraint(widthConstraint) + if (heightConstraint != null) solver.removeConstraint(heightConstraint) + solver.dsl { + widthConstraint = (widthAnchor equalTo width) + heightConstraint = (heightAnchor equalTo height) + } + layout() + } + /** * Convenience method that removes this window from its [screen]. */ diff --git a/src/main/kotlin/net/shadowfacts/cacao/view/View.kt b/src/main/kotlin/net/shadowfacts/cacao/view/View.kt index 806e9ba..d548dfb 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/view/View.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/view/View.kt @@ -207,7 +207,7 @@ open class View() { * Called during [wasAdded] to add any constraints to the [solver] that are internal to this view. * If overridden, the super-class method must be called. */ - open fun createInternalConstraints() { + protected open fun createInternalConstraints() { if (!usesConstraintBasedLayout) return solver.dsl {