propertyEditor fix (not yet fully functional)

This commit is contained in:
Alexander Nozik 2020-04-13 17:09:44 +03:00
parent 8d3de8688f
commit 3aba8297e8
17 changed files with 197 additions and 164 deletions

View File

@ -39,8 +39,10 @@ kotlin {
api(npm("styled-components"))
api(npm("inline-style-prefixer"))
api(npm("source-map-resolve","0.6.0"))
api(npm("bootstrap","4.3.1"))
api(npm("popper.js","1.14.7"))
api(npm("jquery","3.5.0"))
//api(npm("jsoneditor", "8.6.1"))
api(npm("file-saver","2.0.2"))
}

View File

@ -1,6 +1,7 @@
package hep.dataforge.vis.editor
import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.ItemDescriptor
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.descriptors.defaultItem
import hep.dataforge.meta.descriptors.get
@ -13,6 +14,7 @@ import kotlinx.html.classes
import kotlinx.html.js.onChangeFunction
import kotlinx.html.js.onClickFunction
import org.w3c.dom.Element
import org.w3c.dom.HTMLInputElement
import org.w3c.dom.events.Event
import react.RBuilder
import react.RComponent
@ -47,7 +49,7 @@ interface ConfigEditorProps : RProps {
class ConfigEditorComponent : RComponent<ConfigEditorProps, TreeState>() {
override fun TreeState.init() {
expanded = false
expanded = true
}
override fun componentDidMount() {
@ -70,85 +72,96 @@ class ConfigEditorComponent : RComponent<ConfigEditorProps, TreeState>() {
}
}
private val onValueChange: (Event) -> Unit = {
val value = (it.target as HTMLInputElement).value
try {
if(value.isEmpty()){
props.root.remove(props.name)
}
props.root.setValue(props.name, value.asValue())
} catch (ex: Exception) {
console.error("Can't set config property ${props.name} to $value")
}
}
override fun RBuilder.render() {
val item = props.root[props.name]
val descriptorItem = props.descriptor?.get(props.name)
val descriptorItem: ItemDescriptor? = props.descriptor?.get(props.name)
val defaultItem = props.default?.get(props.name)
val actualItem = item ?: defaultItem ?: descriptorItem?.defaultItem()
val token = props.name.last()
val token = props.name.last()?.toString() ?: "Properties"
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") {
when (actualItem) {
is MetaItem.NodeItem -> {
div("d-inline-block text-truncate") {
span("tree-caret") {
attrs {
if (state.expanded) {
classes += "rotate"
classes += "tree-caret-down"
}
onClickFunction = onClick
}
}
}
}
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
}
span("tree-label") {
+token
attrs {
if (item == null) {
classes += "tree-label-inactive"
}
}
}
}
} else if (actualItem is MetaItem.ValueItem) {
div("row") {
div("col") {
label("tree-label") {
+token.toString()
if (state.expanded) {
ul("tree") {
val keys = buildSet<NameToken> {
item?.node?.items?.keys?.let { addAll(it) }
defaultItem?.node?.items?.keys?.let { addAll(it) }
(descriptorItem as? NodeDescriptor)?.items?.keys?.forEach {
add(NameToken(it))
}
}
}
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")
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
}
}
}
}
//+actualItem.value.toString()
}
}
}
is MetaItem.ValueItem -> {
div("d-inline-block text-truncate") {
div("row") {
div("col") {
p("tree-label") {
+token
attrs {
if (item == null) {
classes += "tree-label-inactive"
}
}
}
}
div("col") {
div("float-right") {
input(type = InputType.text) {
attrs {
defaultValue = actualItem.value.string
onChangeFunction = onValueChange
}
}
//+actualItem.value.toString()
}
}
}
}
}
@ -182,3 +195,15 @@ fun RBuilder.configEditor(config: Config, descriptor: NodeDescriptor? = null, de
}
}
}
fun RBuilder.configEditor(obj: Configurable, descriptor: NodeDescriptor? = obj.descriptor, default: Meta? = null) {
child(ConfigEditorComponent::class) {
attrs {
root = obj.config
name = Name.EMPTY
this.descriptor = descriptor
this.default = default
listen = true
}
}
}

View File

@ -41,15 +41,15 @@ class ObjectTreeComponent : RComponent<ObjectTreeProps, TreeState>() {
//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") {
span("tree-caret") {
attrs {
if (state.expanded) {
classes += "objTree-caret-down"
classes += "tree-caret-down"
}
onClickFunction = onClick
}
}
label("objTree-label") {
a("#",classes = "tree-label") {
+token
attrs {
onClickFunction = { props.clickCallback(props.name) }
@ -57,12 +57,12 @@ class ObjectTreeComponent : RComponent<ObjectTreeProps, TreeState>() {
}
}
if (state.expanded) {
ul("objTree-subtree") {
ul("tree") {
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 {
li("tree-item") {
child(ObjectTreeComponent::class) {
attrs {
name = props.name + childToken
@ -76,8 +76,8 @@ class ObjectTreeComponent : RComponent<ObjectTreeProps, TreeState>() {
}
} else {
div("d-inline-block text-truncate") {
span("objTree-leaf") {}
label("objTree-label") {
span("tree-leaf") {}
a("#",classes = "tree-label") {
+token
attrs {
onClickFunction = { props.clickCallback(props.name) }

View File

@ -93,7 +93,7 @@ fun RBuilder.visualPropertyEditor(
}
}
}
configEditor(item.config, descriptor, Meta(default))
configEditor(item, descriptor, Meta(default))
}
fun Element.visualPropertyEditor(

View File

@ -1,40 +1,42 @@
/* Remove default bullets */
ul, .objTree-subtree {
ul, .tree {
list-style-type: none;
}
/* Style the caret/arrow */
.objTree-caret {
.tree-caret {
cursor: pointer;
user-select: none; /* Prevent text selection */
}
/* Create the caret/arrow with a unicode, and style it */
.objTree-caret::before {
.tree-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);
.tree-leaf{
user-select: none;
display: inline-block;
}
ul, .tree {
list-style-type: none;
}
i, .tree-caret{
.tree-leaf::before {
content: "\25C6";
color: black;
display: inline-block;
margin-right: 6px;
}
.rotate {
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
.tree-caret-down::before {
transform: rotate(90deg);
}
.tree-label-inactive {
background-color: lightgrey;
color: gray;
display: inline-block;
}

View File

@ -26,4 +26,14 @@ class TestConvertor {
val visual = xml.toVisual()
// println(visual)
}
@Test
fun testSimple() {
val stream = javaClass.getResourceAsStream("/gdml/simple1.gdml")
val xmlReader = StAXReader(stream, "UTF-8")
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
val visual = xml.toVisual()
println(visual.stringify())
}
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<gdml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd">
<define/>
<materials>
<material name="Vacuum" Z="1">
<D unit="g/cm3" value="0"/>
<atom unit="g/mole" value="0"/>
</material>
<material name="Al" Z="13">
<D unit="g/cm3" value="2.7000000000000002"/>
<atom unit="g/mole" value="26.98"/>
</material>
</materials>
<solids>
<box name="R" x="50" y="50" z="10" lunit="cm"/>
</solids>
<structure>
<volume name="R">
<materialref ref="Vacuum"/>
<solidref ref="R"/>
</volume>
</structure>
<setup name="default" version="1.0">
<world ref="R"/>
</setup>
</gdml>

View File

@ -47,23 +47,17 @@ class Material3D : Scheme() {
val descriptor by lazy {
//must be lazy to avoid initialization bug
NodeDescriptor {
defineValue(VisualObject3D.VISIBLE_KEY) {
type(ValueType.BOOLEAN)
default(true)
defineValue(COLOR_KEY) {
type(ValueType.STRING, ValueType.NUMBER)
default("#ffffff")
}
defineNode(MATERIAL_KEY) {
defineValue(COLOR_KEY) {
type(ValueType.STRING, ValueType.NUMBER)
default("#ffffff")
}
defineValue(OPACITY_KEY) {
type(ValueType.NUMBER)
default(1.0)
}
defineValue(WIREFRAME_KEY) {
type(ValueType.BOOLEAN)
default(false)
}
defineValue(OPACITY_KEY) {
type(ValueType.NUMBER)
default(1.0)
}
defineValue(WIREFRAME_KEY) {
type(ValueType.BOOLEAN)
default(false)
}
}
}

View File

@ -10,6 +10,7 @@ import hep.dataforge.names.toName
import hep.dataforge.vis.SimpleVisualGroup
import hep.dataforge.vis.Visual
import hep.dataforge.vis.VisualObject
import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.modules.SerializersModule
@ -53,6 +54,7 @@ class Visual3D(meta: Meta) : AbstractPlugin(meta) {
}
}
@OptIn(UnstableDefault::class)
internal val json = Json(
JsonConfiguration(
prettyPrint = true,

View File

@ -17,12 +17,12 @@
}
/* Remove default bullets */
ul, .objTree-subtree {
ul, .tree {
list-style-type: none;
}
/* Style the caret/arrow */
.objTree-caret {
.tree-caret {
cursor: pointer;
user-select: none; /* Prevent text selection */
}
@ -32,7 +32,7 @@ ul, .objTree-subtree {
}
/* Create the caret/arrow with a unicode, and style it */
.objTree-caret::before {
.tree-caret::before {
content: "\25B6";
color: black;
display: inline-block;
@ -47,6 +47,6 @@ ul, .objTree-subtree {
}
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
.objTree-caret-down::before {
.tree-caret-down::before {
transform: rotate(90deg);
}

View File

@ -13,9 +13,19 @@ kotlin {
val installJS = tasks.getByName("jsBrowserDistribution")
js{
browser {
dceTask {
dceOptions {
keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
}
}
}
}
jvm {
withJava()
compilations.findByName("jvmMain").apply {
compilations.findByName("main").apply {
tasks.getByName<ProcessResources>("jvmProcessResources") {
dependsOn(installJS)
afterEvaluate {

View File

@ -10,12 +10,8 @@ import hep.dataforge.vis.VisualObject
import hep.dataforge.vis.editor.card
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
import hep.dataforge.vis.spatial.Visual3D
import hep.dataforge.vis.spatial.VisualObject3D
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
@ -92,28 +88,8 @@ private class MMDemoApp : Application {
visual is VisualGroup -> visual[name] ?: return
else -> return
}
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
}
}
// 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)
// }
editorElement.visualPropertyEditor(name, child, descriptor = VisualObject3D.descriptor)
}
// canvas.clickListener = ::selectElement

File diff suppressed because one or more lines are too long

View File

@ -1,48 +1,40 @@
.loader {
border: 16px solid #f3f3f3; /* Light grey */
border-top: 16px solid #3498db; /* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Remove default bullets */
ul, .objTree-subtree {
ul, .tree {
list-style-type: none;
}
/* Style the caret/arrow */
.objTree-caret {
.tree-caret {
cursor: pointer;
user-select: none; /* Prevent text selection */
}
.objTree-label {
cursor: pointer;
}
/* Create the caret/arrow with a unicode, and style it */
.objTree-caret::before {
.tree-caret::before {
content: "\25B6";
color: black;
display: inline-block;
margin-right: 6px;
}
.objTree-leaf::before {
.tree-leaf{
user-select: none;
display: inline-block;
}
.tree-leaf::before {
content: "\25C6";
color: black;
display: inline-block;
margin-right: 6px;
}
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
.objTree-caret-down::before {
.tree-caret-down::before {
transform: rotate(90deg);
}
.tree-label-inactive {
color: gray;
}

View File

@ -4,10 +4,8 @@
<meta charset="utf-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">-->
<title>Three js demo for particle physics</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="css/jsoneditor.min.css">
<script type="text/javascript" src="main.bundle.js"></script>
</head>
<body class="testApp">

View File

@ -17,6 +17,7 @@ import io.ktor.routing.get
import io.ktor.serialization.json
import io.ktor.server.cio.CIO
import io.ktor.server.engine.embeddedServer
import io.ktor.util.KtorExperimentalAPI
import org.apache.commons.math3.random.JDKRandomGenerator
import ru.mipt.npm.muon.monitor.Model
import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
@ -56,6 +57,7 @@ fun Application.module() {
}
}
@OptIn(KtorExperimentalAPI::class)
fun main() {
embeddedServer(CIO, 8080, host = "localhost", module = Application::module).start(wait = true)
}

View File

@ -1,16 +1,16 @@
/* Remove default bullets */
ul, .objTree-subtree {
ul, .tree {
list-style-type: none;
}
/* Style the caret/arrow */
.objTree-caret {
.tree-caret {
cursor: pointer;
user-select: none; /* Prevent text selection */
}
/* Create the caret/arrow with a unicode, and style it */
.objTree-caret::before {
.tree-caret::before {
content: "\25B6";
color: black;
display: inline-block;
@ -18,7 +18,7 @@ ul, .objTree-subtree {
}
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
.objTree-caret-down::before {
.tree-caret-down::before {
transform: rotate(90deg);
}