From f0db286ce645fbea36794b4927fc5992d9bc3e11 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 16 Feb 2024 18:21:09 +0300 Subject: [PATCH] Finalize refactor for 0.4 --- CHANGELOG.md | 15 +- README.md | 26 +- build.gradle.kts | 2 +- demo/compose-desktop-demo/README.md | 4 + .../api/compose-desktop-demo.api | 17 ++ demo/compose-desktop-demo/build.gradle.kts | 40 +++ .../src/jvmMain/kotlin/main.kt | 33 +++ .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 8 +- .../src/jsMain/kotlin/JsPlaygroundApp.kt | 8 +- demo/muon-monitor/api/muon-monitor.api | 9 + demo/muon-monitor/build.gradle.kts | 2 +- .../ru/mipt/npm/muon/monitor/MMDemoApp.kt | 4 +- demo/playground/api/playground.api | 5 + .../src/jsMain/kotlin/playgroundMain.kt | 2 +- .../visionforge/solid/demo/ThreeDemoApp.kt | 4 +- settings.gradle.kts | 3 +- visionforge-compose-html/build.gradle.kts | 7 +- .../html/ComposeHtmlVisionRenderer.kt | 1 - .../visionforge/html/PropertyEditor.kt | 7 +- .../kscience/visionforge/html/TreeStyles.kt | 22 -- .../visionforge/html/VisionForgeStyles.kt | 23 +- .../compose/ComposeVisionRenderer.kt | 15 - .../visionforge/compose/composeVision.kt | 24 -- visionforge-compose-multiplatform/README.md | 21 ++ .../build.gradle.kts | 17 +- .../compose/ComposeVisionClient.kt | 134 +++++++++ .../compose/ComposeVisionRenderer.kt | 47 +++ .../visionforge/compose/MetaViewer.kt | 69 +++++ .../visionforge/compose/PropertyEditor.kt | 174 +++++++++++ .../visionforge/compose/valueChooser.kt | 270 ++++++++++++++++++ visionforge-core/README.md | 4 +- visionforge-core/api/visionforge-core.api | 174 +++++------ .../space/kscience/visionforge/StyleSheet.kt | 2 +- .../kscience/visionforge/VisionManager.kt | 2 + .../kscience/visionforge/html/VisionOfHtml.kt | 16 +- .../visionforge/html/VisionTagConsumer.kt | 2 +- .../visionforge/meta/VisionPropertyTest.kt | 2 + .../visionforge/{ => html}/Application.kt | 4 +- .../{ => html}/ElementVisionRenderer.kt | 3 +- .../visionforge/{ => html}/JsVisionClient.kt | 37 +-- .../visionforge/{ => html}/formRenderers.kt | 5 +- .../visionforge/{ => html}/inputRenderers.kt | 13 +- .../space/kscience/visionforge/FormTest.kt | 1 + .../visionforge/meta/PropertyFlowTest.kt | 65 +++++ visionforge-gdml/README.md | 4 +- visionforge-jupyter/README.md | 4 +- .../src/jsMain/kotlin/VFNotebookClient.kt | 8 +- .../src/jsMain/kotlin/commonJupyter.kt | 2 +- visionforge-markdown/README.md | 4 +- .../visionforge/markup/MarkupPlugin.kt | 6 +- visionforge-plotly/README.md | 4 +- .../kscience/visionforge/plotly/plotlyJs.kt | 4 +- visionforge-server/README.md | 4 +- visionforge-solid/README.md | 4 +- visionforge-solid/api/visionforge-solid.api | 25 +- visionforge-solid/build.gradle.kts | 1 + .../visionforge/solid/SolidMaterial.kt | 2 + .../solid/specifications/Canvas3DOptions.kt | 2 + .../solid/specifications/Canvas3DUIScheme.kt | 8 +- visionforge-tables/README.md | 4 +- .../visionforge/tables/TableVisionJsPlugin.kt | 4 +- visionforge-threejs/README.md | 4 +- .../visionforge/solid/three/ThreePlugin.kt | 7 +- .../solid/three/compose/ThreeControls.kt | 2 - .../solid/three/compose/ThreeView.kt | 1 - .../visionforge-threejs-server/README.md | 4 +- .../build.gradle.kts | 1 + .../kscience/visionforge/three/jsMain.kt | 2 +- 68 files changed, 1175 insertions(+), 279 deletions(-) create mode 100644 demo/compose-desktop-demo/README.md create mode 100644 demo/compose-desktop-demo/api/compose-desktop-demo.api create mode 100644 demo/compose-desktop-demo/build.gradle.kts create mode 100644 demo/compose-desktop-demo/src/jvmMain/kotlin/main.kt delete mode 100644 visionforge-compose-mpp/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt delete mode 100644 visionforge-compose-mpp/src/commonMain/kotlin/space/kscience/visionforge/compose/composeVision.kt create mode 100644 visionforge-compose-multiplatform/README.md rename {visionforge-compose-mpp => visionforge-compose-multiplatform}/build.gradle.kts (62%) create mode 100644 visionforge-compose-multiplatform/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionClient.kt create mode 100644 visionforge-compose-multiplatform/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt create mode 100644 visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt create mode 100644 visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt create mode 100644 visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt rename visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/{ => html}/Application.kt (94%) rename visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/{ => html}/ElementVisionRenderer.kt (96%) rename visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/{ => html}/JsVisionClient.kt (98%) rename visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/{ => html}/formRenderers.kt (95%) rename visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/{ => html}/inputRenderers.kt (92%) create mode 100644 visionforge-core/src/jvmTest/kotlin/space/kscience/visionforge/meta/PropertyFlowTest.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index eaf7966f..9c2a4746 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,6 @@ ### Added ### Changed -- **Breaking API** Move vision cache to upper level for renderers to avoid re-creating visions for page reload. -- **Breaking API** Forms refactor ### Deprecated @@ -16,6 +14,19 @@ ### Security +## 0.4.0 - 2024-02-16 + +### Added + +- Added compose-mpp rendering. + +### Changed + +- **Breaking API** Move vision cache to upper level for renderers to avoid re-creating visions for page reload. +- **Breaking API** Forms refactor. +- **Breaking API** Migrated from React to Compose-html. +- **Breaking API** changed js package for `visionforge-core` to `space.kscience.visionforge.html` to avoid mixing html and generic parts. + ## 0.3.0 - 2023-12-23 ### Added diff --git a/README.md b/README.md index f8fb04fe..b75dcb55 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,11 @@ To learn more about DataForge, please consult the following URLs: > > **Maturity**: EXPERIMENTAL -### [ui](ui) +### [visionforge-compose-html](visionforge-compose-html) +> +> **Maturity**: EXPERIMENTAL + +### [visionforge-compose-multiplatform](visionforge-compose-multiplatform) > > **Maturity**: EXPERIMENTAL @@ -111,6 +115,10 @@ To learn more about DataForge, please consult the following URLs: > > **Maturity**: EXPERIMENTAL +### [demo/compose-desktop-demo](demo/compose-desktop-demo) +> +> **Maturity**: EXPERIMENTAL + ### [demo/gdml](demo/gdml) > > **Maturity**: EXPERIMENTAL @@ -135,22 +143,6 @@ To learn more about DataForge, please consult the following URLs: > > **Maturity**: EXPERIMENTAL -### [ui/bootstrap](ui/bootstrap) -> -> **Maturity**: EXPERIMENTAL - -### [ui/compose](ui/compose) -> -> **Maturity**: EXPERIMENTAL - -### [ui/react](ui/react) -> -> **Maturity**: EXPERIMENTAL - -### [ui/ring](ui/ring) -> -> **Maturity**: EXPERIMENTAL - ### [visionforge-jupyter/visionforge-jupyter-common](visionforge-jupyter/visionforge-jupyter-common) > Jupyter api artifact including all common modules > diff --git a/build.gradle.kts b/build.gradle.kts index debd7323..335299c2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ val dataforgeVersion by extra("0.8.0") allprojects { group = "space.kscience" - version = "0.4.0-dev-3" + version = "0.4.0" } subprojects { diff --git a/demo/compose-desktop-demo/README.md b/demo/compose-desktop-demo/README.md new file mode 100644 index 00000000..591acad6 --- /dev/null +++ b/demo/compose-desktop-demo/README.md @@ -0,0 +1,4 @@ +# Module compose-desktop-demo + + + diff --git a/demo/compose-desktop-demo/api/compose-desktop-demo.api b/demo/compose-desktop-demo/api/compose-desktop-demo.api new file mode 100644 index 00000000..7a968e47 --- /dev/null +++ b/demo/compose-desktop-demo/api/compose-desktop-demo.api @@ -0,0 +1,17 @@ +public final class ComposableSingletons$MainKt { + public static final field INSTANCE LComposableSingletons$MainKt; + public static field lambda-1 Lkotlin/jvm/functions/Function2; + public static field lambda-2 Lkotlin/jvm/functions/Function3; + public static field lambda-3 Lkotlin/jvm/functions/Function3; + public fun ()V + public final fun getLambda-1$compose_desktop_demo ()Lkotlin/jvm/functions/Function2; + public final fun getLambda-2$compose_desktop_demo ()Lkotlin/jvm/functions/Function3; + public final fun getLambda-3$compose_desktop_demo ()Lkotlin/jvm/functions/Function3; +} + +public final class MainKt { + public static final fun App (Landroidx/compose/runtime/Composer;I)V + public static final fun main ()V + public static synthetic fun main ([Ljava/lang/String;)V +} + diff --git a/demo/compose-desktop-demo/build.gradle.kts b/demo/compose-desktop-demo/build.gradle.kts new file mode 100644 index 00000000..ff6bc292 --- /dev/null +++ b/demo/compose-desktop-demo/build.gradle.kts @@ -0,0 +1,40 @@ +plugins { + id("space.kscience.gradle.mpp") + alias(spclibs.plugins.compose) +} + +kscience { + jvm() + useCoroutines() + + commonMain{ + implementation(projects.visionforgeSolid) + } + + jvmMain { + implementation(projects.visionforgeComposeMultiplatform) + } +} + +kotlin{ + explicitApi = null + sourceSets{ + commonMain{ + dependencies { + implementation(compose.desktop.currentOs) + api(compose.preview) + } + } + } +} + + +compose{ + desktop{ + desktop { + application { + mainClass = "MainKt" + } + } + } +} \ No newline at end of file diff --git a/demo/compose-desktop-demo/src/jvmMain/kotlin/main.kt b/demo/compose-desktop-demo/src/jvmMain/kotlin/main.kt new file mode 100644 index 00000000..c9a1b8d6 --- /dev/null +++ b/demo/compose-desktop-demo/src/jvmMain/kotlin/main.kt @@ -0,0 +1,33 @@ +import androidx.compose.desktop.ui.tooling.preview.Preview +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application +import space.kscience.dataforge.meta.set +import space.kscience.visionforge.compose.PropertyEditor +import space.kscience.visionforge.solid.specifications.Canvas3DOptions + +@Composable +@Preview +fun App(){ + val options = remember { + Canvas3DOptions{ + meta["custom.field"] = 32 + } + } + PropertyEditor( + properties = options.meta, + descriptor = Canvas3DOptions.descriptor, + expanded = true + ) +} + + +fun main() = application { + Window(onCloseRequest = ::exitApplication) { + MaterialTheme { + App() + } + } +} diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index 5add1d6f..3f4d775c 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -6,14 +6,14 @@ import org.jetbrains.compose.web.renderComposable import org.w3c.dom.Document import space.kscience.dataforge.context.Context import space.kscience.gdml.GdmlShowCase -import space.kscience.visionforge.Application import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.html.TreeStyles +import space.kscience.visionforge.html.Application +import space.kscience.visionforge.html.VisionForgeStyles +import space.kscience.visionforge.html.startApplication import space.kscience.visionforge.solid.ambientLight import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.three.ThreePlugin -import space.kscience.visionforge.startApplication private class GDMLDemoApp : Application { @@ -33,7 +33,7 @@ private class GDMLDemoApp : Application { } renderComposable(element) { - Style(TreeStyles) + Style(VisionForgeStyles) Style { "html" { height(100.percent) diff --git a/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt index 71de963a..b544b17a 100644 --- a/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt @@ -5,16 +5,16 @@ import org.w3c.dom.Document import space.kscience.dataforge.context.Context import space.kscience.plotly.models.Trace import space.kscience.plotly.scatter -import space.kscience.visionforge.Application import space.kscience.visionforge.Colors +import space.kscience.visionforge.html.Application import space.kscience.visionforge.html.Tabs -import space.kscience.visionforge.html.TreeStyles +import space.kscience.visionforge.html.VisionForgeStyles +import space.kscience.visionforge.html.startApplication import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin 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 kotlin.random.Random fun Trace.appendXYLatest(x: Number, y: Number, history: Int = 400, xErr: Number? = null, yErr: Number? = null) { @@ -40,7 +40,7 @@ private class JsPlaygroundApp : Application { val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page") renderComposable(element) { - Style(TreeStyles) + Style(VisionForgeStyles) Div({ style { padding(0.pt) diff --git a/demo/muon-monitor/api/muon-monitor.api b/demo/muon-monitor/api/muon-monitor.api index c0b6c4d8..24b6218c 100644 --- a/demo/muon-monitor/api/muon-monitor.api +++ b/demo/muon-monitor/api/muon-monitor.api @@ -1,4 +1,5 @@ public final class ru/mipt/npm/muon/monitor/Event { + public static final field $stable I public static final field Companion Lru/mipt/npm/muon/monitor/Event$Companion; public fun (ILjava/util/List;Ljava/util/Collection;)V public final fun component1 ()I @@ -15,6 +16,7 @@ public final class ru/mipt/npm/muon/monitor/Event { } public final class ru/mipt/npm/muon/monitor/Event$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field $stable I public static final field INSTANCE Lru/mipt/npm/muon/monitor/Event$$serializer; public fun childSerializers ()[Lkotlinx/serialization/KSerializer; public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; @@ -30,6 +32,7 @@ public final class ru/mipt/npm/muon/monitor/Event$Companion { } public final class ru/mipt/npm/muon/monitor/Model { + public static final field $stable I public fun (Lspace/kscience/visionforge/VisionManager;)V public final fun displayEvent (Lru/mipt/npm/muon/monitor/Event;)V public final fun encodeToString ()Ljava/lang/String; @@ -40,6 +43,7 @@ public final class ru/mipt/npm/muon/monitor/Model { } public final class ru/mipt/npm/muon/monitor/Monitor { + public static final field $stable I public static final field CENTRAL_LAYER_Z F public static final field GEOMETRY_TOLERANCE D public static final field INSTANCE Lru/mipt/npm/muon/monitor/Monitor; @@ -57,6 +61,7 @@ public final class ru/mipt/npm/muon/monitor/ReadResourceKt { } public final class ru/mipt/npm/muon/monitor/SC1 { + public static final field $stable I public fun (Ljava/lang/String;Lspace/kscience/visionforge/solid/Float32Vector3D;FFF)V public synthetic fun (Ljava/lang/String;Lspace/kscience/visionforge/solid/Float32Vector3D;FFFILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getCenter ()Lspace/kscience/visionforge/solid/Float32Vector3D; @@ -67,6 +72,7 @@ public final class ru/mipt/npm/muon/monitor/SC1 { } public final class ru/mipt/npm/muon/monitor/SC16 { + public static final field $stable I public fun (Ljava/lang/String;Lspace/kscience/visionforge/solid/Float32Vector3D;)V public final fun getCenter ()Lspace/kscience/visionforge/solid/Float32Vector3D; public final fun getName ()Ljava/lang/String; @@ -81,6 +87,7 @@ public final class ru/mipt/npm/muon/monitor/server/MMServerKt { } public final class ru/mipt/npm/muon/monitor/sim/Cos2TrackGenerator : ru/mipt/npm/muon/monitor/sim/TrackGenerator { + public static final field $stable I public fun (Lorg/apache/commons/math3/random/RandomGenerator;DFF)V public synthetic fun (Lorg/apache/commons/math3/random/RandomGenerator;DFFILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun generate ()Lorg/apache/commons/math3/geometry/euclidean/threed/Line; @@ -91,6 +98,7 @@ public final class ru/mipt/npm/muon/monitor/sim/Cos2TrackGenerator : ru/mipt/npm } public final class ru/mipt/npm/muon/monitor/sim/FixedAngleGenerator : ru/mipt/npm/muon/monitor/sim/TrackGenerator { + public static final field $stable I public fun (Lorg/apache/commons/math3/random/RandomGenerator;DDFF)V public synthetic fun (Lorg/apache/commons/math3/random/RandomGenerator;DDFFILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun generate ()Lorg/apache/commons/math3/geometry/euclidean/threed/Line; @@ -134,6 +142,7 @@ public abstract interface class ru/mipt/npm/muon/monitor/sim/TrackGenerator { } public final class ru/mipt/npm/muon/monitor/sim/UniformTrackGenerator : ru/mipt/npm/muon/monitor/sim/TrackGenerator { + public static final field $stable I public fun (Lorg/apache/commons/math3/random/RandomGenerator;FF)V public synthetic fun (Lorg/apache/commons/math3/random/RandomGenerator;FFILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun generate ()Lorg/apache/commons/math3/geometry/euclidean/threed/Line; diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index 66673306..3893e40e 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -30,6 +30,7 @@ kscience { commonMain { implementation(projects.visionforgeSolid) + implementation(projects.visionforgeComposeHtml) } jvmMain { implementation("org.apache.commons:commons-math3:3.6.1") @@ -39,7 +40,6 @@ kscience { implementation("ch.qos.logback:logback-classic:1.2.11") } jsMain { -// implementation(projects.visionforgeComposeHtml) implementation(projects.visionforgeThreejs) //implementation(devNpm("webpack-bundle-analyzer", "4.4.0")) } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index d117d91d..bf985b4c 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -5,11 +5,11 @@ import org.jetbrains.compose.web.renderComposable import org.w3c.dom.Document import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.request -import space.kscience.visionforge.Application import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.html.Application import space.kscience.visionforge.html.VisionForgeStyles +import space.kscience.visionforge.html.startApplication import space.kscience.visionforge.solid.three.ThreePlugin -import space.kscience.visionforge.startApplication private class MMDemoApp : Application { diff --git a/demo/playground/api/playground.api b/demo/playground/api/playground.api index ca5e1cc5..45992241 100644 --- a/demo/playground/api/playground.api +++ b/demo/playground/api/playground.api @@ -53,6 +53,11 @@ public final class space/kscience/visionforge/examples/GenerateSchemaKt { public static synthetic fun main ([Ljava/lang/String;)V } +public final class space/kscience/visionforge/examples/MarkdownVisionKt { + public static final fun main ()V + public static synthetic fun main ([Ljava/lang/String;)V +} + public final class space/kscience/visionforge/examples/PlotlyVisionKt { public static final fun main ()V public static synthetic fun main ([Ljava/lang/String;)V diff --git a/demo/playground/src/jsMain/kotlin/playgroundMain.kt b/demo/playground/src/jsMain/kotlin/playgroundMain.kt index 32a518ba..1ae93b7f 100644 --- a/demo/playground/src/jsMain/kotlin/playgroundMain.kt +++ b/demo/playground/src/jsMain/kotlin/playgroundMain.kt @@ -1,8 +1,8 @@ import space.kscience.dataforge.misc.DFExperimental +import space.kscience.visionforge.html.runVisionClient import space.kscience.visionforge.jupyter.VFNotebookClient import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin -import space.kscience.visionforge.runVisionClient import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.tables.TableVisionJsPlugin diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt index 5bdbcefe..5be57d31 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt @@ -4,10 +4,10 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import org.w3c.dom.Document -import space.kscience.visionforge.Application +import space.kscience.visionforge.html.Application +import space.kscience.visionforge.html.startApplication import space.kscience.visionforge.solid.x import space.kscience.visionforge.solid.y -import space.kscience.visionforge.startApplication import kotlin.random.Random private class ThreeDemoApp : Application { diff --git a/settings.gradle.kts b/settings.gradle.kts index 8f4e56b3..d8cf13ae 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -42,7 +42,7 @@ dependencyResolutionManagement { include( ":visionforge-core", ":visionforge-compose-html", - ":visionforge-compose-mpp", + ":visionforge-compose-multiplatform", ":visionforge-solid", // ":visionforge-fx", ":visionforge-threejs", @@ -60,6 +60,7 @@ include( ":demo:playground", // ":demo:plotly-fx", ":demo:js-playground", + ":demo:compose-desktop-demo", ":visionforge-jupyter", ":visionforge-jupyter:visionforge-jupyter-common" ) diff --git a/visionforge-compose-html/build.gradle.kts b/visionforge-compose-html/build.gradle.kts index efcad990..d3f5d754 100644 --- a/visionforge-compose-html/build.gradle.kts +++ b/visionforge-compose-html/build.gradle.kts @@ -14,11 +14,7 @@ kotlin { commonMain { dependencies { api(projects.visionforgeCore) - } - } - jvmMain{ - //need this to placate compose compiler in MPP applications - dependencies{ + //need this to placate compose compiler in MPP applications api(compose.runtime) } } @@ -28,7 +24,6 @@ kotlin { api("app.softwork:bootstrap-compose:0.1.15") api("app.softwork:bootstrap-compose-icons:0.1.15") - api(compose.runtime) api(compose.html.core) } } diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/ComposeHtmlVisionRenderer.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/ComposeHtmlVisionRenderer.kt index f2b6db2f..5a54292d 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/ComposeHtmlVisionRenderer.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/ComposeHtmlVisionRenderer.kt @@ -7,7 +7,6 @@ import org.jetbrains.compose.web.renderComposable import org.w3c.dom.Element import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.Name -import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision /** diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/PropertyEditor.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/PropertyEditor.kt index cfea11e0..04329625 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/PropertyEditor.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/PropertyEditor.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.html import androidx.compose.runtime.* import app.softwork.bootstrapcompose.CloseButton -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow @@ -39,7 +38,6 @@ public sealed class EditorPropertyState { */ @Composable public fun PropertyEditor( - scope: CoroutineScope, rootMeta: MutableMeta, getPropertyState: (Name) -> EditorPropertyState, updates: Flow, @@ -136,7 +134,7 @@ public fun PropertyEditor( Div({ classes(TreeStyles.treeItem) }) { - PropertyEditor(scope, rootMeta, getPropertyState, updates, name + token, rootDescriptor, expanded) + PropertyEditor(rootMeta, getPropertyState, updates, name + token, rootDescriptor, expanded) } } } @@ -145,13 +143,12 @@ public fun PropertyEditor( @Composable public fun PropertyEditor( - scope: CoroutineScope, properties: ObservableMutableMeta, descriptor: MetaDescriptor? = null, expanded: Boolean? = null, ) { + val scope = rememberCoroutineScope() PropertyEditor( - scope = scope, rootMeta = properties, getPropertyState = { name -> if (properties[name] != null) { diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/TreeStyles.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/TreeStyles.kt index d9469dff..4d8406ad 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/TreeStyles.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/TreeStyles.kt @@ -67,26 +67,4 @@ public object TreeStyles : StyleSheet(VisionForgeStyles) { public val treeLabelSelected: String by style { backgroundColor(Color.lightblue) } - - public val propertyEditorButton: String by style { - width(24.px) - alignSelf(AlignSelf.Stretch) - marginAll(1.px, 5.px) - backgroundColor(Color.white) - border { - style(LineStyle.Solid) - } - borderRadius(2.px) - textAlign("center") - textDecoration("none") - cursor("pointer") - (self + disabled) { - cursor("auto") - border { - style(LineStyle.Dashed) - } - color(Color.lightgray) - } - } - } \ No newline at end of file diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionForgeStyles.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionForgeStyles.kt index 82a3a608..311f41b2 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionForgeStyles.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionForgeStyles.kt @@ -1,7 +1,28 @@ package space.kscience.visionforge.html -import org.jetbrains.compose.web.css.StyleSheet +import org.jetbrains.compose.web.css.* public object VisionForgeStyles: StyleSheet() { + public val propertyEditorButton: String by style { + width(24.px) + alignSelf(AlignSelf.Stretch) + marginAll(1.px, 5.px) + backgroundColor(Color.white) + border { + style(LineStyle.Solid) + } + borderRadius(2.px) + textAlign("center") + textDecoration("none") + cursor("pointer") + (self + disabled) { + cursor("auto") + border { + style(LineStyle.Dashed) + } + color(Color.lightgray) + } + } + } \ No newline at end of file diff --git a/visionforge-compose-mpp/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt b/visionforge-compose-mpp/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt deleted file mode 100644 index 81450070..00000000 --- a/visionforge-compose-mpp/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt +++ /dev/null @@ -1,15 +0,0 @@ -package space.kscience.visionforge.compose - -import androidx.compose.runtime.Composable -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.names.Name -import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionClient - -public interface ComposeVisionRenderer { - public fun rateVision(vision: Vision): Int - @Composable - public fun render(client: VisionClient, name: Name, vision: Vision, meta: Meta) - - public companion object -} \ No newline at end of file diff --git a/visionforge-compose-mpp/src/commonMain/kotlin/space/kscience/visionforge/compose/composeVision.kt b/visionforge-compose-mpp/src/commonMain/kotlin/space/kscience/visionforge/compose/composeVision.kt deleted file mode 100644 index 2a7d3d97..00000000 --- a/visionforge-compose-mpp/src/commonMain/kotlin/space/kscience/visionforge/compose/composeVision.kt +++ /dev/null @@ -1,24 +0,0 @@ -package space.kscience.visionforge.compose - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.visionforge.Vision - - -/** - * Render an Element vision via injected vision renderer inside compose-html - */ -@Composable -public fun Vision( - context: Context, - vision: Vision, - name: Name = "@vision[${vision.hashCode().toString(16)}]".asName(), - meta: Meta = Meta.EMPTY, - modifier: Modifier = Modifier, -) { - -} diff --git a/visionforge-compose-multiplatform/README.md b/visionforge-compose-multiplatform/README.md new file mode 100644 index 00000000..0ba9ae3c --- /dev/null +++ b/visionforge-compose-multiplatform/README.md @@ -0,0 +1,21 @@ +# Module visionforge-compose-multiplatform + + + +## Usage + +## Artifact: + +The Maven coordinates of this project are `space.kscience:visionforge-compose-multiplatform:0.4.0-dev-3`. + +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + mavenCentral() +} + +dependencies { + implementation("space.kscience:visionforge-compose-multiplatform:0.4.0-dev-3") +} +``` diff --git a/visionforge-compose-mpp/build.gradle.kts b/visionforge-compose-multiplatform/build.gradle.kts similarity index 62% rename from visionforge-compose-mpp/build.gradle.kts rename to visionforge-compose-multiplatform/build.gradle.kts index e4a447cd..b3175b38 100644 --- a/visionforge-compose-mpp/build.gradle.kts +++ b/visionforge-compose-multiplatform/build.gradle.kts @@ -1,3 +1,5 @@ +import space.kscience.gradle.Maturity + plugins { id("space.kscience.gradle.mpp") alias(spclibs.plugins.compose) @@ -14,15 +16,20 @@ kotlin { commonMain { dependencies { api(projects.visionforgeCore) - api(compose.runtime) api(compose.foundation) + api(compose.runtime) + api(compose.material) + api(compose.materialIconsExtended) } } - jvmMain{ - dependencies{ - api(compose.material) - api(compose.preview) + jvmMain { + dependencies { + implementation("com.eygraber:compose-color-picker:0.0.17") } } } +} + +readme { + maturity = Maturity.EXPERIMENTAL } \ No newline at end of file diff --git a/visionforge-compose-multiplatform/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionClient.kt b/visionforge-compose-multiplatform/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionClient.kt new file mode 100644 index 00000000..29bca480 --- /dev/null +++ b/visionforge-compose-multiplatform/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionClient.kt @@ -0,0 +1,134 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.key +import androidx.compose.runtime.remember +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import space.kscience.dataforge.context.* +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.asName +import space.kscience.visionforge.* +import space.kscience.visionforge.html.VisionOutput +import space.kscience.visionforge.html.VisionTagConsumer + +/** + * A Kotlin-browser plugin that renders visions based on provided renderers and governs communication with the server. + */ +public class ComposeVisionClient : AbstractPlugin(), VisionClient { + override val tag: PluginTag get() = Companion.tag + override val visionManager: VisionManager by require(VisionManager) + + + private val renderers by lazy { context.gather(ComposeVisionRenderer.TYPE).values } + + private fun findRendererFor(vision: Vision): ComposeVisionRenderer? = renderers.mapNotNull { + val rating = it.rateVision(vision) + if (rating > 0) { + rating to it + } else { + null + } + }.maxByOrNull { it.first }?.second + + + private val mutex = Mutex() + + + private val rootChangeCollector = VisionChangeBuilder() + + /** + * Communicate vision property changed from rendering engine to model + */ + override fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { + context.launch { + mutex.withLock { + rootChangeCollector.propertyChanged(visionName, propertyName, item) + } + } + } + + private val eventCollector = MutableSharedFlow>(meta["feedback.eventCache"].int ?: 100) + + /** + * Send a custom feedback event + */ + override suspend fun sendEvent(targetName: Name, event: VisionEvent) { + eventCollector.emit(targetName to event) + } + + @Composable + public fun renderVision(name: Name, vision: Vision, outputMeta: Meta) { + val renderer: ComposeVisionRenderer = remember(vision) { + findRendererFor(vision) ?: error("Could not find renderer for ${vision::class}") + } + + key(vision) { + vision.setAsRoot(visionManager) + } + //subscribe to a backwards events propagation for control visions + if (vision is ControlVision) { + LaunchedEffect(vision) { + vision.controlEventFlow.collect { + sendEvent(name, it) + } + } + } + + renderer.render(name, vision, outputMeta) + } + + +// override fun content(target: String): Map = if (target == ComposeVisionRenderer.TYPE) { +// listOf( +// htmlVisionRenderer, +// inputVisionRenderer, +// checkboxVisionRenderer, +// numberVisionRenderer, +// textVisionRenderer, +// rangeVisionRenderer, +// formVisionRenderer, +// buttonVisionRenderer +// ).associateBy { it.toString().asName() } +// } else super.content(target) + + public companion object : PluginFactory { + override fun build(context: Context, meta: Meta): ComposeVisionClient = ComposeVisionClient() + + override val tag: PluginTag = PluginTag(name = "vision.client.compose", group = PluginTag.DATAFORGE_GROUP) + } +} + +/** + * Render an Element vision via injected vision renderer inside compose-html + */ +@Composable +public fun Vision( + context: Context, + vision: Vision, + name: Name? = null, + meta: Meta = Meta.EMPTY, +) { + val actualName = name ?: NameToken(VisionTagConsumer.DEFAULT_VISION_NAME, vision.hashCode().toUInt().toString()).asName() + context.request(ComposeVisionClient).renderVision(actualName, vision, meta) +} + +@Composable +public fun Vision( + context: Context, + name: Name? = null, + meta: Meta = Meta.EMPTY, + buildOutput: VisionOutput.() -> Vision, +) { + val actualName = name ?: NameToken(VisionTagConsumer.DEFAULT_VISION_NAME, buildOutput.hashCode().toUInt().toString()).asName() + val output = VisionOutput(context, actualName) + val vision = output.buildOutput() + context.request(ComposeVisionClient).renderVision(actualName, vision, meta) +} \ No newline at end of file diff --git a/visionforge-compose-multiplatform/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt b/visionforge-compose-multiplatform/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt new file mode 100644 index 00000000..a7abee3f --- /dev/null +++ b/visionforge-compose-multiplatform/src/commonMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt @@ -0,0 +1,47 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.misc.DfType +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Vision +import kotlin.reflect.KClass +import kotlin.reflect.cast + +@DfType(ComposeVisionRenderer.TYPE) +public interface ComposeVisionRenderer { + public fun rateVision(vision: Vision): Int + + @Composable + public fun render(name: Name, vision: Vision, meta: Meta) + + public companion object { + public const val TYPE: String = "composeVisionRenderer" + public const val ZERO_RATING: Int = 0 + public const val DEFAULT_RATING: Int = 10 + } +} + +public class SingleTypeComposeRenderer( + public val kClass: KClass, + private val acceptRating: Int = ComposeVisionRenderer.DEFAULT_RATING, + private val renderFunction: @Composable (name: Name, vision: T, meta: Meta) -> Unit, +) : ComposeVisionRenderer { + + override fun rateVision(vision: Vision): Int = + if (vision::class == kClass) acceptRating else ComposeVisionRenderer.ZERO_RATING + + @Composable + override fun render( + name: Name, + vision: Vision, + meta: Meta, + ) { + renderFunction(name, kClass.cast(vision), meta) + } +} + +public inline fun ComposeVisionRenderer( + acceptRating: Int = ComposeVisionRenderer.DEFAULT_RATING, + noinline renderFunction: @Composable (name: Name, vision: T, meta: Meta) -> Unit, +): ComposeVisionRenderer = SingleTypeComposeRenderer(T::class, acceptRating, renderFunction) diff --git a/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt b/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt new file mode 100644 index 00000000..d6578c73 --- /dev/null +++ b/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt @@ -0,0 +1,69 @@ +package space.kscience.visionforge.compose + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ExpandLess +import androidx.compose.material.icons.filled.ExpandMore +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.isLeaf +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.lastOrNull +import space.kscience.dataforge.names.plus + + +@Composable +private fun MetaViewerItem(root: Meta, name: Name, rootDescriptor: MetaDescriptor? = null) { + var expanded: Boolean by remember { mutableStateOf(true) } + val item: Meta? = root[name] + val descriptorItem: MetaDescriptor? = rootDescriptor?.get(name) + val actualValue = item?.value ?: descriptorItem?.defaultValue + val actualMeta = item ?: descriptorItem?.defaultNode + + val token = name.lastOrNull()?.toString() ?: "" + + Row(modifier = Modifier.fillMaxWidth()) { + if (actualMeta?.isLeaf == false) { + TextButton({ expanded = !expanded }) { + if (expanded) { + Icon(Icons.Filled.ExpandLess, "collapse") + } else { + Icon(Icons.Filled.ExpandMore, "expand") + } + } + } + Text(token, color = if (item == null) Color.Gray else Color.Unspecified) + Spacer(Modifier.weight(1f)) + Text(actualValue.toString()) + } + if (expanded) { + Column { + val keys = buildSet { + descriptorItem?.nodes?.keys?.forEach { + add(NameToken(it)) + } + actualMeta!!.items.keys.let { addAll(it) } + } + + keys.filter { !it.body.startsWith("@") }.forEach { token -> + MetaViewerItem(root, name + token, rootDescriptor) + } + } + } +} + +@Composable +public fun MetaViewer(meta: Meta, descriptor: MetaDescriptor? = null) { + MetaViewerItem(meta, Name.EMPTY, descriptor) +} diff --git a/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt b/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt new file mode 100644 index 00000000..f2088c61 --- /dev/null +++ b/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt @@ -0,0 +1,174 @@ +package space.kscience.visionforge.compose + +import androidx.compose.foundation.layout.* +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Clear +import androidx.compose.material.icons.filled.ExpandLess +import androidx.compose.material.icons.filled.ExpandMore +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.launch +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.ObservableMutableMeta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.ValueRestriction +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.remove +import space.kscience.dataforge.names.* +import space.kscience.visionforge.hidden + + +/** + * The display state of a property + */ +public sealed class EditorPropertyState { + public data object Defined : EditorPropertyState() + public data class Default(public val source: String = "unknown") : EditorPropertyState() + public data object Undefined : EditorPropertyState() +} + +/** + * @param rootMeta Root config object - always non-null + * @param rootDescriptor Full path to the displayed node in [rootMeta]. Could be empty + */ +@Composable +public fun PropertyEditor( + rootMeta: MutableMeta, + getPropertyState: (Name) -> EditorPropertyState, + updates: Flow, + name: Name, + rootDescriptor: MetaDescriptor?, + initialExpanded: Boolean? = null, +) { + var expanded: Boolean by remember { mutableStateOf(initialExpanded ?: true) } + val descriptor: MetaDescriptor? by derivedStateOf { rootDescriptor?.get(name) } + var displayedValue by remember { mutableStateOf(rootMeta.getValue(name)) } + var editorPropertyState: EditorPropertyState by remember { mutableStateOf(getPropertyState(name)) } + + fun buildKeys() = buildSet { + descriptor?.nodes?.filterNot { + it.key.startsWith("@") || it.value.hidden + }?.forEach { + add(NameToken(it.key)) + } + rootMeta[name]?.items?.keys?.filterNot { it.body.startsWith("@") }?.let { addAll(it) } + } + + var keys by remember { mutableStateOf(buildKeys()) } + + val token = name.lastOrNull()?.toString() ?: "Properties" + + fun update() { + displayedValue = rootMeta.getValue(name) + editorPropertyState = getPropertyState(name) + keys = buildKeys() + } + + LaunchedEffect(rootMeta) { + updates.collect { updatedName -> + if (name.startsWith(updatedName)) { + update() + } + } + } + Column(modifier = Modifier.fillMaxWidth().padding(start = 20.dp)) { + Row(modifier = Modifier.fillMaxWidth().padding(start = 20.dp)) { + //if node has children + if (keys.isNotEmpty()) { + TextButton( + { expanded = !expanded }, + modifier = Modifier.align(Alignment.CenterVertically).width(40.dp) + ) { + if (expanded) { + Icon(Icons.Filled.ExpandLess, "collapse") + } else { + Icon(Icons.Filled.ExpandMore, "expand") + } + } + } + Text( + token, + color = when (editorPropertyState) { + is EditorPropertyState.Default, EditorPropertyState.Undefined -> Color.Gray + else -> Color.Unspecified + }, + modifier = Modifier.align(Alignment.CenterVertically) + ) + Spacer(modifier = Modifier.weight(1f)) + + if (!name.isEmpty() && descriptor?.valueRestriction != ValueRestriction.ABSENT) { + Box(modifier = Modifier.padding(1.dp, 5.dp).width(160.dp)) { + ValueChooser(descriptor, editorPropertyState, displayedValue) { + rootMeta.setValue(name, it) + update() + } + } + + } + if (!name.isEmpty()) { + TextButton( + onClick = { + rootMeta.remove(name) + update() + }, + enabled = editorPropertyState == EditorPropertyState.Defined, + modifier = Modifier.align(Alignment.CenterVertically).width(50.dp) + ) { + if (editorPropertyState == EditorPropertyState.Defined) { + Icon(Icons.Filled.Clear, "Reset") + } + } + } + } + if (expanded) { + Column(modifier = Modifier.fillMaxWidth()) { + keys.forEach { token -> + PropertyEditor(rootMeta, getPropertyState, updates, name + token, rootDescriptor, expanded) + } + } + } + } +} + + +@Composable +public fun PropertyEditor( + properties: ObservableMutableMeta, + descriptor: MetaDescriptor? = null, + expanded: Boolean? = null, +) { + val scope = rememberCoroutineScope() + PropertyEditor( + rootMeta = properties, + getPropertyState = { name -> + if (properties[name] != null) { + EditorPropertyState.Defined + } else if (descriptor?.get(name)?.defaultValue != null) { + EditorPropertyState.Default("descriptor") + } else { + EditorPropertyState.Undefined + } + }, + updates = callbackFlow { + properties.onChange(scope) { name -> + scope.launch { + send(name) + } + } + + awaitClose { properties.removeListener(scope) } + }, + name = Name.EMPTY, + rootDescriptor = descriptor, + initialExpanded = expanded, + ) +} \ No newline at end of file diff --git a/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt b/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt new file mode 100644 index 00000000..cfecc54e --- /dev/null +++ b/visionforge-compose-multiplatform/src/jvmMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt @@ -0,0 +1,270 @@ +@file:Suppress("UNUSED_PARAMETER") + +package space.kscience.visionforge.compose + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.CheckBox +import androidx.compose.material.icons.filled.CheckBoxOutlineBlank +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.isSpecified +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.text.input.KeyboardType +import com.eygraber.compose.colorpicker.ColorPicker +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.allowedValues +import space.kscience.visionforge.widgetType +import kotlin.math.roundToInt + + +@Composable +public fun StringValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var stringValue by remember(value, descriptor) { mutableStateOf(value?.string ?: "") } + TextField( + value = stringValue, + onValueChange = { + stringValue = it + onValueChange(it.asValue()) + }, + modifier = Modifier.fillMaxWidth() + ) +} + + +@Composable +public fun BooleanValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var innerValue by remember(value, descriptor) { + mutableStateOf( + value?.boolean ?: descriptor?.defaultValue?.boolean ?: false + ) + } + + Button( + onClick = { + innerValue = !innerValue + onValueChange(innerValue.asValue()) + }, + colors = if (innerValue) ButtonDefaults.buttonColors(Color.Green) else ButtonDefaults.buttonColors(Color.Gray) + ) { + if (innerValue) { + Text("On") + } else { + Text("Off") + } + } +} + +@Composable +public fun NumberValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var stringValue by remember(value, descriptor) { mutableStateOf(value?.string ?: descriptor?.defaultValue?.string) } + + TextField( + value = stringValue ?: "", + onValueChange = { newValue -> + stringValue = newValue + newValue.toDoubleOrNull()?.let { onValueChange(it.asValue()) } + }, + isError = stringValue?.toDoubleOrNull() != null, + modifier = Modifier.fillMaxWidth(), + keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number) + ) +} + + +@OptIn(ExperimentalMaterialApi::class) +@Composable +public fun ComboValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var expanded by remember { mutableStateOf(false) } + var selected by remember(value, descriptor) { mutableStateOf(value?.string ?: "") } + + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { + expanded = !expanded + }, + modifier = Modifier.fillMaxWidth() + ) { + TextField( + value = selected, + onValueChange = {}, + readOnly = true, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, + ) + + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false } + ) { + descriptor?.allowedValues?.forEach { item: Value -> + DropdownMenuItem( + onClick = { + selected = item.string + expanded = false + onValueChange(selected.asValue()) + } + ) { + Text(item.string) + } + } + } + } +} + + +@Composable +public fun ColorValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + //var innerValue by remember { mutableStateOf(value ?: descriptor?.defaultValue) } + + Box(Modifier.fillMaxWidth()) { + ColorPicker(Modifier.fillMaxWidth()) { + if (it.isSpecified) { + onValueChange(it.toArgb().asValue()) + } + } + } +} + + +@OptIn(ExperimentalMaterialApi::class) +@Composable +public fun MultiSelectChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var expanded by remember { mutableStateOf(false) } + var selected: Set by remember(value) { + mutableStateOf(value?.list?.toSet() ?: emptySet()) + } + + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { + expanded = !expanded + }, + modifier = Modifier.fillMaxWidth() + ) { + TextField( + value = selected.joinToString(prefix = "[", postfix = "]"), + onValueChange = {}, + readOnly = true, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, + ) + + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false } + ) { + descriptor?.allowedValues?.forEach { item: Value -> + val currentlySelected = item in selected + + DropdownMenuItem( + onClick = { + selected = if (currentlySelected) { + selected - item + } else { + selected + item + } + onValueChange(selected.asValue()) + } + ) { + if (currentlySelected) { + Icon(Icons.Default.CheckBox, "checked") + } else { + Icon(Icons.Default.CheckBoxOutlineBlank, "checked") + } + Text(item.string) + } + } + } + } +} + + +@Composable +public fun RangeValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var innerValue by remember(value, descriptor) { mutableStateOf(value?.number ?: descriptor?.defaultValue?.number) } + val min by derivedStateOf { + descriptor?.attributes?.get("min").float ?: 0f + } + + val max by derivedStateOf { + descriptor?.attributes?.get("max").float ?: 0f + } + + val step by derivedStateOf { + descriptor?.attributes?.get("step").float ?: 0.1f + } + + Slider( + value = innerValue?.toFloat() ?: 0f, + onValueChange = { + innerValue = it + onValueChange(it.asValue()) + }, + valueRange = min..max, + steps = ((max - min) / step).roundToInt(), + modifier = Modifier.fillMaxWidth() + ) +} + +@Composable +public fun ValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + val rawInput by remember { mutableStateOf(false) } + + val type = descriptor?.valueTypes?.firstOrNull() + + when { + rawInput -> StringValueChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "color" -> ColorValueChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "multiSelect" -> MultiSelectChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "range" -> RangeValueChooser(descriptor, state, value, onValueChange) + type == ValueType.BOOLEAN -> BooleanValueChooser(descriptor, state, value, onValueChange) + type == ValueType.NUMBER -> NumberValueChooser(descriptor, state, value, onValueChange) + descriptor?.allowedValues?.isNotEmpty() ?: false -> ComboValueChooser(descriptor, state, value, onValueChange) + //TODO handle lists + else -> StringValueChooser(descriptor, state, value, onValueChange) + } +} \ No newline at end of file diff --git a/visionforge-core/README.md b/visionforge-core/README.md index 5c5b493b..d1cad403 100644 --- a/visionforge-core/README.md +++ b/visionforge-core/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-core:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-core:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-core:0.3.0-rc") + implementation("space.kscience:visionforge-core:0.4.0-dev-3") } ``` diff --git a/visionforge-core/api/visionforge-core.api b/visionforge-core/api/visionforge-core.api index 89e926ec..90fce073 100644 --- a/visionforge-core/api/visionforge-core.api +++ b/visionforge-core/api/visionforge-core.api @@ -1,3 +1,16 @@ +public abstract class space/kscience/visionforge/AbstractControlVision : space/kscience/visionforge/AbstractVision, space/kscience/visionforge/ControlVision { + public static final field Companion Lspace/kscience/visionforge/AbstractControlVision$Companion; + public fun ()V + public synthetic fun (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 getControlEventFlow ()Lkotlinx/coroutines/flow/SharedFlow; + public static final synthetic fun write$Self (Lspace/kscience/visionforge/AbstractControlVision;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V +} + +public final class space/kscience/visionforge/AbstractControlVision$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + public abstract class space/kscience/visionforge/AbstractVision : space/kscience/visionforge/Vision { public static final field Companion Lspace/kscience/visionforge/AbstractVision$Companion; public fun ()V @@ -34,29 +47,20 @@ public final class space/kscience/visionforge/AbstractVisionGroup$Companion { public static synthetic fun updateProperties$default (Lspace/kscience/visionforge/AbstractVisionGroup$Companion;Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)V } -public abstract class space/kscience/visionforge/AbstractVisionProperties : space/kscience/visionforge/MutableVisionProperties { - public fun (Lspace/kscience/visionforge/Vision;)V - public synthetic fun getChanges ()Lkotlinx/coroutines/flow/Flow; - public fun getChanges ()Lkotlinx/coroutines/flow/SharedFlow; +public class space/kscience/visionforge/AbstractVisionProperties : space/kscience/visionforge/MutableVisionProperties { + public fun (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/MutableMeta;)V + public fun flowChanges ()Lkotlinx/coroutines/flow/Flow; protected final fun getChangesInternal ()Lkotlinx/coroutines/flow/MutableSharedFlow; public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; - protected final fun getOrCreateProperties ()Lspace/kscience/dataforge/meta/MutableMeta; - public fun getOwn ()Lspace/kscience/dataforge/meta/Meta; - protected abstract fun getProperties ()Lspace/kscience/dataforge/meta/MutableMeta; + public synthetic fun getOwn ()Lspace/kscience/dataforge/meta/Meta; + public final fun getOwn ()Lspace/kscience/dataforge/meta/MutableMeta; public fun getValue (Lspace/kscience/dataforge/names/Name;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lspace/kscience/dataforge/meta/Value; public final fun getVision ()Lspace/kscience/visionforge/Vision; public fun invalidate (Lspace/kscience/dataforge/names/Name;)V public fun set (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;Z)V - protected abstract fun setProperties (Lspace/kscience/dataforge/meta/MutableMeta;)V public fun setValue (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Value;Z)V } -public abstract interface class space/kscience/visionforge/ClickControl : space/kscience/visionforge/ControlVision { - public fun click (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun click$default (Lspace/kscience/visionforge/ClickControl;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public static synthetic fun click$suspendImpl (Lspace/kscience/visionforge/ClickControl;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; -} - public final class space/kscience/visionforge/Colors { public static final field BLUE_KEY Ljava/lang/String; public static final field GREEN_KEY Ljava/lang/String; @@ -223,13 +227,21 @@ public abstract interface class space/kscience/visionforge/ControlVision : space } 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 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 VisionSubmitEvent (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionSubmitEvent; + public static synthetic fun VisionSubmitEvent$default (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionSubmitEvent; 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 final fun onClick (Lspace/kscience/visionforge/ClickControl;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job; + public static final fun asyncControlEvent (Lspace/kscience/visionforge/ControlVision;Lspace/kscience/visionforge/VisionControlEvent;Lkotlinx/coroutines/CoroutineScope;)V + public static synthetic fun asyncControlEvent$default (Lspace/kscience/visionforge/ControlVision;Lspace/kscience/visionforge/VisionControlEvent;Lkotlinx/coroutines/CoroutineScope;ILjava/lang/Object;)V + public static final fun onSubmit (Lspace/kscience/visionforge/DataControl;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job; +} + +public abstract interface class space/kscience/visionforge/DataControl : space/kscience/visionforge/ControlVision { + public fun submit (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun submit$default (Lspace/kscience/visionforge/DataControl;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public static synthetic fun submit$suspendImpl (Lspace/kscience/visionforge/DataControl;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class space/kscience/visionforge/FlowPropertyKt { @@ -320,9 +332,9 @@ public final class space/kscience/visionforge/StyleReference { public final class space/kscience/visionforge/StyleReferenceKt { public static final fun style (Lspace/kscience/visionforge/Vision;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty; - public static final fun style (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/Specification;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty; + public static final fun style (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/SchemeSpec;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty; public static synthetic fun style$default (Lspace/kscience/visionforge/Vision;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun style$default (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/Specification;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun style$default (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/SchemeSpec;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; public static final fun useStyle (Lspace/kscience/visionforge/Vision;Lspace/kscience/visionforge/StyleReference;Z)V public static synthetic fun useStyle$default (Lspace/kscience/visionforge/Vision;Lspace/kscience/visionforge/StyleReference;ZILjava/lang/Object;)V } @@ -364,7 +376,9 @@ public final class space/kscience/visionforge/StyleSheetKt { public final class space/kscience/visionforge/UsePropertyKt { public static final fun onPropertyChange (Lspace/kscience/visionforge/Vision;Lkotlin/reflect/KProperty1;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/Job; + public static final fun onPropertyChange (Lspace/kscience/visionforge/Vision;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job; public static synthetic fun onPropertyChange$default (Lspace/kscience/visionforge/Vision;Lkotlin/reflect/KProperty1;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlinx/coroutines/Job; + public static synthetic fun onPropertyChange$default (Lspace/kscience/visionforge/Vision;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job; public static final fun useProperty (Lspace/kscience/visionforge/Vision;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/Job; public static final fun useProperty (Lspace/kscience/visionforge/Vision;Lkotlin/reflect/KProperty1;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job; public static final fun useProperty (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/names/Name;Ljava/lang/Boolean;Ljava/lang/Boolean;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/Job; @@ -462,30 +476,6 @@ public final class space/kscience/visionforge/VisionChildren$Companion { public final fun empty (Lspace/kscience/visionforge/Vision;)Lspace/kscience/visionforge/VisionChildren; } -public final class space/kscience/visionforge/VisionClickEvent : space/kscience/visionforge/VisionControlEvent { - public static final field Companion Lspace/kscience/visionforge/VisionClickEvent$Companion; - public fun (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 getPayload ()Lspace/kscience/dataforge/meta/Meta; - public fun toString ()Ljava/lang/String; -} - -public final class space/kscience/visionforge/VisionClickEvent$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lspace/kscience/visionforge/VisionClickEvent$$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/VisionClickEvent; - 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/VisionClickEvent;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class space/kscience/visionforge/VisionClickEvent$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - public abstract interface class space/kscience/visionforge/VisionClient : space/kscience/dataforge/context/Plugin { public abstract fun getVisionManager ()Lspace/kscience/visionforge/VisionManager; public abstract fun notifyPropertyChanged (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/Meta;)V @@ -589,8 +579,6 @@ public final class space/kscience/visionforge/VisionInputEvent$Companion { public final class space/kscience/visionforge/VisionKt { 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 synthetic fun onPropertyChange$default (Lspace/kscience/visionforge/Vision;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job; public static final fun setVisible (Lspace/kscience/visionforge/Vision;Ljava/lang/Boolean;)V } @@ -659,10 +647,10 @@ public abstract class space/kscience/visionforge/VisionPlugin : space/kscience/d } public abstract interface class space/kscience/visionforge/VisionProperties : space/kscience/dataforge/meta/MetaProvider { + public abstract fun flowChanges ()Lkotlinx/coroutines/flow/Flow; public fun get (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Meta; public abstract fun get (Lspace/kscience/dataforge/names/Name;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lspace/kscience/dataforge/meta/Meta; public static synthetic fun get$default (Lspace/kscience/visionforge/VisionProperties;Lspace/kscience/dataforge/names/Name;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Meta; - public abstract fun getChanges ()Lkotlinx/coroutines/flow/Flow; public abstract fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; public abstract fun getOwn ()Lspace/kscience/dataforge/meta/Meta; public fun getValue (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/Value; @@ -685,6 +673,30 @@ public final class space/kscience/visionforge/VisionPropertiesKt { public static synthetic fun root$default (Lspace/kscience/visionforge/MutableVisionProperties;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/MutableMeta; } +public final class space/kscience/visionforge/VisionSubmitEvent : space/kscience/visionforge/VisionControlEvent { + public static final field Companion Lspace/kscience/visionforge/VisionSubmitEvent$Companion; + public fun (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 getPayload ()Lspace/kscience/dataforge/meta/Meta; + public fun toString ()Ljava/lang/String; +} + +public final class space/kscience/visionforge/VisionSubmitEvent$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lspace/kscience/visionforge/VisionSubmitEvent$$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/VisionSubmitEvent; + 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/VisionSubmitEvent;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class space/kscience/visionforge/VisionSubmitEvent$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + public final class space/kscience/visionforge/VisionValueChangeEvent : space/kscience/visionforge/VisionControlEvent { public static final field Companion Lspace/kscience/visionforge/VisionValueChangeEvent$Companion; public fun (Lspace/kscience/dataforge/meta/Meta;)V @@ -750,10 +762,10 @@ public abstract interface class space/kscience/visionforge/html/HtmlVisionFragme public final class space/kscience/visionforge/html/HtmlVisionRendererKt { public static final fun appendTo (Lspace/kscience/visionforge/html/HtmlVisionFragment;Lspace/kscience/visionforge/html/VisionTagConsumer;)V - public static final fun visionFragment (Lkotlinx/html/FlowContent;Lspace/kscience/visionforge/VisionManager;ZLjava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Lspace/kscience/visionforge/html/HtmlVisionFragment;)V - public static final fun visionFragment (Lkotlinx/html/TagConsumer;Lspace/kscience/visionforge/VisionManager;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lspace/kscience/visionforge/html/HtmlVisionFragment;)V - public static synthetic fun visionFragment$default (Lkotlinx/html/FlowContent;Lspace/kscience/visionforge/VisionManager;ZLjava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Lspace/kscience/visionforge/html/HtmlVisionFragment;ILjava/lang/Object;)V - public static synthetic fun visionFragment$default (Lkotlinx/html/TagConsumer;Lspace/kscience/visionforge/VisionManager;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lspace/kscience/visionforge/html/HtmlVisionFragment;ILjava/lang/Object;)V + public static final fun visionFragment (Lkotlinx/html/FlowContent;Lspace/kscience/visionforge/VisionManager;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lspace/kscience/visionforge/html/HtmlVisionFragment;)V + public static final fun visionFragment (Lkotlinx/html/TagConsumer;Lspace/kscience/visionforge/VisionManager;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lspace/kscience/visionforge/html/HtmlVisionFragment;)V + public static synthetic fun visionFragment$default (Lkotlinx/html/FlowContent;Lspace/kscience/visionforge/VisionManager;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lspace/kscience/visionforge/html/HtmlVisionFragment;ILjava/lang/Object;)V + public static synthetic fun visionFragment$default (Lkotlinx/html/TagConsumer;Lspace/kscience/visionforge/VisionManager;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lspace/kscience/visionforge/html/HtmlVisionFragment;ILjava/lang/Object;)V } public final class space/kscience/visionforge/html/InputFeedbackMode : java/lang/Enum { @@ -782,6 +794,21 @@ public final class space/kscience/visionforge/html/ResourceLocation : java/lang/ public abstract interface annotation class space/kscience/visionforge/html/VisionDSL : java/lang/annotation/Annotation { } +public final class space/kscience/visionforge/html/VisionDisplay { + public fun (Lspace/kscience/visionforge/VisionManager;Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/Meta;)V + public final fun component1 ()Lspace/kscience/visionforge/VisionManager; + public final fun component2 ()Lspace/kscience/visionforge/Vision; + public final fun component3 ()Lspace/kscience/dataforge/meta/Meta; + public final fun copy (Lspace/kscience/visionforge/VisionManager;Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/visionforge/html/VisionDisplay; + public static synthetic fun copy$default (Lspace/kscience/visionforge/html/VisionDisplay;Lspace/kscience/visionforge/VisionManager;Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lspace/kscience/visionforge/html/VisionDisplay; + public fun equals (Ljava/lang/Object;)Z + public final fun getMeta ()Lspace/kscience/dataforge/meta/Meta; + public final fun getVision ()Lspace/kscience/visionforge/Vision; + public final fun getVisionManager ()Lspace/kscience/visionforge/VisionManager; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + public final class space/kscience/visionforge/html/VisionOfCheckbox : space/kscience/visionforge/html/VisionOfHtmlInput { public static final field Companion Lspace/kscience/visionforge/html/VisionOfCheckbox$Companion; public fun ()V @@ -804,20 +831,14 @@ public final class space/kscience/visionforge/html/VisionOfCheckbox$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public abstract class space/kscience/visionforge/html/VisionOfHtml : space/kscience/visionforge/AbstractVision { - public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtml$Companion; - public fun ()V - public synthetic fun (ILspace/kscience/dataforge/meta/MutableMeta;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public final fun getClasses ()Ljava/util/Set; - 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 abstract interface class space/kscience/visionforge/html/VisionOfHtml : space/kscience/visionforge/Vision { + public fun getClasses ()Ljava/util/Set; + public fun getStyleString ()Ljava/lang/String; + public fun setClasses (Ljava/util/Set;)V + public fun setStyleString (Ljava/lang/String;)V } -public final class space/kscience/visionforge/html/VisionOfHtml$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class space/kscience/visionforge/html/VisionOfHtmlButton : space/kscience/visionforge/html/VisionOfHtmlControl, space/kscience/visionforge/ClickControl { +public final class space/kscience/visionforge/html/VisionOfHtmlButton : space/kscience/visionforge/AbstractControlVision, space/kscience/visionforge/DataControl, space/kscience/visionforge/html/VisionOfHtml { public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtmlButton$Companion; public fun ()V public final fun getLabel ()Ljava/lang/String; @@ -839,20 +860,7 @@ public final class space/kscience/visionforge/html/VisionOfHtmlButton$Companion public final fun serializer ()Lkotlinx/serialization/KSerializer; } -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 ()V - public synthetic fun (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 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/AbstractControlVision, space/kscience/visionforge/DataControl, space/kscience/visionforge/html/VisionOfHtml { public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtmlForm$Companion; public fun (Ljava/lang/String;)V public final fun getFormId ()Ljava/lang/String; @@ -876,12 +884,14 @@ public final class space/kscience/visionforge/html/VisionOfHtmlForm$Companion { } public final class space/kscience/visionforge/html/VisionOfHtmlFormKt { - public static final fun bindForm (Lkotlinx/html/TagConsumer;Lspace/kscience/visionforge/html/VisionOfHtmlForm;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static final fun button (Lspace/kscience/visionforge/html/VisionOutput;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lspace/kscience/visionforge/html/VisionOfHtmlButton; public static synthetic fun button$default (Lspace/kscience/visionforge/html/VisionOutput;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/html/VisionOfHtmlButton; + public static final fun onFormSubmit (Lspace/kscience/visionforge/html/VisionOfHtmlForm;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/Job; + public static final fun visionOfForm (Lkotlinx/html/TagConsumer;Lspace/kscience/visionforge/html/VisionOfHtmlForm;Ljava/lang/String;Lkotlinx/html/FormEncType;Lkotlinx/html/FormMethod;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static synthetic fun visionOfForm$default (Lkotlinx/html/TagConsumer;Lspace/kscience/visionforge/html/VisionOfHtmlForm;Ljava/lang/String;Lkotlinx/html/FormEncType;Lkotlinx/html/FormMethod;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/Object; } -public class space/kscience/visionforge/html/VisionOfHtmlInput : space/kscience/visionforge/html/VisionOfHtmlControl { +public class space/kscience/visionforge/html/VisionOfHtmlInput : space/kscience/visionforge/AbstractControlVision, space/kscience/visionforge/html/VisionOfHtml { public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtmlInput$Companion; public synthetic fun (ILspace/kscience/dataforge/meta/MutableMeta;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V public fun (Ljava/lang/String;)V @@ -951,7 +961,7 @@ public final class space/kscience/visionforge/html/VisionOfNumberField$Companion public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public final class space/kscience/visionforge/html/VisionOfPlainHtml : space/kscience/visionforge/html/VisionOfHtml { +public final class space/kscience/visionforge/html/VisionOfPlainHtml : space/kscience/visionforge/AbstractVision, space/kscience/visionforge/html/VisionOfHtml { public static final field Companion Lspace/kscience/visionforge/html/VisionOfPlainHtml$Companion; public fun ()V public final fun getContent ()Ljava/lang/String; @@ -1027,7 +1037,6 @@ public final class space/kscience/visionforge/html/VisionOutput : space/kscience public final fun getMeta ()Lspace/kscience/dataforge/meta/Meta; public final fun getName ()Lspace/kscience/dataforge/names/Name; public final fun getVisionManager ()Lspace/kscience/visionforge/VisionManager; - public final fun meta (Lkotlin/jvm/functions/Function1;)V public final fun requirePlugin (Lspace/kscience/dataforge/context/PluginFactory;)V public final fun setMeta (Lspace/kscience/dataforge/meta/Meta;)V } @@ -1098,6 +1107,11 @@ public abstract class space/kscience/visionforge/html/VisionTagConsumer : kotlin public final class space/kscience/visionforge/html/VisionTagConsumer$Companion { } +public final class space/kscience/visionforge/html/VisionTagConsumerKt { + public static final fun meta (Lspace/kscience/visionforge/html/VisionOutput;Lkotlin/jvm/functions/Function1;)V + public static final fun meta (Lspace/kscience/visionforge/html/VisionOutput;Lspace/kscience/dataforge/meta/MetaRepr;)V +} + public final class space/kscience/visionforge/visitor/CountDistinctKt { public static final fun countDistinct (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun countDistinctBy (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index cff29e61..85fea7f4 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -64,7 +64,7 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) } /** - * List of names of styles applied to this object. Order matters. Not inherited. + * List of style names applied to this object. Order matters. Not inherited. */ public var Vision.styles: List get() = properties.own[Vision.STYLE_KEY]?.stringList ?: emptyList() diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 2bee6a4f..406dfeba 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -132,6 +132,8 @@ public class RootVision(override val manager: VisionManager) : AbstractVisionGro * Designate this [Vision] as a root and assign a [VisionManager] as its parent */ public fun Vision.setAsRoot(manager: VisionManager) { + //do nothing if vision is already rooted + if(this.manager == manager) return if (parent != null) error("Vision $this already has a parent. It could not be set as root") parent = RootVision(manager) } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt index 30932c37..050e88ae 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt @@ -17,11 +17,24 @@ import space.kscience.visionforge.* public interface VisionOfHtml : Vision { + + /** + * Html class strings for this instance. Does not use vision inheritance, but uses styles + */ public var classes: Set - get() = properties[::classes.name, false].stringList?.toSet() ?: emptySet() + get() = properties[::classes.name, false, true].stringList?.toSet() ?: emptySet() set(value) { properties[::classes.name] = value.map { it.asValue() } } + + /** + * A custom style string + */ + public var styleString: String? + get() = properties[::styleString.name,false,true].string + set(value){ + properties[::styleString.name] = value?.asValue() + } } @Serializable @@ -67,7 +80,6 @@ public open class VisionOfHtmlInput( public var value: Value? by properties.value() public var disabled: Boolean by properties.boolean { false } public var fieldName: String? by properties.string() - } /** diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt index 19cfc80a..ccf9892e 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt @@ -23,7 +23,7 @@ public annotation class VisionDSL * A placeholder object to attach inline vision builders. */ @VisionDSL -public class VisionOutput @PublishedApi internal constructor(override val context: Context, public val name: Name): ContextAware { +public class VisionOutput(override val context: Context, public val name: Name): ContextAware { public var meta: Meta = Meta.EMPTY private val requirements: MutableSet> = HashSet() diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 8b800add..71b3109c 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -10,6 +10,7 @@ import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.* import space.kscience.visionforge.* +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals @@ -91,6 +92,7 @@ internal class VisionPropertyTest { } @Test + @Ignore fun testChildrenPropertyFlow() = runTest(timeout = 500.milliseconds) { val group = Global.request(VisionManager).group { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/Application.kt similarity index 94% rename from visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt rename to visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/Application.kt index 85ead127..1e00d529 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/Application.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge +package space.kscience.visionforge.html import kotlinx.browser.document import kotlinx.coroutines.CoroutineScope @@ -46,7 +46,7 @@ public interface Application: CoroutineScope { } public fun startApplication(builder: () -> Application) { - fun start(document: Document, state: dynamic): Application{ + fun start(document: Document, state: dynamic): Application { val application = builder() @Suppress("UnsafeCastFromDynamic") diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/ElementVisionRenderer.kt similarity index 96% rename from visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt rename to visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/ElementVisionRenderer.kt index 305fa70b..1441350b 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/ElementVisionRenderer.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge +package space.kscience.visionforge.html import kotlinx.dom.clear import kotlinx.html.TagConsumer @@ -8,6 +8,7 @@ import org.w3c.dom.HTMLElement import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.misc.DfType import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Vision import kotlin.reflect.KClass import kotlin.reflect.cast diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/JsVisionClient.kt similarity index 98% rename from visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt rename to visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/JsVisionClient.kt index 946de13c..c69e1e91 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/JsVisionClient.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge +package space.kscience.visionforge.html import kotlinx.browser.document import kotlinx.browser.window @@ -23,7 +23,7 @@ import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.parseAsName -import space.kscience.visionforge.html.VisionTagConsumer +import space.kscience.visionforge.* import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_CONNECT_ATTRIBUTE import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_ENDPOINT_ATTRIBUTE import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_FETCH_ATTRIBUTE @@ -92,19 +92,6 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { eventCollector.emit(targetName to event) } - private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) { - vision.setAsRoot(visionManager) - val renderer: ElementVisionRenderer = - findRendererFor(vision) ?: error("Could not find renderer for ${vision::class}") - //subscribe to a backwards events propagation for control visions - if(vision is ControlVision){ - vision.controlEventFlow.onEach { - sendEvent(name,it) - }.launchIn(context) - } - renderer.render(element, name, vision, outputMeta) - } - private fun startVisionUpdate(element: Element, visionName: Name, vision: Vision, outputMeta: Meta) { element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { @@ -187,6 +174,24 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { } } + + private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) { + vision.setAsRoot(visionManager) + val renderer: ElementVisionRenderer = + findRendererFor(vision) ?: error("Could not find renderer for ${vision::class}") + //render vision + renderer.render(element, name, vision, outputMeta) + //start vision update from backend model + startVisionUpdate(element, name, vision, outputMeta) + //subscribe to a backwards events propagation for control visions + if(vision is ControlVision){ + vision.controlEventFlow.onEach { + sendEvent(name,it) + }.launchIn(context) + } + + } + /** * Fetch from server and render a vision, described in a given with [VisionTagConsumer.OUTPUT_CLASS] class. */ @@ -230,7 +235,6 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { response.text().then { text -> val vision = visionManager.decodeFromString(text) renderVision(element, name, vision, outputMeta) - startVisionUpdate(element, name, vision, outputMeta) } } else { logger.error { "Failed to fetch initial vision state from $fetchUrl" } @@ -246,7 +250,6 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { } logger.info { "Found embedded vision for output with name $name" } renderVision(element, name, embeddedVision, outputMeta) - startVisionUpdate(element, name, embeddedVision, outputMeta) } //Try to load vision via websocket diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/formRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/formRenderers.kt similarity index 95% rename from visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/formRenderers.kt rename to visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/formRenderers.kt index f82850cf..a8c693d6 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/formRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/formRenderers.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge +package space.kscience.visionforge.html import kotlinx.browser.document import kotlinx.coroutines.launch @@ -12,8 +12,7 @@ import space.kscience.dataforge.context.debug import space.kscience.dataforge.context.logger import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name -import space.kscience.visionforge.html.VisionOfHtmlButton -import space.kscience.visionforge.html.VisionOfHtmlForm +import space.kscience.visionforge.* /** * Convert form data to Meta diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/inputRenderers.kt similarity index 92% rename from visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt rename to visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/inputRenderers.kt index 4e7a9d36..5ad1bb19 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/html/inputRenderers.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge +package space.kscience.visionforge.html import kotlinx.dom.clear import kotlinx.html.InputType @@ -9,7 +9,10 @@ import org.w3c.dom.HTMLInputElement import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.string -import space.kscience.visionforge.html.* +import space.kscience.visionforge.VisionInputEvent +import space.kscience.visionforge.VisionValueChangeEvent +import space.kscience.visionforge.asyncControlEvent +import space.kscience.visionforge.useProperty /** * Subscribes the HTML element to a given vision. @@ -20,6 +23,10 @@ internal fun HTMLElement.subscribeToVision(vision: VisionOfHtml) { vision.useProperty(VisionOfHtml::classes) { classList.value = classes.joinToString(separator = " ") } + + vision.useProperty(VisionOfHtml::styleString) { + style.cssText = it ?: "" + } } /** @@ -54,7 +61,7 @@ internal val inputVisionRenderer: ElementVisionRenderer = ElementVisionRenderer< }.also { htmlInputElement -> htmlInputElement.onchange = { - vision.asyncControlEvent( VisionValueChangeEvent(htmlInputElement.value.asValue(), name)) + vision.asyncControlEvent(VisionValueChangeEvent(htmlInputElement.value.asValue(), name)) } htmlInputElement.oninput = { diff --git a/visionforge-core/src/jsTest/kotlin/space/kscience/visionforge/FormTest.kt b/visionforge-core/src/jsTest/kotlin/space/kscience/visionforge/FormTest.kt index 58bd2b09..75b5c188 100644 --- a/visionforge-core/src/jsTest/kotlin/space/kscience/visionforge/FormTest.kt +++ b/visionforge-core/src/jsTest/kotlin/space/kscience/visionforge/FormTest.kt @@ -4,6 +4,7 @@ import org.w3c.xhr.FormData import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.stringList +import space.kscience.visionforge.html.toMeta import kotlin.test.Test import kotlin.test.assertEquals diff --git a/visionforge-core/src/jvmTest/kotlin/space/kscience/visionforge/meta/PropertyFlowTest.kt b/visionforge-core/src/jvmTest/kotlin/space/kscience/visionforge/meta/PropertyFlowTest.kt new file mode 100644 index 00000000..3c5834a5 --- /dev/null +++ b/visionforge-core/src/jvmTest/kotlin/space/kscience/visionforge/meta/PropertyFlowTest.kt @@ -0,0 +1,65 @@ +package space.kscience.visionforge.meta + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Timeout +import space.kscience.dataforge.context.Global +import space.kscience.dataforge.context.request +import space.kscience.dataforge.meta.* +import space.kscience.visionforge.* +import kotlin.test.Test +import kotlin.test.assertEquals + +internal class PropertyFlowTest { + + private val manager = Global.request(VisionManager) + + @Test + @Timeout(200) + fun testChildrenPropertyFlow() = runBlocking{ + val group = Global.request(VisionManager).group { + + properties { + "test" put 11 + } + + group("child") { + properties { + "test" put 22 + } + } + + } + + val child = group.children["child"]!! + + val changesFlow = child.flowPropertyValue("test", inherit = true).map { + it!!.int + } + + val collectedValues = ArrayList(5) + + val collectorJob = changesFlow.onEach { + collectedValues.add(it) + }.launchIn(this) + + + delay(2) + assertEquals(22, child.properties["test", true].int) + + child.properties.remove("test") + delay(2) + + assertEquals(11, child.properties["test", true].int) + group.properties["test"] = 33 + delay(2) + + assertEquals(33, child.properties["test", true].int) + + collectorJob.cancel() + assertEquals(listOf(22, 11, 33), collectedValues) + } +} \ No newline at end of file diff --git a/visionforge-gdml/README.md b/visionforge-gdml/README.md index a6429697..9c0a8e5a 100644 --- a/visionforge-gdml/README.md +++ b/visionforge-gdml/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-gdml:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-gdml:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-gdml:0.3.0-rc") + implementation("space.kscience:visionforge-gdml:0.4.0-dev-3") } ``` diff --git a/visionforge-jupyter/README.md b/visionforge-jupyter/README.md index 43df6bfd..f2fda065 100644 --- a/visionforge-jupyter/README.md +++ b/visionforge-jupyter/README.md @@ -6,7 +6,7 @@ Common visionforge jupyter module ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-jupyter:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-jupyter:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-jupyter:0.3.0-rc") + implementation("space.kscience:visionforge-jupyter:0.4.0-dev-3") } ``` diff --git a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt index e095485c..2b78f450 100644 --- a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt +++ b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt @@ -8,10 +8,10 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta -import space.kscience.visionforge.JsVisionClient -import space.kscience.visionforge.renderAllVisions -import space.kscience.visionforge.renderAllVisionsById -import space.kscience.visionforge.renderAllVisionsIn +import space.kscience.visionforge.html.JsVisionClient +import space.kscience.visionforge.html.renderAllVisions +import space.kscience.visionforge.html.renderAllVisionsById +import space.kscience.visionforge.html.renderAllVisionsIn @JsExport public class VFNotebookClient : AbstractPlugin() { diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt index ae0e29e2..10138701 100644 --- a/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.gdml.jupyter +import space.kscience.visionforge.html.runVisionClient import space.kscience.visionforge.jupyter.VFNotebookClient import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin -import space.kscience.visionforge.runVisionClient import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.tables.TableVisionJsPlugin diff --git a/visionforge-markdown/README.md b/visionforge-markdown/README.md index 5e35ccf7..6226bbea 100644 --- a/visionforge-markdown/README.md +++ b/visionforge-markdown/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-markdown:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-markdown:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-markdown:0.3.0-rc") + implementation("space.kscience:visionforge-markdown:0.4.0-dev-3") } ``` diff --git a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index d6df2162..4806ec38 100644 --- a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -13,9 +13,13 @@ import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.visionforge.* +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionPlugin +import space.kscience.visionforge.html.ElementVisionRenderer +import space.kscience.visionforge.html.JsVisionClient import space.kscience.visionforge.markup.VisionOfMarkup.Companion.COMMONMARK_FORMAT import space.kscience.visionforge.markup.VisionOfMarkup.Companion.GFM_FORMAT +import space.kscience.visionforge.useProperty public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { public val visionClient: JsVisionClient by require(JsVisionClient) diff --git a/visionforge-plotly/README.md b/visionforge-plotly/README.md index 83f3b06b..4fdf04e2 100644 --- a/visionforge-plotly/README.md +++ b/visionforge-plotly/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-plotly:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-plotly:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-plotly:0.3.0-rc") + implementation("space.kscience:visionforge-plotly:0.4.0-dev-3") } ``` diff --git a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt index 074be6dc..32c46132 100644 --- a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt +++ b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt @@ -10,10 +10,10 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.plotly.PlotlyConfig import space.kscience.plotly.plot -import space.kscience.visionforge.ElementVisionRenderer -import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionPlugin +import space.kscience.visionforge.html.ElementVisionRenderer +import space.kscience.visionforge.html.JsVisionClient public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { public val visionClient: JsVisionClient by require(JsVisionClient) diff --git a/visionforge-server/README.md b/visionforge-server/README.md index c51b38ae..78c6a18f 100644 --- a/visionforge-server/README.md +++ b/visionforge-server/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-server:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-server:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-server:0.3.0-rc") + implementation("space.kscience:visionforge-server:0.4.0-dev-3") } ``` diff --git a/visionforge-solid/README.md b/visionforge-solid/README.md index 331c8485..177b60ad 100644 --- a/visionforge-solid/README.md +++ b/visionforge-solid/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-solid:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-solid:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-solid:0.3.0-rc") + implementation("space.kscience:visionforge-solid:0.4.0-dev-3") } ``` diff --git a/visionforge-solid/api/visionforge-solid.api b/visionforge-solid/api/visionforge-solid.api index cfeecfe3..b8fc8211 100644 --- a/visionforge-solid/api/visionforge-solid.api +++ b/visionforge-solid/api/visionforge-solid.api @@ -747,6 +747,7 @@ public final class space/kscience/visionforge/solid/SolidKt { public static final fun getY (Lspace/kscience/visionforge/solid/Solid;)Ljava/lang/Number; public static final fun getZ (Lspace/kscience/visionforge/solid/Solid;)Ljava/lang/Number; public static final fun rotate (Lspace/kscience/visionforge/solid/Solid;Lspace/kscience/kmath/geometry/Angle;Lspace/kscience/kmath/geometry/Vector3D;)V + public static final fun scale (Lspace/kscience/visionforge/solid/Solid;Ljava/lang/Number;)V public static final fun setDetail (Lspace/kscience/visionforge/solid/Solid;Ljava/lang/Integer;)V public static final fun setIgnore (Lspace/kscience/visionforge/Vision;Ljava/lang/Boolean;)V public static final fun setLayer (Lspace/kscience/visionforge/solid/Solid;I)V @@ -802,8 +803,10 @@ public final class space/kscience/visionforge/solid/SolidMaterial : space/kscien public final fun getEmissiveColor ()Lspace/kscience/visionforge/solid/ColorAccessor; public final fun getOpacity ()F public final fun getSpecularColor ()Lspace/kscience/visionforge/solid/ColorAccessor; + public final fun getType ()Ljava/lang/String; public final fun getWireframe ()Z public final fun setOpacity (F)V + public final fun setType (Ljava/lang/String;)V public final fun setWireframe (Z)V } @@ -1087,23 +1090,6 @@ public final class space/kscience/visionforge/solid/SurfaceKt { public static synthetic fun surface$default (Lspace/kscience/visionforge/MutableVisionContainer;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/solid/Surface; } -public final class space/kscience/visionforge/solid/specifications/AxesScheme : space/kscience/dataforge/meta/Scheme { - public static final field AXIS_SIZE D - public static final field AXIS_WIDTH D - public static final field Companion Lspace/kscience/visionforge/solid/specifications/AxesScheme$Companion; - public fun ()V - public final fun getSize ()D - public final fun getVisible ()Z - public final fun getWidth ()D - public final fun setSize (D)V - public final fun setVisible (Z)V - public final fun setWidth (D)V -} - -public final class space/kscience/visionforge/solid/specifications/AxesScheme$Companion : space/kscience/dataforge/meta/SchemeSpec { - public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; -} - public final class space/kscience/visionforge/solid/specifications/CameraScheme : space/kscience/dataforge/meta/Scheme { public static final field Companion Lspace/kscience/visionforge/solid/specifications/CameraScheme$Companion; public static final field FAR_CLIP D @@ -1138,15 +1124,15 @@ public final class space/kscience/visionforge/solid/specifications/CameraSchemeK public final class space/kscience/visionforge/solid/specifications/Canvas3DOptions : space/kscience/dataforge/meta/Scheme { public static final field Companion Lspace/kscience/visionforge/solid/specifications/Canvas3DOptions$Companion; public fun ()V - public final fun getAxes ()Lspace/kscience/visionforge/solid/specifications/AxesScheme; public final fun getCamera ()Lspace/kscience/visionforge/solid/specifications/CameraScheme; + public final fun getCanvasName ()Ljava/lang/String; public final fun getClipping ()Lspace/kscience/visionforge/solid/specifications/PointScheme; public final fun getControls ()Lspace/kscience/visionforge/solid/specifications/Canvas3DUIScheme; public final fun getLayers ()Ljava/util/List; public final fun getOnSelect ()Lkotlin/jvm/functions/Function1; public final fun getSize ()Lspace/kscience/visionforge/solid/specifications/CanvasSize; - 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 setCanvasName (Ljava/lang/String;)V public final fun setClipping (Lspace/kscience/visionforge/solid/specifications/PointScheme;)V public final fun setControls (Lspace/kscience/visionforge/solid/specifications/Canvas3DUIScheme;)V public final fun setLayers (Ljava/util/List;)V @@ -1171,6 +1157,7 @@ public final class space/kscience/visionforge/solid/specifications/Canvas3DUISch } public final class space/kscience/visionforge/solid/specifications/Canvas3DUIScheme$Companion : space/kscience/dataforge/meta/SchemeSpec { + public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; } public final class space/kscience/visionforge/solid/specifications/CanvasSize : space/kscience/dataforge/meta/Scheme { diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index f87cef77..f6ee0ab4 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -8,6 +8,7 @@ kscience { jvm() js() native() +// wasm() useSerialization { json() } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index e45c18dd..6e336110 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.ValueRestriction import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name @@ -66,6 +67,7 @@ public class SolidMaterial : Scheme() { //must be lazy to avoid initialization bug MetaDescriptor { inherited = true + valueRestriction = ValueRestriction.ABSENT value(TYPE_KEY, ValueType.STRING) { inherited = true diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt index 19e93b0f..a67532ce 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt @@ -4,6 +4,7 @@ package space.kscience.visionforge.solid.specifications import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.ValueRestriction import space.kscience.dataforge.meta.descriptors.scheme import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.meta.set @@ -15,6 +16,7 @@ import space.kscience.visionforge.widgetType public object Clipping : SchemeSpec(::PointScheme) { override val descriptor: MetaDescriptor = MetaDescriptor { + valueRestriction = ValueRestriction.ABSENT value(PointScheme::x) { widgetType = "range" attributes["min"] = 0.0 diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DUIScheme.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DUIScheme.kt index 5f85cc44..46665a56 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DUIScheme.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DUIScheme.kt @@ -3,11 +3,17 @@ package space.kscience.visionforge.solid.specifications import space.kscience.dataforge.meta.Scheme import space.kscience.dataforge.meta.SchemeSpec import space.kscience.dataforge.meta.boolean +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.ValueRestriction public class Canvas3DUIScheme : Scheme() { public var enabled: Boolean by boolean { true } - public companion object : SchemeSpec(::Canvas3DUIScheme) + public companion object : SchemeSpec(::Canvas3DUIScheme) { + override val descriptor: MetaDescriptor = MetaDescriptor { + valueRestriction = ValueRestriction.ABSENT + } + } } \ No newline at end of file diff --git a/visionforge-tables/README.md b/visionforge-tables/README.md index b02284f8..59af4988 100644 --- a/visionforge-tables/README.md +++ b/visionforge-tables/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-tables:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-tables:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-tables:0.3.0-rc") + implementation("space.kscience:visionforge-tables:0.4.0-dev-3") } ``` diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index ba11976a..4b6e9be9 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -11,9 +11,9 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.toDynamic import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.visionforge.ElementVisionRenderer -import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.Vision +import space.kscience.visionforge.html.ElementVisionRenderer +import space.kscience.visionforge.html.JsVisionClient import tabulator.Tabulator import tabulator.TabulatorFull diff --git a/visionforge-threejs/README.md b/visionforge-threejs/README.md index 3b26d996..4b0cbb6d 100644 --- a/visionforge-threejs/README.md +++ b/visionforge-threejs/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-threejs:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-threejs:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-threejs:0.3.0-rc") + implementation("space.kscience:visionforge-threejs:0.4.0-dev-3") } ``` diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 30010a12..f63c1841 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -9,11 +9,16 @@ import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.* -import space.kscience.visionforge.* +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionChildren +import space.kscience.visionforge.VisionClient import space.kscience.visionforge.html.ComposeHtmlVisionRenderer +import space.kscience.visionforge.html.ElementVisionRenderer +import space.kscience.visionforge.html.JsVisionClient import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.compose.ThreeView +import space.kscience.visionforge.visible import three.core.Object3D import kotlin.collections.set import kotlin.reflect.KClass diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeControls.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeControls.kt index 63e95760..a0211a1e 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeControls.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeControls.kt @@ -9,7 +9,6 @@ import app.softwork.bootstrapcompose.Layout.Width import org.jetbrains.compose.web.dom.Hr import org.w3c.files.Blob import org.w3c.files.BlobPropertyBag -import space.kscience.dataforge.context.Global import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.encodeToString @@ -33,7 +32,6 @@ internal fun CanvasControls( } Hr() PropertyEditor( - scope = vision?.manager?.context ?: Global, properties = options.meta, descriptor = Canvas3DOptions.descriptor, expanded = false diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeView.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeView.kt index b3dd1347..1f496b05 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeView.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeView.kt @@ -135,7 +135,6 @@ public fun ThreeView( NameCrumbs(selected) { selected = it } Hr() PropertyEditor( - scope = context, rootMeta = vision.properties.root(), getPropertyState = { name -> if (vision.properties.own[name] != null) { diff --git a/visionforge-threejs/visionforge-threejs-server/README.md b/visionforge-threejs/visionforge-threejs-server/README.md index 16ac3520..2f94128a 100644 --- a/visionforge-threejs/visionforge-threejs-server/README.md +++ b/visionforge-threejs/visionforge-threejs-server/README.md @@ -6,7 +6,7 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:visionforge-threejs-server:0.3.0-rc`. +The Maven coordinates of this project are `space.kscience:visionforge-threejs-server:0.4.0-dev-3`. **Gradle Kotlin DSL:** ```kotlin @@ -16,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:visionforge-threejs-server:0.3.0-rc") + implementation("space.kscience:visionforge-threejs-server:0.4.0-dev-3") } ``` diff --git a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts index cf62eede..8a762d13 100644 --- a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts +++ b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts @@ -23,6 +23,7 @@ kscience { commonMain { api(projects.visionforgeSolid) + api(projects.visionforgeComposeHtml) } jvmMain { diff --git a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt index ed2908f5..c0169f81 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.three import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.runVisionClient +import space.kscience.visionforge.html.runVisionClient import space.kscience.visionforge.solid.three.ThreePlugin