diff --git a/orx-parameters/src/main/kotlin/Annotations.kt b/orx-parameters/src/main/kotlin/Annotations.kt index af3a9b12..9cc845e6 100644 --- a/orx-parameters/src/main/kotlin/Annotations.kt +++ b/orx-parameters/src/main/kotlin/Annotations.kt @@ -6,6 +6,14 @@ import kotlin.reflect.KVisibility import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.full.findAnnotation +/* In case you are here to add an extra annotation type: + 1. Add an annotation class + 2. Add an entry to ParameterType + 3. Add extra fields (if any) to Parameter + 4. Add handling annotation code to listParameters + 5. Add a test in TestAnnotations.kt + */ + @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) annotation class Description(val title: String, val description: String = "") @@ -43,7 +51,7 @@ annotation class IntParameter(val label: String, val low: Int, val high: Int, va annotation class BooleanParameter(val label: String, val order: Int = Integer.MAX_VALUE) /** - * Text annotation for a text parameter + * TextParameter annotation for a text parameter * @property label a short description of the parameter * @property order hint for where to place the parameter in user interfaces */ @@ -51,6 +59,14 @@ annotation class BooleanParameter(val label: String, val order: Int = Integer.MA @Retention(AnnotationRetention.RUNTIME) annotation class TextParameter(val label: String, val order: Int = Integer.MAX_VALUE) +/** + * ColorParameter annotation for a ColorRGBa 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 ColorParameter(val label: String, val order: Int = Integer.MAX_VALUE) /** * ButtonParameter annotation for button parameter @@ -61,25 +77,20 @@ annotation class TextParameter(val label: String, val order: Int = Integer.MAX_V @Retention(AnnotationRetention.RUNTIME) annotation class ButtonParameter(val label: String, val order: Int = Integer.MAX_VALUE) -enum class ParameterType(val annotation: KClass) { +enum class ParameterType(val annotationClass: KClass) { Double(DoubleParameter::class), Int(IntParameter::class), Boolean(BooleanParameter::class), Button(ButtonParameter::class), - Text(TextParameter::class) + Text(TextParameter::class), + Color(ColorParameter::class) ; companion object { - fun forParameterAnnotationClass(annotation: Annotation): ParameterType { - return when (annotation) { - is DoubleParameter -> Double - is IntParameter -> Int - is BooleanParameter -> Boolean - is ButtonParameter -> Button - is TextParameter -> Text - else -> error("no type for $annotation") - } - } + fun forParameterAnnotationClass(annotation: Annotation): ParameterType = + values().find { it.annotationClass == annotation.annotationClass } ?: error("no type for $annotation") + + val parameterAnnotationClasses get() = values().map { it.annotationClass } } } @@ -111,17 +122,9 @@ fun Any.listParameters(): List { return this::class.declaredMemberProperties.filter { !it.isConst && it.visibility == KVisibility.PUBLIC && - (it.findAnnotation() != null || - it.findAnnotation() != null || - it.findAnnotation() != null || - it.findAnnotation() != null) || - it.findAnnotation() != null + it.annotations.map { it.annotationClass }.intersect(ParameterType.parameterAnnotationClasses).isNotEmpty() }.map { - val annotations = listOfNotNull(it.findAnnotation(), - it.findAnnotation(), - it.findAnnotation(), - it.findAnnotation(), - it.findAnnotation()) + val annotations = it.annotations.filter { it.annotationClass in ParameterType.parameterAnnotationClasses } var intRange: IntRange? = null var doubleRange: ClosedRange? = null var order: Int = Integer.MAX_VALUE @@ -155,6 +158,10 @@ fun Any.listParameters(): List { label = it.label order = it.order } + is ColorParameter -> { + label = it.label + order = it.order + } } } Parameter(type diff --git a/orx-parameters/src/test/kotlin/TestAnnotations.kt b/orx-parameters/src/test/kotlin/TestAnnotations.kt index 8c86dd07..abe9eeb7 100644 --- a/orx-parameters/src/test/kotlin/TestAnnotations.kt +++ b/orx-parameters/src/test/kotlin/TestAnnotations.kt @@ -1,5 +1,6 @@ import org.amshove.kluent.`should be equal to` import org.amshove.kluent.shouldBeInRange +import org.openrndr.color.ColorRGBa import org.openrndr.extra.parameters.* import org.spekframework.spek2.Spek import org.spekframework.spek2.style.specification.describe @@ -19,13 +20,18 @@ val a = object { @TextParameter("a text parameter", order = 4) var t = "test" + + @ColorParameter("a color parameter", order = 5) + var c = ColorRGBa.WHITE + } object TestAnnotations : Spek({ describe("an annotated object") { it("has listable parameters") { val list = a.listParameters() - list.size `should be equal to` 5 + list.size `should be equal to` 6 + 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" @@ -50,9 +56,15 @@ object TestAnnotations : Spek({ list[3].parameterType `should be equal to` ParameterType.Button list[3].property.name `should be equal to` "f" + list[3].label `should be equal to` "a button parameter" list[4].parameterType `should be equal to` ParameterType.Text list[4].property.name `should be equal to` "t" + list[4].label `should be equal to` "a text parameter" + + list[5].parameterType `should be equal to` ParameterType.Color + list[5].property.name `should be equal to` "c" + list[5].label `should be equal to` "a color parameter" } } })