Add sequence editor control and DoubleListParameter

This commit is contained in:
Edwin Jakobs
2020-03-26 19:36:14 +01:00
parent 8d810226da
commit d88f258f9c
4 changed files with 114 additions and 28 deletions

View File

@@ -5,9 +5,17 @@ import org.openrndr.KeyModifier
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.Drawer
import org.openrndr.draw.LineCap
import org.openrndr.draw.isolated
import org.openrndr.events.Event
import org.openrndr.math.Vector2
import org.openrndr.math.map
import org.openrndr.panel.style.Color
import org.openrndr.panel.style.color
import org.openrndr.panel.style.effectiveColor
import org.openrndr.panel.tools.Tooltip
import org.openrndr.shape.Rectangle
import org.openrndr.text.Cursor
import org.openrndr.text.Writer
import kotlin.math.abs
import kotlin.math.round
import kotlin.math.roundToInt
@@ -15,13 +23,17 @@ import kotlin.math.roundToInt
class SequenceEditor : Element(ElementType("sequence-editor")) {
var value = mutableListOf(0.0)
var label = "sequence"
var precision = 2
var maximumSequenceLength = 16
var minimumSequenceLength = 1
var range: ClosedRange<Double> = -1.0..1.0
private var selectedIndex: Int? = null
private var tooltip: Tooltip? = null
private val footerHeight = 20.0
class ValueChangedEvent(val source: SequenceEditor,
val oldValue: List<Double>,
val newValue: List<Double>)
@@ -35,7 +47,7 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
init {
fun query(position: Vector2): Vector2 {
val x = (position.x - layout.screenX) / layout.screenWidth
val y = 1.0 - ((position.y - layout.screenY) / (layout.screenHeight * 0.5))
val y = 1.0 - ((position.y - layout.screenY) / ((layout.screenHeight - footerHeight) * 0.5))
return Vector2(x, y)
}
@@ -68,7 +80,7 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
if (value.size < maximumSequenceLength) {
val q = query(it.position)
val oldValue = value.map { it }
value.add(index.toInt(), q.y)
value.add(index.toInt(), q.y.map(-1.0, 1.0, range.start, range.endInclusive))
events.valueChanged.trigger(ValueChangedEvent(this, oldValue, value))
}
}
@@ -108,7 +120,7 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
val readIndex = index.roundToInt() - 1
if (readIndex >= 0 && readIndex < value.size) {
val value = String.format("%.0${precision}f", value[readIndex])
tooltip = Tooltip(this@SequenceEditor, it.position - Vector2(layout.screenX, layout.screenY), "index: ${index.roundToInt()}, $value")
tooltip = Tooltip(this@SequenceEditor, it.position - Vector2(layout.screenX, layout.screenY), "$value")
requestRedraw()
}
}
@@ -121,7 +133,7 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
val writeIndex = index - 1
if (writeIndex >= 0 && writeIndex < value.size) {
val oldValue = value.map { it }
value[writeIndex] = q.y.coerceIn(-1.0, 1.0)
value[writeIndex] = q.y.coerceIn(-1.0, 1.0).map(-1.0, 1.0, range.start, range.endInclusive)
events.valueChanged.trigger(ValueChangedEvent(this, oldValue, value))
}
requestRedraw()
@@ -130,21 +142,47 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
}
override fun draw(drawer: Drawer) {
drawer.stroke = (ColorRGBa.BLACK.opacify(0.25))
drawer.strokeWeight = (1.0)
drawer.lineSegment(0.0, layout.screenHeight / 2.0, layout.screenWidth, layout.screenHeight / 2.0)
val controlArea = Rectangle(0.0, 0.0, layout.screenWidth, layout.screenHeight - footerHeight)
drawer.stroke = computedStyle.effectiveColor?.opacify(0.25)
drawer.strokeWeight = (1.0)
val zeroHeight = 0.0.map(range.start, range.endInclusive, -1.0, 1.0).coerceIn(-1.0, 1.0) * controlArea.height / -2.0
drawer.lineSegment(0.0, controlArea.height / 2.0 + zeroHeight, layout.screenWidth, controlArea.height / 2.0 + zeroHeight)
drawer.strokeWeight = 7.0
drawer.fill = computedStyle.effectiveColor
drawer.strokeWeight = 1.0
drawer.stroke = ColorRGBa.WHITE
for (i in value.indices) {
val dx = layout.screenWidth / (value.size + 1)
val height = -value[i] * layout.screenHeight / 2.0
val height = -value[i].map(range.start, range.endInclusive, -1.0, 1.0).coerceIn(-1.0, 1.0) * controlArea.height / 2.0
val x = dx * (i + 1)
drawer.lineCap = LineCap.ROUND
drawer.lineSegment(x, layout.screenHeight / 2.0, x, layout.screenHeight / 2.0 + height)
drawer.circle(x, layout.screenHeight / 2.0 + height, 5.0)
drawer.stroke = computedStyle.effectiveColor
drawer.lineSegment(x, controlArea.height / 2.0 + zeroHeight, x, controlArea.height / 2.0 + height)
drawer.stroke = computedStyle.effectiveColor?.shade(1.1)
drawer.fill = ColorRGBa.PINK
drawer.circle(x, controlArea.height / 2.0 + height, 7.0)
}
drawer.isolated {
drawer.translate(0.0, controlArea.height)
drawer.fill = computedStyle.effectiveColor
(root() as? Body)?.controlManager?.fontManager?.let {
val font = it.font(computedStyle)
val writer = Writer(drawer)
drawer.fontMap = (font)
drawer.fill = computedStyle.effectiveColor
writer.cursor = Cursor(0.0, 4.0)
writer.box = Rectangle(0.0, 4.0, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY)
writer.newLine()
writer.text(label)
}
}
tooltip?.draw(drawer)
}
}

View File

@@ -105,6 +105,10 @@ fun defaultStyles(
marginBottom = 15.px
marginLeft = 5.px
marginRight = 5.px
color = controlTextColor
and(has state "active") {
color = controlActiveColor
}
},
styleSheet(has type "colorpicker") {
@@ -116,6 +120,8 @@ fun defaultStyles(
marginRight = 5.px
},
styleSheet(has type "xy-pad") {
display = Display.BLOCK
background = Color.RGBa(ColorRGBa.GRAY)

View File

@@ -37,7 +37,8 @@ class Tooltip(val parent: Element, val position: Vector2, val message: String) {
drawer.translate(position)
drawer.translate(10.0, 0.0)
drawer.stroke = null
drawer.strokeWeight = 0.5
drawer.stroke = ColorRGBa.WHITE.opacify(0.25)
drawer.fill = ColorRGBa.GRAY
drawer.rectangle(0.0, 0.0, maxX + 20.0, maxY)
drawer.fill = ColorRGBa.BLACK