Fix node selector animation

This commit is contained in:
LeshaInc 2020-05-30 18:42:14 +03:00
parent f9709d44e0
commit c7ac857aea
No known key found for this signature in database
GPG Key ID: B4855290FC36DE72
8 changed files with 58 additions and 36 deletions

View File

@ -10,4 +10,6 @@ case class Padding2D(top: Float = 0, right: Float = 0, bottom: Float = 0, left:
def vertical: Float = top + bottom def vertical: Float = top + bottom
def sizeAddition: Size2D = Size2D(horizontal, vertical) def sizeAddition: Size2D = Size2D(horizontal, vertical)
def offset: Vector2D = Vector2D(left, top)
} }

View File

@ -0,0 +1,19 @@
package ocelot.desktop.ui.layout
import ocelot.desktop.geometry.Padding2D
import ocelot.desktop.ui.widget.Widget
class PaddingLayout(widget: Widget, padding: Padding2D) extends Layout(widget) {
override def recalculateBounds(): Unit = {
val inner = widget.children(0)
minimumSize = inner.minimumSize + padding.sizeAddition
maximumSize = inner.maximumSize + padding.sizeAddition
widget.relayoutParent()
}
override def relayout(): Unit = {
val inner = widget.children(0)
inner.position = widget.position + padding.offset
inner.size = widget.size - padding.sizeAddition
}
}

View File

@ -10,11 +10,10 @@ class CenterBox(inner: Widget,
orientation: Orientation.Value = Orientation.Vertical, orientation: Orientation.Value = Orientation.Vertical,
background: Color = RGBAColorNorm(1f, 1f, 1f, 0f)) background: Color = RGBAColorNorm(1f, 1f, 1f, 0f))
extends Widget { extends Widget {
override protected val layout: Layout = new LinearLayout(this, orientation, alignItems = AlignItems.Center, justifyContent = JustifyContent.Center)
children +:= inner children +:= inner
override protected val layout: Layout = new LinearLayout(this, orientation, alignItems = AlignItems.Center, justifyContent = JustifyContent.Center)
override def maximumSize: Size2D = Size2D.Inf override def maximumSize: Size2D = Size2D.Inf
override def draw(g: Graphics): Unit = { override def draw(g: Graphics): Unit = {

View File

@ -1,16 +1,10 @@
package ocelot.desktop.ui.widget package ocelot.desktop.ui.widget
import ocelot.desktop.geometry.{Padding2D, Size2D, Vector2D} import ocelot.desktop.geometry.Padding2D
import ocelot.desktop.ui.layout.PaddingLayout
class PaddingBox(inner: Widget, padding: Padding2D) extends Widget { class PaddingBox(inner: Widget, padding: Padding2D) extends Widget {
override val layout = new PaddingLayout(this, padding)
children = Array(inner) children = Array(inner)
override def minimumSize: Size2D = inner.minimumSize + padding.sizeAddition
override def maximumSize: Size2D = inner.maximumSize + padding.sizeAddition
override def relayout(): Unit = {
size = inner.size + padding.sizeAddition
inner.position = position + Vector2D(padding.left, padding.top)
}
} }

View File

@ -56,7 +56,7 @@ class ScrollView(val inner: Widget) extends Widget with Logging {
override def size_=(value: Size2D): Unit = { override def size_=(value: Size2D): Unit = {
super.size_=(value) super.size_=(value)
inner.size = value // inner.size = value
clampOffsets() clampOffsets()
} }

View File

@ -49,6 +49,18 @@ class Widget {
} }
} }
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 bounds: Rect2D = Rect2D(position, size)
def children: Array[Widget] = _children def children: Array[Widget] = _children

View File

@ -1,17 +1,16 @@
package ocelot.desktop.ui.window package ocelot.desktop.ui.window
import ocelot.desktop.color.RGBAColor import ocelot.desktop.geometry.{Padding2D, Rect2D}
import ocelot.desktop.geometry.{Padding2D, Rect2D, Size2D}
import ocelot.desktop.graphics.Graphics import ocelot.desktop.graphics.Graphics
import ocelot.desktop.ui.UiHandler import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.event.{CloseWindowEvent, KeyEvent} import ocelot.desktop.ui.event.CloseWindowEvent
import ocelot.desktop.ui.layout.LinearLayout import ocelot.desktop.ui.layout.LinearLayout
import ocelot.desktop.ui.widget.{PaddingBox, ScrollView, Widget} import ocelot.desktop.ui.widget.{PaddingBox, ScrollView, Widget}
import ocelot.desktop.ui.workspace.{NodeRegistry, NodeTypeWidget, ScreenNode} import ocelot.desktop.ui.workspace.{NodeRegistry, NodeTypeWidget}
import ocelot.desktop.util.{DrawUtils, Orientation}
import ocelot.desktop.util.animation.UnitAnimation import ocelot.desktop.util.animation.UnitAnimation
import ocelot.desktop.util.{DrawUtils, Logging, Orientation}
class NodeSelector extends Window { class NodeSelector extends Window with Logging {
override val layout = new LinearLayout(this) override val layout = new LinearLayout(this)
override def dragRegions: Iterator[Rect2D] = Iterator() override def dragRegions: Iterator[Rect2D] = Iterator()
@ -20,11 +19,9 @@ class NodeSelector extends Window {
override val layout = new LinearLayout(this, Orientation.Vertical) override val layout = new LinearLayout(this, Orientation.Vertical)
} }
private val outer: Widget = new PaddingBox(rowsWidget, Padding2D.equal(4))
private val inner: Widget = new PaddingBox(rowsWidget, Padding2D.equal(4)) private val inner: Widget = new PaddingBox(rowsWidget, Padding2D.equal(4))
private val scrollView = new ScrollView(inner) private val scrollView = new ScrollView(inner)
private val outer: Widget = new PaddingBox(scrollView, Padding2D.equal(4))
outer.children +:= scrollView
children +:= outer children +:= outer
private def rows: Array[Widget] = rowsWidget.children private def rows: Array[Widget] = rowsWidget.children
@ -34,7 +31,7 @@ class NodeSelector extends Window {
private var numNodes: Int = 0 private var numNodes: Int = 0
private def add(widget: Widget): Unit = { private def addNodeWidget(widget: Widget): Unit = {
val row = if (rows.lastOption.exists(row => row.children.length < 4)) { val row = if (rows.lastOption.exists(row => row.children.length < 4)) {
rows.last rows.last
} else { } else {
@ -47,11 +44,10 @@ class NodeSelector extends Window {
numNodes += 1 numNodes += 1
} }
NodeRegistry.types.foreach(t => add(new NodeTypeWidget(t))) NodeRegistry.types.foreach(t => addNodeWidget(new NodeTypeWidget(t)))
private var _isShown: Boolean = false private var _isShown: Boolean = false
private var isClosing: Boolean = false private var isClosing: Boolean = false
private var width = 0f
private var finalHeight = 0f private var finalHeight = 0f
private var heightAnimation: UnitAnimation = _ private var heightAnimation: UnitAnimation = _
private var animationTime: Float = 0f private var animationTime: Float = 0f
@ -68,7 +64,8 @@ class NodeSelector extends Window {
animationTime += UiHandler.dt animationTime += UiHandler.dt
} }
size = Size2D(width, heightAnimation.value * finalHeight) width = inner.maximumSize.width + 8
height = heightAnimation.value * finalHeight
if (size.height < 10) { if (size.height < 10) {
_isOpen = false _isOpen = false
@ -122,7 +119,6 @@ class NodeSelector extends Window {
heightAnimation = UnitAnimation.easeOutQuad(0.2f) heightAnimation = UnitAnimation.easeOutQuad(0.2f)
heightAnimation.goUp() heightAnimation.goUp()
animationTime = 0f animationTime = 0f
width = inner.maximumSize.width
finalHeight = inner.minimumSize.height.min(250) finalHeight = inner.minimumSize.height.min(250)
} }

View File

@ -15,11 +15,11 @@ class ScreenWindow(screen: Screen) extends BasicWindow with Logging {
private val fontWidth = 8f private val fontWidth = 8f
private val fontHeight = 16f private val fontHeight = 16f
private def width: Int = screen.getWidth private def screenWidth: Int = screen.getWidth
private def height: Int = screen.getHeight private def screenHeight: Int = screen.getHeight
override def minimumSize: Size2D = Size2D(width * fontWidth + 32, height * fontHeight + 20) override def minimumSize: Size2D = Size2D(screenWidth * fontWidth + 32, screenHeight * fontHeight + 20)
override def maximumSize: Size2D = minimumSize override def maximumSize: Size2D = minimumSize
@ -72,7 +72,7 @@ class ScreenWindow(screen: Screen) extends BasicWindow with Logging {
screen.mouseScroll(lastMousePos.x, lastMousePos.y, event.offset, User("myself")) screen.mouseScroll(lastMousePos.x, lastMousePos.y, event.offset, User("myself"))
} }
private def checkBounds(p: Vector2D): Boolean = p.x >= 0 && p.y >= 0 && p.x < width && p.y < height private def checkBounds(p: Vector2D): Boolean = p.x >= 0 && p.y >= 0 && p.x < screenWidth && p.y < screenHeight
private def convertMousePos(p: Vector2D): Vector2D = { private def convertMousePos(p: Vector2D): Vector2D = {
Vector2D( Vector2D(
@ -97,20 +97,20 @@ class ScreenWindow(screen: Screen) extends BasicWindow with Logging {
} }
private def closeButtonBounds: Rect2D = Rect2D( private def closeButtonBounds: Rect2D = Rect2D(
position.x + fontWidth * width + 2, position.x + fontWidth * screenWidth + 2,
position.y - 2, 22, 22) position.y - 2, 22, 22)
override def draw(g: Graphics): Unit = { override def draw(g: Graphics): Unit = {
val sx = position.x + 16 val sx = position.x + 16
val sy = position.y + 20 val sy = position.y + 20
val w = fontWidth * width val w = fontWidth * screenWidth
val h = fontHeight * height val h = fontHeight * screenHeight
DrawUtils.shadow(g, sx - 22, sy - 22, w + 44, h + 52, shadowAlpha) DrawUtils.shadow(g, sx - 22, sy - 22, w + 44, h + 52, shadowAlpha)
DrawUtils.screenBorder(g, sx, sy, w, h, RGBAColorNorm(1, 1, 1, backgroundAlpha)) DrawUtils.screenBorder(g, sx, sy, w, h, RGBAColorNorm(1, 1, 1, backgroundAlpha))
for (y <- 0 until height) { for (y <- 0 until screenHeight) {
for (x <- 0 until width) { for (x <- 0 until screenWidth) {
val char = screen.data.buffer(y)(x) val char = screen.data.buffer(y)(x)
val color = screen.data.color(y)(x) val color = screen.data.color(y)(x)
val bg = PackedColor.unpackBackground(color, screen.data.format) val bg = PackedColor.unpackBackground(color, screen.data.format)