diff --git a/build.gradle.kts b/build.gradle.kts index b75039f7..8236106e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,11 +17,10 @@ allprojects { jcenter() maven("https://repo.kotlin.link") maven("https://maven.jzy3d.org/releases") - maven("https://maven.pkg.jetbrains.space/mipt-npm/p/mipt-npm/maven") } group = "space.kscience" - version = "0.2.0-dev-20" + version = "0.2.0-dev-21" } subprojects { diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt index b86f11fc..a3972612 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt @@ -1,5 +1,7 @@ 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.* @@ -60,9 +62,9 @@ private fun RBuilder.metaViewerItem(props: MetaViewerProps) { when (actualItem) { is MetaItemNode -> { - styledDiv { + flexRow { css { - +TreeStyles.treeLeaf + alignItems = Align.center } styledSpan { css { @@ -117,22 +119,18 @@ private fun RBuilder.metaViewerItem(props: MetaViewerProps) { } } is MetaItemValue -> { - styledDiv { + flexRow { css { - +TreeStyles.treeLeaf + alignItems = Align.center } - styledDiv { + styledSpan { css { +TreeStyles.treeLabel - } - styledSpan { - css { - if (item == null) { - +TreeStyles.treeLabelInactive - } + if (item == null) { + +TreeStyles.treeLabelInactive } - +token } + +token } styledDiv { a { diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index 66779588..6e41555b 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -9,6 +9,8 @@ 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.Element import org.w3c.dom.events.Event @@ -129,10 +131,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { // Do not show nodes without visible children if (keys.isEmpty()) return - styledDiv { - css { - +TreeStyles.treeLeaf - } + flexRow { styledSpan { css { +TreeStyles.treeCaret @@ -179,26 +178,25 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } } } else { - styledDiv { + flexRow { css { - +TreeStyles.treeLeaf + alignItems = Align.center } - styledDiv { + styledSpan { css { +TreeStyles.treeLabel - } - styledSpan { - css { - if (ownProperty == null) { - +TreeStyles.treeLabelInactive - } + if (ownProperty == null) { + +TreeStyles.treeLabelInactive } - +token } + +token } + styledDiv { css { - +TreeStyles.resizeableInput + //+TreeStyles.resizeableInput + width = 160.px + margin(1.px, 5.px) } valueChooser( props.name, @@ -207,9 +205,23 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { valueChanged ) } + styledButton { css { - +TreeStyles.removeButton + width = 24.px + alignSelf = Align.stretch + 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 { diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index abeeaa86..2b11143b 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -1,5 +1,7 @@ package space.kscience.visionforge.react +import kotlinx.css.pct +import kotlinx.css.width import kotlinx.html.InputType import kotlinx.html.js.onChangeFunction import org.w3c.dom.HTMLInputElement @@ -12,6 +14,7 @@ import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.string import space.kscience.dataforge.values.asValue +import styled.css import styled.styledInput @JsExport @@ -45,6 +48,9 @@ public val RangeValueChooser: FunctionalComponent = } styledInput(type = InputType.range) { + css{ + width = 100.pct + } attrs { disabled = rangeDisabled value = innerValue?.toString() ?: "" diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt index 0c42caf3..6dd563de 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt @@ -50,7 +50,7 @@ public val ThreeCanvasComponent: FunctionalComponent = functio css { maxWidth = 100.vw maxHeight = 100.vh - flex(1.0, 1.0, FlexBasis.auto) + flex(1.0) } ref = elementRef } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt index 59bee78f..5d693a3c 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt @@ -1,7 +1,8 @@ package space.kscience.visionforge.react import kotlinx.css.* -import kotlinx.css.properties.* +import kotlinx.css.properties.deg +import kotlinx.css.properties.rotate import styled.StyleSheet public object TreeStyles : StyleSheet("treeStyles", true) { @@ -48,21 +49,13 @@ public object TreeStyles : StyleSheet("treeStyles", true) { borderLeftStyle = BorderStyle.dashed borderLeftWidth = 1.px borderLeftColor = Color.lightGray - borderBottomStyle = BorderStyle.dashed - borderBottomWidth = 1.px - borderBottomColor = Color.lightGray - } - - public val treeLeaf:RuleSet by css { - display = Display.flex - flexDirection = FlexDirection.row - flexWrap = FlexWrap.nowrap - //alignItems = Align.center } public val treeLabel:RuleSet by css { - overflow = Overflow.hidden - flex(flexGrow = 1.0, flexShrink = 1.0) + border = "none" + padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) + textAlign = TextAlign.left + flex(1.0) } public val treeLabelInactive: RuleSet by css { @@ -73,48 +66,4 @@ public object TreeStyles : StyleSheet("treeStyles", true) { backgroundColor = Color.lightBlue } - public val linkButton:RuleSet by css { - backgroundColor = Color.white - border = "none" - padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) - textAlign = TextAlign.left - fontFamily = "arial,sans-serif" - color = Color("#069") - cursor = Cursor.pointer - hover { - textDecoration(TextDecorationLine.underline) - } - } - - public val removeButton:RuleSet by css { - backgroundColor = Color.white - borderStyle = BorderStyle.solid - borderRadius = 2.px - padding(1.px, 5.px) - marginLeft = 4.px - textAlign = TextAlign.center - textDecoration = TextDecoration.none - display = Display.inlineBlock - flexShrink = 1.0 - cursor = Cursor.pointer - disabled { - cursor = Cursor.auto - borderStyle = BorderStyle.dashed - color = Color.lightGray - } - } - - public val resizeableInput: RuleSet by css { - overflow = Overflow.hidden - maxWidth = 120.pt - flex(flexGrow = 2.0, flexShrink = 2.0, flexBasis = 60.pt) - input { - textAlign = TextAlign.right - width = 100.pct - } - select{ - textAlign = TextAlign.right - width = 100.pct - } - } } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt index 3e715342..bcb7e84a 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt @@ -1,5 +1,11 @@ package space.kscience.visionforge.react +import kotlinx.css.Color +import kotlinx.css.Cursor +import kotlinx.css.color +import kotlinx.css.cursor +import kotlinx.css.properties.TextDecorationLine +import kotlinx.css.properties.textDecoration import kotlinx.html.js.onClickFunction import org.w3c.dom.events.Event import react.* @@ -12,7 +18,6 @@ import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.isEmpty import styled.css -import styled.styledButton import styled.styledDiv import styled.styledSpan @@ -23,6 +28,27 @@ public external interface ObjectTreeProps : RProps { public var clickCallback: (Name) -> Unit } +private val TreeLabel = functionalComponent { props -> + val token = useMemo(props.name) { props.name.lastOrNull()?.toString() ?: "World" } + styledSpan { + css { + +TreeStyles.treeLabel + color = Color("#069") + cursor = Cursor.pointer + hover { + textDecoration(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 } @@ -30,32 +56,11 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { expanded = !expanded } - fun RBuilder.treeLabel(text: String) { - styledButton { - css { - //classes = mutableListOf("btn", "btn-link", "align-middle", "text-truncate", "p-0") - +TreeStyles.treeLabel - +TreeStyles.linkButton - if (props.name == props.selected) { - +TreeStyles.treeLabelSelected - } - } - +text - attrs { - onClickFunction = { props.clickCallback(props.name) } - } - } - } - - val token = props.name.lastOrNull()?.toString() ?: "World" val obj = props.obj //display as node if any child is visible if (obj is VisionGroup) { - styledDiv { - css { - +TreeStyles.treeLeaf - } + flexRow { if (obj.children.any { !it.key.body.startsWith("@") }) { styledSpan { css { @@ -69,7 +74,7 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { } } } - treeLabel(token) + child(TreeLabel, props = props) } if (expanded) { flexColumn { @@ -97,12 +102,7 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { } } } else { - styledDiv { - css { - +TreeStyles.treeLeaf - } - treeLabel(token) - } + child(TreeLabel, props = props) } } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/layout.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/layout.kt index 2f35bb24..e8d928f5 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/layout.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/layout.kt @@ -11,20 +11,22 @@ import styled.StyledDOMBuilder import styled.css import styled.styledDiv -public inline fun RBuilder.flexColumn(block: StyledDOMBuilder
.() -> Unit): ReactElement = - styledDiv { - css { - display = Display.flex - flexDirection = FlexDirection.column - } - block() +public inline fun RBuilder.flexColumn( + block: StyledDOMBuilder
.() -> Unit +): ReactElement = styledDiv { + css { + display = Display.flex + flexDirection = FlexDirection.column } + block() +} -public inline fun RBuilder.flexRow(block: StyledDOMBuilder
.() -> Unit): ReactElement = - styledDiv { - css { - display = Display.flex - flexDirection = FlexDirection.row - } - block() - } \ No newline at end of file +public inline fun RBuilder.flexRow( + block: StyledDOMBuilder
.() -> Unit +): ReactElement = styledDiv { + css { + display = Display.flex + flexDirection = FlexDirection.row + } + block() +} \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index 7a32ef4f..2147b191 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -1,5 +1,9 @@ package space.kscience.visionforge.react +import kotlinx.css.margin +import kotlinx.css.pct +import kotlinx.css.px +import kotlinx.css.width import kotlinx.html.InputType import kotlinx.html.js.onChangeFunction import kotlinx.html.js.onKeyDownFunction @@ -15,13 +19,14 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.values.* import space.kscience.visionforge.Colors import space.kscience.visionforge.widgetType +import styled.css import styled.styledInput import styled.styledSelect public external interface ValueChooserProps : RProps { public var item: MetaItem? public var descriptor: ValueDescriptor? - public var nullable: Boolean? + //public var nullable: Boolean? public var valueChanged: ((Value?) -> Unit)? } @@ -41,6 +46,9 @@ public val StringValueChooser: FunctionalComponent = value = (it.target as HTMLInputElement).value } styledInput(type = InputType.text) { + css{ + width = 100.pct + } attrs { this.value = value onKeyDownFunction = keyDown @@ -57,6 +65,9 @@ public val BooleanValueChooser: FunctionalComponent = props.valueChanged?.invoke(newValue.asValue()) } styledInput(type = InputType.checkBox) { + css{ + width = 100.pct + } attrs { //this.attributes["indeterminate"] = (props.item == null).toString() defaultChecked = props.item.boolean ?: false @@ -84,6 +95,9 @@ public val NumberValueChooser: FunctionalComponent = innerValue = (it.target as HTMLInputElement).value } styledInput(type = InputType.number) { + css{ + width = 100.pct + } attrs { value = innerValue onKeyDownFunction = keyDown @@ -110,6 +124,9 @@ public val ComboValueChooser: FunctionalComponent = props.valueChanged?.invoke(selected.asValue()) } styledSelect { + css{ + width = 100.pct + } props.descriptor?.allowedValues?.forEach { option { +it.string @@ -137,6 +154,10 @@ public val ColorValueChooser: FunctionalComponent = props.valueChanged?.invoke(value.asValue()) } styledInput(type = InputType.color) { + css{ + width = 100.pct + margin(0.px) + } attrs { this.value = value onChangeFunction = handleChange diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index a6518bd2..2bdb82a0 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -4,6 +4,9 @@ import kotlinx.css.* import react.* import react.dom.div import react.dom.span +import ringui.Island +import ringui.IslandContent +import ringui.IslandHeader import ringui.Link import space.kscience.dataforge.context.Context import space.kscience.dataforge.names.Name @@ -50,7 +53,7 @@ public fun RBuilder.nameCrumbs(name: Name?, link: (Name) -> Unit): ReactElement name.tokens.forEach { token -> tokens.add(token) val fullName = Name(tokens.toList()) - span { +"/" } + span { +"." } Link { +token.toString() attrs { @@ -116,44 +119,30 @@ public val ThreeCanvasWithControls: FunctionalComponent styledDiv { - css { + css{ position = Position.absolute - top = 10.px - right = 10.px + top = 5.px + right = 5.px + width = 450.px } - styledDiv { - css { - minWidth = 450.px - backgroundColor = Color.white - borderRadius = 3.px - borderColor = Color.blue - borderWidth = 1.px - borderStyle = BorderStyle.solid - padding(3.px) + Island{ + IslandHeader{ + attrs { + border = true + } + nameCrumbs(selected) { selected = it } + } + IslandContent{ + propertyEditor( + ownProperties = vision.ownProperties, + allProperties = vision.allProperties(), + updateFlow = vision.propertyChanges, + descriptor = vision.descriptor, + key = selected + ) } - propertyEditor( - ownProperties = vision.ownProperties, - allProperties = vision.allProperties(), - updateFlow = vision.propertyChanges, - descriptor = vision.descriptor, - key = selected - ) } } - styledDiv { - css { - position = Position.absolute - bottom = 10.px - left = 10.px - backgroundColor = Color.white - borderRadius = 3.px - borderColor = Color.blue - borderWidth = 1.px - borderStyle = BorderStyle.solid - padding(3.px) - } - nameCrumbs(selected) { selected = it } - } } } flexColumn { @@ -161,9 +150,6 @@ public val ThreeCanvasWithControls: FunctionalComponent String) { event.stopPropagation(); @@ -93,14 +95,8 @@ public val ThreeControls: FunctionalComponent = functionalCo SmartTabs("Tree") { props.vision?.let { Tab("Tree") { - styledDiv { - css { - height = 100.pct - overflowY = Overflow.auto - } - Island("Vision tree") { - visionTree(it, props.selected, props.onSelect) - } + Island("Vision tree") { + visionTree(it, props.selected, props.onSelect) } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index f61aaebf..7dd89a32 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -18,9 +18,9 @@ import info.laht.threekt.math.Vector3 import info.laht.threekt.objects.LineSegments import info.laht.threekt.objects.Mesh import info.laht.threekt.scenes.Scene +import kotlinx.browser.window import org.w3c.dom.Element import org.w3c.dom.HTMLCanvasElement -import org.w3c.dom.HTMLElement import org.w3c.dom.Node import org.w3c.dom.events.MouseEvent import space.kscience.dataforge.context.info @@ -149,7 +149,7 @@ public class ThreeCanvas( } }, false) - (element as? HTMLElement)?.onresize = { + window.onresize = { updateSize() } @@ -188,7 +188,8 @@ public class ThreeCanvas( val absoluteValue = boundingBox.min.z + (boundingBox.max.z - boundingBox.min.z) * it Plane(Vector3(0.0, 0.0, -1.0), absoluteValue) } - renderer.clippingPlanes = listOfNotNull(xClippingPlane, yClippingPlane, zClippingPlane).toTypedArray() + renderer.clippingPlanes = + listOfNotNull(xClippingPlane, yClippingPlane, zClippingPlane).toTypedArray() } } else { renderer.localClippingEnabled = false