Programmer UI: Draw I/O connection lines

This commit is contained in:
Shadowfacts 2019-08-09 15:23:48 -04:00
parent 089aaca1ea
commit 5c66e961d2
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
10 changed files with 86 additions and 36 deletions

View File

@ -5,6 +5,7 @@ package net.shadowfacts.asmr.program
*/
class ProgramBlockInput<Type: Any>(
val type: ProgramType<Type>,
val block: ProgramBlock,
var source: ProgramBlockOutput<Type>? = null
) {

View File

@ -4,7 +4,8 @@ package net.shadowfacts.asmr.program
* @author shadowfacts
*/
class ProgramBlockOutput<Type: Any>(
val type: ProgramType<Type>
val type: ProgramType<Type>,
val block: ProgramBlock
) {
lateinit var value: Type

View File

@ -13,7 +13,7 @@ class ConstantBlock<Type: Any>(
val value: Type
): ProgramBlock() {
val output = ProgramBlockOutput(type).apply {
val output = ProgramBlockOutput(type, this).apply {
value = this@ConstantBlock.value
}

View File

@ -13,7 +13,7 @@ class PrintBlock<Type: Any>(
val type: ProgramType<Type>
): ExecutableBlock() {
val input = ProgramBlockInput(type, null)
val input = ProgramBlockInput(type, this)
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(input)
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf()

View File

@ -20,10 +20,10 @@ class BinaryOperatorBlock<Type: Any>(
}
}
val left = ProgramBlockInput(type)
val right = ProgramBlockInput(type)
val left = ProgramBlockInput(type, this)
val right = ProgramBlockInput(type, this)
val output = ProgramBlockOutput(type)
val output = ProgramBlockOutput(type, this)
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(left, right)
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf(output)

View File

@ -21,10 +21,11 @@ class ManagerViewController(val managerBlockEntity: ManagerBlockEntity): ViewCon
panel = view.addSubview(View())
val background = panel.addSubview(NinePatchView(NinePatchTexture.PANEL_BG))
val label = panel.addSubview(Label("test label"))
val canvas = panel.addSubview(ProgramCanvasView(managerBlockEntity.program))
createConstraints {
panel.widthAnchor equalTo (view.widthAnchor - 40)
panel.heightAnchor equalTo (view.heightAnchor - 40)
panel.widthAnchor equalTo (view.widthAnchor - 20)
panel.heightAnchor equalTo (view.heightAnchor - 20)
panel.centerXAnchor equalTo view.centerXAnchor
panel.centerYAnchor equalTo view.centerYAnchor
@ -35,34 +36,12 @@ class ManagerViewController(val managerBlockEntity: ManagerBlockEntity): ViewCon
label.centerXAnchor equalTo view.centerXAnchor
label.centerYAnchor equalTo view.centerYAnchor
canvas.widthAnchor equalTo (panel.widthAnchor - 8)
canvas.heightAnchor equalTo (panel.heightAnchor - 8)
canvas.centerXAnchor equalTo panel.centerXAnchor
canvas.centerYAnchor equalTo panel.centerYAnchor
}
createProgramView()
}
private fun createProgramView() {
val program = managerBlockEntity.program
program.blocks.forEach {
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

@ -23,7 +23,7 @@ class ProgramBlockView(val block: ProgramBlock): View() {
respondsToDragging = true
backgroundColor = Color.BLACK
zIndex = 5.0
zIndex = 10.0
val title = addSubview(Label(block.javaClass.simpleName))

View File

@ -0,0 +1,45 @@
package net.shadowfacts.asmr.ui
import net.shadowfacts.asmr.program.Program
import net.shadowfacts.asmr.program.ProgramBlock
import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.util.RenderHelper
import net.shadowfacts.cacao.view.View
/**
* @author shadowfacts
*/
class ProgramCanvasView(val program: Program): View() {
lateinit var blocks: Map<ProgramBlock, ProgramBlockView>
override fun wasAdded() {
super.wasAdded()
zIndex = 5.0
blocks = program.blocks.associateWith { ProgramBlockView(it) }
blocks.values.forEach {
addSubview(it)
}
}
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)
}
}
}
}

View File

@ -17,4 +17,8 @@ data class Point(val x: Double, val y: Double) {
return Point(x + other.x, y + other.y)
}
operator fun minus(other: Point): Point {
return Point(x - other.x, y - other.y)
}
}

View File

@ -3,10 +3,13 @@ package net.shadowfacts.cacao.util
import com.mojang.blaze3d.platform.GlStateManager
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawableHelper
import net.minecraft.client.render.BufferBuilder
import net.minecraft.client.render.Tessellator
import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormats
import net.minecraft.client.sound.PositionedSoundInstance
import net.minecraft.sound.SoundEvent
import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.geometry.Rect
import net.shadowfacts.cacao.util.texture.Texture
import org.lwjgl.opengl.GL11
@ -45,6 +48,18 @@ object RenderHelper {
draw(rect.left, rect.top, texture.u, texture.v, rect.width, rect.height, texture.width, texture.height)
}
fun drawLine(start: Point, end: Point, z: Double, width: Float, color: Color) {
if (disabled) return
GlStateManager.lineWidth(width)
val tessellator = Tessellator.getInstance()
val buffer = tessellator.bufferBuilder
buffer.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR)
buffer.vertex(start.x, start.y, z).color(color).next()
buffer.vertex(end.x, end.y, z).color(color).next()
tessellator.draw()
}
/**
* Draws the bound texture with the given screen and texture position and size.
*/
@ -101,4 +116,9 @@ object RenderHelper {
GlStateManager.color4f(r, g, b, alpha)
}
private fun BufferBuilder.color(color: Color): BufferBuilder {
color(color.alpha, color.red, color.green, color.blue)
return this
}
}