More or less working muon monitor
This commit is contained in:
parent
72ead21ef0
commit
659b9c3525
@ -1,50 +0,0 @@
|
||||
@file:JsModule("react-file-drop")
|
||||
@file:JsNonModule
|
||||
|
||||
package drop
|
||||
|
||||
import org.w3c.dom.DragEvent
|
||||
import org.w3c.files.FileList
|
||||
import react.Component
|
||||
import react.Props
|
||||
import react.State
|
||||
|
||||
sealed external class DropEffects {
|
||||
@JsName("copy")
|
||||
object Copy : DropEffects
|
||||
|
||||
@JsName("move")
|
||||
object Move : DropEffects
|
||||
|
||||
@JsName("link")
|
||||
object Link : DropEffects
|
||||
|
||||
@JsName("none")
|
||||
object None : DropEffects
|
||||
}
|
||||
|
||||
external interface FileDropProps : Props {
|
||||
var className: String?
|
||||
var targetClassName: String?
|
||||
var draggingOverFrameClassName: String?
|
||||
var draggingOverTargetClassName: String?
|
||||
|
||||
// var frame?: Exclude<HTMLElementTagNameMap[keyof HTMLElementTagNameMap], HTMLElement> | HTMLDocument;
|
||||
var onFrameDragEnter: ((event: DragEvent) -> Unit)?
|
||||
var onFrameDragLeave: ((event: DragEvent) -> Unit)?
|
||||
var onFrameDrop: ((event: DragEvent) -> Unit)?
|
||||
|
||||
// var onDragOver: ReactDragEventHandler<HTMLDivElement>?
|
||||
// var onDragLeave: ReactDragEventHandler<HTMLDivElement>?
|
||||
var onDrop: ((files: FileList?, event: dynamic) -> Unit)?//event:DragEvent<HTMLDivElement>)
|
||||
var dropEffect: DropEffects?
|
||||
}
|
||||
|
||||
external interface FileDropState : State {
|
||||
var draggingOverFrame: Boolean
|
||||
var draggingOverTarget: Boolean
|
||||
}
|
||||
|
||||
external class FileDrop : Component<FileDropProps, FileDropState> {
|
||||
override fun render(): dynamic
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
@file:OptIn(ExperimentalComposeWebApi::class)
|
||||
|
||||
package space.kscience.visionforge.gdml.demo
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import org.jetbrains.compose.web.ExperimentalComposeWebApi
|
||||
import org.jetbrains.compose.web.attributes.InputType
|
||||
import org.jetbrains.compose.web.attributes.name
|
||||
import org.jetbrains.compose.web.css.*
|
||||
import org.jetbrains.compose.web.dom.Div
|
||||
import org.jetbrains.compose.web.dom.I
|
||||
import org.jetbrains.compose.web.dom.Input
|
||||
import org.jetbrains.compose.web.dom.Text
|
||||
import org.w3c.files.FileList
|
||||
|
||||
|
||||
//https://codepen.io/zahedkamal87/pen/PobNNwE
|
||||
@Composable
|
||||
fun FileDrop(
|
||||
title: String = "Drop files or Click here to select files to upload.",
|
||||
onFileDrop: (FileList) -> Unit,
|
||||
) {
|
||||
var dragOver by remember { mutableStateOf(false) }
|
||||
|
||||
Div({
|
||||
id("dropzone")
|
||||
style {
|
||||
border(
|
||||
width = 0.2.cssRem,
|
||||
style = LineStyle.Dashed,
|
||||
color = Color("#6583fe")
|
||||
)
|
||||
padding(2.cssRem)
|
||||
borderRadius(0.25.cssRem)
|
||||
backgroundColor(Color("#fff"))
|
||||
textAlign("center")
|
||||
fontSize(1.5.cssRem)
|
||||
transitions {
|
||||
all {
|
||||
delay(0.25.s)
|
||||
timingFunction(AnimationTimingFunction.EaseInOut)
|
||||
properties("background-color")
|
||||
}
|
||||
}
|
||||
cursor("pointer")
|
||||
}
|
||||
listOf("drag", "dragstart", "dragend", "dragenter").forEach {
|
||||
addEventListener(it) { event ->
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
}
|
||||
}
|
||||
onDragOver { event ->
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
dragOver = true
|
||||
}
|
||||
onDragLeave { event ->
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
dragOver = false
|
||||
}
|
||||
onDrop { event ->
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
dragOver = false
|
||||
event.dataTransfer?.files?.let {
|
||||
onFileDrop(it)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
|
||||
I({ classes("bi", "bi-cloud-upload", "dropzone-icon") })
|
||||
Text(title)
|
||||
Input(type = InputType.File, attrs = {
|
||||
style {
|
||||
display(DisplayStyle.None)
|
||||
}
|
||||
classes("dropzone-input")
|
||||
name("files")
|
||||
})
|
||||
}
|
||||
}
|
||||
//
|
||||
//dropzone.addEventListener("click", function(e) {
|
||||
// dropzone_input.click();
|
||||
//});
|
@ -69,8 +69,8 @@ fun GDMLApp(solids: Solids, initialVision: Solid?, selected: Name? = null) {
|
||||
H2 {
|
||||
Text("Drag and drop .gdml or .json VisionForge files here")
|
||||
}
|
||||
fileDrop("(drag file here)") { files ->
|
||||
val file = files?.get(0)
|
||||
FileDrop("(drag file here)") { files ->
|
||||
val file = files[0]
|
||||
if (file != null) {
|
||||
readFileAsync(file)
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
package space.kscience.visionforge.gdml.demo
|
||||
|
||||
import drop.FileDrop
|
||||
import kotlinx.css.*
|
||||
import org.w3c.files.FileList
|
||||
import react.RBuilder
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
|
||||
//TODO move styles to inline
|
||||
|
||||
fun RBuilder.fileDrop(title: String, action: (files: FileList?) -> Unit) {
|
||||
styledDiv {
|
||||
css {
|
||||
border = Border(style = BorderStyle.dashed, width = 1.px, color = Color.orange)
|
||||
flexGrow = 0.0
|
||||
alignContent = Align.center
|
||||
}
|
||||
|
||||
child(FileDrop::class) {
|
||||
attrs {
|
||||
onDrop = { files, _ ->
|
||||
console.info("loaded $files")
|
||||
action(files)
|
||||
}
|
||||
}
|
||||
+title
|
||||
}
|
||||
}
|
||||
}
|
3
demo/gdml/webpack.config.d/01.ring.js
vendored
3
demo/gdml/webpack.config.d/01.ring.js
vendored
@ -1,3 +0,0 @@
|
||||
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
|
||||
|
||||
config.module.rules.push(...ringConfig.module.rules)
|
@ -1,3 +0,0 @@
|
||||
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
|
||||
|
||||
config.module.rules.push(...ringConfig.module.rules)
|
@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
id("space.kscience.gradle.mpp")
|
||||
alias(spclibs.plugins.compose)
|
||||
application
|
||||
}
|
||||
|
||||
@ -14,11 +15,22 @@ kscience {
|
||||
fullStack(
|
||||
"muon-monitor.js",
|
||||
jvmConfig = { withJava() },
|
||||
jsConfig = { useCommonJs() }
|
||||
// jsConfig = { useCommonJs() },
|
||||
browserConfig = {
|
||||
webpackTask{
|
||||
cssSupport{
|
||||
enabled = true
|
||||
}
|
||||
scssSupport{
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
commonMain {
|
||||
implementation(projects.visionforgeSolid)
|
||||
implementation(projects.visionforgeComposeHtml)
|
||||
}
|
||||
jvmMain {
|
||||
implementation("org.apache.commons:commons-math3:3.6.1")
|
||||
|
@ -4,12 +4,13 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.remember
|
||||
import app.softwork.bootstrapcompose.Button
|
||||
import app.softwork.bootstrapcompose.ButtonGroup
|
||||
import app.softwork.bootstrapcompose.Container
|
||||
import kotlinx.browser.window
|
||||
import kotlinx.coroutines.await
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.jetbrains.compose.web.css.*
|
||||
import org.jetbrains.compose.web.dom.Div
|
||||
import org.jetbrains.compose.web.dom.P
|
||||
import org.jetbrains.compose.web.dom.Span
|
||||
import org.jetbrains.compose.web.dom.Text
|
||||
@ -17,8 +18,6 @@ import org.w3c.fetch.RequestInit
|
||||
import space.kscience.dataforge.meta.invoke
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.Colors
|
||||
import space.kscience.visionforge.compose.FlexColumn
|
||||
import space.kscience.visionforge.compose.FlexRow
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import space.kscience.visionforge.solid.ambientLight
|
||||
import space.kscience.visionforge.solid.edges
|
||||
@ -51,16 +50,21 @@ fun MMApp(solids: Solids, model: Model, selected: Name? = null) {
|
||||
|
||||
val events = remember { mutableStateListOf<Event>() }
|
||||
|
||||
Div({
|
||||
style {
|
||||
height(100.vh - 12.pt)
|
||||
Container(fluid = true,
|
||||
attrs = {
|
||||
style {
|
||||
height(100.vh - 12.pt)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
ThreeView(solids, root, selected, mmOptions) {
|
||||
Tab("Events") {
|
||||
|
||||
FlexColumn {
|
||||
FlexRow {
|
||||
) {
|
||||
ThreeView(
|
||||
solids = solids,
|
||||
solid = root,
|
||||
initialSelected = selected,
|
||||
options = mmOptions,
|
||||
sidebarTabs = {
|
||||
Tab("Events") {
|
||||
ButtonGroup {
|
||||
Button("Next") {
|
||||
solids.context.launch {
|
||||
val event = window.fetch(
|
||||
@ -84,23 +88,24 @@ fun MMApp(solids: Solids, model: Model, selected: Name? = null) {
|
||||
model.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
events.forEach { event ->
|
||||
P {
|
||||
Span {
|
||||
Text(event.id.toString())
|
||||
}
|
||||
Text(" : ")
|
||||
Span({
|
||||
style {
|
||||
color(Color.blue)
|
||||
|
||||
events.forEach { event ->
|
||||
P {
|
||||
Span {
|
||||
Text(event.id.toString())
|
||||
}
|
||||
Text(" : ")
|
||||
Span({
|
||||
style {
|
||||
color(Color.blue)
|
||||
}
|
||||
}) {
|
||||
Text(event.hits.toString())
|
||||
}
|
||||
}) {
|
||||
Text(event.hits.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
package ru.mipt.npm.muon.monitor
|
||||
|
||||
import org.jetbrains.compose.web.css.Style
|
||||
import org.jetbrains.compose.web.renderComposable
|
||||
import org.w3c.dom.Document
|
||||
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.solid.Solids
|
||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||
import space.kscience.visionforge.startApplication
|
||||
@ -22,8 +24,8 @@ private class MMDemoApp : Application {
|
||||
|
||||
val model = Model(visionManager)
|
||||
|
||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||
renderComposable(element) {
|
||||
renderComposable("app") {
|
||||
Style(VisionForgeStyles)
|
||||
MMApp(context.request(Solids), model)
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
|
||||
|
||||
config.module.rules.push(...ringConfig.module.rules)
|
@ -16,6 +16,12 @@ kotlin {
|
||||
js(IR) {
|
||||
browser {
|
||||
webpackTask {
|
||||
cssSupport{
|
||||
enabled = true
|
||||
}
|
||||
scssSupport{
|
||||
enabled = true
|
||||
}
|
||||
mainOutputFileName.set("js/visionforge-playground.js")
|
||||
}
|
||||
}
|
||||
|
23
demo/playground/webpack.config.d/01.ring.js
vendored
23
demo/playground/webpack.config.d/01.ring.js
vendored
@ -1,23 +0,0 @@
|
||||
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
|
||||
const path = require('path');
|
||||
|
||||
config.module.rules.push(...ringConfig.module.rules)
|
||||
|
||||
config.module.rules.push(
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: [
|
||||
path.resolve(__dirname, "../../node_modules/@jetbrains/ring-ui")
|
||||
],
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader',
|
||||
options: {}
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {}
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
@ -41,11 +41,11 @@ dependencyResolutionManagement {
|
||||
|
||||
include(
|
||||
// ":ui",
|
||||
":ui:react",
|
||||
":ui:ring",
|
||||
// ":ui:react",
|
||||
// ":ui:ring",
|
||||
// ":ui:material",
|
||||
":ui:bootstrap",
|
||||
":visionforge-compose",
|
||||
// ":ui:bootstrap",
|
||||
":visionforge-compose-html",
|
||||
":visionforge-core",
|
||||
":visionforge-solid",
|
||||
// ":visionforge-fx",
|
||||
|
@ -1,10 +1,9 @@
|
||||
|
||||
plugins {
|
||||
id("space.kscience.gradle.mpp")
|
||||
alias(spclibs.plugins.compose)
|
||||
}
|
||||
|
||||
kscience{
|
||||
kscience {
|
||||
jvm()
|
||||
js()
|
||||
// wasm()
|
||||
@ -13,22 +12,22 @@ kscience{
|
||||
kotlin {
|
||||
// android()
|
||||
sourceSets {
|
||||
commonMain{
|
||||
dependencies{
|
||||
commonMain {
|
||||
dependencies {
|
||||
api(projects.visionforgeCore)
|
||||
api(compose.runtime)
|
||||
}
|
||||
}
|
||||
|
||||
val jvmMain by getting {
|
||||
dependencies {
|
||||
api(compose.runtime)
|
||||
api(compose.foundation)
|
||||
api(compose.material)
|
||||
api(compose.preview)
|
||||
}
|
||||
}
|
||||
|
||||
val jsMain by getting{
|
||||
val jsMain by getting {
|
||||
dependencies {
|
||||
api(compose.html.core)
|
||||
api("app.softwork:bootstrap-compose:0.1.15")
|
@ -0,0 +1,88 @@
|
||||
package space.kscience.visionforge.compose
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import app.softwork.bootstrapcompose.Card
|
||||
import app.softwork.bootstrapcompose.NavbarLink
|
||||
import app.softwork.bootstrapcompose.Styling
|
||||
import org.jetbrains.compose.web.dom.*
|
||||
import org.w3c.dom.HTMLAnchorElement
|
||||
import org.w3c.dom.HTMLDivElement
|
||||
|
||||
|
||||
public class ComposeTab(
|
||||
public val key: String,
|
||||
public val title: ContentBuilder<HTMLAnchorElement>,
|
||||
public val disabled: Boolean,
|
||||
public val content: ContentBuilder<HTMLDivElement>,
|
||||
)
|
||||
|
||||
@Composable
|
||||
public fun Tabs(
|
||||
tabs: List<ComposeTab>,
|
||||
activeKey: String,
|
||||
styling: (Styling.() -> Unit)? = null,
|
||||
attrs: AttrBuilderContext<HTMLDivElement>? = null,
|
||||
) {
|
||||
var active by remember(activeKey) { mutableStateOf(activeKey) }
|
||||
|
||||
val activeTab by derivedStateOf { tabs.find { it.key == active } }
|
||||
|
||||
Card(
|
||||
styling,
|
||||
attrs,
|
||||
header = {
|
||||
Ul({ classes("nav", "nav-tabs", "card-header-tabs") }) {
|
||||
tabs.forEach { tab ->
|
||||
Li({
|
||||
classes("nav-item")
|
||||
}) {
|
||||
NavbarLink(
|
||||
active = active == tab.key,
|
||||
disabled = tab.disabled,
|
||||
attrs = {
|
||||
onClick { event ->
|
||||
event.preventDefault()
|
||||
active = tab.key
|
||||
}
|
||||
}
|
||||
) {
|
||||
tab.title.invoke(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
activeTab?.content?.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
public class TabsBuilder {
|
||||
internal val tabs: MutableList<ComposeTab> = mutableListOf()
|
||||
|
||||
@Composable
|
||||
public fun Tab(
|
||||
key: String,
|
||||
label: ContentBuilder<HTMLAnchorElement> = { Text(key) },
|
||||
disabled: Boolean = false,
|
||||
content: ContentBuilder<HTMLDivElement>,
|
||||
) {
|
||||
tabs.add(ComposeTab(key, label, disabled, content))
|
||||
}
|
||||
|
||||
public fun addTab(tab: ComposeTab) {
|
||||
tabs.add(tab)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
public fun Tabs(
|
||||
activeKey: String? = null,
|
||||
styling: (Styling.() -> Unit)? = null,
|
||||
attrs: AttrBuilderContext<HTMLDivElement>? = null,
|
||||
builder: @Composable TabsBuilder.() -> Unit,
|
||||
) {
|
||||
val result = TabsBuilder().apply { builder() }
|
||||
|
||||
Tabs(result.tabs, activeKey ?: result.tabs.firstOrNull()?.key ?: "", styling, attrs)
|
||||
}
|
@ -5,7 +5,7 @@ import org.jetbrains.compose.web.css.*
|
||||
|
||||
|
||||
@OptIn(ExperimentalComposeWebApi::class)
|
||||
public object TreeStyles : StyleSheet() {
|
||||
public object TreeStyles : StyleSheet(VisionForgeStyles) {
|
||||
/**
|
||||
* Remove default bullets
|
||||
*/
|
||||
@ -46,13 +46,11 @@ public object TreeStyles : StyleSheet() {
|
||||
public val treeItem: String by style {
|
||||
alignItems(AlignItems.Center)
|
||||
paddingLeft(10.px)
|
||||
border {
|
||||
left {
|
||||
width(1.px)
|
||||
color(Color.lightgray)
|
||||
style = LineStyle.Dashed
|
||||
}
|
||||
}
|
||||
property("border-left", CSSBorder().apply{
|
||||
width(1.px)
|
||||
color(Color.lightgray)
|
||||
style = LineStyle.Dashed
|
||||
})
|
||||
}
|
||||
|
||||
public val treeLabel: String by style {
|
||||
@ -75,7 +73,7 @@ public object TreeStyles : StyleSheet() {
|
||||
alignSelf(AlignSelf.Stretch)
|
||||
marginAll(1.px, 5.px)
|
||||
backgroundColor(Color.white)
|
||||
border{
|
||||
border {
|
||||
style(LineStyle.Solid)
|
||||
}
|
||||
borderRadius(2.px)
|
||||
@ -84,7 +82,7 @@ public object TreeStyles : StyleSheet() {
|
||||
cursor("pointer")
|
||||
disabled {
|
||||
cursor("auto")
|
||||
border{
|
||||
border {
|
||||
style(LineStyle.Dashed)
|
||||
}
|
||||
color(Color.lightgray)
|
@ -0,0 +1,7 @@
|
||||
package space.kscience.visionforge.compose
|
||||
|
||||
import org.jetbrains.compose.web.css.StyleSheet
|
||||
|
||||
public object VisionForgeStyles: StyleSheet() {
|
||||
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package space.kscience.visionforge.compose
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import org.jetbrains.compose.web.dom.*
|
||||
import org.w3c.dom.HTMLDivElement
|
||||
import org.w3c.dom.HTMLLIElement
|
||||
|
||||
|
||||
public class ComposeTab(
|
||||
public val key: String,
|
||||
public val title: String,
|
||||
public val content: ContentBuilder<HTMLDivElement>,
|
||||
public val disabled: Boolean,
|
||||
public val titleExt: ContentBuilder<HTMLLIElement>,
|
||||
)
|
||||
|
||||
@Composable
|
||||
public fun Tabs(tabs: List<ComposeTab>, activeKey: String) {
|
||||
var active by remember(activeKey) { mutableStateOf(activeKey) }
|
||||
|
||||
Div({ classes("card", "text-center") }) {
|
||||
Div({ classes("card-header") }) {
|
||||
|
||||
Ul({ classes("nav", "nav-tabs", "card-header-tabs") }) {
|
||||
tabs.forEach { tab ->
|
||||
Li({
|
||||
classes("nav-item")
|
||||
}) {
|
||||
A(attrs = {
|
||||
classes("nav-link")
|
||||
if (active == tab.key) {
|
||||
classes("active")
|
||||
}
|
||||
if (tab.disabled) {
|
||||
classes("disabled")
|
||||
}
|
||||
onClick {
|
||||
active = tab.key
|
||||
}
|
||||
}) {
|
||||
Text(tab.title)
|
||||
}
|
||||
tab.titleExt.invoke(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tabs.find { it.key == active }?.let { tab ->
|
||||
Div({ classes("card-body") }) {
|
||||
tab.content.invoke(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class TabBuilder internal constructor(public val key: String) {
|
||||
private var title: String = key
|
||||
public var disabled: Boolean = false
|
||||
private var content: ContentBuilder<HTMLDivElement> = {}
|
||||
private var titleExt: ContentBuilder<HTMLLIElement> = {}
|
||||
|
||||
@Composable
|
||||
public fun Content(content: ContentBuilder<HTMLDivElement>) {
|
||||
this.content = content
|
||||
}
|
||||
|
||||
@Composable
|
||||
public fun Title(title: String, titleExt: ContentBuilder<HTMLLIElement> = {}) {
|
||||
this.title = title
|
||||
this.titleExt = titleExt
|
||||
}
|
||||
|
||||
internal fun build(): ComposeTab = ComposeTab(
|
||||
key,
|
||||
title,
|
||||
content,
|
||||
disabled,
|
||||
titleExt
|
||||
)
|
||||
}
|
||||
|
||||
public class TabsBuilder {
|
||||
public var active: String = ""
|
||||
internal val tabs: MutableList<ComposeTab> = mutableListOf()
|
||||
|
||||
@Composable
|
||||
public fun Tab(key: String, builder: @Composable TabBuilder.() -> Unit) {
|
||||
tabs.add(TabBuilder(key).apply { builder() }.build())
|
||||
}
|
||||
|
||||
public fun addTab(tab: ComposeTab) {
|
||||
tabs.add(tab)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
public fun Tabs(builder: @Composable TabsBuilder.() -> Unit) {
|
||||
val result = TabsBuilder().apply { builder() }
|
||||
Tabs(result.tabs, result.active)
|
||||
}
|
@ -7,6 +7,16 @@ description = "Jupyter api artifact including all common modules"
|
||||
kscience {
|
||||
fullStack(
|
||||
"js/visionforge-jupyter-common.js",
|
||||
browserConfig = {
|
||||
webpackTask {
|
||||
cssSupport{
|
||||
enabled = true
|
||||
}
|
||||
scssSupport {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
dependencies {
|
||||
api(projects.visionforgeSolid)
|
||||
|
@ -1,24 +0,0 @@
|
||||
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
|
||||
|
||||
const path = require('path');
|
||||
|
||||
config.module.rules.push(...ringConfig.module.rules)
|
||||
|
||||
config.module.rules.push(
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: [
|
||||
path.resolve(__dirname, "../../node_modules/@jetbrains/ring-ui")
|
||||
],
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader',
|
||||
options: {}
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {}
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
@ -7,7 +7,7 @@ import space.kscience.dataforge.meta.boolean
|
||||
|
||||
public class Canvas3DUIScheme : Scheme() {
|
||||
|
||||
public var enabled: Boolean by boolean{true}
|
||||
public var enabled: Boolean by boolean { true }
|
||||
|
||||
public companion object : SchemeSpec<Canvas3DUIScheme>(::Canvas3DUIScheme)
|
||||
}
|
@ -7,8 +7,14 @@ val tablesVersion = "0.3.0"
|
||||
kscience {
|
||||
jvm()
|
||||
js {
|
||||
useCommonJs()
|
||||
binaries.library()
|
||||
browser {
|
||||
webpackTask{
|
||||
scssSupport {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useSerialization()
|
||||
@ -17,8 +23,8 @@ kscience {
|
||||
api("space.kscience:tables-kt:${tablesVersion}")
|
||||
}
|
||||
jsMain {
|
||||
implementation(npm("tabulator-tables", "5.5.2"))
|
||||
implementation(npm("@types/tabulator-tables", "5.5.3"))
|
||||
api(npm("tabulator-tables", "5.5.2"))
|
||||
api(npm("@types/tabulator-tables", "5.5.3"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
"NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING")
|
||||
|
||||
@file:JsModule("tabulator-tables")
|
||||
@file:JsNonModule
|
||||
|
||||
package tabulator
|
||||
|
||||
|
@ -14,7 +14,7 @@ kscience {
|
||||
|
||||
commonMain {
|
||||
api(projects.visionforgeSolid)
|
||||
api(projects.visionforgeCompose)
|
||||
api(projects.visionforgeComposeHtml)
|
||||
}
|
||||
|
||||
jsMain {
|
||||
|
@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import org.jetbrains.compose.web.renderComposable
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.HTMLElement
|
||||
import space.kscience.dataforge.context.*
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.names.*
|
||||
|
@ -1,6 +1,9 @@
|
||||
package space.kscience.visionforge.solid.three.compose
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import app.softwork.bootstrapcompose.Column
|
||||
import app.softwork.bootstrapcompose.Layout.Height
|
||||
import app.softwork.bootstrapcompose.Row
|
||||
import org.jetbrains.compose.web.css.*
|
||||
import org.jetbrains.compose.web.dom.Button
|
||||
import org.jetbrains.compose.web.dom.Text
|
||||
@ -18,8 +21,8 @@ internal fun CanvasControls(
|
||||
vision: Vision?,
|
||||
options: Canvas3DOptions,
|
||||
) {
|
||||
FlexColumn {
|
||||
FlexRow({
|
||||
Column {
|
||||
Row(attrs = {
|
||||
style {
|
||||
border {
|
||||
width(1.px)
|
||||
@ -64,8 +67,11 @@ public fun ThreeControls(
|
||||
onSelect: (Name?) -> Unit,
|
||||
tabBuilder: @Composable TabsBuilder.() -> Unit = {},
|
||||
) {
|
||||
Tabs {
|
||||
active = "Tree"
|
||||
Tabs(
|
||||
styling = {
|
||||
Layout.height = Height.Full
|
||||
}
|
||||
) {
|
||||
vision?.let { vision ->
|
||||
Tab("Tree") {
|
||||
CardTitle("Vision tree")
|
||||
|
@ -2,6 +2,10 @@ package space.kscience.visionforge.solid.three.compose
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import app.softwork.bootstrapcompose.Card
|
||||
import app.softwork.bootstrapcompose.Column
|
||||
import app.softwork.bootstrapcompose.Layout.Height
|
||||
import app.softwork.bootstrapcompose.Layout.Width
|
||||
import app.softwork.bootstrapcompose.Row
|
||||
import kotlinx.dom.clear
|
||||
import org.jetbrains.compose.web.ExperimentalComposeWebApi
|
||||
import org.jetbrains.compose.web.css.*
|
||||
@ -90,24 +94,27 @@ public fun ThreeView(
|
||||
|
||||
if (optionsSnapshot.controls.enabled) {
|
||||
|
||||
|
||||
FlexRow({
|
||||
style {
|
||||
height(100.percent)
|
||||
width(100.percent)
|
||||
flexWrap(FlexWrap.Wrap)
|
||||
alignItems(AlignItems.Stretch)
|
||||
alignContent(AlignContent.Stretch)
|
||||
}
|
||||
}) {
|
||||
FlexColumn({
|
||||
style {
|
||||
height(100.percent)
|
||||
minWidth(600.px)
|
||||
flex(10, 1, 600.px)
|
||||
position(Position.Relative)
|
||||
Row(
|
||||
styling = {
|
||||
Layout {
|
||||
width = Width.Full
|
||||
height = Height.Full
|
||||
}
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
Column(
|
||||
styling = {
|
||||
Layout {
|
||||
height = Height.Full
|
||||
}
|
||||
},
|
||||
attrs = {
|
||||
style {
|
||||
position(Position.Relative)
|
||||
minWidth(600.px)
|
||||
}
|
||||
}
|
||||
) {
|
||||
if (solid == null) {
|
||||
Div({
|
||||
style {
|
||||
@ -143,61 +150,68 @@ public fun ThreeView(
|
||||
}
|
||||
|
||||
selectedVision?.let { vision ->
|
||||
Div({
|
||||
style {
|
||||
position(Position.Absolute)
|
||||
top(5.px)
|
||||
right(5.px)
|
||||
width(450.px)
|
||||
Card(
|
||||
attrs = {
|
||||
style {
|
||||
position(Position.Absolute)
|
||||
top(5.px)
|
||||
right(5.px)
|
||||
width(450.px)
|
||||
}
|
||||
},
|
||||
headerAttrs = {
|
||||
// border = true
|
||||
},
|
||||
header = {
|
||||
NameCrumbs(selected) { selected = it }
|
||||
},
|
||||
footer = {
|
||||
vision.styles.takeIf { it.isNotEmpty() }?.let { styles ->
|
||||
P {
|
||||
B { Text("Styles: ") }
|
||||
Text(styles.joinToString(separator = ", "))
|
||||
}
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Card(
|
||||
headerAttrs = {
|
||||
// border = true
|
||||
) {
|
||||
PropertyEditor(
|
||||
scope = solids.context,
|
||||
meta = vision.properties.root(),
|
||||
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
|
||||
}
|
||||
},
|
||||
header = {
|
||||
NameCrumbs(selected) { selected = it }
|
||||
}
|
||||
) {
|
||||
PropertyEditor(
|
||||
scope = solids.context,
|
||||
meta = vision.properties.root(),
|
||||
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
|
||||
}
|
||||
},
|
||||
updates = vision.properties.changes,
|
||||
rootDescriptor = vision.descriptor
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
vision.styles.takeIf { it.isNotEmpty() }?.let { styles ->
|
||||
P {
|
||||
B { Text("Styles: ") }
|
||||
Text(styles.joinToString(separator = ", "))
|
||||
}
|
||||
}
|
||||
updates = vision.properties.changes,
|
||||
rootDescriptor = vision.descriptor
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FlexColumn({
|
||||
style {
|
||||
paddingAll(4.px)
|
||||
minWidth(400.px)
|
||||
height(100.percent)
|
||||
overflowY("auto")
|
||||
flex(1, 10, 300.px)
|
||||
|
||||
Column(
|
||||
auto = true,
|
||||
styling = {
|
||||
Layout {
|
||||
height = Height.Full
|
||||
}
|
||||
},
|
||||
attrs = {
|
||||
style {
|
||||
paddingAll(4.px)
|
||||
minWidth(400.px)
|
||||
height(100.percent)
|
||||
overflowY("auto")
|
||||
}
|
||||
}
|
||||
) {
|
||||
ThreeControls(solid, optionsSnapshot, selected, onSelect = { selected = it }, tabBuilder = sidebarTabs)
|
||||
}
|
||||
}) {
|
||||
ThreeControls(solid, optionsSnapshot, selected, onSelect = { selected = it }, tabBuilder = sidebarTabs)
|
||||
}
|
||||
} else {
|
||||
SimpleThreeView(solids.context, optionsSnapshot, solid, selected)
|
||||
|
@ -10,7 +10,7 @@ kscience {
|
||||
|
||||
commonMain {
|
||||
api(projects.visionforgeSolid)
|
||||
api(projects.visionforgeCompose)
|
||||
api(projects.visionforgeComposeHtml)
|
||||
}
|
||||
|
||||
jvmMain{
|
||||
@ -19,6 +19,8 @@ kscience {
|
||||
|
||||
jsMain{
|
||||
api(projects.visionforgeThreejs)
|
||||
implementation(npm("file-saver","2.0.5"))
|
||||
implementation(npm("@types/file-saver", "2.0.7"))
|
||||
compileOnly(npm("webpack-bundle-analyzer","4.5.0"))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user