Fix bind functions, add WatchDiv

This commit is contained in:
Edwin Jakobs
2020-05-07 21:06:47 +02:00
parent 6a0455cfaf
commit 43edd55d68
11 changed files with 252 additions and 43 deletions

View File

@@ -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 {
@@ -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()
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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")
}
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<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")
}
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()
}
}

View File

@@ -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()
}
}
}

View File

@@ -86,13 +86,18 @@ fun TextElement.bind(property: KMutableProperty0<String>) {
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()
}
}

View File

@@ -142,14 +142,17 @@ fun Textfield.bind(property: KMutableProperty0<String>) {
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()
}
}

View File

@@ -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

View File

@@ -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)
}

View File

@@ -230,19 +230,22 @@ fun XYPad.bind(property: KMutableProperty0<Vector2>) {
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 }