diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/ColorpickerButton.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/ColorpickerButton.kt index 754fb3d8..a2cf8285 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/ColorpickerButton.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/ColorpickerButton.kt @@ -1,22 +1,26 @@ package org.openrndr.panel.elements +import kotlinx.coroutines.yield import org.openrndr.color.ColorRGBa import org.openrndr.draw.Drawer import org.openrndr.draw.LineCap import org.openrndr.events.Event +import org.openrndr.launch import org.openrndr.panel.style.* import org.openrndr.text.Writer +import kotlin.reflect.KMutableProperty0 -class ColorpickerButton : Element(ElementType("colorpicker-button")) { +class ColorpickerButton : Element(ElementType("colorpicker-button")), DisposableElement { + override var disposed: Boolean = false var label: String = "OK" var color: ColorRGBa = ColorRGBa(0.5, 0.5, 0.5) - set(value) { - if (value != field) { - field = value - events.valueChanged.trigger(ColorChangedEvent(this, value)) - } + set(value) { + if (value != field) { + field = value + events.valueChanged.trigger(ColorChangedEvent(this, value)) } + } class ColorChangedEvent(val source: ColorpickerButton, val color: ColorRGBa) @@ -79,7 +83,7 @@ class ColorpickerButton : Element(ElementType("colorpicker-button")) { } } - class SlideOut(val x: Double, val y: Double, val width: Double, val height: Double, color:ColorRGBa, parent: Element) : Element(ElementType("slide-out")) { + class SlideOut(val x: Double, val y: Double, val width: Double, val height: Double, color: ColorRGBa, parent: Element) : Element(ElementType("slide-out")) { init { style = StyleSheet(CompoundSelector.DUMMY).apply { @@ -118,4 +122,31 @@ class ColorpickerButton : Element(ElementType("colorpicker-button")) { parent?.remove(this) } } +} + +fun ColorpickerButton.bind(property: KMutableProperty0) { + var currentValue: ColorRGBa? = null + + events.valueChanged.listen { + currentValue = color + property.set(it.color) + } + if (root() as? Body == null) { + throw RuntimeException("no body") + } + + fun update() { + if (property.get() != currentValue) { + val lcur = property.get() + currentValue = lcur + color = lcur + } + } + update() + (root() as? Body)?.controlManager?.program?.launch { + while (!disposed) { + update() + yield() + } + } } \ No newline at end of file diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/DropdownButton.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/DropdownButton.kt index 766b879e..73f8f770 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/DropdownButton.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/DropdownButton.kt @@ -32,7 +32,8 @@ class Item : Element(ElementType("item")) { } } -class DropdownButton : Element(ElementType("dropdown-button")) { +class DropdownButton : Element(ElementType("dropdown-button")), DisposableElement { + override var disposed = false var label: String = "OK" var value: Item? = null @@ -268,7 +269,7 @@ fun > DropdownButton.bind(property: KMutableProperty0, map: Map) { if (root() as? Body == null) { throw RuntimeException("no body") } + + fun update() { + if (property.get() != currentValue) { + val lcur = property.get() + currentValue = lcur + value = lcur + } + } + update() + (root() as? Body)?.controlManager?.program?.launch { - while (true) { - if (property.get() != currentValue) { - val lcur = property.get() - currentValue = lcur - value = lcur - } + while (!disposed) { + update() yield() } } @@ -258,7 +265,6 @@ fun Slider.bind(property: KMutableProperty0) { @JvmName("bindInt") fun Slider.bind(property: KMutableProperty0) { var currentValue: Int? = null - events.valueChanged.listen { currentValue = it.newValue.toInt() property.set(it.newValue.toInt()) @@ -266,13 +272,17 @@ fun Slider.bind(property: KMutableProperty0) { if (root() as? Body == null) { throw RuntimeException("no body") } + fun update() { + if (property.get() != currentValue) { + val lcur = property.get() + currentValue = lcur + value = lcur.toDouble() + } + } + update() (root() as? Body)?.controlManager?.program?.launch { - while (true) { - if (property.get()!= currentValue) { - val lcur = property.get() - currentValue = lcur - value = lcur.toDouble() - } + while (!disposed) { + update() yield() } } 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 index df0b18b6..76529e55 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SlidersVector.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/SlidersVector.kt @@ -1,9 +1,13 @@ package org.openrndr.panel.elements +import kotlinx.coroutines.yield +import org.openrndr.color.ColorRGBa import org.openrndr.events.Event +import org.openrndr.launch import org.openrndr.math.Vector2 import org.openrndr.math.Vector3 import org.openrndr.math.Vector4 +import kotlin.reflect.KMutableProperty0 class SlidersVector2 : SequenceEditorBase("sliders-vector2") { var value : Vector2 @@ -39,6 +43,31 @@ class SlidersVector2 : SequenceEditorBase("sliders-vector2") { } } +fun SlidersVector2.bind(property: KMutableProperty0) { + var currentValue: Vector2? = null + + events.valueChanged.listen { + currentValue = value + property.set(it.newValue) + } + if (root() as? Body == null) { + throw RuntimeException("no body") + } + fun update() { + if (property.get() != currentValue) { + val lcur = property.get() + currentValue = lcur + value = lcur + } + } + update() + (root() as? Body)?.controlManager?.program?.launch { + while (!disposed) { + update() + yield() + } + } +} class SlidersVector3 : SequenceEditorBase("sliders-vector3") { var value : Vector3 @@ -75,6 +104,32 @@ class SlidersVector3 : SequenceEditorBase("sliders-vector3") { } } +fun SlidersVector3.bind(property: KMutableProperty0) { + var currentValue: Vector3? = null + + events.valueChanged.listen { + currentValue = value + property.set(it.newValue) + } + if (root() as? Body == null) { + throw RuntimeException("no body") + } + fun update() { + if (property.get() != currentValue) { + val lcur = property.get() + currentValue = lcur + value = lcur + } + } + update() + (root() as? Body)?.controlManager?.program?.launch { + while (!disposed) { + update() + yield() + } + } +} + class SlidersVector4 : SequenceEditorBase("sliders-vector4") { var value : Vector4 get() { @@ -111,3 +166,28 @@ class SlidersVector4 : SequenceEditorBase("sliders-vector4") { } } +fun SlidersVector4.bind(property: KMutableProperty0) { + var currentValue: Vector4? = null + + events.valueChanged.listen { + currentValue = value + property.set(it.newValue) + } + if (root() as? Body == null) { + throw RuntimeException("no body") + } + fun update() { + if (property.get() != currentValue) { + val lcur = property.get() + currentValue = lcur + value = lcur + } + } + update() + (root() as? Body)?.controlManager?.program?.launch { + while (!disposed) { + update() + yield() + } + } +} \ No newline at end of file diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/TextElements.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/TextElements.kt index 67830cc0..7ef382fe 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/TextElements.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/TextElements.kt @@ -86,13 +86,18 @@ fun TextElement.bind(property: KMutableProperty0) { if (root() as? Body == null) { throw RuntimeException("no body") } + var lastText = "" + fun update() { + if (property.get() != lastText) { + replaceText(property.get()) + lastText = property.get() + } + } + (root() as? Body)?.controlManager?.program?.launch { - var lastText = "" + update() while (true) { - if (property.get() != lastText) { - replaceText(property.get()) - lastText = property.get() - } + update() yield() } } diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/Textfield.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/Textfield.kt index 29fd8d34..4fe2b0ba 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/Textfield.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/Textfield.kt @@ -142,14 +142,17 @@ fun Textfield.bind(property: KMutableProperty0) { currentValue = it.newValue property.set(it.newValue) } - + fun update() { + val cval = property.get() + if (cval != currentValue) { + currentValue = cval + value = cval + } + } + update() (root() as Body).controlManager.program.launch { while (true) { - val cval = property.get() - if (cval != currentValue) { - currentValue = cval - value = cval - } + update() yield() } } diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/Toggle.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/Toggle.kt index 4305724a..ad7dec8f 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/Toggle.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/Toggle.kt @@ -12,7 +12,9 @@ import org.openrndr.events.Event import org.openrndr.launch import kotlin.reflect.KMutableProperty0 -class Toggle : Element(ElementType("toggle")) { +class Toggle : Element(ElementType("toggle")), DisposableElement { + override var disposed = false + var label = "" var value = false @@ -106,7 +108,7 @@ fun Toggle.bind(property: KMutableProperty0) { } (root() as Body).controlManager.program.launch { - while (true) { + while (!disposed) { val cval = property.get() if (cval != currentValue) { currentValue = cval diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/WatchDiv.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/WatchDiv.kt new file mode 100644 index 00000000..87dea7a3 --- /dev/null +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/WatchDiv.kt @@ -0,0 +1,65 @@ +package org.openrndr.panel.elements + +import kotlinx.coroutines.Job +import kotlinx.coroutines.yield +import org.openrndr.draw.Drawer +import org.openrndr.launch + +class WatchDiv(val watchList: List, val builder: WatchDiv.(T) -> Unit) : Div(), DisposableElement { + override var disposed: Boolean = false + var listState = emptyList() + var watchJob : Job? = null + + override fun dispose() { + for (child in children) { + child.parent = null + (child as? DisposableElement)?.dispose() + } + children.clear() + } + + private fun regenerate() { + var regenerate = false + if (listState.size != watchList.size) { + regenerate = true + } + if (!regenerate) { + for (i in watchList.indices) { + if (watchList[i] !== listState[i]) { + regenerate = true + break + } + } + } + if (regenerate) { + for (child in children) { + child.parent = null + (child as? DisposableElement)?.dispose() + } + children.clear() + listState = watchList.map { it } + for (i in watchList) { + builder(i) + } + requestRedraw() + } + } + + override fun draw(drawer: Drawer) { + if (watchJob == null) { + watchJob = (root() as Body).controlManager.program.launch { + while (!disposed) { + regenerate() + yield() + } + } + } + super.draw(drawer) + } +} + +fun Element.watchDiv(vararg classes: String, watchList: List, builder: WatchDiv.(T) -> Unit) { + val wd = WatchDiv(watchList, builder) + wd.classes.addAll(classes.map { ElementClass(it) }) + this.append(wd) +} diff --git a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/XYPad.kt b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/XYPad.kt index a94b8ae9..a1ba22de 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/XYPad.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/XYPad.kt @@ -230,19 +230,22 @@ fun XYPad.bind(property: KMutableProperty0) { if (root() as? Body == null) { throw RuntimeException("no body") } + fun update() { + if (property.get() != currentValue) { + val lcur = property.get() + currentValue = lcur + value = lcur + } + } + update() (root() as? Body)?.controlManager?.program?.launch { while (true) { - if (property.get() != currentValue) { - val lcur = property.get() - currentValue = lcur - value = lcur - } + update() yield() } } } - fun Double.round(decimals: Int): Double { var multiplier = 1.0 repeat(decimals) { multiplier *= 10 }