Property resolution simplification

This commit is contained in:
Alexander Nozik 2019-12-24 22:09:39 +03:00
parent 8d39a3efa5
commit 193fed524e
14 changed files with 113 additions and 51 deletions

View File

@ -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")

View File

@ -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{

View File

@ -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) {

View File

@ -78,4 +78,4 @@ interface MutableVisualGroup : VisualGroup {
operator fun set(name: Name, child: VisualObject?)
}
operator fun VisualGroup.get(str: String?) = get(str?.toName() ?: EmptyName)
operator fun VisualGroup.get(str: String?) = get(str?.toName() ?: Name.EMPTY)

View File

@ -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

View File

@ -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<Config> -> {
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 {

View File

@ -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<VisualObject>()
var item: VisualObject? by itemProperty
@ -26,8 +28,21 @@ class VisualObjectEditorFragment(val selector: (VisualObject) -> Config) : Fragm
this.descriptorProperty.set(descriptor)
}
private val configProperty: Binding<Config?> = itemProperty.objectBinding {
it?.let { selector(it) }
private var currentConfig: Config? = null
private val configProperty: Binding<Config?> = 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<Node?> = configProperty.objectBinding(descriptorProperty) {

View File

@ -7,25 +7,47 @@ import javafx.scene.control.SelectionMode
import javafx.scene.control.TreeItem
import tornadofx.*
private fun toTreeItem(visualObject: VisualObject, title: String): TreeItem<Pair<String, VisualObject>> {
return object : TreeItem<Pair<String, VisualObject>>(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<VisualObject>()
var item: VisualObject? by itemProperty
val selectedProperty = SimpleObjectProperty<VisualObject>()
override val root = borderpane{
center = titledpane("Object tree") {
treeview<VisualObject> {
override val root = vbox {
titledpane("Object tree", collapsible = false) {
treeview<Pair<String, VisualObject>> {
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)
}
}

View File

@ -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

View File

@ -1,10 +1,13 @@
import org.openjfx.gradle.JavaFXOptions
import scientifik.useSerialization
plugins {
id("scientifik.mpp")
id("org.openjfx.javafxplugin")
}
useSerialization()
kotlin {
jvm {
withJava()

View File

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

View File

@ -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<String>
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<String>
get() = super.styles + prototype.styles
set(value) {
setProperty(VisualObject.STYLE_KEY, value)
updateStyles(value)
}
override val children: Map<NameToken, VisualObject>
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 {

View File

@ -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<Proxy> {
@ -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() }
// }
}

View File

@ -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()) {