Demo structure change and fx update

This commit is contained in:
Alexander Nozik 2019-12-24 14:14:10 +03:00
parent a564e078e5
commit 8d39a3efa5
43 changed files with 514 additions and 81 deletions

View File

@ -29,6 +29,7 @@ kotlin {
dependencies { dependencies {
api("hep.dataforge:dataforge-output-html:$dataforgeVersion") api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
api(npm("bootstrap","4.4.1")) api(npm("bootstrap","4.4.1"))
implementation(npm("jsoneditor"))
} }
} }
} }

View File

@ -27,18 +27,21 @@ class StyleSheet() {
return styleMap[key] ?: (owner?.parent as? VisualGroup)?.styleSheet?.get(key) return styleMap[key] ?: (owner?.parent as? VisualGroup)?.styleSheet?.get(key)
} }
operator fun set(key: String, style: Meta?) { /**
val oldStyle = styleMap[key] * Define a style without notifying
*/
fun define(key: String, style: Meta?) {
if (style == null) { if (style == null) {
styleMap.remove(key) styleMap.remove(key)
} else { } else {
styleMap[key] = style styleMap[key] = style
} }
owner?.styleChanged(key, oldStyle, style)
} }
infix fun String.put(style: Meta?) { operator fun set(key: String, style: Meta?) {
set(this, style) val oldStyle = styleMap[key]
define(key, style)
owner?.styleChanged(key, oldStyle, style)
} }
operator fun set(key: String, builder: MetaBuilder.() -> Unit) { operator fun set(key: String, builder: MetaBuilder.() -> Unit) {

View File

@ -1,6 +1,7 @@
package hep.dataforge.js package hep.dataforge.js
external fun require(name: String): dynamic @JsName("require")
external fun requireJS(name: String): dynamic
inline fun <T : Any> jsObject(builder: T.() -> Unit): T { inline fun <T : Any> jsObject(builder: T.() -> Unit): T {
val obj: T = js("({})") as T val obj: T = js("({})") as T

View File

@ -1,4 +1,4 @@
package hep.dataforge.vis.spatial.editor package hep.dataforge.vis.js.editor
import kotlinx.html.TagConsumer import kotlinx.html.TagConsumer
import kotlinx.html.js.div import kotlinx.html.js.div

View File

@ -4,7 +4,7 @@ import hep.dataforge.names.NameToken
import hep.dataforge.vis.common.VisualGroup import hep.dataforge.vis.common.VisualGroup
import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.isEmpty import hep.dataforge.vis.common.isEmpty
import hep.dataforge.vis.spatial.editor.card import hep.dataforge.vis.js.editor.card
import kotlinx.html.TagConsumer import kotlinx.html.TagConsumer
import kotlinx.html.dom.append import kotlinx.html.dom.append
import kotlinx.html.js.* import kotlinx.html.js.*

View File

@ -0,0 +1,185 @@
@file:Suppress(
"INTERFACE_WITH_SUPERCLASS",
"OVERRIDING_FINAL_MEMBER",
"RETURN_TYPE_MISMATCH_ON_OVERRIDE",
"CONFLICTING_OVERLOADS",
"EXTERNAL_DELEGATION"
)
package hep.dataforge.vis.js.editor
import org.w3c.dom.HTMLElement
external interface Node {
var field: String
var value: String? get() = definedExternally; set(value) = definedExternally
var path: dynamic
}
external interface NodeName {
var path: Array<String>
var type: dynamic /* 'object' | 'array' */
var size: Number
}
external interface ValidationError {
var path: dynamic
var message: String
}
external interface Template {
var text: String
var title: String
var className: String? get() = definedExternally; set(value) = definedExternally
var field: String
var value: Any
}
external interface `T$6` {
var startFrom: Number
var options: Array<String>
}
external interface AutoCompleteOptions {
var confirmKeys: Array<Number>? get() = definedExternally; set(value) = definedExternally
var caseSensitive: Boolean? get() = definedExternally; set(value) = definedExternally
// var getOptions: AutoCompleteOptionsGetter? get() = definedExternally; set(value) = definedExternally
}
external interface SelectionPosition {
var row: Number
var column: Number
}
external interface SerializableNode {
var value: Any
var path: dynamic
}
external interface Color {
var rgba: Array<Number>
var hsla: Array<Number>
var rgbString: String
var rgbaString: String
var hslString: String
var hslaString: String
var hex: String
}
//external interface `T$0` {
// var field: Boolean
// var value: Boolean
//}
//
//external interface `T$1` {
// @nativeGetter
// operator fun get(key: String): String?
//
// @nativeSetter
// operator fun set(key: String, value: String)
//}
//external interface Languages {
// @nativeGetter
// operator fun get(lang: String): `T$1`?
//
// @nativeSetter
// operator fun set(lang: String, value: `T$1`)
//}
external interface JSONEditorOptions {
// var ace: AceAjax.Ace? get() = definedExternally; set(value) = definedExternally
// var ajv: Ajv? get() = definedExternally; set(value) = definedExternally
var onChange: (() -> Unit)? get() = definedExternally; set(value) = definedExternally
var onChangeJSON: ((json: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally
var onChangeText: ((jsonString: String) -> Unit)? get() = definedExternally; set(value) = definedExternally
var onEditable: ((node: Node) -> dynamic)? get() = definedExternally; set(value) = definedExternally
var onError: ((error: Error) -> Unit)? get() = definedExternally; set(value) = definedExternally
var onModeChange: ((newMode: dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */, oldMode: dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */) -> Unit)? get() = definedExternally; set(value) = definedExternally
var onNodeName: ((nodeName: NodeName) -> String?)? get() = definedExternally; set(value) = definedExternally
var onValidate: ((json: Any) -> dynamic)? get() = definedExternally; set(value) = definedExternally
var escapeUnicode: Boolean? get() = definedExternally; set(value) = definedExternally
var sortObjectKeys: Boolean? get() = definedExternally; set(value) = definedExternally
var history: Boolean? get() = definedExternally; set(value) = definedExternally
var mode: dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */
var modes: Array<dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */>? get() = definedExternally; set(value) = definedExternally
var name: String? get() = definedExternally; set(value) = definedExternally
var schema: Any? get() = definedExternally; set(value) = definedExternally
var schemaRefs: Any? get() = definedExternally; set(value) = definedExternally
var search: Boolean? get() = definedExternally; set(value) = definedExternally
var indentation: Number? get() = definedExternally; set(value) = definedExternally
var theme: String? get() = definedExternally; set(value) = definedExternally
var templates: Array<Template>? get() = definedExternally; set(value) = definedExternally
var autocomplete: AutoCompleteOptions? get() = definedExternally; set(value) = definedExternally
var mainMenuBar: Boolean? get() = definedExternally; set(value) = definedExternally
var navigationBar: Boolean? get() = definedExternally; set(value) = definedExternally
var statusBar: Boolean? get() = definedExternally; set(value) = definedExternally
var onTextSelectionChange: ((start: SelectionPosition, end: SelectionPosition, text: String) -> Unit)? get() = definedExternally; set(value) = definedExternally
var onSelectionChange: ((start: SerializableNode, end: SerializableNode) -> Unit)? get() = definedExternally; set(value) = definedExternally
var onEvent: ((node: Node, event: String) -> Unit)? get() = definedExternally; set(value) = definedExternally
var colorPicker: Boolean? get() = definedExternally; set(value) = definedExternally
var onColorPicker: ((parent: HTMLElement, color: String, onChange: (color: Color) -> Unit) -> Unit)? get() = definedExternally; set(value) = definedExternally
var timestampTag: Boolean? get() = definedExternally; set(value) = definedExternally
var language: String? get() = definedExternally; set(value) = definedExternally
//var languages: Languages? get() = definedExternally; set(value) = definedExternally
var modalAnchor: HTMLElement? get() = definedExternally; set(value) = definedExternally
var enableSort: Boolean? get() = definedExternally; set(value) = definedExternally
var enableTransform: Boolean? get() = definedExternally; set(value) = definedExternally
var maxVisibleChilds: Number? get() = definedExternally; set(value) = definedExternally
}
external interface JsonPath {
var path: dynamic
}
external interface EditorSelection {
var start: SerializableNode
var end: SerializableNode
}
external interface TextSelection {
var start: SelectionPosition
var end: SelectionPosition
var text: String
}
@JsModule("jsoneditor")
@JsNonModule
external open class JSONEditor(
container: HTMLElement,
options: JSONEditorOptions? = definedExternally /* null */,
json: dynamic = definedExternally /* null */
) {
open fun collapseAll()
open fun destroy()
open fun expandAll()
open fun focus()
open fun get(): Any
open fun getMode(): dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */
open fun getName(): String?
open fun getNodesByRange(start: JsonPath, end: JsonPath): Array<SerializableNode>
open fun getSelection(): EditorSelection
open fun getText(): String
open fun getTextSelection(): TextSelection
open fun refresh()
open fun set(json: Any)
open fun setMode(mode: String /* 'tree' */)
open fun setMode(mode: String /* 'view' */)
open fun setMode(mode: String /* 'form' */)
open fun setMode(mode: String /* 'code' */)
open fun setMode(mode: String /* 'text' */)
open fun setName(name: String? = definedExternally /* null */)
open fun setSchema(schema: Any?, schemaRefs: Any? = definedExternally /* null */)
open fun setSelection(start: JsonPath, end: JsonPath)
open fun setText(jsonString: String)
open fun setTextSelection(start: SelectionPosition, end: SelectionPosition)
open fun update(json: Any)
open fun updateText(jsonString: String)
companion object {
var VALID_OPTIONS: Array<String>
// var ace: AceAjax.Ace
// var Ajv: Ajv
var VanillaPicker: Any
}
}

View File

@ -1,17 +1,12 @@
package hep.dataforge.vis.spatial.editor package hep.dataforge.vis.js.editor
import hep.dataforge.io.toJson import hep.dataforge.io.toJson
import hep.dataforge.js.jsObject import hep.dataforge.js.jsObject
import hep.dataforge.meta.DynamicMeta import hep.dataforge.meta.DynamicMeta
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.builder
import hep.dataforge.meta.update import hep.dataforge.meta.update
import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.findStyle import hep.dataforge.vis.common.findStyle
import hep.dataforge.vis.spatial.*
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
import kotlinx.html.dom.append import kotlinx.html.dom.append
import kotlinx.html.js.div import kotlinx.html.js.div
import kotlinx.html.js.h4 import kotlinx.html.js.h4
@ -21,21 +16,13 @@ import kotlin.dom.clear
//FIXME something rotten in JS-Meta converter //FIXME something rotten in JS-Meta converter
fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString()) fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString())
//TODO add node descriptor instead of configuring property selector
fun Element.propertyEditor(item: VisualObject?) { fun Element.propertyEditor(item: VisualObject?, propertySelector: (VisualObject) -> Meta = { it.config }) {
clear() clear()
if (item != null) { if (item != null) {
append { append {
card("Properties") { card("Properties") {
val config: Meta = item.prototype.config val dMeta: dynamic = propertySelector(item).toDynamic()
val metaToEdit = config.builder().apply {
VISIBLE_KEY to (item.visible ?: true)
if (item is VisualObject3D) {
MATERIAL_COLOR_KEY to (item.color ?: "#ffffff")
MATERIAL_OPACITY_KEY to (item.opacity ?: 1.0)
}
}
val dMeta: dynamic = metaToEdit.toDynamic()
val options: JSONEditorOptions = jsObject { val options: JSONEditorOptions = jsObject {
mode = "form" mode = "form"
onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) } onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) }
@ -48,13 +35,17 @@ fun Element.propertyEditor(item: VisualObject?) {
card("Styles") { card("Styles") {
item.styles.forEach { style -> item.styles.forEach { style ->
val styleMeta = item.findStyle(style) val styleMeta = item.findStyle(style)
h4("container") { +style.toString() } h4("container") { +style }
if (styleMeta != null) { if (styleMeta != null) {
div("container").apply { div("container").apply {
val options: JSONEditorOptions = jsObject { val options: JSONEditorOptions = jsObject {
mode = "view" mode = "view"
} }
JSONEditor(this, options, styleMeta.toDynamic()) JSONEditor(
this,
options,
styleMeta.toDynamic()
)
} }
} }
} }
@ -62,4 +53,4 @@ fun Element.propertyEditor(item: VisualObject?) {
} }
} }
} }
} }

View File

@ -1,4 +1,4 @@
package hep.dataforge.vis.fx.values package hep.dataforge.vis.fx.editor
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.names.Name import hep.dataforge.names.Name
@ -44,6 +44,7 @@ class ColorValueChooser : ValueChooserBase<ColorPicker>() {
companion object : ValueChooser.Factory { companion object : ValueChooser.Factory {
override val name: Name = "color".asName() override val name: Name = "color".asName()
override fun invoke(meta: Meta): ValueChooser = ColorValueChooser() override fun invoke(meta: Meta): ValueChooser =
ColorValueChooser()
} }
} }

View File

@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package hep.dataforge.vis.fx.values package hep.dataforge.vis.fx.editor
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.get import hep.dataforge.meta.get
@ -54,7 +54,8 @@ class ComboBoxValueChooser(val values: Collection<Value>? = null) : ValueChooser
companion object : ValueChooser.Factory { companion object : ValueChooser.Factory {
override val name: Name = "combo".asName() override val name: Name = "combo".asName()
override fun invoke(meta: Meta): ValueChooser = ComboBoxValueChooser(meta["values"].value?.list) override fun invoke(meta: Meta): ValueChooser =
ComboBoxValueChooser(meta["values"].value?.list)
} }
} }

View File

@ -3,14 +3,13 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package hep.dataforge.vis.fx.meta package hep.dataforge.vis.fx.editor
import hep.dataforge.context.Global import hep.dataforge.context.Global
import hep.dataforge.descriptors.NodeDescriptor import hep.dataforge.descriptors.NodeDescriptor
import hep.dataforge.meta.Config import hep.dataforge.meta.Config
import hep.dataforge.names.NameToken import hep.dataforge.names.NameToken
import hep.dataforge.vis.fx.dfIconView import hep.dataforge.vis.fx.dfIconView
import hep.dataforge.vis.fx.values.ValueChooser
import javafx.scene.control.* import javafx.scene.control.*
import javafx.scene.control.cell.TextFieldTreeTableCell import javafx.scene.control.cell.TextFieldTreeTableCell
import javafx.scene.layout.Priority import javafx.scene.layout.Priority
@ -29,8 +28,9 @@ class ConfigEditor(
val allowNew: Boolean = true, val allowNew: Boolean = true,
title: String = "Configuration editor" title: String = "Configuration editor"
) : Fragment(title = title, icon = dfIconView) { ) : Fragment(title = title, icon = dfIconView) {
//TODO replace parameters by properties
constructor(config: Config, descriptor: NodeDescriptor, title: String = "Configuration editor") : constructor(config: Config, descriptor: NodeDescriptor?, title: String = "Configuration editor") :
this(FXMeta.root(config, descriptor = descriptor), title = title) this(FXMeta.root(config, descriptor = descriptor), title = title)
override val root = borderpane { override val root = borderpane {

View File

@ -1,4 +1,4 @@
package hep.dataforge.vis.fx.meta package hep.dataforge.vis.fx.editor
import hep.dataforge.descriptors.ItemDescriptor import hep.dataforge.descriptors.ItemDescriptor
import hep.dataforge.descriptors.NodeDescriptor import hep.dataforge.descriptors.NodeDescriptor

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package hep.dataforge.vis.fx.meta package hep.dataforge.vis.fx.editor
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.vis.fx.dfIconView import hep.dataforge.vis.fx.dfIconView

View File

@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package hep.dataforge.vis.fx.values package hep.dataforge.vis.fx.editor
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.names.Name import hep.dataforge.names.Name
@ -103,6 +103,7 @@ class TextValueChooser : ValueChooserBase<TextField>() {
companion object : ValueChooser.Factory { companion object : ValueChooser.Factory {
override val name: Name = "text".asName() override val name: Name = "text".asName()
override fun invoke(meta: Meta): ValueChooser = TextValueChooser() override fun invoke(meta: Meta): ValueChooser =
TextValueChooser()
} }
} }

View File

@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package hep.dataforge.vis.fx.values package hep.dataforge.vis.fx.editor
import hep.dataforge.values.Value import hep.dataforge.values.Value

View File

@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package hep.dataforge.vis.fx.values package hep.dataforge.vis.fx.editor
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.context.Named import hep.dataforge.context.Named
@ -87,7 +87,10 @@ interface ValueChooser {
val widgetType = descriptor.widgetType val widgetType = descriptor.widgetType
val chooser: ValueChooser = when { val chooser: ValueChooser = when {
widgetType != null -> { widgetType != null -> {
findWidgetByType(context, widgetType)?.invoke( findWidgetByType(
context,
widgetType
)?.invoke(
descriptor.widget descriptor.widget
) ?: TextValueChooser() ) ?: TextValueChooser()
} }
@ -105,7 +108,8 @@ interface ValueChooser {
descriptor: ValueDescriptor? = null, descriptor: ValueDescriptor? = null,
setter: (Value) -> Unit setter: (Value) -> Unit
): ValueChooser { ): ValueChooser {
val chooser = build(context, descriptor) val chooser =
build(context, descriptor)
chooser.setDisplayValue(value.value ?: Null) chooser.setDisplayValue(value.value ?: Null)
value.onChange { value.onChange {
chooser.setDisplayValue(it ?: Null) chooser.setDisplayValue(it ?: Null)
@ -115,7 +119,11 @@ interface ValueChooser {
setter(result) setter(result)
ValueCallbackResponse(true, result, "OK") ValueCallbackResponse(true, result, "OK")
} else { } else {
ValueCallbackResponse(false, value.value ?: Null, "Not allowed") ValueCallbackResponse(
false,
value.value ?: Null,
"Not allowed"
)
} }
} }
return chooser return chooser

View File

@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package hep.dataforge.vis.fx.values package hep.dataforge.vis.fx.editor
import hep.dataforge.descriptors.ValueDescriptor import hep.dataforge.descriptors.ValueDescriptor
import hep.dataforge.values.Null import hep.dataforge.values.Null

View File

@ -0,0 +1,59 @@
package hep.dataforge.vis.fx.editor
import hep.dataforge.descriptors.NodeDescriptor
import hep.dataforge.meta.Config
import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.findStyle
import javafx.beans.binding.Binding
import javafx.beans.property.SimpleObjectProperty
import javafx.scene.Node
import javafx.scene.Parent
import javafx.scene.layout.VBox
import tornadofx.*
class VisualObjectEditorFragment(val selector: (VisualObject) -> Config) : Fragment() {
val itemProperty = SimpleObjectProperty<VisualObject>()
var item: VisualObject? by itemProperty
val descriptorProperty = SimpleObjectProperty<NodeDescriptor>()
constructor(
item: VisualObject?,
descriptor: NodeDescriptor?,
selector: (VisualObject) -> Config = { it.config }
) : this(selector) {
this.item = item
this.descriptorProperty.set(descriptor)
}
private val configProperty: Binding<Config?> = itemProperty.objectBinding {
it?.let { selector(it) }
}
private val configEditorProperty: Binding<Node?> = configProperty.objectBinding(descriptorProperty) {
it?.let {
ConfigEditor(it, descriptorProperty.get()).root
}
}
private val styleBoxProperty: Binding<Node?> = configProperty.objectBinding() {
VBox().apply {
item?.styles?.forEach { styleName ->
val styleMeta = item?.findStyle(styleName)
if (styleMeta != null) {
titledpane(styleName, node = MetaViewer(styleMeta).root)
}
}
}
}
override val root: Parent = vbox {
titledpane("Properties", collapsible = false) {
contentProperty().bind(configEditorProperty)
}
titledpane("Styles", collapsible = false) {
visibleWhen(itemProperty.booleanBinding { it?.styles?.isNotEmpty() ?: false })
contentProperty().bind(styleBoxProperty)
}
}
}

View File

@ -0,0 +1,33 @@
package hep.dataforge.vis.fx.editor
import hep.dataforge.vis.common.VisualGroup
import hep.dataforge.vis.common.VisualObject
import javafx.beans.property.SimpleObjectProperty
import javafx.scene.control.SelectionMode
import javafx.scene.control.TreeItem
import tornadofx.*
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> {
itemProperty.onChange { rootObject ->
if (rootObject != null) {
root = TreeItem(rootObject)
populate { item ->
(item.value as? VisualGroup)?.children?.values?.toList()
}
}
}
selectionModel.selectionMode = SelectionMode.SINGLE
val selectedValue = selectionModel.selectedItemProperty().objectBinding{it?.value}
selectedProperty.bind(selectedValue)
}
}
}
}

View File

@ -4,9 +4,9 @@ import hep.dataforge.descriptors.NodeDescriptor
import hep.dataforge.meta.buildMeta import hep.dataforge.meta.buildMeta
import hep.dataforge.meta.toConfig import hep.dataforge.meta.toConfig
import hep.dataforge.values.ValueType import hep.dataforge.values.ValueType
import hep.dataforge.vis.fx.meta.ConfigEditor import hep.dataforge.vis.fx.editor.ConfigEditor
import hep.dataforge.vis.fx.meta.FXMeta import hep.dataforge.vis.fx.editor.FXMeta
import hep.dataforge.vis.fx.meta.MetaViewer import hep.dataforge.vis.fx.editor.MetaViewer
import javafx.geometry.Orientation import javafx.geometry.Orientation
import tornadofx.* import tornadofx.*

View File

@ -16,7 +16,7 @@ import scientifik.gdml.*
import kotlin.random.Random import kotlin.random.Random
class GDMLTransformer(val root: GDML) { class GDMLTransformer(val root: GDML) {
private val materialCache = HashMap<GDMLMaterial, Meta>() //private val materialCache = HashMap<GDMLMaterial, Meta>()
private val random = Random(222) private val random = Random(222)
enum class Action { enum class Action {
@ -39,7 +39,7 @@ class GDMLTransformer(val root: GDML) {
var solidConfiguration: VisualObject3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { _, _ -> } var solidConfiguration: VisualObject3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { _, _ -> }
fun VisualObject.useStyle(name: String, builder: MetaBuilder.() -> Unit) { fun VisualObject3D.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
styleCache.getOrPut(name.toName()) { styleCache.getOrPut(name.toName()) {
buildMeta(builder) buildMeta(builder)
} }
@ -69,7 +69,7 @@ class GDMLTransformer(val root: GDML) {
final.prototypes = proto final.prototypes = proto
styleCache.forEach { styleCache.forEach {
final.styleSheet { final.styleSheet {
this[it.key.toString()] = it.value define(it.key.toString(), it.value)
} }
} }
final.rotationOrder = RotationOrder.ZXY final.rotationOrder = RotationOrder.ZXY
@ -77,4 +77,4 @@ class GDMLTransformer(val root: GDML) {
return final return final
} }
} }

View File

@ -256,6 +256,6 @@ fun GDML.toVisual(block: GDMLTransformer.() -> Unit = {}): VisualGroup3D {
*/ */
fun VisualGroup3D.gdml(gdml: GDML, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) { fun VisualGroup3D.gdml(gdml: GDML, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) {
val visual = gdml.toVisual(transformer) val visual = gdml.toVisual(transformer)
println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual)) //println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual))
set(key, visual) set(key, visual)
} }

File diff suppressed because one or more lines are too long

View File

@ -6,8 +6,13 @@ import scientifik.gdml.GDML
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
fun VisualGroup3D.gdml(file: Path, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) { fun GDML.Companion.readFile(file: Path): GDML {
val xmlReader = StAXReader(Files.newInputStream(file), "UTF-8") val xmlReader = StAXReader(Files.newInputStream(file), "UTF-8")
val gdml = GDML.format.parse(GDML.serializer(), xmlReader) return GDML.format.parse(GDML.serializer(), xmlReader)
}
fun VisualGroup3D.gdml(file: Path, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) {
val gdml = GDML.readFile(file)
gdml(gdml, key, transformer) gdml(gdml, key, transformer)
} }

View File

@ -28,7 +28,7 @@ kotlin {
} }
jsMain { jsMain {
dependencies { dependencies {
api(project(":wrappers")) // api(project(":wrappers"))
implementation(npm("three", "0.106.2")) implementation(npm("three", "0.106.2"))
implementation(npm("@hi-level/three-csg", "1.0.6")) implementation(npm("@hi-level/three-csg", "1.0.6"))
} }

View File

@ -1,6 +1,6 @@
package hep.dataforge.vis.spatial.editor package hep.dataforge.vis.spatial.three
import hep.dataforge.vis.spatial.three.ThreeCanvas import hep.dataforge.vis.js.editor.card
import kotlinx.html.InputType import kotlinx.html.InputType
import kotlinx.html.dom.append import kotlinx.html.dom.append
import kotlinx.html.js.div import kotlinx.html.js.div

View File

@ -10,6 +10,9 @@ import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_DISTANCE
import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_X_ANGLE import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_X_ANGLE
import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_Y_ANGLE import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_Y_ANGLE
import hep.dataforge.vis.spatial.World.CAMERA_NEAR_CLIP import hep.dataforge.vis.spatial.World.CAMERA_NEAR_CLIP
import javafx.application.Platform
import javafx.beans.property.ObjectProperty
import javafx.beans.property.SimpleObjectProperty
import javafx.event.EventHandler import javafx.event.EventHandler
import javafx.scene.* import javafx.scene.*
import javafx.scene.input.KeyCode import javafx.scene.input.KeyCode
@ -80,9 +83,26 @@ class FXCanvas3D(val plugin: FX3DPlugin, meta: Meta = EmptyMeta) :
center = canvas center = canvas
} }
val rootObjectProperty: ObjectProperty<VisualObject3D> = SimpleObjectProperty()
var rootObject: VisualObject3D? by rootObjectProperty
private val rootNodeProperty = rootObjectProperty.objectBinding {
it?.let { plugin.buildNode(it) }
}
init { init {
canvas.widthProperty().bind(root.widthProperty()) canvas.widthProperty().bind(root.widthProperty())
canvas.heightProperty().bind(root.heightProperty()) canvas.heightProperty().bind(root.heightProperty())
rootNodeProperty.addListener { _, oldValue: Node?, newValue: Node? ->
Platform.runLater {
if (oldValue != null) {
world.children.remove(oldValue)
}
if (newValue != null) {
world.children.add(newValue)
}
}
}
} }
@ -167,8 +187,7 @@ class FXCanvas3D(val plugin: FX3DPlugin, meta: Meta = EmptyMeta) :
} }
override fun render(obj: VisualObject3D, meta: Meta) { override fun render(obj: VisualObject3D, meta: Meta) {
val node = plugin.buildNode(obj) ?: kotlin.error("Can't render FX node for object $obj") rootObject = obj
world.children.add(node)
} }
companion object { companion object {

0
demo/build.gradle.kts Normal file
View File

View File

@ -0,0 +1,39 @@
import org.openjfx.gradle.JavaFXOptions
plugins {
id("scientifik.mpp")
id("org.openjfx.javafxplugin")
id("application")
}
kotlin {
jvm {
withJava()
}
js {
browser {
webpackTask {
sourceMaps = false
}
}
}
sourceSets {
commonMain {
dependencies {
api(project(":dataforge-vis-spatial"))
api(project(":dataforge-vis-spatial-gdml"))
}
}
}
}
application {
mainClassName = "hep.dataforge.vis.spatial.gdml.demo.GDMLDemoAppKt"
}
configure<JavaFXOptions> {
modules("javafx.controls")
}

View File

@ -4,13 +4,15 @@ import hep.dataforge.context.Global
import hep.dataforge.js.Application import hep.dataforge.js.Application
import hep.dataforge.js.objectTree import hep.dataforge.js.objectTree
import hep.dataforge.js.startApplication import hep.dataforge.js.startApplication
import hep.dataforge.meta.Meta
import hep.dataforge.meta.builder
import hep.dataforge.names.NameToken import hep.dataforge.names.NameToken
import hep.dataforge.vis.spatial.*
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vis.spatial.Visual3DPlugin import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
import hep.dataforge.vis.spatial.VisualGroup3D import hep.dataforge.vis.js.editor.propertyEditor
import hep.dataforge.vis.spatial.VisualObject3D import hep.dataforge.vis.spatial.three.threeOutputConfig
import hep.dataforge.vis.spatial.editor.propertyEditor
import hep.dataforge.vis.spatial.editor.threeOutputConfig
import hep.dataforge.vis.spatial.gdml.GDMLTransformer import hep.dataforge.vis.spatial.gdml.GDMLTransformer
import hep.dataforge.vis.spatial.gdml.LUnit import hep.dataforge.vis.spatial.gdml.LUnit
import hep.dataforge.vis.spatial.gdml.toVisual import hep.dataforge.vis.spatial.gdml.toVisual
@ -153,7 +155,18 @@ private class GDMLDemoApp : Application {
output.camera.layers.set(0) output.camera.layers.set(0)
configElement.threeOutputConfig(output) configElement.threeOutputConfig(output)
//tree.visualObjectTree(visual, editor::propertyEditor) //tree.visualObjectTree(visual, editor::propertyEditor)
treeElement.objectTree(NameToken("World"), visual, editorElement::propertyEditor) treeElement.objectTree(NameToken("World"), visual) {
editorElement.propertyEditor(it) {item->
val config: Meta = item.prototype.config
config.builder().apply {
VISIBLE_KEY to (item.visible ?: true)
if (item is VisualObject3D) {
MATERIAL_COLOR_KEY to (item.color ?: "#ffffff")
MATERIAL_OPACITY_KEY to (item.opacity ?: 1.0)
}
}
}
}
output.render(visual) output.render(visual)

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1,78 @@
package hep.dataforge.vis.spatial.gdml.demo
import hep.dataforge.context.Global
import hep.dataforge.vis.fx.editor.VisualObjectEditorFragment
import hep.dataforge.vis.fx.editor.VisualObjectTreeFragment
import hep.dataforge.vis.spatial.Material3D
import hep.dataforge.vis.spatial.fx.FX3DPlugin
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
import scientifik.gdml.GDML
import tornadofx.*
class GDMLDemoApp : App(GDMLView::class)
class GDMLView : View() {
private val fx3d = Global.plugins.fetch(FX3DPlugin)
private val canvas = FXCanvas3D(fx3d)
private val treeFragment = VisualObjectTreeFragment().apply {
this.itemProperty.bind(canvas.rootObjectProperty)
}
private val propertyEditor = VisualObjectEditorFragment { it.prototype.config }.apply {
//TODO add descriptor here
itemProperty.bind(treeFragment.selectedProperty)
}
override val root: Parent = borderpane {
top {
buttonbar {
button("Load GDML") {
action {
val file = chooseFile("Select a GDML file", filters = gdmlFilter).firstOrNull()
if (file != null) {
val obj = GDML.readFile(file.toPath()).toVisual {
lUnit = LUnit.CM
solidConfiguration = { parent, solid ->
if(solid.name == "cave"){
setProperty(Material3D.MATERIAL_WIREFRAME_KEY, true)
}
if (parent.physVolumes.isNotEmpty()) {
useStyle("opaque") {
Material3D.MATERIAL_OPACITY_KEY put 0.3
}
}
}
}
canvas.render(obj)
}
}
}
}
}
center {
splitpane(Orientation.HORIZONTAL, treeFragment.root, canvas.root, propertyEditor.root) {
setDividerPositions(0.2, 0.6, 0.2)
}
}
}
companion object {
private val gdmlFilter = arrayOf(
FileChooser.ExtensionFilter("GDML", "*.gdml", "*.xml")
)
}
}
fun main() {
launch<GDMLDemoApp>()
}

View File

@ -1,12 +1,9 @@
package hep.dataforge.vis.spatial.demo package hep.dataforge.vis.spatial.demo
import hep.dataforge.context.ContextBuilder
import hep.dataforge.context.Global
import hep.dataforge.js.Application import hep.dataforge.js.Application
import hep.dataforge.js.startApplication import hep.dataforge.js.startApplication
import hep.dataforge.vis.spatial.three.MeshThreeFactory.Companion.EDGES_ENABLED_KEY import hep.dataforge.vis.spatial.three.MeshThreeFactory.Companion.EDGES_ENABLED_KEY
import hep.dataforge.vis.spatial.three.MeshThreeFactory.Companion.WIREFRAME_ENABLED_KEY import hep.dataforge.vis.spatial.three.MeshThreeFactory.Companion.WIREFRAME_ENABLED_KEY
import hep.dataforge.vis.spatial.three.ThreePlugin
import hep.dataforge.vis.spatial.x import hep.dataforge.vis.spatial.x
import hep.dataforge.vis.spatial.y import hep.dataforge.vis.spatial.y
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope

View File

@ -4,14 +4,11 @@ import hep.dataforge.context.Global
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.buildMeta import hep.dataforge.meta.buildMeta
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.toName
import hep.dataforge.output.OutputManager import hep.dataforge.output.OutputManager
import hep.dataforge.output.Renderer import hep.dataforge.output.Renderer
import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.spatial.VisualGroup3D
import hep.dataforge.vis.spatial.fx.FX3DPlugin import hep.dataforge.vis.spatial.fx.FX3DPlugin
import hep.dataforge.vis.spatial.fx.FXCanvas3D import hep.dataforge.vis.spatial.fx.FXCanvas3D
import hep.dataforge.vis.spatial.render
import javafx.collections.FXCollections import javafx.collections.FXCollections
import javafx.scene.Parent import javafx.scene.Parent
import javafx.scene.control.Tab import javafx.scene.control.Tab

View File

@ -27,10 +27,11 @@ rootProject.name = "dataforge-vis"
include( include(
":dataforge-vis-common", ":dataforge-vis-common",
":wrappers", // ":wrappers",
":dataforge-vis-spatial", ":dataforge-vis-spatial",
":dataforge-vis-spatial-gdml", ":dataforge-vis-spatial-gdml",
":spatial-demo" ":demo:spatial-showcase",
":demo:gdml"
) )
//if(file("../dataforge-core").exists()) { //if(file("../dataforge-core").exists()) {