From 5c16642c145eb1aed250f9cf61c5507110e3ae2d Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 16 Sep 2019 21:18:15 +0300 Subject: [PATCH] show json in demo --- .../vis/common/AbstractVisualGroup.kt | 7 + .../vis/spatial/gdml/GDMLTransformer.kt | 4 +- .../dataforge/vis/spatial/gdml/visualGDML.kt | 15 +- .../vis/spatial/gdml/demo/GDMLDemoApp.kt | 96 ++-- .../src/jsMain/web/index.html | 1 + .../dataforge/vis/spatial/gdml/testMain.kt | 24 +- dataforge-vis-spatial/build.gradle.kts | 2 + .../dataforge/vis/spatial/VisualGroup3D.kt | 24 +- .../dataforge/vis/spatial/VisualObject3D.kt | 11 + .../hep/dataforge/vis/fancytree/Fancytree.kt | 427 ++++++++++++++++++ .../hep/dataforge/vis/fancytree/extensions.kt | 78 ++++ .../hep/dataforge/vis/fancytree/kotlinized.kt | 6 + .../vis/spatial/three/ThreeFactory.kt | 9 - .../vis/spatial/three/ThreeOutput.kt | 10 +- 14 files changed, 636 insertions(+), 78 deletions(-) create mode 100644 dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/Fancytree.kt create mode 100644 dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/extensions.kt create mode 100644 dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/kotlinized.kt diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt index 73b5bbf2..f4486451 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt @@ -21,6 +21,13 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup { */ abstract override val children: Map //get() = _children +// init { +// //Do after deserialization +// children.values.forEach { +// it.parent = this +// } +// } + override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) { super.propertyChanged(name, before, after) forEach { diff --git a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/GDMLTransformer.kt b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/GDMLTransformer.kt index 953474ca..ad8ac85d 100644 --- a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/GDMLTransformer.kt +++ b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/GDMLTransformer.kt @@ -29,7 +29,7 @@ class GDMLTransformer(val root: GDML) { var volumeAction: (GDMLGroup) -> Action = { Action.ACCEPT } - var configure: VisualObject3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { _, _ -> } + var solidConfiguration: VisualObject3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { _, _ -> } internal fun configureSolid(obj: VisualObject3D, parent: GDMLVolume, solid: GDMLSolid) { val material = parent.materialref.resolve(root) ?: GDMLElement(parent.materialref.ref) @@ -41,7 +41,7 @@ class GDMLTransformer(val root: GDML) { } obj.material = materialColor - obj.configure(parent, solid) + obj.solidConfiguration(parent, solid) } fun printStatistics() { diff --git a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt index 030b173b..f2e31d30 100644 --- a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt +++ b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt @@ -178,12 +178,12 @@ private fun VisualGroup3D.addPhysicalVolume( } } GDMLTransformer.Action.CACHE -> { - val name = volumesName + volume.name.asName() - if (context.templates[name] == null) { - context.templates[name] = volume(context, volume) + val fullName = volumesName + volume.name.asName() + if (context.templates[fullName] == null) { + context.templates[fullName] = volume(context, volume) } - this[physVolume.name ?: ""] = Proxy(name).apply { + this[physVolume.name ?: ""] = Proxy(fullName).apply { withPosition( context.lUnit, physVolume.resolvePosition(context.root), @@ -215,12 +215,7 @@ private fun VisualGroup3D.addDivisionVolume( ) } -//private fun VisualGroup3D.addVolume( -// context: GDMLTransformer, -// group: GDMLGroup -//) { -// this[group.name] = volume(context, group) -//} +private val solidsName = "solids".asName() private fun volume( context: GDMLTransformer, diff --git a/dataforge-vis-spatial-gdml/src/jsMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt b/dataforge-vis-spatial-gdml/src/jsMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt index fa56fd8b..7e74041a 100644 --- a/dataforge-vis-spatial-gdml/src/jsMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt +++ b/dataforge-vis-spatial-gdml/src/jsMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt @@ -3,10 +3,10 @@ package hep.dataforge.vis.spatial.gdml.demo import hep.dataforge.context.Global import hep.dataforge.vis.hmr.ApplicationBase import hep.dataforge.vis.hmr.startApplication +import hep.dataforge.vis.spatial.* 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.opacity import hep.dataforge.vis.spatial.three.ThreeOutput import hep.dataforge.vis.spatial.three.ThreePlugin import hep.dataforge.vis.spatial.three.output @@ -25,11 +25,10 @@ import org.w3c.files.FileReader import org.w3c.files.get import scientifik.gdml.GDML import kotlin.browser.document +import kotlin.browser.window import kotlin.dom.clear private class GDMLDemoApp : ApplicationBase() { - - /** * Handle mouse drag according to https://www.html5rocks.com/en/tutorials/file/dndfiles/ */ @@ -42,7 +41,7 @@ private class GDMLDemoApp : ApplicationBase() { /** * Load data from text file */ - private fun loadData(event: Event, block: suspend CoroutineScope.(String) -> Unit) { + private fun loadData(event: Event, block: suspend CoroutineScope.(name: String, data: String) -> Unit) { event.stopPropagation() event.preventDefault() @@ -54,7 +53,7 @@ private class GDMLDemoApp : ApplicationBase() { onload = { val string = result as String GlobalScope.launch { - block(string) + block(file.name, string) } } readAsText(file) @@ -82,12 +81,12 @@ private class GDMLDemoApp : ApplicationBase() { fun setupSidebar(element: Element, output: ThreeOutput) { element.clear() - (0..9).forEach{layer-> + (0..9).forEach { layer -> element.append { div("row") { +"layer $layer" input(type = InputType.checkBox).apply { - if (layer == 0 || layer == 1) { + if (layer == 0) { checked = true } onchange = { @@ -103,6 +102,38 @@ private class GDMLDemoApp : ApplicationBase() { } } + 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.ACCEPT + } + } + +// optimizeSingleChild = true + + solidConfiguration = { parent, solid -> + if (!parent.physVolumes.isEmpty()) { + opacity = 0.3 + } + if (solid.name.startsWith("Coil") + || solid.name.startsWith("Yoke") + || solid.name.startsWith("Magnet") + || solid.name.startsWith("Pole") + ) { + opacity = 0.3 + } + } + } + override fun start(state: Map) { @@ -114,51 +145,30 @@ private class GDMLDemoApp : ApplicationBase() { val sidebar = document.getElementById("sidebar") ?: error("Element with id 'sidebar' not found on page") canvas.clear() - val action: suspend CoroutineScope.(String) -> Unit = { it -> + val action: suspend CoroutineScope.(name: String, data: String) -> Unit = { name, data -> canvas.clear() launch { spinner(true) } launch { message("Loading GDML") } - val gdml = GDML.format.parse(GDML.serializer(), it) + val gdml = GDML.format.parse(GDML.serializer(), data) launch { message("Converting GDML into DF-VIS format") } - val visual = gdml.toVisual { - 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.ACCEPT - } - } - configure = { parent, solid -> - if (!parent.physVolumes.isEmpty()) { - opacity = 0.3 - } - if (solid.name.startsWith("Coil") - || solid.name.startsWith("Yoke") - || solid.name.startsWith("Magnet") - || solid.name.startsWith("Pole") - ) { - opacity = 0.3 - } + val visual: VisualObject3D = when { + name.endsWith(".gdml") || name.endsWith(".xml") -> gdml.toVisual(gdmlConfiguration) + name.endsWith(".json") -> { + Visual3DPlugin.json.parse(VisualGroup3D.serializer(), data).apply { attachChildren() } + } + else -> { + window.alert("File extension is not recognized: $name") + error("File extension is not recognized: $name") } } + launch { message("Rendering") } - val output = three.output(canvas) { - // "axis" to { -// "size" to 100 -// } - } - //make top layer visible - //output.camera.layers.disable(0) - output.camera.layers.enable(1) + val output = three.output(canvas) + + //output.camera.layers.enable(1) + output.camera.layers.set(0) setupSidebar(sidebar, output) output.render(visual) diff --git a/dataforge-vis-spatial-gdml/src/jsMain/web/index.html b/dataforge-vis-spatial-gdml/src/jsMain/web/index.html index 483a1de8..1a27e18d 100644 --- a/dataforge-vis-spatial-gdml/src/jsMain/web/index.html +++ b/dataforge-vis-spatial-gdml/src/jsMain/web/index.html @@ -6,6 +6,7 @@ Three js demo for particle physics + diff --git a/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/testMain.kt b/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/testMain.kt index 36584814..37e45cda 100644 --- a/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/testMain.kt +++ b/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/testMain.kt @@ -2,6 +2,7 @@ package hep.dataforge.vis.spatial.gdml import hep.dataforge.vis.spatial.Visual3DPlugin import hep.dataforge.vis.spatial.VisualGroup3D +import hep.dataforge.vis.spatial.opacity import nl.adaptivity.xmlutil.StAXReader import scientifik.gdml.GDML import java.io.File @@ -16,14 +17,32 @@ fun main() { 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 - volume.name.startsWith("tof") -> GDMLTransformer.Action.CACHE else -> GDMLTransformer.Action.ACCEPT } } - optimizeSingleChild = true + + solidConfiguration = { parent, solid -> + if (parent.physVolumes.isNotEmpty()) { + opacity = 0.3 + } + if (solid.name.startsWith("Coil") + || solid.name.startsWith("Yoke") + || solid.name.startsWith("Magnet") + || solid.name.startsWith("Pole") + ) { + opacity = 0.3 + } + } + +// optimizeSingleChild = true //optimizations = listOf(optimizeSingleChild) onFinish = { printStatistics() } } @@ -36,7 +55,6 @@ fun main() { println(tmpFile.canonicalPath) - // val template = visual.getTemplate("volumes.ecal01mod".toName()) // println(template) // visual.flatMap { (it as? VisualGroup3D) ?: listOf(it) }.forEach { diff --git a/dataforge-vis-spatial/build.gradle.kts b/dataforge-vis-spatial/build.gradle.kts index 25a1dc19..0916534d 100644 --- a/dataforge-vis-spatial/build.gradle.kts +++ b/dataforge-vis-spatial/build.gradle.kts @@ -31,6 +31,8 @@ kotlin { implementation(npm("@hi-level/three-csg", "1.0.6")) implementation(npm("style-loader")) implementation(npm("element-resize-event")) + api("kotlin.js.externals:kotlin-js-jquery:3.2.0-0") + implementation(npm("jquery.fancytree","2.32.0")) } } } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualGroup3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualGroup3D.kt index 98995f59..8c75a314 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualGroup3D.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualGroup3D.kt @@ -11,6 +11,7 @@ import hep.dataforge.names.NameToken import hep.dataforge.names.asName import hep.dataforge.names.isEmpty import hep.dataforge.vis.common.AbstractVisualGroup +import hep.dataforge.vis.common.VisualGroup import hep.dataforge.vis.common.VisualObject import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -37,13 +38,6 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D { private val _children = HashMap() override val children: Map get() = _children - init { - //Do after deserialization - _children.values.forEach { - it.parent = this - } - } - override fun removeChild(token: NameToken) { _children.remove(token) childrenChanged(token.asName(), null) @@ -94,5 +88,21 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D { } } +/** + * A fix for serialization bug that writes all proper parents inside the tree after deserialization + */ +fun VisualGroup.attachChildren() { + this.children.values.forEach { + it.parent = this + (it as? VisualGroup)?.attachChildren() + } + if(this is VisualGroup3D){ + templates?.apply { + parent = this@attachChildren + attachChildren() + } + } +} + fun VisualGroup3D.group(key: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D = VisualGroup3D().apply(action).also { set(key, it) } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt index c61a9df2..c57e6841 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt @@ -9,6 +9,7 @@ import hep.dataforge.output.Output import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.asName import hep.dataforge.vis.spatial.VisualObject3D.Companion.DETAIL_KEY +import hep.dataforge.vis.spatial.VisualObject3D.Companion.LAYER_KEY import hep.dataforge.vis.spatial.VisualObject3D.Companion.MATERIAL_KEY import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY import kotlinx.serialization.UseSerializers @@ -34,6 +35,7 @@ interface VisualObject3D : VisualObject { val MATERIAL_KEY = "material".asName() val VISIBLE_KEY = "visible".asName() val DETAIL_KEY = "detail".asName() + val LAYER_KEY = "layer".asName() val x = "x".asName() val y = "y".asName() @@ -61,6 +63,15 @@ interface VisualObject3D : VisualObject { } } +/** + * Count number of layers to the top object. Return 1 if this is top layer + */ +var VisualObject3D.layer: Int + get() = getProperty(LAYER_KEY).int ?: 0 + set(value) { + setProperty(LAYER_KEY, value) + } + fun Output.render(meta: Meta = EmptyMeta, action: VisualGroup3D.() -> Unit) = render(VisualGroup3D().apply(action), meta) diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/Fancytree.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/Fancytree.kt new file mode 100644 index 00000000..c19a8a8b --- /dev/null +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/Fancytree.kt @@ -0,0 +1,427 @@ +@file:JsModule("jquery.fancytree") +@file:JsNonModule +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", + "OVERRIDING_FINAL_MEMBER", + "RETURN_TYPE_MISMATCH_ON_OVERRIDE", + "CONFLICTING_OVERLOADS", + "EXTERNAL_DELEGATION" +) + +package ru.mipt.npm.fancytreekt + +import js.externals.jquery.JQuery +import js.externals.jquery.JQueryEventObject +import js.externals.jquery.JQueryPromise +import org.w3c.dom.Element +import org.w3c.dom.HTMLElement +import org.w3c.dom.HTMLTableRowElement +import org.w3c.dom.events.Event + +external fun createTree(id: String, options: FancytreeOptions = definedExternally /* null */): Fancytree + +external interface Fancytree { + var `$div`: JQuery<*> + var widget: Any + var rootNode: FancytreeNode + var `$container`: JQuery<*> + var focusNode: FancytreeNode + var options: FancytreeOptions + fun activateKey(key: String): FancytreeNode + fun activateKey(key: Boolean): FancytreeNode + fun applyPatch(patchList: Array): JQueryPromise + fun changeRefKey(oldRefKey: String, newRefKey: String) + fun clearCookies() + fun clearFilter() + fun count(): Number + fun debug(msg: Any) + fun filterBranches(filter: String): Number + fun filterBranches(filter: (node: FancytreeNode) -> Boolean): Number + fun filterNodes(filter: String, leavesOnly: Boolean? = definedExternally /* null */): Number + fun filterNodes( + filter: (node: FancytreeNode) -> Boolean, + leavesOnly: Boolean? = definedExternally /* null */ + ): Number + + fun findNextNode(match: String, startNode: FancytreeNode? = definedExternally /* null */): FancytreeNode + fun findNextNode( + match: (node: FancytreeNode) -> Boolean, + startNode: FancytreeNode? = definedExternally /* null */ + ): FancytreeNode + + fun findAll(match: String): Array + fun findAll(match: (node: FancytreeNode) -> Boolean?): Array + fun generateFormElements( + selected: Boolean? = definedExternally /* null */, + active: Boolean? = definedExternally /* null */ + ) + + fun getActiveNode(): FancytreeNode + fun getFirstChild(): FancytreeNode + fun getFocusNode(ifTreeHasFocus: Boolean? = definedExternally /* null */): FancytreeNode + fun getNodeByKey(key: String, searchRoot: FancytreeNode? = definedExternally /* null */): FancytreeNode + fun getNodesByRef(refKey: String, rootNode: FancytreeNode? = definedExternally /* null */): Array + fun getPersistData() + fun getRootNode(): FancytreeNode + fun getSelectedNodes(stopOnParents: Boolean? = definedExternally /* null */): Array + fun hasFocus(): Boolean + fun info(msg: Any) + fun isEditing(): FancytreeNode + fun loadKeyPath( + keyPathList: Array, + callback: (node: FancytreeNode, status: String) -> Unit + ): JQueryPromise + + fun loadKeyPath(keyPath: String, callback: (node: FancytreeNode, status: String) -> Unit): JQueryPromise + fun reactivate() + fun reload(source: Any? = definedExternally /* null */): JQueryPromise + fun render(force: Boolean? = definedExternally /* null */, deep: Boolean? = definedExternally /* null */) + fun setFocus(flag: Boolean? = definedExternally /* null */) + fun toDict( + includeRoot: Boolean? = definedExternally /* null */, + callback: ((node: FancytreeNode) -> Unit)? = definedExternally /* null */ + ): Any + + fun visit(fn: (node: FancytreeNode) -> Any): Boolean + fun warn(msg: Any) + fun enableUpdate(enabled: Boolean) +} + +external interface FancytreeNode { + var tree: Fancytree + var parent: FancytreeNode + var key: String + var title: String + var data: Any + var children: Array + var expanded: Boolean + var extraClasses: String + var folder: Boolean + var statusNodeType: String + var lazy: Boolean + var tooltip: String + var span: HTMLElement + var tr: HTMLTableRowElement + fun addChildren( + children: Array, + insertBefore: FancytreeNode? = definedExternally /* null */ + ): FancytreeNode + + fun addChildren(children: Array, insertBefore: String? = definedExternally /* null */): FancytreeNode + fun addChildren(children: Array, insertBefore: Number? = definedExternally /* null */): FancytreeNode + fun addChildren(child: NodeData, insertBefore: FancytreeNode? = definedExternally /* null */): FancytreeNode + fun addChildren(child: NodeData, insertBefore: String? = definedExternally /* null */): FancytreeNode + fun addChildren(child: NodeData, insertBefore: Number? = definedExternally /* null */): FancytreeNode + fun addClass(className: String) + fun addNode(node: NodeData, mode: String? = definedExternally /* null */): FancytreeNode + fun applyPatch(patch: NodePatch): JQueryPromise + fun collapseSiblings(): JQueryPromise + fun copyTo( + node: FancytreeNode, + mode: String? = definedExternally /* null */, + map: ((node: NodeData) -> Unit)? = definedExternally /* null */ + ): FancytreeNode + + fun countChildren(deep: Boolean? = definedExternally /* null */): Number + fun debug(msg: Any) + fun editCreateNode(mode: String? = definedExternally /* null */, init: Any? = definedExternally /* null */) + fun editEnd(applyChanges: Boolean) + fun editStart() + fun findAll(match: String): Array + fun findAll(match: (node: FancytreeNode) -> Boolean): Array + fun findFirst(match: String): FancytreeNode + fun findFirst(match: (node: FancytreeNode) -> Boolean): FancytreeNode + fun fixSelection3AfterClick() + fun fixSelection3FromEndNodes() + fun fromDict(dict: NodeData) + fun getChildren(): Array + fun getCloneList(includeSelf: Boolean? = definedExternally /* null */): Array + fun getFirstChild(): FancytreeNode + fun getIndex(): Number + fun getIndexHier(): String + fun getKeyPath(excludeSelf: Boolean): String + fun getLastChild(): FancytreeNode + fun getLevel(): Number + fun getNextSibling(): FancytreeNode + fun getParent(): FancytreeNode + fun getParentList(includeRoot: Boolean, includeSelf: Boolean): Array + fun getPrevSibling(): FancytreeNode + fun hasChildren(): Boolean + fun hasFocus(): Boolean + fun info(msg: String) + fun isActive(): Boolean + fun isChildOf(otherNode: FancytreeNode): Boolean + fun isClone(): Boolean + fun isDescendantOf(otherNode: FancytreeNode): Boolean + fun isEditing(): Boolean + fun isExpanded(): Boolean + fun isFirstSibling(): Boolean + fun isFolder(): Boolean + fun isLastSibling(): Boolean + fun isLazy(): Boolean + fun isLoaded(): Boolean + fun isLoading(): Boolean + fun isRootNode(): Boolean + fun isSelected(): Boolean + fun isStatusNode(): Boolean + fun isTopLevel(): Boolean + fun isUndefined(): Boolean + fun isVisible(): Boolean + fun load(forceReload: Boolean? = definedExternally /* null */): JQueryPromise + fun makeVisible(opts: Any? = definedExternally /* null */): JQueryPromise + fun moveTo( + targetNode: FancytreeNode, + mode: String, + map: ((node: FancytreeNode) -> Unit)? = definedExternally /* null */ + ) + + fun navigate(where: Number, activate: Boolean? = definedExternally /* null */): JQueryPromise + fun remove() + fun removeChild(childNode: FancytreeNode) + fun removeChildren() + fun removeClass(className: String) + fun render(force: Boolean? = definedExternally /* null */, deep: Boolean? = definedExternally /* null */) + fun renderStatus() + fun renderTitle() + fun reRegister(key: String, refKey: String): Boolean + fun resetLazy() + fun scheduleAction(mode: String, ms: Number) + fun scrollIntoView( + effects: Boolean? = definedExternally /* null */, + options: Any? = definedExternally /* null */ + ): JQueryPromise + + fun scrollIntoView( + effects: Any? = definedExternally /* null */, + options: Any? = definedExternally /* null */ + ): JQueryPromise + + fun setActive( + flag: Boolean? = definedExternally /* null */, + opts: Any? = definedExternally /* null */ + ): JQueryPromise + + fun setExpanded( + flag: Boolean? = definedExternally /* null */, + opts: Any? = definedExternally /* null */ + ): JQueryPromise + + fun setFocus(flag: Boolean? = definedExternally /* null */) + fun setSelected(flag: Boolean? = definedExternally /* null */) + fun setStatus( + status: String, + message: String? = definedExternally /* null */, + details: String? = definedExternally /* null */ + ) + + fun setTitle(title: String) + fun sortChildren( + cmp: ((a: FancytreeNode, b: FancytreeNode) -> Number)? = definedExternally /* null */, + deep: Boolean? = definedExternally /* null */ + ) + + fun toDict( + recursive: Boolean? = definedExternally /* null */, + callback: ((dict: NodeData) -> Unit)? = definedExternally /* null */ + ): NodeData + + fun toggleClass(className: String, flag: Boolean? = definedExternally /* null */): Boolean + fun toggleExpanded() + fun toggleSelected() + fun visit(fn: (node: FancytreeNode) -> Any, includeSelf: Boolean? = definedExternally /* null */): Boolean + fun visitAndLoad( + fn: (node: FancytreeNode) -> Any, + includeSelf: Boolean? = definedExternally /* null */ + ): JQueryPromise + + fun visitParents(fn: (node: FancytreeNode) -> Any, includeSelf: Boolean? = definedExternally /* null */): Boolean + fun warn(msg: Any) + fun addChildren(children: Array): FancytreeNode + fun addChildren(child: NodeData): FancytreeNode + fun scrollIntoView(): JQueryPromise +} + +external enum class FancytreeClickFolderMode { + activate /* = 1 */, + expand /* = 2 */, + activate_and_expand /* = 3 */, + activate_dblclick_expands /* = 4 */ +} + +external enum class FancytreeSelectMode { + single /* = 1 */, + multi /* = 2 */, + mutlti_hier /* = 3 */ +} + +external interface EventData { + var tree: Fancytree + var widget: Any + var options: FancytreeOptions + var originalEvent: JQueryEventObject + var node: FancytreeNode + var result: Any + var targetType: String + var response: Any +} + +external interface FancytreeEvents { + val activate: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val beforeActivate: ((event: JQueryEventObject, data: EventData) -> Boolean)? get() = definedExternally + val beforeExpand: ((event: JQueryEventObject, data: EventData) -> Boolean)? get() = definedExternally + val beforeSelect: ((event: JQueryEventObject, data: EventData) -> Boolean)? get() = definedExternally + val blur: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val blurTree: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val click: ((event: JQueryEventObject, data: EventData) -> Boolean)? get() = definedExternally + val collapse: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val create: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val createNode: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val dblclick: ((event: JQueryEventObject, data: EventData) -> Boolean)? get() = definedExternally + val deactivate: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val expand: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val focus: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val focusTree: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val init: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val keydown: ((event: JQueryEventObject, data: EventData) -> Boolean)? get() = definedExternally + val keypress: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val lazyLoad: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val loadChildren: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val loadError: ((event: JQueryEventObject, data: EventData) -> Boolean)? get() = definedExternally + val postProcess: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val removeNode: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val renderColumns: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val renderNode: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val renderTitle: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val restore: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + val select: ((event: JQueryEventObject, data: EventData) -> Unit)? get() = definedExternally + var rtl: Boolean? get() = definedExternally; set(value) = definedExternally +} + +external interface `T$0` { + var type: String + var cache: Boolean + var dataType: String +} + +external interface `T$1` { + var top: Number + var bottom: Number +} + +external interface FancytreeOptions : FancytreeEvents { + var activeVisible: Boolean? get() = definedExternally; set(value) = definedExternally + var ajax: `T$0`? get() = definedExternally; set(value) = definedExternally + var aria: Boolean? get() = definedExternally; set(value) = definedExternally + var autoActivate: Boolean? get() = definedExternally; set(value) = definedExternally + var autoCollapse: Boolean? get() = definedExternally; set(value) = definedExternally + var autoScroll: Boolean? get() = definedExternally; set(value) = definedExternally + var checkbox: dynamic /* Boolean | String | (event: JQueryEventObject, data: EventData) -> Boolean */ + var clickFolderMode: FancytreeClickFolderMode? get() = definedExternally; set(value) = definedExternally + var debugLevel: dynamic /* 0 | 1 | 2 | 3 | 4 */ + var defaultKey: ((node: FancytreeNode) -> String)? get() = definedExternally; set(value) = definedExternally + var enableAspx: Boolean? get() = definedExternally; set(value) = definedExternally + var enableTitles: Boolean? get() = definedExternally; set(value) = definedExternally + var extensions: Array? get() = definedExternally; set(value) = definedExternally + var focusOnSelect: Boolean? get() = definedExternally; set(value) = definedExternally + var generateIds: Boolean? get() = definedExternally; set(value) = definedExternally + var icon: dynamic /* Boolean | String */ + var idPrefix: String? get() = definedExternally; set(value) = definedExternally + var imagePath: String? get() = definedExternally; set(value) = definedExternally + var keyboard: Boolean? get() = definedExternally; set(value) = definedExternally + var keyPathSeparator: String? get() = definedExternally; set(value) = definedExternally + var minExpandLevel: Number? get() = definedExternally; set(value) = definedExternally + var quicksearch: Boolean? get() = definedExternally; set(value) = definedExternally + var scrollOfs: `T$1`? get() = definedExternally; set(value) = definedExternally + var scrollParent: JQuery<*>? get() = definedExternally; set(value) = definedExternally + var selectMode: FancytreeSelectMode? get() = definedExternally; set(value) = definedExternally + var source: dynamic /* Array | Any */ + var strings: TranslationTable? get() = definedExternally; set(value) = definedExternally + var tabbable: Boolean? get() = definedExternally; set(value) = definedExternally + var titlesTabbable: Boolean? get() = definedExternally; set(value) = definedExternally + //var toggleEffect: EffectOptions? get() = definedExternally; set(value) = definedExternally + var tooltip: Boolean? get() = definedExternally; set(value) = definedExternally + var unselectable: dynamic /* Boolean | (event: JQueryEventObject, data: Fancytree.EventData) -> Boolean? */ + var unselectableIgnore: dynamic /* Boolean | (event: JQueryEventObject, data: Fancytree.EventData) -> Boolean? */ + var unselectableStatus: dynamic /* Boolean | (event: JQueryEventObject, data: Fancytree.EventData) -> Boolean? */ + var dnd5: DragAndDrop5 + var filter: Filter + var table: Table + @nativeGetter + operator fun get(extension: String): Any? + + @nativeSetter + operator fun set(extension: String, value: Any) +} + +external interface TranslationTable { + var loading: String + var loadError: String + var moreData: String + var noData: String +} + +external interface NodeData { + var title: String + var icon: dynamic /* Boolean | String */ + var key: String? get() = definedExternally; set(value) = definedExternally + var refKey: String? get() = definedExternally; set(value) = definedExternally + var expanded: Boolean? get() = definedExternally; set(value) = definedExternally + var active: Boolean? get() = definedExternally; set(value) = definedExternally + var focus: Boolean? get() = definedExternally; set(value) = definedExternally + var folder: Boolean? get() = definedExternally; set(value) = definedExternally + var hideCheckbox: Boolean? get() = definedExternally; set(value) = definedExternally + var lazy: Boolean? get() = definedExternally; set(value) = definedExternally + var selected: Boolean? get() = definedExternally; set(value) = definedExternally + var unselectable: Boolean? get() = definedExternally; set(value) = definedExternally + var children: Array? get() = definedExternally; set(value) = definedExternally + var tooltip: String? get() = definedExternally; set(value) = definedExternally + var extraClasses: String? get() = definedExternally; set(value) = definedExternally + var data: Any? get() = definedExternally; set(value) = definedExternally + var iconTooltip: String? get() = definedExternally; set(value) = definedExternally + var statusNodeType: String? get() = definedExternally; set(value) = definedExternally + var type: String? get() = definedExternally; set(value) = definedExternally + var unselectableIgnore: Boolean? get() = definedExternally; set(value) = definedExternally + var unselectableStatus: Boolean? get() = definedExternally; set(value) = definedExternally +} + +external interface NodePatch { + var appendChildren: NodeData? get() = definedExternally; set(value) = definedExternally + var replaceChildren: NodeData? get() = definedExternally; set(value) = definedExternally + var insertChildren: NodeData? get() = definedExternally; set(value) = definedExternally +} + +external interface TreePatch { + @nativeGetter + operator fun get(key: String): NodePatch? + + @nativeSetter + operator fun set(key: String, value: NodePatch) +} + +external object FancytreeStatic { + var buildType: String + var debugLevel: Number + var version: String + fun assert(cond: Boolean, msg: String) + fun Unit> debounce( + timeout: Number, + fn: T, + invokeAsap: Boolean? = definedExternally /* null */, + ctx: Any? = definedExternally /* null */ + ): T + + fun debug(msg: String) + fun error(msg: String) + fun escapeHtml(s: String): String + fun getEventTarget(event: Event): Any + fun getEventTargetType(event: Event): String + fun getNode(el: JQuery<*>): FancytreeNode + fun getNode(el: Event): FancytreeNode + fun getNode(el: Element): FancytreeNode + fun info(msg: String) + fun keyEventToString(event: Event): String + fun parseHtml(`$ul`: JQuery<*>): Array + fun registerExtension(definition: Any) + fun unescapeHtml(s: String): String + fun warn(msg: String) +} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/extensions.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/extensions.kt new file mode 100644 index 00000000..cbe01cae --- /dev/null +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/extensions.kt @@ -0,0 +1,78 @@ +@file:JsModule("jquery.fancytree") +@file:JsNonModule +@file:Suppress( + "INTERFACE_WITH_SUPERCLASS", + "OVERRIDING_FINAL_MEMBER", + "RETURN_TYPE_MISMATCH_ON_OVERRIDE", + "CONFLICTING_OVERLOADS", + "EXTERNAL_DELEGATION" +) +package ru.mipt.npm.fancytreekt + +external interface List { + var dnd5: DragAndDrop5? get() = definedExternally; set(value) = definedExternally + var filter: Filter? get() = definedExternally; set(value) = definedExternally + var table: Table? get() = definedExternally; set(value) = definedExternally + @nativeGetter + operator fun get(extension: String): Any? + + @nativeSetter + operator fun set(extension: String, value: Any) +} + +external interface DragAndDrop5 { + var autoExpandMS: Number? get() = definedExternally; set(value) = definedExternally + var dropMarkerOffsetX: Number? get() = definedExternally; set(value) = definedExternally + var dropMarkerInsertOffsetX: Number? get() = definedExternally; set(value) = definedExternally + var multiSource: Boolean? get() = definedExternally; set(value) = definedExternally + var preventForeignNodes: Boolean? get() = definedExternally; set(value) = definedExternally + var preventNonNodes: Boolean? get() = definedExternally; set(value) = definedExternally + var preventRecursiveMoves: Boolean? get() = definedExternally; set(value) = definedExternally + var preventVoidMoves: Boolean? get() = definedExternally; set(value) = definedExternally + var scroll: Boolean? get() = definedExternally; set(value) = definedExternally + var scrollSensitivity: Number? get() = definedExternally; set(value) = definedExternally + var scrollSpeed: Number? get() = definedExternally; set(value) = definedExternally + var setTextTypeJson: Boolean? get() = definedExternally; set(value) = definedExternally + var dragStart: ((sourceNode: FancytreeNode, data: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally + var dragDrag: ((sourceNode: FancytreeNode, data: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally + var dragEnd: ((sourceNode: FancytreeNode, data: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally + var dragEnter: ((targetNode: FancytreeNode, data: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally + var dragOver: ((targetNode: FancytreeNode, data: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally + var dragExpand: ((targetNode: FancytreeNode, data: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally + var dragDrop: ((node: FancytreeNode, data: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally + var dragLeave: ((targetNode: FancytreeNode, data: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: Any) +} + +external interface Filter { + var autoApply: Boolean + var autoExpand: Boolean + var counter: Boolean + var fuzzy: Boolean + var hideExpandedCounter: Boolean + var hideExpanders: Boolean + var highlight: Boolean + var leavesOnly: Boolean + var nodata: Boolean + var mode: dynamic /* 'dimm' | 'string' */ + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: Any) +} + +external interface Table { + var checkboxColumnIdx: Any + var indentation: Number + var nodeColumnIdx: Number + @nativeGetter + operator fun get(key: String): Any? + + @nativeSetter + operator fun set(key: String, value: Any) +} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/kotlinized.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/kotlinized.kt new file mode 100644 index 00000000..762dd6b5 --- /dev/null +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/fancytree/kotlinized.kt @@ -0,0 +1,6 @@ +package ru.mipt.npm.fancytreekt + +import kotlin.js.json + +@Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE", "FunctionName") +fun NodeData(block: NodeData.() -> Unit): NodeData = (json() as NodeData).apply(block) \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt index bb5dc5b2..96289702 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt @@ -1,7 +1,6 @@ package hep.dataforge.vis.spatial.three import hep.dataforge.meta.boolean -import hep.dataforge.meta.int import hep.dataforge.meta.node import hep.dataforge.names.plus import hep.dataforge.names.startsWith @@ -43,13 +42,6 @@ internal fun Object3D.updatePosition(obj: VisualObject3D) { updateMatrix() } -/** - * Count number of layers to the top object. Return 1 if this is top layer - */ -val VisualObject3D.layer: Int - get() = getProperty(MeshThreeFactory.LAYER_KEY).int ?: ((parent as? VisualObject3D)?.layer ?: 0 + 1) - - internal fun Mesh.updateFrom(obj: T) { matrixAutoUpdate = false @@ -109,7 +101,6 @@ abstract class MeshThreeFactory(override val type: KClass buildMesh(obj: T, geometryBuilder: (T) -> BufferGeometry): Mesh { //TODO add caching for geometries using templates diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeOutput.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeOutput.kt index fb191900..fbd98c7f 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeOutput.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeOutput.kt @@ -19,12 +19,14 @@ class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output Unit = {}) = ThreeOutput(this, buildMeta(meta, override)).apply { - if(element!=null){ + if (element != null) { attach(element) } } \ No newline at end of file