0.2.0 #71
@ -3,6 +3,9 @@ package space.kscience.visionforge.gdml.demo
|
|||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
import kotlinx.coroutines.Deferred
|
import kotlinx.coroutines.Deferred
|
||||||
|
import kotlinx.css.height
|
||||||
|
import kotlinx.css.pt
|
||||||
|
import kotlinx.css.vh
|
||||||
import org.w3c.files.File
|
import org.w3c.files.File
|
||||||
import org.w3c.files.FileReader
|
import org.w3c.files.FileReader
|
||||||
import org.w3c.files.get
|
import org.w3c.files.get
|
||||||
@ -20,6 +23,8 @@ import space.kscience.visionforge.ring.tab
|
|||||||
import space.kscience.visionforge.root
|
import space.kscience.visionforge.root
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
import styled.css
|
||||||
|
import styled.styledDiv
|
||||||
|
|
||||||
external interface GDMLAppProps : RProps {
|
external interface GDMLAppProps : RProps {
|
||||||
var context: Context
|
var context: Context
|
||||||
@ -63,6 +68,10 @@ val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
|||||||
return deferred
|
return deferred
|
||||||
}
|
}
|
||||||
|
|
||||||
|
styledDiv {
|
||||||
|
css {
|
||||||
|
height = 100.vh - 12.pt
|
||||||
|
}
|
||||||
child(ThreeCanvasWithControls) {
|
child(ThreeCanvasWithControls) {
|
||||||
attrs {
|
attrs {
|
||||||
this.context = props.context
|
this.context = props.context
|
||||||
@ -83,4 +92,5 @@ val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,14 @@ kotlin {
|
|||||||
jvm {
|
jvm {
|
||||||
withJava()
|
withJava()
|
||||||
}
|
}
|
||||||
|
js {
|
||||||
|
useCommonJs()
|
||||||
|
browser {
|
||||||
|
commonWebpackConfig {
|
||||||
|
cssSupport.enabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
val jsBrowserDistribution by tasks.getting
|
val jsBrowserDistribution by tasks.getting
|
||||||
@ -43,7 +51,7 @@ kotlin {
|
|||||||
}
|
}
|
||||||
jsMain {
|
jsMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":ui:bootstrap"))
|
implementation(project(":ui:ring"))
|
||||||
implementation("io.ktor:ktor-client-js:$ktorVersion")
|
implementation("io.ktor:ktor-client-js:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
|
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
|
||||||
implementation(project(":visionforge-threejs"))
|
implementation(project(":visionforge-threejs"))
|
||||||
|
@ -2,31 +2,27 @@ package ru.mipt.npm.muon.monitor
|
|||||||
|
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.get
|
||||||
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import kotlinx.html.js.onClickFunction
|
import kotlinx.html.js.onClickFunction
|
||||||
import react.*
|
import react.*
|
||||||
import react.dom.*
|
import react.dom.attrs
|
||||||
|
import react.dom.button
|
||||||
|
import react.dom.p
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.NameToken
|
|
||||||
import space.kscience.dataforge.names.isEmpty
|
|
||||||
import space.kscience.dataforge.names.length
|
|
||||||
import space.kscience.visionforge.Vision
|
|
||||||
import space.kscience.visionforge.bootstrap.canvasControls
|
|
||||||
import space.kscience.visionforge.bootstrap.card
|
|
||||||
import space.kscience.visionforge.bootstrap.gridRow
|
|
||||||
import space.kscience.visionforge.bootstrap.visionPropertyEditor
|
|
||||||
import space.kscience.visionforge.react.ThreeCanvasComponent
|
|
||||||
import space.kscience.visionforge.react.flexColumn
|
import space.kscience.visionforge.react.flexColumn
|
||||||
import space.kscience.visionforge.react.visionTree
|
import space.kscience.visionforge.react.flexRow
|
||||||
|
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||||||
|
import space.kscience.visionforge.ring.tab
|
||||||
import space.kscience.visionforge.solid.specifications.Camera
|
import space.kscience.visionforge.solid.specifications.Camera
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
import space.kscience.visionforge.solid.three.edges
|
import space.kscience.visionforge.solid.three.edges
|
||||||
import styled.css
|
import styled.css
|
||||||
import styled.styledDiv
|
import styled.styledDiv
|
||||||
|
import styled.styledSpan
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
external interface MMAppProps : RProps {
|
external interface MMAppProps : RProps {
|
||||||
@ -39,11 +35,6 @@ external interface MMAppProps : RProps {
|
|||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
@JsExport
|
@JsExport
|
||||||
val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
||||||
var selected by useState { props.selected }
|
|
||||||
|
|
||||||
val onSelect: (Name?) -> Unit = {
|
|
||||||
selected = it
|
|
||||||
}
|
|
||||||
|
|
||||||
val mmOptions = useMemo {
|
val mmOptions = useMemo {
|
||||||
Canvas3DOptions {
|
Canvas3DOptions {
|
||||||
@ -52,7 +43,6 @@ val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
|||||||
latitude = PI / 6
|
latitude = PI / 6
|
||||||
azimuth = PI + PI / 6
|
azimuth = PI + PI / 6
|
||||||
}
|
}
|
||||||
this.onSelect = onSelect
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,68 +52,30 @@ val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gridRow {
|
var events: Set<Event> by useState(emptySet())
|
||||||
flexColumn {
|
|
||||||
css {
|
|
||||||
+"col-lg-3"
|
|
||||||
+"order-lg-1"
|
|
||||||
+"order-2"
|
|
||||||
padding(0.px)
|
|
||||||
overflowY = Overflow.auto
|
|
||||||
height = 100.vh
|
|
||||||
}
|
|
||||||
//tree
|
|
||||||
card("Object tree") {
|
|
||||||
css {
|
|
||||||
flex(1.0, 1.0, FlexBasis.auto)
|
|
||||||
}
|
|
||||||
visionTree(root, selected, onSelect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flexColumn {
|
|
||||||
css {
|
|
||||||
+"col-lg-6"
|
|
||||||
+"order-lg-2"
|
|
||||||
+"order-1"
|
|
||||||
height = 100.vh
|
|
||||||
}
|
|
||||||
h1("mx-auto page-header") {
|
|
||||||
+"Muon monitor demo"
|
|
||||||
}
|
|
||||||
//canvas
|
|
||||||
|
|
||||||
child(ThreeCanvasComponent) {
|
|
||||||
attrs {
|
|
||||||
this.context = props.context
|
|
||||||
this.solid = root
|
|
||||||
this.selected = selected
|
|
||||||
this.options = mmOptions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flexColumn {
|
|
||||||
css {
|
|
||||||
+"col-lg-3"
|
|
||||||
+"order-3"
|
|
||||||
padding(0.px)
|
|
||||||
height = 100.vh
|
|
||||||
}
|
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css {
|
css {
|
||||||
flex(0.0, 1.0, FlexBasis.zero)
|
height = 100.vh - 12.pt
|
||||||
}
|
}
|
||||||
//settings
|
child(ThreeCanvasWithControls) {
|
||||||
card("Canvas configuration") {
|
attrs {
|
||||||
canvasControls(mmOptions, root)
|
this.context = props.context
|
||||||
}
|
this.builderOfSolid = CompletableDeferred(root)
|
||||||
|
this.selected = props.selected
|
||||||
card("Events") {
|
this.options = mmOptions
|
||||||
|
tab("Events") {
|
||||||
|
flexColumn {
|
||||||
|
flexRow {
|
||||||
button {
|
button {
|
||||||
+"Next"
|
+"Next"
|
||||||
attrs {
|
attrs {
|
||||||
onClickFunction = {
|
onClickFunction = {
|
||||||
GlobalScope.launch {
|
context.launch {
|
||||||
val event = props.connection.get<Event>("http://localhost:8080/event")
|
val event = props.connection.get<Event>(
|
||||||
|
"http://localhost:8080/event"
|
||||||
|
)
|
||||||
|
events = events + event
|
||||||
props.model.displayEvent(event)
|
props.model.displayEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,66 +85,24 @@ val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
|||||||
+"Clear"
|
+"Clear"
|
||||||
attrs {
|
attrs {
|
||||||
onClickFunction = {
|
onClickFunction = {
|
||||||
|
events = emptySet()
|
||||||
props.model.reset()
|
props.model.reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
styledDiv {
|
events.forEach { event ->
|
||||||
|
p {
|
||||||
|
styledSpan {
|
||||||
|
+event.id.toString()
|
||||||
|
}
|
||||||
|
+" : "
|
||||||
|
styledSpan {
|
||||||
css{
|
css{
|
||||||
padding(0.px)
|
color = Color.blue
|
||||||
}
|
}
|
||||||
nav {
|
+event.hits.toString()
|
||||||
attrs {
|
|
||||||
attributes["aria-label"] = "breadcrumb"
|
|
||||||
}
|
|
||||||
ol("breadcrumb") {
|
|
||||||
li("breadcrumb-item") {
|
|
||||||
button(classes = "btn btn-link p-0") {
|
|
||||||
+"World"
|
|
||||||
attrs {
|
|
||||||
onClickFunction = {
|
|
||||||
selected = Name.EMPTY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selected != null) {
|
|
||||||
val tokens = ArrayList<NameToken>(selected?.length ?: 1)
|
|
||||||
selected?.tokens?.forEach { token ->
|
|
||||||
tokens.add(token)
|
|
||||||
val fullName = Name(tokens.toList())
|
|
||||||
li("breadcrumb-item") {
|
|
||||||
button(classes = "btn btn-link p-0") {
|
|
||||||
+token.toString()
|
|
||||||
attrs {
|
|
||||||
onClickFunction = {
|
|
||||||
console.log("Selected = $fullName")
|
|
||||||
selected = fullName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
styledDiv {
|
|
||||||
css {
|
|
||||||
overflowY = Overflow.auto
|
|
||||||
}
|
|
||||||
//properties
|
|
||||||
card("Properties") {
|
|
||||||
selected.let { selected ->
|
|
||||||
val selectedObject: Vision? = when {
|
|
||||||
selected == null -> null
|
|
||||||
selected.isEmpty() -> root
|
|
||||||
else -> root[selected]
|
|
||||||
}
|
|
||||||
if (selectedObject != null) {
|
|
||||||
visionPropertyEditor(selectedObject, key = selected)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,3 +111,151 @@ val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// var selected by useState { props.selected }
|
||||||
|
//
|
||||||
|
// val onSelect: (Name?) -> Unit = {
|
||||||
|
// selected = it
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// gridRow {
|
||||||
|
// flexColumn {
|
||||||
|
// css {
|
||||||
|
// +"col-lg-3"
|
||||||
|
// +"order-lg-1"
|
||||||
|
// +"order-2"
|
||||||
|
// padding(0.px)
|
||||||
|
// overflowY = Overflow.auto
|
||||||
|
// height = 100.vh
|
||||||
|
// }
|
||||||
|
// //tree
|
||||||
|
// card("Object tree") {
|
||||||
|
// css {
|
||||||
|
// flex(1.0, 1.0, FlexBasis.auto)
|
||||||
|
// }
|
||||||
|
// visionTree(root, selected, onSelect)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// flexColumn {
|
||||||
|
// css {
|
||||||
|
// +"col-lg-6"
|
||||||
|
// +"order-lg-2"
|
||||||
|
// +"order-1"
|
||||||
|
// height = 100.vh
|
||||||
|
// }
|
||||||
|
// h1("mx-auto page-header") {
|
||||||
|
// +"Muon monitor demo"
|
||||||
|
// }
|
||||||
|
// //canvas
|
||||||
|
//
|
||||||
|
// child(ThreeCanvasComponent) {
|
||||||
|
// attrs {
|
||||||
|
// this.context = props.context
|
||||||
|
// this.solid = root
|
||||||
|
// this.selected = selected
|
||||||
|
// this.options = mmOptions
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// flexColumn {
|
||||||
|
// css {
|
||||||
|
// +"col-lg-3"
|
||||||
|
// +"order-3"
|
||||||
|
// padding(0.px)
|
||||||
|
// height = 100.vh
|
||||||
|
// }
|
||||||
|
// styledDiv {
|
||||||
|
// css {
|
||||||
|
// flex(0.0, 1.0, FlexBasis.zero)
|
||||||
|
// }
|
||||||
|
// //settings
|
||||||
|
// card("Canvas configuration") {
|
||||||
|
// canvasControls(mmOptions, root)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// card("Events") {
|
||||||
|
// button {
|
||||||
|
// +"Next"
|
||||||
|
// attrs {
|
||||||
|
// onClickFunction = {
|
||||||
|
// GlobalScope.launch {
|
||||||
|
// val event = props.connection.get<Event>("http://localhost:8080/event")
|
||||||
|
// props.model.displayEvent(event)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// button {
|
||||||
|
// +"Clear"
|
||||||
|
// attrs {
|
||||||
|
// onClickFunction = {
|
||||||
|
// props.model.reset()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// styledDiv {
|
||||||
|
// css {
|
||||||
|
// padding(0.px)
|
||||||
|
// }
|
||||||
|
// nav {
|
||||||
|
// attrs {
|
||||||
|
// attributes["aria-label"] = "breadcrumb"
|
||||||
|
// }
|
||||||
|
// ol("breadcrumb") {
|
||||||
|
// li("breadcrumb-item") {
|
||||||
|
// button(classes = "btn btn-link p-0") {
|
||||||
|
// +"World"
|
||||||
|
// attrs {
|
||||||
|
// onClickFunction = {
|
||||||
|
// selected = Name.EMPTY
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (selected != null) {
|
||||||
|
// val tokens = ArrayList<NameToken>(selected?.length ?: 1)
|
||||||
|
// selected?.tokens?.forEach { token ->
|
||||||
|
// tokens.add(token)
|
||||||
|
// val fullName = Name(tokens.toList())
|
||||||
|
// li("breadcrumb-item") {
|
||||||
|
// button(classes = "btn btn-link p-0") {
|
||||||
|
// +token.toString()
|
||||||
|
// attrs {
|
||||||
|
// onClickFunction = {
|
||||||
|
// console.log("Selected = $fullName")
|
||||||
|
// selected = fullName
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// styledDiv {
|
||||||
|
// css {
|
||||||
|
// overflowY = Overflow.auto
|
||||||
|
// }
|
||||||
|
// //properties
|
||||||
|
// card("Properties") {
|
||||||
|
// selected.let { selected ->
|
||||||
|
// val selectedObject: Vision? = when {
|
||||||
|
// selected == null -> null
|
||||||
|
// selected.isEmpty() -> root
|
||||||
|
// else -> root[selected]
|
||||||
|
// }
|
||||||
|
// if (selectedObject != null) {
|
||||||
|
// visionPropertyEditor(selectedObject, key = selected)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
}
|
@ -10,7 +10,6 @@ import space.kscience.dataforge.context.Context
|
|||||||
import space.kscience.dataforge.context.fetch
|
import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
import space.kscience.visionforge.VisionManager
|
import space.kscience.visionforge.VisionManager
|
||||||
import space.kscience.visionforge.bootstrap.useBootstrap
|
|
||||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.startApplication
|
import space.kscience.visionforge.startApplication
|
||||||
|
|
||||||
@ -23,7 +22,6 @@ private class MMDemoApp : Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(state: Map<String, Any>) {
|
||||||
useBootstrap()
|
|
||||||
|
|
||||||
val context = Context("MM-demo"){
|
val context = Context("MM-demo"){
|
||||||
plugin(ThreePlugin)
|
plugin(ThreePlugin)
|
||||||
|
3
demo/muon-monitor/webpack.config.d/01.ring.js
vendored
Normal file
3
demo/muon-monitor/webpack.config.d/01.ring.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
|
||||||
|
|
||||||
|
config.module.rules.push(...ringConfig.module.rules)
|
@ -70,7 +70,7 @@ public val BooleanValueChooser: FunctionComponent<ValueChooserProps> =
|
|||||||
}
|
}
|
||||||
attrs {
|
attrs {
|
||||||
//this.attributes["indeterminate"] = (props.item == null).toString()
|
//this.attributes["indeterminate"] = (props.item == null).toString()
|
||||||
defaultChecked = props.actual.boolean ?: false
|
checked = props.actual.boolean ?: false
|
||||||
onChangeFunction = handleChange
|
onChangeFunction = handleChange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ public external interface ThreeCanvasWithControlsProps : RProps {
|
|||||||
public var context: Context
|
public var context: Context
|
||||||
public var builderOfSolid: Deferred<Solid?>
|
public var builderOfSolid: Deferred<Solid?>
|
||||||
public var selected: Name?
|
public var selected: Name?
|
||||||
|
public var options: Canvas3DOptions?
|
||||||
public var additionalTabs: Map<String, RBuilder.() -> Unit>?
|
public var additionalTabs: Map<String, RBuilder.() -> Unit>?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,8 +93,8 @@ public val ThreeCanvasWithControls: FunctionComponent<ThreeCanvasWithControlsPro
|
|||||||
selected = it
|
selected = it
|
||||||
}
|
}
|
||||||
|
|
||||||
val options = useMemo(props.context) {
|
val options = useMemo(props.options) {
|
||||||
Canvas3DOptions.invoke {
|
(props.options?: Canvas3DOptions()).apply {
|
||||||
this.onSelect = onSelect
|
this.onSelect = onSelect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,6 +173,8 @@ public val ThreeCanvasWithControls: FunctionComponent<ThreeCanvasWithControlsPro
|
|||||||
css {
|
css {
|
||||||
padding(4.px)
|
padding(4.px)
|
||||||
minWidth = 400.px
|
minWidth = 400.px
|
||||||
|
height = 100.pct
|
||||||
|
overflowY = Overflow.auto
|
||||||
flex(1.0, 10.0, FlexBasis("300px"))
|
flex(1.0, 10.0, FlexBasis("300px"))
|
||||||
}
|
}
|
||||||
ringThreeControls(options, solid, selected, onSelect, additionalTabs = props.additionalTabs)
|
ringThreeControls(options, solid, selected, onSelect, additionalTabs = props.additionalTabs)
|
||||||
|
Loading…
Reference in New Issue
Block a user