diff --git a/build.gradle.kts b/build.gradle.kts index f396caad..a19fe8ff 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ import scientifik.useSerialization -val dataforgeVersion by extra("0.1.5-dev-4") +val dataforgeVersion by extra("0.1.5-dev-5") plugins { val kotlinVersion = "1.3.61" @@ -30,7 +30,7 @@ allprojects { } subprojects{ - useSerialization("0.13.0") + this.useSerialization() } val githubProject by extra("dataforge-vis") diff --git a/dataforge-vis-common/build.gradle.kts b/dataforge-vis-common/build.gradle.kts index 87b03571..4ac0092e 100644 --- a/dataforge-vis-common/build.gradle.kts +++ b/dataforge-vis-common/build.gradle.kts @@ -1,4 +1,5 @@ import org.openjfx.gradle.JavaFXOptions +import scientifik.useSerialization plugins { id("scientifik.mpp") @@ -8,6 +9,8 @@ plugins { val dataforgeVersion: String by rootProject.extra //val kvisionVersion: String by rootProject.extra("2.0.0-M1") +useSerialization() + kotlin { jvm{ withJava() @@ -22,7 +25,9 @@ kotlin { jvmMain{ dependencies { api("no.tornado:tornadofx:1.7.19") - api("no.tornado:tornadofx-controlsfx:0.1") + //api("no.tornado:tornadofx-controlsfx:0.1.1") + api("de.jensd:fontawesomefx-fontawesome:4.7.0-11") + api("de.jensd:fontawesomefx-commons:11.0") } } jsMain{ diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualObject.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualObject.kt index b59f2564..7d75df0a 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualObject.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualObject.kt @@ -61,10 +61,6 @@ abstract class AbstractVisualObject : VisualObject { listeners.removeAll { it.owner == owner } } - override fun setProperty(name: Name, value: Any?) { - config[name] = value - } - private var styleCache: Meta? = null /** @@ -75,6 +71,7 @@ abstract class AbstractVisualObject : VisualObject { styleCache = it } + override fun allProperties(): Laminate = Laminate(properties, mergedStyles) override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { return if (inherit) { diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualGroup.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualGroup.kt index 11d3dcab..8fb97451 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualGroup.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualGroup.kt @@ -78,4 +78,4 @@ interface MutableVisualGroup : VisualGroup { operator fun set(name: Name, child: VisualObject?) } -operator fun VisualGroup.get(str: String?) = get(str?.toName() ?: EmptyName) \ No newline at end of file +operator fun VisualGroup.get(str: String?) = get(str?.toName() ?: Name.EMPTY) \ No newline at end of file diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualObject.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualObject.kt index 008ecd9d..b9f6dd10 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualObject.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualObject.kt @@ -23,10 +23,17 @@ interface VisualObject : Configurable { @Transient var parent: VisualObject? + /** + * All properties including styles and prototypes if present, but without inheritance + */ + fun allProperties(): Meta + /** * Set property for this object */ - fun setProperty(name: Name, value: Any?) + fun setProperty(name: Name, value: Any?) { + config[name] = value + } /** * Get property including or excluding parent properties diff --git a/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/ConfigEditor.kt b/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/ConfigEditor.kt index 01c9973d..93af2df4 100644 --- a/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/ConfigEditor.kt +++ b/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/ConfigEditor.kt @@ -5,17 +5,20 @@ */ package hep.dataforge.vis.fx.editor +import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon +import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView import hep.dataforge.context.Global import hep.dataforge.descriptors.NodeDescriptor import hep.dataforge.meta.Config import hep.dataforge.names.NameToken import hep.dataforge.vis.fx.dfIconView +import javafx.scene.Node import javafx.scene.control.* import javafx.scene.control.cell.TextFieldTreeTableCell +import javafx.scene.layout.HBox import javafx.scene.layout.Priority import javafx.scene.paint.Color import javafx.scene.text.Text -import org.controlsfx.glyphfont.Glyph import tornadofx.* /** @@ -133,8 +136,9 @@ class ConfigEditor( is FXMetaNode -> { if (allowNew) { text = null - graphic = hbox { - button("node", Glyph("FontAwesome", "PLUS_CIRCLE")) { + graphic = HBox().apply { + val glyph: Node = FontAwesomeIconView(FontAwesomeIcon.PLUS_CIRCLE) + button("node", graphic = glyph) { hgrow = Priority.ALWAYS maxWidth = Double.POSITIVE_INFINITY action { @@ -143,7 +147,7 @@ class ConfigEditor( } } } - button("value", Glyph("FontAwesome", "PLUS_SQUARE")) { + button("value", graphic = FontAwesomeIconView(FontAwesomeIcon.PLUS_SQUARE)) { hgrow = Priority.ALWAYS maxWidth = Double.POSITIVE_INFINITY action { diff --git a/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/VisualObjectEditorFragment.kt b/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/VisualObjectEditorFragment.kt index d1af9a93..fd52d64c 100644 --- a/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/VisualObjectEditorFragment.kt +++ b/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/VisualObjectEditorFragment.kt @@ -2,6 +2,8 @@ package hep.dataforge.vis.fx.editor import hep.dataforge.descriptors.NodeDescriptor import hep.dataforge.meta.Config +import hep.dataforge.meta.Meta +import hep.dataforge.meta.update import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.findStyle import javafx.beans.binding.Binding @@ -11,7 +13,7 @@ import javafx.scene.Parent import javafx.scene.layout.VBox import tornadofx.* -class VisualObjectEditorFragment(val selector: (VisualObject) -> Config) : Fragment() { +class VisualObjectEditorFragment(val selector: (VisualObject) -> Meta) : Fragment() { val itemProperty = SimpleObjectProperty() var item: VisualObject? by itemProperty @@ -26,8 +28,21 @@ class VisualObjectEditorFragment(val selector: (VisualObject) -> Config) : Fragm this.descriptorProperty.set(descriptor) } - private val configProperty: Binding = itemProperty.objectBinding { - it?.let { selector(it) } + private var currentConfig: Config? = null + + private val configProperty: Binding = itemProperty.objectBinding { visualObject -> + if (visualObject == null) return@objectBinding null + val meta = selector(visualObject) + val config = Config().apply { + update(meta) + onChange(this@VisualObjectEditorFragment) { key, _, after -> + visualObject.setProperty(key, after) + } + } + //remember old config reference to cleanup listeners + currentConfig?.removeListener(this) + currentConfig = config + config } private val configEditorProperty: Binding = configProperty.objectBinding(descriptorProperty) { diff --git a/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/VisualObjectTreeFragment.kt b/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/VisualObjectTreeFragment.kt index 5f18f1ef..4f27ef87 100644 --- a/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/VisualObjectTreeFragment.kt +++ b/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/VisualObjectTreeFragment.kt @@ -7,25 +7,47 @@ import javafx.scene.control.SelectionMode import javafx.scene.control.TreeItem import tornadofx.* +private fun toTreeItem(visualObject: VisualObject, title: String): TreeItem> { + return object : TreeItem>(title to visualObject) { + init { + if (visualObject is VisualGroup) { + //lazy populate the tree + expandedProperty().onChange { expanded -> + if (expanded && children.isEmpty()) { + children.setAll(visualObject.children.map { + toTreeItem(it.value, it.key.toString()) + }) + } + } + } + } + + override fun isLeaf(): Boolean { + return !(visualObject is VisualGroup && visualObject.children.isNotEmpty()) + } + } +} + + class VisualObjectTreeFragment : Fragment() { val itemProperty = SimpleObjectProperty() var item: VisualObject? by itemProperty val selectedProperty = SimpleObjectProperty() - override val root = borderpane{ - center = titledpane("Object tree") { - treeview { + override val root = vbox { + titledpane("Object tree", collapsible = false) { + treeview> { + cellFormat { + text = item.first + } itemProperty.onChange { rootObject -> if (rootObject != null) { - root = TreeItem(rootObject) - populate { item -> - (item.value as? VisualGroup)?.children?.values?.toList() - } + root = toTreeItem(rootObject, "world") } } selectionModel.selectionMode = SelectionMode.SINGLE - val selectedValue = selectionModel.selectedItemProperty().objectBinding{it?.value} + val selectedValue = selectionModel.selectedItemProperty().objectBinding { it?.value?.second } selectedProperty.bind(selectedValue) } } diff --git a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt index ff38c2ae..95c316bf 100644 --- a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt +++ b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt @@ -1,6 +1,7 @@ package hep.dataforge.vis.spatial.gdml -import hep.dataforge.names.EmptyName + +import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.names.plus import hep.dataforge.vis.common.get @@ -194,7 +195,7 @@ private fun VisualGroup3D.addDivisionVolume( //TODO add divisions set( - EmptyName, + Name.EMPTY, volume( context, volume diff --git a/dataforge-vis-spatial/build.gradle.kts b/dataforge-vis-spatial/build.gradle.kts index 896c4ee1..2fe2ac14 100644 --- a/dataforge-vis-spatial/build.gradle.kts +++ b/dataforge-vis-spatial/build.gradle.kts @@ -1,10 +1,13 @@ import org.openjfx.gradle.JavaFXOptions +import scientifik.useSerialization plugins { id("scientifik.mpp") id("org.openjfx.javafxplugin") } +useSerialization() + kotlin { jvm { withJava() diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Material3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Material3D.kt index 40520f0f..8e4ce2d8 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Material3D.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Material3D.kt @@ -1,8 +1,10 @@ package hep.dataforge.vis.spatial +import hep.dataforge.descriptors.NodeDescriptor import hep.dataforge.meta.* import hep.dataforge.names.asName import hep.dataforge.names.plus +import hep.dataforge.values.ValueType import hep.dataforge.vis.common.Colors import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY @@ -23,12 +25,28 @@ class Material3D(override val config: Config) : Specific { val MATERIAL_KEY = "material".asName() internal val COLOR_KEY = "color".asName() val MATERIAL_COLOR_KEY = MATERIAL_KEY + COLOR_KEY - val SPECULAR_COLOR ="specularColor".asName() + val SPECULAR_COLOR = "specularColor".asName() internal val OPACITY_KEY = "opacity".asName() val MATERIAL_OPACITY_KEY = MATERIAL_KEY + OPACITY_KEY internal val WIREFRAME_KEY = "wireframe".asName() val MATERIAL_WIREFRAME_KEY = MATERIAL_KEY + WIREFRAME_KEY + val descriptor = NodeDescriptor { + node(MATERIAL_KEY) { + value(COLOR_KEY) { + type(ValueType.STRING, ValueType.NUMBER) + default("#ffffff") + } + value(OPACITY_KEY){ + type(ValueType.NUMBER) + default(1.0) + } + value(WIREFRAME_KEY){ + type(ValueType.BOOLEAN) + default(false) + } + } + } } } @@ -63,7 +81,7 @@ fun VisualObject3D.material(builder: Material3D.() -> Unit) { if (node != null) { Material3D.update(node, builder) } else { - config[Material3D.MATERIAL_KEY] = Material3D.build(builder) + config[Material3D.MATERIAL_KEY] = Material3D(builder) } } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt index c74e2236..62d7b5c0 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt @@ -5,6 +5,7 @@ package hep.dataforge.vis.spatial import hep.dataforge.io.serialization.ConfigSerializer import hep.dataforge.io.serialization.NameSerializer import hep.dataforge.meta.Config +import hep.dataforge.meta.Laminate import hep.dataforge.meta.MetaItem import hep.dataforge.meta.get import hep.dataforge.names.Name @@ -76,12 +77,7 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua ?: error("Prototype with name $name not found in $this") } - override var styles: List - get() = super.styles + prototype.styles - set(value) { - setProperty(VisualObject.STYLE_KEY, value) - updateStyles(value) - } + override fun allProperties(): Laminate = Laminate(properties, mergedStyles, prototype.allProperties()) //override fun findAllStyles(): Laminate = Laminate((styles + prototype.styles).mapNotNull { findStyle(it) }) @@ -92,13 +88,6 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua override val styleSheet: StyleSheet get() = this@Proxy.styleSheet - override var styles: List - get() = super.styles + prototype.styles - set(value) { - setProperty(VisualObject.STYLE_KEY, value) - updateStyles(value) - } - override val children: Map get() = (prototype as? VisualGroup)?.children?.mapValues { (key, _) -> ProxyChild( @@ -136,6 +125,9 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua } } + + override fun allProperties(): Laminate = Laminate(properties, mergedStyles, prototype.allProperties()) + } companion object { diff --git a/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/FXProxyFactory.kt b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/FXProxyFactory.kt index 7a7c11da..6cdb6610 100644 --- a/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/FXProxyFactory.kt +++ b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/FXProxyFactory.kt @@ -2,14 +2,11 @@ package hep.dataforge.vis.spatial.fx import hep.dataforge.names.Name import hep.dataforge.names.isEmpty -import hep.dataforge.names.startsWith import hep.dataforge.names.toName import hep.dataforge.vis.common.VisualObject -import hep.dataforge.vis.spatial.Material3D import hep.dataforge.vis.spatial.Proxy import javafx.scene.Group import javafx.scene.Node -import javafx.scene.shape.Shape3D import kotlin.reflect.KClass class FXProxyFactory(val plugin: FX3DPlugin) : FX3DFactory { @@ -44,7 +41,7 @@ private fun Node.findChild(name: Name): Node? { } private fun Node.updateProperty(obj: VisualObject, propertyName: Name) { - if (propertyName.startsWith(Material3D.MATERIAL_KEY)) { - (this as? Shape3D)?.let { it.material = obj.getProperty(Material3D.MATERIAL_KEY).material() } - } +// if (propertyName.startsWith(Material3D.MATERIAL_KEY)) { +// (this as? Shape3D)?.let { it.material = obj.getProperty(Material3D.MATERIAL_KEY).material() } +// } } \ No newline at end of file diff --git a/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt b/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt index 7613536f..b4a75c37 100644 --- a/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt +++ b/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt @@ -9,7 +9,6 @@ import hep.dataforge.vis.spatial.fx.FXCanvas3D import hep.dataforge.vis.spatial.gdml.LUnit import hep.dataforge.vis.spatial.gdml.readFile import hep.dataforge.vis.spatial.gdml.toVisual -import hep.dataforge.vis.spatial.prototype import javafx.geometry.Orientation import javafx.scene.Parent import javafx.stage.FileChooser @@ -26,8 +25,10 @@ class GDMLView : View() { this.itemProperty.bind(canvas.rootObjectProperty) } - private val propertyEditor = VisualObjectEditorFragment { it.prototype.config }.apply { - //TODO add descriptor here + private val propertyEditor = VisualObjectEditorFragment { + it.allProperties() + }.apply { + descriptorProperty.set(Material3D.descriptor) itemProperty.bind(treeFragment.selectedProperty) } @@ -43,7 +44,7 @@ class GDMLView : View() { lUnit = LUnit.CM solidConfiguration = { parent, solid -> - if(solid.name == "cave"){ + if (solid.name == "cave") { setProperty(Material3D.MATERIAL_WIREFRAME_KEY, true) } if (parent.physVolumes.isNotEmpty()) {