[orx-gui] Fix multi-window support. Add WindowedGUI

This commit is contained in:
Edwin Jakobs
2024-05-14 10:12:30 +02:00
parent dcf04b06d6
commit 4db8f28543
5 changed files with 110 additions and 10 deletions

View File

@@ -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
val settings = @Description("Settings") object {
@DoubleParameter("radius", 0.0, 100.0)
var radius = 50.0

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

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

View File

@@ -48,6 +48,10 @@ private class TrackedObjectBinding(
private val persistentCompartmentStates = mutableMapOf<Long, MutableMap<String, CompartmentState>>()
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) {
SidebarState()
}
@@ -57,7 +61,7 @@ private fun <T : Any> getPersistedOrDefault(
property: KMutableProperty1<Any, T>,
obj: Any
): T {
val state = persistentCompartmentStates[Driver.instance.contextID]!![compartmentLabel]
val state = compartmentState()[compartmentLabel]
if (state == null) {
return property.get(obj)
} 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) {
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
}
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")
class GUI(
open class GUI(
val appearance: GUIAppearance = GUIAppearance(),
val defaultStyles: List<StyleSheet> = defaultStyles(),
) : Extension {
@@ -204,7 +210,7 @@ class GUI(
this.width = 100.percent
this.display = Display.FLEX
this.flexDirection = FlexDirection.Row
this.background = Color.RGBa(appearance.baseColor.copy(alpha = 0.99))
this.background = Color.RGBa(appearance.baseColor)
}
styleSheet(has class_ "collapsed") {
@@ -223,7 +229,7 @@ class GUI(
this.paddingRight = 10.px
this.marginRight = 2.px
this.height = 100.percent
this.background = Color.RGBa(appearance.baseColor.copy(alpha = 0.99))
this.background = Color.RGBa(appearance.baseColor)
this.overflow = Overflow.Scroll
//<editor-fold desc="1) setup control style">
@@ -360,7 +366,7 @@ class GUI(
val collapseClass = ElementClass("collapsed")
/* 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) {
collapsible.classes.add(collapseClass)
}
@@ -372,7 +378,7 @@ class GUI(
if (KeyModifier.CTRL in me.modifiers) {
collapsible.classes.remove(collapseClass)
persistentCompartmentStates[Driver.instance.contextID]!!.forEach {
compartmentState().forEach {
it.value.collapsed = true
}
collapseState.collapsed = false

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