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 e60f1dec..5add1d6f 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 @@ -8,8 +8,8 @@ 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.compose.TreeStyles import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.html.TreeStyles import space.kscience.visionforge.solid.ambientLight import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.three.ThreePlugin diff --git a/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt index 8516736c..71de963a 100644 --- a/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt @@ -7,8 +7,8 @@ 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.compose.Tabs -import space.kscience.visionforge.compose.TreeStyles +import space.kscience.visionforge.html.Tabs +import space.kscience.visionforge.html.TreeStyles import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.solid.* diff --git a/demo/js-playground/src/jsMain/kotlin/gravityDemo.kt b/demo/js-playground/src/jsMain/kotlin/gravityDemo.kt index 5cff2864..9a5089fa 100644 --- a/demo/js-playground/src/jsMain/kotlin/gravityDemo.kt +++ b/demo/js-playground/src/jsMain/kotlin/gravityDemo.kt @@ -15,8 +15,8 @@ import space.kscience.plotly.Plot import space.kscience.plotly.layout import space.kscience.plotly.models.Trace import space.kscience.visionforge.Colors -import space.kscience.visionforge.compose.Vision -import space.kscience.visionforge.compose.zIndex +import space.kscience.visionforge.html.Vision +import space.kscience.visionforge.html.zIndex import space.kscience.visionforge.markup.VisionOfMarkup import space.kscience.visionforge.plotly.asVision import space.kscience.visionforge.solid.* 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 d26bc052..d117d91d 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 @@ -7,7 +7,7 @@ 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.compose.VisionForgeStyles +import space.kscience.visionforge.html.VisionForgeStyles import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication diff --git a/settings.gradle.kts b/settings.gradle.kts index 6ccab6fa..8f4e56b3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,13 +40,9 @@ dependencyResolutionManagement { } include( -// ":ui", -// ":ui:react", -// ":ui:ring", -// ":ui:material", -// ":ui:bootstrap", - ":visionforge-compose-html", ":visionforge-core", + ":visionforge-compose-html", + ":visionforge-compose-mpp", ":visionforge-solid", // ":visionforge-fx", ":visionforge-threejs", diff --git a/ui/README.md b/ui/README.md deleted file mode 100644 index ec08d176..00000000 --- a/ui/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Module ui - - - diff --git a/ui/bootstrap/README.md b/ui/bootstrap/README.md deleted file mode 100644 index 0cc57002..00000000 --- a/ui/bootstrap/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Module bootstrap - - - diff --git a/ui/bootstrap/build.gradle.kts b/ui/bootstrap/build.gradle.kts deleted file mode 100644 index f50ae119..00000000 --- a/ui/bootstrap/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -plugins { - id("space.kscience.gradle.mpp") -} - -val dataforgeVersion: String by rootProject.extra - -kscience{ - js() - jsMain{ - dependencies { - api(project(":visionforge-solid")) - api(project(":ui:react")) - implementation(npm("file-saver", "2.0.2")) - implementation(npm("bootstrap","4.6.0")) - implementation(npm("jquery","3.5.1")) - implementation(npm("popper.js","1.16.1")) - } - } -} \ No newline at end of file diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt deleted file mode 100644 index c0171cb7..00000000 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt +++ /dev/null @@ -1,121 +0,0 @@ -package space.kscience.visionforge.bootstrap - -public fun useBootstrap(){ - kotlinext.js.require("bootstrap/dist/css/bootstrap.min.css") - kotlinext.js.require("bootstrap") -} - -//public inline fun TagConsumer.card(title: String, crossinline block: TagConsumer.() -> Unit) { -// div("card w-100") { -// div("card-body") { -// h3(classes = "card-title") { +title } -// block() -// } -// } -//} - -//public typealias SectionsBuilder = MutableList Unit>> -// -//public fun SectionsBuilder.entry(title: String, builder: DIV.() -> Unit) { -// add(title to builder) -//} - - -//public fun TagConsumer.accordion(id: String, elements: List Unit>>) { -// div("container-fluid") { -// div("accordion") { -// this.id = id -// elements.forEachIndexed { index, (title, builder) -> -// val headerID = "${id}-${index}-heading" -// val collapseID = "${id}-${index}-collapse" -// div("card") { -// div("card-header") { -// this.id = headerID -// h5("mb-0") { -// button(classes = "btn btn-link collapsed", type = ButtonType.button) { -// attributes["data-toggle"] = "collapse" -// attributes["data-target"] = "#$collapseID" -// attributes["aria-expanded"] = "false" -// attributes["aria-controls"] = collapseID -// +title -// } -// } -// } -// div("collapse") { -// this.id = collapseID -// attributes["aria-labelledby"] = headerID -// attributes["data-parent"] = "#$id" -// div("card-body", block = builder) -// } -// } -// } -// } -// } -//} - - -//public fun TagConsumer.accordion(id: String, builder: AccordionBuilder.() -> Unit) { -// val list = ArrayList Unit>>().apply(builder) -// accordion(id, list) -//} - -//public fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer.() -> Unit = {}) { -// clear() -// append { -// accordion("controls") { -// entry("Settings") { -// div("row") { -// div("col-2") { -// label("checkbox-inline") { -// input(type = InputType.checkBox) { -// checked = canvas.axes.visible -// onChangeFunction = { -// canvas.axes.visible = checked -// } -// } -// +"Axes" -// } -// } -// div("col-1") { -// button { -// +"Export" -// onClickFunction = { -// val json = (canvas.content as? SolidGroup)?.let { group -> -// val visionManager = canvas.context.plugins.fetch(SolidManager).visionManager -// visionManager.encodeToString(group) -// } -// if (json != null) { -// saveData(it, "object.json", "text/json") { -// json -// } -// } -// } -// } -// } -// } -// } -// entry("Layers") { -// div("row") { -// (0..11).forEach { layer -> -// div("col-1") { -// label { +layer.toString() } -// input(type = InputType.checkBox) { -// if (layer == 0) { -// checked = true -// } -// onChangeFunction = { -// if (checked) { -// canvas.camera.layers.enable(layer) -// } else { -// canvas.camera.layers.disable(layer) -// } -// } -// } -// } -// } -// } -// } -// } -// block() -// } -//} \ No newline at end of file diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt deleted file mode 100644 index f42235a8..00000000 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt +++ /dev/null @@ -1,77 +0,0 @@ -package space.kscience.visionforge.bootstrap - -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.GlobalScope -import kotlinx.css.* -import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event -import org.w3c.files.Blob -import org.w3c.files.BlobPropertyBag -import react.FC -import react.Props -import react.RBuilder -import react.dom.attrs -import react.dom.button -import react.fc -import space.kscience.visionforge.Vision -import space.kscience.visionforge.encodeToString -import space.kscience.visionforge.react.flexColumn -import space.kscience.visionforge.react.flexRow -import space.kscience.visionforge.react.propertyEditor -import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import styled.css - -private fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) { - event.stopPropagation(); - event.preventDefault(); - - val fileSaver = kotlinext.js.require("file-saver") - val blob = Blob(arrayOf(dataBuilder()), BlobPropertyBag("$mimeType;charset=utf-8")) - fileSaver.saveAs(blob, fileName) -} - -public fun RBuilder.canvasControls(canvasOptions: Canvas3DOptions, vision: Vision?) { - child(CanvasControls) { - attrs { - this.canvasOptions = canvasOptions - this.vision = vision - } - } -} - -public external interface CanvasControlsProps : Props { - public var canvasOptions: Canvas3DOptions - public var vision: Vision? -} - - -public val CanvasControls: FC = fc("CanvasControls") { props -> - flexColumn { - flexRow { - css { - border = Border(1.px, BorderStyle.solid, Color.blue) - padding = Padding(4.px) - } - props.vision?.let { vision -> - button { - +"Export" - attrs { - onClickFunction = { - val json = vision.encodeToString() - saveData(it, "object.json", "text/json") { - json - } - } - } - } - } - } - @OptIn(DelicateCoroutinesApi::class) - propertyEditor( - scope = props.vision?.manager?.context ?: GlobalScope, - properties = props.canvasOptions.meta, - descriptor = Canvas3DOptions.descriptor, - expanded = false - ) - } -} \ No newline at end of file diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt deleted file mode 100644 index b37637fe..00000000 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt +++ /dev/null @@ -1,181 +0,0 @@ -package space.kscience.visionforge.bootstrap - -import kotlinx.html.ButtonType -import kotlinx.html.DIV -import kotlinx.html.id -import kotlinx.html.js.onClickFunction -import react.RBuilder -import react.dom.* -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.NameToken -import space.kscience.dataforge.names.length -import styled.StyledDOMBuilder -import styled.css -import styled.styledDiv -import styled.styledNav - - -public inline fun RBuilder.card(title: String, crossinline block: StyledDOMBuilder
.() -> Unit): Unit = - styledDiv { - css { - +"card" - +"w-100" - } - styledDiv { - css { - +"card-body" - } - h3(classes = "card-title") { - +title - } - block() - } - } - -public fun RBuilder.accordion( - id: String, - elements: List.() -> Unit>>, -): Unit = styledDiv { - css { - +"accordion" - //+"p-1" - } - attrs { - this.id = id - } - elements.forEachIndexed { index, (title, builder) -> - val headerID = "${id}-${index}-heading" - val collapseID = "${id}-${index}-collapse" - div("card p-0 m-0") { - div("card-header") { - attrs { - this.id = headerID - } - h5("mb-0") { - button(classes = "btn btn-link collapsed", type = ButtonType.button) { - attrs { - attributes["data-toggle"] = "collapse" - attributes["data-target"] = "#$collapseID" - attributes["aria-expanded"] = "false" - attributes["aria-controls"] = collapseID - } - +title - } - } - } - div("collapse") { - attrs { - this.id = collapseID - attributes["aria-labelledby"] = headerID - attributes["data-parent"] = "#$id" - } - styledDiv { - css { - +"card-body" - } - builder() - } - } - } - } -} - - -public fun RBuilder.nameCrumbs(name: Name?, rootTitle: String, link: (Name) -> Unit): Unit = styledNav { - css { - +"p-0" - } - attrs { - attributes["aria-label"] = "breadcrumb" - } - ol("breadcrumb") { - li("breadcrumb-item") { - button(classes = "btn btn-link p-0") { - +rootTitle - attrs { - onClickFunction = { - link(Name.EMPTY) - } - } - } - } - if (name != null) { - val tokens = ArrayList(name.length) - name.tokens.forEach { token -> - tokens.add(token) - val fullName = Name(tokens.toList()) - li("breadcrumb-item") { - button(classes = "btn btn-link p-0") { - +token.toString() - attrs { - onClickFunction = { - console.log("Selected = $fullName") - link(fullName) - } - } - } - } - } - } - } -} - -public typealias RSectionsBuilder = MutableList.() -> Unit>> - -public fun RSectionsBuilder.entry(title: String, builder: StyledDOMBuilder
.() -> Unit) { - add(title to builder) -} - -public fun RBuilder.accordion(id: String, builder: RSectionsBuilder.() -> Unit): Unit { - val list = ArrayList.() -> Unit>>().apply(builder) - accordion(id, list) -} - -public enum class ContainerSize(public val suffix: String) { - DEFAULT(""), - SM("-sm"), - MD("-md"), - LG("-lg"), - XL("-xl"), - FLUID("-fluid") -} - -public inline fun RBuilder.container( - size: ContainerSize = ContainerSize.FLUID, - block: StyledDOMBuilder
.() -> Unit, -): Unit = styledDiv { - css { - classes.add("container${size.suffix}") - } - block() -} - - -public enum class GridMaxSize(public val suffix: String) { - NONE(""), - SM("-sm"), - MD("-md"), - LG("-lg"), - XL("-xl") -} - -public inline fun RBuilder.gridColumn( - weight: Int? = null, - maxSize: GridMaxSize = GridMaxSize.NONE, - block: StyledDOMBuilder
.() -> Unit, -): Unit = styledDiv { - val weightSuffix = weight?.let { "-$it" } ?: "" - css { - classes.add("col${maxSize.suffix}$weightSuffix") - } - block() -} - -public inline fun RBuilder.gridRow( - block: StyledDOMBuilder
.() -> Unit, -): Unit = styledDiv { - css { - classes.add("row") - } - block() -} \ No newline at end of file diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt deleted file mode 100644 index 23b5071b..00000000 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt +++ /dev/null @@ -1,86 +0,0 @@ -package space.kscience.visionforge.bootstrap - -import kotlinx.html.DIV -import kotlinx.html.classes -import kotlinx.html.js.onClickFunction -import react.* -import react.dom.attrs -import react.dom.button -import react.dom.li -import react.dom.ul -import space.kscience.visionforge.react.flexColumn -import styled.StyledDOMBuilder -import styled.styledDiv - -public external interface TabProps : PropsWithChildren { - public var id: String - public var title: String? -} - -@JsExport -public val Tab: FC = fc { props -> - props.children() -} - -public external interface TabPaneProps : PropsWithChildren { - public var activeTab: String? -} - -@JsExport -public val TabPane: FC = fc("TabPane") { props -> - var activeTab: String? by useState(props.activeTab) - - val children: Array?> = Children.map(props.children) { - it.asElementOrNull() - } ?: emptyArray() - - val childrenProps = children.mapNotNull { - it?.props?.unsafeCast() - } - - flexColumn { - ul("nav nav-tabs") { - childrenProps.forEach { cp -> - li("nav-item") { - button(classes = "nav-link") { - +(cp.title ?: cp.id) - attrs { - if (cp.id == activeTab) { - classes = classes + "active" - } - onClickFunction = { - activeTab = cp.id - } - } - } - } - } - } - children.find { (it?.props?.unsafeCast())?.id == activeTab }?.let { - child(it) - } - } -} - -public class TabBuilder(internal val parentBuilder: RBuilder) { - public fun tab(id: String, title: String? = null, builder: StyledDOMBuilder
.() -> Unit) { - parentBuilder.child(Tab) { - attrs { - this.id = id - this.title = title - } - styledDiv { - builder() - } - } - } -} - -public inline fun RBuilder.tabPane(activeTab: String? = null, crossinline builder: TabBuilder.() -> Unit) { - child(TabPane) { - attrs { - this.activeTab = activeTab - } - TabBuilder(this).builder() - } -} diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt deleted file mode 100644 index 0d5578a7..00000000 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt +++ /dev/null @@ -1,80 +0,0 @@ -package space.kscience.visionforge.bootstrap - -import kotlinx.css.* -import react.FC -import react.PropsWithChildren -import react.RBuilder -import react.dom.h2 -import react.fc -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.isEmpty -import space.kscience.visionforge.Vision -import space.kscience.visionforge.react.visionTree -import space.kscience.visionforge.solid.SolidGroup -import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import styled.css -import styled.styledDiv - -public external interface ThreeControlsProps : PropsWithChildren { - public var canvasOptions: Canvas3DOptions - public var vision: Vision? - public var selected: Name? - public var onSelect: (Name) -> Unit -} - -@JsExport -public val ThreeControls: FC = fc { props -> - tabPane(if (props.selected != null) "Properties" else null) { - tab("Canvas") { - card("Canvas configuration") { - canvasControls(props.canvasOptions, props.vision) - } - } - tab("Tree") { - css { - border = Border(1.px, BorderStyle.solid, Color.lightGray) - padding = Padding(10.px) - } - h2 { +"Object tree" } - styledDiv { - css { - flex = Flex(1.0, 1.0, FlexBasis.inherit) - } - props.vision?.let { - visionTree(it, props.selected, props.onSelect) - } - } - } - tab("Properties") { - props.selected.let { selected -> - val selectedObject: Vision? = when { - selected == null -> null - selected.isEmpty() -> props.vision - else -> (props.vision as? SolidGroup)?.get(selected) - } - if (selectedObject != null) { - visionPropertyEditor(selectedObject, key = selected) - } - } - } - this.parentBuilder.run { - props.children() - } - } -} - -public fun RBuilder.threeControls( - canvasOptions: Canvas3DOptions, - vision: Vision?, - selected: Name?, - onSelect: (Name) -> Unit = {}, - builder: TabBuilder.() -> Unit = {}, -): Unit = child(ThreeControls) { - attrs { - this.canvasOptions = canvasOptions - this.vision = vision - this.selected = selected - this.onSelect = onSelect - } - TabBuilder(this).builder() -} \ No newline at end of file diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt deleted file mode 100644 index 8264ae43..00000000 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ /dev/null @@ -1,71 +0,0 @@ -package space.kscience.visionforge.bootstrap - -import org.w3c.dom.Element -import react.RBuilder -import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.isEmpty -import space.kscience.visionforge.Vision -import space.kscience.visionforge.getStyle -import space.kscience.visionforge.react.EditorPropertyState -import space.kscience.visionforge.react.PropertyEditor -import space.kscience.visionforge.react.metaViewer -import space.kscience.visionforge.react.render -import space.kscience.visionforge.root -import space.kscience.visionforge.solid.SolidReference -import space.kscience.visionforge.styles - -public fun RBuilder.visionPropertyEditor( - vision: Vision, - descriptor: MetaDescriptor? = vision.descriptor, - key: Any? = null, -) { - - card("Properties") { - child(PropertyEditor) { - attrs { - this.key = key?.toString() - this.meta = vision.properties.root() - this.updates = vision.properties.changes - this.descriptor = descriptor - this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") - this.getPropertyState = { name -> - val ownMeta = vision.properties.own?.get(name) - if (ownMeta != null && !ownMeta.isEmpty()) { - EditorPropertyState.Defined - } else if (vision.properties.root().getValue(name) != null) { - // TODO differentiate - EditorPropertyState.Default() - } else { - EditorPropertyState.Undefined - } - } - } - } - } - val styles = if (vision is SolidReference) { - (vision.styles + vision.prototype.styles).distinct() - } else { - vision.styles - } - if (styles.isNotEmpty()) { - card("Styles") { - accordion("styles") { - styles.forEach { styleName -> - val style = vision.getStyle(styleName) - if (style != null) { - entry(styleName) { - metaViewer(style) - } - } - } - } - } - } -} - -public fun Element.visionPropertyEditor( - item: Vision, - descriptor: MetaDescriptor? = item.descriptor, -): Unit = space.kscience.visionforge.react.createRoot(this).render { - visionPropertyEditor(item, descriptor = descriptor) -} \ No newline at end of file diff --git a/ui/bootstrap/src/jsMain/resources/css/custom-bootstrap.css b/ui/bootstrap/src/jsMain/resources/css/custom-bootstrap.css deleted file mode 100644 index ecb7ee5f..00000000 --- a/ui/bootstrap/src/jsMain/resources/css/custom-bootstrap.css +++ /dev/null @@ -1,56 +0,0 @@ -/*full height*/ -html, body { - height: 100%; - width: 100%; -} - -.container-fluid { height: inherit; } - -/* Remove default bullets */ -ul, .tree { - list-style-type: none; -} - -/* Style the caret/arrow */ -.tree-caret { - cursor: pointer; - user-select: none; /* Prevent text selection */ -} - -/* Create the caret/arrow with a unicode, and style it */ -.tree-caret::before { - content: "\25B6"; - color: black; - display: inline-block; - margin-right: 6px; -} - -.tree-leaf{ - user-select: none; - display: inline-block; -} - -.tree-leaf::before { - content: "\25C6"; - color: black; - display: inline-block; - margin-right: 6px; -} - - -/* Rotate the caret/arrow icon when clicked on (using JavaScript) */ -.tree-caret-down::before { - transform: rotate(90deg); -} - -.tree-label-inactive { - color: lightgrey; -} - -.tree-label-selected{ - background-color: lightblue; -} - -.no-padding{ - padding: 0; -} \ No newline at end of file diff --git a/ui/react/README.md b/ui/react/README.md deleted file mode 100644 index 9f862213..00000000 --- a/ui/react/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Module react - - - diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts deleted file mode 100644 index 1770feeb..00000000 --- a/ui/react/build.gradle.kts +++ /dev/null @@ -1,16 +0,0 @@ -plugins { - id("space.kscience.gradle.mpp") -} - -kscience { - js() - jsMain { - dependencies { - api(projects.visionforgeSolid) - api("org.jetbrains.kotlin-wrappers:kotlin-styled") - api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") -// implementation(npm("react-select","4.3.0")) - api(projects.visionforgeThreejs) - } - } -} \ No newline at end of file diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt deleted file mode 100644 index 651c9d31..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt +++ /dev/null @@ -1,149 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.css.Align -import kotlinx.css.alignItems -import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event -import react.* -import react.dom.a -import react.dom.attrs -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.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 -import styled.css -import styled.styledDiv -import styled.styledSpan - -public external interface MetaViewerProps : Props { - /** - * Root meta - */ - public var root: Meta - - /** - * The title of root node - */ - public var rootName: String? - - /** - * Full path to the displayed node in [root]. Could be empty - */ - public var name: Name - - /** - * Root descriptor - */ - public var descriptor: MetaDescriptor? -} - -private val MetaViewerItem: FC = fc("MetaViewerItem") { props -> - metaViewerItem(props) -} - -private fun RBuilder.metaViewerItem(props: MetaViewerProps) { - var expanded: Boolean by useState { true } - val item = props.root[props.name] - val descriptorItem: MetaDescriptor? = props.descriptor?.get(props.name) - val actualValue = item?.value ?: descriptorItem?.defaultValue - val actualMeta = item ?: descriptorItem?.defaultNode - - val token = props.name.lastOrNull()?.toString() ?: props.rootName ?: "" - - val expanderClick: (Event) -> Unit = { - expanded = !expanded - } - - flexRow { - css { - alignItems = Align.center - } - if (actualMeta?.isLeaf == false) { - styledSpan { - css { - +TreeStyles.treeCaret - if (expanded) { - +TreeStyles.treeCaredDown - } - } - attrs { - onClickFunction = expanderClick - } - } - } - - styledSpan { - css { - +TreeStyles.treeLabel - if (item == null) { - +TreeStyles.treeLabelInactive - } - } - +token - } - styledDiv { - a { - +actualValue.toString() - } - } - } - if (expanded) { - flexColumn { - css { - +TreeStyles.tree - } - val keys = buildSet { - descriptorItem?.children?.keys?.forEach { - add(NameToken(it)) - } - actualMeta!!.items.keys.let { addAll(it) } - } - - keys.filter { !it.body.startsWith("@") }.forEach { token -> - styledDiv { - css { - +TreeStyles.treeItem - } - child(MetaViewerItem) { - attrs { - this.key = props.name.toString() - this.root = props.root - this.name = props.name + token - this.descriptor = props.descriptor - } - } - //configEditor(props.root, props.name + token, props.descriptor, props.default) - } - } - } - } - - -} - -@JsExport -public val MetaViewer: FC = fc("MetaViewer") { props -> - child(MetaViewerItem) { - attrs { - this.key = "" - this.root = props.root - this.name = Name.EMPTY - this.descriptor = props.descriptor - } - } -} - -public fun RBuilder.metaViewer(meta: Meta, descriptor: MetaDescriptor? = null, key: Any? = null) { - child(MetaViewer) { - attrs { - this.key = key?.toString() ?: "" - this.root = meta - this.descriptor = descriptor - } - } -} diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt deleted file mode 100644 index fc635d21..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ /dev/null @@ -1,38 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.html.js.onChangeFunction -import org.w3c.dom.HTMLOptionElement -import org.w3c.dom.HTMLSelectElement -import org.w3c.dom.asList -import org.w3c.dom.events.Event -import react.FC -import react.dom.attrs -import react.dom.option -import react.dom.select -import react.fc -import space.kscience.dataforge.meta.asValue -import space.kscience.dataforge.meta.descriptors.allowedValues -import space.kscience.dataforge.meta.string - -@JsExport -public val MultiSelectChooser: FC = fc("MultiSelectChooser") { props -> - val onChange: (Event) -> Unit = { event: Event -> - val newSelected = (event.target as HTMLSelectElement).selectedOptions.asList() - .map { (it as HTMLOptionElement).value.asValue() } - props.onValueChange(newSelected.asValue()) - } - - select { - attrs { - multiple = true - values = (props.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } - onChangeFunction = onChange - } - props.descriptor?.allowedValues?.forEach { optionValue -> - option { - +optionValue.string - } - } - - } -} \ No newline at end of file diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt deleted file mode 100644 index b13e7304..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ /dev/null @@ -1,277 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import kotlinx.css.* -import kotlinx.css.properties.TextDecoration -import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event -import react.* -import react.dom.attrs -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 -import styled.css -import styled.styledButton -import styled.styledDiv -import styled.styledSpan - -/** - * The display state of a property - */ -public sealed class EditorPropertyState { - public object Defined : EditorPropertyState() - public class Default(public val source: String = "unknown") : EditorPropertyState() - - public object Undefined : EditorPropertyState() - -} - - -public external interface PropertyEditorProps : Props { - - /** - * Root config object - always non-null - */ - public var meta: MutableMeta - - public var getPropertyState: (Name) -> EditorPropertyState - - public var scope: CoroutineScope - - public var updates: Flow - - /** - * Full path to the displayed node in [meta]. Could be empty - */ - public var name: Name - - /** - * Root descriptor - */ - public var descriptor: MetaDescriptor? - - /** - * Initial expanded state - */ - public var expanded: Boolean? -} - -private val PropertyEditorItem: FC = fc("PropertyEditorItem") { props -> - propertyEditorItem(props) -} - -private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { - var expanded: Boolean by useState { props.expanded ?: true } - val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) } - var property: MutableMeta by useState { props.meta.getOrCreate(props.name) } - var editorPropertyState: EditorPropertyState by useState { props.getPropertyState(props.name) } - - - val keys = useMemo(descriptor) { - buildSet { - descriptor?.children?.filterNot { - it.key.startsWith("@") || it.value.hidden - }?.forEach { - add(NameToken(it.key)) - } - //ownProperty?.items?.keys?.filterNot { it.body.startsWith("@") }?.let { addAll(it) } - } - } - - val token = props.name.lastOrNull()?.toString() ?: "Properties" - - fun update() { - property = props.meta.getOrCreate(props.name) - editorPropertyState = props.getPropertyState(props.name) - } - - useEffect(props.meta) { - val job = props.updates.onEach { updatedName -> - if (updatedName == props.name) { - update() - } - }.launchIn(props.scope) - - cleanup { - job.cancel() - } - } - - val expanderClick: (Event) -> Unit = { - expanded = !expanded - } - - val removeClick: (Event) -> Unit = { - props.meta.remove(props.name) - update() - } - - - - flexRow { - css { - alignItems = Align.center - } - if (keys.isNotEmpty()) { - styledSpan { - css { - +TreeStyles.treeCaret - if (expanded) { - +TreeStyles.treeCaredDown - } - } - attrs { - onClickFunction = expanderClick - } - } - } - styledSpan { - css { - +TreeStyles.treeLabel - if (editorPropertyState != EditorPropertyState.Defined) { - +TreeStyles.treeLabelInactive - } - } - +token - } - if (!props.name.isEmpty() && descriptor?.valueRestriction != ValueRestriction.ABSENT) { - styledDiv { - css { - //+TreeStyles.resizeableInput - width = 160.px - margin = Margin(1.px, 5.px) - } - ValueChooser { - attrs { - this.descriptor = descriptor - this.state = editorPropertyState - this.value = property.value - this.onValueChange = { - property.value = it - editorPropertyState = props.getPropertyState(props.name) - } - } - } - } - - styledButton { - css { - width = 24.px - alignSelf = Align.stretch - margin = Margin(1.px, 5.px) - backgroundColor = Color.white - borderStyle = BorderStyle.solid - borderRadius = 2.px - textAlign = TextAlign.center - textDecoration = TextDecoration.none - cursor = Cursor.pointer - disabled { - cursor = Cursor.auto - borderStyle = BorderStyle.dashed - color = Color.lightGray - } - } - +"\u00D7" - attrs { - if (editorPropertyState != EditorPropertyState.Defined) { - disabled = true - } else { - onClickFunction = removeClick - } - } - } - } - } - if (expanded) { - flexColumn { - css { - +TreeStyles.tree - } - keys.forEach { token -> - styledDiv { - css { - +TreeStyles.treeItem - } - child(PropertyEditorItem) { - attrs { - this.key = props.name.toString() - this.meta = props.meta - this.name = props.name + token - this.descriptor = props.descriptor - this.scope = props.scope - this.getPropertyState = { props.getPropertyState(props.name + token) } - this.updates = props.updates - } - } - //configEditor(props.root, props.name + token, props.descriptor, props.default) - } - } - } - } -} - -@JsExport -public val PropertyEditor: FC = fc("PropertyEditor") { props -> - child(PropertyEditorItem) { - attrs { - this.key = "" - this.meta = props.meta - this.name = Name.EMPTY - this.descriptor = props.descriptor - this.expanded = props.expanded - this.scope = props.scope - this.getPropertyState = props.getPropertyState - this.updates = props.updates - } - } -} - -@OptIn(ExperimentalCoroutinesApi::class) -public fun RBuilder.propertyEditor( - scope: CoroutineScope, - properties: ObservableMutableMeta, - descriptor: MetaDescriptor? = null, - key: Any? = null, - expanded: Boolean? = null, -) { - child(PropertyEditor) { - attrs { - this.meta = properties - this.descriptor = descriptor - this.key = key?.toString() ?: "" - this.expanded = expanded - this.scope = scope - this.getPropertyState = { name -> - if (properties[name] != null) { - EditorPropertyState.Defined - } else if (descriptor?.get(name)?.defaultValue != null) { - EditorPropertyState.Default("descriptor") - } else { - EditorPropertyState.Undefined - } - } - this.updates = callbackFlow { - properties.onChange(scope) { name -> - scope.launch { - send(name) - } - } - - invokeOnClose { - properties.removeListener(scope) - } - } - } - } -} \ No newline at end of file diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt deleted file mode 100644 index bec34fc1..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ /dev/null @@ -1,78 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.css.pct -import kotlinx.css.width -import kotlinx.html.InputType -import kotlinx.html.js.onChangeFunction -import kotlinx.html.js.onInputFunction -import org.w3c.dom.HTMLInputElement -import org.w3c.dom.events.Event -import react.FC -import react.dom.attrs -import react.fc -import react.useState -import space.kscience.dataforge.meta.asValue -import space.kscience.dataforge.meta.descriptors.ValueRestriction -import space.kscience.dataforge.meta.double -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.string -import styled.css -import styled.styledInput - -@JsExport -public val RangeValueChooser: FC = fc("RangeValueChooser") { props -> - var innerValue by useState(props.value?.double) - var rangeDisabled: Boolean by useState(props.state != EditorPropertyState.Defined) - - val handleDisable: (Event) -> Unit = { - val checkBoxValue = (it.target as HTMLInputElement).checked - rangeDisabled = !checkBoxValue - props.onValueChange( - if (!checkBoxValue) { - null - } else { - innerValue?.asValue() - } - ) - } - - val handleChange: (Event) -> Unit = { - val newValue = (it.target as HTMLInputElement).value - props.onValueChange(newValue.toDoubleOrNull()?.asValue()) - innerValue = newValue.toDoubleOrNull() - } - - flexRow { - if (props.descriptor?.valueRestriction != ValueRestriction.REQUIRED) { - styledInput(type = InputType.checkBox) { - attrs { - defaultChecked = rangeDisabled.not() - onChangeFunction = handleDisable - } - } - } - - styledInput(type = InputType.range) { - css { - width = 100.pct - } - attrs { - disabled = rangeDisabled - value = innerValue?.toString() ?: "" -// onChangeFunction = handleChange - onInputFunction = handleChange - val minValue = props.descriptor?.attributes?.get("min").string - minValue?.let { - min = it - } - val maxValue = props.descriptor?.attributes?.get("max").string - maxValue?.let { - max = it - } - props.descriptor?.attributes?.get("step").string?.let { - step = it - } - } - } - } -} \ No newline at end of file diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt deleted file mode 100644 index 8cfa515d..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt +++ /dev/null @@ -1,55 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.css.* -import org.w3c.dom.Element -import react.* -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.request -import space.kscience.dataforge.names.Name -import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.ThreeCanvas -import space.kscience.visionforge.solid.three.ThreePlugin -import styled.css -import styled.styledDiv - -public external interface ThreeCanvasProps : Props { - public var context: Context - public var options: Canvas3DOptions? - public var solid: Solid? - public var selected: Name? -} - -public val ThreeCanvasComponent: FC = fc("ThreeCanvasComponent") { props -> - val elementRef = useRef(null) - var canvas by useState(null) - - val three: ThreePlugin = useMemo(props.context) { props.context.request(ThreePlugin) } - - useEffect(props.solid, props.options, elementRef) { - if (canvas == null) { - val element = elementRef.current ?: error("Canvas element not found") - canvas = ThreeCanvas(three, element, props.options ?: Canvas3DOptions()) - } - } - - useEffect(canvas, props.solid) { - props.solid?.let { obj -> - canvas?.render(obj) - } - } - - useEffect(canvas, props.selected) { - canvas?.select(props.selected) - } - - styledDiv { - css { - maxWidth = 100.vw - maxHeight = 100.vh - width = 100.pct - height = 100.pct - } - ref = elementRef - } -} \ No newline at end of file diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt deleted file mode 100644 index 109d0256..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt +++ /dev/null @@ -1,69 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.css.* -import kotlinx.css.properties.deg -import kotlinx.css.properties.rotate -import styled.StyleSheet - -public object TreeStyles : StyleSheet("treeStyles", true) { - /** - * Remove default bullets - */ - public val tree: RuleSet by css { - paddingLeft = 5.px - marginLeft = 0.px - listStyleType = ListStyleType.none - } - - /** - * Style the caret/arrow - */ - public val treeCaret: RuleSet by css { - cursor = Cursor.pointer - userSelect = UserSelect.none - /* Create the caret/arrow with a unicode, and style it */ - before { - content = "\u25B6".quoted - color = Color.black - display = Display.inlineBlock - marginRight = 6.px - } - } - - /** - * Rotate the caret/arrow icon when clicked on (using JavaScript) - */ - public val treeCaredDown:RuleSet by css { - before { - content = "\u25B6".quoted - color = Color.black - display = Display.inlineBlock - marginRight = 6.px - transform.rotate(90.deg) - } - } - - public val treeItem:RuleSet by css { - alignItems = Align.center - paddingLeft = 10.px - borderLeftStyle = BorderStyle.dashed - borderLeftWidth = 1.px - borderLeftColor = Color.lightGray - } - - public val treeLabel:RuleSet by css { - border = Border.none - padding = Padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) - textAlign = TextAlign.left - flex = Flex(1.0) - } - - public val treeLabelInactive: RuleSet by css { - color = Color.lightGray - } - - public val treeLabelSelected:RuleSet by css { - backgroundColor = Color.lightBlue - } - -} \ No newline at end of file diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt deleted file mode 100644 index 6212a456..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt +++ /dev/null @@ -1,126 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.css.* -import kotlinx.css.properties.TextDecoration -import kotlinx.css.properties.TextDecorationLine -import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event -import react.* -import react.dom.attrs -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.lastOrNull -import space.kscience.dataforge.names.plus -import space.kscience.dataforge.names.startsWith -import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionGroup -import space.kscience.visionforge.asSequence -import space.kscience.visionforge.isEmpty -import styled.css -import styled.styledDiv -import styled.styledSpan - -public external interface ObjectTreeProps : Props { - public var name: Name - public var selected: Name? - public var obj: Vision - public var clickCallback: (Name) -> Unit -} - -private val TreeLabel = fc { props -> - val token = useMemo(props.name) { props.name.lastOrNull()?.toString() ?: "World" } - styledSpan { - css { - +TreeStyles.treeLabel - color = Color("#069") - cursor = Cursor.pointer - hover { - textDecoration = TextDecoration(setOf(TextDecorationLine.underline)) - } - if (props.name == props.selected) { - +TreeStyles.treeLabelSelected - } - } - +token - attrs { - onClickFunction = { props.clickCallback(props.name) } - } - } -} - -private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { - var expanded: Boolean by useState { props.selected?.startsWith(props.name) ?: false } - - val onClick: (Event) -> Unit = { - expanded = !expanded - } - - val obj = props.obj - - //display as node if any child is visible - if (obj is VisionGroup) { - flexRow { - if (obj.children.keys.any { !it.body.startsWith("@") }) { - styledSpan { - css { - +TreeStyles.treeCaret - if (expanded) { - +TreeStyles.treeCaredDown - } - } - attrs { - onClickFunction = onClick - } - } - } - child(TreeLabel, props = props) - } - if (expanded) { - flexColumn { - css { - +TreeStyles.tree - } - obj.children.asSequence() - .filter { !it.first.toString().startsWith("@") } // ignore statics and other hidden children - .sortedBy { (it.second as? VisionGroup)?.children?.isEmpty() ?: true } // ignore empty groups - .forEach { (childToken, child) -> - styledDiv { - css { - +TreeStyles.treeItem - } - child(ObjectTree) { - attrs { - this.name = props.name + childToken - this.obj = child - this.selected = props.selected - this.clickCallback = props.clickCallback - } - } - } - } - } - } - } else { - child(TreeLabel, props = props) - } -} - -@JsExport -public val ObjectTree: FC = fc("ObjectTree") { props -> - visionTree(props) -} - -public fun RBuilder.visionTree( - vision: Vision, - selected: Name? = null, - clickCallback: (Name) -> Unit = {}, -) { - child(ObjectTree) { - attrs { - this.name = Name.EMPTY - this.obj = vision - this.selected = selected - this.clickCallback = clickCallback - } - } -} - diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/createRoot.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/createRoot.kt deleted file mode 100644 index fec86770..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/createRoot.kt +++ /dev/null @@ -1,17 +0,0 @@ - -@file:JsModule("react-dom/client") -@file:JsNonModule - -package space.kscience.visionforge.react - -import org.w3c.dom.Element -import react.dom.client.Root -import react.dom.client.RootOptions - -/** - * Compatibility method to work with old browser API - */ -public external fun createRoot( - container: Element, - options: RootOptions = definedExternally, -): Root diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ext.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ext.kt deleted file mode 100644 index ae47fa65..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ext.kt +++ /dev/null @@ -1,10 +0,0 @@ -package space.kscience.visionforge.react - -import react.Props -import react.RBuilder -import react.createElement -import react.dom.client.Root - -public fun Root.render(block: RBuilder.() -> Unit) { - render(createElement(block)) -} \ No newline at end of file diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/layout.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/layout.kt deleted file mode 100644 index 11a13561..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/layout.kt +++ /dev/null @@ -1,31 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.css.Display -import kotlinx.css.FlexDirection -import kotlinx.css.display -import kotlinx.css.flexDirection -import kotlinx.html.DIV -import react.RBuilder -import styled.StyledDOMBuilder -import styled.css -import styled.styledDiv - -public inline fun RBuilder.flexColumn( - block: StyledDOMBuilder
.() -> Unit -): Unit = styledDiv { - css { - display = Display.flex - flexDirection = FlexDirection.column - } - block() -} - -public inline fun RBuilder.flexRow( - block: StyledDOMBuilder
.() -> Unit -): Unit = styledDiv { - css { - display = Display.flex - flexDirection = FlexDirection.row - } - block() -} \ No newline at end of file diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt deleted file mode 100644 index 5d0c7c3d..00000000 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ /dev/null @@ -1,175 +0,0 @@ -package space.kscience.visionforge.react - -import kotlinx.css.* -import kotlinx.html.InputType -import kotlinx.html.js.onChangeFunction -import kotlinx.html.js.onKeyDownFunction -import org.w3c.dom.HTMLInputElement -import org.w3c.dom.HTMLSelectElement -import org.w3c.dom.events.Event -import react.FC -import react.Props -import react.dom.attrs -import react.dom.option -import react.fc -import react.useState -import space.kscience.dataforge.meta.* -import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.allowedValues -import space.kscience.visionforge.Colors -import space.kscience.visionforge.widgetType -import styled.css -import styled.styledInput -import styled.styledSelect -import three.math.Color - -public external interface ValueChooserProps : Props { - public var descriptor: MetaDescriptor? - public var state: EditorPropertyState - public var value: Value? - public var onValueChange: (Value?) -> Unit -} - -@JsExport -public val StringValueChooser: FC = fc("StringValueChooser") { props -> - var value by useState(props.value?.string ?: "") - val keyDown: (Event) -> Unit = { event -> - if (event.type == "keydown" && event.asDynamic().key == "Enter") { - value = (event.target as HTMLInputElement).value - props.onValueChange(value.asValue()) - } - } - val handleChange: (Event) -> Unit = { - value = (it.target as HTMLInputElement).value - } - styledInput(type = InputType.text) { - css { - width = 100.pct - } - attrs { - this.value = value - onKeyDownFunction = keyDown - onChangeFunction = handleChange - } - } -} - -@JsExport -public val BooleanValueChooser: FC = fc("BooleanValueChooser") { props -> - val handleChange: (Event) -> Unit = { - val newValue = (it.target as HTMLInputElement).checked - props.onValueChange(newValue.asValue()) - } - styledInput(type = InputType.checkBox) { - css { - width = 100.pct - } - attrs { - //this.attributes["indeterminate"] = (props.item == null).toString() - checked = props.value?.boolean ?: false - onChangeFunction = handleChange - } - } -} - -@JsExport -public val NumberValueChooser: FC = fc("NumberValueChooser") { props -> - var innerValue by useState(props.value?.string ?: "") - val keyDown: (Event) -> Unit = { event -> - if (event.type == "keydown" && event.asDynamic().key == "Enter") { - innerValue = (event.target as HTMLInputElement).value - val number = innerValue.toDoubleOrNull() - if (number == null) { - console.error("The input value $innerValue is not a number") - } else { - props.onValueChange(number.asValue()) - } - } - } - val handleChange: (Event) -> Unit = { - innerValue = (it.target as HTMLInputElement).value - } - styledInput(type = InputType.number) { - css { - width = 100.pct - } - attrs { - value = innerValue - onKeyDownFunction = keyDown - onChangeFunction = handleChange - props.descriptor?.attributes?.get("step").string?.let { - step = it - } - props.descriptor?.attributes?.get("min").string?.let { - min = it - } - props.descriptor?.attributes?.get("max").string?.let { - max = it - } - } - } -} - -@JsExport -public val ComboValueChooser: FC = fc("ComboValueChooser") { props -> - var selected by useState(props.value?.string ?: "") - val handleChange: (Event) -> Unit = { - selected = (it.target as HTMLSelectElement).value - props.onValueChange(selected.asValue()) - } - styledSelect { - css { - width = 100.pct - } - props.descriptor?.allowedValues?.forEach { - option { - +it.string - } - } - attrs { - this.value = props.value?.string ?: "" - multiple = false - onChangeFunction = handleChange - } - } -} - -@JsExport -public val ColorValueChooser: FC = fc("ColorValueChooser") { props -> - val handleChange: (Event) -> Unit = { - props.onValueChange((it.target as HTMLInputElement).value.asValue()) - } - styledInput(type = InputType.color) { - css { - width = 100.pct - margin = Margin(0.px) - } - attrs { - this.value = props.value?.let { value -> - if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) - else "#" + Color(value.string).getHexString() - } ?: "#000000" - onChangeFunction = handleChange - } - } -} - -@JsExport -public val ValueChooser: FC = fc("ValueChooser") { props -> - val rawInput by useState(false) - - val descriptor = props.descriptor - val type = descriptor?.valueTypes?.firstOrNull() - - when { - rawInput -> child(StringValueChooser, props) - descriptor?.widgetType == "color" -> child(ColorValueChooser, props) - descriptor?.widgetType == "multiSelect" -> child(MultiSelectChooser, props) - descriptor?.widgetType == "range" -> child(RangeValueChooser, props) - type == ValueType.BOOLEAN -> child(BooleanValueChooser, props) - type == ValueType.NUMBER -> child(NumberValueChooser, props) - descriptor?.allowedValues?.isNotEmpty() ?: false -> child(ComboValueChooser, props) - //TODO handle lists - else -> child(StringValueChooser, props) - } -} diff --git a/ui/ring/README.md b/ui/ring/README.md deleted file mode 100644 index 6cdcbb60..00000000 --- a/ui/ring/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Module ring - - - diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts deleted file mode 100644 index d1f2ff72..00000000 --- a/ui/ring/build.gradle.kts +++ /dev/null @@ -1,25 +0,0 @@ -plugins { - id("space.kscience.gradle.mpp") -} - -val dataforgeVersion: String by rootProject.extra - -kscience{ - js{ - useCommonJs() - browser { - commonWebpackConfig { - cssSupport{ - enabled.set(false) - } - } - } - } - jsMain{ - api(projects.ui.react) - api("org.jetbrains.kotlin-wrappers:kotlin-ring-ui") - - implementation(npm("core-js","3.12.1")) - implementation(npm("file-saver", "2.0.2")) - } -} \ No newline at end of file diff --git a/ui/ring/src/jsMain/kotlin/ringui/Loader.kt b/ui/ring/src/jsMain/kotlin/ringui/Loader.kt deleted file mode 100644 index b7bc63a9..00000000 --- a/ui/ring/src/jsMain/kotlin/ringui/Loader.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:JsModule("@jetbrains/ring-ui/components/loader/loader") -@file:JsNonModule - -package ringui - -import react.ComponentClass -import react.PropsWithClassName - - -// https://github.com/JetBrains/ring-ui/blob/master/components/loader/loader.js -public external interface LoaderProps : PropsWithClassName { - public var size: Number - public var colors: Array - public var message: String - public var stop: Boolean - public var deterministic: Boolean -} - -@JsName("default") -public external val Loader: ComponentClass \ No newline at end of file diff --git a/ui/ring/src/jsMain/kotlin/ringui/LoaderScreen.kt b/ui/ring/src/jsMain/kotlin/ringui/LoaderScreen.kt deleted file mode 100644 index d662ee2b..00000000 --- a/ui/ring/src/jsMain/kotlin/ringui/LoaderScreen.kt +++ /dev/null @@ -1,16 +0,0 @@ -@file:JsModule("@jetbrains/ring-ui/components/loader-screen/loader-screen") -@file:JsNonModule - -package ringui - -import react.ComponentClass -import react.PropsWithClassName - -// https://github.com/JetBrains/ring-ui/blob/master/components/loader-screen/loader-screen.js -public external interface LoaderScreenProps : PropsWithClassName { - public var containerClassName: String - public var message: String -} - -@JsName("default") -public external val LoaderScreen: ComponentClass \ No newline at end of file diff --git a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt deleted file mode 100644 index 6ae2ec62..00000000 --- a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ /dev/null @@ -1,212 +0,0 @@ -package space.kscience.visionforge.ring - -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.async -import kotlinx.coroutines.launch -import kotlinx.css.* -import react.* -import react.dom.b -import react.dom.div -import react.dom.p -import react.dom.span -import ringui.* -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.NameToken -import space.kscience.dataforge.names.isEmpty -import space.kscience.dataforge.names.length -import space.kscience.visionforge.* -import space.kscience.visionforge.react.* -import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidGroup -import space.kscience.visionforge.solid.Solids -import space.kscience.visionforge.solid.solidGroup -import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import styled.css -import styled.styledDiv - -public external interface ThreeCanvasWithControlsProps : Props { - public var solids: Solids - public var builderOfSolid: Deferred - public var selected: Name? - public var options: Canvas3DOptions? - public var additionalTabs: Map Unit>? -} - -private val ThreeCanvasWithControlsProps.context get() = solids.context - -public fun ThreeCanvasWithControlsProps.solid(block: SolidGroup.() -> Unit) { - builderOfSolid = context.async { - solids.solidGroup(null, block) - } -} - -public fun ThreeCanvasWithControlsProps.options(block: Canvas3DOptions.() -> Unit) { - options = Canvas3DOptions(block) -} - -public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.() -> Unit) { - additionalTabs = (additionalTabs ?: emptyMap()) + (title to block) -} - - -public fun RBuilder.nameCrumbs(name: Name?, link: (Name) -> Unit): Unit = styledDiv { - div { - Link { - attrs { - onClick = { - link(Name.EMPTY) - } - } - +"\u2302" - } - - if (name != null) { - val tokens = ArrayList(name.length) - name.tokens.forEach { token -> - tokens.add(token) - val fullName = Name(tokens.toList()) - span { +"." } - Link { - +token.toString() - attrs { - onClick = { - console.log("Selected = $fullName") - link(fullName) - } - } - } - } - } - } - -} - -@JsExport -public val ThreeCanvasWithControls: FC = fc("ThreeViewWithControls") { props -> - var selected: Name? by useState { props.selected } - var solid: Solid? by useState(null) - - useEffect { - props.context.launch { - solid = props.builderOfSolid.await() - //ensure that the solid is properly rooted - if (solid?.parent == null) { - solid?.setAsRoot(props.context.visionManager) - } - } - } - - val onSelect: (Name?) -> Unit = { - selected = it - } - - val options = useMemo(props.options) { - (props.options ?: Canvas3DOptions()).apply { - this.onSelect = onSelect - } - } - - val selectedVision: Vision? = useMemo(props.builderOfSolid, selected) { - selected?.let { - when { - it.isEmpty() -> solid - else -> (solid as? SolidGroup)?.get(it) - } - } - } - - - flexRow { - css { - height = 100.pct - width = 100.pct - flexWrap = FlexWrap.wrap - alignItems = Align.stretch - alignContent = Align.stretch - } - - flexColumn { - css { - height = 100.pct - minWidth = 600.px - flex = Flex(10.0, 1.0, FlexBasis("600px")) - position = Position.relative - } - - if (solid == null) { - LoaderScreen { - attrs { - message = "Loading Three vision" - } - } - } else { - child(ThreeCanvasComponent) { - attrs { - this.context = props.context - this.solid = solid - this.selected = selected - this.options = options - } - } - } - - selectedVision?.let { vision -> - styledDiv { - css { - position = Position.absolute - top = 5.px - right = 5.px - width = 450.px - } - Island { - IslandHeader { - attrs { - border = true - } - nameCrumbs(selected) { selected = it } - } - IslandContent { - child(PropertyEditor) { - attrs { - this.key = selected.toString() - this.meta = vision.properties.root() - this.updates = vision.properties.changes - this.descriptor = vision.descriptor - this.scope = props.context - this.getPropertyState = { name -> - if (vision.properties.own?.get(name) != null) { - EditorPropertyState.Defined - } else if (vision.properties.root()[name] != null) { - // TODO differentiate - EditorPropertyState.Default() - } else { - EditorPropertyState.Undefined - } - } - } - } - vision.styles.takeIf { it.isNotEmpty() }?.let { styles -> - p { - b { +"Styles: " } - +styles.joinToString(separator = ", ") - } - } - } - } - } - } - } - flexColumn { - css { - padding = Padding(4.px) - minWidth = 400.px - height = 100.pct - overflowY = Overflow.auto - flex = Flex(1.0, 10.0, FlexBasis("300px")) - } - ringThreeControls(options, solid, selected, onSelect, additionalTabs = props.additionalTabs) - } - } -} - diff --git a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt deleted file mode 100644 index bf557bb8..00000000 --- a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ /dev/null @@ -1,52 +0,0 @@ -package space.kscience.visionforge.ring - -import kotlinx.coroutines.async -import org.w3c.dom.Element -import space.kscience.dataforge.context.AbstractPlugin -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.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.visionforge.ElementVisionRenderer -import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionClient -import space.kscience.visionforge.react.render -import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.ThreePlugin - -public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { - public val three: ThreePlugin by require(ThreePlugin) - - override val tag: PluginTag get() = Companion.tag - - override fun rateVision(vision: Vision): Int = - if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING - - override fun render(element: Element, client: VisionClient, name: Name, vision: Vision, meta: Meta) { - space.kscience.visionforge.react.createRoot(element).render { - child(ThreeCanvasWithControls) { - attrs { - this.solids = three.solids - this.options = Canvas3DOptions.read(meta) - this.builderOfSolid = context.async { vision as Solid } - } - } - } - } - - override fun content(target: String): Map { - return when (target) { - ElementVisionRenderer.TYPE -> mapOf("three.withControls".asName() to this) - else -> super.content(target) - } - } - - public companion object : PluginFactory { - override val tag: PluginTag = PluginTag("vision.threejs.withControls", PluginTag.DATAFORGE_GROUP) - - override fun build(context: Context, meta: Meta): ThreeWithControlsPlugin = ThreeWithControlsPlugin() - } -} \ No newline at end of file diff --git a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt deleted file mode 100644 index 83529d28..00000000 --- a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt +++ /dev/null @@ -1,88 +0,0 @@ -package space.kscience.visionforge.ring - -import org.w3c.dom.Element -import react.RBuilder -import react.dom.p -import ringui.Island -import ringui.SmartTabs -import ringui.Tab -import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.get -import space.kscience.visionforge.Vision -import space.kscience.visionforge.getStyle -import space.kscience.visionforge.react.* -import space.kscience.visionforge.root -import space.kscience.visionforge.solid.SolidReference -import space.kscience.visionforge.styles - -public fun RBuilder.ringPropertyEditor( - vision: Vision, - descriptor: MetaDescriptor? = vision.descriptor, - key: Any? = null, -) { - val styles = if (vision is SolidReference) { - (vision.styles + vision.prototype.styles).distinct() - } else { - vision.styles - } - - flexColumn { - Island("Properties") { - child(PropertyEditor) { - attrs { - this.key = key?.toString() - this.meta = vision.properties.root() - this.updates = vision.properties.changes - this.descriptor = descriptor - this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") - this.getPropertyState = {name-> - if(vision.properties.own?.get(name)!= null){ - EditorPropertyState.Defined - } else if(vision.properties.root()[name] != null){ - // TODO differentiate - EditorPropertyState.Default() - } else { - EditorPropertyState.Undefined - } - } - } - } - } - - if (styles.isNotEmpty()) { - Island("Styles") { - if (styles.size == 1) { - val styleName = styles.first() - p { - +styleName - } - val style = vision.getStyle(styleName) - if (style != null) { - Tab(styleName, id = styleName) { - metaViewer(style) - } - } - } else { - SmartTabs { - styles.forEach { styleName -> - val style = vision.getStyle(styleName) - if (style != null) { - Tab(styleName, id = styleName) { - metaViewer(style) - } - } - } - } - } - } - } - } -} - - -public fun Element.ringPropertyEditor( - item: Vision, - descriptor: MetaDescriptor? = item.descriptor, -): Unit = createRoot(this).render { - ringPropertyEditor(item, descriptor = descriptor) -} \ No newline at end of file diff --git a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt deleted file mode 100644 index 6cdc0707..00000000 --- a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt +++ /dev/null @@ -1,131 +0,0 @@ -package space.kscience.visionforge.ring - -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.GlobalScope -import kotlinx.css.* -import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event -import org.w3c.files.Blob -import org.w3c.files.BlobPropertyBag -import react.FC -import react.Props -import react.RBuilder -import react.dom.attrs -import react.dom.button -import react.fc -import ringui.Island -import ringui.SmartTabs -import ringui.Tab -import space.kscience.dataforge.names.Name -import space.kscience.visionforge.Vision -import space.kscience.visionforge.encodeToString -import space.kscience.visionforge.react.flexColumn -import space.kscience.visionforge.react.flexRow -import space.kscience.visionforge.react.propertyEditor -import space.kscience.visionforge.react.visionTree -import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import styled.css - -internal fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) { - event.stopPropagation(); - event.preventDefault(); - - val fileSaver = kotlinext.js.require("file-saver") - val blob = Blob(arrayOf(dataBuilder()), BlobPropertyBag("$mimeType;charset=utf-8")) - fileSaver.saveAs(blob, fileName) -} - -internal fun RBuilder.canvasControls(options: Canvas3DOptions, vision: Vision?): Unit { - child(CanvasControls) { - attrs { - this.options = options - this.vision = vision - } - } -} - -internal external interface CanvasControlsProps : Props { - public var options: Canvas3DOptions - public var vision: Vision? -} - -@OptIn(DelicateCoroutinesApi::class) -internal val CanvasControls: FC = fc("CanvasControls") { props -> - flexColumn { - flexRow { - css { - border = Border(1.px, BorderStyle.solid, Color.blue) - padding = Padding(4.px) - } - props.vision?.let { vision -> - button { - +"Export" - attrs { - onClickFunction = { - val json = vision.encodeToString() - saveData(it, "object.json", "text/json") { - json - } - - } - } - } - } - } - propertyEditor( - scope = props.vision?.manager?.context ?: GlobalScope, - properties = props.options.meta, - descriptor = Canvas3DOptions.descriptor, - expanded = false - ) - - } -} - - -public external interface ThreeControlsProps : Props { - public var canvasOptions: Canvas3DOptions - public var vision: Vision? - public var selected: Name? - public var onSelect: (Name?) -> Unit - public var additionalTabs: Map Unit> -} - -@JsExport -public val ThreeControls: FC = fc { props -> - SmartTabs("Tree") { - props.vision?.let { - Tab("Tree") { - Island("Vision tree") { - visionTree(it, props.selected, props.onSelect) - } - } - } - Tab("Settings") { - Island("Canvas configuration") { - canvasControls(props.canvasOptions, props.vision) - } - } - props.additionalTabs.forEach { (name, handler) -> - Tab(name) { - handler() - } - } - } -} - -public fun RBuilder.ringThreeControls( - canvasOptions: Canvas3DOptions, - vision: Vision?, - selected: Name?, - onSelect: (Name?) -> Unit = {}, - additionalTabs: Map Unit>? = null -): Unit = child(ThreeControls) { - attrs { - this.canvasOptions = canvasOptions - this.vision = vision - this.selected = selected - this.onSelect = onSelect - this.additionalTabs = additionalTabs ?: emptyMap() - } -} \ No newline at end of file diff --git a/ui/ring/webpack.config.d/01.ring.js b/ui/ring/webpack.config.d/01.ring.js deleted file mode 100644 index 41da041c..00000000 --- a/ui/ring/webpack.config.d/01.ring.js +++ /dev/null @@ -1,3 +0,0 @@ -const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; - -config.module.rules.push(...ringConfig.module.rules) \ No newline at end of file diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/ComposeVisionRenderer.kt similarity index 95% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/ComposeVisionRenderer.kt index 32d9d129..91cb87be 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/ComposeVisionRenderer.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/ComposeVisionRenderer.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.Composable import org.jetbrains.compose.web.css.Style diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/MetaViewer.kt similarity index 98% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/MetaViewer.kt index 5c93cd15..3f85fd9f 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/MetaViewer.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.* import org.jetbrains.compose.web.css.AlignItems diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/NameCrumbs.kt similarity index 96% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/NameCrumbs.kt index 12d78210..787a45fa 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/NameCrumbs.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.Composable import org.jetbrains.compose.web.dom.* diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/PropertyEditor.kt similarity index 99% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/PropertyEditor.kt index 452750df..cfea11e0 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/PropertyEditor.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.* import app.softwork.bootstrapcompose.CloseButton diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/Tabs.kt similarity index 98% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/Tabs.kt index 3e0db26a..36504cf4 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/Tabs.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.* import app.softwork.bootstrapcompose.Card diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/TreeStyles.kt similarity index 98% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/TreeStyles.kt index 95a58aaf..d9469dff 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/TreeStyles.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import org.jetbrains.compose.web.ExperimentalComposeWebApi import org.jetbrains.compose.web.css.* diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionForgeStyles.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionForgeStyles.kt similarity index 69% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionForgeStyles.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionForgeStyles.kt index 06d1187c..82a3a608 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionForgeStyles.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionForgeStyles.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import org.jetbrains.compose.web.css.StyleSheet diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionTree.kt similarity index 98% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionTree.kt index 39a4d669..b714fb71 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/VisionTree.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.* import org.jetbrains.compose.web.css.Color diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/bootstrap.kt similarity index 74% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/bootstrap.kt index 8b0ee5b5..ce27653b 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/bootstrap.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.Composable import org.jetbrains.compose.web.dom.H5 diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/composeVision.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/composeVision.kt similarity index 97% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/composeVision.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/composeVision.kt index ffb3da5f..9344f3ce 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/composeVision.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/composeVision.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/css.kt similarity index 95% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/css.kt index 0bf8f7c2..9ae652cf 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/css.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import org.jetbrains.compose.web.css.* import org.jetbrains.compose.web.css.keywords.CSSAutoKeyword diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/layouts.kt similarity index 96% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/layouts.kt index 882f1f1c..ecdfbb1c 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/layouts.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.Composable import org.jetbrains.compose.web.css.DisplayStyle diff --git a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/valueChooser.kt similarity index 99% rename from visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt rename to visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/valueChooser.kt index 9b9a9905..fdec8c3f 100644 --- a/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt +++ b/visionforge-compose-html/src/jsMain/kotlin/space/kscience/visionforge/html/valueChooser.kt @@ -1,6 +1,6 @@ @file:Suppress("UNUSED_PARAMETER") -package space.kscience.visionforge.compose +package space.kscience.visionforge.html import androidx.compose.runtime.* import kotlinx.uuid.UUID diff --git a/visionforge-compose-mpp/build.gradle.kts b/visionforge-compose-mpp/build.gradle.kts new file mode 100644 index 00000000..0dc2b6d9 --- /dev/null +++ b/visionforge-compose-mpp/build.gradle.kts @@ -0,0 +1,24 @@ +plugins { + id("space.kscience.gradle.mpp") + alias(spclibs.plugins.compose) +} + +kscience { + jvm() + wasm() +} + +kotlin { +// android() + sourceSets { + commonMain { + dependencies { + api(projects.visionforgeCore) + api(compose.runtime) + api(compose.foundation) + api(compose.material) + api(compose.preview) + } + } + } +} \ No newline at end of file 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 5d3fbdc3..5691d1f7 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 @@ -10,7 +10,7 @@ import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.* import space.kscience.visionforge.* -import space.kscience.visionforge.compose.ComposeVisionRenderer +import space.kscience.visionforge.html.ComposeVisionRenderer import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.compose.ThreeView 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 2e03ec6a..63e95760 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 @@ -12,8 +12,8 @@ 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.compose.* import space.kscience.visionforge.encodeToString +import space.kscience.visionforge.html.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions @Composable 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 a9ba1146..b3dd1347 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 @@ -13,7 +13,7 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.request import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.isEmpty -import space.kscience.visionforge.compose.* +import space.kscience.visionforge.html.* import space.kscience.visionforge.root import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidGroup