[orx-gui] Fix multi-window support. Add WindowedGUI
This commit is contained in:
@@ -19,10 +19,9 @@ fun main() = application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val gui = GUI(GUIAppearance(barWidth = 400))
|
val gui = GUI(GUIAppearance(baseColor = ColorRGBa.GRAY.opacify(0.9), barWidth = 400))
|
||||||
gui.compartmentsCollapsedByDefault = false
|
gui.compartmentsCollapsedByDefault = false
|
||||||
|
|
||||||
|
|
||||||
val settings = @Description("Settings") object {
|
val settings = @Description("Settings") object {
|
||||||
@DoubleParameter("radius", 0.0, 100.0)
|
@DoubleParameter("radius", 0.0, 100.0)
|
||||||
var radius = 50.0
|
var radius = 50.0
|
||||||
|
|||||||
32
orx-jvm/orx-gui/src/demo/kotlin/DemoMultiWindow01.kt
Normal file
32
orx-jvm/orx-gui/src/demo/kotlin/DemoMultiWindow01.kt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import org.openrndr.WindowConfiguration
|
||||||
|
import org.openrndr.application
|
||||||
|
import org.openrndr.extra.gui.GUI
|
||||||
|
import org.openrndr.extra.parameters.*
|
||||||
|
import org.openrndr.window
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstration of multi window GUI in the manual way
|
||||||
|
*/
|
||||||
|
fun main() {
|
||||||
|
// skip this demo on CI
|
||||||
|
if (System.getProperty("takeScreenshot") == "true") {
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
application {
|
||||||
|
program {
|
||||||
|
val settings = object {
|
||||||
|
@DoubleParameter("radius", 10.0, 100.0)
|
||||||
|
var radius = 10.0
|
||||||
|
}
|
||||||
|
window(WindowConfiguration(width = 200, resizable = true)) {
|
||||||
|
val gui = GUI()
|
||||||
|
gui.add(settings)
|
||||||
|
extend(gui)
|
||||||
|
}
|
||||||
|
extend {
|
||||||
|
drawer.circle(drawer.bounds.center, settings.radius)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
orx-jvm/orx-gui/src/demo/kotlin/DemoMultiWindow02.kt
Normal file
32
orx-jvm/orx-gui/src/demo/kotlin/DemoMultiWindow02.kt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import org.openrndr.WindowConfiguration
|
||||||
|
import org.openrndr.application
|
||||||
|
import org.openrndr.extra.gui.GUI
|
||||||
|
import org.openrndr.extra.gui.WindowedGUI
|
||||||
|
import org.openrndr.extra.parameters.*
|
||||||
|
import org.openrndr.window
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstration of multi window GUI using WindowedGUI extension
|
||||||
|
*/
|
||||||
|
fun main() {
|
||||||
|
// skip this demo on CI
|
||||||
|
if (System.getProperty("takeScreenshot") == "true") {
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
application {
|
||||||
|
program {
|
||||||
|
val settings = object {
|
||||||
|
@DoubleParameter("radius", 10.0, 100.0)
|
||||||
|
var radius = 10.0
|
||||||
|
}
|
||||||
|
val gui = WindowedGUI()
|
||||||
|
gui.add(settings)
|
||||||
|
extend(gui)
|
||||||
|
|
||||||
|
extend {
|
||||||
|
drawer.circle(drawer.bounds.center, settings.radius)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,6 +48,10 @@ private class TrackedObjectBinding(
|
|||||||
private val persistentCompartmentStates = mutableMapOf<Long, MutableMap<String, CompartmentState>>()
|
private val persistentCompartmentStates = mutableMapOf<Long, MutableMap<String, CompartmentState>>()
|
||||||
private val persistentSidebarStates = mutableMapOf<Long, SidebarState>()
|
private val persistentSidebarStates = mutableMapOf<Long, SidebarState>()
|
||||||
|
|
||||||
|
private fun compartmentState(): MutableMap<String, CompartmentState> = persistentCompartmentStates.getOrPut(Driver.instance.contextID) {
|
||||||
|
mutableMapOf()
|
||||||
|
}
|
||||||
|
|
||||||
private fun sidebarState(): SidebarState = persistentSidebarStates.getOrPut(Driver.instance.contextID) {
|
private fun sidebarState(): SidebarState = persistentSidebarStates.getOrPut(Driver.instance.contextID) {
|
||||||
SidebarState()
|
SidebarState()
|
||||||
}
|
}
|
||||||
@@ -57,7 +61,7 @@ private fun <T : Any> getPersistedOrDefault(
|
|||||||
property: KMutableProperty1<Any, T>,
|
property: KMutableProperty1<Any, T>,
|
||||||
obj: Any
|
obj: Any
|
||||||
): T {
|
): T {
|
||||||
val state = persistentCompartmentStates[Driver.instance.contextID]!![compartmentLabel]
|
val state = compartmentState()[compartmentLabel]
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
return property.get(obj)
|
return property.get(obj)
|
||||||
} else {
|
} else {
|
||||||
@@ -68,17 +72,19 @@ private fun <T : Any> getPersistedOrDefault(
|
|||||||
|
|
||||||
private fun <T : Any> setAndPersist(compartmentLabel: String, property: KMutableProperty1<Any, T>, obj: Any, value: T) {
|
private fun <T : Any> setAndPersist(compartmentLabel: String, property: KMutableProperty1<Any, T>, obj: Any, value: T) {
|
||||||
property.set(obj, value)
|
property.set(obj, value)
|
||||||
val state = persistentCompartmentStates[Driver.instance.contextID]!![compartmentLabel]!!
|
val state = compartmentState()[compartmentLabel] ?: error("item '$compartmentLabel' not in state (${compartmentState()}. ContextID ${Driver.instance.contextID} )")
|
||||||
state.parameterValues[property.name] = value
|
state.parameterValues[property.name] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
private val logger = KotlinLogging.logger { }
|
private val logger = KotlinLogging.logger { }
|
||||||
|
|
||||||
|
|
||||||
class GUIAppearance(val baseColor: ColorRGBa = ColorRGBa.GRAY, val barWidth: Int = 200)
|
class GUIAppearance(
|
||||||
|
val baseColor: ColorRGBa = ColorRGBa.GRAY.opacify(0.99),
|
||||||
|
val barWidth: Int = 200)
|
||||||
|
|
||||||
@Suppress("unused", "UNCHECKED_CAST")
|
@Suppress("unused", "UNCHECKED_CAST")
|
||||||
class GUI(
|
open class GUI(
|
||||||
val appearance: GUIAppearance = GUIAppearance(),
|
val appearance: GUIAppearance = GUIAppearance(),
|
||||||
val defaultStyles: List<StyleSheet> = defaultStyles(),
|
val defaultStyles: List<StyleSheet> = defaultStyles(),
|
||||||
) : Extension {
|
) : Extension {
|
||||||
@@ -204,7 +210,7 @@ class GUI(
|
|||||||
this.width = 100.percent
|
this.width = 100.percent
|
||||||
this.display = Display.FLEX
|
this.display = Display.FLEX
|
||||||
this.flexDirection = FlexDirection.Row
|
this.flexDirection = FlexDirection.Row
|
||||||
this.background = Color.RGBa(appearance.baseColor.copy(alpha = 0.99))
|
this.background = Color.RGBa(appearance.baseColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
styleSheet(has class_ "collapsed") {
|
styleSheet(has class_ "collapsed") {
|
||||||
@@ -223,7 +229,7 @@ class GUI(
|
|||||||
this.paddingRight = 10.px
|
this.paddingRight = 10.px
|
||||||
this.marginRight = 2.px
|
this.marginRight = 2.px
|
||||||
this.height = 100.percent
|
this.height = 100.percent
|
||||||
this.background = Color.RGBa(appearance.baseColor.copy(alpha = 0.99))
|
this.background = Color.RGBa(appearance.baseColor)
|
||||||
this.overflow = Overflow.Scroll
|
this.overflow = Overflow.Scroll
|
||||||
|
|
||||||
//<editor-fold desc="1) setup control style">
|
//<editor-fold desc="1) setup control style">
|
||||||
@@ -360,7 +366,7 @@ class GUI(
|
|||||||
val collapseClass = ElementClass("collapsed")
|
val collapseClass = ElementClass("collapsed")
|
||||||
|
|
||||||
/* this is guaranteed to be in the dictionary after insertion through add() */
|
/* this is guaranteed to be in the dictionary after insertion through add() */
|
||||||
val collapseState = persistentCompartmentStates[Driver.instance.contextID]!![label]!!
|
val collapseState = compartmentState()[label]!!
|
||||||
if (collapseState.collapsed) {
|
if (collapseState.collapsed) {
|
||||||
collapsible.classes.add(collapseClass)
|
collapsible.classes.add(collapseClass)
|
||||||
}
|
}
|
||||||
@@ -372,7 +378,7 @@ class GUI(
|
|||||||
|
|
||||||
if (KeyModifier.CTRL in me.modifiers) {
|
if (KeyModifier.CTRL in me.modifiers) {
|
||||||
collapsible.classes.remove(collapseClass)
|
collapsible.classes.remove(collapseClass)
|
||||||
persistentCompartmentStates[Driver.instance.contextID]!!.forEach {
|
compartmentState().forEach {
|
||||||
it.value.collapsed = true
|
it.value.collapsed = true
|
||||||
}
|
}
|
||||||
collapseState.collapsed = false
|
collapseState.collapsed = false
|
||||||
|
|||||||
31
orx-jvm/orx-gui/src/main/kotlin/WindowedGUI.kt
Normal file
31
orx-jvm/orx-gui/src/main/kotlin/WindowedGUI.kt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package org.openrndr.extra.gui
|
||||||
|
|
||||||
|
import org.openrndr.Extension
|
||||||
|
import org.openrndr.Program
|
||||||
|
import org.openrndr.WindowConfiguration
|
||||||
|
import org.openrndr.extra.parameters.title
|
||||||
|
import org.openrndr.math.IntVector2
|
||||||
|
import org.openrndr.panel.style.StyleSheet
|
||||||
|
import org.openrndr.panel.style.defaultStyles
|
||||||
|
import org.openrndr.window
|
||||||
|
|
||||||
|
class WindowedGUI(val appearance: GUIAppearance = GUIAppearance(), val defaultStyles: List<StyleSheet> = defaultStyles()) : Extension {
|
||||||
|
override var enabled: Boolean = true
|
||||||
|
|
||||||
|
val addedObjects = mutableListOf<Pair<Any, String?>>()
|
||||||
|
fun <T : Any> add(objectWithParameters: T, label: String? = objectWithParameters.title()): T {
|
||||||
|
addedObjects.add(Pair(objectWithParameters, label))
|
||||||
|
return objectWithParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun setup(program: Program) {
|
||||||
|
program.window(WindowConfiguration(width = 200, height = program.height, position = program.window.position.toInt() - IntVector2(200,0) )) {
|
||||||
|
val gui = GUI(appearance, defaultStyles)
|
||||||
|
for ((obj, label) in addedObjects) {
|
||||||
|
gui.add(obj, label)
|
||||||
|
}
|
||||||
|
extend(gui)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user