Add WatchDiv demo
This commit is contained in:
@@ -10,6 +10,8 @@ sourceSets {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
demoImplementation("org.openrndr:openrndr-extensions:$openrndrVersion")
|
demoImplementation("org.openrndr:openrndr-extensions:$openrndrVersion")
|
||||||
|
demoImplementation("org.openrndr:openrndr-dialogs:$openrndrVersion")
|
||||||
|
demoImplementation("com.google.code.gson:gson:$gsonVersion")
|
||||||
demoRuntimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion")
|
demoRuntimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion")
|
||||||
demoRuntimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion")
|
demoRuntimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion")
|
||||||
demoImplementation(sourceSets.getByName("main").output)
|
demoImplementation(sourceSets.getByName("main").output)
|
||||||
|
|||||||
123
orx-panel/src/demo/kotlin/DemoWatchDiv01.kt
Normal file
123
orx-panel/src/demo/kotlin/DemoWatchDiv01.kt
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
import com.google.gson.Gson
|
||||||
|
import org.openrndr.application
|
||||||
|
import org.openrndr.dialogs.openFileDialog
|
||||||
|
import org.openrndr.dialogs.saveFileDialog
|
||||||
|
import org.openrndr.panel.controlManager
|
||||||
|
import org.openrndr.panel.elements.*
|
||||||
|
import org.openrndr.panel.style.*
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
// -- these have to be top-level classes or Gson will silently fail.
|
||||||
|
private class ConfigItem {
|
||||||
|
var value: Double = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProgramState {
|
||||||
|
var rows = 1
|
||||||
|
var columns = 1
|
||||||
|
val matrix = mutableListOf(mutableListOf(ConfigItem()))
|
||||||
|
|
||||||
|
fun copyTo(programState: ProgramState) {
|
||||||
|
programState.rows = rows
|
||||||
|
programState.columns = columns
|
||||||
|
programState.matrix.clear()
|
||||||
|
programState.matrix.addAll(matrix)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun save(file: File) {
|
||||||
|
file.writeText(Gson().toJson(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load(file: File) {
|
||||||
|
Gson().fromJson(file.readText(), ProgramState::class.java).copyTo(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() = application {
|
||||||
|
configure {
|
||||||
|
width = 900
|
||||||
|
height = 720
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
val programState = ProgramState()
|
||||||
|
val cm = controlManager {
|
||||||
|
layout {
|
||||||
|
styleSheet(has class_ "matrix") {
|
||||||
|
this.width = 100.percent
|
||||||
|
}
|
||||||
|
|
||||||
|
styleSheet(has class_ "row") {
|
||||||
|
this.display = Display.FLEX
|
||||||
|
this.flexDirection = FlexDirection.Row
|
||||||
|
this.width = 100.percent
|
||||||
|
|
||||||
|
child(has type "slider") {
|
||||||
|
this.width = 80.px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
label = "save"
|
||||||
|
clicked {
|
||||||
|
saveFileDialog(supportedExtensions = listOf("json")) {
|
||||||
|
programState.save(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
label = "load"
|
||||||
|
clicked {
|
||||||
|
openFileDialog(supportedExtensions = listOf("json")) {
|
||||||
|
programState.load(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slider {
|
||||||
|
label = "rows"
|
||||||
|
precision = 0
|
||||||
|
bind(programState::rows)
|
||||||
|
|
||||||
|
events.valueChanged.listen {
|
||||||
|
while (programState.matrix.size > programState.rows) {
|
||||||
|
programState.matrix.removeAt(programState.matrix.size - 1)
|
||||||
|
}
|
||||||
|
while (programState.matrix.size < programState.rows) {
|
||||||
|
programState.matrix.add(MutableList(programState.columns) { ConfigItem() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slider {
|
||||||
|
label = "columns"
|
||||||
|
precision = 0
|
||||||
|
bind(programState::columns)
|
||||||
|
events.valueChanged.listen {
|
||||||
|
for (row in programState.matrix) {
|
||||||
|
while (row.size > programState.columns) {
|
||||||
|
row.removeAt(row.size - 1)
|
||||||
|
}
|
||||||
|
while (row.size < programState.columns) {
|
||||||
|
row.add(ConfigItem())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watchDiv("matrix", watchList = programState.matrix) { row ->
|
||||||
|
watchDiv("row", watchList = row) { item ->
|
||||||
|
this.id = "some-row"
|
||||||
|
slider {
|
||||||
|
label = "value"
|
||||||
|
bind(item::value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extend(cm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -5,12 +5,13 @@ import kotlinx.coroutines.yield
|
|||||||
import org.openrndr.draw.Drawer
|
import org.openrndr.draw.Drawer
|
||||||
import org.openrndr.launch
|
import org.openrndr.launch
|
||||||
|
|
||||||
class WatchDiv<T : Any>(val watchList: List<T>, val builder: WatchDiv<T>.(T) -> Unit) : Div(), DisposableElement {
|
class WatchDiv<T : Any>(private val watchList: List<T>, private val builder: WatchDiv<T>.(T) -> Unit) : Div(), DisposableElement {
|
||||||
override var disposed: Boolean = false
|
override var disposed: Boolean = false
|
||||||
var listState = emptyList<T>()
|
private var listState = emptyList<T>()
|
||||||
var watchJob : Job? = null
|
private var watchJob: Job? = null
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
|
super.dispose()
|
||||||
for (child in children) {
|
for (child in children) {
|
||||||
child.parent = null
|
child.parent = null
|
||||||
(child as? DisposableElement)?.dispose()
|
(child as? DisposableElement)?.dispose()
|
||||||
@@ -18,7 +19,7 @@ class WatchDiv<T : Any>(val watchList: List<T>, val builder: WatchDiv<T>.(T) ->
|
|||||||
children.clear()
|
children.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun regenerate() {
|
fun regenerate() {
|
||||||
var regenerate = false
|
var regenerate = false
|
||||||
if (listState.size != watchList.size) {
|
if (listState.size != watchList.size) {
|
||||||
regenerate = true
|
regenerate = true
|
||||||
@@ -45,7 +46,7 @@ class WatchDiv<T : Any>(val watchList: List<T>, val builder: WatchDiv<T>.(T) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun draw(drawer: Drawer) {
|
fun checkJob() {
|
||||||
if (watchJob == null) {
|
if (watchJob == null) {
|
||||||
watchJob = (root() as Body).controlManager.program.launch {
|
watchJob = (root() as Body).controlManager.program.launch {
|
||||||
while (!disposed) {
|
while (!disposed) {
|
||||||
@@ -54,6 +55,9 @@ class WatchDiv<T : Any>(val watchList: List<T>, val builder: WatchDiv<T>.(T) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
override fun draw(drawer: Drawer) {
|
||||||
|
checkJob()
|
||||||
super.draw(drawer)
|
super.draw(drawer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,4 +66,6 @@ fun <T : Any> Element.watchDiv(vararg classes: String, watchList: List<T>, build
|
|||||||
val wd = WatchDiv(watchList, builder)
|
val wd = WatchDiv(watchList, builder)
|
||||||
wd.classes.addAll(classes.map { ElementClass(it) })
|
wd.classes.addAll(classes.map { ElementClass(it) })
|
||||||
this.append(wd)
|
this.append(wd)
|
||||||
|
wd.regenerate()
|
||||||
|
wd.checkJob()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user