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.FileReader
|
||||||
import org.w3c.files.get
|
import org.w3c.files.get
|
||||||
import react.*
|
import react.*
|
||||||
|
import react.dom.h2
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.fetch
|
import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.dataforge.names.Name
|
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.gdml.toVision
|
||||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||||||
import space.kscience.visionforge.ring.tab
|
import space.kscience.visionforge.ring.tab
|
||||||
|
import space.kscience.visionforge.root
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
import styled.styledDiv
|
|
||||||
|
|
||||||
external interface GDMLAppProps : RProps {
|
external interface GDMLAppProps : RProps {
|
||||||
var context: Context
|
var context: Context
|
||||||
@ -24,8 +25,8 @@ external interface GDMLAppProps : RProps {
|
|||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
||||||
var vision: Solid? by useState { props.vision }
|
|
||||||
val visionManager = useMemo(props.context) { props.context.fetch(Solids).visionManager }
|
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) {
|
fun loadData(name: String, data: String) {
|
||||||
val parsedVision = when {
|
val parsedVision = when {
|
||||||
@ -43,28 +44,30 @@ val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
|||||||
vision = parsedVision as? Solid ?: error("Parsed vision is not a solid")
|
vision = parsedVision as? Solid ?: error("Parsed vision is not a solid")
|
||||||
}
|
}
|
||||||
|
|
||||||
styledDiv {
|
child(ThreeCanvasWithControls) {
|
||||||
child(ThreeCanvasWithControls) {
|
attrs {
|
||||||
attrs {
|
this.context = props.context
|
||||||
this.context = props.context
|
this.solid = vision
|
||||||
this.solid = vision
|
this.selected = props.selected
|
||||||
this.selected = props.selected
|
tab("Load") {
|
||||||
tab("Load") {
|
h2 {
|
||||||
fileDrop("(drag file here)") { files ->
|
+"Drag and drop .gdml or .json VisionForge files here"
|
||||||
val file = files?.get(0)
|
}
|
||||||
if (file != null) {
|
fileDrop("(drag file here)") { files ->
|
||||||
FileReader().apply {
|
val file = files?.get(0)
|
||||||
onload = {
|
if (file != null) {
|
||||||
val string = result as String
|
FileReader().apply {
|
||||||
loadData(file.name, string)
|
onload = {
|
||||||
}
|
val string = result as String
|
||||||
readAsText(file)
|
loadData(file.name, string)
|
||||||
}
|
}
|
||||||
|
readAsText(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +1,45 @@
|
|||||||
package space.kscience.visionforge.gdml.demo
|
package space.kscience.visionforge.gdml.demo
|
||||||
|
|
||||||
import kotlinx.browser.document
|
import kotlinx.browser.document
|
||||||
|
import kotlinx.css.*
|
||||||
import react.child
|
import react.child
|
||||||
import react.dom.render
|
import react.dom.render
|
||||||
import space.kscience.dataforge.context.Global
|
import space.kscience.dataforge.context.Global
|
||||||
import space.kscience.gdml.GdmlShowCase
|
import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
import space.kscience.visionforge.bootstrap.useBootstrap
|
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.startApplication
|
import space.kscience.visionforge.startApplication
|
||||||
|
import styled.injectGlobal
|
||||||
|
|
||||||
|
|
||||||
private class GDMLDemoApp : Application {
|
private class GDMLDemoApp : Application {
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(state: Map<String, Any>) {
|
||||||
useBootstrap()
|
val context = Global.buildContext("gdml-demo"){
|
||||||
|
|
||||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
|
||||||
|
|
||||||
val context = Global.buildContext("demo"){
|
|
||||||
plugin(ThreePlugin)
|
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) {
|
render(element) {
|
||||||
child(GDMLApp) {
|
child(GDMLApp) {
|
||||||
val vision = GdmlShowCase.cubes().toVision()
|
val vision = GdmlShowCase.cubes().toVision()
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
<link rel="stylesheet" href="css/fileDrop.css">
|
<link rel="stylesheet" href="css/fileDrop.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="application">
|
<body class="application">
|
||||||
<div class="container-fluid max-vh-100" id = "app"> </div>
|
<div id = "application"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -21,11 +21,6 @@ public external interface ThreeCanvasProps : RProps {
|
|||||||
public var selected: Name?
|
public var selected: Name?
|
||||||
}
|
}
|
||||||
|
|
||||||
public external interface ThreeCanvasState : RState {
|
|
||||||
public var element: Element?
|
|
||||||
// var canvas: ThreeCanvas?
|
|
||||||
}
|
|
||||||
|
|
||||||
public val ThreeCanvasComponent: FunctionalComponent<ThreeCanvasProps> = functionalComponent(
|
public val ThreeCanvasComponent: FunctionalComponent<ThreeCanvasProps> = functionalComponent(
|
||||||
"ThreeCanvasComponent"
|
"ThreeCanvasComponent"
|
||||||
) { props ->
|
) { props ->
|
||||||
@ -55,8 +50,7 @@ public val ThreeCanvasComponent: FunctionalComponent<ThreeCanvasProps> = functio
|
|||||||
css {
|
css {
|
||||||
maxWidth = 100.vw
|
maxWidth = 100.vw
|
||||||
maxHeight = 100.vh
|
maxHeight = 100.vh
|
||||||
display = Display.block
|
flex(1.0, 1.0, FlexBasis.auto)
|
||||||
bottom = 0.px
|
|
||||||
}
|
}
|
||||||
ref = elementRef
|
ref = elementRef
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ringui
|
package ringui
|
||||||
|
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
|
import react.RClass
|
||||||
import react.RHandler
|
import react.RHandler
|
||||||
import react.dom.WithClassName
|
import react.dom.WithClassName
|
||||||
|
|
||||||
@ -27,8 +28,14 @@ public object AlertTypes {
|
|||||||
public var LOADING: String = "loading"
|
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>) {
|
public fun RBuilder.ringAlert(handler: RHandler<AlertProps>) {
|
||||||
RingUI.Alert {
|
AlertModule.Alert {
|
||||||
handler()
|
handler()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package ringui
|
|||||||
|
|
||||||
import org.w3c.dom.events.MouseEvent
|
import org.w3c.dom.events.MouseEvent
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
|
import react.RClass
|
||||||
import react.RHandler
|
import react.RHandler
|
||||||
import react.dom.WithClassName
|
import react.dom.WithClassName
|
||||||
|
|
||||||
@ -28,8 +29,15 @@ public external interface ButtonProps : WithClassName {
|
|||||||
public var onMouseDown: (MouseEvent) -> Unit
|
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>) {
|
public fun RBuilder.ringButton(handler: RHandler<ButtonProps>) {
|
||||||
RingUI.Button {
|
ButtonModule.Button {
|
||||||
handler()
|
handler()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package ringui
|
package ringui
|
||||||
|
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
|
import react.RClass
|
||||||
import react.RHandler
|
import react.RHandler
|
||||||
import react.dom.WithClassName
|
import react.dom.WithClassName
|
||||||
|
|
||||||
@ -20,8 +21,14 @@ public external interface DialogProps : WithClassName {
|
|||||||
public var autoFocusFirst: Boolean
|
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>) {
|
public fun RBuilder.ringDialog(show: Boolean, handler: RHandler<DialogProps>) {
|
||||||
RingUI.Dialog {
|
DialogModule.Dialog {
|
||||||
attrs.show = show
|
attrs.show = show
|
||||||
handler()
|
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
|
package ringui
|
||||||
|
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
|
import react.RClass
|
||||||
import react.RHandler
|
import react.RHandler
|
||||||
import react.dom.WithClassName
|
import react.dom.WithClassName
|
||||||
|
|
||||||
@ -14,8 +15,14 @@ public external interface IconProps : WithClassName {
|
|||||||
public var loading: Boolean
|
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>) {
|
public fun RBuilder.ringIcon(handler: RHandler<IconProps>) {
|
||||||
RingUI.Icon {
|
IconModule.Icon {
|
||||||
handler()
|
handler()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package ringui
|
|||||||
|
|
||||||
import org.w3c.dom.events.MouseEvent
|
import org.w3c.dom.events.MouseEvent
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
|
import react.RClass
|
||||||
import react.RHandler
|
import react.RHandler
|
||||||
import react.dom.WithClassName
|
import react.dom.WithClassName
|
||||||
|
|
||||||
@ -17,8 +18,14 @@ public external interface LinkProps : WithClassName {
|
|||||||
public var onClick: (MouseEvent) -> Unit
|
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>) {
|
public fun RBuilder.ringLink(handler: RHandler<LinkProps>) {
|
||||||
RingUI.Link {
|
LinkModule.Link {
|
||||||
handler()
|
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.RClass
|
||||||
import react.RHandler
|
import react.RHandler
|
||||||
import react.dom.WithClassName
|
import react.dom.WithClassName
|
||||||
import ringui.RingUI
|
|
||||||
|
|
||||||
@JsModule("@jetbrains/ring-ui/components/header/header")
|
@JsModule("@jetbrains/ring-ui/components/header/header")
|
||||||
internal external object HeaderModule {
|
internal external object HeaderModule {
|
||||||
|
@JsName("default")
|
||||||
|
val Header: RClass<HeaderProps>
|
||||||
val RerenderableHeader: RClass<HeaderProps>
|
val RerenderableHeader: RClass<HeaderProps>
|
||||||
val Logo: RClass<HeaderLogoProps>
|
val Logo: RClass<HeaderLogoProps>
|
||||||
val Tray: RClass<HeaderTrayProps>
|
val Tray: RClass<HeaderTrayProps>
|
||||||
@ -24,8 +25,9 @@ public external interface HeaderProps : WithClassName {
|
|||||||
public var theme: String
|
public var theme: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public fun RBuilder.ringHeader(handler: RHandler<HeaderProps>) {
|
public fun RBuilder.ringHeader(handler: RHandler<HeaderProps>) {
|
||||||
RingUI.Header {
|
HeaderModule.Header {
|
||||||
handler()
|
handler()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,21 @@ package space.kscience.visionforge.ring
|
|||||||
|
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import react.*
|
import react.*
|
||||||
import ringui.grid.RowPosition
|
import react.dom.div
|
||||||
import ringui.grid.ringCol
|
import react.dom.span
|
||||||
import ringui.grid.ringGrid
|
import ringui.ringLink
|
||||||
import ringui.grid.ringRow
|
|
||||||
import ringui.tabs.ringTab
|
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.names.Name
|
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.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.Solid
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
import styled.css
|
import styled.css
|
||||||
@ -22,72 +29,143 @@ public external interface ThreeCanvasWithControlsProps : RProps {
|
|||||||
public var additionalTabs: Map<String, RBuilder.() -> Unit>?
|
public var additionalTabs: Map<String, RBuilder.() -> Unit>?
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.()->Unit){
|
public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.() -> Unit) {
|
||||||
additionalTabs = (additionalTabs?: emptyMap()) + (title to block)
|
additionalTabs = (additionalTabs ?: emptyMap()) + (title to block)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
|
||||||
public val ThreeCanvasWithControls: (props: ThreeCanvasWithControlsProps) -> dynamic =
|
public fun RBuilder.nameCrumbs(name: Name?, link: (Name) -> Unit): ReactElement = styledDiv {
|
||||||
functionalComponent("ThreeViewWithControls") { props ->
|
div {
|
||||||
var selected by useState { props.selected }
|
ringLink {
|
||||||
val onSelect: (Name?) -> Unit = {
|
attrs {
|
||||||
selected = it
|
onClick = {
|
||||||
}
|
link(Name.EMPTY)
|
||||||
val options = useMemo {
|
}
|
||||||
Canvas3DOptions.invoke {
|
|
||||||
this.onSelect = onSelect
|
|
||||||
}
|
}
|
||||||
|
+"\u2302"
|
||||||
}
|
}
|
||||||
|
|
||||||
styledDiv {
|
if (name != null) {
|
||||||
css {
|
val tokens = ArrayList<NameToken>(name.length)
|
||||||
height = 100.pct
|
name.tokens.forEach { token ->
|
||||||
width = 100.pct
|
tokens.add(token)
|
||||||
maxHeight = 100.vh
|
val fullName = Name(tokens.toList())
|
||||||
maxWidth = 100.vw
|
span { +"/" }
|
||||||
}
|
ringLink {
|
||||||
ringGrid {
|
+token.toString()
|
||||||
ringRow {
|
|
||||||
attrs {
|
attrs {
|
||||||
start = RowPosition.sm
|
onClick = {
|
||||||
}
|
console.log("Selected = $fullName")
|
||||||
ringCol {
|
link(fullName)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@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.RBuilder
|
||||||
import react.dom.p
|
import react.dom.p
|
||||||
import react.dom.render
|
import react.dom.render
|
||||||
import react.useMemo
|
|
||||||
import ringui.island.ringIsland
|
import ringui.island.ringIsland
|
||||||
import ringui.island.ringIslandContent
|
import ringui.island.ringIslandContent
|
||||||
import ringui.island.ringIslandHeader
|
import ringui.island.ringIslandHeader
|
||||||
@ -22,14 +21,12 @@ public fun RBuilder.ringPropertyEditor(
|
|||||||
descriptor: NodeDescriptor? = vision.descriptor,
|
descriptor: NodeDescriptor? = vision.descriptor,
|
||||||
key: Any? = null,
|
key: Any? = null,
|
||||||
) {
|
) {
|
||||||
|
val styles = if (vision is SolidReference) {
|
||||||
val styles = useMemo(vision, key) {
|
(vision.styles + vision.prototype.styles).distinct()
|
||||||
if (vision is SolidReference) {
|
} else {
|
||||||
(vision.styles + vision.prototype.styles).distinct()
|
vision.styles
|
||||||
} else {
|
|
||||||
vision.styles
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flexColumn {
|
flexColumn {
|
||||||
ringIsland("Properties") {
|
ringIsland("Properties") {
|
||||||
propertyEditor(
|
propertyEditor(
|
||||||
@ -52,7 +49,7 @@ public fun RBuilder.ringPropertyEditor(
|
|||||||
ringIslandContent {
|
ringIslandContent {
|
||||||
if (styles.size == 1) {
|
if (styles.size == 1) {
|
||||||
val styleName = styles.first()
|
val styleName = styles.first()
|
||||||
p{
|
p {
|
||||||
+styleName
|
+styleName
|
||||||
}
|
}
|
||||||
val style = vision.getStyle(styleName)
|
val style = vision.getStyle(styleName)
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package space.kscience.visionforge.ring
|
package space.kscience.visionforge.ring
|
||||||
|
|
||||||
import kotlinx.css.BorderStyle
|
import kotlinx.css.*
|
||||||
import kotlinx.css.Color
|
|
||||||
import kotlinx.css.padding
|
|
||||||
import kotlinx.css.properties.border
|
import kotlinx.css.properties.border
|
||||||
import kotlinx.css.px
|
|
||||||
import kotlinx.html.js.onClickFunction
|
import kotlinx.html.js.onClickFunction
|
||||||
import org.w3c.dom.events.Event
|
import org.w3c.dom.events.Event
|
||||||
import org.w3c.files.Blob
|
import org.w3c.files.Blob
|
||||||
@ -17,9 +14,7 @@ import ringui.tabs.ringSmartTabs
|
|||||||
import ringui.tabs.ringTab
|
import ringui.tabs.ringTab
|
||||||
import space.kscience.dataforge.meta.withDefault
|
import space.kscience.dataforge.meta.withDefault
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.isEmpty
|
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.VisionGroup
|
|
||||||
import space.kscience.visionforge.encodeToString
|
import space.kscience.visionforge.encodeToString
|
||||||
import space.kscience.visionforge.react.flexColumn
|
import space.kscience.visionforge.react.flexColumn
|
||||||
import space.kscience.visionforge.react.flexRow
|
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.react.visionTree
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
import styled.css
|
import styled.css
|
||||||
|
import styled.styledDiv
|
||||||
|
|
||||||
internal fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) {
|
internal fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@ -89,38 +85,35 @@ public external interface ThreeControlsProps : RProps {
|
|||||||
public var vision: Vision?
|
public var vision: Vision?
|
||||||
public var selected: Name?
|
public var selected: Name?
|
||||||
public var onSelect: (Name?) -> Unit
|
public var onSelect: (Name?) -> Unit
|
||||||
|
public var additionalTabs: Map<String, RBuilder.() -> Unit>
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
public val ThreeControls: FunctionalComponent<ThreeControlsProps> = functionalComponent { props ->
|
public val ThreeControls: FunctionalComponent<ThreeControlsProps> = functionalComponent { props ->
|
||||||
ringSmartTabs(if (props.selected != null) "Properties" else "Tree") {
|
ringSmartTabs("Tree") {
|
||||||
ringTab("Canvas") {
|
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") {
|
ringIsland("Canvas configuration") {
|
||||||
canvasControls(props.canvasOptions, props.vision)
|
canvasControls(props.canvasOptions, props.vision)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
props.vision?.let {
|
props.additionalTabs.forEach { (name, handler) ->
|
||||||
ringTab("Tree") {
|
ringTab(name){
|
||||||
ringIsland("Vision tree") {
|
handler()
|
||||||
visionTree(it, props.selected, props.onSelect)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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?,
|
vision: Vision?,
|
||||||
selected: Name?,
|
selected: Name?,
|
||||||
onSelect: (Name?) -> Unit = {},
|
onSelect: (Name?) -> Unit = {},
|
||||||
builder: RBuilder.() -> Unit = {},
|
additionalTabs: Map<String, RBuilder.() -> Unit>? = null
|
||||||
): ReactElement = child(ThreeControls) {
|
): ReactElement = child(ThreeControls) {
|
||||||
attrs {
|
attrs {
|
||||||
this.canvasOptions = canvasOptions
|
this.canvasOptions = canvasOptions
|
||||||
this.vision = vision
|
this.vision = vision
|
||||||
this.selected = selected
|
this.selected = selected
|
||||||
this.onSelect = onSelect
|
this.onSelect = onSelect
|
||||||
|
this.additionalTabs = additionalTabs?: emptyMap()
|
||||||
}
|
}
|
||||||
builder()
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user