From 74e70819ee4409486e1c6f1bacb4316b44ac9a43 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 12 Jun 2019 21:13:41 +0300 Subject: [PATCH] FXMeta viewer and editor fully functional --- build.gradle.kts | 3 +- dataforge-vis-common/build.gradle.kts | 10 +- .../dataforge/vis/fx/demo/MetaEditorDemo.kt | 53 ++++ .../hep/dataforge/vis/fx/meta/ConfigEditor.kt | 49 +-- .../hep/dataforge/vis/fx/meta/ConfigFX.kt | 286 ------------------ .../hep/dataforge/vis/fx/meta/FXMeta.kt | 152 +++++++--- .../hep/dataforge/vis/fx/meta/MetaViewer.kt | 21 +- settings.gradle.kts | 4 +- 8 files changed, 217 insertions(+), 361 deletions(-) create mode 100644 dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/demo/MetaEditorDemo.kt delete mode 100644 dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/ConfigFX.kt diff --git a/build.gradle.kts b/build.gradle.kts index b0cc2184..d4d4d681 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,8 @@ -val dataforgeVersion by extra("0.1.3-dev-2") +val dataforgeVersion by extra("0.1.3-dev-5") allprojects { repositories { + mavenLocal() jcenter() maven("https://kotlin.bintray.com/kotlinx") maven("http://npm.mipt.ru:8081/artifactory/gradle-dev-local") diff --git a/dataforge-vis-common/build.gradle.kts b/dataforge-vis-common/build.gradle.kts index 069181bb..7706865b 100644 --- a/dataforge-vis-common/build.gradle.kts +++ b/dataforge-vis-common/build.gradle.kts @@ -9,17 +9,17 @@ kotlin { val commonMain by getting { dependencies { api("hep.dataforge:dataforge-output:$dataforgeVersion") - api("hep.dataforge:dataforge-output-metadata:$dataforgeVersion") +// api("hep.dataforge:dataforge-output-metadata:$dataforgeVersion") } } - val jvmMain by getting{ + val jvmMain by getting { dependencies { - api("hep.dataforge:dataforge-output-jvm:$dataforgeVersion") +// api("hep.dataforge:dataforge-output-jvm:$dataforgeVersion") } } - val jsMain by getting{ + val jsMain by getting { dependencies { - api("hep.dataforge:dataforge-output-js:$dataforgeVersion") +// api("hep.dataforge:dataforge-output-js:$dataforgeVersion") } } } diff --git a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/demo/MetaEditorDemo.kt b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/demo/MetaEditorDemo.kt new file mode 100644 index 00000000..73419942 --- /dev/null +++ b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/demo/MetaEditorDemo.kt @@ -0,0 +1,53 @@ +package hep.dataforge.vis.fx.demo + +import hep.dataforge.descriptors.NodeDescriptor +import hep.dataforge.meta.buildMeta +import hep.dataforge.meta.toConfig +import hep.dataforge.values.ValueType +import hep.dataforge.vis.fx.meta.ConfigEditor +import hep.dataforge.vis.fx.meta.FXMeta +import hep.dataforge.vis.fx.meta.MetaViewer +import javafx.geometry.Orientation +import tornadofx.* + + +class MetaEditorDemoApp : App(MetaEditorDemo::class) + +class MetaEditorDemo : View("Meta editor demo") { + + val meta = buildMeta { + "aNode" to { + "innerNode" to { + "innerValue" to true + } + "b" to 22 + "c" to "StringValue" + } + }.toConfig() + + val descriptor = NodeDescriptor.build { + node("aNode") { + info = "A root demo node" + value("b") { + info = "b number value" + type(ValueType.NUMBER) + } + node("otherNode") { + value("otherValue") { + type(ValueType.BOOLEAN) + default(false) + info = "default value" + } + } + } + } + + private val rootNode = FXMeta.root(meta,descriptor) + + override val root = + splitpane(Orientation.HORIZONTAL, MetaViewer(rootNode).root, ConfigEditor(rootNode).root) +} + +fun main() { + launch() +} diff --git a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/ConfigEditor.kt b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/ConfigEditor.kt index 5cafce9a..ea5e21c9 100644 --- a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/ConfigEditor.kt +++ b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/ConfigEditor.kt @@ -24,27 +24,30 @@ import tornadofx.* * @author Alexander Nozik */ class ConfigEditor( - val configuration: Config, - title: String = "Configuration editor", - val descriptor: NodeDescriptor? = null + val rootNode: FXMetaNode, + title: String = "Configuration editor" ) : Fragment(title = title, icon = dfIconView) { - val filter: (FXMeta) -> Boolean = { cfg -> - when (cfg) { - is FXMetaNode<*> -> !(cfg.descriptor?.tags?.contains(NO_CONFIGURATOR_TAG) ?: false) - is FXMetaValue -> !(cfg.descriptor?.tags?.contains(NO_CONFIGURATOR_TAG) ?: false) - } - } + constructor(config: Config, descriptor: NodeDescriptor, title: String = "Configuration editor") : + this(FXMeta.root(config, descriptor = descriptor)) override val root = borderpane { - center = treetableview { - root = TreeItem(FXMeta.root(configuration, descriptor)) + center = treetableview> { + root = TreeItem(rootNode) root.isExpanded = true sortMode = TreeSortMode.ALL_DESCENDANTS columnResizePolicy = TreeTableView.CONSTRAINED_RESIZE_POLICY - column("Name", FXMeta::name) { + populate { + when (val fxMeta = it.value) { + is FXMetaNode -> { + fxMeta.children + } + is FXMetaValue -> null + } + } + column("Name", FXMeta::name) { setCellFactory { - object : TextFieldTreeTableCell() { + object : TextFieldTreeTableCell, NameToken>() { override fun updateItem(item: NameToken?, empty: Boolean) { super.updateItem(item, empty) contextMenu?.items?.removeIf { it.text == "Remove" } @@ -57,7 +60,7 @@ class ConfigEditor( Color.GRAY } }) - if (treeTableRow.treeItem.value.hasValue.get()) { + if (treeTableRow.treeItem.value.parent != null && treeTableRow.treeItem.value.hasValue.get()) { contextmenu { item("Remove") { action { @@ -73,15 +76,15 @@ class ConfigEditor( } } - column("Value") { param: TreeTableColumn.CellDataFeatures -> + column("Value") { param: TreeTableColumn.CellDataFeatures, FXMeta> -> param.value.valueProperty() }.setCellFactory { ValueCell() } - column("Description") { param: TreeTableColumn.CellDataFeatures -> param.value.value.descriptionProperty } - .setCellFactory { param: TreeTableColumn -> - val cell = TreeTableCell() + column("Description") { param: TreeTableColumn.CellDataFeatures, String> -> param.value.value.descriptionProperty } + .setCellFactory { param: TreeTableColumn, String> -> + val cell = TreeTableCell, String>() val text = Text() cell.graphic = text cell.prefHeight = Control.USE_COMPUTED_SIZE @@ -112,22 +115,20 @@ class ConfigEditor( return result.orElse(null) } - private inner class ValueCell : TreeTableCell() { + private inner class ValueCell : TreeTableCell, FXMeta?>() { - public override fun updateItem(item: FXMeta?, empty: Boolean) { + public override fun updateItem(item: FXMeta?, empty: Boolean) { if (!empty) { if (item != null) { when (item) { - is FXMetaValue -> { + is FXMetaValue -> { text = null val chooser = ValueChooser.build(item.valueProperty, item.descriptor) { item.set(it) } graphic = chooser.node } - is FXMetaNode<*> -> { - item as FXMetaNode - + is FXMetaNode -> { text = null graphic = hbox { button("node", Glyph("FontAwesome", "PLUS_CIRCLE")) { diff --git a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/ConfigFX.kt b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/ConfigFX.kt deleted file mode 100644 index fc06e4e7..00000000 --- a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/ConfigFX.kt +++ /dev/null @@ -1,286 +0,0 @@ -//package hep.dataforge.vis.fx.meta -// -//import hep.dataforge.descriptors.NodeDescriptor -//import hep.dataforge.descriptors.ValueDescriptor -//import hep.dataforge.meta.Config -//import hep.dataforge.meta.Meta -//import hep.dataforge.names.Name -//import hep.dataforge.values.Null -//import hep.dataforge.values.Value -//import javafx.beans.binding.StringBinding -//import javafx.beans.property.SimpleObjectProperty -//import javafx.beans.property.SimpleStringProperty -//import javafx.beans.value.ObservableBooleanValue -//import javafx.beans.value.ObservableStringValue -//import javafx.collections.FXCollections -//import javafx.collections.ObservableList -//import javafx.scene.control.TreeItem -//import tornadofx.* -// -//class ConfigTreeItem(configFX: ConfigFX) : TreeItem(configFX) { -// init { -// this.children.bind(value.children) { ConfigTreeItem(it) } -// } -// -// override fun isLeaf(): Boolean = value is ConfigFXValue -//} -// -// -///** -// * A node, containing relative representation of configuration node and description -// * Created by darksnake on 01-May-17. -// */ -//sealed class ConfigFX(name: String) { -// -// val nameProperty = SimpleStringProperty(name) -// val name by nameProperty -// -// val parentProperty = SimpleObjectProperty() -// val parent by parentProperty -// -// abstract val hasValueProperty: ObservableBooleanValue -// //abstract val hasDefaultProperty: ObservableBooleanValue -// -// abstract val descriptionProperty: ObservableStringValue -// -// abstract val children: ObservableList -// -// /** -// * remove itself from parent -// */ -// abstract fun remove() -// -// abstract fun invalidate() -//} -// -// -///** -// * Tree item for node -// * Created by darksnake on 30-Apr-17. -// */ -//open class ConfigFXNode(name: String, parent: ConfigFXNode? = null) : ConfigFX(name) { -// -// final override val hasValueProperty = parentProperty.booleanBinding(nameProperty) { -// it?.config?.hasMeta(this.name) ?: false -// } -// -// /** -// * A descriptor that could be manually set to the node -// */ -// val descriptorProperty = SimpleObjectProperty() -// -// /** -// * Actual descriptor which holds value inferred from parrent -// */ -// private val actualDescriptor = objectBinding(descriptorProperty, parentProperty, nameProperty) { -// value ?: parent?.descriptor?.getNodeDescriptor(name) -// } -// -// val descriptor: NodeDescriptor? by actualDescriptor -// -// val configProperty = SimpleObjectProperty() -// -// private val actualConfig = objectBinding(configProperty, parentProperty, nameProperty) { -// value ?: parent?.config?.getMetaList(name)?.firstOrNull() -// } -// -// val config: Config? by actualConfig -// -// final override val descriptionProperty: ObservableStringValue = stringBinding(actualDescriptor) { -// value?.info ?: "" -// } -// -// override val children: ObservableList = FXCollections.observableArrayList() -// -// init { -// parentProperty.set(parent) -// hasValueProperty.onChange { -// parent?.hasValueProperty?.invalidate() -// } -// invalidate() -// } -// -// /** -// * Get existing configuration node or create and attach new one -// * -// * @return -// */ -// private fun getOrBuildNode(): Config { -// return config ?: if (parent == null) { -// throw RuntimeException("The configuration for root node is note defined") -// } else { -// parent.getOrBuildNode().requestNode(name) -// } -// } -// -// fun addValue(name: String) { -// getOrBuildNode().setValue(name, Null) -// } -// -// fun setValue(name: String, value: Value) { -// getOrBuildNode().setValue(name, value) -// } -// -// fun removeValue(valueName: String) { -// config?.removeValue(valueName) -// children.removeIf { it.name == name } -// } -// -// fun addNode(name: String) { -// getOrBuildNode().requestNode(name) -// } -// -// fun removeNode(name: String) { -// config?.removeNode(name) -// } -// -// override fun remove() { -// //FIXME does not work on multinodes -// parent?.removeNode(name) -// invalidate() -// } -// -// final override fun invalidate() { -// actualDescriptor.invalidate() -// actualConfig.invalidate() -// hasValueProperty.invalidate() -// -// val nodeNames = ArrayList() -// val valueNames = ArrayList() -// -// config?.apply { -// nodeNames.addAll(this.nodeNames.toList()) -// valueNames.addAll(this.valueNames.toList()) -// } -// -// descriptor?.apply { -// nodeNames.addAll(childrenDescriptors().keys) -// valueNames.addAll(valueDescriptors().keys) -// } -// -// //removing old values -// children.removeIf { !(valueNames.contains(it.name) || nodeNames.contains(it.name)) } -// -// valueNames.forEach { name -> -// children.find { it.name == name }?.invalidate().orElse { -// children.add(ConfigFXValue(name, this)) -// } -// } -// -// nodeNames.forEach { name -> -// children.find { it.name == name }?.invalidate().orElse { -// children.add(ConfigFXNode(name, this)) -// } -// } -// children.sortBy { it.name } -// } -// -// fun updateValue(path: Name, value: Value?) { -// when { -// path.length == 0 -> kotlin.error("Path never could be empty when updating value") -// path.length == 1 -> { -// val hasDescriptor = descriptor?.getValueDescriptor(path) != null -// if (value == null && !hasDescriptor) { -// //removing the value if it is present -// children.removeIf { it.name == path.unescaped } -// } else { -// //invalidating value if it is present -// children.find { it is ConfigFXValue && it.name == path.unescaped }?.invalidate().orElse { -// //adding new node otherwise -// children.add(ConfigFXValue(path.unescaped, this)) -// } -// } -// } -// path.length > 1 -> children.filterIsInstance().find { it.name == path.first.unescaped }?.updateValue( -// path.cutFirst(), -// value -// ) -// } -// } -// -// fun updateNode(path: Name, list: List) { -// when { -// path.isEmpty() -> invalidate() -// path.length == 1 -> { -// val hasDescriptor = descriptor?.getNodeDescriptor(path.unescaped) != null -// if (list.isEmpty() && !hasDescriptor) { -// children.removeIf { it.name == path.unescaped } -// } else { -// children.find { it is ConfigFXNode && it.name == path.unescaped }?.invalidate().orElse { -// children.add(ConfigFXNode(path.unescaped, this)) -// } -// } -// } -// else -> children.filterIsInstance().find { it.name == path.first.toString() }?.updateNode( -// path.cutFirst(), -// list -// ) -// } -// } -//} -// -//class ConfigFXRoot(rootConfig: Config, rootDescriptor: NodeDescriptor? = null) : ConfigFXNode(rootConfig.name), -// ConfigChangeListener { -// -// init { -// configProperty.set(rootConfig) -// descriptorProperty.set(rootDescriptor) -// rootConfig.addListener(this) -// invalidate() -// } -// -// override fun notifyValueChanged(name: Name, oldItem: Value?, newItem: Value?) { -// updateValue(name, newItem) -// } -// -// override fun notifyNodeChanged(nodeName: Name, oldItem: List, newItem: List) { -// updateNode(nodeName, newItem) -// } -//} -// -// -///** -// * Created by darksnake on 01-May-17. -// */ -//class ConfigFXValue(name: String, parent: ConfigFXNode) : ConfigFX(name) { -// -// init { -// parentProperty.set(parent) -// } -// -// override val hasValueProperty = parentProperty.booleanBinding(nameProperty) { -// it?.config?.hasValue(this.name) ?: false -// } -// -// -// override val children: ObservableList = FXCollections.emptyObservableList() -// -// val descriptor: ValueDescriptor? = parent.descriptor?.values[name] -// -// override val descriptionProperty: ObservableStringValue = object : StringBinding() { -// override fun computeValue(): String { -// return descriptor?.info ?: "" -// } -// } -// -// val valueProperty = parentProperty.objectBinding(nameProperty) { -// parent.config?.optValue(name).nullable ?: descriptor?.default -// } -// -// var value: Value -// set(value) { -// parent?.setValue(name, value) -// } -// get() = valueProperty.value ?: Value.NULL -// -// -// override fun remove() { -// parent?.removeValue(name) -// invalidate() -// } -// -// override fun invalidate() { -// valueProperty.invalidate() -// hasValueProperty.invalidate() -// } -//} diff --git a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/FXMeta.kt b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/FXMeta.kt index 2b33a767..625c1ba3 100644 --- a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/FXMeta.kt +++ b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/FXMeta.kt @@ -1,9 +1,13 @@ package hep.dataforge.vis.fx.meta +import hep.dataforge.descriptors.ItemDescriptor import hep.dataforge.descriptors.NodeDescriptor +import hep.dataforge.descriptors.ValueDescriptor import hep.dataforge.meta.* +import hep.dataforge.names.Name import hep.dataforge.names.NameToken import hep.dataforge.names.asName +import hep.dataforge.values.Null import hep.dataforge.values.Value import javafx.beans.binding.ListBinding import javafx.beans.binding.ObjectBinding @@ -13,67 +17,129 @@ import javafx.beans.value.ObservableStringValue import javafx.collections.ObservableList import tornadofx.* -sealed class FXMeta { +/** + * A display for meta and descriptor + */ +sealed class FXMeta> : Comparable> { abstract val name: NameToken - abstract val parent: FXMetaNode<*>? + abstract val parent: FXMetaNode? abstract val descriptionProperty: ObservableStringValue + abstract val descriptor: ItemDescriptor? abstract val hasValue: ObservableBooleanValue - companion object { - fun > root(node: M, descriptor: NodeDescriptor? = null): FXMetaNode = - FXMetaNode(NameToken("root"), null, node, descriptor) + override fun compareTo(other: FXMeta<*>): Int { + return if (this.hasValue.get() == other.hasValue.get()) { + this.name.toString().compareTo(other.name.toString()) + } else { + this.hasValue.get().compareTo(other.hasValue.get()) + } + } - fun root(node: Meta, descriptor: NodeDescriptor? = null): FXMetaNode = - root(node.seal(), descriptor) + companion object { + fun > root( + node: M, + descriptor: NodeDescriptor? = null, + rootName: String = "root" + ): FXMetaNode = + FXMetaNode(NameToken(rootName), null, node, descriptor) + + fun root(node: Meta, descriptor: NodeDescriptor? = null, rootName: String = "root"): FXMetaNode = + root(node.seal(), descriptor, rootName) } } class FXMetaNode>( override val name: NameToken, override val parent: FXMetaNode?, - node: M? = null, - descriptor: NodeDescriptor? = null -) : FXMeta() { + nodeValue: M? = null, + descriptorValue: NodeDescriptor? = null +) : FXMeta() { /** * A descriptor that could be manually set to the node */ - val descriptorProperty = SimpleObjectProperty(descriptor) + private val innerDescriptorProperty = SimpleObjectProperty(descriptorValue) /** * Actual descriptor which holds value inferred from parrent */ - private val actualDescriptorProperty = objectBinding(descriptorProperty) { + val descriptorProperty = objectBinding(innerDescriptorProperty) { value ?: parent?.descriptor?.nodes?.get(this@FXMetaNode.name.body) } - val descriptor: NodeDescriptor? by actualDescriptorProperty + override val descriptor: NodeDescriptor? by descriptorProperty - private val innerNodeProperty = SimpleObjectProperty(node) + private val innerNodeProperty = SimpleObjectProperty(nodeValue) val nodeProperty: ObjectBinding = objectBinding(innerNodeProperty) { - value ?: parent?.node?.get(this@FXMetaNode.name.asName()).node + value ?: parent?.node?.get(this@FXMetaNode.name).node } val node: M? by nodeProperty - override val descriptionProperty = descriptorProperty.stringBinding { it?.info ?: "" } + override val descriptionProperty = innerDescriptorProperty.stringBinding { it?.info ?: "" } override val hasValue: ObservableBooleanValue = nodeProperty.booleanBinding { it != null } - val children = object : ListBinding() { - override fun computeValue(): ObservableList { - TODO() + private val filter: (FXMeta) -> Boolean = { cfg -> + !(cfg.descriptor?.tags?.contains(ConfigEditor.NO_CONFIGURATOR_TAG) ?: false) + } + + val children = object : ListBinding>() { + + init { + bind(nodeProperty, descriptorProperty) + + val listener: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit = { name, _, _ -> + if (name.length == 1) invalidate() + } + + (node as? MutableMeta<*>)?.onChange(this, listener) + + nodeProperty.addListener { _, oldValue, newValue -> + if (newValue == null) { + (oldValue as? MutableMeta<*>)?.removeListener(this) + } + + if (newValue is MutableMeta<*>) { + newValue.onChange(this, listener) + } + } + } + + override fun computeValue(): ObservableList> { + val nodeKeys = node?.items?.keys?.toSet() ?: emptySet() + val descriptorKeys = descriptor?.items?.keys?.map { NameToken(it) } ?: emptyList() + val keys: Set = nodeKeys + descriptorKeys + + val items = keys.map { token -> + val actualItem = node?.items?.get(token) + val actualDescriptor = descriptor?.items?.get(token.body) + + if (actualItem is MetaItem.NodeItem || actualDescriptor is NodeDescriptor) { + FXMetaNode(token, this@FXMetaNode) + } else { + FXMetaValue(token, this@FXMetaNode) + } + } + + return items.filter(filter).observable() + } + } + + init { + if (parent != null) { + parent.descriptorProperty.onChange { descriptorProperty.invalidate() } + parent.nodeProperty.onChange { nodeProperty.invalidate() } } } } -class FXMetaValue( +class FXMetaValue>( override val name: NameToken, - override val parent: FXMetaNode<*>, - value: Value? = null -) : FXMeta() { + override val parent: FXMetaNode +) : FXMeta() { val descriptorProperty = parent.descriptorProperty.objectBinding { it?.values?.get(name.body) @@ -82,15 +148,15 @@ class FXMetaValue( /** * A descriptor that could be manually set to the node */ - val descriptor by descriptorProperty + override val descriptor: ValueDescriptor? by descriptorProperty - private val innerValueProperty = SimpleObjectProperty(value) + //private val innerValueProperty = SimpleObjectProperty(value) val valueProperty = descriptorProperty.objectBinding { descriptor -> parent.node[name].value ?: descriptor?.default } - override val hasValue: ObservableBooleanValue = valueProperty.booleanBinding { it != null } + override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it[name] != null } val value by valueProperty @@ -102,18 +168,36 @@ fun > FXMetaNode.remove(name: NameToken) { children.invalidate() } -fun FXMeta.remove() { - (parent?.node as? MutableMeta<*>)?.remove(name.asName()) +private fun > M.createEmptyNode(token: NameToken): M { + this.setNode(token.asName(), EmptyMeta) + //FIXME possible concurrency bug + return get(token).node!! } -fun > FXMetaNode.addValue(key: String){ - TODO() +fun > FXMetaNode.getOrCreateNode(): M { + val node = node + return when { + node != null -> node + parent != null -> parent.getOrCreateNode().createEmptyNode(this.name).also { + parent.children.invalidate() + } + else -> kotlin.error("Orphan empty node is not allowed") + } + } -fun > FXMetaNode.addNode(key: String){ - TODO() +fun > FXMeta.remove() { + parent?.node?.remove(name.asName()) } -fun FXMetaValue.set(value: Value?){ - TODO() +fun > FXMetaNode.addValue(key: String) { + getOrCreateNode()[key] = Null +} + +fun > FXMetaNode.addNode(key: String) { + getOrCreateNode()[key] = EmptyMeta +} + +fun > FXMetaValue.set(value: Value?) { + parent.getOrCreateNode()[this.name] = value } \ No newline at end of file diff --git a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/MetaViewer.kt b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/MetaViewer.kt index 3eddfb78..2e5697a1 100644 --- a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/MetaViewer.kt +++ b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/MetaViewer.kt @@ -17,7 +17,6 @@ package hep.dataforge.vis.fx.meta import hep.dataforge.meta.Meta -import hep.dataforge.meta.seal import hep.dataforge.vis.fx.dfIconView import javafx.beans.property.SimpleStringProperty import javafx.scene.control.TreeItem @@ -25,15 +24,17 @@ import javafx.scene.control.TreeSortMode import javafx.scene.control.TreeTableView import tornadofx.* -open class MetaViewer(val meta: Meta, title: String = "Meta viewer") : Fragment(title, dfIconView) { +class MetaViewer(val rootNode: FXMetaNode<*>, title: String = "Meta viewer") : Fragment(title, dfIconView) { + constructor(meta: Meta, title: String = "Meta viewer"): this(FXMeta.root(meta)) + override val root = borderpane { center { - treetableview { + treetableview> { isShowRoot = false - root = TreeItem(FXMeta.root(meta.seal())) + root = TreeItem(rootNode) populate { when (val fxMeta = it.value) { - is FXMetaNode<*> -> { + is FXMetaNode -> { fxMeta.children } is FXMetaValue -> null @@ -42,11 +43,11 @@ open class MetaViewer(val meta: Meta, title: String = "Meta viewer") : Fragment( root.isExpanded = true sortMode = TreeSortMode.ALL_DESCENDANTS columnResizePolicy = TreeTableView.CONSTRAINED_RESIZE_POLICY - column("Name", FXMeta::name) - column("Value"){ - when(val item = it.value.value){ - is FXMetaValue -> item.valueProperty.stringBinding{it?.string?: ""} - is FXMetaNode<*> -> SimpleStringProperty("[node]") + column("Name", FXMeta<*>::name) + column, String>("Value") { cellDataFeatures -> + when (val item = cellDataFeatures.value.value) { + is FXMetaValue -> item.valueProperty.stringBinding { it?.string ?: "" } + is FXMetaNode -> SimpleStringProperty("[node]") } } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 3cb6cf55..f128394c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -31,7 +31,9 @@ include( //if(file("../dataforge-core").exists()) { // includeBuild("../dataforge-core"){ // dependencySubstitution { -// substitute(module("hep.dataforge:dataforge-output")).with(project(":dataforge-output")) +// //substitute(module("hep.dataforge:dataforge-output")).with(project(":dataforge-output")) +// substitute(module("hep.dataforge:dataforge-output-jvm")).with(project(":dataforge-output")) +// substitute(module("hep.dataforge:dataforge-output-js")).with(project(":dataforge-output")) // } // } //} \ No newline at end of file