Trying to create a react tree for meta editor.
This commit is contained in:
parent
fc5af5e469
commit
b5164916bb
@ -1,4 +1,4 @@
|
|||||||
val dataforgeVersion by extra("0.1.3-dev-5")
|
val dataforgeVersion by extra("0.1.3-dev-7")
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -8,7 +8,7 @@ repositories {
|
|||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
}
|
}
|
||||||
|
|
||||||
val kotlinVersion = "1.3.21"
|
val kotlinVersion = "1.3.40"
|
||||||
|
|
||||||
// Add plugins used in buildSrc as dependencies, also we should specify version only here
|
// Add plugins used in buildSrc as dependencies, also we should specify version only here
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
// define version in buildSrc and have autocompletion and compile-time check
|
// define version in buildSrc and have autocompletion and compile-time check
|
||||||
// Also dependencies itself can be moved here
|
// Also dependencies itself can be moved here
|
||||||
object Versions {
|
object Versions {
|
||||||
val ioVersion = "0.1.8"
|
val ioVersion = "0.1.10"
|
||||||
val coroutinesVersion = "1.2.1"
|
val coroutinesVersion = "1.2.1"
|
||||||
val atomicfuVersion = "0.12.6"
|
val atomicfuVersion = "0.12.6"
|
||||||
val serializationVersion = "0.11.0"
|
val serializationVersion = "0.11.1"
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
import org.gradle.kotlin.dsl.`maven-publish`
|
|
||||||
import org.gradle.kotlin.dsl.apply
|
|
||||||
import org.gradle.kotlin.dsl.dependencies
|
|
||||||
import org.gradle.kotlin.dsl.kotlin
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform")
|
kotlin("multiplatform")
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.vis.common
|
||||||
|
|
||||||
import hep.dataforge.meta.EmptyMeta
|
import hep.dataforge.meta.EmptyMeta
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
@ -1,10 +1,10 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.vis.common
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.DisplayObject.Companion.META_KEY
|
import hep.dataforge.vis.common.DisplayObject.Companion.META_KEY
|
||||||
import hep.dataforge.vis.DisplayObject.Companion.TAGS_KEY
|
import hep.dataforge.vis.common.DisplayObject.Companion.TAGS_KEY
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A root type for display hierarchy
|
* A root type for display hierarchy
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.vis.common
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.vis.common
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
@ -8,7 +8,7 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":dataforge-vis-common"))
|
api(project(":dataforge-vis-common"))
|
||||||
api("no.tornado:tornadofx:1.7.18")
|
api("no.tornado:tornadofx:1.7.19")
|
||||||
api("no.tornado:tornadofx-controlsfx:0.1")
|
api("no.tornado:tornadofx-controlsfx:0.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import javafx.scene.image.Image
|
|||||||
import javafx.scene.image.ImageView
|
import javafx.scene.image.ImageView
|
||||||
import javafx.stage.Stage
|
import javafx.stage.Stage
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
import kotlin.concurrent.thread
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,12 +46,9 @@ class FXPlugin(meta: Meta = EmptyMeta) : AbstractPlugin(meta) {
|
|||||||
super.attach(context)
|
super.attach(context)
|
||||||
if (FX.getApplication(FX.defaultScope) == null) {
|
if (FX.getApplication(FX.defaultScope) == null) {
|
||||||
if (consoleMode) {
|
if (consoleMode) {
|
||||||
Thread {
|
thread(name = "${context.name} FX application thread") {
|
||||||
context.logger.debug("Starting FX application surrogate")
|
context.logger.debug("Starting FX application surrogate")
|
||||||
launch<ApplicationSurrogate>()
|
launch<ApplicationSurrogate>()
|
||||||
}.apply {
|
|
||||||
name = "${context.name} FX application thread"
|
|
||||||
start()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!FX.initialized.get()) {
|
while (!FX.initialized.get()) {
|
||||||
|
@ -30,7 +30,7 @@ class ConfigEditor(
|
|||||||
) : Fragment(title = title, icon = dfIconView) {
|
) : Fragment(title = title, icon = dfIconView) {
|
||||||
|
|
||||||
constructor(config: Config, descriptor: NodeDescriptor, title: String = "Configuration editor") :
|
constructor(config: Config, descriptor: NodeDescriptor, title: String = "Configuration editor") :
|
||||||
this(FXMeta.root(config, descriptor = descriptor))
|
this(FXMeta.root(config, descriptor = descriptor),title = title)
|
||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
center = treetableview<FXMeta<Config>> {
|
center = treetableview<FXMeta<Config>> {
|
||||||
|
@ -7,6 +7,7 @@ import hep.dataforge.meta.*
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
|
import hep.dataforge.names.withIndex
|
||||||
import hep.dataforge.values.Null
|
import hep.dataforge.values.Null
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
import javafx.beans.binding.ListBinding
|
import javafx.beans.binding.ListBinding
|
||||||
@ -124,7 +125,7 @@ class FXMetaNode<M : MetaNode<M>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return items.filter(filter).observable()
|
return items.filter(filter).asObservable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,9 +170,17 @@ fun <M : MutableMeta<M>> FXMetaNode<M>.remove(name: NameToken) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boolean): M {
|
private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boolean): M {
|
||||||
this.setNode(token.asName(), EmptyMeta)
|
return if (append && token.index.isNotEmpty()) {
|
||||||
//FIXME possible concurrency bug
|
val name = token.asName()
|
||||||
return get(token).node!!
|
val index = (getAll(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
||||||
|
val newName = name.withIndex(index.toString())
|
||||||
|
set(newName, EmptyMeta)
|
||||||
|
get(newName).node!!
|
||||||
|
} else {
|
||||||
|
this.setNode(token.asName(), EmptyMeta)
|
||||||
|
//FIXME possible concurrency bug
|
||||||
|
get(token).node!!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> FXMetaNode<out M>.getOrCreateNode(): M {
|
fun <M : MutableMeta<M>> FXMetaNode<out M>.getOrCreateNode(): M {
|
||||||
@ -192,24 +201,24 @@ fun <M : MutableMeta<M>> FXMeta<M>.remove() {
|
|||||||
|
|
||||||
fun <M : MutableMeta<M>> FXMetaNode<M>.addValue(key: String) {
|
fun <M : MutableMeta<M>> FXMetaNode<M>.addValue(key: String) {
|
||||||
val parent = getOrCreateNode()
|
val parent = getOrCreateNode()
|
||||||
if(descriptor?.multiple == true){
|
if (descriptor?.multiple == true) {
|
||||||
parent.append(key, Null)
|
parent.append(key, Null)
|
||||||
} else{
|
} else {
|
||||||
parent[key] = Null
|
parent[key] = Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> FXMetaNode<M>.addNode(key: String) {
|
fun <M : MutableMeta<M>> FXMetaNode<M>.addNode(key: String) {
|
||||||
val parent = getOrCreateNode()
|
val parent = getOrCreateNode()
|
||||||
if(descriptor?.multiple == true){
|
if (descriptor?.multiple == true) {
|
||||||
parent.append(key, EmptyMeta)
|
parent.append(key, EmptyMeta)
|
||||||
} else{
|
} else {
|
||||||
parent[key] = EmptyMeta
|
parent[key] = EmptyMeta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> FXMetaValue<M>.set(value: Value?) {
|
fun <M : MutableMeta<M>> FXMetaValue<M>.set(value: Value?) {
|
||||||
if(descriptor?.multiple == true){
|
if (descriptor?.multiple == true) {
|
||||||
parent.getOrCreateNode().append(this.name.body, value)
|
parent.getOrCreateNode().append(this.name.body, value)
|
||||||
} else {
|
} else {
|
||||||
parent.getOrCreateNode()[this.name] = value
|
parent.getOrCreateNode()[this.name] = value
|
||||||
|
@ -25,7 +25,7 @@ import javafx.scene.control.TreeTableView
|
|||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
class MetaViewer(val rootNode: FXMetaNode<*>, title: String = "Meta viewer") : Fragment(title, dfIconView) {
|
class MetaViewer(val rootNode: FXMetaNode<*>, title: String = "Meta viewer") : Fragment(title, dfIconView) {
|
||||||
constructor(meta: Meta, title: String = "Meta viewer"): this(FXMeta.root(meta))
|
constructor(meta: Meta, title: String = "Meta viewer"): this(FXMeta.root(meta),title = title)
|
||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
center {
|
center {
|
||||||
|
70
dataforge-vis-js-tree/build.gradle.kts
Normal file
70
dataforge-vis-js-tree/build.gradle.kts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.frontend.KotlinFrontendExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.frontend.npm.NpmExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.frontend.webpack.WebPackExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("kotlin2js")
|
||||||
|
id("kotlin-dce-js")
|
||||||
|
id("org.jetbrains.kotlin.frontend")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven("https://kotlin.bintray.com/kotlin-js-wrappers")
|
||||||
|
}
|
||||||
|
|
||||||
|
val kotlinVersion: String by rootProject.extra
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(kotlin("stdlib-js"))
|
||||||
|
implementation(project(":dataforge-vis-common"))
|
||||||
|
implementation("org.jetbrains:kotlin-react:16.6.0-pre.73-kotlin-1.3.40")
|
||||||
|
implementation("org.jetbrains:kotlin-react-dom:16.6.0-pre.73-kotlin-1.3.40")
|
||||||
|
testCompile(kotlin("test-js"))
|
||||||
|
}
|
||||||
|
|
||||||
|
configure<KotlinFrontendExtension> {
|
||||||
|
downloadNodeJsVersion = "latest"
|
||||||
|
|
||||||
|
configure<NpmExtension> {
|
||||||
|
dependency("core-js", "3.1.4")
|
||||||
|
dependency("cp-react-tree-table","1.0.0-beta.6")
|
||||||
|
dependency("react")
|
||||||
|
dependency("react-dom")
|
||||||
|
devDependency("karma")
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceMaps = true
|
||||||
|
|
||||||
|
bundle<WebPackExtension>("webpack") {
|
||||||
|
this as WebPackExtension
|
||||||
|
bundleName = "main"
|
||||||
|
contentPath = file("src/main/web")
|
||||||
|
sourceMapEnabled = true
|
||||||
|
//mode = "production"
|
||||||
|
mode = "development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
"compileKotlin2Js"(Kotlin2JsCompile::class) {
|
||||||
|
kotlinOptions {
|
||||||
|
metaInfo = true
|
||||||
|
outputFile = "${project.buildDir.path}/js/${project.name}.js"
|
||||||
|
sourceMap = true
|
||||||
|
moduleKind = "commonjs"
|
||||||
|
main = "call"
|
||||||
|
kotlinOptions.sourceMapEmbedSources = "always"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"compileTestKotlin2Js"(Kotlin2JsCompile::class) {
|
||||||
|
kotlinOptions {
|
||||||
|
metaInfo = true
|
||||||
|
outputFile = "${project.buildDir.path}/js/${project.name}-test.js"
|
||||||
|
sourceMap = true
|
||||||
|
moduleKind = "commonjs"
|
||||||
|
kotlinOptions.sourceMapEmbedSources = "always"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package hep.dataforge.vis.js.tree
|
||||||
|
|
||||||
|
import react.RBuilder
|
||||||
|
import react.RComponent
|
||||||
|
import react.RProps
|
||||||
|
import react.RState
|
||||||
|
|
||||||
|
class MetaEditorState : RState {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MetaEditorProps : RProps
|
||||||
|
|
||||||
|
class MetaEditor(props: MetaEditorProps) : RComponent<MetaEditorProps, MetaEditorState>(props) {
|
||||||
|
override fun RBuilder.render() {
|
||||||
|
//this.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
@file:JsModule("cp-react-tree-table")
|
||||||
|
@file:JsNonModule
|
||||||
|
|
||||||
|
package hep.dataforge.vis.js.tree
|
||||||
|
|
||||||
|
import react.Component
|
||||||
|
|
||||||
|
external interface RowMetadata {
|
||||||
|
var depth: Number
|
||||||
|
var index: Number
|
||||||
|
var height: Number
|
||||||
|
var hasChildren: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
external interface RowState {
|
||||||
|
var isVisible: Boolean
|
||||||
|
var top: Number
|
||||||
|
}
|
||||||
|
|
||||||
|
open external class RowModel(data: RowData, metadata: RowMetadata, state: RowState) {
|
||||||
|
var data: RowData
|
||||||
|
var metadata: RowMetadata
|
||||||
|
var `$state`: RowState
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
var DEFAULT_HEIGHT: Number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
external interface RowAPI {
|
||||||
|
var toggleChildren: () -> Unit
|
||||||
|
var updateData: (newData: RowData) -> Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
external class Row(model: RowModel, api: RowAPI) : RowModel, RowAPI {
|
||||||
|
override var toggleChildren: () -> Unit
|
||||||
|
override var updateData: (newData: RowData) -> Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
external class Column : Component<ColumnProps, dynamic> {
|
||||||
|
override fun render(): dynamic
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
var displayName: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
external interface TreeNode {
|
||||||
|
val data: Any
|
||||||
|
val children: Array<TreeNode>?
|
||||||
|
val height: Number?
|
||||||
|
}
|
||||||
|
|
||||||
|
external class TreeState(data: Array<RowModel>) {
|
||||||
|
var data: Array<RowModel>
|
||||||
|
var height: Number
|
||||||
|
var hasData: Boolean
|
||||||
|
fun findRowModel(node: TreeNode): RowModel?
|
||||||
|
fun indexAtYPos(yPos: Number): Number
|
||||||
|
fun yPosAtIndex(index: Number): Number
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun create(data: Array<TreeNode>): TreeState
|
||||||
|
fun createEmpty(): TreeState
|
||||||
|
fun sliceRows(source: TreeState, from: Number, to: Number): Array<RowModel>
|
||||||
|
var _hideRowsInRange: Any
|
||||||
|
var _showRowsInRange: Any
|
||||||
|
fun expandAll(source: TreeState, depthLimit: Number? = definedExternally /* null */): TreeState
|
||||||
|
fun collapseAll(source: TreeState): TreeState
|
||||||
|
fun expandAncestors(source: TreeState, model: RowModel): TreeState
|
||||||
|
fun toggleChildren(source: TreeState, model: RowModel): TreeState
|
||||||
|
fun updateData(source: TreeState, model: RowModel, newData: RowData): TreeState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
external class TreeTable : Component<TreeTableProps, dynamic> {
|
||||||
|
var vListRef: Any
|
||||||
|
override fun render(): dynamic
|
||||||
|
var handleChange: Any
|
||||||
|
fun scrollTo(posY: Number): Unit
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val Column: Column
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package hep.dataforge.vis.js.tree.demo
|
||||||
|
|
||||||
|
external val module: Module
|
||||||
|
|
||||||
|
external interface Module {
|
||||||
|
val hot: Hot?
|
||||||
|
}
|
||||||
|
|
||||||
|
external interface Hot {
|
||||||
|
val data: dynamic
|
||||||
|
|
||||||
|
fun accept()
|
||||||
|
fun accept(dependency: String, callback: () -> Unit)
|
||||||
|
fun accept(dependencies: Array<String>, callback: (updated: Array<String>) -> Unit)
|
||||||
|
|
||||||
|
fun dispose(callback: (data: dynamic) -> Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
external fun require(name: String): dynamic
|
@ -0,0 +1,54 @@
|
|||||||
|
package hep.dataforge.vis.js.tree.demo
|
||||||
|
|
||||||
|
import hep.dataforge.vis.js.tree.ApplicationBase
|
||||||
|
import hep.dataforge.vis.js.tree.TreeTable
|
||||||
|
import hep.dataforge.vis.js.tree.column
|
||||||
|
import hep.dataforge.vis.js.tree.tree
|
||||||
|
import react.dom.render
|
||||||
|
import react.dom.span
|
||||||
|
import kotlin.browser.document
|
||||||
|
|
||||||
|
|
||||||
|
data class TableData(val name: String, val col1: String, val col2: Int)
|
||||||
|
|
||||||
|
class TreeDemoApp : ApplicationBase() {
|
||||||
|
|
||||||
|
override val stateKeys: List<String> = emptyList()
|
||||||
|
|
||||||
|
override fun start(state: Map<String, Any>) {
|
||||||
|
|
||||||
|
println("Starting application")
|
||||||
|
val element = document.getElementById("demo")!!
|
||||||
|
|
||||||
|
println("Started application")
|
||||||
|
|
||||||
|
println("${TreeTable::class} is loaded")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
render(element) {
|
||||||
|
child(TreeTable::class) {
|
||||||
|
attrs {
|
||||||
|
tree<TableData> {
|
||||||
|
child(TableData("aaa", "bbb", 2))
|
||||||
|
child(TableData("ccc", "ddd", 66)) {
|
||||||
|
child(TableData("ddd", "ggg", 22))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onScroll = {}
|
||||||
|
}
|
||||||
|
column<TableData>("title"){
|
||||||
|
span { +(it.data as TableData).name }
|
||||||
|
}
|
||||||
|
column<TableData>("col1"){
|
||||||
|
span { +(it.data as TableData).col1 }
|
||||||
|
}
|
||||||
|
column<TableData>("col2"){
|
||||||
|
span { +(it.data as TableData).col2 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" to presenter.dispose())
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package hep.dataforge.vis.js.tree
|
||||||
|
|
||||||
|
import hep.dataforge.vis.js.tree.demo.TreeDemoApp
|
||||||
|
import hep.dataforge.vis.js.tree.demo.module
|
||||||
|
import kotlin.browser.document
|
||||||
|
import kotlin.dom.hasClass
|
||||||
|
|
||||||
|
|
||||||
|
abstract class ApplicationBase {
|
||||||
|
abstract val stateKeys: List<String>
|
||||||
|
|
||||||
|
abstract fun start(state: Map<String, Any>)
|
||||||
|
abstract fun dispose(): Map<String, Any>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
var application: ApplicationBase? = null
|
||||||
|
|
||||||
|
val state: dynamic = module.hot?.let { hot ->
|
||||||
|
hot.accept()
|
||||||
|
|
||||||
|
hot.dispose { data ->
|
||||||
|
data.appState = application?.dispose()
|
||||||
|
application = null
|
||||||
|
}
|
||||||
|
|
||||||
|
hot.data
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.body != null) {
|
||||||
|
application = start(state)
|
||||||
|
} else {
|
||||||
|
application = null
|
||||||
|
document.addEventListener("DOMContentLoaded", {
|
||||||
|
application = start(state) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start(state: dynamic): ApplicationBase? {
|
||||||
|
return if (document.body?.hasClass("testApp") == true) {
|
||||||
|
val application = TreeDemoApp()
|
||||||
|
|
||||||
|
@Suppress("UnsafeCastFromDynamic")
|
||||||
|
application.start(state?.appState ?: emptyMap<String, Any>())
|
||||||
|
|
||||||
|
application
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package hep.dataforge.vis.js.tree
|
||||||
|
|
||||||
|
import react.RProps
|
||||||
|
import react.ReactElement
|
||||||
|
|
||||||
|
class ColumnProps(
|
||||||
|
var renderCell: (row: Row) -> ReactElement,
|
||||||
|
var renderHeaderCell: () -> ReactElement,
|
||||||
|
var grow: Number? = null,
|
||||||
|
var basis: String? = null // <CSS size> | auto
|
||||||
|
) : RProps
|
||||||
|
|
||||||
|
class TreeTableProps(
|
||||||
|
// Model properties
|
||||||
|
var value: TreeState,
|
||||||
|
var children: Array<ReactElement>,
|
||||||
|
var onChange: ((TreeState) -> Unit)? = null,
|
||||||
|
// View callbacks
|
||||||
|
var onScroll: ((scrollTop: Number) -> Unit)? = null,
|
||||||
|
|
||||||
|
// View properties
|
||||||
|
var height: Number? = null, // view height (px)
|
||||||
|
var headerHeight: Number? = null, // header height (px)
|
||||||
|
var className: String? = null
|
||||||
|
) : RProps
|
@ -0,0 +1,49 @@
|
|||||||
|
package hep.dataforge.vis.js.tree
|
||||||
|
|
||||||
|
import react.RElementBuilder
|
||||||
|
import react.ReactElement
|
||||||
|
import react.createElement
|
||||||
|
import react.dom.span
|
||||||
|
|
||||||
|
typealias RowData = Any
|
||||||
|
|
||||||
|
class TreeNodeBuilder<D : Any>(override val data: D, override var height: Number? = null) : TreeNode {
|
||||||
|
private val _children = ArrayList<TreeNodeBuilder<D>>()
|
||||||
|
override val children: Array<TreeNode> get() = _children.toTypedArray()
|
||||||
|
|
||||||
|
fun child(data: D, block: TreeNodeBuilder<D>.() -> Unit = {}) {
|
||||||
|
val child = TreeNodeBuilder(data).apply(block)
|
||||||
|
_children.add(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TreeTableBuilder<D : Any> {
|
||||||
|
private val children = ArrayList<TreeNode>()
|
||||||
|
|
||||||
|
fun child(data: D, height: Number? = null, block: TreeNodeBuilder<D>.() -> Unit = {}) {
|
||||||
|
this.children.add(TreeNodeBuilder(data, height).apply(block))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build(): TreeState = TreeState.create(children.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <D : Any> TreeState.Companion.build(block: TreeTableBuilder<D>.() -> Unit): TreeState {
|
||||||
|
return TreeTableBuilder<D>().apply(block).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <D : Any> TreeTableProps.tree(block: TreeTableBuilder<D>.() -> Unit) {
|
||||||
|
value = TreeTableBuilder<D>().apply(block).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <D : Any> RElementBuilder<TreeTableProps>.column(
|
||||||
|
name: String,
|
||||||
|
renderer: (Row) -> ReactElement
|
||||||
|
): ReactElement {
|
||||||
|
val props = ColumnProps(
|
||||||
|
renderHeaderCell = { span { +name } },
|
||||||
|
renderCell = { row -> renderer.invoke(row) }
|
||||||
|
)
|
||||||
|
return createElement(TreeTable.Column, props = props)
|
||||||
|
}
|
||||||
|
|
11
dataforge-vis-js-tree/src/main/web/index.html
Normal file
11
dataforge-vis-js-tree/src/main/web/index.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Three js demo for tree</title>
|
||||||
|
<script type="text/javascript" src="main.bundle.js"></script>
|
||||||
|
</head>
|
||||||
|
<body class="testApp">
|
||||||
|
<h1>Tree demo</h1>
|
||||||
|
<div id="demo"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -7,8 +7,8 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":dataforge-vis-spatial"))
|
implementation(project(":dataforge-vis-spatial"))
|
||||||
api("no.tornado:tornadofx:1.7.18")
|
implementation(project(":dataforge-vis-fx"))
|
||||||
implementation("org.fxyz3d:fxyz3d:0.4.0")
|
implementation("org.fxyz3d:fxyz3d:0.4.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ package hep.dataforge.vis.spatial
|
|||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.getProperty
|
import hep.dataforge.vis.common.getProperty
|
||||||
import hep.dataforge.vis.onChange
|
import hep.dataforge.vis.common.onChange
|
||||||
import javafx.beans.binding.ObjectBinding
|
import javafx.beans.binding.ObjectBinding
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ package hep.dataforge.vis.spatial
|
|||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.output.Output
|
import hep.dataforge.output.Output
|
||||||
import hep.dataforge.vis.DisplayGroup
|
import hep.dataforge.vis.common.DisplayGroup
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import javafx.scene.Group
|
import javafx.scene.Group
|
||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
||||||
import org.fxyz3d.shapes.primitives.CuboidMesh
|
import org.fxyz3d.shapes.primitives.CuboidMesh
|
||||||
|
@ -2,7 +2,7 @@ package hep.dataforge.vis.spatial
|
|||||||
|
|
||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.meta.number
|
import hep.dataforge.meta.number
|
||||||
import hep.dataforge.vis.DisplayGroup
|
import hep.dataforge.vis.common.DisplayGroup
|
||||||
import javafx.scene.Parent
|
import javafx.scene.Parent
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
@ -15,7 +15,7 @@ val kotlinVersion: String by rootProject.extra
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":dataforge-vis-spatial"))
|
implementation(project(":dataforge-vis-spatial"))
|
||||||
implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2")
|
implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2")
|
||||||
testCompile("org.jetbrains.kotlin:kotlin-test-js:1.3.21")
|
testCompile(kotlin("test-js"))
|
||||||
}
|
}
|
||||||
|
|
||||||
configure<KotlinFrontendExtension> {
|
configure<KotlinFrontendExtension> {
|
||||||
@ -29,10 +29,9 @@ configure<KotlinFrontendExtension> {
|
|||||||
|
|
||||||
sourceMaps = true
|
sourceMaps = true
|
||||||
|
|
||||||
bundle("webpack") {
|
bundle<WebPackExtension>("webpack") {
|
||||||
this as WebPackExtension
|
this as WebPackExtension
|
||||||
bundleName = "main"
|
bundleName = "main"
|
||||||
proxyUrl = "http://localhost:8080"
|
|
||||||
contentPath = file("src/main/web")
|
contentPath = file("src/main/web")
|
||||||
sourceMapEnabled = true
|
sourceMapEnabled = true
|
||||||
//mode = "production"
|
//mode = "production"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.vis.spatial.jsroot.JSRootDemoApp
|
import hep.dataforge.vis.spatial.ThreeDemoApp
|
||||||
import kotlin.browser.document
|
import kotlin.browser.document
|
||||||
import kotlin.dom.hasClass
|
import kotlin.dom.hasClass
|
||||||
|
|
||||||
@ -37,10 +37,10 @@ fun main() {
|
|||||||
|
|
||||||
fun start(state: dynamic): ApplicationBase? {
|
fun start(state: dynamic): ApplicationBase? {
|
||||||
return if (document.body?.hasClass("testApp") == true) {
|
return if (document.body?.hasClass("testApp") == true) {
|
||||||
val application = JSRootDemoApp()
|
val application = ThreeDemoApp()
|
||||||
|
|
||||||
@Suppress("UnsafeCastFromDynamic")
|
@Suppress("UnsafeCastFromDynamic")
|
||||||
application.start(state?.appState ?: emptyMap())
|
application.start(state?.appState ?: emptyMap<String, Any>())
|
||||||
|
|
||||||
application
|
application
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vis.spatial
|
|||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.meta.number
|
import hep.dataforge.meta.number
|
||||||
import hep.dataforge.vis.ApplicationBase
|
import hep.dataforge.vis.ApplicationBase
|
||||||
import hep.dataforge.vis.DisplayGroup
|
import hep.dataforge.vis.common.DisplayGroup
|
||||||
import hep.dataforge.vis.require
|
import hep.dataforge.vis.require
|
||||||
import hep.dataforge.vis.spatial.jsroot.JSRootPlugin
|
import hep.dataforge.vis.spatial.jsroot.JSRootPlugin
|
||||||
import hep.dataforge.vis.spatial.jsroot.jsRootGeometry
|
import hep.dataforge.vis.spatial.jsroot.jsRootGeometry
|
||||||
|
@ -2,9 +2,9 @@ package hep.dataforge.vis.spatial
|
|||||||
|
|
||||||
import hep.dataforge.meta.boolean
|
import hep.dataforge.meta.boolean
|
||||||
import hep.dataforge.provider.Type
|
import hep.dataforge.provider.Type
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.getProperty
|
import hep.dataforge.vis.common.getProperty
|
||||||
import hep.dataforge.vis.onChange
|
import hep.dataforge.vis.common.onChange
|
||||||
import hep.dataforge.vis.spatial.ThreeFactory.Companion.TYPE
|
import hep.dataforge.vis.spatial.ThreeFactory.Companion.TYPE
|
||||||
import hep.dataforge.vis.spatial.ThreeFactory.Companion.buildMesh
|
import hep.dataforge.vis.spatial.ThreeFactory.Companion.buildMesh
|
||||||
import hep.dataforge.vis.spatial.ThreeFactory.Companion.updateMesh
|
import hep.dataforge.vis.spatial.ThreeFactory.Companion.updateMesh
|
||||||
|
@ -4,8 +4,8 @@ import hep.dataforge.context.Context
|
|||||||
import hep.dataforge.context.content
|
import hep.dataforge.context.content
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.output.Output
|
import hep.dataforge.output.Output
|
||||||
import hep.dataforge.vis.DisplayGroup
|
import hep.dataforge.vis.common.DisplayGroup
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.spatial.three.Group
|
import hep.dataforge.vis.spatial.three.Group
|
||||||
import info.laht.threekt.WebGLRenderer
|
import info.laht.threekt.WebGLRenderer
|
||||||
import info.laht.threekt.cameras.PerspectiveCamera
|
import info.laht.threekt.cameras.PerspectiveCamera
|
||||||
|
@ -4,9 +4,9 @@ import hep.dataforge.meta.Meta
|
|||||||
import hep.dataforge.meta.buildMeta
|
import hep.dataforge.meta.buildMeta
|
||||||
import hep.dataforge.meta.toDynamic
|
import hep.dataforge.meta.toDynamic
|
||||||
import hep.dataforge.meta.values
|
import hep.dataforge.meta.values
|
||||||
import hep.dataforge.vis.DisplayLeaf
|
import hep.dataforge.vis.common.DisplayLeaf
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.int
|
import hep.dataforge.vis.common.int
|
||||||
import hep.dataforge.vis.spatial.MeshThreeFactory
|
import hep.dataforge.vis.spatial.MeshThreeFactory
|
||||||
import hep.dataforge.vis.spatial.jsroot.createCubeBuffer
|
import hep.dataforge.vis.spatial.jsroot.createCubeBuffer
|
||||||
import hep.dataforge.vis.spatial.jsroot.createGeometry
|
import hep.dataforge.vis.spatial.jsroot.createGeometry
|
||||||
|
@ -5,6 +5,7 @@ import hep.dataforge.meta.Meta
|
|||||||
import hep.dataforge.meta.buildMeta
|
import hep.dataforge.meta.buildMeta
|
||||||
import hep.dataforge.meta.toDynamic
|
import hep.dataforge.meta.toDynamic
|
||||||
import hep.dataforge.vis.*
|
import hep.dataforge.vis.*
|
||||||
|
import hep.dataforge.vis.common.*
|
||||||
import hep.dataforge.vis.spatial.MeshThreeFactory
|
import hep.dataforge.vis.spatial.MeshThreeFactory
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.BufferGeometry
|
||||||
|
|
||||||
|
@ -3,10 +3,10 @@ package hep.dataforge.vis.spatial.jsroot
|
|||||||
import hep.dataforge.meta.EmptyMeta
|
import hep.dataforge.meta.EmptyMeta
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.toDynamic
|
import hep.dataforge.meta.toDynamic
|
||||||
import hep.dataforge.vis.DisplayLeaf
|
import hep.dataforge.vis.common.DisplayLeaf
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.DisplayObjectList
|
import hep.dataforge.vis.common.DisplayObjectList
|
||||||
import hep.dataforge.vis.node
|
import hep.dataforge.vis.common.node
|
||||||
import hep.dataforge.vis.spatial.ThreeFactory
|
import hep.dataforge.vis.spatial.ThreeFactory
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.MetaItem
|
|||||||
import hep.dataforge.meta.float
|
import hep.dataforge.meta.float
|
||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.meta.node
|
import hep.dataforge.meta.node
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.spatial.rotationOrder
|
import hep.dataforge.vis.spatial.rotationOrder
|
||||||
import hep.dataforge.vis.spatial.rotationX
|
import hep.dataforge.vis.spatial.rotationX
|
||||||
import hep.dataforge.vis.spatial.rotationY
|
import hep.dataforge.vis.spatial.rotationY
|
||||||
|
@ -2,10 +2,10 @@ package hep.dataforge.vis.spatial
|
|||||||
|
|
||||||
import hep.dataforge.meta.EmptyMeta
|
import hep.dataforge.meta.EmptyMeta
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vis.DisplayLeaf
|
import hep.dataforge.vis.common.DisplayLeaf
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.DisplayObjectList
|
import hep.dataforge.vis.common.DisplayObjectList
|
||||||
import hep.dataforge.vis.double
|
import hep.dataforge.vis.common.double
|
||||||
|
|
||||||
class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||||
var xSize by double(1.0)
|
var xSize by double(1.0)
|
||||||
|
@ -2,9 +2,9 @@ package hep.dataforge.vis.spatial
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.DisplayLeaf
|
import hep.dataforge.vis.common.DisplayLeaf
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.DisplayObjectList
|
import hep.dataforge.vis.common.DisplayObjectList
|
||||||
|
|
||||||
class Convex(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
class Convex(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ package hep.dataforge.vis.spatial
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.DisplayLeaf
|
import hep.dataforge.vis.common.DisplayLeaf
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.DisplayObjectList
|
import hep.dataforge.vis.common.DisplayObjectList
|
||||||
|
|
||||||
class Extruded(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
class Extruded(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ package hep.dataforge.vis.spatial
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.output.Output
|
import hep.dataforge.output.Output
|
||||||
import hep.dataforge.vis.DisplayGroup
|
import hep.dataforge.vis.common.DisplayGroup
|
||||||
import hep.dataforge.vis.DisplayObject
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
import hep.dataforge.vis.DisplayObjectList
|
import hep.dataforge.vis.common.DisplayObjectList
|
||||||
import hep.dataforge.vis.getProperty
|
import hep.dataforge.vis.common.getProperty
|
||||||
|
|
||||||
fun DisplayObjectList.group(meta: Meta = EmptyMeta, action: DisplayObjectList.() -> Unit = {}): DisplayGroup =
|
fun DisplayObjectList.group(meta: Meta = EmptyMeta, action: DisplayObjectList.() -> Unit = {}): DisplayGroup =
|
||||||
DisplayObjectList(this, meta).apply(action).also { addChild(it) }
|
DisplayObjectList(this, meta).apply(action).also { addChild(it) }
|
||||||
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.get
|
|||||||
import hep.dataforge.meta.getAll
|
import hep.dataforge.meta.getAll
|
||||||
import hep.dataforge.meta.node
|
import hep.dataforge.meta.node
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.DisplayObjectList
|
import hep.dataforge.vis.common.DisplayObjectList
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ include(
|
|||||||
":dataforge-vis-fx",
|
":dataforge-vis-fx",
|
||||||
":dataforge-vis-spatial",
|
":dataforge-vis-spatial",
|
||||||
":dataforge-vis-spatial-fx",
|
":dataforge-vis-spatial-fx",
|
||||||
":dataforge-vis-spatial-js"
|
":dataforge-vis-spatial-js",
|
||||||
|
":dataforge-vis-js-tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
//if(file("../dataforge-core").exists()) {
|
//if(file("../dataforge-core").exists()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user