[orx-gui] Add showToolbar configuration option

This commit is contained in:
Edwin Jakobs
2023-02-21 17:16:00 +01:00
parent 2fd444604b
commit fe3e0e7b34

View File

@@ -54,7 +54,11 @@ private fun sidebarState(): SidebarState = persistentSidebarStates.getOrPut(Driv
SidebarState()
}
private fun <T : Any> getPersistedOrDefault(compartmentLabel: String, property: KMutableProperty1<Any, T>, obj: Any): T? {
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)
@@ -76,8 +80,10 @@ private val logger = KotlinLogging.logger { }
class GUIAppearance(val baseColor: ColorRGBa = ColorRGBa.GRAY, val barWidth: Int = 200)
@Suppress("unused", "UNCHECKED_CAST")
class GUI(val appearance: GUIAppearance = GUIAppearance(),
val defaultStyles: List<StyleSheet> = defaultStyles()) : Extension {
class GUI(
val appearance: GUIAppearance = GUIAppearance(),
val defaultStyles: List<StyleSheet> = defaultStyles(),
) : Extension {
private var onChangeListener: ((name: String, value: Any?) -> Unit)? = null
override var enabled = true
@@ -101,6 +107,7 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
var defaultSaveFolder = "gui-parameters"
var persistState = true
var enableSideCanvas = false
var showToolbar = true
var canvas: Canvas? = null
private var panel: ControlManager? = null
@@ -148,14 +155,14 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
if (it.key == KEY_LEFT_SHIFT) {
shiftDown = true
randomizeButton!!.classes.add(ElementClass("randomize-strong"))
randomizeButton?.classes?.add(ElementClass("randomize-strong"))
}
}
program.keyboard.keyUp.listen {
if (it.key == KEY_LEFT_SHIFT) {
shiftDown = false
randomizeButton!!.classes.remove(ElementClass("randomize-strong"))
randomizeButton?.classes?.remove(ElementClass("randomize-strong"))
}
}
@@ -247,12 +254,14 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
this.height = (appearance.barWidth - 25).px
}
descendant(has type listOf(
descendant(
has type listOf(
"sequence-editor",
"sliders-vector2",
"sliders-vector3",
"sliders-vector4"
)) {
)
) {
this.width = (appearance.barWidth - 25).px
this.height = 100.px
}
@@ -275,7 +284,9 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
div("fullscreen") {
div("container") {
id = "container"
@Suppress("UNUSED_VARIABLE") val header = div("toolbar") {
if (showToolbar) {
@Suppress("UNUSED_VARIABLE")
val header = div("toolbar") {
randomizeButton = button {
label = "Randomize"
clicked {
@@ -285,7 +296,10 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
button {
label = "Load"
clicked {
openFileDialog(supportedExtensions = listOf("json"), contextID = "gui.parameters") {
openFileDialog(
supportedExtensions = listOf("json"),
contextID = "gui.parameters"
) {
loadParameters(it)
}
}
@@ -299,7 +313,10 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
val local = File(".")
val parameters = File(local, defaultSaveFolder)
if (parameters.exists() && parameters.isDirectory) {
setDefaultPathForContext(contextID = "gui.parameters", file = parameters)
setDefaultPathForContext(
contextID = "gui.parameters",
file = parameters
)
} else {
if (parameters.mkdirs()) {
setDefaultPathForContext(
@@ -322,6 +339,7 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
}
}
}
}
val collapseBorder = div("collapse-border") {
}
@@ -426,26 +444,45 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
range = Range(parameter.intRange!!.first.toDouble(), parameter.intRange!!.last.toDouble())
precision = 0
events.valueChanged.listen {
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, Int>, obj, it.newValue.toInt())
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 {
getPersistedOrDefault(
compartment.label,
parameter.property as KMutableProperty1<Any, Int>,
obj
)?.let {
value = it.toDouble()
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, Int>, obj, it)
}
}
}
ParameterType.Double -> {
slider {
label = parameter.label
range = Range(parameter.doubleRange!!.start, parameter.doubleRange!!.endInclusive)
precision = parameter.precision!!
events.valueChanged.listen {
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, Double>, obj, it.newValue)
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 {
getPersistedOrDefault(
compartment.label,
parameter.property as KMutableProperty1<Any, Double>,
obj
)?.let {
value = it
/* this is generally not needed, but when the persisted value is equal to the slider default
it will not emit the newly set value */
@@ -453,6 +490,7 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
}
}
}
ParameterType.Action -> {
button {
label = parameter.label
@@ -463,32 +501,53 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
}
}
}
ParameterType.Boolean -> {
toggle {
label = parameter.label
events.valueChanged.listen {
value = it.newValue
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, Boolean>, obj, it.newValue)
setAndPersist(
compartment.label,
parameter.property as KMutableProperty1<Any, Boolean>,
obj,
it.newValue
)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
getPersistedOrDefault(compartment.label, parameter.property as KMutableProperty1<Any, Boolean>, obj)?.let {
getPersistedOrDefault(
compartment.label,
parameter.property as KMutableProperty1<Any, Boolean>,
obj
)?.let {
value = it
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, Boolean>, obj, it)
}
}
}
ParameterType.Text -> {
textfield {
label = parameter.label
events.valueChanged.listen {
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, String>, obj, it.newValue)
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 {
getPersistedOrDefault(
compartment.label,
parameter.property as KMutableProperty1<Any, String>,
obj
)?.let {
value = it
}
}
}
ParameterType.Color -> {
colorpickerButton {
label = parameter.label
@@ -557,7 +616,12 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
obj
)?.let {
value = it
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, MutableList<Double>>, obj, it)
setAndPersist(
compartment.label,
parameter.property as KMutableProperty1<Any, MutableList<Double>>,
obj,
it
)
}
}
}
@@ -573,7 +637,8 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
compartment.label,
parameter.property as KMutableProperty1<Any, Vector2>,
obj,
it.newValue)
it.newValue
)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
@@ -599,7 +664,8 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
compartment.label,
parameter.property as KMutableProperty1<Any, Vector3>,
obj,
it.newValue)
it.newValue
)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
@@ -625,7 +691,8 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
compartment.label,
parameter.property as KMutableProperty1<Any, Vector4>,
obj,
it.newValue)
it.newValue
)
onChangeListener?.invoke(parameter.property!!.name, it.newValue)
}
@@ -639,6 +706,7 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
}
}
}
ParameterType.Option -> {
dropdownButton {
val enumProperty = parameter.property as KMutableProperty1<Any, Enum<*>>
@@ -670,7 +738,12 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
)?.let { enum ->
(this@dropdownButton).value = items().find { item -> item.data == enum }
?: error("no matching item found")
setAndPersist(compartment.label, parameter.property as KMutableProperty1<Any, Enum<*>>, obj, enum)
setAndPersist(
compartment.label,
parameter.property as KMutableProperty1<Any, Enum<*>>,
obj,
enum
)
}
}
}
@@ -688,7 +761,8 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
}
}
class ParameterValue(var doubleValue: Double? = null,
class ParameterValue(
var doubleValue: Double? = null,
var intValue: Int? = null,
var booleanValue: Boolean? = null,
var colorValue: ColorRGBa? = null,
@@ -715,7 +789,8 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
return trackedObjects.entries.associate { (lo, b) ->
Pair(lo.label, b.parameterControls.keys.associate { k ->
Pair(k.property?.name ?: k.function?.name
Pair(
k.property?.name ?: k.function?.name
?: error("no name"), when (k.parameterType) {
/* 3) setup serializers */
ParameterType.Double -> ParameterValue(
@@ -729,13 +804,16 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
minValue = k.intRange?.start?.toDouble(),
maxValue = k.intRange?.endInclusive?.toDouble()
)
ParameterType.Action -> ParameterValue()
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(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>,
minValue = k.doubleRange?.start,
maxValue = k.doubleRange?.endInclusive
)
@@ -745,18 +823,22 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
minValue = k.doubleRange?.start,
maxValue = k.doubleRange?.endInclusive
)
ParameterType.Vector3 -> ParameterValue(
vector3Value = k.property.qget(lo.obj) as Vector3,
minValue = k.doubleRange?.start,
maxValue = k.doubleRange?.endInclusive
)
ParameterType.Vector4 -> ParameterValue(
vector4Value = k.property.qget(lo.obj) as Vector4,
minValue = k.doubleRange?.start,
maxValue = k.doubleRange?.endInclusive
)
ParameterType.Option -> ParameterValue(optionValue = (k.property.qget(lo.obj) as Enum<*>).name)
})
}
)
})
}
}
@@ -794,36 +876,47 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
ParameterType.Double -> parameterValue.doubleValue?.let {
parameter.property.qset(lo.obj, it)
}
ParameterType.Int -> parameterValue.intValue?.let {
parameter.property.qset(lo.obj, it)
}
ParameterType.Text -> parameterValue.textValue?.let {
parameter.property.qset(lo.obj, it)
}
ParameterType.Color -> parameterValue.colorValue?.let {
parameter.property.qset(lo.obj, it)
}
ParameterType.XY -> parameterValue.vector2Value?.let {
parameter.property.qset(lo.obj, it)
}
ParameterType.DoubleList -> parameterValue.doubleListValue?.let {
parameter.property.qset(lo.obj, it)
}
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.Option -> parameterValue.optionValue?.let {
parameter.property.enumSet(lo.obj, it)
}
ParameterType.Action -> {
// intentionally do nothing
}
@@ -847,39 +940,62 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
when (parameter.parameterType) {
/* 5) Update control from property value */
ParameterType.Double -> {
(control as Slider).value = (parameter.property as KMutableProperty1<Any, Double>).get(labeledObject.obj)
(control as Slider).value =
(parameter.property as KMutableProperty1<Any, Double>).get(labeledObject.obj)
}
ParameterType.Int -> {
(control as Slider).value = (parameter.property as KMutableProperty1<Any, Int>).get(labeledObject.obj).toDouble()
(control as Slider).value =
(parameter.property as KMutableProperty1<Any, Int>).get(labeledObject.obj).toDouble()
}
ParameterType.Text -> {
(control as Textfield).value = (parameter.property as KMutableProperty1<Any, String>).get(labeledObject.obj)
(control as Textfield).value =
(parameter.property as KMutableProperty1<Any, String>).get(labeledObject.obj)
}
ParameterType.Color -> {
(control as ColorpickerButton).color = (parameter.property as KMutableProperty1<Any, ColorRGBa>).get(labeledObject.obj)
(control as ColorpickerButton).color =
(parameter.property as KMutableProperty1<Any, ColorRGBa>).get(labeledObject.obj)
}
ParameterType.XY -> {
(control as XYPad).value = (parameter.property as KMutableProperty1<Any, Vector2>).get(labeledObject.obj)
(control as XYPad).value =
(parameter.property as KMutableProperty1<Any, Vector2>).get(labeledObject.obj)
}
ParameterType.DoubleList -> {
(control as SequenceEditor).value = (parameter.property as KMutableProperty1<Any, MutableList<Double>>).get(labeledObject.obj)
(control as SequenceEditor).value =
(parameter.property as KMutableProperty1<Any, MutableList<Double>>).get(labeledObject.obj)
}
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)
(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)
(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)
(control as SlidersVector4).value =
(parameter.property as KMutableProperty1<Any, Vector4>).get(labeledObject.obj)
}
ParameterType.Option -> {
val ddb = control as DropdownButton
ddb.value = ddb.items().find { item -> item.data == (parameter.property as KMutableProperty1<Any, Enum<*>>).get(labeledObject.obj) } ?: error("could not find item")
ddb.value = ddb.items().find { item ->
item.data == (parameter.property as KMutableProperty1<Any, Enum<*>>).get(labeledObject.obj)
} ?: error("could not find item")
}
ParameterType.Action -> {
// intentionally do nothing
}
@@ -900,6 +1016,7 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
val newValue = mix(currentValue, randomValue, strength)
(parameter.property as KMutableProperty1<Any, Double>).set(labeledObject.obj, newValue)
}
ParameterType.Int -> {
val min = parameter.intRange!!.first
val max = parameter.intRange!!.last
@@ -908,48 +1025,61 @@ class GUI(val appearance: GUIAppearance = GUIAppearance(),
val newValue = mix(currentValue.toDouble(), randomValue, strength).roundToInt()
(parameter.property as KMutableProperty1<Any, Int>).set(labeledObject.obj, newValue)
}
ParameterType.Boolean -> {
//I am not sure about randomizing boolean values here
//(parameter.property as KMutableProperty1<Any, Boolean>).set(labeledObject.obj, (Math.random() < 0.5))
}
ParameterType.Color -> {
val currentValue = (parameter.property as KMutableProperty1<Any, ColorRGBa>).get(labeledObject.obj)
val randomValue = ColorRGBa.fromVector(Random.vector3(0.0, 1.0), currentValue.alpha, currentValue.linearity)
val currentValue =
(parameter.property as KMutableProperty1<Any, ColorRGBa>).get(labeledObject.obj)
val randomValue =
ColorRGBa.fromVector(Random.vector3(0.0, 1.0), currentValue.alpha, currentValue.linearity)
val newValue = currentValue.mix(randomValue, strength)
(parameter.property as KMutableProperty1<Any, ColorRGBa>).set(labeledObject.obj, newValue)
}
ParameterType.Vector2 -> {
val min = parameter.doubleRange!!.start
val max = parameter.doubleRange!!.endInclusive
val currentValue = (parameter.property as KMutableProperty1<Any, Vector2>).get(labeledObject.obj)
val currentValue =
(parameter.property as KMutableProperty1<Any, Vector2>).get(labeledObject.obj)
val randomValue = Random.vector2(min, max)
val newValue = currentValue.mix(randomValue, strength)
(parameter.property as KMutableProperty1<Any, Vector2>).set(labeledObject.obj, newValue)
}
ParameterType.XY -> {
val min = parameter.vectorRange!!.first
val max = parameter.vectorRange!!.second
val currentValue = (parameter.property as KMutableProperty1<Any, Vector2>).get(labeledObject.obj)
val currentValue =
(parameter.property as KMutableProperty1<Any, Vector2>).get(labeledObject.obj)
val randomValue = Vector2.uniform(min, max)
val newValue = currentValue.mix(randomValue, strength)
(parameter.property as KMutableProperty1<Any, Vector2>).set(labeledObject.obj, newValue)
}
ParameterType.Vector3 -> {
val min = parameter.doubleRange!!.start
val max = parameter.doubleRange!!.endInclusive
val currentValue = (parameter.property as KMutableProperty1<Any, Vector3>).get(labeledObject.obj)
val currentValue =
(parameter.property as KMutableProperty1<Any, Vector3>).get(labeledObject.obj)
val randomValue = Random.vector3(min, max)
val newValue = currentValue.mix(randomValue, strength)
(parameter.property as KMutableProperty1<Any, Vector3>).set(labeledObject.obj, newValue)
}
ParameterType.Vector4 -> {
val min = parameter.doubleRange!!.start
val max = parameter.doubleRange!!.endInclusive
val currentValue = (parameter.property as KMutableProperty1<Any, Vector4>).get(labeledObject.obj)
val currentValue =
(parameter.property as KMutableProperty1<Any, Vector4>).get(labeledObject.obj)
val randomValue = Random.vector4(min, max)
val newValue = currentValue.mix(randomValue, strength)
(parameter.property as KMutableProperty1<Any, Vector4>).set(labeledObject.obj, newValue)
}
else -> {
// intentionally do nothing
}