visionforge/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt

172 lines
5.8 KiB
Kotlin
Raw Normal View History

2021-05-10 22:07:16 +03:00
package space.kscience.visionforge.ring
import kotlinx.css.*
2021-06-06 20:57:39 +03:00
import react.*
2021-06-14 16:42:02 +03:00
import react.dom.div
import react.dom.span
import ringui.Link
2021-05-10 22:07:16 +03:00
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.names.Name
2021-06-14 16:42:02 +03:00
import space.kscience.dataforge.names.NameToken
import space.kscience.dataforge.names.isEmpty
import space.kscience.dataforge.names.length
import space.kscience.visionforge.VisionGroup
import space.kscience.visionforge.allProperties
import space.kscience.visionforge.ownProperties
2021-05-10 22:07:16 +03:00
import space.kscience.visionforge.react.ThreeCanvasComponent
2021-06-14 16:42:02 +03:00
import space.kscience.visionforge.react.flexColumn
import space.kscience.visionforge.react.flexRow
import space.kscience.visionforge.react.propertyEditor
2021-05-10 22:07:16 +03:00
import space.kscience.visionforge.solid.Solid
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
import styled.css
import styled.styledDiv
2021-06-08 18:45:03 +03:00
public external interface ThreeCanvasWithControlsProps : RProps {
2021-05-10 22:07:16 +03:00
public var context: Context
2021-06-08 18:45:03 +03:00
public var solid: Solid?
2021-05-10 22:07:16 +03:00
public var selected: Name?
2021-06-09 11:48:03 +03:00
public var additionalTabs: Map<String, RBuilder.() -> Unit>?
}
2021-06-14 16:42:02 +03:00
public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.() -> Unit) {
additionalTabs = (additionalTabs ?: emptyMap()) + (title to block)
}
public fun RBuilder.nameCrumbs(name: Name?, link: (Name) -> Unit): ReactElement = styledDiv {
div {
Link {
2021-06-14 16:42:02 +03:00
attrs {
onClick = {
link(Name.EMPTY)
}
}
+"\u2302"
}
if (name != null) {
val tokens = ArrayList<NameToken>(name.length)
name.tokens.forEach { token ->
tokens.add(token)
val fullName = Name(tokens.toList())
span { +"/" }
Link {
2021-06-14 16:42:02 +03:00
+token.toString()
attrs {
onClick = {
console.log("Selected = $fullName")
link(fullName)
}
}
}
}
}
}
2021-05-10 22:07:16 +03:00
}
@JsExport
2021-06-14 16:42:02 +03:00
public val ThreeCanvasWithControls: FunctionalComponent<ThreeCanvasWithControlsProps> =
2021-06-06 20:57:39 +03:00
functionalComponent("ThreeViewWithControls") { props ->
2021-05-10 22:07:16 +03:00
var selected by useState { props.selected }
2021-06-14 16:42:02 +03:00
2021-05-10 22:07:16 +03:00
val onSelect: (Name?) -> Unit = {
selected = it
}
2021-06-14 16:42:02 +03:00
val options = useMemo(props.context) {
2021-06-06 20:57:39 +03:00
Canvas3DOptions.invoke {
this.onSelect = onSelect
}
}
2021-05-10 22:07:16 +03:00
2021-06-14 16:42:02 +03:00
val selectedVision = useMemo(selected) {
selected?.let {
when {
it.isEmpty() -> props.solid
else -> (props.solid as? VisionGroup)?.get(it)
}
}
}
flexRow {
2021-05-10 22:07:16 +03:00
css {
2021-06-14 16:42:02 +03:00
flex(1.0, 1.0, FlexBasis.auto)
flexWrap = FlexWrap.wrap
alignItems = Align.stretch
alignContent = Align.stretch
2021-05-10 22:07:16 +03:00
}
2021-06-14 16:42:02 +03:00
flexColumn {
css {
minWidth = 600.px
flex(10.0, 1.0, FlexBasis("600px"))
position = Position.relative
}
child(ThreeCanvasComponent) {
2021-06-09 11:48:03 +03:00
attrs {
2021-06-14 16:42:02 +03:00
this.context = props.context
this.solid = props.solid
this.selected = selected
this.options = options
2021-06-09 11:48:03 +03:00
}
2021-06-14 16:42:02 +03:00
}
selectedVision?.let { vision ->
styledDiv {
css {
position = Position.absolute
top = 10.px
right = 10.px
2021-05-10 22:07:16 +03:00
}
styledDiv {
css {
2021-06-14 16:42:02 +03:00
minWidth = 450.px
backgroundColor = Color.white
borderRadius = 3.px
borderColor = Color.blue
borderWidth = 1.px
borderStyle = BorderStyle.solid
padding(3.px)
2021-06-09 11:48:03 +03:00
}
2021-06-14 16:42:02 +03:00
propertyEditor(
ownProperties = vision.ownProperties,
allProperties = vision.allProperties(),
updateFlow = vision.propertyChanges,
descriptor = vision.descriptor,
key = selected
)
2021-05-10 22:07:16 +03:00
}
}
2021-06-14 16:42:02 +03:00
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 {
css {
padding(4.px)
minWidth = 400.px
flex(1.0, 10.0, FlexBasis("300px"))
alignItems = Align.stretch
alignContent = Align.stretch
//border(1.px, BorderStyle.solid, Color.lightGray)
2021-05-10 22:07:16 +03:00
}
2021-06-14 16:42:02 +03:00
ringThreeControls(options, props.solid, selected, onSelect, additionalTabs = props.additionalTabs)
2021-05-10 22:07:16 +03:00
}
}
2021-06-14 16:42:02 +03:00
}