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

@@ -14,6 +14,8 @@ import org.openrndr.draw.Drawer
import org.openrndr.extra.parameters.* import org.openrndr.extra.parameters.*
import org.openrndr.internal.Driver import org.openrndr.internal.Driver
import org.openrndr.math.Vector2 import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
import org.openrndr.math.Vector4
import org.openrndr.panel.ControlManager import org.openrndr.panel.ControlManager
import org.openrndr.panel.controlManager import org.openrndr.panel.controlManager
import org.openrndr.panel.elements.* import org.openrndr.panel.elements.*
@@ -185,6 +187,19 @@ class GUI : Extension {
this.width = 175.px this.width = 175.px
this.height = 100.px this.height = 100.px
} }
descendant(has type "sliders-vector2") {
this.width = 175.px
this.height = 100.px
}
descendant(has type "sliders-vector3") {
this.width = 175.px
this.height = 100.px
}
descendant(has type "sliders-vector4") {
this.width = 175.px
this.height = 100.px
}
//</editor-fold> //</editor-fold>
} }
@@ -468,6 +483,82 @@ class GUI : Extension {
} }
} }
ParameterType.Vector2 -> {
slidersVector2 {
range = parameter.doubleRange!!
label = parameter.label
precision = parameter.precision!!
events.valueChanged.listen {
setAndPersist(
compartment.label,
parameter.property as KMutableProperty1<Any, Vector2>,
obj,
it.newValue)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
getPersistedOrDefault(
compartment.label,
parameter.property as KMutableProperty1<Any, Vector2>,
obj
)?.let {
value = it
}
}
}
ParameterType.Vector3 -> {
slidersVector3 {
range = parameter.doubleRange!!
label = parameter.label
precision = parameter.precision!!
events.valueChanged.listen {
setAndPersist(
compartment.label,
parameter.property as KMutableProperty1<Any, Vector3>,
obj,
it.newValue)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
getPersistedOrDefault(
compartment.label,
parameter.property as KMutableProperty1<Any, Vector3>,
obj
)?.let {
value = it
}
}
}
ParameterType.Vector4 -> {
slidersVector4 {
range = parameter.doubleRange!!
label = parameter.label
precision = parameter.precision!!
events.valueChanged.listen {
setAndPersist(
compartment.label,
parameter.property as KMutableProperty1<Any, Vector4>,
obj,
it.newValue)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
getPersistedOrDefault(
compartment.label,
parameter.property as KMutableProperty1<Any, Vector4>,
obj
)?.let {
value = it
}
}
}
} }
} }
//</editor-fold> //</editor-fold>
@@ -486,7 +577,9 @@ class GUI : Extension {
var intValue: Int? = null, var intValue: Int? = null,
var booleanValue: Boolean? = null, var booleanValue: Boolean? = null,
var colorValue: ColorRGBa? = null, var colorValue: ColorRGBa? = null,
var vectorValue: Vector2? = null, var vector2Value: Vector2? = null,
var vector3Value: Vector3? = null,
var vector4Value: Vector4? = null,
var doubleListValue: MutableList<Double>? = null, var doubleListValue: MutableList<Double>? = null,
var textValue: String? = null) var textValue: String? = null)
@@ -507,8 +600,11 @@ class GUI : Extension {
ParameterType.Color -> ParameterValue(colorValue = k.property.qget(lo.obj) as ColorRGBa) ParameterType.Color -> ParameterValue(colorValue = k.property.qget(lo.obj) as ColorRGBa)
ParameterType.Text -> ParameterValue(textValue = k.property.qget(lo.obj) as String) ParameterType.Text -> ParameterValue(textValue = k.property.qget(lo.obj) as String)
ParameterType.Boolean -> ParameterValue(booleanValue = k.property.qget(lo.obj) as Boolean) ParameterType.Boolean -> ParameterValue(booleanValue = k.property.qget(lo.obj) as Boolean)
ParameterType.XY -> ParameterValue(vectorValue = k.property.qget(lo.obj) as Vector2) ParameterType.XY -> ParameterValue(vector2Value = k.property.qget(lo.obj) as Vector2)
ParameterType.DoubleList -> ParameterValue(doubleListValue = k.property.qget(lo.obj) as MutableList<Double>) ParameterType.DoubleList -> ParameterValue(doubleListValue = k.property.qget(lo.obj) as MutableList<Double>)
ParameterType.Vector2 -> ParameterValue(vector2Value = k.property.qget(lo.obj) as Vector2)
ParameterType.Vector3 -> ParameterValue(vector3Value = k.property.qget(lo.obj) as Vector3)
ParameterType.Vector4 -> ParameterValue(vector4Value = k.property.qget(lo.obj) as Vector4)
}) })
}) })
} }
@@ -543,7 +639,7 @@ class GUI : Extension {
ParameterType.Color -> parameterValue.colorValue?.let { ParameterType.Color -> parameterValue.colorValue?.let {
parameter.property.qset(lo.obj, it) parameter.property.qset(lo.obj, it)
} }
ParameterType.XY -> parameterValue.vectorValue?.let { ParameterType.XY -> parameterValue.vector2Value?.let {
parameter.property.qset(lo.obj, it) parameter.property.qset(lo.obj, it)
} }
ParameterType.DoubleList -> parameterValue.doubleListValue?.let { ParameterType.DoubleList -> parameterValue.doubleListValue?.let {
@@ -552,6 +648,15 @@ class GUI : Extension {
ParameterType.Boolean -> parameterValue.booleanValue?.let { ParameterType.Boolean -> parameterValue.booleanValue?.let {
parameter.property.qset(lo.obj, it) parameter.property.qset(lo.obj, it)
} }
ParameterType.Vector2 -> parameterValue.vector2Value?.let {
parameter.property.qset(lo.obj, it)
}
ParameterType.Vector3 -> parameterValue.vector3Value?.let {
parameter.property.qset(lo.obj, it)
}
ParameterType.Vector4 -> parameterValue.vector4Value?.let {
parameter.property.qset(lo.obj, it)
}
ParameterType.Action -> { ParameterType.Action -> {
// intentionally do nothing // intentionally do nothing
} }
@@ -587,13 +692,22 @@ class GUI : Extension {
ParameterType.Boolean -> { ParameterType.Boolean -> {
(control as Toggle).value = (parameter.property as KMutableProperty1<Any, Boolean>).get(labeledObject.obj) (control as Toggle).value = (parameter.property as KMutableProperty1<Any, Boolean>).get(labeledObject.obj)
} }
ParameterType.Vector2 -> {
(control as SlidersVector2).value = (parameter.property as KMutableProperty1<Any, Vector2>).get(labeledObject.obj)
}
ParameterType.Vector3 -> {
(control as SlidersVector3).value = (parameter.property as KMutableProperty1<Any, Vector3>).get(labeledObject.obj)
}
ParameterType.Vector4 -> {
(control as SlidersVector4).value = (parameter.property as KMutableProperty1<Any, Vector4>).get(labeledObject.obj)
}
ParameterType.Action -> { ParameterType.Action -> {
// intentionally do nothing // intentionally do nothing
} }
} }
} }
fun randomize(strength:Double = 0.05) { fun randomize(strength: Double = 0.05) {
for ((labeledObject, binding) in trackedObjects) { for ((labeledObject, binding) in trackedObjects) {
// -- only randomize visible parameters // -- only randomize visible parameters
for (parameter in binding.parameterControls.keys) { for (parameter in binding.parameterControls.keys) {
@@ -604,7 +718,7 @@ class GUI : Extension {
val max = parameter.doubleRange!!.endInclusive val max = parameter.doubleRange!!.endInclusive
val currentValue = (parameter.property as KMutableProperty1<Any, Double>).get(labeledObject.obj) val currentValue = (parameter.property as KMutableProperty1<Any, Double>).get(labeledObject.obj)
val randomValue = Math.random() * (max - min) + min val randomValue = Math.random() * (max - min) + min
val newValue = (1.0 - strength) * currentValue + randomValue * strength val newValue = (1.0 - strength) * currentValue + randomValue * strength
(parameter.property as KMutableProperty1<Any, Double>).set(labeledObject.obj, newValue) (parameter.property as KMutableProperty1<Any, Double>).set(labeledObject.obj, newValue)
} }
ParameterType.Int -> { ParameterType.Int -> {
@@ -612,7 +726,7 @@ class GUI : Extension {
val max = parameter.intRange!!.last val max = parameter.intRange!!.last
val currentValue = (parameter.property as KMutableProperty1<Any, Int>).get(labeledObject.obj) val currentValue = (parameter.property as KMutableProperty1<Any, Int>).get(labeledObject.obj)
val randomValue = Math.random() * (max - min) + min val randomValue = Math.random() * (max - min) + min
val newValue = ((1.0 - strength) * currentValue + randomValue * strength).roundToInt() val newValue = ((1.0 - strength) * currentValue + randomValue * strength).roundToInt()
(parameter.property as KMutableProperty1<Any, Int>).set(labeledObject.obj, newValue) (parameter.property as KMutableProperty1<Any, Int>).set(labeledObject.obj, newValue)
} }
ParameterType.Boolean -> { ParameterType.Boolean -> {
@@ -622,9 +736,9 @@ class GUI : Extension {
ParameterType.Color -> { ParameterType.Color -> {
val currentValue = (parameter.property as KMutableProperty1<Any, ColorRGBa>).get(labeledObject.obj) val currentValue = (parameter.property as KMutableProperty1<Any, ColorRGBa>).get(labeledObject.obj)
val randomValue = ColorRGBa(Math.random(), Math.random(), Math.random(), currentValue.a) val randomValue = ColorRGBa(Math.random(), Math.random(), Math.random(), currentValue.a)
val newValue = ColorRGBa((1.0 - strength) * currentValue.r + randomValue.r * strength, val newValue = ColorRGBa((1.0 - strength) * currentValue.r + randomValue.r * strength,
(1.0 - strength) * currentValue.g + randomValue.g * strength, (1.0 - strength) * currentValue.g + randomValue.g * strength,
(1.0 - strength) * currentValue.b + randomValue.b * strength) (1.0 - strength) * currentValue.b + randomValue.b * strength)
(parameter.property as KMutableProperty1<Any, ColorRGBa>).set(labeledObject.obj, newValue) (parameter.property as KMutableProperty1<Any, ColorRGBa>).set(labeledObject.obj, newValue)
} }
@@ -637,7 +751,6 @@ class GUI : Extension {
updateControls() updateControls()
} }
/** /**
* Recursively find a unique label * Recursively find a unique label
* @param label to find an alternate for in case it already exist * @param label to find an alternate for in case it already exist
@@ -690,7 +803,7 @@ class GUI : Extension {
} }
@JvmName("addToGui") @JvmName("addToGui")
fun <T : Any> T.addTo(gui: GUI, label:String? = this.title()): T { fun <T : Any> T.addTo(gui: GUI, label: String? = this.title()): T {
gui.add(this, label) gui.add(this, label)
return this return this
} }

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

View File

@@ -115,6 +115,36 @@ annotation class XYParameter(
val order: Int = Integer.MAX_VALUE val order: Int = Integer.MAX_VALUE
) )
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class Vector2Parameter(
val label: String,
val min: Double = -1.0,
val max: Double = 1.0,
val precision: Int = 2,
val order: Int = Integer.MAX_VALUE
)
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class Vector3Parameter(
val label: String,
val min: Double = -1.0,
val max: Double = 1.0,
val precision: Int = 2,
val order: Int = Integer.MAX_VALUE
)
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class Vector4Parameter(
val label: String,
val min: Double = -1.0,
val max: Double = 1.0,
val precision: Int = 2,
val order: Int = Integer.MAX_VALUE
)
/** /**
* ActionParameter annotation for functions without arguments * ActionParameter annotation for functions without arguments
* @property label a short description of the parameter * @property label a short description of the parameter
@@ -134,7 +164,10 @@ enum class ParameterType(val annotationClass: KClass<out Annotation>) {
Text(TextParameter::class), Text(TextParameter::class),
Color(ColorParameter::class), Color(ColorParameter::class),
XY(XYParameter::class), XY(XYParameter::class),
DoubleList(DoubleListParameter::class) DoubleList(DoubleListParameter::class),
Vector2(Vector2Parameter::class),
Vector3(Vector3Parameter::class),
Vector4(Vector4Parameter::class)
; ;
companion object { companion object {
@@ -236,7 +269,24 @@ fun Any.listParameters(): List<Parameter> {
doubleRange = it.low..it.high doubleRange = it.low..it.high
precision = it.precision precision = it.precision
sizeRange = it.minimumListLength..it.maximumListLength sizeRange = it.minimumListLength..it.maximumListLength
}
is Vector2Parameter -> {
label = it.label
order = it.order
doubleRange = it.min..it.max
precision = it.precision
}
is Vector3Parameter -> {
label = it.label
order = it.order
doubleRange = it.min..it.max
precision = it.precision
}
is Vector4Parameter -> {
label = it.label
order = it.order
doubleRange = it.min..it.max
precision = it.precision
} }
} }
} }

View File

@@ -2,6 +2,8 @@ import org.amshove.kluent.*
import org.openrndr.color.ColorRGBa import org.openrndr.color.ColorRGBa
import org.openrndr.extra.parameters.* import org.openrndr.extra.parameters.*
import org.openrndr.math.Vector2 import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
import org.openrndr.math.Vector4
import org.spekframework.spek2.Spek import org.spekframework.spek2.Spek
import org.spekframework.spek2.style.specification.describe import org.spekframework.spek2.style.specification.describe
@@ -31,13 +33,24 @@ val a = object {
@DoubleListParameter("a double list parameter", order = 7) @DoubleListParameter("a double list parameter", order = 7)
var dl = mutableListOf<Double>() var dl = mutableListOf<Double>()
@Vector2Parameter("a vector 2 parameter", order = 8)
var v2 = Vector2.ZERO
@Vector3Parameter("a vector 3 parameter", order = 9)
var v3 = Vector3.ZERO
@Vector4Parameter("a vector 4 parameter", order = 10)
var v4 = Vector4.ZERO
} }
object TestAnnotations : Spek({ object TestAnnotations : Spek({
describe("an annotated object") { describe("an annotated object") {
it("has listable parameters") { it("has listable parameters") {
val list = a.listParameters() val list = a.listParameters()
list.size `should be equal to` 8 list.size `should be equal to` 11
list[0].property?.name `should be equal to` "d" list[0].property?.name `should be equal to` "d"
list[0].parameterType `should be equal to` ParameterType.Double list[0].parameterType `should be equal to` ParameterType.Double
@@ -92,6 +105,18 @@ object TestAnnotations : Spek({
list[7].parameterType `should be equal to` ParameterType.DoubleList list[7].parameterType `should be equal to` ParameterType.DoubleList
list[7].property?.name `should be equal to` "dl" list[7].property?.name `should be equal to` "dl"
list[7].label `should be equal to` "a double list parameter" list[7].label `should be equal to` "a double list parameter"
list[8].parameterType `should be equal to` ParameterType.Vector2
list[8].property?.name `should be equal to` "v2"
list[8].label `should be equal to` "a vector 2 parameter"
list[9].parameterType `should be equal to` ParameterType.Vector3
list[9].property?.name `should be equal to` "v3"
list[9].label `should be equal to` "a vector 3 parameter"
list[10].parameterType `should be equal to` ParameterType.Vector4
list[10].property?.name `should be equal to` "v4"
list[10].label `should be equal to` "a vector 4 parameter"
} }
} }
}) })