Css revamp
This commit is contained in:
parent
9cc3f65a18
commit
ea5f0abbf6
@ -4,6 +4,7 @@ import kotlinx.browser.window
|
||||
import org.w3c.files.FileReader
|
||||
import org.w3c.files.get
|
||||
import react.*
|
||||
import react.dom.h2
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.dataforge.names.Name
|
||||
@ -12,9 +13,9 @@ import space.kscience.gdml.decodeFromString
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||||
import space.kscience.visionforge.ring.tab
|
||||
import space.kscience.visionforge.root
|
||||
import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import styled.styledDiv
|
||||
|
||||
external interface GDMLAppProps : RProps {
|
||||
var context: Context
|
||||
@ -24,8 +25,8 @@ external interface GDMLAppProps : RProps {
|
||||
|
||||
@JsExport
|
||||
val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
||||
var vision: Solid? by useState { props.vision }
|
||||
val visionManager = useMemo(props.context) { props.context.fetch(Solids).visionManager }
|
||||
var vision: Solid? by useState { props.vision?.apply { root(visionManager) } }
|
||||
|
||||
fun loadData(name: String, data: String) {
|
||||
val parsedVision = when {
|
||||
@ -43,28 +44,30 @@ val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
||||
vision = parsedVision as? Solid ?: error("Parsed vision is not a solid")
|
||||
}
|
||||
|
||||
styledDiv {
|
||||
child(ThreeCanvasWithControls) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.solid = vision
|
||||
this.selected = props.selected
|
||||
tab("Load") {
|
||||
fileDrop("(drag file here)") { files ->
|
||||
val file = files?.get(0)
|
||||
if (file != null) {
|
||||
FileReader().apply {
|
||||
onload = {
|
||||
val string = result as String
|
||||
loadData(file.name, string)
|
||||
}
|
||||
readAsText(file)
|
||||
child(ThreeCanvasWithControls) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.solid = vision
|
||||
this.selected = props.selected
|
||||
tab("Load") {
|
||||
h2 {
|
||||
+"Drag and drop .gdml or .json VisionForge files here"
|
||||
}
|
||||
fileDrop("(drag file here)") { files ->
|
||||
val file = files?.get(0)
|
||||
if (file != null) {
|
||||
FileReader().apply {
|
||||
onload = {
|
||||
val string = result as String
|
||||
loadData(file.name, string)
|
||||
}
|
||||
readAsText(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,28 +1,45 @@
|
||||
package space.kscience.visionforge.gdml.demo
|
||||
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.css.*
|
||||
import react.child
|
||||
import react.dom.render
|
||||
import space.kscience.dataforge.context.Global
|
||||
import space.kscience.gdml.GdmlShowCase
|
||||
import space.kscience.visionforge.Application
|
||||
import space.kscience.visionforge.bootstrap.useBootstrap
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||
import space.kscience.visionforge.startApplication
|
||||
import styled.injectGlobal
|
||||
|
||||
|
||||
private class GDMLDemoApp : Application {
|
||||
|
||||
override fun start(state: Map<String, Any>) {
|
||||
useBootstrap()
|
||||
|
||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||
|
||||
val context = Global.buildContext("demo"){
|
||||
val context = Global.buildContext("gdml-demo"){
|
||||
plugin(ThreePlugin)
|
||||
}
|
||||
|
||||
injectGlobal {
|
||||
html{
|
||||
height = 100.pct
|
||||
}
|
||||
|
||||
body{
|
||||
height = 100.pct
|
||||
display = Display.flex
|
||||
alignItems = Align.stretch
|
||||
}
|
||||
|
||||
"#application"{
|
||||
width = 100.pct
|
||||
display = Display.flex
|
||||
alignItems = Align.stretch
|
||||
}
|
||||
}
|
||||
|
||||
val element = document.getElementById("application") ?: error("Element with id 'application' not found on page")
|
||||
|
||||
render(element) {
|
||||
child(GDMLApp) {
|
||||
val vision = GdmlShowCase.cubes().toVision()
|
||||
|
@ -8,6 +8,6 @@
|
||||
<link rel="stylesheet" href="css/fileDrop.css">
|
||||
</head>
|
||||
<body class="application">
|
||||
<div class="container-fluid max-vh-100" id = "app"> </div>
|
||||
<div id = "application"></div>
|
||||
</body>
|
||||
</html>
|
@ -21,11 +21,6 @@ public external interface ThreeCanvasProps : RProps {
|
||||
public var selected: Name?
|
||||
}
|
||||
|
||||
public external interface ThreeCanvasState : RState {
|
||||
public var element: Element?
|
||||
// var canvas: ThreeCanvas?
|
||||
}
|
||||
|
||||
public val ThreeCanvasComponent: FunctionalComponent<ThreeCanvasProps> = functionalComponent(
|
||||
"ThreeCanvasComponent"
|
||||
) { props ->
|
||||
@ -55,8 +50,7 @@ public val ThreeCanvasComponent: FunctionalComponent<ThreeCanvasProps> = functio
|
||||
css {
|
||||
maxWidth = 100.vw
|
||||
maxHeight = 100.vh
|
||||
display = Display.block
|
||||
bottom = 0.px
|
||||
flex(1.0, 1.0, FlexBasis.auto)
|
||||
}
|
||||
ref = elementRef
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ringui
|
||||
|
||||
import react.RBuilder
|
||||
import react.RClass
|
||||
import react.RHandler
|
||||
import react.dom.WithClassName
|
||||
|
||||
@ -27,8 +28,14 @@ public object AlertTypes {
|
||||
public var LOADING: String = "loading"
|
||||
}
|
||||
|
||||
@JsModule("@jetbrains/ring-ui/components/alert/alert")
|
||||
internal external object AlertModule {
|
||||
@JsName("default")
|
||||
val Alert: RClass<AlertProps>
|
||||
}
|
||||
|
||||
public fun RBuilder.ringAlert(handler: RHandler<AlertProps>) {
|
||||
RingUI.Alert {
|
||||
AlertModule.Alert {
|
||||
handler()
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package ringui
|
||||
|
||||
import org.w3c.dom.events.MouseEvent
|
||||
import react.RBuilder
|
||||
import react.RClass
|
||||
import react.RHandler
|
||||
import react.dom.WithClassName
|
||||
|
||||
@ -28,8 +29,15 @@ public external interface ButtonProps : WithClassName {
|
||||
public var onMouseDown: (MouseEvent) -> Unit
|
||||
}
|
||||
|
||||
@JsModule("@jetbrains/ring-ui/components/button/button")
|
||||
internal external object ButtonModule {
|
||||
@JsName("default")
|
||||
val Button: RClass<ButtonProps>
|
||||
}
|
||||
|
||||
|
||||
public fun RBuilder.ringButton(handler: RHandler<ButtonProps>) {
|
||||
RingUI.Button {
|
||||
ButtonModule.Button {
|
||||
handler()
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package ringui
|
||||
|
||||
import react.RBuilder
|
||||
import react.RClass
|
||||
import react.RHandler
|
||||
import react.dom.WithClassName
|
||||
|
||||
@ -20,8 +21,14 @@ public external interface DialogProps : WithClassName {
|
||||
public var autoFocusFirst: Boolean
|
||||
}
|
||||
|
||||
@JsModule("@jetbrains/ring-ui/components/dialog/dialog")
|
||||
internal external object DialogModule {
|
||||
@JsName("default")
|
||||
val Dialog: RClass<DialogProps>
|
||||
}
|
||||
|
||||
public fun RBuilder.ringDialog(show: Boolean, handler: RHandler<DialogProps>) {
|
||||
RingUI.Dialog {
|
||||
DialogModule.Dialog {
|
||||
attrs.show = show
|
||||
handler()
|
||||
}
|
||||
|
46
ui/ring/src/main/kotlin/ringui/Dropdown.kt
Normal file
46
ui/ring/src/main/kotlin/ringui/Dropdown.kt
Normal file
@ -0,0 +1,46 @@
|
||||
package ringui
|
||||
|
||||
import org.w3c.dom.events.Event
|
||||
import react.RBuilder
|
||||
import react.RClass
|
||||
import react.RHandler
|
||||
import react.ReactElement
|
||||
import react.dom.WithClassName
|
||||
|
||||
public external interface AnchorProps : WithClassName
|
||||
|
||||
public external interface DropdownProps : WithClassName {
|
||||
/**
|
||||
* Can be string, React element, or a function accepting an object with {active, pinned} properties and returning a React element
|
||||
* React element should render some interactive HTML element like `button` or `a`
|
||||
*/
|
||||
public var anchor: dynamic //: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
|
||||
public var initShown: Boolean
|
||||
public var activeClassName: String
|
||||
public var clickMode: Boolean
|
||||
public var hoverMode: Boolean
|
||||
public var hoverShowTimeOut: Number
|
||||
public var hoverHideTimeOut: Number
|
||||
public var onShow: () -> Unit
|
||||
public var onHide: () -> Unit
|
||||
public var onMouseEnter: (Event) -> Unit
|
||||
public var onMouseLeave: (Event) -> Unit
|
||||
//'data-test': PropTypes.string
|
||||
}
|
||||
|
||||
@JsModule("@jetbrains/ring-ui/components/dropdown/dropdown")
|
||||
public external object DropdownModule {
|
||||
public val Anchor: RClass<AnchorProps>
|
||||
|
||||
@JsName("default")
|
||||
public val Dropdown: RClass<DropdownProps>
|
||||
}
|
||||
|
||||
|
||||
public fun RBuilder.ringDropdown(anchor: dynamic, handler: RHandler<DropdownProps>): ReactElement =
|
||||
DropdownModule.Dropdown {
|
||||
attrs {
|
||||
this.anchor = anchor
|
||||
}
|
||||
handler()
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package ringui
|
||||
|
||||
import react.RBuilder
|
||||
import react.RClass
|
||||
import react.RHandler
|
||||
import react.dom.WithClassName
|
||||
|
||||
@ -14,8 +15,14 @@ public external interface IconProps : WithClassName {
|
||||
public var loading: Boolean
|
||||
}
|
||||
|
||||
@JsModule("@jetbrains/ring-ui/components/icon/icon")
|
||||
internal external object IconModule {
|
||||
@JsName("default")
|
||||
val Icon: RClass<IconProps>
|
||||
}
|
||||
|
||||
public fun RBuilder.ringIcon(handler: RHandler<IconProps>) {
|
||||
RingUI.Icon {
|
||||
IconModule.Icon {
|
||||
handler()
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package ringui
|
||||
|
||||
import org.w3c.dom.events.MouseEvent
|
||||
import react.RBuilder
|
||||
import react.RClass
|
||||
import react.RHandler
|
||||
import react.dom.WithClassName
|
||||
|
||||
@ -17,8 +18,14 @@ public external interface LinkProps : WithClassName {
|
||||
public var onClick: (MouseEvent) -> Unit
|
||||
}
|
||||
|
||||
@JsModule("@jetbrains/ring-ui/components/link/link")
|
||||
internal external object LinkModule {
|
||||
@JsName("default")
|
||||
val Link: RClass<LinkProps>
|
||||
}
|
||||
|
||||
public fun RBuilder.ringLink(handler: RHandler<LinkProps>) {
|
||||
RingUI.Link {
|
||||
LinkModule.Link {
|
||||
handler()
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package ringui
|
||||
|
||||
import react.RClass
|
||||
import ringui.header.HeaderProps
|
||||
|
||||
@JsModule("@jetbrains/ring-ui")
|
||||
public external object RingUI {
|
||||
public val Alert: RClass<AlertProps>
|
||||
public val Button: RClass<ButtonProps>
|
||||
public val Dialog: RClass<DialogProps>
|
||||
public val Header: RClass<HeaderProps>
|
||||
public val Link: RClass<LinkProps>
|
||||
public val Icon: RClass<IconProps>
|
||||
}
|
@ -4,10 +4,11 @@ import react.RBuilder
|
||||
import react.RClass
|
||||
import react.RHandler
|
||||
import react.dom.WithClassName
|
||||
import ringui.RingUI
|
||||
|
||||
@JsModule("@jetbrains/ring-ui/components/header/header")
|
||||
internal external object HeaderModule {
|
||||
@JsName("default")
|
||||
val Header: RClass<HeaderProps>
|
||||
val RerenderableHeader: RClass<HeaderProps>
|
||||
val Logo: RClass<HeaderLogoProps>
|
||||
val Tray: RClass<HeaderTrayProps>
|
||||
@ -24,8 +25,9 @@ public external interface HeaderProps : WithClassName {
|
||||
public var theme: String
|
||||
}
|
||||
|
||||
|
||||
public fun RBuilder.ringHeader(handler: RHandler<HeaderProps>) {
|
||||
RingUI.Header {
|
||||
HeaderModule.Header {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,21 @@ package space.kscience.visionforge.ring
|
||||
|
||||
import kotlinx.css.*
|
||||
import react.*
|
||||
import ringui.grid.RowPosition
|
||||
import ringui.grid.ringCol
|
||||
import ringui.grid.ringGrid
|
||||
import ringui.grid.ringRow
|
||||
import ringui.tabs.ringTab
|
||||
import react.dom.div
|
||||
import react.dom.span
|
||||
import ringui.ringLink
|
||||
import space.kscience.dataforge.context.Context
|
||||
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.VisionGroup
|
||||
import space.kscience.visionforge.allProperties
|
||||
import space.kscience.visionforge.ownProperties
|
||||
import space.kscience.visionforge.react.ThreeCanvasComponent
|
||||
import space.kscience.visionforge.react.flexColumn
|
||||
import space.kscience.visionforge.react.flexRow
|
||||
import space.kscience.visionforge.react.propertyEditor
|
||||
import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||
import styled.css
|
||||
@ -22,72 +29,143 @@ public external interface ThreeCanvasWithControlsProps : RProps {
|
||||
public var additionalTabs: Map<String, RBuilder.() -> Unit>?
|
||||
}
|
||||
|
||||
public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.()->Unit){
|
||||
additionalTabs = (additionalTabs?: emptyMap()) + (title to block)
|
||||
public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.() -> Unit) {
|
||||
additionalTabs = (additionalTabs ?: emptyMap()) + (title to block)
|
||||
}
|
||||
|
||||
@JsExport
|
||||
public val ThreeCanvasWithControls: (props: ThreeCanvasWithControlsProps) -> dynamic =
|
||||
functionalComponent("ThreeViewWithControls") { props ->
|
||||
var selected by useState { props.selected }
|
||||
val onSelect: (Name?) -> Unit = {
|
||||
selected = it
|
||||
}
|
||||
val options = useMemo {
|
||||
Canvas3DOptions.invoke {
|
||||
this.onSelect = onSelect
|
||||
|
||||
public fun RBuilder.nameCrumbs(name: Name?, link: (Name) -> Unit): ReactElement = styledDiv {
|
||||
div {
|
||||
ringLink {
|
||||
attrs {
|
||||
onClick = {
|
||||
link(Name.EMPTY)
|
||||
}
|
||||
}
|
||||
+"\u2302"
|
||||
}
|
||||
|
||||
styledDiv {
|
||||
css {
|
||||
height = 100.pct
|
||||
width = 100.pct
|
||||
maxHeight = 100.vh
|
||||
maxWidth = 100.vw
|
||||
}
|
||||
ringGrid {
|
||||
ringRow {
|
||||
if (name != null) {
|
||||
val tokens = ArrayList<NameToken>(name.length)
|
||||
name.tokens.forEach { token ->
|
||||
tokens.add(token)
|
||||
val fullName = Name(tokens.toList())
|
||||
span { +"/" }
|
||||
ringLink {
|
||||
+token.toString()
|
||||
attrs {
|
||||
start = RowPosition.sm
|
||||
}
|
||||
ringCol {
|
||||
attrs {
|
||||
xs = 12
|
||||
sm = 12
|
||||
md = 8
|
||||
lg = 9
|
||||
}
|
||||
child(ThreeCanvasComponent) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.solid = props.solid
|
||||
this.selected = selected
|
||||
this.options = options
|
||||
}
|
||||
}
|
||||
}
|
||||
ringCol {
|
||||
attrs {
|
||||
xs = 12
|
||||
sm = 12
|
||||
md = 4
|
||||
lg = 3
|
||||
}
|
||||
styledDiv {
|
||||
css {
|
||||
padding(top = 4.px)
|
||||
width = 100.pct
|
||||
//border(1.px, BorderStyle.solid, Color.lightGray)
|
||||
}
|
||||
ringThreeControls(options, props.solid, selected, onSelect) {
|
||||
props.additionalTabs?.forEach { (title, builder) ->
|
||||
ringTab(title, title, builder)
|
||||
}
|
||||
}
|
||||
onClick = {
|
||||
console.log("Selected = $fullName")
|
||||
link(fullName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@JsExport
|
||||
public val ThreeCanvasWithControls: FunctionalComponent<ThreeCanvasWithControlsProps> =
|
||||
functionalComponent("ThreeViewWithControls") { props ->
|
||||
var selected by useState { props.selected }
|
||||
|
||||
val onSelect: (Name?) -> Unit = {
|
||||
selected = it
|
||||
}
|
||||
|
||||
val options = useMemo(props.context) {
|
||||
Canvas3DOptions.invoke {
|
||||
this.onSelect = onSelect
|
||||
}
|
||||
}
|
||||
|
||||
val selectedVision = useMemo(selected) {
|
||||
selected?.let {
|
||||
when {
|
||||
it.isEmpty() -> props.solid
|
||||
else -> (props.solid as? VisionGroup)?.get(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flexRow {
|
||||
css {
|
||||
flex(1.0, 1.0, FlexBasis.auto)
|
||||
flexWrap = FlexWrap.wrap
|
||||
alignItems = Align.stretch
|
||||
alignContent = Align.stretch
|
||||
}
|
||||
|
||||
flexColumn {
|
||||
css {
|
||||
minWidth = 600.px
|
||||
flex(10.0, 1.0, FlexBasis("600px"))
|
||||
position = Position.relative
|
||||
}
|
||||
|
||||
child(ThreeCanvasComponent) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.solid = props.solid
|
||||
this.selected = selected
|
||||
this.options = options
|
||||
}
|
||||
}
|
||||
|
||||
selectedVision?.let { vision ->
|
||||
styledDiv {
|
||||
css {
|
||||
position = Position.absolute
|
||||
top = 10.px
|
||||
right = 10.px
|
||||
}
|
||||
styledDiv {
|
||||
css {
|
||||
minWidth = 450.px
|
||||
backgroundColor = Color.white
|
||||
borderRadius = 3.px
|
||||
borderColor = Color.blue
|
||||
borderWidth = 1.px
|
||||
borderStyle = BorderStyle.solid
|
||||
padding(3.px)
|
||||
}
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
ringThreeControls(options, props.solid, selected, onSelect, additionalTabs = props.additionalTabs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import org.w3c.dom.Element
|
||||
import react.RBuilder
|
||||
import react.dom.p
|
||||
import react.dom.render
|
||||
import react.useMemo
|
||||
import ringui.island.ringIsland
|
||||
import ringui.island.ringIslandContent
|
||||
import ringui.island.ringIslandHeader
|
||||
@ -22,14 +21,12 @@ public fun RBuilder.ringPropertyEditor(
|
||||
descriptor: NodeDescriptor? = vision.descriptor,
|
||||
key: Any? = null,
|
||||
) {
|
||||
|
||||
val styles = useMemo(vision, key) {
|
||||
if (vision is SolidReference) {
|
||||
(vision.styles + vision.prototype.styles).distinct()
|
||||
} else {
|
||||
vision.styles
|
||||
}
|
||||
val styles = if (vision is SolidReference) {
|
||||
(vision.styles + vision.prototype.styles).distinct()
|
||||
} else {
|
||||
vision.styles
|
||||
}
|
||||
|
||||
flexColumn {
|
||||
ringIsland("Properties") {
|
||||
propertyEditor(
|
||||
@ -52,7 +49,7 @@ public fun RBuilder.ringPropertyEditor(
|
||||
ringIslandContent {
|
||||
if (styles.size == 1) {
|
||||
val styleName = styles.first()
|
||||
p{
|
||||
p {
|
||||
+styleName
|
||||
}
|
||||
val style = vision.getStyle(styleName)
|
||||
|
@ -1,10 +1,7 @@
|
||||
package space.kscience.visionforge.ring
|
||||
|
||||
import kotlinx.css.BorderStyle
|
||||
import kotlinx.css.Color
|
||||
import kotlinx.css.padding
|
||||
import kotlinx.css.*
|
||||
import kotlinx.css.properties.border
|
||||
import kotlinx.css.px
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import org.w3c.dom.events.Event
|
||||
import org.w3c.files.Blob
|
||||
@ -17,9 +14,7 @@ import ringui.tabs.ringSmartTabs
|
||||
import ringui.tabs.ringTab
|
||||
import space.kscience.dataforge.meta.withDefault
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.isEmpty
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.VisionGroup
|
||||
import space.kscience.visionforge.encodeToString
|
||||
import space.kscience.visionforge.react.flexColumn
|
||||
import space.kscience.visionforge.react.flexRow
|
||||
@ -27,6 +22,7 @@ import space.kscience.visionforge.react.propertyEditor
|
||||
import space.kscience.visionforge.react.visionTree
|
||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
|
||||
internal fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) {
|
||||
event.stopPropagation();
|
||||
@ -89,38 +85,35 @@ public external interface ThreeControlsProps : RProps {
|
||||
public var vision: Vision?
|
||||
public var selected: Name?
|
||||
public var onSelect: (Name?) -> Unit
|
||||
public var additionalTabs: Map<String, RBuilder.() -> Unit>
|
||||
}
|
||||
|
||||
@JsExport
|
||||
public val ThreeControls: FunctionalComponent<ThreeControlsProps> = functionalComponent { props ->
|
||||
ringSmartTabs(if (props.selected != null) "Properties" else "Tree") {
|
||||
ringTab("Canvas") {
|
||||
ringSmartTabs("Tree") {
|
||||
props.vision?.let {
|
||||
ringTab("Tree") {
|
||||
styledDiv {
|
||||
css {
|
||||
height = 100.pct
|
||||
overflowY = Overflow.auto
|
||||
}
|
||||
ringIsland("Vision tree") {
|
||||
visionTree(it, props.selected, props.onSelect)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ringTab("Settings") {
|
||||
ringIsland("Canvas configuration") {
|
||||
canvasControls(props.canvasOptions, props.vision)
|
||||
}
|
||||
}
|
||||
props.vision?.let {
|
||||
ringTab("Tree") {
|
||||
ringIsland("Vision tree") {
|
||||
visionTree(it, props.selected, props.onSelect)
|
||||
}
|
||||
props.additionalTabs.forEach { (name, handler) ->
|
||||
ringTab(name){
|
||||
handler()
|
||||
}
|
||||
}
|
||||
if (props.selected != null) {
|
||||
ringTab("Properties") {
|
||||
props.selected.let { selected ->
|
||||
val selectedObject: Vision? = when {
|
||||
selected == null -> null
|
||||
selected.isEmpty() -> props.vision
|
||||
else -> (props.vision as? VisionGroup)?.get(selected)
|
||||
}
|
||||
if (selectedObject != null) {
|
||||
ringPropertyEditor(selectedObject, key = selected)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
props.children()
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,13 +122,13 @@ public fun RBuilder.ringThreeControls(
|
||||
vision: Vision?,
|
||||
selected: Name?,
|
||||
onSelect: (Name?) -> Unit = {},
|
||||
builder: RBuilder.() -> Unit = {},
|
||||
additionalTabs: Map<String, RBuilder.() -> Unit>? = null
|
||||
): ReactElement = child(ThreeControls) {
|
||||
attrs {
|
||||
this.canvasOptions = canvasOptions
|
||||
this.vision = vision
|
||||
this.selected = selected
|
||||
this.onSelect = onSelect
|
||||
this.additionalTabs = additionalTabs?: emptyMap()
|
||||
}
|
||||
builder()
|
||||
}
|
Loading…
Reference in New Issue
Block a user