Tree viewer replacement
This commit is contained in:
parent
017995e045
commit
1d5debb8a6
@ -17,6 +17,9 @@ allprojects {
|
|||||||
repositories {
|
repositories {
|
||||||
maven("https://dl.bintray.com/pdvrieze/maven")
|
maven("https://dl.bintray.com/pdvrieze/maven")
|
||||||
maven("http://maven.jzy3d.org/releases")
|
maven("http://maven.jzy3d.org/releases")
|
||||||
|
maven("https://kotlin.bintray.com/js-externals")
|
||||||
|
// maven("https://dl.bintray.com/gbaldeck/kotlin")
|
||||||
|
// maven("https://dl.bintray.com/rjaros/kotlin")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "hep.dataforge"
|
group = "hep.dataforge"
|
||||||
|
@ -10,6 +10,7 @@ scientifik{
|
|||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
|
//val kvisionVersion: String by rootProject.extra("2.0.0-M1")
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm{
|
jvm{
|
||||||
@ -31,9 +32,9 @@ kotlin {
|
|||||||
jsMain{
|
jsMain{
|
||||||
dependencies {
|
dependencies {
|
||||||
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
||||||
|
api("kotlin.js.externals:kotlin-js-jquery:3.2.0-0")
|
||||||
api(npm("text-encoding"))
|
api(npm("text-encoding"))
|
||||||
api("org.jetbrains:kotlin-extensions:1.0.1-pre.83-kotlin-1.3.50")
|
api(npm("bootstrap","4.3.1"))
|
||||||
api(npm("core-js"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,8 @@ interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val VisualGroup.isEmpty: Boolean get() = this.children.isEmpty()
|
||||||
|
|
||||||
interface MutableVisualGroup : VisualGroup {
|
interface MutableVisualGroup : VisualGroup {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.js
|
||||||
|
|
||||||
import kotlin.browser.document
|
import kotlin.browser.document
|
||||||
import kotlin.dom.hasClass
|
import kotlin.dom.hasClass
|
||||||
|
|
||||||
external val module: Module
|
external val module: Module
|
||||||
|
|
||||||
external interface Module {
|
|
||||||
val hot: Hot?
|
|
||||||
}
|
|
||||||
|
|
||||||
external interface Hot {
|
external interface Hot {
|
||||||
val data: dynamic
|
val data: dynamic
|
||||||
|
|
||||||
@ -19,17 +15,31 @@ external interface Hot {
|
|||||||
fun dispose(callback: (data: dynamic) -> Unit)
|
fun dispose(callback: (data: dynamic) -> Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
external fun require(name: String): dynamic
|
external interface Module {
|
||||||
|
val hot: Hot?
|
||||||
abstract class ApplicationBase {
|
|
||||||
open val stateKeys: List<String> get() = emptyList()
|
|
||||||
|
|
||||||
abstract fun start(state: Map<String, Any>)
|
|
||||||
open fun dispose(): Map<String, Any> = emptyMap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startApplication(builder: () -> ApplicationBase) {
|
/**
|
||||||
fun start(state: dynamic): ApplicationBase? {
|
* Base interface for applications.
|
||||||
|
*
|
||||||
|
* Base interface for applications supporting Hot Module Replacement (HMR).
|
||||||
|
*/
|
||||||
|
interface Application {
|
||||||
|
/**
|
||||||
|
* Starting point for an application.
|
||||||
|
* @param state Initial state between Hot Module Replacement (HMR).
|
||||||
|
*/
|
||||||
|
fun start(state: Map<String, Any>)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ending point for an application.
|
||||||
|
* @return final state for Hot Module Replacement (HMR).
|
||||||
|
*/
|
||||||
|
fun dispose(): Map<String, Any> = emptyMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startApplication(builder: () -> Application) {
|
||||||
|
fun start(state: dynamic): Application? {
|
||||||
return if (document.body?.hasClass("testApp") == true) {
|
return if (document.body?.hasClass("testApp") == true) {
|
||||||
val application = builder()
|
val application = builder()
|
||||||
|
|
||||||
@ -42,7 +52,7 @@ fun startApplication(builder: () -> ApplicationBase) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var application: ApplicationBase? = null
|
var application: Application? = null
|
||||||
|
|
||||||
val state: dynamic = module.hot?.let { hot ->
|
val state: dynamic = module.hot?.let { hot ->
|
||||||
hot.accept()
|
hot.accept()
|
@ -1,4 +1,6 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.js
|
||||||
|
|
||||||
|
external fun require(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
|
23
dataforge-vis-common/src/jsMain/resources/css/common.css
Normal file
23
dataforge-vis-common/src/jsMain/resources/css/common.css
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* Remove default bullets */
|
||||||
|
ul, .objTree-subtree {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style the caret/arrow */
|
||||||
|
.objTree-caret {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none; /* Prevent text selection */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the caret/arrow with a unicode, and style it */
|
||||||
|
.objTree-caret::before {
|
||||||
|
content: "\25B6";
|
||||||
|
color: black;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
|
||||||
|
.objTree-caret-down::before {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
package hep.dataforge.vis.spatial.gdml.demo
|
package hep.dataforge.vis.spatial.gdml.demo
|
||||||
|
|
||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.vis.ApplicationBase
|
import hep.dataforge.js.Application
|
||||||
|
import hep.dataforge.js.objectTree
|
||||||
|
import hep.dataforge.js.startApplication
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.OPACITY_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.OPACITY_KEY
|
||||||
import hep.dataforge.vis.spatial.Visual3DPlugin
|
import hep.dataforge.vis.spatial.Visual3DPlugin
|
||||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||||
@ -9,13 +12,11 @@ import hep.dataforge.vis.spatial.VisualObject3D
|
|||||||
import hep.dataforge.vis.spatial.attachChildren
|
import hep.dataforge.vis.spatial.attachChildren
|
||||||
import hep.dataforge.vis.spatial.editor.propertyEditor
|
import hep.dataforge.vis.spatial.editor.propertyEditor
|
||||||
import hep.dataforge.vis.spatial.editor.threeOutputConfig
|
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.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
|
||||||
import hep.dataforge.vis.spatial.three.ThreePlugin
|
import hep.dataforge.vis.spatial.three.ThreePlugin
|
||||||
import hep.dataforge.vis.spatial.three.output
|
import hep.dataforge.vis.spatial.three.output
|
||||||
import hep.dataforge.vis.startApplication
|
|
||||||
import kotlinx.html.dom.append
|
import kotlinx.html.dom.append
|
||||||
import kotlinx.html.js.p
|
import kotlinx.html.js.p
|
||||||
import org.w3c.dom.DragEvent
|
import org.w3c.dom.DragEvent
|
||||||
@ -29,7 +30,7 @@ import kotlin.browser.document
|
|||||||
import kotlin.browser.window
|
import kotlin.browser.window
|
||||||
import kotlin.dom.clear
|
import kotlin.dom.clear
|
||||||
|
|
||||||
private class GDMLDemoApp : ApplicationBase() {
|
private class GDMLDemoApp : Application {
|
||||||
/**
|
/**
|
||||||
* Handle mouse drag according to https://www.html5rocks.com/en/tutorials/file/dndfiles/
|
* Handle mouse drag according to https://www.html5rocks.com/en/tutorials/file/dndfiles/
|
||||||
*/
|
*/
|
||||||
@ -46,7 +47,6 @@ private class GDMLDemoApp : ApplicationBase() {
|
|||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
|
|
||||||
val file = (event.dataTransfer?.files as FileList)[0]
|
val file = (event.dataTransfer?.files as FileList)[0]
|
||||||
?: throw RuntimeException("Failed to load file")
|
?: throw RuntimeException("Failed to load file")
|
||||||
|
|
||||||
@ -153,7 +153,9 @@ private class GDMLDemoApp : ApplicationBase() {
|
|||||||
|
|
||||||
output.camera.layers.set(0)
|
output.camera.layers.set(0)
|
||||||
layers.threeOutputConfig(output)
|
layers.threeOutputConfig(output)
|
||||||
tree.visualObjectTree(visual, editor::propertyEditor)
|
//tree.visualObjectTree(visual, editor::propertyEditor)
|
||||||
|
tree.objectTree(NameToken("World"),visual, editor::propertyEditor)
|
||||||
|
|
||||||
|
|
||||||
output.render(visual)
|
output.render(visual)
|
||||||
message(null)
|
message(null)
|
||||||
@ -166,10 +168,6 @@ private class GDMLDemoApp : ApplicationBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose(): Map<String, Any> {
|
|
||||||
return super.dispose()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -11,3 +11,38 @@
|
|||||||
0% { transform: rotate(0deg); }
|
0% { transform: rotate(0deg); }
|
||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove default bullets */
|
||||||
|
ul, .objTree-subtree {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style the caret/arrow */
|
||||||
|
.objTree-caret {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none; /* Prevent text selection */
|
||||||
|
}
|
||||||
|
|
||||||
|
.objTree-label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the caret/arrow with a unicode, and style it */
|
||||||
|
.objTree-caret::before {
|
||||||
|
content: "\25B6";
|
||||||
|
color: black;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objTree-leaf::before {
|
||||||
|
content: "\25C6";
|
||||||
|
color: black;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
|
||||||
|
.objTree-caret-down::before {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
@ -4,13 +4,9 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">-->
|
<!-- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">-->
|
||||||
<title>Three js demo for particle physics</title>
|
<title>Three js demo for particle physics</title>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
|
|
||||||
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
|
|
||||||
crossorigin="anonymous"></script>
|
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
||||||
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="css/main.css">
|
<link rel="stylesheet" href="css/main.css">
|
||||||
<link rel="stylesheet" href="css/inspire-tree-light.min.css">
|
|
||||||
<link rel="stylesheet" href="css/jsoneditor.min.css">
|
<link rel="stylesheet" href="css/jsoneditor.min.css">
|
||||||
<script type="text/javascript" src="main.bundle.js"></script>
|
<script type="text/javascript" src="main.bundle.js"></script>
|
||||||
</head>
|
</head>
|
||||||
@ -37,12 +33,5 @@
|
|||||||
<div class="col-lg-3" id="editor"></div>
|
<div class="col-lg-3" id="editor"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
|
|
||||||
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
|
|
||||||
crossorigin="anonymous"></script>
|
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
|
|
||||||
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
|
|
||||||
crossorigin="anonymous"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -0,0 +1,75 @@
|
|||||||
|
package hep.dataforge.js
|
||||||
|
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
|
import hep.dataforge.vis.common.VisualGroup
|
||||||
|
import hep.dataforge.vis.common.VisualObject
|
||||||
|
import hep.dataforge.vis.common.isEmpty
|
||||||
|
import hep.dataforge.vis.spatial.editor.card
|
||||||
|
import kotlinx.html.TagConsumer
|
||||||
|
import kotlinx.html.dom.append
|
||||||
|
import kotlinx.html.js.*
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
import org.w3c.dom.HTMLElement
|
||||||
|
import org.w3c.dom.HTMLSpanElement
|
||||||
|
import kotlin.dom.clear
|
||||||
|
|
||||||
|
fun Element.objectTree(
|
||||||
|
token: NameToken,
|
||||||
|
obj: VisualObject,
|
||||||
|
clickCallback: (VisualObject) -> Unit = {}
|
||||||
|
) {
|
||||||
|
clear()
|
||||||
|
append {
|
||||||
|
card("Object tree") {
|
||||||
|
subTree(token, obj, clickCallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TagConsumer<HTMLElement>.subTree(
|
||||||
|
token: NameToken,
|
||||||
|
obj: VisualObject,
|
||||||
|
clickCallback: (VisualObject) -> Unit
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (obj is VisualGroup && !obj.isEmpty) {
|
||||||
|
lateinit var toggle: HTMLSpanElement
|
||||||
|
div("d-inline-block text-truncate") {
|
||||||
|
toggle = span("objTree-caret")
|
||||||
|
label("objTree-label") {
|
||||||
|
+token.toString()
|
||||||
|
onClickFunction = { clickCallback(obj) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val subtree = ul("objTree-subtree")
|
||||||
|
toggle.onclick = {
|
||||||
|
toggle.classList.toggle("objTree-caret-down")
|
||||||
|
subtree.apply {
|
||||||
|
if (toggle.classList.contains("objTree-caret-down")) {
|
||||||
|
obj.children.entries
|
||||||
|
.filter { !it.key.toString().startsWith("@") }
|
||||||
|
.sortedBy { (it.value as? VisualGroup)?.isEmpty ?: true }
|
||||||
|
.forEach { (token, child) ->
|
||||||
|
append {
|
||||||
|
li().apply {
|
||||||
|
subTree(token, child, clickCallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//jQuery(subtree).asDynamic().collapse("toggle")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
div("d-inline-block text-truncate") {
|
||||||
|
span("objTree-leaf")
|
||||||
|
label("objTree-label") {
|
||||||
|
+token.toString()
|
||||||
|
onClickFunction = { clickCallback(obj) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,136 +0,0 @@
|
|||||||
@file:Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE")
|
|
||||||
|
|
||||||
package hep.dataforge.vis.spatial.editor
|
|
||||||
|
|
||||||
import hep.dataforge.meta.string
|
|
||||||
import hep.dataforge.names.EmptyName
|
|
||||||
import hep.dataforge.names.Name
|
|
||||||
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 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)
|
|
||||||
|
|
||||||
|
|
||||||
private fun createInspireTree(block: Config.() -> Unit = {}): InspireTree {
|
|
||||||
val config = (json(
|
|
||||||
"checkbox" to json(
|
|
||||||
"autoCheckChildren" to false
|
|
||||||
)
|
|
||||||
) as Config).apply(block)
|
|
||||||
return InspireTree(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun VisualObject.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }): InspireTree {
|
|
||||||
|
|
||||||
val map = HashMap<String, VisualObject>()
|
|
||||||
|
|
||||||
fun generateNodeConfig(item: VisualObject, fullName: Name): NodeConfig {
|
|
||||||
val title = item.getProperty("title").string ?: fullName.last()?.toString() ?: "root"
|
|
||||||
val className = if (item is Proxy) {
|
|
||||||
item.prototype::class.toString()
|
|
||||||
} else {
|
|
||||||
item::class.toString()
|
|
||||||
}.replace("class ", "")
|
|
||||||
|
|
||||||
val text: String = if (title.startsWith("@")) {
|
|
||||||
"[$className}]"
|
|
||||||
} else {
|
|
||||||
"$title[$className}]"
|
|
||||||
}
|
|
||||||
|
|
||||||
return json(
|
|
||||||
"children" to if ((item as? VisualGroup)?.children?.isEmpty() != false) {
|
|
||||||
emptyArray<NodeConfig>()
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
},
|
|
||||||
"text" to text,
|
|
||||||
"id" to fullName.toString(),
|
|
||||||
"itree" to json(
|
|
||||||
"state" to json(
|
|
||||||
"checked" to (item.visible ?: true)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) as NodeConfig
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun TreeNode.fillChildren(group: VisualObject, groupName: Name) {
|
|
||||||
if(group is VisualGroup) {
|
|
||||||
group.children.forEach { (token, obj) ->
|
|
||||||
if (!token.body.startsWith("@")) {
|
|
||||||
val name = groupName + token
|
|
||||||
val nodeConfig = generateNodeConfig(obj, name)
|
|
||||||
val childNode = addChild(nodeConfig)
|
|
||||||
map[childNode.id] = obj
|
|
||||||
if (obj is VisualGroup) {
|
|
||||||
childNode.fillChildren(obj, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val inspireTree = createInspireTree {
|
|
||||||
|
|
||||||
}
|
|
||||||
val nodeConfig = generateNodeConfig(this, EmptyName)
|
|
||||||
val rootNode = inspireTree.addNode(nodeConfig)
|
|
||||||
map[rootNode.id] = this
|
|
||||||
rootNode.fillChildren(this, EmptyName)
|
|
||||||
|
|
||||||
// inspireTree.on("node.selected") { node: TreeNode, isLoadEvent: Boolean ->
|
|
||||||
// if (!isLoadEvent) {
|
|
||||||
// map[node.id]?.selected = node.selected()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// inspireTree.on("node.deselect") { node: TreeNode ->
|
|
||||||
// map[node.id]?.selected = node.selected()
|
|
||||||
// }
|
|
||||||
|
|
||||||
inspireTree.on("node.checked") { node: TreeNode, isLoadEvent: Boolean ->
|
|
||||||
if (!isLoadEvent) {
|
|
||||||
map[node.id]?.visible = node.checked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inspireTree.on("node.unchecked") { node: TreeNode ->
|
|
||||||
if (!node.indeterminate()) {
|
|
||||||
map[node.id]?.visible = node.checked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inspireTree.on("node.focused") { node: TreeNode, isLoadEvent: Boolean ->
|
|
||||||
if (!isLoadEvent) {
|
|
||||||
onFocus(map[node.id], node.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inspireTree.collapseDeep()
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,10 @@
|
|||||||
package hep.dataforge.vis.spatial.editor
|
package hep.dataforge.vis.spatial.editor
|
||||||
|
|
||||||
import hep.dataforge.io.toJson
|
import hep.dataforge.io.toJson
|
||||||
|
import hep.dataforge.js.jsObject
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
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.jsObject
|
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.COLOR_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.COLOR_KEY
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.OPACITY_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.OPACITY_KEY
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
|
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
|
||||||
@ -22,7 +22,7 @@ import kotlin.dom.clear
|
|||||||
fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString())
|
fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString())
|
||||||
|
|
||||||
|
|
||||||
fun Element.propertyEditor(item: VisualObject?, name: String?) {
|
fun Element.propertyEditor(item: VisualObject?) {
|
||||||
clear()
|
clear()
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
append {
|
append {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package hep.dataforge.vis.spatial.demo
|
package hep.dataforge.vis.spatial.demo
|
||||||
|
|
||||||
import hep.dataforge.context.ContextBuilder
|
import hep.dataforge.context.ContextBuilder
|
||||||
import hep.dataforge.vis.ApplicationBase
|
import hep.dataforge.js.Application
|
||||||
|
import hep.dataforge.js.startApplication
|
||||||
import hep.dataforge.vis.common.Colors
|
import hep.dataforge.vis.common.Colors
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
import hep.dataforge.vis.startApplication
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
@ -15,9 +15,7 @@ import kotlin.math.sin
|
|||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
|
||||||
private class ThreeDemoApp : ApplicationBase() {
|
private class ThreeDemoApp : Application {
|
||||||
|
|
||||||
override val stateKeys: List<String> = emptyList()
|
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(state: Map<String, Any>) {
|
||||||
|
|
||||||
@ -141,7 +139,7 @@ private class ThreeDemoApp : ApplicationBase() {
|
|||||||
thickness = 208.0
|
thickness = 208.0
|
||||||
rotationX = it * PI2 / 20
|
rotationX = it * PI2 / 20
|
||||||
color(Colors.green)
|
color(Colors.green)
|
||||||
//rotationY = it * PI2 / 20
|
//rotationY = it * PI2 / 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user