Add inter-evaluation persistence for orx-gui

This commit is contained in:
Edwin Jakobs
2020-02-06 00:07:33 +01:00
parent dce423fe88
commit 5111bd6fb8

View File

@@ -13,9 +13,24 @@ import org.openrndr.panel.style.*
import kotlin.reflect.KMutableProperty1
private data class LabeledObject(val label: String, val obj: Any)
private class CollapseState(var collapsed:Boolean = false)
private class CompartmentState(var collapsed: Boolean = false, val parameterValues: MutableMap<String, Any> = mutableMapOf())
private val persistentCollapseStates = mutableMapOf<Long, MutableMap<String, CollapseState>>()
private val persistentCompartmentStates = mutableMapOf<Long, MutableMap<String, CompartmentState>>()
private fun <T : Any> getPersistedOrDefault(compartmentLabel: String, property: KMutableProperty1<Any, T>, obj: Any): T? {
val state = persistentCompartmentStates[Driver.instance.contextID]!![compartmentLabel]
if (state == null) {
return property.get(obj)
} else {
return state.parameterValues[property.name] as? T?
}
}
private fun <T : Any> setAndPersist(compartmentLabel: String, property: KMutableProperty1<Any, T>, obj: Any, value: T) {
property.set(obj, value)
val state = persistentCompartmentStates[Driver.instance.contextID]!![compartmentLabel]!!
state.parameterValues[property.name] = value
}
@Suppress("unused", "UNCHECKED_CAST")
class GUI : Extension {
@@ -49,6 +64,10 @@ class GUI : Extension {
this.display = Display.NONE
}
styleSheet(has class_ "compartment") {
this.paddingBottom = 20.px
}
styleSheet(has class_ "sidebar") {
this.width = 200.px
this.paddingBottom = 20.px
@@ -57,7 +76,7 @@ class GUI : Extension {
this.paddingRight = 10.px
this.marginRight = 2.px
this.height = 100.percent
this.background = Color.RGBa(ColorRGBa.GRAY.copy(a = 0.2))
this.background = Color.RGBa(ColorRGBa.GRAY.copy(a = 0.99))
this.overflow = Overflow.Scroll
descendant(has type "colorpicker-button") {
@@ -98,15 +117,15 @@ class GUI : Extension {
val (label, obj) = labeledObject
val header = h3 { label }
val collapsible = div {
val collapsible = div("compartment") {
for (parameter in parameters) {
addControl(obj, parameter)
addControl(labeledObject, parameter)
}
}
val collapseClass = ElementClass("collapsed")
/* this is guaranteed to be in the dictionary after insertion through add() */
val collapseState = persistentCollapseStates[Driver.instance.contextID]!![label]!!
val collapseState = persistentCompartmentStates[Driver.instance.contextID]!![label]!!
if (collapseState.collapsed) {
collapsible.classes.add(collapseClass)
}
@@ -131,18 +150,23 @@ class GUI : Extension {
program.extend(panel)
}
private fun Div.addControl(obj: Any, parameter: Parameter) {
private fun Div.addControl(compartment: LabeledObject, parameter: Parameter) {
val obj = compartment.obj
when (parameter.parameterType) {
ParameterType.Int -> {
slider {
label = parameter.label
range = Range(parameter.intRange!!.first.toDouble(), parameter.intRange!!.last.toDouble())
precision = 0
value = (parameter.property as KMutableProperty1<Any, Int>).get(obj).toDouble()
events.valueChanged.subscribe {
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, Int>, obj, it.newValue.toInt())
(parameter.property as KMutableProperty1<Any, Int>).set(obj, value.toInt())
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
getPersistedOrDefault(compartment.label, parameter.property as KMutableProperty1<Any, Int>, obj)?.let {
value = it.toDouble()
}
}
}
ParameterType.Double -> {
@@ -150,11 +174,13 @@ class GUI : Extension {
label = parameter.label
range = Range(parameter.doubleRange!!.start, parameter.doubleRange!!.endInclusive)
precision = parameter.precision!!
value = (parameter.property as KMutableProperty1<Any, Double>).get(obj)
events.valueChanged.subscribe {
(parameter.property as KMutableProperty1<Any, Double>).set(obj, value)
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, Double>, obj, it.newValue)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
getPersistedOrDefault(compartment.label, parameter.property as KMutableProperty1<Any, Double>, obj)?.let {
value = it
}
}
}
@@ -174,35 +200,38 @@ class GUI : Extension {
label = parameter.label
range = Range(0.0, 1.0)
precision = 0
value = if ((parameter.property as KMutableProperty1<Any, Boolean>).get(obj)) 1.0 else 0.0
events.valueChanged.subscribe {
value = it.newValue
(parameter.property as KMutableProperty1<Any, Boolean>).set(obj, value > 0.5)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
value = if ((parameter.property as KMutableProperty1<Any, Boolean>).get(obj)) 1.0 else 0.0
}
}
ParameterType.Text -> {
textfield {
label = parameter.label
value = (parameter.property as KMutableProperty1<Any, String>).get(obj)
events.valueChanged.subscribe {
value = it.newValue
(parameter.property as KMutableProperty1<Any, String>).set(obj, value)
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, String>, obj, it.newValue)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
getPersistedOrDefault(compartment.label, parameter.property as KMutableProperty1<Any, String>, obj)?.let {
value = it
}
}
}
ParameterType.Color -> {
colorpickerButton {
label = parameter.label
color = (parameter.property as KMutableProperty1<Any, ColorRGBa>).get(obj)
events.valueChanged.subscribe {
(parameter.property as KMutableProperty1<Any, ColorRGBa>).set(obj, it.color)
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, ColorRGBa>, obj, it.color)
onChangeListener?.invoke(parameter.property!!.name, it.color)
}
getPersistedOrDefault(compartment.label, parameter.property as KMutableProperty1<Any, ColorRGBa>, obj)?.let {
color = it
}
}
}
}
@@ -233,11 +262,11 @@ class GUI : Extension {
val uniqueLabel = resolveUniqueLabel(label ?: "No name")
if (parameters.isNotEmpty()) {
val collapseStates = persistentCollapseStates.getOrPut(Driver.instance.contextID) {
val collapseStates = persistentCompartmentStates.getOrPut(Driver.instance.contextID) {
mutableMapOf()
}
collapseStates.getOrPut(uniqueLabel) {
CollapseState()
CompartmentState()
}
trackedParams[LabeledObject(uniqueLabel, objectWithParameters)] = parameters
}