forked from kscience/visionforge
New layout
This commit is contained in:
parent
9f157a80b9
commit
0fbad16be6
@ -27,7 +27,7 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
||||
|
||||
override fun getStyle(name: Name): Meta? = styleSheet[name]
|
||||
|
||||
override fun addStyle(name: Name, meta: Meta) {
|
||||
override fun addStyle(name: Name, meta: Meta, apply: Boolean) {
|
||||
fun VisualObject.applyStyle(name: Name, meta: Meta) {
|
||||
if (styles.contains(name)) {
|
||||
//full update
|
||||
@ -45,8 +45,10 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
||||
}
|
||||
}
|
||||
styleSheet[name] = meta
|
||||
if (apply) {
|
||||
applyStyle(name, meta)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// init {
|
||||
|
@ -41,7 +41,7 @@ interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
|
||||
/**
|
||||
* Add or replace style with given name
|
||||
*/
|
||||
fun addStyle(name: Name, meta: Meta)
|
||||
fun addStyle(name: Name, meta: Meta, apply: Boolean = true)
|
||||
|
||||
operator fun get(name: Name): VisualObject? {
|
||||
return when {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package hep.dataforge.vis.hmr
|
||||
package hep.dataforge.vis
|
||||
|
||||
import kotlin.browser.document
|
||||
import kotlin.dom.hasClass
|
@ -1,6 +1,4 @@
|
||||
package hep.dataforge.vis.hmr
|
||||
|
||||
import kotlinext.js.objectAssign
|
||||
package hep.dataforge.vis
|
||||
|
||||
inline fun <T : Any> jsObject(builder: T.() -> Unit): T {
|
||||
val obj: T = js("({})") as T
|
@ -69,7 +69,7 @@ class GDMLTransformer(val root: GDML) {
|
||||
internal fun finalize(final: VisualGroup3D): VisualGroup3D {
|
||||
final.templates = templates
|
||||
styleCache.forEach {
|
||||
final.addStyle(it.key, it.value)
|
||||
final.addStyle(it.key, it.value, false)
|
||||
}
|
||||
final.rotationOrder = RotationOrder.ZXY
|
||||
onFinish(this@GDMLTransformer)
|
||||
|
@ -1,36 +1,26 @@
|
||||
package hep.dataforge.vis.spatial.gdml.demo
|
||||
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.hmr.ApplicationBase
|
||||
import hep.dataforge.vis.hmr.startApplication
|
||||
import hep.dataforge.vis.ApplicationBase
|
||||
import hep.dataforge.vis.spatial.Material3D.Companion.OPACITY_KEY
|
||||
import hep.dataforge.vis.spatial.Visual3DPlugin
|
||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||
import hep.dataforge.vis.spatial.VisualObject3D
|
||||
import hep.dataforge.vis.spatial.attachChildren
|
||||
import hep.dataforge.vis.spatial.editor.propertyEditor
|
||||
import hep.dataforge.vis.spatial.editor.threeOutputConfig
|
||||
import hep.dataforge.vis.spatial.editor.visualObjectTree
|
||||
import hep.dataforge.vis.spatial.gdml.GDMLTransformer
|
||||
import hep.dataforge.vis.spatial.gdml.LUnit
|
||||
import hep.dataforge.vis.spatial.gdml.toVisual
|
||||
import hep.dataforge.vis.spatial.three.ThreeOutput
|
||||
import hep.dataforge.vis.spatial.three.ThreePlugin
|
||||
import hep.dataforge.vis.spatial.three.output
|
||||
import hep.dataforge.vis.spatial.transform.RemoveSingleChild
|
||||
import hep.dataforge.vis.spatial.transform.UnRef
|
||||
import hep.dataforge.vis.spatial.transform.transformInPlace
|
||||
import hep.dataforge.vis.spatial.editor.propertyEditor
|
||||
import hep.dataforge.vis.spatial.editor.render
|
||||
import hep.dataforge.vis.spatial.editor.toTree
|
||||
import kotlinx.html.InputType
|
||||
import hep.dataforge.vis.startApplication
|
||||
import kotlinx.html.dom.append
|
||||
import kotlinx.html.js.input
|
||||
import kotlinx.html.js.li
|
||||
import kotlinx.html.js.p
|
||||
import kotlinx.html.js.ul
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.DragEvent
|
||||
import org.w3c.dom.HTMLDivElement
|
||||
import org.w3c.dom.HTMLElement
|
||||
import org.w3c.dom.events.Event
|
||||
import org.w3c.files.FileList
|
||||
import org.w3c.files.FileReader
|
||||
import org.w3c.files.get
|
||||
@ -43,33 +33,27 @@ private class GDMLDemoApp : ApplicationBase() {
|
||||
/**
|
||||
* Handle mouse drag according to https://www.html5rocks.com/en/tutorials/file/dndfiles/
|
||||
*/
|
||||
private fun handleDragOver(event: Event) {
|
||||
private fun handleDragOver(event: DragEvent) {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
event.asDynamic().dataTransfer.dropEffect = "copy"
|
||||
event.dataTransfer?.dropEffect = "copy"
|
||||
}
|
||||
|
||||
/**
|
||||
* Load data from text file
|
||||
*/
|
||||
private fun loadData(event: Event, block: (name: String, data: String) -> Unit) {
|
||||
private fun loadData(event: DragEvent, block: (name: String, data: String) -> Unit) {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
|
||||
|
||||
val file = (event.asDynamic().dataTransfer.files as FileList)[0]
|
||||
val file = (event.dataTransfer?.files as FileList)[0]
|
||||
?: throw RuntimeException("Failed to load file")
|
||||
|
||||
FileReader().apply {
|
||||
onload = {
|
||||
val string = result as String
|
||||
|
||||
// try {
|
||||
block(file.name, string)
|
||||
// } catch (ex: Exception) {
|
||||
// console.error(ex)
|
||||
// }
|
||||
|
||||
}
|
||||
readAsText(file)
|
||||
}
|
||||
@ -102,52 +86,22 @@ private class GDMLDemoApp : ApplicationBase() {
|
||||
}
|
||||
}
|
||||
|
||||
fun setupLayers(element: Element, output: ThreeOutput) {
|
||||
element.clear()
|
||||
element.append {
|
||||
ul("list-group") {
|
||||
(0..9).forEach { layer ->
|
||||
li("list-group-item") {
|
||||
+"layer $layer"
|
||||
input(type = InputType.checkBox).apply {
|
||||
if (layer == 0) {
|
||||
checked = true
|
||||
}
|
||||
onchange = {
|
||||
if (checked) {
|
||||
output.camera.layers.enable(layer)
|
||||
} else {
|
||||
output.camera.layers.disable(layer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val gdmlConfiguration: GDMLTransformer.() -> Unit = {
|
||||
lUnit = LUnit.CM
|
||||
volumeAction = { volume ->
|
||||
when {
|
||||
volume.name.startsWith("ecal01lay") -> GDMLTransformer.Action.REJECT
|
||||
// volume.name.startsWith("ecal") -> GDMLTransformer.Action.CACHE
|
||||
volume.name.startsWith("UPBL") -> GDMLTransformer.Action.REJECT
|
||||
volume.name.startsWith("USCL") -> GDMLTransformer.Action.REJECT
|
||||
// volume.name.startsWith("U") -> GDMLTransformer.Action.CACHE
|
||||
volume.name.startsWith("VPBL") -> GDMLTransformer.Action.REJECT
|
||||
volume.name.startsWith("VSCL") -> GDMLTransformer.Action.REJECT
|
||||
// volume.name.startsWith("V") -> GDMLTransformer.Action.CACHE
|
||||
else -> GDMLTransformer.Action.CACHE
|
||||
}
|
||||
}
|
||||
|
||||
solidConfiguration = { parent, solid ->
|
||||
if (
|
||||
solid.name.startsWith("Coil")
|
||||
|| solid.name.startsWith("Yoke")
|
||||
|| solid.name.startsWith("Magnet")
|
||||
solid.name.startsWith("Yoke")
|
||||
|| solid.name.startsWith("Pole")
|
||||
|| parent.physVolumes.isNotEmpty()
|
||||
) {
|
||||
@ -193,17 +147,13 @@ private class GDMLDemoApp : ApplicationBase() {
|
||||
//(visual as? VisualGroup3D)?.transformInPlace(UnRef, RemoveSingleChild)
|
||||
|
||||
message("Rendering")
|
||||
val output = three.output(canvas as HTMLElement)
|
||||
|
||||
//output.camera.layers.enable(1)
|
||||
output.camera.layers.set(0)
|
||||
setupLayers(layers, output)
|
||||
val output = three.output(canvas as HTMLElement)
|
||||
|
||||
if (visual is VisualGroup) {
|
||||
visual.toTree(editor::propertyEditor).render(tree as HTMLElement) {
|
||||
showCheckboxes = false
|
||||
}
|
||||
}
|
||||
output.camera.layers.set(0)
|
||||
layers.threeOutputConfig(output)
|
||||
tree.visualObjectTree(visual, editor::propertyEditor)
|
||||
|
||||
output.render(visual)
|
||||
message(null)
|
||||
@ -211,8 +161,8 @@ private class GDMLDemoApp : ApplicationBase() {
|
||||
}
|
||||
|
||||
(document.getElementById("drop_zone") as? HTMLDivElement)?.apply {
|
||||
addEventListener("dragover", { handleDragOver(it) }, false)
|
||||
addEventListener("drop", { loadData(it, action) }, false)
|
||||
addEventListener("dragover", { handleDragOver(it as DragEvent) }, false)
|
||||
addEventListener("drop", { loadData(it as DragEvent, action) }, false)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,45 +29,12 @@
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-9" id="canvas"></div>
|
||||
<div class="col-3">
|
||||
|
||||
<div id="editor"></div>
|
||||
<div class="accordion" id="accordion">
|
||||
<div class="card">
|
||||
<div class="card-header" id="layers-header">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#layers-body"
|
||||
aria-expanded="true" aria-controls="layers-body">
|
||||
Layers
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div id="layers-body" class="collapse show" aria-labelledby="layers-header"
|
||||
data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
<div id="layers"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="tree-header">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse"
|
||||
data-target="#tree-body" aria-expanded="false" aria-controls="tree-body">
|
||||
Object tree
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="tree-body" class="collapse" aria-labelledby="tree-header" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
<div id="tree"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3" id="tree"></div>
|
||||
<div class="col-lg-6">
|
||||
<div class="row" id="layers"></div>
|
||||
<div class="row container" id="canvas"></div>
|
||||
</div>
|
||||
<div class="col-lg-3" id="editor"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -5,8 +5,14 @@ package hep.dataforge.vis.spatial
|
||||
import hep.dataforge.io.ConfigSerializer
|
||||
import hep.dataforge.io.NameSerializer
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.vis.common.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.MutableVisualGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
import kotlin.collections.component1
|
||||
@ -35,16 +41,21 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
||||
|
||||
override fun getStyle(name: Name): Meta? = (parent as VisualGroup?)?.getStyle(name)
|
||||
|
||||
override fun addStyle(name: Name, meta: Meta) {
|
||||
(parent as VisualGroup?)?.addStyle(name, meta)
|
||||
override fun addStyle(name: Name, meta: Meta, apply: Boolean) {
|
||||
(parent as VisualGroup?)?.addStyle(name, meta, apply)
|
||||
//do nothing
|
||||
}
|
||||
|
||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||
return if (inherit) {
|
||||
super.getProperty(name, false) ?: prototype.getProperty(name, false) ?: parent?.getProperty(name, inherit)
|
||||
properties?.get(name)
|
||||
?: mergedStyles[name]
|
||||
?: prototype.getProperty(name, false)
|
||||
?: parent?.getProperty(name, inherit)
|
||||
} else {
|
||||
super.getProperty(name, false) ?: prototype.getProperty(name, false)
|
||||
properties?.get(name)
|
||||
?: mergedStyles[name]
|
||||
?: prototype.getProperty(name, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,8 +104,8 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
||||
|
||||
override fun getStyle(name: Name): Meta? = this@Proxy.getStyle(name)
|
||||
|
||||
override fun addStyle(name: Name, meta: Meta) {
|
||||
this@Proxy.addStyle(name, meta)
|
||||
override fun addStyle(name: Name, meta: Meta, apply: Boolean) {
|
||||
this@Proxy.addStyle(name, meta, apply)
|
||||
}
|
||||
|
||||
override var properties: Config?
|
||||
@ -118,8 +129,8 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
||||
return if (inherit) {
|
||||
properties?.get(name)
|
||||
?: mergedStyles[name]
|
||||
?: parent?.getProperty(name, inherit)
|
||||
?: prototype.getProperty(name, inherit)
|
||||
?: parent?.getProperty(name, inherit)
|
||||
} else {
|
||||
properties?.get(name)
|
||||
?: mergedStyles[name]
|
||||
|
@ -0,0 +1,15 @@
|
||||
package hep.dataforge.vis.spatial.editor
|
||||
|
||||
import kotlinx.html.TagConsumer
|
||||
import kotlinx.html.js.div
|
||||
import kotlinx.html.js.h3
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
|
||||
div("card w-100") {
|
||||
div("card-body") {
|
||||
h3(classes = "card-title") { +title }
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
@ -9,21 +9,19 @@ import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.getProperty
|
||||
import hep.dataforge.vis.jsObject
|
||||
import hep.dataforge.vis.spatial.Proxy
|
||||
import hep.dataforge.vis.spatial.visible
|
||||
import org.w3c.dom.HTMLElement
|
||||
import info.laht.threekt.loaders.Cache.clear
|
||||
import kotlinx.html.div
|
||||
import kotlinx.html.dom.append
|
||||
import org.w3c.dom.Element
|
||||
import kotlin.js.json
|
||||
|
||||
operator fun Name.plus(other: NameToken): Name = Name(tokens + other)
|
||||
|
||||
fun InspireTree.render(element: HTMLElement, block: DomConfig.() -> Unit = {}) {
|
||||
val config = (json(
|
||||
"target" to element
|
||||
) as DomConfig).apply(block)
|
||||
InspireTreeDOM(this, config)
|
||||
}
|
||||
|
||||
internal fun createInspireTree(block: Config.() -> Unit = {}): InspireTree {
|
||||
private fun createInspireTree(block: Config.() -> Unit = {}): InspireTree {
|
||||
val config = (json(
|
||||
"checkbox" to json(
|
||||
"autoCheckChildren" to false
|
||||
@ -32,7 +30,7 @@ internal fun createInspireTree(block: Config.() -> Unit = {}): InspireTree {
|
||||
return InspireTree(config)
|
||||
}
|
||||
|
||||
fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }): InspireTree {
|
||||
private fun VisualObject.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }): InspireTree {
|
||||
|
||||
val map = HashMap<String, VisualObject>()
|
||||
|
||||
@ -67,9 +65,10 @@ fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }):
|
||||
|
||||
}
|
||||
|
||||
fun TreeNode.fillChildren(group: VisualGroup, groupName: Name) {
|
||||
fun TreeNode.fillChildren(group: VisualObject, groupName: Name) {
|
||||
if(group is VisualGroup) {
|
||||
group.children.forEach { (token, obj) ->
|
||||
if(! token.body.startsWith("@")) {
|
||||
if (!token.body.startsWith("@")) {
|
||||
val name = groupName + token
|
||||
val nodeConfig = generateNodeConfig(obj, name)
|
||||
val childNode = addChild(nodeConfig)
|
||||
@ -80,6 +79,7 @@ fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }):
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val inspireTree = createInspireTree {
|
||||
|
||||
@ -121,3 +121,16 @@ fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }):
|
||||
|
||||
return inspireTree
|
||||
}
|
||||
|
||||
fun Element.visualObjectTree(group: VisualObject, onFocus: (VisualObject?, String?) -> Unit) {
|
||||
clear()
|
||||
append {
|
||||
card("Visual object tree") {
|
||||
val domConfig = jsObject<DomConfig> {
|
||||
target = div()
|
||||
showCheckboxes = false
|
||||
}
|
||||
InspireTreeDOM(group.toTree(onFocus), domConfig)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package hep.dataforge.vis.spatial.editor
|
||||
|
||||
import hep.dataforge.vis.spatial.three.ThreeOutput
|
||||
import kotlinx.html.InputType
|
||||
import kotlinx.html.dom.append
|
||||
import kotlinx.html.js.div
|
||||
import kotlinx.html.js.input
|
||||
import kotlinx.html.js.label
|
||||
import org.w3c.dom.Element
|
||||
import kotlin.dom.clear
|
||||
|
||||
fun Element.threeOutputConfig(output: ThreeOutput) {
|
||||
clear()
|
||||
append {
|
||||
card("Layers"){
|
||||
div("row") {
|
||||
(0..11).forEach { layer ->
|
||||
div("col-1") {
|
||||
label { +layer.toString() }
|
||||
input(type = InputType.checkBox).apply {
|
||||
if (layer == 0) {
|
||||
checked = true
|
||||
}
|
||||
onchange = {
|
||||
if (checked) {
|
||||
output.camera.layers.enable(layer)
|
||||
} else {
|
||||
output.camera.layers.disable(layer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,10 +2,9 @@ package hep.dataforge.vis.spatial.editor
|
||||
|
||||
import hep.dataforge.io.toJson
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.findStyle
|
||||
import hep.dataforge.vis.hmr.jsObject
|
||||
import hep.dataforge.vis.jsObject
|
||||
import hep.dataforge.vis.spatial.Material3D.Companion.COLOR_KEY
|
||||
import hep.dataforge.vis.spatial.Material3D.Companion.OPACITY_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
|
||||
@ -15,11 +14,11 @@ import hep.dataforge.vis.spatial.prototype
|
||||
import hep.dataforge.vis.spatial.visible
|
||||
import kotlinx.html.dom.append
|
||||
import kotlinx.html.js.div
|
||||
import kotlinx.html.js.h3
|
||||
import kotlinx.html.js.h4
|
||||
import org.w3c.dom.Element
|
||||
import kotlin.dom.clear
|
||||
|
||||
//FIXME something rotten in JS-Meta converter
|
||||
fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString())
|
||||
|
||||
|
||||
@ -27,38 +26,30 @@ fun Element.propertyEditor(item: VisualObject?, name: String?) {
|
||||
clear()
|
||||
if (item != null) {
|
||||
append {
|
||||
div("card") {
|
||||
div("card-body") {
|
||||
h3(classes = "card-title") { +"Properties" }
|
||||
}.apply {
|
||||
card("Properties") {
|
||||
val config = (item.properties ?: item.prototype?.properties) ?: EmptyMeta
|
||||
val metaToEdit = config.builder().apply {
|
||||
VISIBLE_KEY to (item.visible ?: true)
|
||||
COLOR_KEY to (item.color ?: "#ffffff")
|
||||
OPACITY_KEY to (item.opacity ?: 1.0)
|
||||
}
|
||||
//FIXME something rotten in JS-Meta converter
|
||||
val dMeta: dynamic = metaToEdit.toDynamic()
|
||||
//jsObject.material.color != null
|
||||
val options: JSONEditorOptions = jsObject{
|
||||
val options: JSONEditorOptions = jsObject {
|
||||
mode = "form"
|
||||
onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) }
|
||||
}
|
||||
JSONEditor(this, options, dMeta)
|
||||
}
|
||||
JSONEditor(div(), options, dMeta)
|
||||
}
|
||||
|
||||
|
||||
div("card") {
|
||||
div("card-body") {
|
||||
h3(classes = "card-title") { +"Styles" }
|
||||
}
|
||||
val styles = item.styles
|
||||
if (styles.isNotEmpty()) {
|
||||
card("Styles") {
|
||||
item.styles.forEach { style ->
|
||||
val styleMeta = item.findStyle(style)
|
||||
h4 { +style.toString() }
|
||||
h4("container") { +style.toString() }
|
||||
if (styleMeta != null) {
|
||||
div("container").apply {
|
||||
val options: JSONEditorOptions = jsObject{
|
||||
val options: JSONEditorOptions = jsObject {
|
||||
mode = "view"
|
||||
}
|
||||
JSONEditor(this, options, styleMeta.toDynamic())
|
||||
@ -68,4 +59,5 @@ fun Element.propertyEditor(item: VisualObject?, name: String?) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package hep.dataforge.vis.spatial.demo
|
||||
|
||||
import hep.dataforge.context.ContextBuilder
|
||||
import hep.dataforge.vis.ApplicationBase
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.hmr.ApplicationBase
|
||||
import hep.dataforge.vis.hmr.startApplication
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import hep.dataforge.vis.startApplication
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
|
Loading…
Reference in New Issue
Block a user