More programmer UI work
This commit is contained in:
parent
37835b578d
commit
56bc870ac5
|
@ -1,9 +1,12 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class ProgramBlockInput<Type: Any>(
|
||||
val identifier: Identifier,
|
||||
val type: ProgramType<Type>,
|
||||
val block: ProgramBlock,
|
||||
var source: ProgramBlockOutput<Type>? = null
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class ProgramBlockOutput<Type: Any>(
|
||||
val identifier: Identifier,
|
||||
val type: ProgramType<Type>,
|
||||
val block: ProgramBlock
|
||||
) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
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.ProgramBlockInput
|
||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||
|
@ -13,7 +15,7 @@ class ConstantBlock<Type: Any>(
|
|||
val value: Type
|
||||
): ProgramBlock() {
|
||||
|
||||
val output = ProgramBlockOutput(type, this).apply {
|
||||
val output = ProgramBlockOutput(Identifier(ASMR.modid, "constant_output"), type, this).apply {
|
||||
value = this@ConstantBlock.value
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
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.ProgramBlockInput
|
||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||
|
@ -13,7 +15,7 @@ class PrintBlock<Type: Any>(
|
|||
val type: ProgramType<Type>
|
||||
): 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 outputs: Array<ProgramBlockOutput<*>> = arrayOf()
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
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.ProgramBlockInput
|
||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||
|
@ -20,10 +22,10 @@ class BinaryOperatorBlock<Type: Any>(
|
|||
}
|
||||
}
|
||||
|
||||
val left = ProgramBlockInput(type, this)
|
||||
val right = ProgramBlockInput(type, this)
|
||||
val left = ProgramBlockInput(Identifier(ASMR.modid, "left_operand"), 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 outputs: Array<ProgramBlockOutput<*>> = arrayOf(output)
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
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.cacao.geometry.Axis
|
||||
import net.shadowfacts.cacao.geometry.Point
|
||||
import net.shadowfacts.cacao.util.Color
|
||||
import net.shadowfacts.cacao.util.MouseButton
|
||||
import net.shadowfacts.cacao.util.texture.Texture
|
||||
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.kiwidsl.dsl
|
||||
import no.birkett.kiwi.Constraint
|
||||
|
@ -12,7 +19,15 @@ import no.birkett.kiwi.Constraint
|
|||
/**
|
||||
* @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 yConstraint: Constraint? = null
|
||||
|
@ -25,13 +40,45 @@ class ProgramBlockView(val block: ProgramBlock): View() {
|
|||
backgroundColor = Color.BLACK
|
||||
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 {
|
||||
widthAnchor equalTo (title.widthAnchor + 8)
|
||||
heightAnchor equalTo (title.heightAnchor + 8)
|
||||
title.centerXAnchor equalTo centerXAnchor
|
||||
title.centerYAnchor equalTo centerYAnchor
|
||||
// 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
|
||||
widthAnchor greaterThanOrEqualTo titleStack.widthAnchor
|
||||
|
||||
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()
|
||||
|
@ -53,4 +100,8 @@ class ProgramBlockView(val block: ProgramBlock): View() {
|
|||
window!!.layout()
|
||||
}
|
||||
|
||||
override fun drawContent(mouse: Point, delta: Float) {
|
||||
super.drawContent(mouse, delta)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package net.shadowfacts.asmr.ui
|
||||
|
||||
import net.shadowfacts.asmr.program.ExecutableBlock
|
||||
import net.shadowfacts.asmr.program.Program
|
||||
import net.shadowfacts.asmr.program.ProgramBlock
|
||||
import net.shadowfacts.cacao.geometry.Point
|
||||
|
@ -28,17 +29,29 @@ class ProgramCanvasView(val program: Program): View() {
|
|||
override fun drawContent(mouse: Point, delta: Float) {
|
||||
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)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -186,14 +186,13 @@ class Window(
|
|||
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 prevView: View? = null
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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 WHITE = Color(0xffffff)
|
||||
val BLACK = Color(0)
|
||||
val GREEN = Color(0x00ff00)
|
||||
}
|
||||
|
||||
}
|
|
@ -117,7 +117,7 @@ object RenderHelper {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
* primary [axis].
|
||||
*/
|
||||
class StackView(
|
||||
open class StackView(
|
||||
val axis: Axis,
|
||||
val distribution: Distribution = Distribution.FILL,
|
||||
val spacing: Double = 0.0
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 889 B |
Loading…
Reference in New Issue