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>( class ProgramBlockInput<Type: Any>(
val type: ProgramType<Type>, val type: ProgramType<Type>,
val block: ProgramBlock,
var source: ProgramBlockOutput<Type>? = null var source: ProgramBlockOutput<Type>? = null
) { ) {

View File

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

View File

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

View File

@ -13,7 +13,7 @@ class PrintBlock<Type: Any>(
val type: ProgramType<Type> val type: ProgramType<Type>
): ExecutableBlock() { ): ExecutableBlock() {
val input = ProgramBlockInput(type, null) val input = ProgramBlockInput(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

@ -20,10 +20,10 @@ class BinaryOperatorBlock<Type: Any>(
} }
} }
val left = ProgramBlockInput(type) val left = ProgramBlockInput(type, this)
val right = ProgramBlockInput(type) val right = ProgramBlockInput(type, this)
val output = ProgramBlockOutput(type) val output = ProgramBlockOutput(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

@ -21,10 +21,11 @@ class ManagerViewController(val managerBlockEntity: ManagerBlockEntity): ViewCon
panel = view.addSubview(View()) panel = view.addSubview(View())
val background = panel.addSubview(NinePatchView(NinePatchTexture.PANEL_BG)) val background = panel.addSubview(NinePatchView(NinePatchTexture.PANEL_BG))
val label = panel.addSubview(Label("test label")) val label = panel.addSubview(Label("test label"))
val canvas = panel.addSubview(ProgramCanvasView(managerBlockEntity.program))
createConstraints { createConstraints {
panel.widthAnchor equalTo (view.widthAnchor - 40) panel.widthAnchor equalTo (view.widthAnchor - 20)
panel.heightAnchor equalTo (view.heightAnchor - 40) panel.heightAnchor equalTo (view.heightAnchor - 20)
panel.centerXAnchor equalTo view.centerXAnchor panel.centerXAnchor equalTo view.centerXAnchor
panel.centerYAnchor equalTo view.centerYAnchor panel.centerYAnchor equalTo view.centerYAnchor
@ -35,34 +36,12 @@ class ManagerViewController(val managerBlockEntity: ManagerBlockEntity): ViewCon
label.centerXAnchor equalTo view.centerXAnchor label.centerXAnchor equalTo view.centerXAnchor
label.centerYAnchor equalTo view.centerYAnchor 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 respondsToDragging = true
backgroundColor = Color.BLACK backgroundColor = Color.BLACK
zIndex = 5.0 zIndex = 10.0
val title = addSubview(Label(block.javaClass.simpleName)) 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) 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 com.mojang.blaze3d.platform.GlStateManager
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawableHelper import net.minecraft.client.gui.DrawableHelper
import net.minecraft.client.render.BufferBuilder
import net.minecraft.client.render.Tessellator import net.minecraft.client.render.Tessellator
import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormats import net.minecraft.client.render.VertexFormats
import net.minecraft.client.sound.PositionedSoundInstance import net.minecraft.client.sound.PositionedSoundInstance
import net.minecraft.sound.SoundEvent import net.minecraft.sound.SoundEvent
import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.geometry.Rect import net.shadowfacts.cacao.geometry.Rect
import net.shadowfacts.cacao.util.texture.Texture import net.shadowfacts.cacao.util.texture.Texture
import org.lwjgl.opengl.GL11 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) 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. * 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) GlStateManager.color4f(r, g, b, alpha)
} }
private fun BufferBuilder.color(color: Color): BufferBuilder {
color(color.alpha, color.red, color.green, color.blue)
return this
}
} }