2020-05-30 18:42:14 +03:00

117 lines
2.4 KiB
Scala

package ocelot.desktop.ui.widget
import ocelot.desktop.geometry.{Rect2D, Size2D, Vector2D}
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.ui.EventHandlers
import ocelot.desktop.ui.event.Event
import ocelot.desktop.ui.layout.{Layout, LinearLayout}
class Widget {
val eventHandlers = new EventHandlers
protected var _children: Array[Widget] = Array[Widget]()
protected var parent: Option[Widget] = None
protected val layout: Layout = new LinearLayout(this)
private var shouldRelayoutParent = false
def relayoutParent(): Unit = {
shouldRelayoutParent = true
}
def minimumSize: Size2D = layout.minimumSize
def maximumSize: Size2D = layout.maximumSize
protected var _position: Vector2D = Vector2D(0, 0)
def position: Vector2D = _position
def position_=(value: Vector2D): Unit = {
if (value == _position) return
_position = value
relayout()
}
protected var _size: Size2D = Size2D(0, 0)
def size: Size2D = _size
def size_=(value: Size2D): Unit = {
val clamped = value.clamped(minimumSize, maximumSize)
if (clamped != _size) {
recalculateBounds()
_size = clamped.copy()
relayout()
shouldRelayoutParent = true
}
}
def width: Float = size.width
def height: Float = size.height
def width_=(value: Float): Unit = {
size = size.copy(width = value)
}
def height_=(value: Float): Unit = {
size = size.copy(height = value)
}
def bounds: Rect2D = Rect2D(position, size)
def children: Array[Widget] = _children
def children_=(value: Array[Widget]): Unit = {
_children = value
for (child <- _children)
child.parent = Some(this)
recalculateBounds()
size = _size
relayout()
}
def recalculateBounds(): Unit = layout.recalculateBounds()
def relayout(): Unit = layout.relayout()
def draw(g: Graphics): Unit = {
drawChildren(g)
}
protected def drawChildren(g: Graphics): Unit = {
for (child <- children) {
g.save()
child.draw(g)
g.restore()
}
}
def update(): Unit = {
if (shouldRelayoutParent) {
parent.foreach(_.recalculateBounds())
parent.foreach(_.relayout())
shouldRelayoutParent = false
}
updateChildren()
}
protected def updateChildren(): Unit = {
for (child <- children)
child.update()
}
def handleEvent(event: Event): Unit = {
eventHandlers(event)
for (child <- children)
child.handleEvent(event)
}
}