Add View dragging and continue manager UI

This commit is contained in:
Shadowfacts 2019-08-09 14:36:12 -04:00
parent 946ebd7d9c
commit 089aaca1ea
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
8 changed files with 189 additions and 28 deletions

View File

@ -2,9 +2,14 @@ package net.shadowfacts.asmr
import net.shadowfacts.cacao.CacaoScreen
import net.shadowfacts.cacao.Window
import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.util.MouseButton
import net.shadowfacts.cacao.view.*
import net.shadowfacts.cacao.view.button.Button
import net.shadowfacts.cacao.viewcontroller.ViewController
import net.shadowfacts.kiwidsl.dsl
import no.birkett.kiwi.Constraint
/**
* @author shadowfacts
@ -18,25 +23,55 @@ class TestCacaoScreen: CacaoScreen() {
}
override fun viewDidLoad() {
val container = view.addSubview(View())
// val test = view.addSubview(object: View() {
// override fun mouseDragged(startPoint: Point, delta: Point, mouseButton: MouseButton): Boolean {
//
// return true
// }
// })
val draggable = view.addSubview(DraggableView())
createConstraints {
container.centerXAnchor equalTo view.centerXAnchor
container.centerYAnchor equalTo view.centerYAnchor
draggable.widthAnchor equalTo 50
draggable.heightAnchor equalTo 25
}
embedChild(object: ViewController() {
override fun loadView() {
val button = Button(Label("test button"))
button.handler = {
println("button clicked")
}
this.view = button
}
}, container = container)
}
}
addWindow(Window(viewController))
}
class DraggableView: View() {
init {
backgroundColor = Color.WHITE
}
var xOffset: Double = 0.0
var yOffset: Double = 0.0
var xConstraint: Constraint? = null
var yConstraint: Constraint? = null
override fun wasAdded() {
super.wasAdded()
updateDraggingConstraints()
}
override fun mouseDragged(startPoint: Point, delta: Point, mouseButton: MouseButton): Boolean {
xOffset += delta.x
yOffset += delta.y
updateDraggingConstraints()
return true
}
private fun updateDraggingConstraints() {
if (xConstraint != null) solver.removeConstraint(xConstraint)
if (yConstraint != null) solver.removeConstraint(yConstraint)
solver.dsl {
xConstraint = (leftAnchor equalTo superview!!.leftAnchor + xOffset)
yConstraint = (topAnchor equalTo superview!!.topAnchor + yOffset)
}
window!!.layout()
}
}
// init {
// addWindow(Window().apply {
// val stack = addView(StackView(Axis.VERTICAL, StackView.Distribution.CENTER, spacing = 4.0).apply {

View File

@ -17,6 +17,7 @@ import net.minecraft.world.World
import net.shadowfacts.asmr.ui.ManagerViewController
import net.shadowfacts.cacao.CacaoScreen
import net.shadowfacts.cacao.Window
import no.birkett.kiwi.UnsatisfiableConstraintException
/**
* @author shadowfacts
@ -35,8 +36,13 @@ class ManagerBlock: Block(Settings.of(Material.METAL)), BlockEntityProvider {
private fun openManagerUI(managerBlockEntity: ManagerBlockEntity) {
val vc = ManagerViewController(managerBlockEntity)
val screen = CacaoScreen()
val window = screen.addWindow(Window(vc))
MinecraftClient.getInstance().openScreen(screen)
try {
val window = screen.addWindow(Window(vc))
MinecraftClient.getInstance().openScreen(screen)
} catch (e: UnsatisfiableConstraintException) {
println("Couldn't open screen")
e.printStackTrace()
}
}
override fun createBlockEntity(world: BlockView): BlockEntity {

View File

@ -44,20 +44,25 @@ class ManagerViewController(val managerBlockEntity: ManagerBlockEntity): ViewCon
val program = managerBlockEntity.program
program.blocks.forEach {
val blockView = panel.addSubview(View())
blockView.backgroundColor = Color.BLACK
val title = blockView.addSubview(Label(it.javaClass.simpleName))
createConstraints {
blockView.widthAnchor equalTo (title.widthAnchor + 8)
blockView.heightAnchor equalTo (title.heightAnchor + 8)
blockView.leftAnchor equalTo (panel.leftAnchor + 4 + it.position.x)
blockView.topAnchor equalTo (panel.topAnchor + 4 + it.position.y)
title.leftAnchor equalTo (blockView.leftAnchor + 4)
title.topAnchor equalTo (blockView.topAnchor + 4)
}
panel.addSubview(ProgramBlockView(it))
}
// program.blocks.forEach {
// val blockView = panel.addSubview(ProgramBlockView(it))
// val blockView = panel.addSubview(View())
// blockView.backgroundColor = Color.BLACK
// val title = blockView.addSubview(Label(it.javaClass.simpleName))
// createConstraints {
// blockView.widthAnchor equalTo (title.widthAnchor + 8)
// blockView.heightAnchor equalTo (title.heightAnchor + 8)
// blockView.leftAnchor equalTo (panel.leftAnchor + 4 + it.position.x)
// blockView.topAnchor equalTo (panel.topAnchor + 4 + it.position.y)
// title.leftAnchor equalTo (blockView.leftAnchor + 4)
// title.topAnchor equalTo (blockView.topAnchor + 4)
// }
// }
}
}

View File

@ -0,0 +1,56 @@
package net.shadowfacts.asmr.ui
import net.shadowfacts.asmr.program.ProgramBlock
import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.util.MouseButton
import net.shadowfacts.cacao.view.Label
import net.shadowfacts.cacao.view.View
import net.shadowfacts.kiwidsl.dsl
import no.birkett.kiwi.Constraint
/**
* @author shadowfacts
*/
class ProgramBlockView(val block: ProgramBlock): View() {
var xConstraint: Constraint? = null
var yConstraint: Constraint? = null
override fun wasAdded() {
super.wasAdded()
respondsToDragging = true
backgroundColor = Color.BLACK
zIndex = 5.0
val title = addSubview(Label(block.javaClass.simpleName))
solver.dsl {
widthAnchor equalTo (title.widthAnchor + 8)
heightAnchor equalTo (title.heightAnchor + 8)
title.centerXAnchor equalTo centerXAnchor
title.centerYAnchor equalTo centerYAnchor
}
updateDraggingConstraints()
}
override fun mouseDragged(startPoint: Point, delta: Point, mouseButton: MouseButton): Boolean {
block.position += delta
updateDraggingConstraints()
return true
}
private fun updateDraggingConstraints() {
if (xConstraint != null) solver.removeConstraint(xConstraint)
if (yConstraint != null) solver.removeConstraint(yConstraint)
solver.dsl {
xConstraint = (leftAnchor equalTo superview!!.leftAnchor + block.position.x)
yConstraint = (topAnchor equalTo superview!!.topAnchor + block.position.y)
}
window!!.layout()
}
}

View File

@ -80,4 +80,18 @@ open class CacaoScreen: Screen(LiteralText("CacaoScreen")) {
}
}
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
val window = windows.lastOrNull()
val startPoint = Point(mouseX, mouseY)
val delta = Point(deltaX, deltaY)
val result = window?.mouseDragged(startPoint, delta, MouseButton.fromMC(button))
return result == true
}
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
val window = windows.lastOrNull()
val result = window?.mouseReleased(Point(mouseX, mouseY), MouseButton.fromMC(button))
return result == true
}
}

View File

@ -8,7 +8,6 @@ import net.shadowfacts.kiwidsl.dsl
import no.birkett.kiwi.Constraint
import no.birkett.kiwi.Solver
import no.birkett.kiwi.Variable
import java.util.*
/**
* A Window is the object at the top of a Cacao view hierarchy. It occupies the entirety of the Minecraft screen size
@ -76,6 +75,8 @@ class Window(
private var widthConstraint: Constraint? = null
private var heightConstraint: Constraint? = null
private var currentDragReceiver: View? = null
init {
createInternalConstraints()
@ -179,4 +180,33 @@ class Window(
return false
}
fun mouseDragged(startPoint: Point, delta: Point, mouseButton: MouseButton): Boolean {
val currentlyDraggedView = this.currentDragReceiver
if (currentlyDraggedView != null) {
return currentlyDraggedView.mouseDragged(startPoint, delta, mouseButton)
} else if (startPoint in viewController.view.frame) {
val startInView = Point(startPoint.x - viewController.view.frame.left, startPoint.y - viewController.view.frame.top)
lateinit var prevView: View
var view = viewController.view.subviewsAtPoint(startInView).maxBy(View::zIndex)
while (view != null && !view.respondsToDragging) {
prevView = view
val pointInView = viewController.view.convert(startInView, to = view)
view = view.subviewsAtPoint(pointInView).maxBy(View::zIndex)
}
// this.currentlyDraggedView = viewController.view.subviewsAtPoint(startInView).maxBy(View::zIndex)
this.currentDragReceiver = view ?: prevView
return this.currentDragReceiver?.mouseDragged(startPoint, delta, mouseButton) ?: false
}
return false
}
fun mouseReleased(point: Point, mouseButton: MouseButton): Boolean {
val currentlyDraggedView = this.currentDragReceiver
if (currentlyDraggedView != null) {
this.currentDragReceiver = null
return true
}
return false
}
}

View File

@ -13,4 +13,8 @@ data class Point(val x: Double, val y: Double) {
val ORIGIN = Point(0.0, 0.0)
}
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}

View File

@ -114,6 +114,8 @@ open class View() {
*/
var backgroundColor = Color.CLEAR
var respondsToDragging = false
/**
* This view's parent view. If `null`, this view is a top-level view in the [Window].
*/
@ -333,6 +335,15 @@ open class View() {
return false
}
open fun mouseDragged(startPoint: Point, delta: Point, mouseButton: MouseButton): Boolean {
val view = subviewsAtPoint(startPoint).maxBy(View::zIndex)
if (view != null) {
val startInView = convert(startPoint, to = view)
return view.mouseDragged(startInView, delta, mouseButton)
}
return false
}
/**
* Converts the given point in this view's coordinate system to the coordinate system of another view or the window.
*