Add View dragging and continue manager UI
This commit is contained in:
parent
946ebd7d9c
commit
089aaca1ea
|
@ -2,9 +2,14 @@ package net.shadowfacts.asmr
|
||||||
|
|
||||||
import net.shadowfacts.cacao.CacaoScreen
|
import net.shadowfacts.cacao.CacaoScreen
|
||||||
import net.shadowfacts.cacao.Window
|
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.*
|
||||||
import net.shadowfacts.cacao.view.button.Button
|
import net.shadowfacts.cacao.view.button.Button
|
||||||
import net.shadowfacts.cacao.viewcontroller.ViewController
|
import net.shadowfacts.cacao.viewcontroller.ViewController
|
||||||
|
import net.shadowfacts.kiwidsl.dsl
|
||||||
|
import no.birkett.kiwi.Constraint
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -18,25 +23,55 @@ class TestCacaoScreen: CacaoScreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun viewDidLoad() {
|
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 {
|
createConstraints {
|
||||||
container.centerXAnchor equalTo view.centerXAnchor
|
draggable.widthAnchor equalTo 50
|
||||||
container.centerYAnchor equalTo view.centerYAnchor
|
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))
|
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 {
|
// init {
|
||||||
// addWindow(Window().apply {
|
// addWindow(Window().apply {
|
||||||
// val stack = addView(StackView(Axis.VERTICAL, StackView.Distribution.CENTER, spacing = 4.0).apply {
|
// val stack = addView(StackView(Axis.VERTICAL, StackView.Distribution.CENTER, spacing = 4.0).apply {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import net.minecraft.world.World
|
||||||
import net.shadowfacts.asmr.ui.ManagerViewController
|
import net.shadowfacts.asmr.ui.ManagerViewController
|
||||||
import net.shadowfacts.cacao.CacaoScreen
|
import net.shadowfacts.cacao.CacaoScreen
|
||||||
import net.shadowfacts.cacao.Window
|
import net.shadowfacts.cacao.Window
|
||||||
|
import no.birkett.kiwi.UnsatisfiableConstraintException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -35,8 +36,13 @@ class ManagerBlock: Block(Settings.of(Material.METAL)), BlockEntityProvider {
|
||||||
private fun openManagerUI(managerBlockEntity: ManagerBlockEntity) {
|
private fun openManagerUI(managerBlockEntity: ManagerBlockEntity) {
|
||||||
val vc = ManagerViewController(managerBlockEntity)
|
val vc = ManagerViewController(managerBlockEntity)
|
||||||
val screen = CacaoScreen()
|
val screen = CacaoScreen()
|
||||||
|
try {
|
||||||
val window = screen.addWindow(Window(vc))
|
val window = screen.addWindow(Window(vc))
|
||||||
MinecraftClient.getInstance().openScreen(screen)
|
MinecraftClient.getInstance().openScreen(screen)
|
||||||
|
} catch (e: UnsatisfiableConstraintException) {
|
||||||
|
println("Couldn't open screen")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createBlockEntity(world: BlockView): BlockEntity {
|
override fun createBlockEntity(world: BlockView): BlockEntity {
|
||||||
|
|
|
@ -44,20 +44,25 @@ class ManagerViewController(val managerBlockEntity: ManagerBlockEntity): ViewCon
|
||||||
val program = managerBlockEntity.program
|
val program = managerBlockEntity.program
|
||||||
|
|
||||||
program.blocks.forEach {
|
program.blocks.forEach {
|
||||||
val blockView = panel.addSubview(View())
|
panel.addSubview(ProgramBlockView(it))
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -8,7 +8,6 @@ import net.shadowfacts.kiwidsl.dsl
|
||||||
import no.birkett.kiwi.Constraint
|
import no.birkett.kiwi.Constraint
|
||||||
import no.birkett.kiwi.Solver
|
import no.birkett.kiwi.Solver
|
||||||
import no.birkett.kiwi.Variable
|
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
|
* 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 widthConstraint: Constraint? = null
|
||||||
private var heightConstraint: Constraint? = null
|
private var heightConstraint: Constraint? = null
|
||||||
|
|
||||||
|
private var currentDragReceiver: View? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
createInternalConstraints()
|
createInternalConstraints()
|
||||||
|
|
||||||
|
@ -179,4 +180,33 @@ class Window(
|
||||||
return false
|
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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -13,4 +13,8 @@ data class Point(val x: Double, val y: Double) {
|
||||||
val ORIGIN = Point(0.0, 0.0)
|
val ORIGIN = Point(0.0, 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun plus(other: Point): Point {
|
||||||
|
return Point(x + other.x, y + other.y)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -114,6 +114,8 @@ open class View() {
|
||||||
*/
|
*/
|
||||||
var backgroundColor = Color.CLEAR
|
var backgroundColor = Color.CLEAR
|
||||||
|
|
||||||
|
var respondsToDragging = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This view's parent view. If `null`, this view is a top-level view in the [Window].
|
* 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
|
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.
|
* Converts the given point in this view's coordinate system to the coordinate system of another view or the window.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue