2019-08-11 22:53:39 +00:00
|
|
|
package net.shadowfacts.asmr.ui.block
|
2019-08-09 18:36:12 +00:00
|
|
|
|
2019-08-10 02:39:01 +00:00
|
|
|
import net.minecraft.util.Identifier
|
|
|
|
import net.shadowfacts.asmr.ASMR
|
2019-08-12 00:05:09 +00:00
|
|
|
import net.shadowfacts.asmr.program.execution.ExecutableBlock
|
2019-08-09 18:36:12 +00:00
|
|
|
import net.shadowfacts.asmr.program.ProgramBlock
|
2019-08-10 04:03:25 +00:00
|
|
|
import net.shadowfacts.asmr.program.ProgramBlockInput
|
|
|
|
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
2019-08-12 00:05:09 +00:00
|
|
|
import net.shadowfacts.asmr.program.execution.OutgoingExecutionFlow
|
2019-08-10 02:39:01 +00:00
|
|
|
import net.shadowfacts.cacao.geometry.Axis
|
2019-08-09 18:36:12 +00:00
|
|
|
import net.shadowfacts.cacao.geometry.Point
|
|
|
|
import net.shadowfacts.cacao.util.Color
|
|
|
|
import net.shadowfacts.cacao.util.MouseButton
|
2019-08-10 02:39:01 +00:00
|
|
|
import net.shadowfacts.cacao.util.texture.Texture
|
2019-08-09 18:36:12 +00:00
|
|
|
import net.shadowfacts.cacao.view.Label
|
2019-08-10 02:39:01 +00:00
|
|
|
import net.shadowfacts.cacao.view.StackView
|
2019-08-09 18:36:12 +00:00
|
|
|
import net.shadowfacts.cacao.view.View
|
|
|
|
import net.shadowfacts.kiwidsl.dsl
|
|
|
|
import no.birkett.kiwi.Constraint
|
2019-08-10 04:03:25 +00:00
|
|
|
import kotlin.math.max
|
2019-08-09 18:36:12 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @author shadowfacts
|
|
|
|
*/
|
2019-08-10 02:39:01 +00:00
|
|
|
class ProgramBlockView(val block: ProgramBlock): StackView(Axis.VERTICAL, Distribution.CENTER, spacing = 4.0) {
|
|
|
|
|
|
|
|
companion object {
|
2019-08-10 04:03:25 +00:00
|
|
|
val emptyConnection = Texture(Identifier(ASMR.modid, "textures/gui/programmer/program_connections.png"), u = 0, v = 0)
|
|
|
|
val executionConnection = Texture(Identifier(ASMR.modid, "textures/gui/programmer/program_connections.png"), u = 7, v = 0)
|
|
|
|
val parameterConnection = Texture(Identifier(ASMR.modid, "textures/gui/programmer/program_connections.png"), u = 14, v = 0)
|
2019-08-10 02:39:01 +00:00
|
|
|
}
|
|
|
|
|
2019-08-12 00:05:09 +00:00
|
|
|
var incomingView: ProgramBlockExecutionView? = null
|
|
|
|
val outgoingViews = mutableMapOf<OutgoingExecutionFlow, ProgramBlockExecutionView>()
|
2019-08-09 18:36:12 +00:00
|
|
|
|
2019-08-11 22:44:22 +00:00
|
|
|
val inputViews = mutableMapOf<ProgramBlockInput<*>, ProgramBlockParamView>()
|
|
|
|
val outputViews = mutableMapOf<ProgramBlockOutput<*>, ProgramBlockParamView>()
|
2019-08-10 04:03:25 +00:00
|
|
|
|
2019-08-09 18:36:12 +00:00
|
|
|
var xConstraint: Constraint? = null
|
|
|
|
var yConstraint: Constraint? = null
|
2019-08-11 02:04:59 +00:00
|
|
|
var didCreateWidthConstraint = false
|
2019-08-09 18:36:12 +00:00
|
|
|
|
|
|
|
override fun wasAdded() {
|
|
|
|
super.wasAdded()
|
|
|
|
|
|
|
|
respondsToDragging = true
|
|
|
|
|
|
|
|
backgroundColor = Color.BLACK
|
2019-08-09 19:23:48 +00:00
|
|
|
zIndex = 10.0
|
2019-08-09 18:36:12 +00:00
|
|
|
|
2019-08-10 02:39:01 +00:00
|
|
|
val titleStack = addArrangedSubview(StackView(Axis.HORIZONTAL, Distribution.CENTER))
|
|
|
|
if (block is ExecutableBlock) {
|
2019-08-12 00:05:09 +00:00
|
|
|
incomingView = titleStack.addArrangedSubview(ProgramBlockExecutionView(block.incoming))
|
2019-08-10 02:39:01 +00:00
|
|
|
}
|
2019-08-12 00:05:09 +00:00
|
|
|
val title = titleStack.addArrangedSubview(Label(block.translateName(), wrappingMode = Label.WrappingMode.NO_WRAP))
|
2019-08-10 02:39:01 +00:00
|
|
|
|
2019-08-09 18:36:12 +00:00
|
|
|
solver.dsl {
|
2019-08-10 02:39:01 +00:00
|
|
|
// we have to constrain the titleStack height, because it's distribution is set to CENTER, so it doesn't do it itself
|
|
|
|
titleStack.heightAnchor equalTo title.heightAnchor
|
|
|
|
|
|
|
|
if (block is ExecutableBlock) {
|
2019-08-12 00:05:09 +00:00
|
|
|
incomingView!!.widthAnchor equalTo incomingView!!.heightAnchor
|
|
|
|
incomingView!!.widthAnchor equalTo 7
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (block is ExecutableBlock) {
|
|
|
|
for (outgoing in block.outgoing) {
|
|
|
|
val hStack = addArrangedSubview(StackView(Axis.HORIZONTAL, Distribution.CENTER))
|
2019-08-12 00:29:27 +00:00
|
|
|
val outgoingLabel = hStack.addArrangedSubview(Label(outgoing.translateName(), wrappingMode = Label.WrappingMode.NO_WRAP, textAlignment = Label.TextAlignment.RIGHT))
|
2019-08-12 00:05:09 +00:00
|
|
|
val outgoingView = hStack.addArrangedSubview(ProgramBlockExecutionView(outgoing))
|
|
|
|
outgoingViews[outgoing] = outgoingView
|
|
|
|
solver.dsl {
|
|
|
|
hStack.heightAnchor equalTo outgoingLabel.heightAnchor
|
|
|
|
|
|
|
|
outgoingView.widthAnchor equalTo outgoingView.heightAnchor
|
|
|
|
outgoingView.widthAnchor equalTo 7
|
|
|
|
}
|
2019-08-10 02:39:01 +00:00
|
|
|
}
|
2019-08-10 04:03:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i in 0 until max(block.inputs.size, block.outputs.size)) {
|
|
|
|
val hStack = addArrangedSubview(StackView(Axis.HORIZONTAL, Distribution.CENTER))
|
|
|
|
|
|
|
|
block.inputs.getOrNull(i)?.let { input ->
|
2019-08-11 22:44:22 +00:00
|
|
|
val inputView = hStack.addArrangedSubview(ProgramBlockParamView(input))
|
2019-08-10 04:03:25 +00:00
|
|
|
inputViews[input] = inputView
|
2019-08-12 00:29:27 +00:00
|
|
|
val inputLabel = hStack.addArrangedSubview(Label(input.translateName(), wrappingMode = Label.WrappingMode.NO_WRAP))
|
2019-08-10 04:03:25 +00:00
|
|
|
solver.dsl {
|
|
|
|
hStack.heightAnchor equalTo inputLabel.heightAnchor
|
|
|
|
|
|
|
|
inputView.widthAnchor equalTo inputView.heightAnchor
|
|
|
|
inputView.widthAnchor equalTo 7
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
val spacingView = hStack.addArrangedSubview(View())
|
|
|
|
solver.dsl {
|
|
|
|
spacingView.widthAnchor equalTo 8
|
|
|
|
}
|
|
|
|
|
|
|
|
block.outputs.getOrNull(i)?.let { output ->
|
2019-08-12 00:29:27 +00:00
|
|
|
val outputLabel = hStack.addArrangedSubview(Label(output.translateName(), wrappingMode = Label.WrappingMode.NO_WRAP, textAlignment = Label.TextAlignment.RIGHT))
|
2019-08-11 22:44:22 +00:00
|
|
|
val outputView = hStack.addArrangedSubview(ProgramBlockParamView(output))
|
2019-08-10 04:03:25 +00:00
|
|
|
outputViews[output] = outputView
|
|
|
|
solver.dsl {
|
|
|
|
hStack.heightAnchor equalTo outputLabel.heightAnchor
|
|
|
|
|
|
|
|
outputView.widthAnchor equalTo outputView.heightAnchor
|
|
|
|
outputView.widthAnchor equalTo 7
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
solver.dsl {
|
2019-08-10 02:39:01 +00:00
|
|
|
for (view in arrangedSubviews.drop(1)) {
|
|
|
|
widthAnchor.equalTo(view.widthAnchor, strength = STRONG)
|
|
|
|
}
|
2019-08-09 18:36:12 +00:00
|
|
|
}
|
|
|
|
|
2019-08-10 04:03:25 +00:00
|
|
|
|
2019-08-09 18:36:12 +00:00
|
|
|
updateDraggingConstraints()
|
|
|
|
}
|
|
|
|
|
2019-08-11 02:04:59 +00:00
|
|
|
override fun didLayout() {
|
|
|
|
super.didLayout()
|
|
|
|
|
|
|
|
// we want to constrain this view's width to be the same as the widest view in the vertical stack,
|
|
|
|
// but we don't know what view that is until after all subviews have been laid-out
|
|
|
|
if (!didCreateWidthConstraint) {
|
|
|
|
didCreateWidthConstraint = true
|
|
|
|
|
|
|
|
arrangedSubviews.maxBy { it.bounds.width }?.let { widestSubview ->
|
|
|
|
solver.dsl {
|
2019-08-12 00:29:27 +00:00
|
|
|
widthAnchor equalTo widestSubview.bounds.width
|
2019-08-11 02:04:59 +00:00
|
|
|
}
|
|
|
|
window!!.layout()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-09 18:36:12 +00:00
|
|
|
override fun mouseDragged(startPoint: Point, delta: Point, mouseButton: MouseButton): Boolean {
|
|
|
|
block.position += delta
|
|
|
|
updateDraggingConstraints()
|
2019-08-11 02:48:19 +00:00
|
|
|
window!!.layout()
|
2019-08-09 18:36:12 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-10 02:39:01 +00:00
|
|
|
override fun drawContent(mouse: Point, delta: Float) {
|
|
|
|
super.drawContent(mouse, delta)
|
|
|
|
}
|
|
|
|
|
2019-08-09 18:36:12 +00:00
|
|
|
}
|