From 2dc7fb1b75da857737d652915b4ab59b6b951527 Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Fri, 8 May 2020 11:03:44 +0200 Subject: [PATCH] Add WatchDiv demo --- orx-panel/build.gradle | 2 + orx-panel/src/demo/kotlin/DemoWatchDiv01.kt | 123 ++++++++++++++++++ .../org/openrndr/panel/elements/WatchDiv.kt | 16 ++- 3 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 orx-panel/src/demo/kotlin/DemoWatchDiv01.kt diff --git a/orx-panel/build.gradle b/orx-panel/build.gradle index 231e348e..ece0f363 100644 --- a/orx-panel/build.gradle +++ b/orx-panel/build.gradle @@ -10,6 +10,8 @@ sourceSets { dependencies { 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-natives-$openrndrOS:$openrndrVersion") demoImplementation(sourceSets.getByName("main").output) diff --git a/orx-panel/src/demo/kotlin/DemoWatchDiv01.kt b/orx-panel/src/demo/kotlin/DemoWatchDiv01.kt new file mode 100644 index 00000000..a1832f19 --- /dev/null +++ b/orx-panel/src/demo/kotlin/DemoWatchDiv01.kt @@ -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) + } +} + 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 index 87dea7a3..46fd45e5 100644 --- a/orx-panel/src/main/kotlin/org/openrndr/panel/elements/WatchDiv.kt +++ b/orx-panel/src/main/kotlin/org/openrndr/panel/elements/WatchDiv.kt @@ -5,12 +5,13 @@ 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 { +class WatchDiv(private val watchList: List, private val builder: WatchDiv.(T) -> Unit) : Div(), DisposableElement { override var disposed: Boolean = false - var listState = emptyList() - var watchJob : Job? = null + private var listState = emptyList() + private var watchJob: Job? = null override fun dispose() { + super.dispose() for (child in children) { child.parent = null (child as? DisposableElement)?.dispose() @@ -18,7 +19,7 @@ class WatchDiv(val watchList: List, val builder: WatchDiv.(T) -> children.clear() } - private fun regenerate() { + fun regenerate() { var regenerate = false if (listState.size != watchList.size) { regenerate = true @@ -45,7 +46,7 @@ class WatchDiv(val watchList: List, val builder: WatchDiv.(T) -> } } - override fun draw(drawer: Drawer) { + fun checkJob() { if (watchJob == null) { watchJob = (root() as Body).controlManager.program.launch { while (!disposed) { @@ -54,6 +55,9 @@ class WatchDiv(val watchList: List, val builder: WatchDiv.(T) -> } } } + } + override fun draw(drawer: Drawer) { + checkJob() super.draw(drawer) } } @@ -62,4 +66,6 @@ fun Element.watchDiv(vararg classes: String, watchList: List, build val wd = WatchDiv(watchList, builder) wd.classes.addAll(classes.map { ElementClass(it) }) this.append(wd) + wd.regenerate() + wd.checkJob() }