Add Vector2/Vector3/Vector4 parameters and controls

This commit is contained in:
Edwin Jakobs
2020-03-26 21:43:46 +01:00
parent 8276099feb
commit c1d6f698ec
7 changed files with 417 additions and 51 deletions

View File

@@ -63,6 +63,12 @@ fun Element.envelopeEditor(vararg classes: String, init: EnvelopeEditor.() -> Un
fun Element.sequenceEditor(vararg classes: String, init: SequenceEditor.() -> Unit) = initElement(classes, SequenceEditor().apply {}, init)
fun Element.slidersVector2(vararg classes: String, init: SlidersVector2.() -> Unit) = initElement(classes, SlidersVector2().apply {}, init)
fun Element.slidersVector3(vararg classes: String, init: SlidersVector3.() -> Unit) = initElement(classes, SlidersVector3().apply {}, init)
fun Element.slidersVector4(vararg classes: String, init: SlidersVector4.() -> Unit) = initElement(classes, SlidersVector4().apply {}, init)
fun Element.textfield(vararg classes: String, init: Textfield.() -> Unit) = initElement(classes, Textfield(), init)

View File

@@ -9,8 +9,6 @@ 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
@@ -20,21 +18,17 @@ import kotlin.math.abs
import kotlin.math.round
import kotlin.math.roundToInt
class SequenceEditor : Element(ElementType("sequence-editor")) {
class SequenceEditor : SequenceEditorBase("sequence-editor") {
var value
get() = baseValue
set(value) {
baseValue = value
}
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
public override var maximumSequenceLength = 16
public override var minimumSequenceLength = 1
private var selectedIndex: Int? = null
private var tooltip: Tooltip? = null
private val footerHeight = 20.0
class ValueChangedEvent(val source: SequenceEditor,
class ValueChangedEvent(val source: SequenceEditorBase,
val oldValue: List<Double>,
val newValue: List<Double>)
@@ -44,6 +38,37 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
val events = Events()
init {
baseEvents.valueChanged.listen {
events.valueChanged.trigger(ValueChangedEvent(this, it.oldValue, it.newValue))
}
}
}
open class SequenceEditorBase(type: String = "sequence-editor-base") : Element(ElementType(type)) {
internal var baseValue = mutableListOf(0.0)
var label = "sequence"
var precision = 2
internal open var maximumSequenceLength = 16
internal open 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
internal class ValueChangedEvent(val source: SequenceEditorBase,
val oldValue: List<Double>,
val newValue: List<Double>)
internal class Events {
val valueChanged = Event<ValueChangedEvent>("sequence-editor-base-value-changed")
}
internal val baseEvents = Events()
init {
fun query(position: Vector2): Vector2 {
val x = (position.x - layout.screenX) / layout.screenWidth
@@ -56,8 +81,8 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
requestRedraw()
}
mouse.pressed.listen {
if (value.isNotEmpty()) {
val dx = (layout.screenWidth / (value.size + 1))
if (baseValue.isNotEmpty()) {
val dx = (layout.screenWidth / (baseValue.size + 1))
val index = (it.position.x - layout.screenX) / dx
val d = index - round(index)
@@ -68,20 +93,20 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
selectedIndex = if (KeyModifier.CTRL !in it.modifiers) {
round(index).toInt()
} else {
if (value.size > minimumSequenceLength) {
val oldValue = value.map { it }
value.removeAt(round(index).toInt() - 1)
events.valueChanged.trigger(ValueChangedEvent(this, oldValue, value))
if (baseValue.size > minimumSequenceLength) {
val oldValue = baseValue.map { it }
baseValue.removeAt(round(index).toInt() - 1)
baseEvents.valueChanged.trigger(ValueChangedEvent(this, oldValue, baseValue))
}
null
}
} else {
if (KeyModifier.CTRL !in it.modifiers) {
if (value.size < maximumSequenceLength) {
if (baseValue.size < maximumSequenceLength) {
val q = query(it.position)
val oldValue = value.map { it }
value.add(index.toInt(), q.y.map(-1.0, 1.0, range.start, range.endInclusive))
events.valueChanged.trigger(ValueChangedEvent(this, oldValue, value))
val oldValue = baseValue.map { it }
baseValue.add(index.toInt(), q.y.map(-1.0, 1.0, range.start, range.endInclusive))
baseEvents.valueChanged.trigger(ValueChangedEvent(this, oldValue, baseValue))
}
}
}
@@ -108,8 +133,8 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
requestRedraw()
}
if (value.isNotEmpty()) {
val dx = (layout.screenWidth / (value.size + 1))
if (baseValue.isNotEmpty()) {
val dx = (layout.screenWidth / (baseValue.size + 1))
val index = (it.position.x - layout.screenX) / dx
val d = index - round(index)
val dp = d * dx
@@ -118,9 +143,9 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
if (dpa < 10.0) {
hoverJob = GlobalScope.launch {
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), "$value")
if (readIndex >= 0 && readIndex < baseValue.size) {
val value = String.format("%.0${precision}f", baseValue[readIndex])
tooltip = Tooltip(this@SequenceEditorBase, it.position - Vector2(layout.screenX, layout.screenY), "$value")
requestRedraw()
}
}
@@ -131,10 +156,10 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
val q = query(it.position)
selectedIndex?.let { index ->
val writeIndex = index - 1
if (writeIndex >= 0 && writeIndex < value.size) {
val oldValue = value.map { it }
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))
if (writeIndex >= 0 && writeIndex < baseValue.size) {
val oldValue = baseValue.map { it }
baseValue[writeIndex] = q.y.coerceIn(-1.0, 1.0).map(-1.0, 1.0, range.start, range.endInclusive)
baseEvents.valueChanged.trigger(ValueChangedEvent(this, oldValue, baseValue))
}
requestRedraw()
}
@@ -154,9 +179,9 @@ class SequenceEditor : Element(ElementType("sequence-editor")) {
drawer.strokeWeight = 7.0
drawer.fill = computedStyle.effectiveColor
for (i in value.indices) {
val dx = layout.screenWidth / (value.size + 1)
val height = -value[i].map(range.start, range.endInclusive, -1.0, 1.0).coerceIn(-1.0, 1.0) * controlArea.height / 2.0
for (i in baseValue.indices) {
val dx = layout.screenWidth / (baseValue.size + 1)
val height = -baseValue[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

View File

@@ -0,0 +1,111 @@
package org.openrndr.panel.elements
import org.openrndr.events.Event
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
import org.openrndr.math.Vector4
class SlidersVector2 : SequenceEditorBase("sliders-vector2") {
var value : Vector2
get() {
return Vector2(baseValue[0], baseValue[1])
}
set(value) {
baseValue[0] = value.x
baseValue[1] = value.y
}
class ValueChangedEvent(val source: SequenceEditorBase,
val oldValue: Vector2,
val newValue: Vector2)
class Events {
val valueChanged = Event<ValueChangedEvent>("sequence-editor-value-changed")
}
val events = Events()
init {
baseValue = mutableListOf(0.0, 0.0)
minimumSequenceLength = 2
maximumSequenceLength = 2
baseEvents.valueChanged.listen {
events.valueChanged.trigger(ValueChangedEvent(this,
Vector2(it.oldValue[0], it.oldValue[1]),
Vector2(it.newValue[0], it.newValue[1]))
)
}
}
}
class SlidersVector3 : SequenceEditorBase("sliders-vector3") {
var value : Vector3
get() {
return Vector3(baseValue[0], baseValue[1], baseValue[2])
}
set(value) {
baseValue[0] = value.x
baseValue[1] = value.y
baseValue[2] = value.z
}
class ValueChangedEvent(val source: SequenceEditorBase,
val oldValue: Vector3,
val newValue: Vector3)
class Events {
val valueChanged = Event<ValueChangedEvent>("sliders-vector3-value-changed")
}
val events = Events()
init {
baseValue = mutableListOf(0.0, 0.0, 0.0)
minimumSequenceLength = 3
maximumSequenceLength = 3
baseEvents.valueChanged.listen {
events.valueChanged.trigger(ValueChangedEvent(this,
Vector3(it.oldValue[0], it.oldValue[1], it.oldValue[2]),
Vector3(it.newValue[0], it.newValue[1], it.newValue[2]))
)
}
}
}
class SlidersVector4 : SequenceEditorBase("sliders-vector4") {
var value : Vector4
get() {
return Vector4(baseValue[0], baseValue[1], baseValue[2], baseValue[3])
}
set(value) {
baseValue[0] = value.x
baseValue[1] = value.y
baseValue[2] = value.z
baseValue[3] = value.w
}
class ValueChangedEvent(val source: SequenceEditorBase,
val oldValue: Vector4,
val newValue: Vector4)
class Events {
val valueChanged = Event<ValueChangedEvent>("sliders-vector4-value-changed")
}
val events = Events()
init {
baseValue = mutableListOf(0.0, 0.0, 0.0, 0.0)
minimumSequenceLength = 4
maximumSequenceLength = 4
baseEvents.valueChanged.listen {
events.valueChanged.trigger(ValueChangedEvent(this,
Vector4(it.oldValue[0], it.oldValue[1], it.oldValue[2], it.oldValue[3]),
Vector4(it.newValue[0], it.newValue[1], it.newValue[2], it.newValue[3]))
)
}
}
}

View File

@@ -110,6 +110,42 @@ fun defaultStyles(
color = controlActiveColor
}
},
styleSheet(has type "sliders-vector2") {
height = 60.px
width = 100.percent
marginTop = 5.px
marginBottom = 15.px
marginLeft = 5.px
marginRight = 5.px
color = controlTextColor
and(has state "active") {
color = controlActiveColor
}
},
styleSheet(has type "sliders-vector3") {
height = 60.px
width = 100.percent
marginTop = 5.px
marginBottom = 15.px
marginLeft = 5.px
marginRight = 5.px
color = controlTextColor
and(has state "active") {
color = controlActiveColor
}
},
styleSheet(has type "sliders-vector4") {
height = 60.px
width = 100.percent
marginTop = 5.px
marginBottom = 15.px
marginLeft = 5.px
marginRight = 5.px
color = controlTextColor
and(has state "active") {
color = controlActiveColor
}
},
styleSheet(has type "colorpicker") {
height = 80.px