More programmer UI work

This commit is contained in:
Shadowfacts 2019-08-09 22:39:01 -04:00
parent 37835b578d
commit 56bc870ac5
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
12 changed files with 101 additions and 25 deletions

View File

@ -1,9 +1,12 @@
package net.shadowfacts.asmr.program package net.shadowfacts.asmr.program
import net.minecraft.util.Identifier
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class ProgramBlockInput<Type: Any>( class ProgramBlockInput<Type: Any>(
val identifier: Identifier,
val type: ProgramType<Type>, val type: ProgramType<Type>,
val block: ProgramBlock, val block: ProgramBlock,
var source: ProgramBlockOutput<Type>? = null var source: ProgramBlockOutput<Type>? = null

View File

@ -1,9 +1,12 @@
package net.shadowfacts.asmr.program package net.shadowfacts.asmr.program
import net.minecraft.util.Identifier
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class ProgramBlockOutput<Type: Any>( class ProgramBlockOutput<Type: Any>(
val identifier: Identifier,
val type: ProgramType<Type>, val type: ProgramType<Type>,
val block: ProgramBlock val block: ProgramBlock
) { ) {

View File

@ -1,5 +1,7 @@
package net.shadowfacts.asmr.program.blocks package net.shadowfacts.asmr.program.blocks
import net.minecraft.util.Identifier
import net.shadowfacts.asmr.ASMR
import net.shadowfacts.asmr.program.ProgramBlock import net.shadowfacts.asmr.program.ProgramBlock
import net.shadowfacts.asmr.program.ProgramBlockInput import net.shadowfacts.asmr.program.ProgramBlockInput
import net.shadowfacts.asmr.program.ProgramBlockOutput import net.shadowfacts.asmr.program.ProgramBlockOutput
@ -13,7 +15,7 @@ class ConstantBlock<Type: Any>(
val value: Type val value: Type
): ProgramBlock() { ): ProgramBlock() {
val output = ProgramBlockOutput(type, this).apply { val output = ProgramBlockOutput(Identifier(ASMR.modid, "constant_output"), type, this).apply {
value = this@ConstantBlock.value value = this@ConstantBlock.value
} }

View File

@ -1,5 +1,7 @@
package net.shadowfacts.asmr.program.blocks package net.shadowfacts.asmr.program.blocks
import net.minecraft.util.Identifier
import net.shadowfacts.asmr.ASMR
import net.shadowfacts.asmr.program.ExecutableBlock import net.shadowfacts.asmr.program.ExecutableBlock
import net.shadowfacts.asmr.program.ProgramBlockInput import net.shadowfacts.asmr.program.ProgramBlockInput
import net.shadowfacts.asmr.program.ProgramBlockOutput import net.shadowfacts.asmr.program.ProgramBlockOutput
@ -13,7 +15,7 @@ class PrintBlock<Type: Any>(
val type: ProgramType<Type> val type: ProgramType<Type>
): ExecutableBlock() { ): ExecutableBlock() {
val input = ProgramBlockInput(type, this) val input = ProgramBlockInput(Identifier(ASMR.modid, "print_input"), type, this)
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(input) override val inputs: Array<ProgramBlockInput<*>> = arrayOf(input)
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf() override val outputs: Array<ProgramBlockOutput<*>> = arrayOf()

View File

@ -1,5 +1,7 @@
package net.shadowfacts.asmr.program.blocks.math package net.shadowfacts.asmr.program.blocks.math
import net.minecraft.util.Identifier
import net.shadowfacts.asmr.ASMR
import net.shadowfacts.asmr.program.ExecutableBlock import net.shadowfacts.asmr.program.ExecutableBlock
import net.shadowfacts.asmr.program.ProgramBlockInput import net.shadowfacts.asmr.program.ProgramBlockInput
import net.shadowfacts.asmr.program.ProgramBlockOutput import net.shadowfacts.asmr.program.ProgramBlockOutput
@ -20,10 +22,10 @@ class BinaryOperatorBlock<Type: Any>(
} }
} }
val left = ProgramBlockInput(type, this) val left = ProgramBlockInput(Identifier(ASMR.modid, "left_operand"), type, this)
val right = ProgramBlockInput(type, this) val right = ProgramBlockInput(Identifier(ASMR.modid, "right_operand"), type, this)
val output = ProgramBlockOutput(type, this) val output = ProgramBlockOutput(Identifier(ASMR.modid, "result"), type, this)
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(left, right) override val inputs: Array<ProgramBlockInput<*>> = arrayOf(left, right)
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf(output) override val outputs: Array<ProgramBlockOutput<*>> = arrayOf(output)

View File

@ -1,10 +1,17 @@
package net.shadowfacts.asmr.ui package net.shadowfacts.asmr.ui
import net.minecraft.util.Identifier
import net.shadowfacts.asmr.ASMR
import net.shadowfacts.asmr.program.ExecutableBlock
import net.shadowfacts.asmr.program.ProgramBlock import net.shadowfacts.asmr.program.ProgramBlock
import net.shadowfacts.cacao.geometry.Axis
import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.util.Color import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.util.MouseButton
import net.shadowfacts.cacao.util.texture.Texture
import net.shadowfacts.cacao.view.Label import net.shadowfacts.cacao.view.Label
import net.shadowfacts.cacao.view.StackView
import net.shadowfacts.cacao.view.TextureView
import net.shadowfacts.cacao.view.View import net.shadowfacts.cacao.view.View
import net.shadowfacts.kiwidsl.dsl import net.shadowfacts.kiwidsl.dsl
import no.birkett.kiwi.Constraint import no.birkett.kiwi.Constraint
@ -12,7 +19,15 @@ import no.birkett.kiwi.Constraint
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class ProgramBlockView(val block: ProgramBlock): View() { class ProgramBlockView(val block: ProgramBlock): StackView(Axis.VERTICAL, Distribution.CENTER, spacing = 4.0) {
companion object {
val executionFlowInactiveTexture = Texture(Identifier(ASMR.modid, "textures/gui/programmer/execution_flow.png"), u = 0, v = 0)
val executionFlowActiveTexture = Texture(Identifier(ASMR.modid, "textures/gui/programmer/execution_flow.png"), u = 7, v = 0)
}
var incomingExecution: View? = null
var outgoingExeuction: View? = null
var xConstraint: Constraint? = null var xConstraint: Constraint? = null
var yConstraint: Constraint? = null var yConstraint: Constraint? = null
@ -25,13 +40,45 @@ class ProgramBlockView(val block: ProgramBlock): View() {
backgroundColor = Color.BLACK backgroundColor = Color.BLACK
zIndex = 10.0 zIndex = 10.0
val title = addSubview(Label(block.javaClass.simpleName)) val titleStack = addArrangedSubview(StackView(Axis.HORIZONTAL, Distribution.CENTER))
val title = titleStack.addArrangedSubview(Label(block.javaClass.simpleName))
if (block is ExecutableBlock) {
val incomingTexture = executionFlowInactiveTexture
incomingExecution = titleStack.addArrangedSubview(TextureView(incomingTexture), index = 0)
val outgoingTexture = if (block.nextExecutableBlock == null) executionFlowInactiveTexture else executionFlowActiveTexture
outgoingExeuction = titleStack.addArrangedSubview(TextureView(outgoingTexture))
}
val pairs = block.inputs.zip(block.outputs)
val remainingInputs = if (block.inputs.size > block.outputs.size) block.inputs.drop(block.outputs.size) else listOf()
val remainingOutputs = if (block.outputs.size > block.inputs.size) block.outputs.drop(block.inputs.size) else listOf()
for ((input, output) in pairs) {
val hStack = addArrangedSubview(StackView(Axis.HORIZONTAL, spacing = 8.0))
hStack.addArrangedSubview(Label(input.identifier.toString()))
hStack.addArrangedSubview(Label(output.identifier.toString()))
}
for (input in remainingInputs) {
addArrangedSubview(Label(input.identifier.toString()))
}
for (output in remainingOutputs) {
addArrangedSubview(Label(output.identifier.toString(), textAlignment = Label.TextAlignment.RIGHT))
}
solver.dsl { solver.dsl {
widthAnchor equalTo (title.widthAnchor + 8) // we have to constrain the titleStack height, because it's distribution is set to CENTER, so it doesn't do it itself
heightAnchor equalTo (title.heightAnchor + 8) titleStack.heightAnchor equalTo title.heightAnchor
title.centerXAnchor equalTo centerXAnchor widthAnchor greaterThanOrEqualTo titleStack.widthAnchor
title.centerYAnchor equalTo centerYAnchor
if (block is ExecutableBlock) {
incomingExecution!!.widthAnchor equalTo incomingExecution!!.heightAnchor
incomingExecution!!.widthAnchor equalTo 7
outgoingExeuction!!.widthAnchor equalTo outgoingExeuction!!.heightAnchor
outgoingExeuction!!.widthAnchor equalTo 7
}
for (view in arrangedSubviews.drop(1)) {
widthAnchor.equalTo(view.widthAnchor, strength = STRONG)
}
} }
updateDraggingConstraints() updateDraggingConstraints()
@ -53,4 +100,8 @@ class ProgramBlockView(val block: ProgramBlock): View() {
window!!.layout() window!!.layout()
} }
override fun drawContent(mouse: Point, delta: Float) {
super.drawContent(mouse, delta)
}
} }

View File

@ -1,5 +1,6 @@
package net.shadowfacts.asmr.ui package net.shadowfacts.asmr.ui
import net.shadowfacts.asmr.program.ExecutableBlock
import net.shadowfacts.asmr.program.Program import net.shadowfacts.asmr.program.Program
import net.shadowfacts.asmr.program.ProgramBlock import net.shadowfacts.asmr.program.ProgramBlock
import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.geometry.Point
@ -28,17 +29,29 @@ class ProgramCanvasView(val program: Program): View() {
override fun drawContent(mouse: Point, delta: Float) { override fun drawContent(mouse: Point, delta: Float) {
super.drawContent(mouse, delta) super.drawContent(mouse, delta)
blocks.keys.forEach { block ->
block.inputs
.filter { it.source != null }
.forEach { input ->
val start = block.position
val source = input.source!!
val sourcePosition = source.block.position
val end = Point(sourcePosition.x + blocks[source.block]!!.bounds.width, sourcePosition.y)
RenderHelper.drawLine(start, end, zIndex, 5f, Color.WHITE) for ((block, view) in blocks) {
} (block as? ExecutableBlock)?.nextExecutableBlock?.let { next ->
blocks[next]?.let { nextView ->
val outgoing = view.outgoingExeuction!!
val incoming = nextView.incomingExecution!!
val start = outgoing.convert(outgoing.bounds.center, to = this)
val end = incoming.convert(outgoing.bounds.center, to = this)
RenderHelper.drawLine(start, end, zIndex, 5f, Color(0x00ff00))
}
}
// for (input in block.inputs) {
// if (input.source == null) continue
// val start = block.position
// val source = input.source!!
// val sourcePosition = source.block.position
// val end = Point(sourcePosition.x + blocks[source.block]!!.bounds.width, sourcePosition.y)
//
// RenderHelper.drawLine(start, end, zIndex, 5f, Color.WHITE)
// }
} }
} }

View File

@ -186,14 +186,13 @@ class Window(
return currentlyDraggedView.mouseDragged(startPoint, delta, mouseButton) return currentlyDraggedView.mouseDragged(startPoint, delta, mouseButton)
} else if (startPoint in viewController.view.frame) { } else if (startPoint in viewController.view.frame) {
val startInView = Point(startPoint.x - viewController.view.frame.left, startPoint.y - viewController.view.frame.top) val startInView = Point(startPoint.x - viewController.view.frame.left, startPoint.y - viewController.view.frame.top)
lateinit var prevView: View var prevView: View? = null
var view = viewController.view.subviewsAtPoint(startInView).maxBy(View::zIndex) var view = viewController.view.subviewsAtPoint(startInView).maxBy(View::zIndex)
while (view != null && !view.respondsToDragging) { while (view != null && !view.respondsToDragging) {
prevView = view prevView = view
val pointInView = viewController.view.convert(startInView, to = view) val pointInView = viewController.view.convert(startInView, to = view)
view = view.subviewsAtPoint(pointInView).maxBy(View::zIndex) view = view.subviewsAtPoint(pointInView).maxBy(View::zIndex)
} }
// this.currentlyDraggedView = viewController.view.subviewsAtPoint(startInView).maxBy(View::zIndex)
this.currentDragReceiver = view ?: prevView this.currentDragReceiver = view ?: prevView
return this.currentDragReceiver?.mouseDragged(startPoint, delta, mouseButton) ?: false return this.currentDragReceiver?.mouseDragged(startPoint, delta, mouseButton) ?: false
} }

View File

@ -26,6 +26,7 @@ data class Color(val red: Int, val green: Int, val blue: Int, val alpha: Int = 2
val CLEAR = Color(0, alpha = 0) val CLEAR = Color(0, alpha = 0)
val WHITE = Color(0xffffff) val WHITE = Color(0xffffff)
val BLACK = Color(0) val BLACK = Color(0)
val GREEN = Color(0x00ff00)
} }
} }

View File

@ -117,7 +117,7 @@ object RenderHelper {
} }
private fun BufferBuilder.color(color: Color): BufferBuilder { private fun BufferBuilder.color(color: Color): BufferBuilder {
color(color.alpha, color.red, color.green, color.blue) color(color.red, color.green, color.blue, color.alpha)
return this return this
} }

View File

@ -19,7 +19,7 @@ import java.util.*
* @param distribution The mode by which this stack lays out its children along the axis perpendicular to the * @param distribution The mode by which this stack lays out its children along the axis perpendicular to the
* primary [axis]. * primary [axis].
*/ */
class StackView( open class StackView(
val axis: Axis, val axis: Axis,
val distribution: Distribution = Distribution.FILL, val distribution: Distribution = Distribution.FILL,
val spacing: Double = 0.0 val spacing: Double = 0.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 889 B