From 5c66e961d23bdf6af6ee5f4f11e8d42acb9604e8 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Fri, 9 Aug 2019 15:23:48 -0400 Subject: [PATCH] Programmer UI: Draw I/O connection lines --- .../asmr/program/ProgramBlockInput.kt | 1 + .../asmr/program/ProgramBlockOutput.kt | 3 +- .../asmr/program/blocks/ConstantBlock.kt | 2 +- .../asmr/program/blocks/PrintBlock.kt | 2 +- .../blocks/math/BinaryOperatorBlock.kt | 6 +-- .../asmr/ui/ManagerViewController.kt | 37 ++++----------- .../shadowfacts/asmr/ui/ProgramBlockView.kt | 2 +- .../shadowfacts/asmr/ui/ProgramCanvasView.kt | 45 +++++++++++++++++++ .../net/shadowfacts/cacao/geometry/Point.kt | 4 ++ .../shadowfacts/cacao/util/RenderHelper.kt | 20 +++++++++ 10 files changed, 86 insertions(+), 36 deletions(-) create mode 100644 src/main/kotlin/net/shadowfacts/asmr/ui/ProgramCanvasView.kt diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockInput.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockInput.kt index 06c417f..8058ba5 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockInput.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockInput.kt @@ -5,6 +5,7 @@ package net.shadowfacts.asmr.program */ class ProgramBlockInput( val type: ProgramType, + val block: ProgramBlock, var source: ProgramBlockOutput? = null ) { diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockOutput.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockOutput.kt index f7dc9da..0a4b3da 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockOutput.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockOutput.kt @@ -4,7 +4,8 @@ package net.shadowfacts.asmr.program * @author shadowfacts */ class ProgramBlockOutput( - val type: ProgramType + val type: ProgramType, + val block: ProgramBlock ) { lateinit var value: Type diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt index 83eee8b..0914baa 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt @@ -13,7 +13,7 @@ class ConstantBlock( val value: Type ): ProgramBlock() { - val output = ProgramBlockOutput(type).apply { + val output = ProgramBlockOutput(type, this).apply { value = this@ConstantBlock.value } diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt index 5baa272..25c2ef0 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt @@ -13,7 +13,7 @@ class PrintBlock( val type: ProgramType ): ExecutableBlock() { - val input = ProgramBlockInput(type, null) + val input = ProgramBlockInput(type, this) override val inputs: Array> = arrayOf(input) override val outputs: Array> = arrayOf() diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt index f12ccf9..554f215 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt @@ -20,10 +20,10 @@ class BinaryOperatorBlock( } } - 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> = arrayOf(left, right) override val outputs: Array> = arrayOf(output) diff --git a/src/main/kotlin/net/shadowfacts/asmr/ui/ManagerViewController.kt b/src/main/kotlin/net/shadowfacts/asmr/ui/ManagerViewController.kt index 242e684..a2b2878 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/ui/ManagerViewController.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/ui/ManagerViewController.kt @@ -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) -// } -// } } } \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/ui/ProgramBlockView.kt b/src/main/kotlin/net/shadowfacts/asmr/ui/ProgramBlockView.kt index 5ef9356..3df2ee0 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/ui/ProgramBlockView.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/ui/ProgramBlockView.kt @@ -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)) diff --git a/src/main/kotlin/net/shadowfacts/asmr/ui/ProgramCanvasView.kt b/src/main/kotlin/net/shadowfacts/asmr/ui/ProgramCanvasView.kt new file mode 100644 index 0000000..c3906b7 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/ui/ProgramCanvasView.kt @@ -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 + + 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) + } + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/cacao/geometry/Point.kt b/src/main/kotlin/net/shadowfacts/cacao/geometry/Point.kt index 4afa7a0..f556a6a 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/geometry/Point.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/geometry/Point.kt @@ -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) + } + } \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/cacao/util/RenderHelper.kt b/src/main/kotlin/net/shadowfacts/cacao/util/RenderHelper.kt index 8d7c807..35addcc 100644 --- a/src/main/kotlin/net/shadowfacts/cacao/util/RenderHelper.kt +++ b/src/main/kotlin/net/shadowfacts/cacao/util/RenderHelper.kt @@ -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 + } + } \ No newline at end of file