Migration to 1.3.70

This commit is contained in:
Alexander Nozik 2020-03-23 22:19:52 +03:00
parent 150fdb2426
commit d4dcd32b73
27 changed files with 803 additions and 140 deletions

View File

@ -18,6 +18,7 @@ allprojects {
maven("https://dl.bintray.com/pdvrieze/maven")
maven("http://maven.jzy3d.org/releases")
maven("https://kotlin.bintray.com/js-externals")
maven("https://kotlin.bintray.com/kotlin-js-wrappers/")
// maven("https://dl.bintray.com/gbaldeck/kotlin")
// maven("https://dl.bintray.com/rjaros/kotlin")
}

View File

@ -1,5 +1,3 @@
import scientifik.serialization
plugins {
id("scientifik.mpp")
}
@ -7,9 +5,6 @@ plugins {
val dataforgeVersion: String by rootProject.extra
//val kvisionVersion: String by rootProject.extra("2.0.0-M1")
serialization()
val fxVersion: String by rootProject.extra
kotlin {
sourceSets {
commonMain {
@ -32,10 +27,22 @@ kotlin {
jsMain {
dependencies {
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
//api(npm("bootstrap","4.4.1"))
implementation(npm("uri-js","4.2.2"))
implementation(npm("jsoneditor","8.6.1"))
implementation(npm("file-saver"))
//React, React DOM + Wrappers (chapter 3)
api("org.jetbrains:kotlin-react:16.13.0-pre.94-kotlin-1.3.70")
api("org.jetbrains:kotlin-react-dom:16.13.0-pre.94-kotlin-1.3.70")
api(npm("react", "16.13.0"))
api(npm("react-dom", "16.13.0"))
//Kotlin Styled (chapter 3)
api("org.jetbrains:kotlin-styled:1.0.0-pre.94-kotlin-1.3.70")
api(npm("styled-components"))
api(npm("inline-style-prefixer"))
api(npm("bootstrap","4.3.1"))
//api(npm("jsoneditor", "8.6.1"))
api(npm("file-saver","2.0.2"))
}
}
}

View File

@ -68,7 +68,7 @@ abstract class AbstractVisualObject : VisualObject {
private var styleCache: Meta? = null
/**
* Collect all styles for this object in a laminate
* Collect all styles for this object in a single cached meta
*/
protected val mergedStyles: Meta
get() = styleCache ?: findAllStyles().merge().also {

View File

@ -1,16 +1,21 @@
package hep.dataforge.vis
import hep.dataforge.meta.*
import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta
import hep.dataforge.meta.descriptors.ValueDescriptor
import hep.dataforge.meta.node
import hep.dataforge.meta.scheme.getProperty
import hep.dataforge.meta.scheme.setProperty
import hep.dataforge.meta.string
import hep.dataforge.values.asValue
/**
* Extension property to access the "widget" key of [ValueDescriptor]
*/
var ValueDescriptor.widget: Meta
get() = this.config["widget"].node?: EmptyMeta
get() = getProperty("widget").node ?: EmptyMeta
set(value) {
config["widget"] = value
setProperty("widget", value)
}
/**
@ -19,5 +24,5 @@ var ValueDescriptor.widget: Meta
var ValueDescriptor.widgetType: String?
get() = getProperty("widget.type").string
set(value) {
config["widget.type"] = value
setProperty("widget.type", value?.asValue())
}

View File

@ -0,0 +1,17 @@
package hep.dataforge.js
import react.RComponent
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
fun <T> RComponent<*, *>.initState(init: () -> T): ReadWriteProperty<RComponent<*, *>, T> =
object : ReadWriteProperty<RComponent<*, *>, T> {
val pair = react.useState(init)
override fun getValue(thisRef: RComponent<*, *>, property: KProperty<*>): T {
return pair.first
}
override fun setValue(thisRef: RComponent<*, *>, property: KProperty<*>, value: T) {
pair.second(value)
}
}

View File

@ -0,0 +1,178 @@
package hep.dataforge.vis.editor
import hep.dataforge.js.initState
import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.descriptors.defaultItem
import hep.dataforge.meta.descriptors.get
import hep.dataforge.names.Name
import hep.dataforge.names.NameToken
import hep.dataforge.names.plus
import hep.dataforge.values.asValue
import kotlinx.html.InputType
import kotlinx.html.classes
import kotlinx.html.js.onChangeFunction
import kotlinx.html.js.onClickFunction
import org.w3c.dom.Element
import react.*
import react.dom.*
interface ConfigEditorProps : RProps {
/**
* Root config object - always non null
*/
var root: Config
/**
* Full path to the displayed node in [root]. Could be empty
*/
var name: Name
/**
* Root default
*/
var default: Meta?
/**
* Root descriptor
*/
var descriptor: NodeDescriptor?
var listen: Boolean
}
class ConfigEditorComponent : RComponent<ConfigEditorProps, TreeState>() {
override fun TreeState.init() {
expanded = false
}
override fun componentDidMount() {
if (props.listen) {
props.root.onChange(this) { name, _, _ ->
if (name == props.name) {
forceUpdate()
}
}
}
}
override fun componentWillUnmount() {
props.root.removeListener(this)
}
override fun RBuilder.render() {
val item = props.root[props.name]
val descriptorItem = props.descriptor?.get(props.name)
val defaultItem = props.default?.get(props.name)
val actualItem = item ?: defaultItem ?: descriptorItem?.defaultItem()
val token = props.name.last()
div("d-inline-block text-truncate") {
when (actualItem) {
null -> {
}
is MetaItem.ValueItem -> {
i("tree-caret") { }
}
is MetaItem.NodeItem -> {
i("tree-caret fa fa-caret-right") {
attrs {
if (state.expanded) {
classes += "rotate"
}
onClickFunction = {
setState {
expanded = !expanded
}
}
}
}
}
}
label("tree-label") {
+token.toString()
attrs {
if (item == null) {
classes += "tree-label-inactive"
}
}
}
if (actualItem is MetaItem.NodeItem && state.expanded) {
ul("tree") {
val keys = buildList<NameToken> {
item?.node?.items?.keys?.let { addAll(it) }
defaultItem?.node?.items?.keys?.let { addAll(it) }
(descriptorItem as? NodeDescriptor)?.items?.keys?.forEach {
add(NameToken(it))
}
}
keys.forEach { token ->
li("tree-item") {
child(ConfigEditorComponent::class) {
attrs {
root = props.root
name = props.name + token
this.default = props.default
this.descriptor = props.descriptor
listen = false
}
}
}
}
}
} else if (actualItem is MetaItem.ValueItem) {
div("row") {
div("col") {
label("tree-label") {
+token.toString()
}
}
div("col") {
input(type = InputType.text) {
attrs {
value = actualItem.value.toString()
onChangeFunction = {
try {
props.root.setValue(props.name, value.asValue())
} catch (ex: Exception) {
console.error("Can't set config property $name to $value")
}
}
}
}
//+actualItem.value.toString()
}
}
}
}
}
}
fun Element.configEditor(config: Config, descriptor: NodeDescriptor? = null, default: Meta? = null) {
render(this) {
child(ConfigEditorComponent::class) {
attrs {
root = config
name = Name.EMPTY
this.descriptor = descriptor
this.default = default
listen = true
}
}
}
}
fun RBuilder.configEditor(config: Config, descriptor: NodeDescriptor? = null, default: Meta? = null) {
child(ConfigEditorComponent::class) {
attrs {
root = config
name = Name.EMPTY
this.descriptor = descriptor
this.default = default
listen = true
}
}
}

View File

@ -0,0 +1,81 @@
package hep.dataforge.vis.editor
import hep.dataforge.js.initState
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.names.NameToken
import kotlinx.html.classes
import kotlinx.html.js.onClickFunction
import react.*
import react.dom.*
interface MetaViewerProps : RProps {
var name: NameToken
var meta: Meta
var descriptor: NodeDescriptor?
}
class MetaViewerComponent : RComponent<MetaViewerProps, TreeState>() {
override fun TreeState.init() {
expanded = false
}
override fun RBuilder.render() {
div("d-inline-block text-truncate") {
if (props.meta.items.isNotEmpty()) {
span("objTree-caret") {
attrs {
classes = if (state.expanded) {
setOf("objTree-caret", "objTree-caret-down")
} else {
setOf("objTree-caret")
}
onClickFunction = {
setState {
expanded = !expanded
}
}
}
}
}
label("tree-label") {
+props.name.toString()
}
ul("tree") {
props.meta.items.forEach { (token, item) ->
//val descriptor = props.
li {
when (item) {
is MetaItem.NodeItem -> {
child(MetaViewerComponent::class) {
attrs {
name = token
meta = item.node
descriptor = props.descriptor?.nodes?.get(token.body)
}
}
}
is MetaItem.ValueItem -> {
div("row") {
div("col") {
label("tree-label") {
+token.toString()
}
}
div("col") {
label {
+item.value.toString()
}
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,108 @@
package hep.dataforge.vis.editor
import hep.dataforge.names.Name
import hep.dataforge.names.plus
import hep.dataforge.vis.VisualGroup
import hep.dataforge.vis.VisualObject
import hep.dataforge.vis.isEmpty
import kotlinx.html.classes
import kotlinx.html.js.onClickFunction
import org.w3c.dom.Element
import react.*
import react.dom.*
interface ObjectTreeProps : RProps {
var name: Name
var obj: VisualObject
var clickCallback: (Name) -> Unit
}
interface TreeState : RState {
var expanded: Boolean
}
class ObjectTreeComponent : RComponent<ObjectTreeProps, TreeState>() {
override fun TreeState.init() {
expanded = false
}
override fun RBuilder.render() {
val token = props.name.last()?.toString() ?: "World"
val obj = props.obj
//display as node if any child is visible
if (obj is VisualGroup && obj.children.keys.any { !it.body.startsWith("@") }) {
div("d-inline-block text-truncate") {
span("objTree-caret") {
attrs {
classes = if (state.expanded) {
setOf("objTree-caret", "objTree-caret-down")
} else {
setOf("objTree-caret")
}
onClickFunction = {
setState {
expanded = !expanded
}
}
}
}
label("objTree-label") {
+token
attrs {
onClickFunction = { props.clickCallback(props.name) }
}
}
}
if (state.expanded) {
ul("objTree-subtree") {
obj.children.entries
.filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children
.sortedBy { (it.value as? VisualGroup)?.isEmpty ?: true }
.forEach { (childToken, child) ->
li {
child(ObjectTreeComponent::class) {
attrs {
name = props.name + childToken
this.obj = child
clickCallback = props.clickCallback
}
}
}
}
}
}
} else {
div("d-inline-block text-truncate") {
span("objTree-leaf") {}
label("objTree-label") {
+token
attrs {
onClickFunction = { props.clickCallback(props.name) }
}
}
}
}
}
}
fun RBuilder.objectTree(
obj: VisualObject,
clickCallback: (Name) -> Unit = {}
) = child(ObjectTreeComponent::class) {
attrs {
name = Name.EMPTY
this.obj = obj
this.clickCallback = clickCallback
}
}
fun Element.objectTree(
obj: VisualObject,
clickCallback: (Name) -> Unit = {}
) {
render(this) {
objectTree(obj, clickCallback)
}
}

View File

@ -3,6 +3,10 @@ package hep.dataforge.vis.editor
import kotlinx.html.*
import kotlinx.html.js.div
import org.w3c.dom.HTMLElement
import react.RBuilder
import react.ReactElement
import react.dom.div
import react.dom.h3
inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
div("card w-100") {
@ -13,6 +17,14 @@ inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagCo
}
}
inline fun RBuilder.card(title: String, crossinline block: RBuilder.() -> Unit): ReactElement = div("card w-100") {
div("card-body") {
h3(classes = "card-title") { +title }
block()
}
}
fun TagConsumer<HTMLElement>.accordion(id: String, elements: Map<String, DIV.() -> Unit>) {
div("container-fluid") {
div("accordion") {

View File

@ -13,18 +13,18 @@ import org.w3c.dom.HTMLElement
import org.w3c.dom.HTMLSpanElement
import kotlin.dom.clear
fun Element.displayObjectTree(
obj: VisualObject,
clickCallback: (Name) -> Unit = {}
) {
clear()
append {
card("Object tree") {
subTree(Name.EMPTY, obj, clickCallback)
}
}
}
//fun Element.displayObjectTree(
// obj: VisualObject,
// clickCallback: (Name) -> Unit = {}
//) {
// clear()
// append {
// card("Object tree") {
// subTree(Name.EMPTY, obj, clickCallback)
// }
// }
//}
//
private fun TagConsumer<HTMLElement>.subTree(
name: Name,
obj: VisualObject,

View File

@ -1,38 +1,88 @@
package hep.dataforge.vis.editor
import hep.dataforge.js.jsObject
import hep.dataforge.meta.DynamicMeta
import hep.dataforge.meta.Meta
import hep.dataforge.meta.toJson
import hep.dataforge.meta.update
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.names.Name
import hep.dataforge.names.isEmpty
import hep.dataforge.vis.VisualObject
import hep.dataforge.vis.findStyle
import kotlinx.html.dom.append
import kotlinx.html.js.*
import org.w3c.dom.Element
import react.RBuilder
import react.ReactElement
import react.dom.li
import react.dom.nav
import react.dom.ol
import react.dom.render
import kotlin.collections.set
import kotlin.dom.clear
//FIXME something rotten in JS-Meta converter
fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString())
////FIXME something rotten in JS-Meta converter
//fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString())
//
////TODO add node descriptor instead of configuring property selector
//fun Element.displayPropertyEditor(
// name: Name,
// item: VisualObject,
// propertySelector: (VisualObject) -> Meta = { it.config }
//) {
// clear()
//
// append {
// card("Properties") {
// if (!name.isEmpty()) {
// nav {
// attributes["aria-label"] = "breadcrumb"
// ol("breadcrumb") {
// name.tokens.forEach { token ->
// li("breadcrumb-item") {
// +token.toString()
// }
// }
// }
// }
// }
// val dMeta: dynamic = propertySelector(item).toDynamic()
// val options: JSONEditorOptions = jsObject {
// mode = "form"
// onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) }
// }
// JSONEditor(div(), options, dMeta)
// }
//
// val styles = item.styles
// if (styles.isNotEmpty()) {
// card("Styles") {
// item.styles.forEach { style ->
// val styleMeta = item.findStyle(style)
// h4("container") { +style }
// if (styleMeta != null) {
// div("container").apply {
// val options: JSONEditorOptions = jsObject {
// mode = "view"
// }
// JSONEditor(
// this,
// options,
// styleMeta.toDynamic()
// )
// }
// }
// }
// }
// }
// }
//}
//TODO add node descriptor instead of configuring property selector
fun Element.displayPropertyEditor(
name: Name,
fun RBuilder.visualPropertyEditor(
path: Name,
item: VisualObject,
propertySelector: (VisualObject) -> Meta = { it.config }
) {
clear()
append {
card("Properties") {
if (!name.isEmpty()) {
default: MetaBuilder.() -> Unit = {}
): ReactElement = card("Properties") {
if (!path.isEmpty()) {
nav {
attrs {
attributes["aria-label"] = "breadcrumb"
}
ol("breadcrumb") {
name.tokens.forEach { token ->
path.tokens.forEach { token ->
li("breadcrumb-item") {
+token.toString()
}
@ -40,34 +90,13 @@ fun Element.displayPropertyEditor(
}
}
}
val dMeta: dynamic = propertySelector(item).toDynamic()
val options: JSONEditorOptions = jsObject {
mode = "form"
onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) }
}
JSONEditor(div(), options, dMeta)
configEditor(item.config, item.descriptor, Meta(default))
}
val styles = item.styles
if (styles.isNotEmpty()) {
card("Styles") {
item.styles.forEach { style ->
val styleMeta = item.findStyle(style)
h4("container") { +style }
if (styleMeta != null) {
div("container").apply {
val options: JSONEditorOptions = jsObject {
mode = "view"
}
JSONEditor(
this,
options,
styleMeta.toDynamic()
)
}
}
}
}
}
}
fun Element.visualPropertyEditor(
path: Name,
item: VisualObject,
default: MetaBuilder.() -> Unit = {}
) = render(this) {
visualPropertyEditor(path, item, default)
}

View File

@ -21,3 +21,20 @@ ul, .objTree-subtree {
.objTree-caret-down::before {
transform: rotate(90deg);
}
ul, .tree {
list-style-type: none;
}
i, .tree-caret{
display: inline-block;
margin-right: 6px;
}
.rotate {
transform: rotate(90deg);
}
.tree-label-inactive {
color: gray;
}

View File

@ -108,8 +108,7 @@ interface ValueChooser {
descriptor: ValueDescriptor? = null,
setter: (Value) -> Unit
): ValueChooser {
val chooser =
build(context, descriptor)
val chooser = build(context, descriptor)
chooser.setDisplayValue(value.value ?: Null)
value.onChange {
chooser.setDisplayValue(it ?: Null)

View File

@ -7,7 +7,7 @@ kotlin {
val commonMain by getting {
dependencies {
api(project(":dataforge-vis-spatial"))
api("scientifik:gdml:0.1.6")
api("scientifik:gdml:0.1.7")
}
}
}

View File

@ -11,7 +11,6 @@ import hep.dataforge.names.NameToken
import hep.dataforge.names.asName
import hep.dataforge.names.plus
import hep.dataforge.vis.*
import hep.dataforge.vis.common.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient

View File

@ -213,3 +213,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val canvas: Canv
fun ThreePlugin.output(element: HTMLElement, spec: Canvas = Canvas.empty()): ThreeCanvas =
ThreeCanvas(element, this, spec)
fun ThreePlugin.render(element: HTMLElement, obj: VisualObject3D, spec: Canvas = Canvas.empty()): Unit =
output(element, spec).render(obj)

View File

@ -0,0 +1,56 @@
package hep.dataforge.vis.spatial.three
import hep.dataforge.context.Global
import hep.dataforge.vis.spatial.VisualObject3D
import hep.dataforge.vis.spatial.specifications.Canvas
import kotlinx.html.id
import org.w3c.dom.HTMLElement
import react.RBuilder
import react.RComponent
import react.RProps
import react.RState
import react.dom.div
import kotlin.browser.document
import kotlin.dom.clear
interface ThreeCanvasProps : RProps {
var obj: VisualObject3D
var canvasId: String
var options: Canvas
}
class ThreeCanvasComponent : RComponent<ThreeCanvasProps, RState>() {
private val three: ThreePlugin = Global.plugins.fetch(ThreePlugin)
override fun componentDidMount() {
val element = document.getElementById(props.canvasId) as? HTMLElement
?: error("Element with id 'canvas' not found on page")
val output = three.output(element, props.options)
output.render(props.obj)
}
override fun componentWillUnmount() {
val element = document.getElementById(props.canvasId) as? HTMLElement
?: error("Element with id 'canvas' not found on page")
element.clear()
}
override fun RBuilder.render() {
div {
attrs {
id = props.canvasId
}
}
}
}
fun RBuilder.threeCanvas(object3D: VisualObject3D, id: String = "threeCanvas", options: Canvas.() -> Unit = {}) {
child(ThreeCanvasComponent::class) {
attrs {
this.obj = object3D
this.canvasId = id
this.options = Canvas.invoke(options)
}
}
}

View File

@ -9,8 +9,8 @@ import hep.dataforge.names.Name
import hep.dataforge.names.isEmpty
import hep.dataforge.vis.VisualGroup
import hep.dataforge.vis.VisualObject
import hep.dataforge.vis.editor.displayObjectTree
import hep.dataforge.vis.editor.displayPropertyEditor
import hep.dataforge.vis.editor.objectTree
import hep.dataforge.vis.editor.visualPropertyEditor
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_WIREFRAME_KEY
@ -163,26 +163,35 @@ private class GDMLDemoApp : Application {
visual is VisualGroup -> visual[name] ?: return
else -> return
}
editorElement.displayPropertyEditor(name, child) { item ->
//val descriptorMeta = Material3D.descriptor
val properties = item.allProperties()
val bottom = Meta {
VISIBLE_KEY put (item.visible ?: true)
if (item is VisualObject3D) {
editorElement.visualPropertyEditor(name, child) {
VISIBLE_KEY put true
if (child is VisualObject3D) {
MATERIAL_COLOR_KEY put "#ffffff"
MATERIAL_OPACITY_KEY put 1.0
MATERIAL_WIREFRAME_KEY put false
}
}
properties.withBottom(bottom)
}
// editorElement.displayPropertyEditor(name, child) { item ->
// //val descriptorMeta = Material3D.descriptor
//
// val properties = item.allProperties()
// val bottom = Meta {
// VISIBLE_KEY put (item.visible ?: true)
// if (item is VisualObject3D) {
// MATERIAL_COLOR_KEY put "#ffffff"
// MATERIAL_OPACITY_KEY put 1.0
// MATERIAL_WIREFRAME_KEY put false
// }
// }
// properties.withBottom(bottom)
// }
}
// canvas.clickListener = ::selectElement
//tree.visualObjectTree(visual, editor::propertyEditor)
treeElement.displayObjectTree(visual) { treeName ->
treeElement.objectTree(visual) { treeName ->
selectElement(treeName)
canvas.highlight(treeName)
}

View File

@ -7,7 +7,7 @@ plugins {
group = "ru.mipt.npm"
val ktor_version = "1.3.2"
val ktorVersion = "1.3.2"
kotlin {
@ -34,23 +34,28 @@ kotlin {
jvmMain {
dependencies {
implementation("org.apache.commons:commons-math3:3.6.1")
implementation("io.ktor:ktor-server-cio:$ktor_version")
implementation("io.ktor:ktor-serialization:$ktor_version")
implementation("io.ktor:ktor-server-cio:$ktorVersion")
implementation("io.ktor:ktor-serialization:$ktorVersion")
}
}
jsMain {
dependencies {
implementation("io.ktor:ktor-client-js:$ktor_version")
implementation("io.ktor:ktor-client-serialization-js:$ktor_version")
implementation("io.ktor:ktor-client-js:$ktorVersion")
implementation("io.ktor:ktor-client-serialization-js:$ktorVersion")
implementation(npm("text-encoding"))
implementation(npm("abort-controller"))
implementation(npm("bufferutil"))
implementation(npm("utf-8-validate"))
// implementation(npm("jquery"))
// implementation(npm("popper.js"))
// implementation(npm("react-is"))
}
}
}
}
application {
mainClassName = "ru.mipt.npm.muon.monitor.server/MMServerKt"
mainClassName = "ru.mipt.npm.muon.monitor.server.MMServerKt"
}
//configure<JavaFXOptions> {

View File

@ -3,15 +3,13 @@ package ru.mipt.npm.muon.monitor
import hep.dataforge.context.Global
import hep.dataforge.js.Application
import hep.dataforge.js.startApplication
import hep.dataforge.meta.Meta
import hep.dataforge.meta.withBottom
import hep.dataforge.names.Name
import hep.dataforge.names.isEmpty
import hep.dataforge.vis.VisualGroup
import hep.dataforge.vis.VisualObject
import hep.dataforge.vis.editor.card
import hep.dataforge.vis.editor.displayObjectTree
import hep.dataforge.vis.editor.displayPropertyEditor
import hep.dataforge.vis.editor.objectTree
import hep.dataforge.vis.editor.visualPropertyEditor
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_WIREFRAME_KEY
@ -21,7 +19,6 @@ import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
import hep.dataforge.vis.spatial.three.ThreePlugin
import hep.dataforge.vis.spatial.three.displayCanvasControls
import hep.dataforge.vis.spatial.three.output
import hep.dataforge.vis.spatial.visible
import info.laht.threekt.math.Vector3
import io.ktor.client.HttpClient
import io.ktor.client.features.json.JsonFeature
@ -94,26 +91,34 @@ private class MMDemoApp : Application {
visual is VisualGroup -> visual[name] ?: return
else -> return
}
editorElement.displayPropertyEditor(name, child) { item ->
//val descriptorMeta = Material3D.descriptor
val properties = item.allProperties()
val bottom = Meta {
VISIBLE_KEY put (item.visible ?: true)
if (item is VisualObject3D) {
editorElement.visualPropertyEditor(name, child) {
VISIBLE_KEY put true
if (child is VisualObject3D) {
MATERIAL_COLOR_KEY put "#ffffff"
MATERIAL_OPACITY_KEY put 1.0
MATERIAL_WIREFRAME_KEY put false
}
}
properties.withBottom(bottom)
}
// editorElement.displayPropertyEditor(name, child) { item ->
// //val descriptorMeta = Material3D.descriptor
//
// val properties = item.allProperties()
// val bottom = Meta {
// VISIBLE_KEY put (item.visible ?: true)
// if (item is VisualObject3D) {
// MATERIAL_COLOR_KEY put "#ffffff"
// MATERIAL_OPACITY_KEY put 1.0
// MATERIAL_WIREFRAME_KEY put false
// }
// }
// properties.withBottom(bottom)
// }
}
// canvas.clickListener = ::selectElement
//tree.visualObjectTree(visual, editor::propertyEditor)
treeElement.displayObjectTree(visual) { name ->
treeElement.objectTree(visual) { name ->
selectElement(name)
canvas.highlight(name)
}

View File

@ -16,14 +16,6 @@ kotlin {
withJava()
}
js {
browser {
webpackTask {
sourceMaps = false
}
}
}
sourceSets {
commonMain {
dependencies {

View File

@ -39,7 +39,6 @@ private class ThreeDemoApp : Application {
}
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" put presenter.dispose())
}
fun main() {

View File

@ -0,0 +1,27 @@
plugins {
kotlin("multiplatform")
}
repositories{
jcenter()
maven("https://kotlin.bintray.com/kotlinx")
maven("https://dl.bintray.com/kotlin/kotlin-eap")
maven("https://dl.bintray.com/mipt-npm/dataforge")
maven("https://dl.bintray.com/mipt-npm/scientifik")
maven("https://dl.bintray.com/mipt-npm/dev")
}
kotlin {
js {
browser {}
}
sourceSets {
commonMain {
dependencies {
api(project(":dataforge-vis-spatial"))
api(project(":dataforge-vis-spatial-gdml"))
}
}
}
}

View File

@ -0,0 +1,56 @@
import hep.dataforge.context.Global
import hep.dataforge.js.Application
import hep.dataforge.js.startApplication
import hep.dataforge.names.Name
import hep.dataforge.vis.editor.objectTree
import hep.dataforge.vis.editor.visualPropertyEditor
import hep.dataforge.vis.spatial.Point3D
import hep.dataforge.vis.spatial.VisualGroup3D
import hep.dataforge.vis.spatial.box
import hep.dataforge.vis.spatial.group
import hep.dataforge.vis.spatial.three.ThreePlugin
import hep.dataforge.vis.spatial.three.threeCanvas
import org.w3c.dom.HTMLElement
import react.dom.div
import react.dom.render
import kotlin.browser.document
private class PlayGroundApp : Application {
private val three = Global.plugins.fetch(ThreePlugin)
override fun start(state: Map<String, Any>) {
val element =
document.getElementById("app") as? HTMLElement ?: error("Element with id 'canvas' not found on page")
val obj = VisualGroup3D().apply {
box(100, 100, 100)
group {
position = Point3D(120, 0, 0)
box(100, 100, 100)
}
}
render(element) {
div("row") {
div("col-3") {
objectTree(obj)
}
div("col-6") {
threeCanvas(obj)
}
div("col-3") {
visualPropertyEditor(Name.EMPTY, obj)
}
}
}
}
}
fun main() {
startApplication(::PlayGroundApp)
}

View File

@ -0,0 +1,40 @@
/* 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);
}
ul, .tree {
list-style-type: none;
}
i, .tree-caret{
display: inline-block;
margin-right: 6px;
}
.rotate {
transform: rotate(90deg);
}
.tree-label-inactive {
color: gray;
}

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Playground</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="css/common.css">
<script type="text/javascript" src="playground.js"></script>
</head>
<body class="testApp">
<div class="container">
<h1>Playground</h1>
</div>
<div id="app"></div>
</body>
</html>

View File

@ -30,7 +30,8 @@ include(
":dataforge-vis-spatial-gdml",
":demo:spatial-showcase",
":demo:gdml",
":demo:muon-monitor"
":demo:muon-monitor",
":playground"
)
//if(file("../dataforge-core").exists()) {