Moving to compose
This commit is contained in:
parent
0c9d849e97
commit
4f6f4b9268
@ -5,6 +5,7 @@
|
|||||||
- Context receivers flag
|
- Context receivers flag
|
||||||
- MeshLine for thick lines
|
- MeshLine for thick lines
|
||||||
- Custom client-side events and thier processing in VisionServer
|
- Custom client-side events and thier processing in VisionServer
|
||||||
|
- Control/input visions
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Color accessor property is now `colorProperty`. Color uses non-nullable `invoke` instead of `set`.
|
- Color accessor property is now `colorProperty`. Color uses non-nullable `invoke` instead of `set`.
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile
|
|
||||||
import space.kscience.gradle.useApache2Licence
|
import space.kscience.gradle.useApache2Licence
|
||||||
import space.kscience.gradle.useSPCTeam
|
import space.kscience.gradle.useSPCTeam
|
||||||
|
|
||||||
@ -11,7 +10,7 @@ val dataforgeVersion by extra("0.7.1")
|
|||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
group = "space.kscience"
|
group = "space.kscience"
|
||||||
version = "0.3.0-RC"
|
version = "0.4.0-dev-1"
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
@ -31,11 +30,11 @@ subprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinJsCompile>{
|
// tasks.withType<KotlinJsCompile>{
|
||||||
kotlinOptions{
|
// kotlinOptions{
|
||||||
useEsClasses = true
|
// useEsClasses = true
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
ksciencePublish {
|
ksciencePublish {
|
||||||
|
@ -7,14 +7,8 @@ group = "demo"
|
|||||||
kscience {
|
kscience {
|
||||||
jvm()
|
jvm()
|
||||||
js {
|
js {
|
||||||
useCommonJs()
|
|
||||||
browser {
|
browser {
|
||||||
binaries.executable()
|
binaries.executable()
|
||||||
commonWebpackConfig {
|
|
||||||
cssSupport {
|
|
||||||
enabled.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -26,7 +20,6 @@ kscience {
|
|||||||
implementation(spclibs.logback.classic)
|
implementation(spclibs.logback.classic)
|
||||||
}
|
}
|
||||||
jsMain {
|
jsMain {
|
||||||
implementation(projects.ui.ring)
|
|
||||||
implementation(projects.visionforgeThreejs)
|
implementation(projects.visionforgeThreejs)
|
||||||
implementation(npm("react-file-drop", "3.0.6"))
|
implementation(npm("react-file-drop", "3.0.6"))
|
||||||
}
|
}
|
||||||
|
@ -1,46 +1,33 @@
|
|||||||
package space.kscience.visionforge.gdml.demo
|
package space.kscience.visionforge.gdml.demo
|
||||||
|
|
||||||
|
import androidx.compose.runtime.*
|
||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
import org.jetbrains.compose.web.css.*
|
||||||
import kotlinx.coroutines.Deferred
|
import org.jetbrains.compose.web.dom.Div
|
||||||
import kotlinx.css.*
|
import org.jetbrains.compose.web.dom.H2
|
||||||
|
import org.jetbrains.compose.web.dom.Text
|
||||||
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
|
||||||
import react.Props
|
|
||||||
import react.dom.h2
|
|
||||||
import react.fc
|
|
||||||
import react.useState
|
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.gdml.Gdml
|
import space.kscience.gdml.Gdml
|
||||||
import space.kscience.gdml.decodeFromString
|
import space.kscience.gdml.decodeFromString
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.gdml.markLayers
|
import space.kscience.visionforge.gdml.markLayers
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
|
||||||
import space.kscience.visionforge.ring.tab
|
|
||||||
import space.kscience.visionforge.setAsRoot
|
import space.kscience.visionforge.setAsRoot
|
||||||
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 space.kscience.visionforge.solid.ambientLight
|
import space.kscience.visionforge.solid.ambientLight
|
||||||
import space.kscience.visionforge.solid.invoke
|
import space.kscience.visionforge.solid.invoke
|
||||||
import styled.css
|
import space.kscience.visionforge.solid.three.compose.ThreeView
|
||||||
import styled.styledDiv
|
|
||||||
|
|
||||||
external interface GDMLAppProps : Props {
|
|
||||||
var solids: Solids
|
|
||||||
var vision: Solid?
|
|
||||||
var selected: Name?
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsExport
|
@Composable
|
||||||
val GDMLApp = fc<GDMLAppProps>("GDMLApp") { props ->
|
fun GDMLApp(solids: Solids, initialVision: Solid?, selected: Name? = null) {
|
||||||
var deferredVision: Deferred<Solid?> by useState {
|
var vision: Solid? by remember { mutableStateOf(initialVision) }
|
||||||
CompletableDeferred(props.vision)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun readFileAsync(file: File): Deferred<Solid?> {
|
fun readFileAsync(file: File) {
|
||||||
val deferred = CompletableDeferred<Solid?>()
|
|
||||||
FileReader().apply {
|
FileReader().apply {
|
||||||
onload = {
|
onload = {
|
||||||
val data = result as String
|
val data = result as String
|
||||||
@ -49,7 +36,7 @@ val GDMLApp = fc<GDMLAppProps>("GDMLApp") { props ->
|
|||||||
name.endsWith(".gdml") || name.endsWith(".xml") -> {
|
name.endsWith(".gdml") || name.endsWith(".xml") -> {
|
||||||
val gdml = Gdml.decodeFromString(data)
|
val gdml = Gdml.decodeFromString(data)
|
||||||
gdml.toVision().apply {
|
gdml.toVision().apply {
|
||||||
setAsRoot(props.solids.visionManager)
|
setAsRoot(solids.visionManager)
|
||||||
console.info("Marking layers for file $name")
|
console.info("Marking layers for file $name")
|
||||||
markLayers()
|
markLayers()
|
||||||
ambientLight {
|
ambientLight {
|
||||||
@ -57,44 +44,39 @@ val GDMLApp = fc<GDMLAppProps>("GDMLApp") { props ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name.endsWith(".json") -> props.solids.visionManager.decodeFromString(data)
|
|
||||||
|
name.endsWith(".json") -> solids.visionManager.decodeFromString(data)
|
||||||
else -> {
|
else -> {
|
||||||
window.alert("File extension is not recognized: $name")
|
window.alert("File extension is not recognized: $name")
|
||||||
error("File extension is not recognized: $name")
|
error("File extension is not recognized: $name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deferred.complete(parsedVision as? Solid ?: error("Parsed vision is not a solid"))
|
vision = parsedVision as? Solid ?: error("Parsed vision is not a solid")
|
||||||
|
Unit
|
||||||
}
|
}
|
||||||
readAsText(file)
|
readAsText(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
return deferred
|
|
||||||
}
|
}
|
||||||
|
|
||||||
styledDiv {
|
Div({
|
||||||
css {
|
style {
|
||||||
height = 100.vh - 12.pt
|
height(100.vh - 12.pt)
|
||||||
width = 100.vw
|
width(100.vw)
|
||||||
}
|
}
|
||||||
child(ThreeCanvasWithControls) {
|
}) {
|
||||||
attrs {
|
ThreeView(solids, vision, selected) {
|
||||||
this.solids = props.solids
|
Tab("Load") {
|
||||||
this.builderOfSolid = deferredVision
|
H2 {
|
||||||
this.selected = props.selected
|
Text("Drag and drop .gdml or .json VisionForge files here")
|
||||||
tab("Load") {
|
|
||||||
h2 {
|
|
||||||
+"Drag and drop .gdml or .json VisionForge files here"
|
|
||||||
}
|
}
|
||||||
fileDrop("(drag file here)") { files ->
|
fileDrop("(drag file here)") { files ->
|
||||||
val file = files?.get(0)
|
val file = files?.get(0)
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
deferredVision = readFileAsync(file)
|
readFileAsync(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,63 +1,58 @@
|
|||||||
package space.kscience.visionforge.gdml.demo
|
package space.kscience.visionforge.gdml.demo
|
||||||
|
|
||||||
import kotlinx.css.*
|
import org.jetbrains.compose.web.css.*
|
||||||
|
import org.jetbrains.compose.web.dom.Style
|
||||||
|
import org.jetbrains.compose.web.renderComposable
|
||||||
import org.w3c.dom.Document
|
import org.w3c.dom.Document
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.request
|
import space.kscience.dataforge.context.request
|
||||||
import space.kscience.gdml.GdmlShowCase
|
import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
|
import space.kscience.visionforge.compose.TreeStyles
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.react.createRoot
|
|
||||||
import space.kscience.visionforge.react.render
|
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
import space.kscience.visionforge.solid.ambientLight
|
import space.kscience.visionforge.solid.ambientLight
|
||||||
import space.kscience.visionforge.solid.invoke
|
import space.kscience.visionforge.solid.invoke
|
||||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.startApplication
|
import space.kscience.visionforge.startApplication
|
||||||
import styled.injectGlobal
|
|
||||||
|
|
||||||
|
|
||||||
private class GDMLDemoApp : Application {
|
private class GDMLDemoApp : Application {
|
||||||
|
|
||||||
override fun start(document: Document, state: Map<String, Any>) {
|
override fun start(document: Document, state: Map<String, Any>) {
|
||||||
val context = Context("gdml-demo"){
|
val context = Context("gdml-demo") {
|
||||||
plugin(ThreePlugin)
|
plugin(ThreePlugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
injectGlobal {
|
|
||||||
html{
|
|
||||||
height = 100.pct
|
|
||||||
}
|
|
||||||
|
|
||||||
body{
|
|
||||||
height = 100.pct
|
|
||||||
display = Display.flex
|
|
||||||
alignItems = Align.stretch
|
|
||||||
}
|
|
||||||
|
|
||||||
"#application"{
|
|
||||||
width = 100.pct
|
|
||||||
display = Display.flex
|
|
||||||
alignItems = Align.stretch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val element = document.getElementById("application") ?: error("Element with id 'application' not found on page")
|
val element = document.getElementById("application") ?: error("Element with id 'application' not found on page")
|
||||||
|
|
||||||
createRoot(element).render {
|
|
||||||
child(GDMLApp) {
|
|
||||||
val vision = GdmlShowCase.cubes().toVision().apply {
|
val vision = GdmlShowCase.cubes().toVision().apply {
|
||||||
ambientLight {
|
ambientLight {
|
||||||
color(Colors.white)
|
color(Colors.white)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//println(context.plugins.fetch(VisionManager).encodeToString(vision))
|
|
||||||
attrs {
|
renderComposable(element) {
|
||||||
this.solids = context.request(Solids)
|
Style(TreeStyles)
|
||||||
this.vision = vision
|
Style {
|
||||||
|
"html" {
|
||||||
|
height(100.percent)
|
||||||
|
}
|
||||||
|
|
||||||
|
"body" {
|
||||||
|
height(100.percent)
|
||||||
|
display(DisplayStyle.Flex)
|
||||||
|
alignItems(AlignItems.Stretch)
|
||||||
|
}
|
||||||
|
|
||||||
|
"#application" {
|
||||||
|
width(100.percent)
|
||||||
|
display(DisplayStyle.Flex)
|
||||||
|
alignItems(AlignItems.Stretch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GDMLApp(context.request(Solids), vision)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,8 @@ kscience {
|
|||||||
kotlin {
|
kotlin {
|
||||||
explicitApi = null
|
explicitApi = null
|
||||||
js {
|
js {
|
||||||
useCommonJs()
|
|
||||||
browser {
|
browser {
|
||||||
binaries.executable()
|
binaries.executable()
|
||||||
commonWebpackConfig {
|
|
||||||
cssSupport {
|
|
||||||
enabled.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,7 +23,4 @@ kscience {
|
|||||||
implementation(projects.visionforge.visionforgeMarkdown)
|
implementation(projects.visionforge.visionforgeMarkdown)
|
||||||
implementation(projects.visionforge.visionforgeThreejs)
|
implementation(projects.visionforge.visionforgeThreejs)
|
||||||
}
|
}
|
||||||
jsMain {
|
|
||||||
implementation(projects.ui.ring)
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import kotlinx.css.*
|
import org.jetbrains.compose.web.css.*
|
||||||
|
import org.jetbrains.compose.web.dom.Div
|
||||||
|
import org.jetbrains.compose.web.renderComposable
|
||||||
import org.w3c.dom.Document
|
import org.w3c.dom.Document
|
||||||
import ringui.SmartTabs
|
|
||||||
import ringui.Tab
|
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.request
|
import space.kscience.dataforge.context.request
|
||||||
import space.kscience.plotly.models.Trace
|
import space.kscience.plotly.models.Trace
|
||||||
@ -9,16 +9,12 @@ import space.kscience.plotly.scatter
|
|||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.JsVisionClient
|
import space.kscience.visionforge.JsVisionClient
|
||||||
|
import space.kscience.visionforge.compose.Tabs
|
||||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||||
import space.kscience.visionforge.react.createRoot
|
|
||||||
import space.kscience.visionforge.react.render
|
|
||||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
|
||||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
|
||||||
import space.kscience.visionforge.ring.solid
|
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
|
import space.kscience.visionforge.solid.three.compose.ThreeView
|
||||||
import space.kscience.visionforge.startApplication
|
import space.kscience.visionforge.startApplication
|
||||||
import styled.css
|
|
||||||
import styled.styledDiv
|
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
fun Trace.appendXYLatest(x: Number, y: Number, history: Int = 400, xErr: Number? = null, yErr: Number? = null) {
|
fun Trace.appendXYLatest(x: Number, y: Number, history: Int = 400, xErr: Number? = null, yErr: Number? = null) {
|
||||||
@ -33,28 +29,28 @@ private class JsPlaygroundApp : Application {
|
|||||||
override fun start(document: Document, state: Map<String, Any>) {
|
override fun start(document: Document, state: Map<String, Any>) {
|
||||||
|
|
||||||
val playgroundContext = Context {
|
val playgroundContext = Context {
|
||||||
plugin(ThreeWithControlsPlugin)
|
plugin(ThreePlugin)
|
||||||
plugin(JsVisionClient)
|
|
||||||
plugin(PlotlyPlugin)
|
plugin(PlotlyPlugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val solids = playgroundContext.request(Solids)
|
||||||
|
val client = playgroundContext.request(JsVisionClient)
|
||||||
|
|
||||||
val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page")
|
val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page")
|
||||||
|
|
||||||
createRoot(element).render {
|
renderComposable(element) {
|
||||||
styledDiv {
|
Div({
|
||||||
css {
|
style {
|
||||||
padding = Padding(0.pt)
|
padding(0.pt)
|
||||||
margin = Margin(0.pt)
|
margin(0.pt)
|
||||||
height = 100.vh
|
height(100.vh)
|
||||||
width = 100.vw
|
width(100.vw)
|
||||||
}
|
}
|
||||||
SmartTabs("gravity") {
|
}) {
|
||||||
|
Tabs {
|
||||||
|
active = "gravity"
|
||||||
Tab("gravity") {
|
Tab("gravity") {
|
||||||
GravityDemo {
|
GravityDemo(solids, client)
|
||||||
attrs {
|
|
||||||
this.solids = playgroundContext.request(Solids)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tab("D0") {
|
// Tab("D0") {
|
||||||
@ -66,38 +62,31 @@ private class JsPlaygroundApp : Application {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
Tab("spheres") {
|
Tab("spheres") {
|
||||||
styledDiv {
|
Div({
|
||||||
css {
|
style {
|
||||||
height = 100.vh - 50.pt
|
height(100.vh - 50.pt)
|
||||||
}
|
}
|
||||||
child(ThreeCanvasWithControls) {
|
}) {
|
||||||
val random = Random(112233)
|
ThreeView(solids, SolidGroup {
|
||||||
attrs {
|
|
||||||
solids = playgroundContext.request(Solids)
|
|
||||||
solid {
|
|
||||||
ambientLight {
|
ambientLight {
|
||||||
color(Colors.white)
|
color(Colors.white)
|
||||||
}
|
}
|
||||||
repeat(100) {
|
repeat(100) {
|
||||||
sphere(5, name = "sphere[$it]") {
|
sphere(5, name = "sphere[$it]") {
|
||||||
x = random.nextDouble(-300.0, 300.0)
|
x = Random.nextDouble(-300.0, 300.0)
|
||||||
y = random.nextDouble(-300.0, 300.0)
|
y = Random.nextDouble(-300.0, 300.0)
|
||||||
z = random.nextDouble(-300.0, 300.0)
|
z = Random.nextDouble(-300.0, 300.0)
|
||||||
material {
|
material {
|
||||||
color(random.nextInt())
|
color(Random.nextInt())
|
||||||
}
|
}
|
||||||
detail = 16
|
detail = 16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tab("plotly") {
|
Tab("plotly") {
|
||||||
Plotly {
|
Plot(client) {
|
||||||
attrs {
|
|
||||||
plot = space.kscience.plotly.Plotly.plot {
|
|
||||||
scatter {
|
scatter {
|
||||||
x(1, 2, 3)
|
x(1, 2, 3)
|
||||||
y(5, 8, 7)
|
y(5, 8, 7)
|
||||||
@ -108,8 +97,7 @@ private class JsPlaygroundApp : Application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun main() {
|
public fun main() {
|
||||||
|
@ -1,47 +1,75 @@
|
|||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import org.jetbrains.compose.web.css.*
|
||||||
import kotlinx.css.*
|
import org.jetbrains.compose.web.dom.AttrBuilderContext
|
||||||
import react.Props
|
import org.jetbrains.compose.web.dom.Div
|
||||||
import react.fc
|
import org.w3c.dom.HTMLDivElement
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.plotly.Plot
|
||||||
import space.kscience.plotly.layout
|
import space.kscience.plotly.layout
|
||||||
import space.kscience.plotly.models.Trace
|
import space.kscience.plotly.models.Trace
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
|
import space.kscience.visionforge.VisionClient
|
||||||
|
import space.kscience.visionforge.compose.FlexRow
|
||||||
|
import space.kscience.visionforge.compose.Vision
|
||||||
|
import space.kscience.visionforge.compose.zIndex
|
||||||
import space.kscience.visionforge.markup.VisionOfMarkup
|
import space.kscience.visionforge.markup.VisionOfMarkup
|
||||||
import space.kscience.visionforge.react.flexRow
|
import space.kscience.visionforge.plotly.asVision
|
||||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
|
||||||
import space.kscience.visionforge.ring.solid
|
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import styled.css
|
import space.kscience.visionforge.solid.three.compose.ThreeView
|
||||||
import styled.styledDiv
|
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
external interface DemoProps : Props {
|
@Composable
|
||||||
var solids: Solids
|
fun Plot(
|
||||||
}
|
client: VisionClient,
|
||||||
|
meta: Meta = Meta.EMPTY,
|
||||||
|
attrs: AttrBuilderContext<HTMLDivElement>? = null,
|
||||||
|
block: Plot.() -> Unit,
|
||||||
|
) = Vision(
|
||||||
|
client = client,
|
||||||
|
attrs = attrs,
|
||||||
|
meta = meta,
|
||||||
|
vision = Plot().apply(block).asVision()
|
||||||
|
)
|
||||||
|
|
||||||
val GravityDemo = fc<DemoProps> { props ->
|
@Composable
|
||||||
val velocityTrace = Trace {
|
fun Markup(
|
||||||
|
client: VisionClient,
|
||||||
|
markup: VisionOfMarkup,
|
||||||
|
meta: Meta = Meta.EMPTY,
|
||||||
|
attrs: AttrBuilderContext<HTMLDivElement>? = null,
|
||||||
|
) = Vision(
|
||||||
|
client = client,
|
||||||
|
attrs = attrs,
|
||||||
|
meta = meta,
|
||||||
|
vision = markup
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val h = 100.0
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun GravityDemo(solids: Solids, client: VisionClient) {
|
||||||
|
val velocityTrace = remember {
|
||||||
|
Trace {
|
||||||
name = "velocity"
|
name = "velocity"
|
||||||
}
|
}
|
||||||
val energyTrace = Trace {
|
}
|
||||||
|
|
||||||
|
val energyTrace = remember {
|
||||||
|
Trace {
|
||||||
name = "energy"
|
name = "energy"
|
||||||
}
|
}
|
||||||
val markup = VisionOfMarkup()
|
}
|
||||||
|
|
||||||
styledDiv {
|
val markup = remember { VisionOfMarkup() }
|
||||||
css {
|
|
||||||
height = 100.vh - 50.pt
|
val solid = remember {
|
||||||
}
|
SolidGroup {
|
||||||
styledDiv {
|
pointLight(200, 200, 200, name = "light") {
|
||||||
css {
|
|
||||||
height = 50.vh
|
|
||||||
}
|
|
||||||
child(ThreeCanvasWithControls) {
|
|
||||||
attrs {
|
|
||||||
solids = props.solids
|
|
||||||
solid {
|
|
||||||
pointLight(200, 200, 200, name = "light"){
|
|
||||||
color(Colors.white)
|
color(Colors.white)
|
||||||
}
|
}
|
||||||
ambientLight()
|
ambientLight()
|
||||||
@ -49,9 +77,18 @@ val GravityDemo = fc<DemoProps> { props ->
|
|||||||
sphere(5.0, "ball") {
|
sphere(5.0, "ball") {
|
||||||
detail = 16
|
detail = 16
|
||||||
color("red")
|
color("red")
|
||||||
val h = 100.0
|
|
||||||
y = h
|
y = h
|
||||||
solids.context.launch {
|
|
||||||
|
|
||||||
|
box(200, 5, 200, name = "floor") {
|
||||||
|
y = -2.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(solid) {
|
||||||
|
val ball = solid["ball"]!!
|
||||||
val g = 10.0
|
val g = 10.0
|
||||||
val dt = 0.1
|
val dt = 0.1
|
||||||
var time = 0.0
|
var time = 0.0
|
||||||
@ -60,13 +97,13 @@ val GravityDemo = fc<DemoProps> { props ->
|
|||||||
delay(20)
|
delay(20)
|
||||||
time += dt
|
time += dt
|
||||||
velocity -= g * dt
|
velocity -= g * dt
|
||||||
val energy = g * y.toDouble() + velocity * velocity / 2
|
val energy = g * ball.y.toDouble() + velocity * velocity / 2
|
||||||
y = y.toDouble() + velocity * dt
|
ball.y = ball.y.toDouble() + velocity * dt
|
||||||
|
|
||||||
velocityTrace.appendXYLatest(time, y)
|
velocityTrace.appendXYLatest(time, ball.y)
|
||||||
energyTrace.appendXYLatest(time, energy)
|
energyTrace.appendXYLatest(time, energy)
|
||||||
|
|
||||||
if (y.toDouble() <= 2.5) {
|
if (ball.y.toDouble() <= 2.5) {
|
||||||
//conservation of energy
|
//conservation of energy
|
||||||
velocity = sqrt(2 * g * h)
|
velocity = sqrt(2 * g * h)
|
||||||
}
|
}
|
||||||
@ -80,32 +117,43 @@ val GravityDemo = fc<DemoProps> { props ->
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
box(200, 5, 200, name = "floor") {
|
Div({
|
||||||
y = -2.5
|
style {
|
||||||
|
height(100.vh - 50.pt)
|
||||||
}
|
}
|
||||||
|
}) {
|
||||||
|
Div({
|
||||||
|
style {
|
||||||
|
height(50.vh)
|
||||||
}
|
}
|
||||||
|
}) {
|
||||||
|
ThreeView(solids, solid)
|
||||||
}
|
}
|
||||||
|
FlexRow({
|
||||||
|
style {
|
||||||
|
alignContent(AlignContent.Stretch)
|
||||||
|
alignItems(AlignItems.Stretch)
|
||||||
|
height(50.vh - 50.pt)
|
||||||
}
|
}
|
||||||
}
|
}) {
|
||||||
flexRow {
|
Plot(client) {
|
||||||
css {
|
|
||||||
alignContent = Align.stretch
|
|
||||||
alignItems = Align.stretch
|
|
||||||
height = 50.vh - 50.pt
|
|
||||||
}
|
|
||||||
plotly {
|
|
||||||
traces(velocityTrace, energyTrace)
|
traces(velocityTrace, energyTrace)
|
||||||
layout {
|
layout {
|
||||||
xaxis.title = "time"
|
xaxis.title = "time"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Markup {
|
Markup(client, markup, attrs = {
|
||||||
attrs {
|
style {
|
||||||
this.markup = markup
|
width(100.percent)
|
||||||
}
|
height(100.percent)
|
||||||
|
border(2.pt, LineStyle.Solid, Color.blue)
|
||||||
|
paddingLeft(8.pt)
|
||||||
|
backgroundColor(Color.white)
|
||||||
|
flex(1)
|
||||||
|
zIndex(10000)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,55 +0,0 @@
|
|||||||
import kotlinx.css.*
|
|
||||||
import kotlinx.dom.clear
|
|
||||||
import kotlinx.html.dom.append
|
|
||||||
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
|
|
||||||
import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor
|
|
||||||
import org.w3c.dom.Element
|
|
||||||
import org.w3c.dom.HTMLElement
|
|
||||||
import react.Props
|
|
||||||
import react.fc
|
|
||||||
import react.useEffect
|
|
||||||
import react.useRef
|
|
||||||
import space.kscience.visionforge.markup.VisionOfMarkup
|
|
||||||
import space.kscience.visionforge.markup.markdown
|
|
||||||
import space.kscience.visionforge.useProperty
|
|
||||||
import styled.css
|
|
||||||
import styled.styledDiv
|
|
||||||
|
|
||||||
external interface MarkupProps : Props {
|
|
||||||
var markup: VisionOfMarkup?
|
|
||||||
}
|
|
||||||
|
|
||||||
val Markup = fc<MarkupProps>("Markup") { props ->
|
|
||||||
val elementRef = useRef<Element>(null)
|
|
||||||
|
|
||||||
useEffect(props.markup, elementRef) {
|
|
||||||
val element = elementRef.current as? HTMLElement ?: error("Markup element not found")
|
|
||||||
props.markup?.let { vision ->
|
|
||||||
val flavour = when (vision.format) {
|
|
||||||
VisionOfMarkup.COMMONMARK_FORMAT -> CommonMarkFlavourDescriptor()
|
|
||||||
VisionOfMarkup.GFM_FORMAT -> GFMFlavourDescriptor()
|
|
||||||
//TODO add new formats via plugins
|
|
||||||
else -> error("Format ${vision.format} not recognized")
|
|
||||||
}
|
|
||||||
vision.useProperty(VisionOfMarkup::content) { content: String? ->
|
|
||||||
element.clear()
|
|
||||||
element.append {
|
|
||||||
markdown(flavour) { content ?: "" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
styledDiv {
|
|
||||||
css {
|
|
||||||
width = 100.pct
|
|
||||||
height = 100.pct
|
|
||||||
border= Border(2.pt, BorderStyle.solid, Color.blue)
|
|
||||||
padding = Padding(left = 8.pt)
|
|
||||||
backgroundColor = Color.white
|
|
||||||
flex = Flex(1.0)
|
|
||||||
zIndex = 10000
|
|
||||||
}
|
|
||||||
ref = elementRef
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
import kotlinx.css.*
|
|
||||||
import org.w3c.dom.Element
|
|
||||||
import org.w3c.dom.HTMLElement
|
|
||||||
import react.*
|
|
||||||
import space.kscience.plotly.Plot
|
|
||||||
import space.kscience.plotly.PlotlyConfig
|
|
||||||
import space.kscience.plotly.plot
|
|
||||||
import styled.css
|
|
||||||
import styled.styledDiv
|
|
||||||
|
|
||||||
external interface PlotlyProps : Props {
|
|
||||||
var plot: Plot?
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val Plotly = fc<PlotlyProps>("Plotly") { props ->
|
|
||||||
val elementRef = useRef<Element>(null)
|
|
||||||
|
|
||||||
useEffect(props.plot, elementRef) {
|
|
||||||
val element = elementRef.current as? HTMLElement ?: error("Plotly element not found")
|
|
||||||
props.plot?.let {
|
|
||||||
element.plot(PlotlyConfig {
|
|
||||||
responsive = true
|
|
||||||
}, it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
styledDiv {
|
|
||||||
css {
|
|
||||||
width = 100.pct
|
|
||||||
height = 100.pct
|
|
||||||
border = Border(2.pt, BorderStyle.solid, Color.blue)
|
|
||||||
flex = Flex(1.0)
|
|
||||||
}
|
|
||||||
ref = elementRef
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun RBuilder.plotly(plotbuilder: Plot.() -> Unit) = Plotly {
|
|
||||||
attrs {
|
|
||||||
this.plot = Plot().apply(plotbuilder)
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,13 +15,7 @@ kscience {
|
|||||||
"muon-monitor.js",
|
"muon-monitor.js",
|
||||||
jvmConfig = { withJava() },
|
jvmConfig = { withJava() },
|
||||||
jsConfig = { useCommonJs() }
|
jsConfig = { useCommonJs() }
|
||||||
) {
|
)
|
||||||
commonWebpackConfig {
|
|
||||||
cssSupport {
|
|
||||||
enabled.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
commonMain {
|
commonMain {
|
||||||
implementation(projects.visionforgeSolid)
|
implementation(projects.visionforgeSolid)
|
||||||
@ -34,7 +28,6 @@ kscience {
|
|||||||
implementation("ch.qos.logback:logback-classic:1.2.11")
|
implementation("ch.qos.logback:logback-classic:1.2.11")
|
||||||
}
|
}
|
||||||
jsMain {
|
jsMain {
|
||||||
implementation(projects.ui.ring)
|
|
||||||
implementation(projects.visionforgeThreejs)
|
implementation(projects.visionforgeThreejs)
|
||||||
//implementation(devNpm("webpack-bundle-analyzer", "4.4.0"))
|
//implementation(devNpm("webpack-bundle-analyzer", "4.4.0"))
|
||||||
}
|
}
|
||||||
|
@ -1,87 +1,67 @@
|
|||||||
package ru.mipt.npm.muon.monitor
|
package ru.mipt.npm.muon.monitor
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import app.softwork.bootstrapcompose.Button
|
||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
|
||||||
import kotlinx.coroutines.await
|
import kotlinx.coroutines.await
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.css.*
|
|
||||||
import kotlinx.html.js.onClickFunction
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import org.jetbrains.compose.web.css.*
|
||||||
|
import org.jetbrains.compose.web.dom.Div
|
||||||
|
import org.jetbrains.compose.web.dom.P
|
||||||
|
import org.jetbrains.compose.web.dom.Span
|
||||||
|
import org.jetbrains.compose.web.dom.Text
|
||||||
import org.w3c.fetch.RequestInit
|
import org.w3c.fetch.RequestInit
|
||||||
import react.Props
|
|
||||||
import react.dom.attrs
|
|
||||||
import react.dom.button
|
|
||||||
import react.dom.p
|
|
||||||
import react.fc
|
|
||||||
import react.useMemo
|
|
||||||
import react.useState
|
|
||||||
import space.kscience.dataforge.meta.invoke
|
import space.kscience.dataforge.meta.invoke
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.react.flexColumn
|
import space.kscience.visionforge.compose.FlexColumn
|
||||||
import space.kscience.visionforge.react.flexRow
|
import space.kscience.visionforge.compose.FlexRow
|
||||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
|
||||||
import space.kscience.visionforge.ring.tab
|
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
import space.kscience.visionforge.solid.ambientLight
|
import space.kscience.visionforge.solid.ambientLight
|
||||||
import space.kscience.visionforge.solid.edges
|
import space.kscience.visionforge.solid.edges
|
||||||
import space.kscience.visionforge.solid.invoke
|
import space.kscience.visionforge.solid.invoke
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
import styled.css
|
import space.kscience.visionforge.solid.three.compose.ThreeView
|
||||||
import styled.styledDiv
|
|
||||||
import styled.styledSpan
|
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
external interface MMAppProps : Props {
|
@Composable
|
||||||
var model: Model
|
fun MMApp(solids: Solids, model: Model, selected: Name? = null) {
|
||||||
var solids: Solids
|
|
||||||
var selected: Name?
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(DelicateCoroutinesApi::class)
|
val mmOptions = remember {
|
||||||
@JsExport
|
|
||||||
val MMApp = fc<MMAppProps>("Muon monitor") { props ->
|
|
||||||
|
|
||||||
val mmOptions = useMemo {
|
|
||||||
Canvas3DOptions {
|
Canvas3DOptions {
|
||||||
camera {
|
camera {
|
||||||
distance = 2100.0
|
distance = 2100.0
|
||||||
latitude = PI / 6
|
latitude = PI / 6
|
||||||
azimuth = PI + PI / 6
|
azimuth = PI + PI / 6
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val root = useMemo(props.model) {
|
val root = remember(model) {
|
||||||
props.model.root.apply {
|
model.root.apply {
|
||||||
edges()
|
edges()
|
||||||
ambientLight{
|
ambientLight {
|
||||||
color(Colors.white)
|
color(Colors.white)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var events: Set<Event> by useState(emptySet())
|
val events = remember { mutableStateListOf<Event>() }
|
||||||
|
|
||||||
styledDiv {
|
Div({
|
||||||
css {
|
style {
|
||||||
height = 100.vh - 12.pt
|
height(100.vh - 12.pt)
|
||||||
}
|
}
|
||||||
child(ThreeCanvasWithControls) {
|
}) {
|
||||||
attrs {
|
ThreeView(solids, root, selected, mmOptions) {
|
||||||
this.solids = props.solids
|
Tab("Events") {
|
||||||
this.builderOfSolid = CompletableDeferred(root)
|
|
||||||
this.selected = props.selected
|
FlexColumn {
|
||||||
this.options = mmOptions
|
FlexRow {
|
||||||
tab("Events") {
|
Button("Next") {
|
||||||
flexColumn {
|
|
||||||
flexRow {
|
|
||||||
button {
|
|
||||||
+"Next"
|
|
||||||
attrs {
|
|
||||||
onClickFunction = {
|
|
||||||
solids.context.launch {
|
solids.context.launch {
|
||||||
val event = window.fetch(
|
val event = window.fetch(
|
||||||
"http://localhost:8080/event",
|
"http://localhost:8080/event",
|
||||||
@ -95,187 +75,32 @@ val MMApp = fc<MMAppProps>("Muon monitor") { props ->
|
|||||||
}.then { body ->
|
}.then { body ->
|
||||||
Json.decodeFromString(Event.serializer(), body)
|
Json.decodeFromString(Event.serializer(), body)
|
||||||
}.await()
|
}.await()
|
||||||
events = events + event
|
events.add(event)
|
||||||
props.model.displayEvent(event)
|
model.displayEvent(event)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
+"Clear"
|
|
||||||
attrs {
|
|
||||||
onClickFunction = {
|
|
||||||
events = emptySet()
|
|
||||||
props.model.reset()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Button("Clear") {
|
||||||
|
events.clear()
|
||||||
|
model.reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
events.forEach { event ->
|
events.forEach { event ->
|
||||||
p {
|
P {
|
||||||
styledSpan {
|
Span {
|
||||||
+event.id.toString()
|
Text(event.id.toString())
|
||||||
}
|
}
|
||||||
+" : "
|
Text(" : ")
|
||||||
styledSpan {
|
Span({
|
||||||
css {
|
style {
|
||||||
color = Color.blue
|
color(Color.blue)
|
||||||
}
|
}
|
||||||
+event.hits.toString()
|
}) {
|
||||||
|
Text(event.hits.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
}
|
@ -1,12 +1,11 @@
|
|||||||
package ru.mipt.npm.muon.monitor
|
package ru.mipt.npm.muon.monitor
|
||||||
|
|
||||||
|
import org.jetbrains.compose.web.renderComposable
|
||||||
import org.w3c.dom.Document
|
import org.w3c.dom.Document
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.request
|
import space.kscience.dataforge.context.request
|
||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
import space.kscience.visionforge.VisionManager
|
import space.kscience.visionforge.VisionManager
|
||||||
import space.kscience.visionforge.react.createRoot
|
|
||||||
import space.kscience.visionforge.react.render
|
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.startApplication
|
import space.kscience.visionforge.startApplication
|
||||||
@ -24,13 +23,8 @@ private class MMDemoApp : Application {
|
|||||||
val model = Model(visionManager)
|
val model = Model(visionManager)
|
||||||
|
|
||||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||||
createRoot(element).render {
|
renderComposable(element) {
|
||||||
child(MMApp) {
|
MMApp(context.request(Solids), model)
|
||||||
attrs {
|
|
||||||
this.model = model
|
|
||||||
this.solids = context.request(Solids)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,17 +14,10 @@ repositories {
|
|||||||
kotlin {
|
kotlin {
|
||||||
|
|
||||||
js(IR) {
|
js(IR) {
|
||||||
useCommonJs()
|
|
||||||
browser {
|
browser {
|
||||||
webpackTask {
|
webpackTask {
|
||||||
mainOutputFileName.set("js/visionforge-playground.js")
|
mainOutputFileName.set("js/visionforge-playground.js")
|
||||||
}
|
}
|
||||||
commonWebpackConfig {
|
|
||||||
sourceMaps = true
|
|
||||||
cssSupport{
|
|
||||||
enabled.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
binaries.executable()
|
binaries.executable()
|
||||||
}
|
}
|
||||||
@ -57,7 +50,6 @@ kotlin {
|
|||||||
|
|
||||||
val jsMain by getting {
|
val jsMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(projects.ui.ring)
|
|
||||||
implementation(projects.visionforgeThreejs)
|
implementation(projects.visionforgeThreejs)
|
||||||
compileOnly(npm("webpack-bundle-analyzer","4.5.0"))
|
compileOnly(npm("webpack-bundle-analyzer","4.5.0"))
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,13 @@ import space.kscience.dataforge.misc.DFExperimental
|
|||||||
import space.kscience.visionforge.jupyter.VFNotebookClient
|
import space.kscience.visionforge.jupyter.VFNotebookClient
|
||||||
import space.kscience.visionforge.markup.MarkupPlugin
|
import space.kscience.visionforge.markup.MarkupPlugin
|
||||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
|
||||||
import space.kscience.visionforge.runVisionClient
|
import space.kscience.visionforge.runVisionClient
|
||||||
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.tables.TableVisionJsPlugin
|
import space.kscience.visionforge.tables.TableVisionJsPlugin
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun main() = runVisionClient {
|
fun main() = runVisionClient {
|
||||||
plugin(ThreeWithControlsPlugin)
|
plugin(ThreePlugin)
|
||||||
plugin(PlotlyPlugin)
|
plugin(PlotlyPlugin)
|
||||||
plugin(MarkupPlugin)
|
plugin(MarkupPlugin)
|
||||||
plugin(TableVisionJsPlugin)
|
plugin(TableVisionJsPlugin)
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
|
||||||
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
alias(spclibs.plugins.ktor)
|
alias(spclibs.plugins.ktor)
|
||||||
@ -19,6 +22,8 @@ kscience {
|
|||||||
|
|
||||||
group = "center.sciprog"
|
group = "center.sciprog"
|
||||||
|
|
||||||
|
kotlin.explicitApi = ExplicitApiMode.Disabled
|
||||||
|
|
||||||
application {
|
application {
|
||||||
mainClass.set("ru.mipt.npm.sat.SatServerKt")
|
mainClass.set("ru.mipt.npm.sat.SatServerKt")
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ class ThreeDemoGrid(element: Element) : VisionLayout<Solid> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val element = document.getElementById("output-$name") ?: error("Element not found")
|
val element = document.getElementById("output-$name") ?: error("Element not found")
|
||||||
three.getOrCreateCanvas(element, canvasOptions)
|
ThreeCanvas(three, element, canvasOptions)
|
||||||
}.render(vision)
|
}.render(vision)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ include(
|
|||||||
":ui:ring",
|
":ui:ring",
|
||||||
// ":ui:material",
|
// ":ui:material",
|
||||||
":ui:bootstrap",
|
":ui:bootstrap",
|
||||||
":ui:compose",
|
":visionforge-compose",
|
||||||
":visionforge-core",
|
":visionforge-core",
|
||||||
":visionforge-solid",
|
":visionforge-solid",
|
||||||
// ":visionforge-fx",
|
// ":visionforge-fx",
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
package space.kscience.visionforge.compose
|
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import kotlinx.dom.clear
|
|
||||||
import org.jetbrains.compose.web.css.*
|
|
||||||
import org.jetbrains.compose.web.dom.Div
|
|
||||||
import space.kscience.dataforge.context.Context
|
|
||||||
import space.kscience.dataforge.context.request
|
|
||||||
import space.kscience.dataforge.names.Name
|
|
||||||
import space.kscience.visionforge.solid.Solid
|
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
|
||||||
import space.kscience.visionforge.solid.three.ThreeCanvas
|
|
||||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
public fun ThreeCanvas(
|
|
||||||
context: Context,
|
|
||||||
options: Canvas3DOptions?,
|
|
||||||
solid: Solid?,
|
|
||||||
selected: Name?,
|
|
||||||
) {
|
|
||||||
|
|
||||||
val three: ThreePlugin by derivedStateOf { context.request(ThreePlugin) }
|
|
||||||
|
|
||||||
Div({
|
|
||||||
style {
|
|
||||||
maxWidth(100.vw)
|
|
||||||
maxHeight(100.vh)
|
|
||||||
width(100.percent)
|
|
||||||
height(100.percent)
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
var canvas: ThreeCanvas? = null
|
|
||||||
DisposableEffect(options) {
|
|
||||||
canvas = ThreeCanvas(three, scopeElement, options ?: Canvas3DOptions())
|
|
||||||
onDispose {
|
|
||||||
scopeElement.clear()
|
|
||||||
canvas = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LaunchedEffect(solid) {
|
|
||||||
if (solid != null) {
|
|
||||||
canvas?.render(solid)
|
|
||||||
} else {
|
|
||||||
canvas?.clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LaunchedEffect(selected) {
|
|
||||||
canvas?.select(selected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,169 +0,0 @@
|
|||||||
@file:OptIn(ExperimentalComposeWebApi::class)
|
|
||||||
|
|
||||||
package space.kscience.visionforge.compose
|
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import app.softwork.bootstrapcompose.Card
|
|
||||||
import kotlinx.coroutines.Deferred
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.jetbrains.compose.web.ExperimentalComposeWebApi
|
|
||||||
import org.jetbrains.compose.web.css.*
|
|
||||||
import org.jetbrains.compose.web.dom.*
|
|
||||||
import space.kscience.dataforge.meta.get
|
|
||||||
import space.kscience.dataforge.names.Name
|
|
||||||
import space.kscience.dataforge.names.isEmpty
|
|
||||||
import space.kscience.visionforge.*
|
|
||||||
import space.kscience.visionforge.solid.Solid
|
|
||||||
import space.kscience.visionforge.solid.SolidGroup
|
|
||||||
import space.kscience.visionforge.solid.Solids
|
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
public fun ThreeCanvasWithControls(
|
|
||||||
solids: Solids,
|
|
||||||
builderOfSolid: Deferred<Solid?>,
|
|
||||||
initialSelected: Name?,
|
|
||||||
options: Canvas3DOptions?,
|
|
||||||
tabBuilder: @Composable TabsBuilder.() -> Unit = {},
|
|
||||||
) {
|
|
||||||
var selected: Name? by remember { mutableStateOf(initialSelected) }
|
|
||||||
var solid: Solid? by remember { mutableStateOf(null) }
|
|
||||||
|
|
||||||
LaunchedEffect(builderOfSolid) {
|
|
||||||
solids.context.launch {
|
|
||||||
solid = builderOfSolid.await()
|
|
||||||
//ensure that the solid is properly rooted
|
|
||||||
if (solid?.parent == null) {
|
|
||||||
solid?.setAsRoot(solids.context.visionManager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val optionsWithSelector = remember(options) {
|
|
||||||
(options ?: Canvas3DOptions()).apply {
|
|
||||||
this.onSelect = {
|
|
||||||
selected = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val selectedVision: Vision? = remember(builderOfSolid, selected) {
|
|
||||||
selected?.let {
|
|
||||||
when {
|
|
||||||
it.isEmpty() -> solid
|
|
||||||
else -> (solid as? SolidGroup)?.get(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FlexRow({
|
|
||||||
style {
|
|
||||||
height(100.percent)
|
|
||||||
width(100.percent)
|
|
||||||
flexWrap(FlexWrap.Wrap)
|
|
||||||
alignItems(AlignItems.Stretch)
|
|
||||||
alignContent(AlignContent.Stretch)
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
FlexColumn({
|
|
||||||
style {
|
|
||||||
height(100.percent)
|
|
||||||
minWidth(600.px)
|
|
||||||
flex(10, 1, 600.px)
|
|
||||||
position(Position.Relative)
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
if (solid == null) {
|
|
||||||
Div({
|
|
||||||
style {
|
|
||||||
position(Position.Fixed)
|
|
||||||
width(100.percent)
|
|
||||||
height(100.percent)
|
|
||||||
zIndex(1000)
|
|
||||||
top(40.percent)
|
|
||||||
left(0.px)
|
|
||||||
opacity(0.5)
|
|
||||||
filter {
|
|
||||||
opacity(50.percent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
Div({ classes("d-flex", " justify-content-center") }) {
|
|
||||||
Div({
|
|
||||||
classes("spinner-grow", "text-primary")
|
|
||||||
style {
|
|
||||||
width(3.cssRem)
|
|
||||||
height(3.cssRem)
|
|
||||||
zIndex(20)
|
|
||||||
}
|
|
||||||
attr("role", "status")
|
|
||||||
}) {
|
|
||||||
Span({ classes("sr-only") }) { Text("Loading 3D vision") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ThreeCanvas(solids.context, optionsWithSelector, solid, selected)
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedVision?.let { vision ->
|
|
||||||
Div({
|
|
||||||
style {
|
|
||||||
position(Position.Absolute)
|
|
||||||
top(5.px)
|
|
||||||
right(5.px)
|
|
||||||
width(450.px)
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
Card(
|
|
||||||
headerAttrs = {
|
|
||||||
// border = true
|
|
||||||
},
|
|
||||||
header = {
|
|
||||||
NameCrumbs(selected) { selected = it }
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
PropertyEditor(
|
|
||||||
scope = solids.context,
|
|
||||||
meta = vision.properties.root(),
|
|
||||||
getPropertyState = { name ->
|
|
||||||
if (vision.properties.own?.get(name) != null) {
|
|
||||||
EditorPropertyState.Defined
|
|
||||||
} else if (vision.properties.root()[name] != null) {
|
|
||||||
// TODO differentiate
|
|
||||||
EditorPropertyState.Default()
|
|
||||||
} else {
|
|
||||||
EditorPropertyState.Undefined
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updates = vision.properties.changes,
|
|
||||||
rootDescriptor = vision.descriptor
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
vision.styles.takeIf { it.isNotEmpty() }?.let { styles ->
|
|
||||||
P {
|
|
||||||
B { Text("Styles: ") }
|
|
||||||
Text(styles.joinToString(separator = ", "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FlexColumn({
|
|
||||||
style {
|
|
||||||
paddingAll(4.px)
|
|
||||||
minWidth(400.px)
|
|
||||||
height(100.percent)
|
|
||||||
overflowY("auto")
|
|
||||||
flex(1, 10, 300.px)
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
ThreeControls(solid, optionsWithSelector, selected, onSelect = { selected = it }, tabBuilder = tabBuilder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -7,8 +7,6 @@ import space.kscience.dataforge.context.Context
|
|||||||
import space.kscience.dataforge.context.PluginFactory
|
import space.kscience.dataforge.context.PluginFactory
|
||||||
import space.kscience.dataforge.context.PluginTag
|
import space.kscience.dataforge.context.PluginTag
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.boolean
|
|
||||||
import space.kscience.dataforge.meta.get
|
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.visionforge.ElementVisionRenderer
|
import space.kscience.visionforge.ElementVisionRenderer
|
||||||
@ -28,9 +26,6 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING
|
if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING
|
||||||
|
|
||||||
override fun render(element: Element, client: VisionClient, name: Name, vision: Vision, meta: Meta) {
|
override fun render(element: Element, client: VisionClient, name: Name, vision: Vision, meta: Meta) {
|
||||||
if (meta["controls.enabled"].boolean == false) {
|
|
||||||
three.render(element, client, name, vision, meta)
|
|
||||||
} else {
|
|
||||||
space.kscience.visionforge.react.createRoot(element).render {
|
space.kscience.visionforge.react.createRoot(element).render {
|
||||||
child(ThreeCanvasWithControls) {
|
child(ThreeCanvasWithControls) {
|
||||||
attrs {
|
attrs {
|
||||||
@ -41,7 +36,6 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun content(target: String): Map<Name, Any> {
|
override fun content(target: String): Map<Name, Any> {
|
||||||
return when (target) {
|
return when (target) {
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
alias(spclibs.plugins.compose)
|
alias(spclibs.plugins.compose)
|
||||||
// id("org.jetbrains.compose") version "1.5.11"
|
|
||||||
// id("com.android.library")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kscience{
|
kscience{
|
||||||
@ -15,9 +13,9 @@ kscience{
|
|||||||
kotlin {
|
kotlin {
|
||||||
// android()
|
// android()
|
||||||
sourceSets {
|
sourceSets {
|
||||||
val commonMain by getting {
|
commonMain{
|
||||||
dependencies {
|
dependencies{
|
||||||
|
api(projects.visionforgeCore)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +33,6 @@ kotlin {
|
|||||||
api(compose.html.core)
|
api(compose.html.core)
|
||||||
api("app.softwork:bootstrap-compose:0.1.15")
|
api("app.softwork:bootstrap-compose:0.1.15")
|
||||||
api("app.softwork:bootstrap-compose-icons:0.1.15")
|
api("app.softwork:bootstrap-compose-icons:0.1.15")
|
||||||
api(projects.visionforge.visionforgeThreejs)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,7 +10,6 @@ import org.jetbrains.compose.web.dom.Text
|
|||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.dataforge.meta.descriptors.get
|
import space.kscience.dataforge.meta.descriptors.get
|
||||||
import space.kscience.dataforge.meta.get
|
|
||||||
import space.kscience.dataforge.meta.isLeaf
|
import space.kscience.dataforge.meta.isLeaf
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.NameToken
|
import space.kscience.dataforge.names.NameToken
|
@ -0,0 +1,49 @@
|
|||||||
|
package space.kscience.visionforge.compose
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import kotlinx.dom.clear
|
||||||
|
import org.jetbrains.compose.web.dom.AttrBuilderContext
|
||||||
|
import org.jetbrains.compose.web.dom.Div
|
||||||
|
import org.w3c.dom.HTMLDivElement
|
||||||
|
import space.kscience.dataforge.context.gather
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.asName
|
||||||
|
import space.kscience.visionforge.ElementVisionRenderer
|
||||||
|
import space.kscience.visionforge.Vision
|
||||||
|
import space.kscience.visionforge.VisionClient
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render an Element vision via injected vision renderer inside compose-html
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
public fun Vision(
|
||||||
|
client: VisionClient,
|
||||||
|
vision: Vision,
|
||||||
|
name: Name = "@vision[${vision.hashCode().toString(16)}]".asName(),
|
||||||
|
meta: Meta = Meta.EMPTY,
|
||||||
|
attrs: AttrBuilderContext<HTMLDivElement>? = null,
|
||||||
|
): Unit = Div(attrs) {
|
||||||
|
|
||||||
|
val renderer by derivedStateOf {
|
||||||
|
client.context.gather<ElementVisionRenderer>(ElementVisionRenderer.TYPE).values.mapNotNull {
|
||||||
|
val rating = it.rateVision(vision)
|
||||||
|
if (rating > 0) {
|
||||||
|
rating to it
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}.maxBy { it.first }.second
|
||||||
|
}
|
||||||
|
|
||||||
|
DisposableEffect(vision, name, renderer, meta) {
|
||||||
|
renderer.render(scopeElement, client, name, vision, meta)
|
||||||
|
onDispose {
|
||||||
|
scopeElement.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,6 @@ import space.kscience.dataforge.meta.descriptors.ValueRestriction
|
|||||||
import space.kscience.dataforge.meta.descriptors.allowedValues
|
import space.kscience.dataforge.meta.descriptors.allowedValues
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.widgetType
|
import space.kscience.visionforge.widgetType
|
||||||
import three.math.Color
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -151,7 +150,8 @@ public fun ColorValueChooser(
|
|||||||
value(
|
value(
|
||||||
value?.let { value ->
|
value?.let { value ->
|
||||||
if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int)
|
if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int)
|
||||||
else "#" + Color(value.string).getHexString()
|
else value.string
|
||||||
|
//else "#" + Color(value.string).getHexString()
|
||||||
} ?: "#000000"
|
} ?: "#000000"
|
||||||
)
|
)
|
||||||
onChange {
|
onChange {
|
@ -225,6 +225,8 @@ public abstract interface class space/kscience/visionforge/ControlVision : space
|
|||||||
public final class space/kscience/visionforge/ControlVisionKt {
|
public final class space/kscience/visionforge/ControlVisionKt {
|
||||||
public static final fun VisionClickEvent (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionClickEvent;
|
public static final fun VisionClickEvent (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionClickEvent;
|
||||||
public static synthetic fun VisionClickEvent$default (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionClickEvent;
|
public static synthetic fun VisionClickEvent$default (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionClickEvent;
|
||||||
|
public static final fun VisionInputEvent (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionInputEvent;
|
||||||
|
public static synthetic fun VisionInputEvent$default (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionInputEvent;
|
||||||
public static final fun VisionValueChangeEvent (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionValueChangeEvent;
|
public static final fun VisionValueChangeEvent (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionValueChangeEvent;
|
||||||
public static synthetic fun VisionValueChangeEvent$default (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionValueChangeEvent;
|
public static synthetic fun VisionValueChangeEvent$default (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionValueChangeEvent;
|
||||||
public static final fun onClick (Lspace/kscience/visionforge/ClickControl;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
public static final fun onClick (Lspace/kscience/visionforge/ClickControl;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
@ -495,6 +497,7 @@ public final class space/kscience/visionforge/VisionClientKt {
|
|||||||
public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Ljava/lang/String;)V
|
public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;)V
|
public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Z)V
|
public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Z)V
|
||||||
|
public static final fun sendEventAsync (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Lspace/kscience/visionforge/VisionEvent;)Lkotlinx/coroutines/Job;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract interface class space/kscience/visionforge/VisionContainer {
|
public abstract interface class space/kscience/visionforge/VisionContainer {
|
||||||
@ -560,6 +563,30 @@ public final class space/kscience/visionforge/VisionGroupKt {
|
|||||||
public static synthetic fun group$default (Lspace/kscience/visionforge/MutableVisionContainer;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/SimpleVisionGroup;
|
public static synthetic fun group$default (Lspace/kscience/visionforge/MutableVisionContainer;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/SimpleVisionGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/visionforge/VisionInputEvent : space/kscience/visionforge/VisionControlEvent {
|
||||||
|
public static final field Companion Lspace/kscience/visionforge/VisionInputEvent$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public fun getMeta ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun getName ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun getValue ()Lspace/kscience/dataforge/meta/Value;
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/visionforge/VisionInputEvent$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/visionforge/VisionInputEvent$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/visionforge/VisionInputEvent;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/visionforge/VisionInputEvent;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/visionforge/VisionInputEvent$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
public final class space/kscience/visionforge/VisionKt {
|
public final class space/kscience/visionforge/VisionKt {
|
||||||
public static final fun getVisible (Lspace/kscience/visionforge/Vision;)Ljava/lang/Boolean;
|
public static final fun getVisible (Lspace/kscience/visionforge/Vision;)Ljava/lang/Boolean;
|
||||||
public static final fun onPropertyChange (Lspace/kscience/visionforge/Vision;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
public static final fun onPropertyChange (Lspace/kscience/visionforge/Vision;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
@ -649,8 +676,8 @@ public final class space/kscience/visionforge/VisionPropertiesKt {
|
|||||||
public static final fun get (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lspace/kscience/dataforge/meta/Meta;
|
public static final fun get (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
public static synthetic fun get$default (Lspace/kscience/visionforge/MutableVisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/MutableMeta;
|
public static synthetic fun get$default (Lspace/kscience/visionforge/MutableVisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/MutableMeta;
|
||||||
public static synthetic fun get$default (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Meta;
|
public static synthetic fun get$default (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
public static final fun getValue (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lspace/kscience/dataforge/meta/Value;
|
public static final fun getValue (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;ZLjava/lang/Boolean;)Lspace/kscience/dataforge/meta/Value;
|
||||||
public static synthetic fun getValue$default (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Value;
|
public static synthetic fun getValue$default (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;ZLjava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Value;
|
||||||
public static final fun invoke (Lspace/kscience/visionforge/MutableVisionProperties;Lkotlin/jvm/functions/Function1;)V
|
public static final fun invoke (Lspace/kscience/visionforge/MutableVisionProperties;Lkotlin/jvm/functions/Function1;)V
|
||||||
public static final fun remove (Lspace/kscience/visionforge/MutableVisionProperties;Ljava/lang/String;)V
|
public static final fun remove (Lspace/kscience/visionforge/MutableVisionProperties;Ljava/lang/String;)V
|
||||||
public static final fun remove (Lspace/kscience/visionforge/MutableVisionProperties;Lspace/kscience/dataforge/names/Name;)V
|
public static final fun remove (Lspace/kscience/visionforge/MutableVisionProperties;Lspace/kscience/dataforge/names/Name;)V
|
||||||
@ -781,8 +808,8 @@ public abstract class space/kscience/visionforge/html/VisionOfHtml : space/kscie
|
|||||||
public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtml$Companion;
|
public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtml$Companion;
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public synthetic fun <init> (ILspace/kscience/dataforge/meta/MutableMeta;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
public synthetic fun <init> (ILspace/kscience/dataforge/meta/MutableMeta;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
public final fun getClasses ()Ljava/util/List;
|
public final fun getClasses ()Ljava/util/Set;
|
||||||
public final fun setClasses (Ljava/util/List;)V
|
public final fun setClasses (Ljava/util/Set;)V
|
||||||
public static final synthetic fun write$Self (Lspace/kscience/visionforge/html/VisionOfHtml;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
public static final synthetic fun write$Self (Lspace/kscience/visionforge/html/VisionOfHtml;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,9 +840,16 @@ public final class space/kscience/visionforge/html/VisionOfHtmlButton$Companion
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract class space/kscience/visionforge/html/VisionOfHtmlControl : space/kscience/visionforge/html/VisionOfHtml, space/kscience/visionforge/ControlVision {
|
public abstract class space/kscience/visionforge/html/VisionOfHtmlControl : space/kscience/visionforge/html/VisionOfHtml, space/kscience/visionforge/ControlVision {
|
||||||
|
public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtmlControl$Companion;
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
|
public synthetic fun <init> (ILspace/kscience/dataforge/meta/MutableMeta;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
public fun dispatchControlEvent (Lspace/kscience/visionforge/VisionControlEvent;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public fun dispatchControlEvent (Lspace/kscience/visionforge/VisionControlEvent;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public fun getControlEventFlow ()Lkotlinx/coroutines/flow/SharedFlow;
|
public fun getControlEventFlow ()Lkotlinx/coroutines/flow/SharedFlow;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/visionforge/html/VisionOfHtmlControl;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/visionforge/html/VisionOfHtmlControl$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class space/kscience/visionforge/html/VisionOfHtmlForm : space/kscience/visionforge/html/VisionOfHtmlControl {
|
public final class space/kscience/visionforge/html/VisionOfHtmlForm : space/kscience/visionforge/html/VisionOfHtmlControl {
|
||||||
@ -849,11 +883,9 @@ public final class space/kscience/visionforge/html/VisionOfHtmlFormKt {
|
|||||||
|
|
||||||
public class space/kscience/visionforge/html/VisionOfHtmlInput : space/kscience/visionforge/html/VisionOfHtmlControl {
|
public class space/kscience/visionforge/html/VisionOfHtmlInput : space/kscience/visionforge/html/VisionOfHtmlControl {
|
||||||
public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtmlInput$Companion;
|
public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtmlInput$Companion;
|
||||||
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/visionforge/html/InputFeedbackMode;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
public synthetic fun <init> (ILspace/kscience/dataforge/meta/MutableMeta;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
public fun <init> (Ljava/lang/String;Lspace/kscience/visionforge/html/InputFeedbackMode;)V
|
public fun <init> (Ljava/lang/String;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Lspace/kscience/visionforge/html/InputFeedbackMode;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
|
||||||
public final fun getDisabled ()Z
|
public final fun getDisabled ()Z
|
||||||
public final fun getFeedbackMode ()Lspace/kscience/visionforge/html/InputFeedbackMode;
|
|
||||||
public final fun getFieldName ()Ljava/lang/String;
|
public final fun getFieldName ()Ljava/lang/String;
|
||||||
public final fun getInputType ()Ljava/lang/String;
|
public final fun getInputType ()Ljava/lang/String;
|
||||||
public final fun getValue ()Lspace/kscience/dataforge/meta/Value;
|
public final fun getValue ()Lspace/kscience/dataforge/meta/Value;
|
||||||
@ -891,6 +923,8 @@ public final class space/kscience/visionforge/html/VisionOfHtmlKt {
|
|||||||
public static synthetic fun htmlRangeField$default (Lspace/kscience/visionforge/html/VisionOutput;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/html/VisionOfRangeField;
|
public static synthetic fun htmlRangeField$default (Lspace/kscience/visionforge/html/VisionOutput;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/html/VisionOfRangeField;
|
||||||
public static final fun htmlTextField (Lspace/kscience/visionforge/html/VisionOutput;Lkotlin/jvm/functions/Function1;)Lspace/kscience/visionforge/html/VisionOfTextField;
|
public static final fun htmlTextField (Lspace/kscience/visionforge/html/VisionOutput;Lkotlin/jvm/functions/Function1;)Lspace/kscience/visionforge/html/VisionOfTextField;
|
||||||
public static synthetic fun htmlTextField$default (Lspace/kscience/visionforge/html/VisionOutput;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/html/VisionOfTextField;
|
public static synthetic fun htmlTextField$default (Lspace/kscience/visionforge/html/VisionOutput;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/html/VisionOfTextField;
|
||||||
|
public static final fun onInput (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
|
public static synthetic fun onInput$default (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||||
public static final fun onValueChange (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
public static final fun onValueChange (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
public static synthetic fun onValueChange$default (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
public static synthetic fun onValueChange$default (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||||
}
|
}
|
||||||
|
@ -83,9 +83,32 @@ public class VisionValueChangeEvent(override val meta: Meta) : VisionControlEven
|
|||||||
override fun toString(): String = meta.toString()
|
override fun toString(): String = meta.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public fun VisionValueChangeEvent(value: Value?, name: Name? = null): VisionValueChangeEvent = VisionValueChangeEvent(
|
public fun VisionValueChangeEvent(value: Value?, name: Name? = null): VisionValueChangeEvent = VisionValueChangeEvent(
|
||||||
Meta {
|
Meta {
|
||||||
this.value = value
|
this.value = value
|
||||||
name?.let { set("name", it.toString()) }
|
name?.let { set("name", it.toString()) }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@SerialName("control.input")
|
||||||
|
public class VisionInputEvent(override val meta: Meta) : VisionControlEvent() {
|
||||||
|
|
||||||
|
public val value: Value? get() = meta.value
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of a control that fired the event
|
||||||
|
*/
|
||||||
|
public val name: Name? get() = meta["name"]?.string?.parseAsName()
|
||||||
|
|
||||||
|
override fun toString(): String = meta.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun VisionInputEvent(value: Value?, name: Name? = null): VisionInputEvent = VisionInputEvent(
|
||||||
|
Meta {
|
||||||
|
this.value = value
|
||||||
|
name?.let { set("name", it.toString()) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package space.kscience.visionforge
|
package space.kscience.visionforge
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import space.kscience.dataforge.context.Plugin
|
import space.kscience.dataforge.context.Plugin
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
@ -16,6 +18,10 @@ public interface VisionClient: Plugin {
|
|||||||
public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?)
|
public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun VisionClient.sendEventAsync(targetName: Name, event: VisionEvent): Job = context.launch {
|
||||||
|
sendEvent(targetName, event)
|
||||||
|
}
|
||||||
|
|
||||||
public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) {
|
public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) {
|
||||||
notifyPropertyChanged(visionName, propertyName.parseAsName(true), item)
|
notifyPropertyChanged(visionName, propertyName.parseAsName(true), item)
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont
|
|||||||
subclass(VisionMetaEvent.serializer())
|
subclass(VisionMetaEvent.serializer())
|
||||||
subclass(VisionClickEvent.serializer())
|
subclass(VisionClickEvent.serializer())
|
||||||
subclass(VisionValueChangeEvent.serializer())
|
subclass(VisionValueChangeEvent.serializer())
|
||||||
|
subclass(VisionInputEvent.serializer())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,14 +265,14 @@ public abstract class AbstractVisionProperties(
|
|||||||
|
|
||||||
public fun VisionProperties.getValue(
|
public fun VisionProperties.getValue(
|
||||||
name: String,
|
name: String,
|
||||||
inherit: Boolean? = null,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean? = null,
|
includeStyles: Boolean? = null,
|
||||||
): Value? = getValue(name.parseAsName(), inherit, includeStyles)
|
): Value? = getValue(name.parseAsName(), inherit, includeStyles)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get [Vision] property using key as a String
|
* Get [Vision] property using key as a String
|
||||||
*/
|
*/
|
||||||
public fun VisionProperties.get(
|
public operator fun VisionProperties.get(
|
||||||
name: String,
|
name: String,
|
||||||
inherit: Boolean? = null,
|
inherit: Boolean? = null,
|
||||||
includeStyles: Boolean? = null,
|
includeStyles: Boolean? = null,
|
||||||
@ -292,7 +292,7 @@ public fun MutableVisionProperties.root(
|
|||||||
/**
|
/**
|
||||||
* Get [Vision] property using key as a String
|
* Get [Vision] property using key as a String
|
||||||
*/
|
*/
|
||||||
public fun MutableVisionProperties.get(
|
public operator fun MutableVisionProperties.get(
|
||||||
name: String,
|
name: String,
|
||||||
inherit: Boolean? = null,
|
inherit: Boolean? = null,
|
||||||
includeStyles: Boolean? = null,
|
includeStyles: Boolean? = null,
|
||||||
|
@ -12,15 +12,16 @@ import kotlinx.serialization.Serializable
|
|||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import space.kscience.dataforge.meta.*
|
import space.kscience.dataforge.meta.*
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.visionforge.AbstractVision
|
import space.kscience.visionforge.*
|
||||||
import space.kscience.visionforge.ControlVision
|
|
||||||
import space.kscience.visionforge.VisionControlEvent
|
|
||||||
import space.kscience.visionforge.VisionValueChangeEvent
|
|
||||||
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
public abstract class VisionOfHtml : AbstractVision() {
|
public abstract class VisionOfHtml : AbstractVision() {
|
||||||
public var classes: List<String> by properties.stringList(*emptyArray())
|
public var classes: Set<String>
|
||||||
|
get() = properties.get(::classes.name,false).stringList?.toSet() ?: emptySet()
|
||||||
|
set(value) {
|
||||||
|
properties[::classes.name] = value.map { it.asValue() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -58,6 +59,7 @@ public enum class InputFeedbackMode {
|
|||||||
NONE
|
NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
public abstract class VisionOfHtmlControl: VisionOfHtml(), ControlVision{
|
public abstract class VisionOfHtmlControl: VisionOfHtml(), ControlVision{
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
@ -76,7 +78,6 @@ public abstract class VisionOfHtmlControl: VisionOfHtml(), ControlVision{
|
|||||||
@SerialName("html.input")
|
@SerialName("html.input")
|
||||||
public open class VisionOfHtmlInput(
|
public open class VisionOfHtmlInput(
|
||||||
public val inputType: String,
|
public val inputType: String,
|
||||||
public val feedbackMode: InputFeedbackMode = InputFeedbackMode.ONCHANGE,
|
|
||||||
) : VisionOfHtmlControl() {
|
) : VisionOfHtmlControl() {
|
||||||
public var value: Value? by properties.value()
|
public var value: Value? by properties.value()
|
||||||
public var disabled: Boolean by properties.boolean { false }
|
public var disabled: Boolean by properties.boolean { false }
|
||||||
@ -92,6 +93,11 @@ public fun VisionOfHtmlInput.onValueChange(
|
|||||||
callback: suspend VisionValueChangeEvent.() -> Unit,
|
callback: suspend VisionValueChangeEvent.() -> Unit,
|
||||||
): Job = controlEventFlow.filterIsInstance<VisionValueChangeEvent>().onEach(callback).launchIn(scope)
|
): Job = controlEventFlow.filterIsInstance<VisionValueChangeEvent>().onEach(callback).launchIn(scope)
|
||||||
|
|
||||||
|
public fun VisionOfHtmlInput.onInput(
|
||||||
|
scope: CoroutineScope = manager?.context ?: error("Coroutine context is not resolved for $this"),
|
||||||
|
callback: suspend VisionInputEvent.() -> Unit,
|
||||||
|
): Job = controlEventFlow.filterIsInstance<VisionInputEvent>().onEach(callback).launchIn(scope)
|
||||||
|
|
||||||
@Suppress("UnusedReceiverParameter")
|
@Suppress("UnusedReceiverParameter")
|
||||||
public inline fun VisionOutput.htmlInput(
|
public inline fun VisionOutput.htmlInput(
|
||||||
inputType: String,
|
inputType: String,
|
||||||
|
@ -40,7 +40,7 @@ internal class VisionPropertyTest {
|
|||||||
@Test
|
@Test
|
||||||
fun testPropertyEdit() {
|
fun testPropertyEdit() {
|
||||||
val vision = manager.group()
|
val vision = manager.group()
|
||||||
vision.properties.get("fff.ddd").apply {
|
vision.properties["fff.ddd"].apply {
|
||||||
value = 2.asValue()
|
value = 2.asValue()
|
||||||
}
|
}
|
||||||
assertEquals(2, vision.properties.getValue("fff.ddd")?.int)
|
assertEquals(2, vision.properties.getValue("fff.ddd")?.int)
|
||||||
@ -50,7 +50,7 @@ internal class VisionPropertyTest {
|
|||||||
@Test
|
@Test
|
||||||
fun testPropertyUpdate() {
|
fun testPropertyUpdate() {
|
||||||
val vision = manager.group()
|
val vision = manager.group()
|
||||||
vision.properties.get("fff").updateWith(TestScheme) {
|
vision.properties["fff"].updateWith(TestScheme) {
|
||||||
ddd = 2
|
ddd = 2
|
||||||
}
|
}
|
||||||
assertEquals(2, vision.properties.getValue("fff.ddd")?.int)
|
assertEquals(2, vision.properties.getValue("fff.ddd")?.int)
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
package space.kscience.visionforge
|
package space.kscience.visionforge
|
||||||
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.dom.clear
|
import kotlinx.dom.clear
|
||||||
import kotlinx.html.InputType
|
import kotlinx.html.InputType
|
||||||
import kotlinx.html.div
|
import kotlinx.html.div
|
||||||
import kotlinx.html.js.input
|
import kotlinx.html.js.input
|
||||||
import org.w3c.dom.HTMLElement
|
import org.w3c.dom.HTMLElement
|
||||||
import org.w3c.dom.HTMLInputElement
|
import org.w3c.dom.HTMLInputElement
|
||||||
import org.w3c.dom.events.Event
|
|
||||||
import space.kscience.dataforge.meta.Value
|
|
||||||
import space.kscience.dataforge.meta.asValue
|
import space.kscience.dataforge.meta.asValue
|
||||||
import space.kscience.dataforge.meta.double
|
import space.kscience.dataforge.meta.double
|
||||||
import space.kscience.dataforge.meta.string
|
import space.kscience.dataforge.meta.string
|
||||||
import space.kscience.dataforge.names.Name
|
|
||||||
import space.kscience.visionforge.html.*
|
import space.kscience.visionforge.html.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,13 +22,6 @@ internal fun HTMLElement.subscribeToVision(vision: VisionOfHtml) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun VisionClient.sendInputEvent(name: Name, value: Value?) {
|
|
||||||
context.launch {
|
|
||||||
sendEvent(name, VisionValueChangeEvent(value, name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribes the HTML input element to a given vision.
|
* Subscribes the HTML input element to a given vision.
|
||||||
*
|
*
|
||||||
@ -62,16 +51,13 @@ internal val inputVisionRenderer: ElementVisionRenderer = ElementVisionRenderer<
|
|||||||
input {
|
input {
|
||||||
type = InputType.text
|
type = InputType.text
|
||||||
}.also { htmlInputElement ->
|
}.also { htmlInputElement ->
|
||||||
val onEvent: (Event) -> Unit = {
|
|
||||||
client.sendInputEvent(name, htmlInputElement.value.asValue())
|
htmlInputElement.onchange = {
|
||||||
|
client.sendEventAsync(name, VisionValueChangeEvent(htmlInputElement.value.asValue(), name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
htmlInputElement.oninput = {
|
||||||
when (vision.feedbackMode) {
|
client.sendEventAsync(name, VisionInputEvent(htmlInputElement.value.asValue(), name))
|
||||||
InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent
|
|
||||||
|
|
||||||
InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent
|
|
||||||
InputFeedbackMode.NONE -> {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlInputElement.subscribeToInput(vision)
|
htmlInputElement.subscribeToInput(vision)
|
||||||
@ -86,18 +72,16 @@ internal val checkboxVisionRenderer: ElementVisionRenderer =
|
|||||||
input {
|
input {
|
||||||
type = InputType.checkBox
|
type = InputType.checkBox
|
||||||
}.also { htmlInputElement ->
|
}.also { htmlInputElement ->
|
||||||
val onEvent: (Event) -> Unit = {
|
|
||||||
client.sendInputEvent(name, htmlInputElement.checked.asValue())
|
htmlInputElement.onchange = {
|
||||||
|
client.sendEventAsync(name, VisionValueChangeEvent(htmlInputElement.value.asValue(), name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
htmlInputElement.oninput = {
|
||||||
when (vision.feedbackMode) {
|
client.sendEventAsync(name, VisionInputEvent(htmlInputElement.value.asValue(), name))
|
||||||
InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent
|
|
||||||
|
|
||||||
InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent
|
|
||||||
InputFeedbackMode.NONE -> {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
htmlInputElement.subscribeToInput(vision)
|
htmlInputElement.subscribeToInput(vision)
|
||||||
vision.useProperty(VisionOfCheckbox::checked) {
|
vision.useProperty(VisionOfCheckbox::checked) {
|
||||||
htmlInputElement.checked = it ?: false
|
htmlInputElement.checked = it ?: false
|
||||||
@ -110,16 +94,13 @@ internal val textVisionRenderer: ElementVisionRenderer =
|
|||||||
input {
|
input {
|
||||||
type = InputType.text
|
type = InputType.text
|
||||||
}.also { htmlInputElement ->
|
}.also { htmlInputElement ->
|
||||||
val onEvent: (Event) -> Unit = {
|
|
||||||
client.sendInputEvent(name, htmlInputElement.value.asValue())
|
htmlInputElement.onchange = {
|
||||||
|
client.sendEventAsync(name, VisionValueChangeEvent(htmlInputElement.value.asValue(), name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
htmlInputElement.oninput = {
|
||||||
when (vision.feedbackMode) {
|
client.sendEventAsync(name, VisionInputEvent(htmlInputElement.value.asValue(), name))
|
||||||
InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent
|
|
||||||
|
|
||||||
InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent
|
|
||||||
InputFeedbackMode.NONE -> {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlInputElement.subscribeToInput(vision)
|
htmlInputElement.subscribeToInput(vision)
|
||||||
@ -135,18 +116,19 @@ internal val numberVisionRenderer: ElementVisionRenderer =
|
|||||||
type = InputType.number
|
type = InputType.number
|
||||||
}.also { htmlInputElement ->
|
}.also { htmlInputElement ->
|
||||||
|
|
||||||
val onEvent: (Event) -> Unit = {
|
htmlInputElement.onchange = {
|
||||||
htmlInputElement.value.toDoubleOrNull()?.let {
|
htmlInputElement.value.toDoubleOrNull()?.let {
|
||||||
client.sendInputEvent(name, htmlInputElement.value.asValue())
|
client.sendEventAsync(name, VisionValueChangeEvent(it.asValue(), name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when (vision.feedbackMode) {
|
htmlInputElement.oninput = {
|
||||||
InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent
|
htmlInputElement.value.toDoubleOrNull()?.let {
|
||||||
|
client.sendEventAsync(name, VisionInputEvent(it.asValue(), name))
|
||||||
InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent
|
|
||||||
InputFeedbackMode.NONE -> {}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
htmlInputElement.subscribeToInput(vision)
|
htmlInputElement.subscribeToInput(vision)
|
||||||
vision.useProperty(VisionOfNumberField::value) {
|
vision.useProperty(VisionOfNumberField::value) {
|
||||||
htmlInputElement.valueAsNumber = it?.double ?: 0.0
|
htmlInputElement.valueAsNumber = it?.double ?: 0.0
|
||||||
@ -163,18 +145,18 @@ internal val rangeVisionRenderer: ElementVisionRenderer =
|
|||||||
step = vision.step.toString()
|
step = vision.step.toString()
|
||||||
}.also { htmlInputElement ->
|
}.also { htmlInputElement ->
|
||||||
|
|
||||||
val onEvent: (Event) -> Unit = {
|
htmlInputElement.onchange = {
|
||||||
htmlInputElement.value.toDoubleOrNull()?.let {
|
htmlInputElement.value.toDoubleOrNull()?.let {
|
||||||
client.sendInputEvent(name, htmlInputElement.value.asValue())
|
client.sendEventAsync(name, VisionValueChangeEvent(it.asValue(), name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when (vision.feedbackMode) {
|
htmlInputElement.oninput = {
|
||||||
InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent
|
htmlInputElement.value.toDoubleOrNull()?.let {
|
||||||
|
client.sendEventAsync(name, VisionInputEvent(it.asValue(), name))
|
||||||
InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent
|
|
||||||
InputFeedbackMode.NONE -> {}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
htmlInputElement.subscribeToInput(vision)
|
htmlInputElement.subscribeToInput(vision)
|
||||||
vision.useProperty(VisionOfRangeField::value) {
|
vision.useProperty(VisionOfRangeField::value) {
|
||||||
htmlInputElement.valueAsNumber = it?.double ?: 0.0
|
htmlInputElement.valueAsNumber = it?.double ?: 0.0
|
||||||
|
@ -7,16 +7,7 @@ description = "Jupyter api artifact including all common modules"
|
|||||||
kscience {
|
kscience {
|
||||||
fullStack(
|
fullStack(
|
||||||
"js/visionforge-jupyter-common.js",
|
"js/visionforge-jupyter-common.js",
|
||||||
jsConfig = { useCommonJs() }
|
)
|
||||||
) {
|
|
||||||
commonWebpackConfig {
|
|
||||||
sourceMaps = false
|
|
||||||
cssSupport {
|
|
||||||
enabled.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.visionforgeSolid)
|
api(projects.visionforgeSolid)
|
||||||
api(projects.visionforgePlotly)
|
api(projects.visionforgePlotly)
|
||||||
@ -30,7 +21,6 @@ kscience {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jsMain {
|
jsMain {
|
||||||
implementation(projects.ui.ring)
|
|
||||||
implementation(projects.visionforgeThreejs)
|
implementation(projects.visionforgeThreejs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,12 +3,12 @@ package space.kscience.visionforge.gdml.jupyter
|
|||||||
import space.kscience.visionforge.jupyter.VFNotebookClient
|
import space.kscience.visionforge.jupyter.VFNotebookClient
|
||||||
import space.kscience.visionforge.markup.MarkupPlugin
|
import space.kscience.visionforge.markup.MarkupPlugin
|
||||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
|
||||||
import space.kscience.visionforge.runVisionClient
|
import space.kscience.visionforge.runVisionClient
|
||||||
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.tables.TableVisionJsPlugin
|
import space.kscience.visionforge.tables.TableVisionJsPlugin
|
||||||
|
|
||||||
public fun main(): Unit = runVisionClient {
|
public fun main(): Unit = runVisionClient {
|
||||||
plugin(ThreeWithControlsPlugin)
|
plugin(ThreePlugin)
|
||||||
plugin(PlotlyPlugin)
|
plugin(PlotlyPlugin)
|
||||||
plugin(MarkupPlugin)
|
plugin(MarkupPlugin)
|
||||||
plugin(TableVisionJsPlugin)
|
plugin(TableVisionJsPlugin)
|
||||||
|
@ -1141,14 +1141,14 @@ public final class space/kscience/visionforge/solid/specifications/Canvas3DOptio
|
|||||||
public final fun getAxes ()Lspace/kscience/visionforge/solid/specifications/AxesScheme;
|
public final fun getAxes ()Lspace/kscience/visionforge/solid/specifications/AxesScheme;
|
||||||
public final fun getCamera ()Lspace/kscience/visionforge/solid/specifications/CameraScheme;
|
public final fun getCamera ()Lspace/kscience/visionforge/solid/specifications/CameraScheme;
|
||||||
public final fun getClipping ()Lspace/kscience/visionforge/solid/specifications/PointScheme;
|
public final fun getClipping ()Lspace/kscience/visionforge/solid/specifications/PointScheme;
|
||||||
public final fun getControls ()Lspace/kscience/visionforge/solid/specifications/ControlsScheme;
|
public final fun getControls ()Lspace/kscience/visionforge/solid/specifications/Canvas3DUIScheme;
|
||||||
public final fun getLayers ()Ljava/util/List;
|
public final fun getLayers ()Ljava/util/List;
|
||||||
public final fun getOnSelect ()Lkotlin/jvm/functions/Function1;
|
public final fun getOnSelect ()Lkotlin/jvm/functions/Function1;
|
||||||
public final fun getSize ()Lspace/kscience/visionforge/solid/specifications/CanvasSize;
|
public final fun getSize ()Lspace/kscience/visionforge/solid/specifications/CanvasSize;
|
||||||
public final fun setAxes (Lspace/kscience/visionforge/solid/specifications/AxesScheme;)V
|
public final fun setAxes (Lspace/kscience/visionforge/solid/specifications/AxesScheme;)V
|
||||||
public final fun setCamera (Lspace/kscience/visionforge/solid/specifications/CameraScheme;)V
|
public final fun setCamera (Lspace/kscience/visionforge/solid/specifications/CameraScheme;)V
|
||||||
public final fun setClipping (Lspace/kscience/visionforge/solid/specifications/PointScheme;)V
|
public final fun setClipping (Lspace/kscience/visionforge/solid/specifications/PointScheme;)V
|
||||||
public final fun setControls (Lspace/kscience/visionforge/solid/specifications/ControlsScheme;)V
|
public final fun setControls (Lspace/kscience/visionforge/solid/specifications/Canvas3DUIScheme;)V
|
||||||
public final fun setLayers (Ljava/util/List;)V
|
public final fun setLayers (Ljava/util/List;)V
|
||||||
public final fun setOnSelect (Lkotlin/jvm/functions/Function1;)V
|
public final fun setOnSelect (Lkotlin/jvm/functions/Function1;)V
|
||||||
public final fun setSize (Lspace/kscience/visionforge/solid/specifications/CanvasSize;)V
|
public final fun setSize (Lspace/kscience/visionforge/solid/specifications/CanvasSize;)V
|
||||||
@ -1163,6 +1163,16 @@ public final class space/kscience/visionforge/solid/specifications/Canvas3DOptio
|
|||||||
public static final fun computeWidth (Lspace/kscience/visionforge/solid/specifications/CanvasSize;Ljava/lang/Number;)I
|
public static final fun computeWidth (Lspace/kscience/visionforge/solid/specifications/CanvasSize;Ljava/lang/Number;)I
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/visionforge/solid/specifications/Canvas3DUIScheme : space/kscience/dataforge/meta/Scheme {
|
||||||
|
public static final field Companion Lspace/kscience/visionforge/solid/specifications/Canvas3DUIScheme$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public final fun getEnabled ()Z
|
||||||
|
public final fun setEnabled (Z)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/visionforge/solid/specifications/Canvas3DUIScheme$Companion : space/kscience/dataforge/meta/SchemeSpec {
|
||||||
|
}
|
||||||
|
|
||||||
public final class space/kscience/visionforge/solid/specifications/CanvasSize : space/kscience/dataforge/meta/Scheme {
|
public final class space/kscience/visionforge/solid/specifications/CanvasSize : space/kscience/dataforge/meta/Scheme {
|
||||||
public static final field Companion Lspace/kscience/visionforge/solid/specifications/CanvasSize$Companion;
|
public static final field Companion Lspace/kscience/visionforge/solid/specifications/CanvasSize$Companion;
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
@ -1189,14 +1199,6 @@ public final class space/kscience/visionforge/solid/specifications/Clipping : sp
|
|||||||
public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
|
public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class space/kscience/visionforge/solid/specifications/ControlsScheme : space/kscience/dataforge/meta/Scheme {
|
|
||||||
public static final field Companion Lspace/kscience/visionforge/solid/specifications/ControlsScheme$Companion;
|
|
||||||
public fun <init> ()V
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class space/kscience/visionforge/solid/specifications/ControlsScheme$Companion : space/kscience/dataforge/meta/SchemeSpec {
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class space/kscience/visionforge/solid/specifications/PointScheme : space/kscience/dataforge/meta/Scheme {
|
public final class space/kscience/visionforge/solid/specifications/PointScheme : space/kscience/dataforge/meta/Scheme {
|
||||||
public static final field Companion Lspace/kscience/visionforge/solid/specifications/PointScheme$Companion;
|
public static final field Companion Lspace/kscience/visionforge/solid/specifications/PointScheme$Companion;
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
|
@ -62,7 +62,7 @@ public class Canvas3DOptions : Scheme() {
|
|||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
public var axes: AxesScheme by spec(AxesScheme)
|
public var axes: AxesScheme by spec(AxesScheme)
|
||||||
public var camera: CameraScheme by spec(CameraScheme)
|
public var camera: CameraScheme by spec(CameraScheme)
|
||||||
public var controls: ControlsScheme by spec(ControlsScheme)
|
public var controls: Canvas3DUIScheme by spec(Canvas3DUIScheme)
|
||||||
|
|
||||||
public var size: CanvasSize by spec(CanvasSize)
|
public var size: CanvasSize by spec(CanvasSize)
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ public class Canvas3DOptions : Scheme() {
|
|||||||
hide()
|
hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme(Canvas3DOptions::controls, ControlsScheme) {
|
scheme(Canvas3DOptions::controls, Canvas3DUIScheme) {
|
||||||
hide()
|
hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package space.kscience.visionforge.solid.specifications
|
||||||
|
|
||||||
|
import space.kscience.dataforge.meta.Scheme
|
||||||
|
import space.kscience.dataforge.meta.SchemeSpec
|
||||||
|
import space.kscience.dataforge.meta.boolean
|
||||||
|
|
||||||
|
|
||||||
|
public class Canvas3DUIScheme : Scheme() {
|
||||||
|
|
||||||
|
public var enabled: Boolean by boolean{true}
|
||||||
|
|
||||||
|
public companion object : SchemeSpec<Canvas3DUIScheme>(::Canvas3DUIScheme)
|
||||||
|
}
|
@ -1,9 +0,0 @@
|
|||||||
package space.kscience.visionforge.solid.specifications
|
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.Scheme
|
|
||||||
import space.kscience.dataforge.meta.SchemeSpec
|
|
||||||
|
|
||||||
|
|
||||||
public class ControlsScheme : Scheme() {
|
|
||||||
public companion object : SchemeSpec<ControlsScheme>(::ControlsScheme)
|
|
||||||
}
|
|
@ -4,6 +4,7 @@ import kotlinx.coroutines.CompletableDeferred
|
|||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import space.kscience.dataforge.meta.getValue
|
||||||
import space.kscience.dataforge.meta.int
|
import space.kscience.dataforge.meta.int
|
||||||
import space.kscience.dataforge.meta.set
|
import space.kscience.dataforge.meta.set
|
||||||
import space.kscience.dataforge.meta.string
|
import space.kscience.dataforge.meta.string
|
||||||
|
@ -9,23 +9,17 @@ kscience {
|
|||||||
js {
|
js {
|
||||||
useCommonJs()
|
useCommonJs()
|
||||||
binaries.library()
|
binaries.library()
|
||||||
browser {
|
|
||||||
commonWebpackConfig {
|
|
||||||
cssSupport {
|
|
||||||
enabled.set(true)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
useSerialization()
|
||||||
}
|
commonMain {
|
||||||
dependencies {
|
|
||||||
api(projects.visionforgeCore)
|
api(projects.visionforgeCore)
|
||||||
api("space.kscience:tables-kt:${tablesVersion}")
|
api("space.kscience:tables-kt:${tablesVersion}")
|
||||||
}
|
}
|
||||||
dependencies(jsMain) {
|
jsMain {
|
||||||
implementation(npm("tabulator-tables", "5.5.2"))
|
implementation(npm("tabulator-tables", "5.5.2"))
|
||||||
implementation(npm("@types/tabulator-tables", "5.5.3"))
|
implementation(npm("@types/tabulator-tables", "5.5.3"))
|
||||||
}
|
}
|
||||||
useSerialization()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readme {
|
readme {
|
||||||
|
@ -13,8 +13,7 @@ import space.kscience.visionforge.VisionPlugin
|
|||||||
public class TableVisionPlugin : VisionPlugin() {
|
public class TableVisionPlugin : VisionPlugin() {
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
override val visionSerializersModule: SerializersModule
|
override val visionSerializersModule: SerializersModule = SerializersModule {
|
||||||
get() = SerializersModule {
|
|
||||||
polymorphic(Vision::class) {
|
polymorphic(Vision::class) {
|
||||||
subclass(VisionOfTable.serializer())
|
subclass(VisionOfTable.serializer())
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
|
alias(spclibs.plugins.compose)
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin{
|
kotlin {
|
||||||
explicitApi = org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode.Disabled
|
explicitApi = org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode.Disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
kscience{
|
kscience {
|
||||||
js{
|
js {
|
||||||
binaries.library()
|
binaries.library()
|
||||||
}
|
}
|
||||||
jsMain{
|
|
||||||
dependencies {
|
commonMain {
|
||||||
api(projects.visionforgeSolid)
|
api(projects.visionforgeSolid)
|
||||||
implementation(npm("three", "0.143.0"))
|
api(projects.visionforgeCompose)
|
||||||
implementation(npm("three-csg-ts", "3.1.10"))
|
|
||||||
implementation(npm("three.meshline","1.4.0"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jsMain {
|
||||||
|
implementation(npm("three", "0.143.0"))
|
||||||
|
implementation(npm("three-csg-ts", "3.1.13"))
|
||||||
|
implementation(npm("three.meshline", "1.4.0"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ public class ThreeCanvas(
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private fun addControls(element: Node, controls: ControlsScheme) {
|
private fun addControls(element: Node, controls: Canvas3DUIScheme) {
|
||||||
when (controls.meta["type"].string) {
|
when (controls.meta["type"].string) {
|
||||||
"trackball" -> TrackballControls(camera, element)
|
"trackball" -> TrackballControls(camera, element)
|
||||||
else -> OrbitControls(camera, element)
|
else -> OrbitControls(camera, element)
|
||||||
|
@ -2,14 +2,15 @@ package space.kscience.visionforge.solid.three
|
|||||||
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import org.jetbrains.compose.web.renderComposable
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.HTMLElement
|
|
||||||
import space.kscience.dataforge.context.*
|
import space.kscience.dataforge.context.*
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.names.*
|
import space.kscience.dataforge.names.*
|
||||||
import space.kscience.visionforge.*
|
import space.kscience.visionforge.*
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
|
import space.kscience.visionforge.solid.three.compose.ThreeView
|
||||||
import space.kscience.visionforge.solid.three.set
|
import space.kscience.visionforge.solid.three.set
|
||||||
import three.core.Object3D
|
import three.core.Object3D
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
@ -21,7 +22,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
|
|
||||||
public val solids: Solids by require(Solids)
|
public val solids: Solids by require(Solids)
|
||||||
|
|
||||||
public val client: VisionClient? get() = context.plugins.get<VisionClient>()
|
public val client: VisionClient by require(JsVisionClient)
|
||||||
|
|
||||||
private val objectFactories = HashMap<KClass<out Solid>, ThreeFactory<*>>()
|
private val objectFactories = HashMap<KClass<out Solid>, ThreeFactory<*>>()
|
||||||
private val compositeFactory = ThreeCompositeFactory(this)
|
private val compositeFactory = ThreeCompositeFactory(this)
|
||||||
@ -123,15 +124,6 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val canvasCache = HashMap<Element, ThreeCanvas>()
|
|
||||||
|
|
||||||
public fun getOrCreateCanvas(
|
|
||||||
element: Element,
|
|
||||||
options: Canvas3DOptions,
|
|
||||||
): ThreeCanvas = canvasCache.getOrPut(element) {
|
|
||||||
ThreeCanvas(this, element, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun content(target: String): Map<Name, Any> {
|
override fun content(target: String): Map<Name, Any> {
|
||||||
return when (target) {
|
return when (target) {
|
||||||
ElementVisionRenderer.TYPE -> mapOf("three".asName() to this)
|
ElementVisionRenderer.TYPE -> mapOf("three".asName() to this)
|
||||||
@ -142,20 +134,11 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
override fun rateVision(vision: Vision): Int =
|
override fun rateVision(vision: Vision): Int =
|
||||||
if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING else ElementVisionRenderer.ZERO_RATING
|
if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING else ElementVisionRenderer.ZERO_RATING
|
||||||
|
|
||||||
internal fun renderSolid(
|
|
||||||
element: Element,
|
|
||||||
vision: Solid,
|
|
||||||
options: Canvas3DOptions,
|
|
||||||
): ThreeCanvas = getOrCreateCanvas(element, options).apply {
|
|
||||||
render(vision)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun render(element: Element, client: VisionClient, name: Name, vision: Vision, meta: Meta) {
|
override fun render(element: Element, client: VisionClient, name: Name, vision: Vision, meta: Meta) {
|
||||||
renderSolid(
|
require(vision is Solid) { "Expected Solid but found ${vision::class}" }
|
||||||
element,
|
renderComposable(element) {
|
||||||
vision as? Solid ?: error("Solid expected but ${vision::class} found"),
|
ThreeView(solids, vision, null, Canvas3DOptions.read(meta))
|
||||||
Canvas3DOptions.read(meta)
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public companion object : PluginFactory<ThreePlugin> {
|
public companion object : PluginFactory<ThreePlugin> {
|
||||||
@ -165,14 +148,6 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun ThreePlugin.render(
|
|
||||||
element: HTMLElement,
|
|
||||||
obj: Solid,
|
|
||||||
optionsBuilder: Canvas3DOptions.() -> Unit = {},
|
|
||||||
): ThreeCanvas = renderSolid(element, obj, Canvas3DOptions(optionsBuilder)).apply {
|
|
||||||
options.apply(optionsBuilder)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal operator fun Object3D.set(token: NameToken, object3D: Object3D) {
|
internal operator fun Object3D.set(token: NameToken, object3D: Object3D) {
|
||||||
object3D.name = token.toString()
|
object3D.name = token.toString()
|
||||||
add(object3D)
|
add(object3D)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package space.kscience.visionforge.compose
|
package space.kscience.visionforge.solid.three.compose
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import org.jetbrains.compose.web.css.*
|
import org.jetbrains.compose.web.css.*
|
||||||
@ -9,6 +9,7 @@ import org.w3c.files.BlobPropertyBag
|
|||||||
import space.kscience.dataforge.context.Global
|
import space.kscience.dataforge.context.Global
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
|
import space.kscience.visionforge.compose.*
|
||||||
import space.kscience.visionforge.encodeToString
|
import space.kscience.visionforge.encodeToString
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
|
|
@ -0,0 +1,205 @@
|
|||||||
|
package space.kscience.visionforge.solid.three.compose
|
||||||
|
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import app.softwork.bootstrapcompose.Card
|
||||||
|
import kotlinx.dom.clear
|
||||||
|
import org.jetbrains.compose.web.ExperimentalComposeWebApi
|
||||||
|
import org.jetbrains.compose.web.css.*
|
||||||
|
import org.jetbrains.compose.web.dom.*
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.dataforge.context.request
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.isEmpty
|
||||||
|
import space.kscience.visionforge.Vision
|
||||||
|
import space.kscience.visionforge.compose.*
|
||||||
|
import space.kscience.visionforge.root
|
||||||
|
import space.kscience.visionforge.solid.Solid
|
||||||
|
import space.kscience.visionforge.solid.SolidGroup
|
||||||
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
|
import space.kscience.visionforge.solid.three.ThreeCanvas
|
||||||
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
|
import space.kscience.visionforge.styles
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SimpleThreeView(
|
||||||
|
context: Context,
|
||||||
|
options: Canvas3DOptions?,
|
||||||
|
solid: Solid?,
|
||||||
|
selected: Name?,
|
||||||
|
) {
|
||||||
|
|
||||||
|
val three: ThreePlugin by derivedStateOf { context.request(ThreePlugin) }
|
||||||
|
|
||||||
|
Div({
|
||||||
|
style {
|
||||||
|
maxWidth(100.vw)
|
||||||
|
maxHeight(100.vh)
|
||||||
|
width(100.percent)
|
||||||
|
height(100.percent)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
var canvas: ThreeCanvas? = null
|
||||||
|
DisposableEffect(options) {
|
||||||
|
canvas = ThreeCanvas(three, scopeElement, options ?: Canvas3DOptions())
|
||||||
|
onDispose {
|
||||||
|
scopeElement.clear()
|
||||||
|
canvas = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LaunchedEffect(solid) {
|
||||||
|
if (solid != null) {
|
||||||
|
canvas?.render(solid)
|
||||||
|
} else {
|
||||||
|
canvas?.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LaunchedEffect(selected) {
|
||||||
|
canvas?.select(selected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
public fun ThreeView(
|
||||||
|
solids: Solids,
|
||||||
|
solid: Solid?,
|
||||||
|
initialSelected: Name? = null,
|
||||||
|
options: Canvas3DOptions? = null,
|
||||||
|
sidebarTabs: @Composable TabsBuilder.() -> Unit = {},
|
||||||
|
) {
|
||||||
|
var selected: Name? by remember { mutableStateOf(initialSelected) }
|
||||||
|
|
||||||
|
val optionsSnapshot = remember(options) {
|
||||||
|
(options ?: Canvas3DOptions()).apply {
|
||||||
|
this.onSelect = {
|
||||||
|
selected = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val selectedVision: Vision? = remember(solid, selected) {
|
||||||
|
selected?.let {
|
||||||
|
when {
|
||||||
|
it.isEmpty() -> solid
|
||||||
|
else -> (solid as? SolidGroup)?.get(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optionsSnapshot.controls.enabled) {
|
||||||
|
|
||||||
|
|
||||||
|
FlexRow({
|
||||||
|
style {
|
||||||
|
height(100.percent)
|
||||||
|
width(100.percent)
|
||||||
|
flexWrap(FlexWrap.Wrap)
|
||||||
|
alignItems(AlignItems.Stretch)
|
||||||
|
alignContent(AlignContent.Stretch)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
FlexColumn({
|
||||||
|
style {
|
||||||
|
height(100.percent)
|
||||||
|
minWidth(600.px)
|
||||||
|
flex(10, 1, 600.px)
|
||||||
|
position(Position.Relative)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
if (solid == null) {
|
||||||
|
Div({
|
||||||
|
style {
|
||||||
|
position(Position.Fixed)
|
||||||
|
width(100.percent)
|
||||||
|
height(100.percent)
|
||||||
|
zIndex(1000)
|
||||||
|
top(40.percent)
|
||||||
|
left(0.px)
|
||||||
|
opacity(0.5)
|
||||||
|
|
||||||
|
@OptIn(ExperimentalComposeWebApi::class) filter {
|
||||||
|
opacity(50.percent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Div({ classes("d-flex", " justify-content-center") }) {
|
||||||
|
Div({
|
||||||
|
classes("spinner-grow", "text-primary")
|
||||||
|
style {
|
||||||
|
width(3.cssRem)
|
||||||
|
height(3.cssRem)
|
||||||
|
zIndex(20)
|
||||||
|
}
|
||||||
|
attr("role", "status")
|
||||||
|
}) {
|
||||||
|
Span({ classes("sr-only") }) { Text("Loading 3D vision") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SimpleThreeView(solids.context, optionsSnapshot, solid, selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedVision?.let { vision ->
|
||||||
|
Div({
|
||||||
|
style {
|
||||||
|
position(Position.Absolute)
|
||||||
|
top(5.px)
|
||||||
|
right(5.px)
|
||||||
|
width(450.px)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Card(
|
||||||
|
headerAttrs = {
|
||||||
|
// border = true
|
||||||
|
},
|
||||||
|
header = {
|
||||||
|
NameCrumbs(selected) { selected = it }
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
PropertyEditor(
|
||||||
|
scope = solids.context,
|
||||||
|
meta = vision.properties.root(),
|
||||||
|
getPropertyState = { name ->
|
||||||
|
if (vision.properties.own?.get(name) != null) {
|
||||||
|
EditorPropertyState.Defined
|
||||||
|
} else if (vision.properties.root()[name] != null) {
|
||||||
|
// TODO differentiate
|
||||||
|
EditorPropertyState.Default()
|
||||||
|
} else {
|
||||||
|
EditorPropertyState.Undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updates = vision.properties.changes,
|
||||||
|
rootDescriptor = vision.descriptor
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
vision.styles.takeIf { it.isNotEmpty() }?.let { styles ->
|
||||||
|
P {
|
||||||
|
B { Text("Styles: ") }
|
||||||
|
Text(styles.joinToString(separator = ", "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FlexColumn({
|
||||||
|
style {
|
||||||
|
paddingAll(4.px)
|
||||||
|
minWidth(400.px)
|
||||||
|
height(100.percent)
|
||||||
|
overflowY("auto")
|
||||||
|
flex(1, 10, 300.px)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
ThreeControls(solid, optionsSnapshot, selected, onSelect = { selected = it }, tabBuilder = sidebarTabs)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SimpleThreeView(solids.context, optionsSnapshot, solid, selected)
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +1,24 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
|
alias(spclibs.plugins.compose)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ktorVersion: String by rootProject.extra
|
val ktorVersion: String by rootProject.extra
|
||||||
|
|
||||||
kscience {
|
kscience {
|
||||||
fullStack("js/visionforge-three.js") {
|
fullStack("js/visionforge-three.js")
|
||||||
commonWebpackConfig {
|
|
||||||
cssSupport {
|
|
||||||
enabled.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
commonMain {
|
||||||
api(projects.visionforgeSolid)
|
api(projects.visionforgeSolid)
|
||||||
|
api(projects.visionforgeCompose)
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies(jvmMain) {
|
jvmMain{
|
||||||
api(projects.visionforgeServer)
|
api(projects.visionforgeServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies(jsMain) {
|
jsMain{
|
||||||
api(projects.visionforgeThreejs)
|
api(projects.visionforgeThreejs)
|
||||||
api(projects.ui.ring)
|
|
||||||
compileOnly(npm("webpack-bundle-analyzer","4.5.0"))
|
compileOnly(npm("webpack-bundle-analyzer","4.5.0"))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package space.kscience.visionforge.three
|
package space.kscience.visionforge.three
|
||||||
|
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
|
||||||
import space.kscience.visionforge.runVisionClient
|
import space.kscience.visionforge.runVisionClient
|
||||||
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
|
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
public fun main(): Unit = runVisionClient {
|
public fun main(): Unit = runVisionClient {
|
||||||
plugin(ThreeWithControlsPlugin)
|
plugin(ThreePlugin)
|
||||||
}
|
}
|
@ -1,23 +0,0 @@
|
|||||||
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
config.module.rules.push(...ringConfig.module.rules)
|
|
||||||
|
|
||||||
config.module.rules.push(
|
|
||||||
{
|
|
||||||
test: /\.css$/,
|
|
||||||
exclude: [
|
|
||||||
path.resolve(__dirname, "../../node_modules/@jetbrains/ring-ui")
|
|
||||||
],
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'style-loader',
|
|
||||||
options: {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
loader: 'css-loader',
|
|
||||||
options: {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
)
|
|
@ -1,10 +0,0 @@
|
|||||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
plugins: [
|
|
||||||
new BundleAnalyzerPlugin({
|
|
||||||
analyzerMode: "static",
|
|
||||||
reportFilename: "bundle-report.html"
|
|
||||||
})
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user