Add orx-gui

Includes changes to orx-parameters to make it work
This commit is contained in:
Edwin Jakobs
2020-02-02 01:04:09 +01:00
parent cde80ff06f
commit df65502cbe
6 changed files with 216 additions and 13 deletions

View File

@@ -1,5 +1,6 @@
package org.openrndr.extra.parameters
import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KVisibility
import kotlin.reflect.full.declaredMemberProperties
@@ -7,7 +8,7 @@ import kotlin.reflect.full.findAnnotation
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Description(val description: String)
annotation class Description(val title: String, val description: String = "")
/**
* DoubleParameter annotation for a double precision Filter parameter
@@ -41,6 +42,37 @@ annotation class IntParameter(val label: String, val low: Int, val high: Int, va
@Retention(AnnotationRetention.RUNTIME)
annotation class BooleanParameter(val label: String, val order: Int = Integer.MAX_VALUE)
/**
* ButtonParameter annotation for an integer Filter parameter
* @property label a short description of the parameter
* @property order hint for where to place the parameter in user interfaces
*/
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class ButtonParameter(val label: String, val order: Int = Integer.MAX_VALUE)
enum class ParameterType(val annotation: KClass<out Annotation>) {
Double(DoubleParameter::class),
Int(IntParameter::class),
Boolean(BooleanParameter::class),
Button(ButtonParameter::class)
;
companion object {
fun forParameterAnnotationClass(annotation: Annotation) : ParameterType {
return when(annotation) {
is DoubleParameter -> Double
is IntParameter -> Int
is BooleanParameter -> Boolean
is ButtonParameter -> Button
else -> error("no type for $annotation")
}
}
}
}
/**
* Parameter summary class. This is used by [listParameters] as a way to report parameters in
* a unified form.
@@ -53,6 +85,7 @@ annotation class BooleanParameter(val label: String, val order: Int = Integer.MA
* @property order a hint for where in the ui this parameter is placed, lower value means higher priority
*/
class Parameter(
val parameterType: ParameterType,
val property: KMutableProperty1<out Any, Any?>,
val label: String,
val doubleRange: ClosedRange<Double>?,
@@ -69,34 +102,49 @@ fun Any.listParameters(): List<Parameter> {
it.visibility == KVisibility.PUBLIC &&
(it.findAnnotation<BooleanParameter>() != null ||
it.findAnnotation<IntParameter>() != null ||
it.findAnnotation<DoubleParameter>() != null)
it.findAnnotation<DoubleParameter>() != null ||
it.findAnnotation<ButtonParameter>() != null)
}.map {
val annotations = listOf(it.findAnnotation<BooleanParameter>(), it.findAnnotation<IntParameter>(), it.findAnnotation<DoubleParameter>()).filterNotNull()
val annotations = listOf(it.findAnnotation<BooleanParameter>(), it.findAnnotation<IntParameter>(), it.findAnnotation<DoubleParameter>(), it.findAnnotation<ButtonParameter>()).filterNotNull()
var intRange: IntRange? = null
var doubleRange: ClosedRange<Double>? = null
var order: Int = Integer.MAX_VALUE
var label: String = ""
var precision: Int? = null
var type : ParameterType? = null
annotations.forEach {
when(it) {
type = ParameterType.forParameterAnnotationClass(it)
when (it) {
is BooleanParameter -> {
label = it.label
order = it.order
}
is DoubleParameter -> {
label = it.label
doubleRange = it.low .. it.high
doubleRange = it.low..it.high
precision = it.precision
order = it.order
}
is IntParameter -> {
label = it.label
intRange = it.low .. it.high
intRange = it.low..it.high
order = it.order
}
is ButtonParameter -> {
label = it.label
order = it.order
}
}
}
Parameter(it as KMutableProperty1<out Any, Any?>, label, doubleRange, intRange, precision, order)
Parameter(type?:error("no type"), it as KMutableProperty1<out Any, Any?>, label, doubleRange, intRange, precision, order)
}.sortedBy { it.order }
}
}
fun Any.title() = this::class.findAnnotation<Description>()?.let {
it.title
}
fun Any.description() = this::class.findAnnotation<Description>()?.let {
it.description
}

View File

@@ -1,9 +1,6 @@
import org.amshove.kluent.`should be equal to`
import org.amshove.kluent.shouldBeInRange
import org.openrndr.extra.parameters.BooleanParameter
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.extra.parameters.IntParameter
import org.openrndr.extra.parameters.listParameters
import org.openrndr.extra.parameters.*
import org.spekframework.spek2.Spek
import org.spekframework.spek2.style.specification.describe
@@ -16,14 +13,18 @@ val a = object {
@BooleanParameter("a boolean parameter", order = 2)
var b = false
@ButtonParameter("a button parameter", order = 3)
var f = {}
}
object TestAnnotations : Spek({
describe("an annotated object") {
it("has listable parameters") {
val list = a.listParameters()
list.size `should be equal to` 3
list.size `should be equal to` 4
list[0].property.name `should be equal to` "d"
list[0].parameterType `should be equal to` ParameterType.Double
list[0].label `should be equal to` "a double scalar"
list[0].doubleRange?.let {
it.start shouldBeInRange 0.0 .. 0.0001
@@ -32,6 +33,7 @@ object TestAnnotations : Spek({
list[0].precision `should be equal to` 3
list[1].property.name `should be equal to` "i"
list[1].parameterType `should be equal to` ParameterType.Int
list[1].label `should be equal to` "an integer scalar"
list[1].intRange?.let {
it.start `should be equal to` 1
@@ -39,8 +41,12 @@ object TestAnnotations : Spek({
}
list[2].property.name `should be equal to` "b"
list[2].parameterType `should be equal to` ParameterType.Boolean
list[2].label `should be equal to` "a boolean parameter"
list[2].precision `should be equal to` null
list[3].parameterType `should be equal to` ParameterType.Button
list[3].property.name `should be equal to` "f"
}
}
})