Fix bind functions, add WatchDiv
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
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)
|
||||
@@ -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 {
|
||||
@@ -119,3 +123,30 @@ class ColorpickerButton : Element(ElementType("colorpicker-button")) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun ColorpickerButton.bind(property: KMutableProperty0<ColorRGBa>) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <E : Enum<E>> DropdownButton.bind(property: KMutableProperty0<E>, map: Map<E
|
||||
draw.dirty = true
|
||||
|
||||
(root() as? Body)?.controlManager?.program?.launch {
|
||||
while (true) {
|
||||
while (!disposed) {
|
||||
val cval = property.get()
|
||||
if (cval != currentValue) {
|
||||
currentValue = cval
|
||||
|
||||
@@ -25,6 +25,14 @@ val disabled = ElementPseudoClass("disabled")
|
||||
|
||||
class FocusEvent
|
||||
|
||||
interface DisposableElement {
|
||||
var disposed : Boolean
|
||||
|
||||
fun dispose() {
|
||||
disposed = true
|
||||
}
|
||||
}
|
||||
|
||||
open class Element(val type: ElementType) {
|
||||
|
||||
var scrollTop = 0.0
|
||||
|
||||
@@ -45,7 +45,8 @@ class SequenceEditor : SequenceEditorBase("sequence-editor") {
|
||||
}
|
||||
}
|
||||
|
||||
open class SequenceEditorBase(type: String = "sequence-editor-base") : Element(ElementType(type)) {
|
||||
open class SequenceEditorBase(type: String = "sequence-editor-base") : Element(ElementType(type)), DisposableElement {
|
||||
override var disposed = false
|
||||
|
||||
internal var baseValue = mutableListOf(0.0)
|
||||
var label = "sequence"
|
||||
|
||||
@@ -23,7 +23,8 @@ data class Range(val min: Double, val max: Double) {
|
||||
val span: Double get() = max - min
|
||||
}
|
||||
|
||||
class Slider : Element(ElementType("slider")) {
|
||||
class Slider : Element(ElementType("slider")), DisposableElement {
|
||||
override var disposed = false
|
||||
|
||||
override val handlesKeyboardFocus = true
|
||||
|
||||
@@ -243,13 +244,19 @@ fun Slider.bind(property: KMutableProperty0<Double>) {
|
||||
if (root() as? Body == null) {
|
||||
throw RuntimeException("no body")
|
||||
}
|
||||
(root() as? Body)?.controlManager?.program?.launch {
|
||||
while (true) {
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -258,7 +265,6 @@ fun Slider.bind(property: KMutableProperty0<Double>) {
|
||||
@JvmName("bindInt")
|
||||
fun Slider.bind(property: KMutableProperty0<Int>) {
|
||||
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<Int>) {
|
||||
if (root() as? Body == null) {
|
||||
throw RuntimeException("no body")
|
||||
}
|
||||
(root() as? Body)?.controlManager?.program?.launch {
|
||||
while (true) {
|
||||
if (property.get()!= currentValue) {
|
||||
fun update() {
|
||||
if (property.get() != currentValue) {
|
||||
val lcur = property.get()
|
||||
currentValue = lcur
|
||||
value = lcur.toDouble()
|
||||
}
|
||||
}
|
||||
update()
|
||||
(root() as? Body)?.controlManager?.program?.launch {
|
||||
while (!disposed) {
|
||||
update()
|
||||
yield()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Vector2>) {
|
||||
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<Vector3>) {
|
||||
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<Vector4>) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,13 +86,18 @@ fun TextElement.bind(property: KMutableProperty0<String>) {
|
||||
if (root() as? Body == null) {
|
||||
throw RuntimeException("no body")
|
||||
}
|
||||
(root() as? Body)?.controlManager?.program?.launch {
|
||||
var lastText = ""
|
||||
while (true) {
|
||||
fun update() {
|
||||
if (property.get() != lastText) {
|
||||
replaceText(property.get())
|
||||
lastText = property.get()
|
||||
}
|
||||
}
|
||||
|
||||
(root() as? Body)?.controlManager?.program?.launch {
|
||||
update()
|
||||
while (true) {
|
||||
update()
|
||||
yield()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,14 +142,17 @@ fun Textfield.bind(property: KMutableProperty0<String>) {
|
||||
currentValue = it.newValue
|
||||
property.set(it.newValue)
|
||||
}
|
||||
|
||||
(root() as Body).controlManager.program.launch {
|
||||
while (true) {
|
||||
fun update() {
|
||||
val cval = property.get()
|
||||
if (cval != currentValue) {
|
||||
currentValue = cval
|
||||
value = cval
|
||||
}
|
||||
}
|
||||
update()
|
||||
(root() as Body).controlManager.program.launch {
|
||||
while (true) {
|
||||
update()
|
||||
yield()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Boolean>) {
|
||||
}
|
||||
|
||||
(root() as Body).controlManager.program.launch {
|
||||
while (true) {
|
||||
while (!disposed) {
|
||||
val cval = property.get()
|
||||
if (cval != currentValue) {
|
||||
currentValue = cval
|
||||
|
||||
@@ -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<T : Any>(val watchList: List<T>, val builder: WatchDiv<T>.(T) -> Unit) : Div(), DisposableElement {
|
||||
override var disposed: Boolean = false
|
||||
var listState = emptyList<T>()
|
||||
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 <T : Any> Element.watchDiv(vararg classes: String, watchList: List<T>, builder: WatchDiv<T>.(T) -> Unit) {
|
||||
val wd = WatchDiv(watchList, builder)
|
||||
wd.classes.addAll(classes.map { ElementClass(it) })
|
||||
this.append(wd)
|
||||
}
|
||||
@@ -230,19 +230,22 @@ fun XYPad.bind(property: KMutableProperty0<Vector2>) {
|
||||
if (root() as? Body == null) {
|
||||
throw RuntimeException("no body")
|
||||
}
|
||||
(root() as? Body)?.controlManager?.program?.launch {
|
||||
while (true) {
|
||||
fun update() {
|
||||
if (property.get() != currentValue) {
|
||||
val lcur = property.get()
|
||||
currentValue = lcur
|
||||
value = lcur
|
||||
}
|
||||
}
|
||||
update()
|
||||
(root() as? Body)?.controlManager?.program?.launch {
|
||||
while (true) {
|
||||
update()
|
||||
yield()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun Double.round(decimals: Int): Double {
|
||||
var multiplier = 1.0
|
||||
repeat(decimals) { multiplier *= 10 }
|
||||
|
||||
Reference in New Issue
Block a user