Slight design improvement

This commit is contained in:
Alexander Nozik 2020-03-01 17:07:31 +03:00
parent ab47652314
commit 82c003ca22
7 changed files with 135 additions and 35 deletions

View File

@ -37,7 +37,7 @@ kotlin {
jsMain{
dependencies {
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
api(npm("bootstrap","4.4.1"))
//api(npm("bootstrap","4.4.1"))
implementation(npm("jsoneditor"))
implementation(npm("file-saver"))
}

View File

@ -1,8 +1,7 @@
package hep.dataforge.vis.js.editor
import kotlinx.html.TagConsumer
import kotlinx.html.*
import kotlinx.html.js.div
import kotlinx.html.js.h3
import org.w3c.dom.HTMLElement
inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
@ -12,4 +11,51 @@ inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagCo
block()
}
}
}
fun TagConsumer<HTMLElement>.accordion(id: String, elements: Map<String, DIV.() -> Unit>) {
div("container-fluid") {
div("accordion") {
this.id = id
elements.entries.forEachIndexed { index, (title, builder) ->
val headerID = "${id}-${index}-heading"
val collapseID = "${id}-${index}-collapse"
div("card") {
div("card-header") {
this.id = headerID
h5("mb-0") {
button(classes = "btn btn-link collapsed", type = ButtonType.button) {
attributes["data-toggle"] = "collapse"
attributes["data-target"] = "#$collapseID"
attributes["aria-expanded"] = "false"
attributes["aria-controls"] = collapseID
+title
}
}
}
div("collapse") {
this.id = collapseID
attributes["aria-labelledby"] = headerID
attributes["data-parent"] = "#$id"
div("card-body", block = builder)
}
}
}
}
}
}
class AccordionBuilder {
private val map = HashMap<String, DIV.() -> Unit>()
fun entry(title: String, block: DIV.() -> Unit) {
map[title] = block
}
fun build(consumer: TagConsumer<HTMLElement>, id: String) {
consumer.accordion(id, map)
}
}
fun TagConsumer<HTMLElement>.accordion(id: String, block: AccordionBuilder.() -> Unit) {
AccordionBuilder().apply(block).build(this, id)
}

View File

@ -25,7 +25,7 @@ object ThreeLabelFactory : ThreeFactory<Label3D> {
} )
return Mesh(textGeo, getMaterial(obj)).apply {
updatePosition(obj)
obj.onPropertyChange(this@ThreeLabelFactory){name: Name, before: MetaItem<*>?, after: MetaItem<*>? ->
obj.onPropertyChange(this@ThreeLabelFactory){ _: Name, _: MetaItem<*>?, _: MetaItem<*>? ->
//TODO
}
}

View File

@ -74,8 +74,8 @@ class ThreePlugin : AbstractPlugin() {
return@onChildrenChange
}
val parentName = name.cutLast()
val childName = name.last()!!
// val parentName = name.cutLast()
// val childName = name.last()!!
//removing old object
findChild(name)?.let { oldChild ->

View File

@ -1,7 +1,7 @@
package hep.dataforge.vis.spatial.three
import hep.dataforge.js.requireJS
import hep.dataforge.vis.js.editor.card
import hep.dataforge.vis.js.editor.accordion
import hep.dataforge.vis.spatial.Visual3D
import hep.dataforge.vis.spatial.VisualGroup3D
import kotlinx.html.InputType
@ -28,7 +28,64 @@ private fun saveData(event: Event, fileName: String, mimeType: String = "text/pl
fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer<HTMLElement>.() -> Unit = {}) {
clear()
append {
card("Settings") {
accordion("controls") {
entry("Settings") {
div("row") {
div("col-2") {
label("checkbox-inline") {
input(type = InputType.checkBox).apply {
checked = canvas.axes.visible
onChangeFunction = {
canvas.axes.visible = checked
}
}
+"Axes"
}
}
div("col-1") {
button {
+"Export"
onClickFunction = {
val json = (canvas.content as? VisualGroup3D)?.let { group ->
Visual3D.json.stringify(
VisualGroup3D.serializer(),
group
)
}
if (json != null) {
saveData(it, "object.json", "text/json") {
json
}
}
}
}
}
}
}
entry("Layers") {
div("row") {
(0..11).forEach { layer ->
div("col-1") {
label { +layer.toString() }
input(type = InputType.checkBox).apply {
if (layer == 0) {
checked = true
}
onChangeFunction = {
if (checked) {
canvas.camera.layers.enable(layer)
} else {
canvas.camera.layers.disable(layer)
}
}
}
}
}
}
}
}
/* card("Settings") {
div("row") {
div("col-2") {
label("checkbox-inline") {
@ -81,7 +138,7 @@ fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer<HTMLEl
}
}
}
}
}*/
block()
}
}

View File

@ -124,7 +124,7 @@ private class GDMLDemoApp : Application {
//val url = URL("https://drive.google.com/open?id=1w5e7fILMN83JGgB8WANJUYm8OW2s0WVO")
val canvasElement = document.getElementById("canvas") ?: error("Element with id 'canvas' not found on page")
val configElement = document.getElementById("layers") ?: error("Element with id 'layers' not found on page")
val configElement = document.getElementById("config") ?: error("Element with id 'layers' not found on page")
val treeElement = document.getElementById("tree") ?: error("Element with id 'tree' not found on page")
val editorElement = document.getElementById("editor") ?: error("Element with id 'editor' not found on page")
canvasElement.clear()
@ -182,9 +182,9 @@ private class GDMLDemoApp : Application {
// canvas.clickListener = ::selectElement
//tree.visualObjectTree(visual, editor::propertyEditor)
treeElement.displayObjectTree(visual) { name ->
selectElement(name)
canvas.highlight(name)
treeElement.displayObjectTree(visual) { treeName ->
selectElement(treeName)
canvas.highlight(treeName)
}
canvas.render(visual)

View File

@ -4,24 +4,26 @@
<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="css/main.css">
<link rel="stylesheet" href="css/jsoneditor.min.css">
<script type="text/javascript" src="main.bundle.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="css/jsoneditor.min.css">
<link rel="stylesheet" href="css/main.css">
</head>
<body class="testApp">
<div class="container">
<div class="row">
<div class="col-6">
<h1>GDML demo</h1>
</div>
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-lg-3">
<div class="card">
<div class="card-body">
<a>Load file:</a>
<input type="file" id="file_load_button" accept=".gdml, application/xml, application/json"/>
</div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-body" id="drop_zone">
Load data
@ -29,23 +31,18 @@
(drag file here)
</div>
</div>
<div class="overflow-auto" id="tree"></div>
</div>
</div>
</div>
<div class="container">
<h1>GDML demo</h1>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-lg-3" id="tree"></div>
<div class="col-lg-6">
<div class="row" id="layers"></div>
<div class="row container" id="canvas"></div>
<div id="canvas"></div>
</div>
<div class="col-lg-3">
<div class="row" id="config"></div>
<div class="row" id="editor"></div>
</div>
<div class="col-lg-3" id="editor"></div>
</div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script></body>
</html>