ASMR/src/main/kotlin/net/shadowfacts/asmr/ui/ProgramCanvasView.kt

81 lines
2.3 KiB
Kotlin

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
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() {
private lateinit var blocks: Map<ProgramBlock, ProgramBlockView>
// map of starting block to (start, end) points
private val executionFlowStartLinks = mutableMapOf<ExecutableBlock, Pair<Point, Point>>()
private val parameterLinks = mutableMapOf<ProgramBlock, Pair<Point, Point>>()
override fun wasAdded() {
super.wasAdded()
zIndex = 5.0
blocks = program.blocks.associateWith { ProgramBlockView(it) }
blocks.values.forEach {
addSubview(it)
}
}
private fun updateBlockLinks() {
for ((startBlock, startView) in blocks) {
(startBlock as? ExecutableBlock)?.executionFlow?.next?.let { endBlock ->
blocks[endBlock]?.let { endView ->
val outgoing = startView.outgoingExeuction!!
val incoming = endView.incomingExecution!!
val start = outgoing.convert(outgoing.bounds.center, to = this)
val end = incoming.convert(outgoing.bounds.center, to = this)
executionFlowStartLinks[startBlock] = start to end
}
}
for (output in startBlock.outputs) {
val outputView = startView.outputViews[output] ?: continue
val start = outputView.convert(outputView.bounds.center, to = this)
for (destination in output.destinations) {
val endView = blocks[destination.block] ?: continue
val inputView = endView.inputViews[destination] ?: continue
val end = inputView.convert(inputView.bounds.center, to = this)
parameterLinks[startBlock] = start to end
}
}
}
}
override fun didLayout() {
super.didLayout()
// we can't calculate the link points until layout is completed and all of the views have concrete positions/sizes
updateBlockLinks()
}
override fun drawContent(mouse: Point, delta: Float) {
super.drawContent(mouse, delta)
for ((start, end) in executionFlowStartLinks.values) {
RenderHelper.drawLine(start, end, zIndex, 5f, Color.GREEN)
}
for ((start, end) in parameterLinks.values) {
RenderHelper.drawLine(start, end, zIndex, 5f, Color.RED)
}
}
}