104 lines
2.9 KiB
Kotlin
104 lines
2.9 KiB
Kotlin
package net.shadowfacts.shadowui
|
|
|
|
import com.mojang.blaze3d.platform.GlStateManager
|
|
import net.shadowfacts.kiwidsl.dsl
|
|
import net.shadowfacts.shadowui.geometry.Rect
|
|
import net.shadowfacts.shadowui.geometry.Size
|
|
import net.shadowfacts.shadowui.util.Color
|
|
import net.shadowfacts.shadowui.util.RenderHelper
|
|
import no.birkett.kiwi.Constraint
|
|
import no.birkett.kiwi.Solver
|
|
|
|
class View {
|
|
|
|
lateinit var solver: Solver
|
|
|
|
// in the coordinate system of the screen
|
|
val leftAnchor = LayoutVariable(this, "left")
|
|
val rightAnchor = LayoutVariable(this, "right")
|
|
val topAnchor = LayoutVariable(this, "top")
|
|
val bottomAnchor = LayoutVariable(this, "bottom")
|
|
val widthAnchor = LayoutVariable(this, "width")
|
|
val heightAnchor = LayoutVariable(this, "height")
|
|
val centerXAnchor = LayoutVariable(this, "centerX")
|
|
val centerYAnchor = LayoutVariable(this, "centerY")
|
|
|
|
// The rectangle for this view in the coordinate system of the parent view.
|
|
lateinit var frame: Rect
|
|
// The rectangle for this view in its own coordinate system.
|
|
lateinit var bounds: Rect
|
|
|
|
var intrinsicContentSize: Size? = null
|
|
set(value) {
|
|
updateIntrinsicContentSizeConstraints(intrinsicContentSize, value)
|
|
field = value
|
|
}
|
|
private var intrinsicContentSizeWidthConstraint: Constraint? = null
|
|
private var intrinsicContentSizeHeightConstraint: Constraint? = null
|
|
|
|
var backgroundColor = Color(0xff0000)
|
|
|
|
var parent: View? = null
|
|
val subviews = mutableListOf<View>()
|
|
|
|
fun addSubview(view: View): View {
|
|
subviews.add(view)
|
|
view.parent = this
|
|
view.solver = solver
|
|
|
|
view.wasAdded()
|
|
|
|
return view
|
|
}
|
|
|
|
fun wasAdded() {
|
|
createInternalConstraints()
|
|
}
|
|
|
|
fun createInternalConstraints() {
|
|
solver.dsl {
|
|
rightAnchor equalTo (leftAnchor + widthAnchor)
|
|
bottomAnchor equalTo (topAnchor + heightAnchor)
|
|
centerXAnchor equalTo (leftAnchor + widthAnchor / 2)
|
|
centerYAnchor equalTo (topAnchor + heightAnchor / 2)
|
|
}
|
|
}
|
|
|
|
private fun updateIntrinsicContentSizeConstraints(old: Size?, new: Size?) {
|
|
if (old != null) {
|
|
solver.removeConstraint(intrinsicContentSizeWidthConstraint!!)
|
|
solver.removeConstraint(intrinsicContentSizeHeightConstraint!!)
|
|
}
|
|
if (new != null) {
|
|
solver.dsl {
|
|
this@View.intrinsicContentSizeWidthConstraint = (widthAnchor.equalTo(new.width, strength = WEAK))
|
|
this@View.intrinsicContentSizeHeightConstraint = (heightAnchor.equalTo(new.height, strength = WEAK))
|
|
}
|
|
}
|
|
}
|
|
|
|
fun didLayout() {
|
|
subviews.forEach(View::didLayout)
|
|
|
|
val parentLeft = parent?.leftAnchor?.value ?: 0.0
|
|
val parentTop = parent?.topAnchor?.value ?: 0.0
|
|
frame = Rect(leftAnchor.value - parentLeft, topAnchor.value - parentTop, widthAnchor.value, heightAnchor.value)
|
|
bounds = Rect(0.0, 0.0, widthAnchor.value, heightAnchor.value)
|
|
}
|
|
|
|
fun draw() {
|
|
GlStateManager.pushMatrix()
|
|
GlStateManager.translated(frame.left, frame.top, 0.0)
|
|
|
|
RenderHelper.fill(bounds, backgroundColor)
|
|
|
|
drawContent()
|
|
|
|
subviews.forEach(View::draw)
|
|
|
|
GlStateManager.popMatrix()
|
|
}
|
|
|
|
fun drawContent() {}
|
|
|
|
} |