diff --git a/orx-gui/src/main/kotlin/Gui.kt b/orx-gui/src/main/kotlin/Gui.kt index 063de2a7..3ac99598 100644 --- a/orx-gui/src/main/kotlin/Gui.kt +++ b/orx-gui/src/main/kotlin/Gui.kt @@ -14,6 +14,8 @@ import org.openrndr.draw.Drawer import org.openrndr.extra.parameters.* import org.openrndr.internal.Driver 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.elements.* @@ -185,6 +187,19 @@ class GUI : Extension { this.width = 175.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 + } + // } @@ -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, + obj, + it.newValue) + + onChangeListener?.invoke(parameter.property!!.name, it.newValue) + } + getPersistedOrDefault( + compartment.label, + parameter.property as KMutableProperty1, + 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, + obj, + it.newValue) + + onChangeListener?.invoke(parameter.property!!.name, it.newValue) + } + getPersistedOrDefault( + compartment.label, + parameter.property as KMutableProperty1, + 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, + obj, + it.newValue) + + onChangeListener?.invoke(parameter.property!!.name, it.newValue) + } + getPersistedOrDefault( + compartment.label, + parameter.property as KMutableProperty1, + obj + )?.let { + value = it + } + } + } + + } } // @@ -486,7 +577,9 @@ class GUI : Extension { var intValue: Int? = null, var booleanValue: Boolean? = null, var colorValue: ColorRGBa? = null, - var vectorValue: Vector2? = null, + var vector2Value: Vector2? = null, + var vector3Value: Vector3? = null, + var vector4Value: Vector4? = null, var doubleListValue: MutableList? = null, var textValue: String? = null) @@ -507,8 +600,11 @@ class GUI : Extension { ParameterType.Color -> ParameterValue(colorValue = k.property.qget(lo.obj) as ColorRGBa) ParameterType.Text -> ParameterValue(textValue = k.property.qget(lo.obj) as String) 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) + 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 { parameter.property.qset(lo.obj, it) } - ParameterType.XY -> parameterValue.vectorValue?.let { + ParameterType.XY -> parameterValue.vector2Value?.let { parameter.property.qset(lo.obj, it) } ParameterType.DoubleList -> parameterValue.doubleListValue?.let { @@ -552,6 +648,15 @@ class GUI : Extension { ParameterType.Boolean -> parameterValue.booleanValue?.let { 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 -> { // intentionally do nothing } @@ -587,13 +692,22 @@ class GUI : Extension { ParameterType.Boolean -> { (control as Toggle).value = (parameter.property as KMutableProperty1).get(labeledObject.obj) } + ParameterType.Vector2 -> { + (control as SlidersVector2).value = (parameter.property as KMutableProperty1).get(labeledObject.obj) + } + ParameterType.Vector3 -> { + (control as SlidersVector3).value = (parameter.property as KMutableProperty1).get(labeledObject.obj) + } + ParameterType.Vector4 -> { + (control as SlidersVector4).value = (parameter.property as KMutableProperty1).get(labeledObject.obj) + } ParameterType.Action -> { // intentionally do nothing } } } - fun randomize(strength:Double = 0.05) { + fun randomize(strength: Double = 0.05) { for ((labeledObject, binding) in trackedObjects) { // -- only randomize visible parameters for (parameter in binding.parameterControls.keys) { @@ -604,7 +718,7 @@ class GUI : Extension { val max = parameter.doubleRange!!.endInclusive val currentValue = (parameter.property as KMutableProperty1).get(labeledObject.obj) 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).set(labeledObject.obj, newValue) } ParameterType.Int -> { @@ -612,7 +726,7 @@ class GUI : Extension { val max = parameter.intRange!!.last val currentValue = (parameter.property as KMutableProperty1).get(labeledObject.obj) 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).set(labeledObject.obj, newValue) } ParameterType.Boolean -> { @@ -622,9 +736,9 @@ class GUI : Extension { ParameterType.Color -> { val currentValue = (parameter.property as KMutableProperty1).get(labeledObject.obj) val randomValue = ColorRGBa(Math.random(), Math.random(), Math.random(), currentValue.a) - val newValue = ColorRGBa((1.0 - strength) * currentValue.r + randomValue.r * strength, - (1.0 - strength) * currentValue.g + randomValue.g * strength, - (1.0 - strength) * currentValue.b + randomValue.b * strength) + val newValue = ColorRGBa((1.0 - strength) * currentValue.r + randomValue.r * strength, + (1.0 - strength) * currentValue.g + randomValue.g * strength, + (1.0 - strength) * currentValue.b + randomValue.b * strength) (parameter.property as KMutableProperty1).set(labeledObject.obj, newValue) } @@ -637,7 +751,6 @@ class GUI : Extension { updateControls() } - /** * Recursively find a unique label * @param label to find an alternate for in case it already exist @@ -690,7 +803,7 @@ class GUI : Extension { } @JvmName("addToGui") -fun T.addTo(gui: GUI, label:String? = this.title()): T { +fun T.addTo(gui: GUI, label: String? = this.title()): T { gui.add(this, label) return this } diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/LayoutBuilder.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/LayoutBuilder.kt index 4b2e9042..4e11f8bd 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/LayoutBuilder.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/LayoutBuilder.kt @@ -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) diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SequenceEditor.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SequenceEditor.kt index 6711e8ea..8b73158c 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SequenceEditor.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SequenceEditor.kt @@ -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 = -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, val newValue: List) @@ -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 = -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, + val newValue: List) + + internal class Events { + val valueChanged = Event("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 diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SlidersVector.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SlidersVector.kt new file mode 100644 index 00000000..ddeedb51 --- /dev/null +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SlidersVector.kt @@ -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("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("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("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])) + ) + } + } +} + diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/style/DefaultStyles.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/style/DefaultStyles.kt index b7ea7f7b..7d9edd27 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/style/DefaultStyles.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/style/DefaultStyles.kt @@ -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 diff --git a/orx-parameters/src/main/kotlin/Annotations.kt b/orx-parameters/src/main/kotlin/Annotations.kt index 8763040f..de2ad511 100644 --- a/orx-parameters/src/main/kotlin/Annotations.kt +++ b/orx-parameters/src/main/kotlin/Annotations.kt @@ -115,6 +115,36 @@ annotation class XYParameter( 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 * @property label a short description of the parameter @@ -134,7 +164,10 @@ enum class ParameterType(val annotationClass: KClass) { Text(TextParameter::class), Color(ColorParameter::class), XY(XYParameter::class), - DoubleList(DoubleListParameter::class) + DoubleList(DoubleListParameter::class), + Vector2(Vector2Parameter::class), + Vector3(Vector3Parameter::class), + Vector4(Vector4Parameter::class) ; companion object { @@ -236,7 +269,24 @@ fun Any.listParameters(): List { doubleRange = it.low..it.high precision = it.precision 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 } } } diff --git a/orx-parameters/src/test/kotlin/TestAnnotations.kt b/orx-parameters/src/test/kotlin/TestAnnotations.kt index 6e2cff93..efa81e12 100644 --- a/orx-parameters/src/test/kotlin/TestAnnotations.kt +++ b/orx-parameters/src/test/kotlin/TestAnnotations.kt @@ -2,6 +2,8 @@ import org.amshove.kluent.* import org.openrndr.color.ColorRGBa import org.openrndr.extra.parameters.* import org.openrndr.math.Vector2 +import org.openrndr.math.Vector3 +import org.openrndr.math.Vector4 import org.spekframework.spek2.Spek import org.spekframework.spek2.style.specification.describe @@ -31,13 +33,24 @@ val a = object { @DoubleListParameter("a double list parameter", order = 7) var dl = mutableListOf() + + @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({ describe("an annotated object") { it("has listable parameters") { 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].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].property?.name `should be equal to` "dl" 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" } } })