Design update for gdml demo
This commit is contained in:
parent
ca2b267fc4
commit
f484d5d1ff
@ -31,21 +31,13 @@ kotlin {
|
|||||||
jsMain {
|
jsMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
||||||
|
|
||||||
api("org.jetbrains:kotlin-react:16.13.1-pre.104-kotlin-1.3.72")
|
|
||||||
api("org.jetbrains:kotlin-react-dom:16.13.1-pre.104-kotlin-1.3.72")
|
|
||||||
api("org.jetbrains.kotlinx:kotlinx-html:0.6.12")
|
api("org.jetbrains.kotlinx:kotlinx-html:0.6.12")
|
||||||
|
|
||||||
api("org.jetbrains:kotlin-extensions:1.0.1-pre.104-kotlin-1.3.72")
|
//api("org.jetbrains:kotlin-extensions:1.0.1-pre.105-kotlin-1.3.72")
|
||||||
api("org.jetbrains:kotlin-css-js:1.0.0-pre.94-kotlin-1.3.70")
|
//api("org.jetbrains:kotlin-css-js:1.0.0-pre.105-kotlin-1.3.72")
|
||||||
api("org.jetbrains:kotlin-styled:1.0.0-pre.104-kotlin-1.3.72")
|
api("org.jetbrains:kotlin-styled:1.0.0-pre.104-kotlin-1.3.72")
|
||||||
|
|
||||||
api(npm("core-js", "2.6.5"))
|
api(npm("core-js", "2.6.5"))
|
||||||
|
|
||||||
api(npm("react", "16.13.1"))
|
|
||||||
api(npm("react-dom", "16.13.1"))
|
|
||||||
|
|
||||||
api(npm("react-is", "16.13.0"))
|
|
||||||
api(npm("inline-style-prefixer", "5.1.0"))
|
api(npm("inline-style-prefixer", "5.1.0"))
|
||||||
api(npm("styled-components", "4.3.2"))
|
api(npm("styled-components", "4.3.2"))
|
||||||
//api(project(":ringui-wrapper"))
|
//api(project(":ringui-wrapper"))
|
||||||
|
@ -2,9 +2,12 @@ package hep.dataforge.vis
|
|||||||
|
|
||||||
import hep.dataforge.meta.Laminate
|
import hep.dataforge.meta.Laminate
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.MetaItem
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.meta.node
|
import hep.dataforge.meta.node
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.names.isEmpty
|
||||||
|
import hep.dataforge.values.ValueType
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return nearest selectable parent [Name]
|
* Return nearest selectable parent [Name]
|
||||||
@ -21,7 +24,7 @@ tailrec fun Name.selectable(): Name? = when {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>?{
|
fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? {
|
||||||
return when (val first = filterNotNull().firstOrNull()) {
|
return when (val first = filterNotNull().firstOrNull()) {
|
||||||
null -> null
|
null -> null
|
||||||
is MetaItem.ValueItem -> first //fast search for first entry if it is value
|
is MetaItem.ValueItem -> first //fast search for first entry if it is value
|
||||||
@ -31,4 +34,12 @@ fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>?{
|
|||||||
MetaItem.NodeItem(laminate)
|
MetaItem.NodeItem(laminate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified E : Enum<E>> NodeDescriptor.enum(key: Name, default: E?) = value(key) {
|
||||||
|
type(ValueType.STRING)
|
||||||
|
default?.let {
|
||||||
|
default(default)
|
||||||
|
}
|
||||||
|
allowedValues = enumValues<E>().map{it.asValue()}
|
||||||
}
|
}
|
@ -69,13 +69,13 @@ class Visual3D(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
|
|
||||||
internal fun VisualObject3D.update(meta: Meta) {
|
internal fun VisualObject3D.update(meta: Meta) {
|
||||||
fun Meta.toVector(default: Float = 0f) = Point3D(
|
fun Meta.toVector(default: Float = 0f) = Point3D(
|
||||||
this[VisualObject3D.x].float ?: default,
|
this[VisualObject3D.X_KEY].float ?: default,
|
||||||
this[VisualObject3D.y].float ?: default,
|
this[VisualObject3D.Y_KEY].float ?: default,
|
||||||
this[VisualObject3D.z].float ?: default
|
this[VisualObject3D.Z_KEY].float ?: default
|
||||||
)
|
)
|
||||||
|
|
||||||
meta[VisualObject3D.position].node?.toVector()?.let { position = it }
|
meta[VisualObject3D.POSITION_KEY].node?.toVector()?.let { position = it }
|
||||||
meta[VisualObject3D.rotation].node?.toVector()?.let { rotation = it }
|
meta[VisualObject3D.ROTATION].node?.toVector()?.let { rotation = it }
|
||||||
meta[VisualObject3D.scale].node?.toVector(1f)?.let { scale = it }
|
meta[VisualObject3D.SCALE_KEY].node?.toVector(1f)?.let { scale = it }
|
||||||
meta["properties"].node?.let { configure(it) }
|
meta["properties"].node?.let { configure(it) }
|
||||||
}
|
}
|
@ -10,6 +10,7 @@ import hep.dataforge.output.Renderer
|
|||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.values.asValue
|
import hep.dataforge.values.asValue
|
||||||
import hep.dataforge.vis.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
|
import hep.dataforge.vis.enum
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.DETAIL_KEY
|
import hep.dataforge.vis.spatial.VisualObject3D.Companion.DETAIL_KEY
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.IGNORE_KEY
|
import hep.dataforge.vis.spatial.VisualObject3D.Companion.IGNORE_KEY
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.LAYER_KEY
|
import hep.dataforge.vis.spatial.VisualObject3D.Companion.LAYER_KEY
|
||||||
@ -37,29 +38,29 @@ interface VisualObject3D : VisualObject {
|
|||||||
|
|
||||||
val GEOMETRY_KEY = "geometry".asName()
|
val GEOMETRY_KEY = "geometry".asName()
|
||||||
|
|
||||||
val x = "x".asName()
|
val X_KEY = "x".asName()
|
||||||
val y = "y".asName()
|
val Y_KEY = "y".asName()
|
||||||
val z = "z".asName()
|
val Z_KEY = "z".asName()
|
||||||
|
|
||||||
val position = "pos".asName()
|
val POSITION_KEY = "pos".asName()
|
||||||
|
|
||||||
val xPos = position + x
|
val X_POSITION_KEY = POSITION_KEY + X_KEY
|
||||||
val yPos = position + y
|
val Y_POSITION_KEY = POSITION_KEY + Y_KEY
|
||||||
val zPos = position + z
|
val Z_POSITION_KEY = POSITION_KEY + Z_KEY
|
||||||
|
|
||||||
val rotation = "rotation".asName()
|
val ROTATION = "rotation".asName()
|
||||||
|
|
||||||
val xRotation = rotation + x
|
val X_ROTATION_KEY = ROTATION + X_KEY
|
||||||
val yRotation = rotation + y
|
val Y_ROTATION_KEY = ROTATION + Y_KEY
|
||||||
val zRotation = rotation + z
|
val Z_ROTATION_KEY = ROTATION + Z_KEY
|
||||||
|
|
||||||
val rotationOrder = rotation + "order"
|
val ROTATION_ORDER_KEY = ROTATION + "order"
|
||||||
|
|
||||||
val scale = "scale".asName()
|
val SCALE_KEY = "scale".asName()
|
||||||
|
|
||||||
val xScale = scale + x
|
val X_SCALE_KEY = SCALE_KEY + X_KEY
|
||||||
val yScale = scale + y
|
val Y_SCALE_KEY = SCALE_KEY + Y_KEY
|
||||||
val zScale = scale + z
|
val Z_SCALE_KEY = SCALE_KEY + Z_KEY
|
||||||
|
|
||||||
val descriptor by lazy {
|
val descriptor by lazy {
|
||||||
NodeDescriptor {
|
NodeDescriptor {
|
||||||
@ -69,12 +70,14 @@ interface VisualObject3D : VisualObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO replace by descriptor merge
|
//TODO replace by descriptor merge
|
||||||
value(VisualObject.STYLE_KEY){
|
value(VisualObject.STYLE_KEY) {
|
||||||
type(ValueType.STRING)
|
type(ValueType.STRING)
|
||||||
multiple = true
|
multiple = true
|
||||||
}
|
}
|
||||||
|
|
||||||
item(Material3D.MATERIAL_KEY.toString(), Material3D.descriptor)
|
item(Material3D.MATERIAL_KEY.toString(), Material3D.descriptor)
|
||||||
|
|
||||||
|
enum<RotationOrder>(ROTATION_ORDER_KEY,default = RotationOrder.XYZ)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,8 +110,8 @@ enum class RotationOrder {
|
|||||||
* Rotation order
|
* Rotation order
|
||||||
*/
|
*/
|
||||||
var VisualObject3D.rotationOrder: RotationOrder
|
var VisualObject3D.rotationOrder: RotationOrder
|
||||||
get() = getProperty(VisualObject3D.rotationOrder).enum<RotationOrder>() ?: RotationOrder.XYZ
|
get() = getProperty(VisualObject3D.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
|
||||||
set(value) = setProperty(VisualObject3D.rotationOrder, value.name.asValue())
|
set(value) = setProperty(VisualObject3D.ROTATION_ORDER_KEY, value.name.asValue())
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,21 +144,21 @@ var VisualObject3D.x: Number
|
|||||||
get() = position?.x ?: 0f
|
get() = position?.x ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
position().x = value.toDouble()
|
position().x = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.xPos)
|
propertyInvalidated(VisualObject3D.X_POSITION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var VisualObject3D.y: Number
|
var VisualObject3D.y: Number
|
||||||
get() = position?.y ?: 0f
|
get() = position?.y ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
position().y = value.toDouble()
|
position().y = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.yPos)
|
propertyInvalidated(VisualObject3D.Y_POSITION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var VisualObject3D.z: Number
|
var VisualObject3D.z: Number
|
||||||
get() = position?.z ?: 0f
|
get() = position?.z ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
position().z = value.toDouble()
|
position().z = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.zPos)
|
propertyInvalidated(VisualObject3D.Z_POSITION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun VisualObject3D.rotation(): Point3D =
|
private fun VisualObject3D.rotation(): Point3D =
|
||||||
@ -165,21 +168,21 @@ var VisualObject3D.rotationX: Number
|
|||||||
get() = rotation?.x ?: 0f
|
get() = rotation?.x ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
rotation().x = value.toDouble()
|
rotation().x = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.xRotation)
|
propertyInvalidated(VisualObject3D.X_ROTATION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var VisualObject3D.rotationY: Number
|
var VisualObject3D.rotationY: Number
|
||||||
get() = rotation?.y ?: 0f
|
get() = rotation?.y ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
rotation().y = value.toDouble()
|
rotation().y = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.yRotation)
|
propertyInvalidated(VisualObject3D.Y_ROTATION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var VisualObject3D.rotationZ: Number
|
var VisualObject3D.rotationZ: Number
|
||||||
get() = rotation?.z ?: 0f
|
get() = rotation?.z ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
rotation().z = value.toDouble()
|
rotation().z = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.zRotation)
|
propertyInvalidated(VisualObject3D.Z_ROTATION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun VisualObject3D.scale(): Point3D =
|
private fun VisualObject3D.scale(): Point3D =
|
||||||
@ -189,19 +192,19 @@ var VisualObject3D.scaleX: Number
|
|||||||
get() = scale?.x ?: 1f
|
get() = scale?.x ?: 1f
|
||||||
set(value) {
|
set(value) {
|
||||||
scale().x = value.toDouble()
|
scale().x = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.xScale)
|
propertyInvalidated(VisualObject3D.X_SCALE_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var VisualObject3D.scaleY: Number
|
var VisualObject3D.scaleY: Number
|
||||||
get() = scale?.y ?: 1f
|
get() = scale?.y ?: 1f
|
||||||
set(value) {
|
set(value) {
|
||||||
scale().y = value.toDouble()
|
scale().y = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.yScale)
|
propertyInvalidated(VisualObject3D.Y_SCALE_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var VisualObject3D.scaleZ: Number
|
var VisualObject3D.scaleZ: Number
|
||||||
get() = scale?.z ?: 1f
|
get() = scale?.z ?: 1f
|
||||||
set(value) {
|
set(value) {
|
||||||
scale().z = value.toDouble()
|
scale().z = value.toDouble()
|
||||||
propertyInvalidated(VisualObject3D.zScale)
|
propertyInvalidated(VisualObject3D.Z_SCALE_KEY)
|
||||||
}
|
}
|
@ -21,8 +21,8 @@ operator fun Point2D.component1() = x
|
|||||||
operator fun Point2D.component2() = y
|
operator fun Point2D.component2() = y
|
||||||
|
|
||||||
fun Point2D.toMeta() = Meta {
|
fun Point2D.toMeta() = Meta {
|
||||||
VisualObject3D.x put x
|
VisualObject3D.X_KEY put x
|
||||||
VisualObject3D.y put y
|
VisualObject3D.Y_KEY put y
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Meta.point2D() = Point2D(this["x"].number ?: 0, this["y"].number ?: 0)
|
fun Meta.point2D() = Point2D(this["x"].number ?: 0, this["y"].number ?: 0)
|
||||||
@ -42,7 +42,7 @@ operator fun Point3D.component3() = z
|
|||||||
fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0)
|
fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0)
|
||||||
|
|
||||||
fun Point3D.toMeta() = Meta {
|
fun Point3D.toMeta() = Meta {
|
||||||
VisualObject3D.x put x
|
VisualObject3D.X_KEY put x
|
||||||
VisualObject3D.y put y
|
VisualObject3D.Y_KEY put y
|
||||||
VisualObject3D.z put z
|
VisualObject3D.Z_KEY put z
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ import hep.dataforge.vis.useStyle
|
|||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@Suppress("UNUSED_VARIABLE")
|
||||||
class PropertyTest {
|
class PropertyTest {
|
||||||
@Test
|
@Test
|
||||||
fun testInheritedProperty() {
|
fun testInheritedProperty() {
|
||||||
|
@ -60,9 +60,9 @@ fun Object3D.updateProperty(source: VisualObject, propertyName: Name) {
|
|||||||
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
|
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
|
||||||
this.material = getMaterial(source)
|
this.material = getMaterial(source)
|
||||||
} else if (
|
} else if (
|
||||||
propertyName.startsWith(VisualObject3D.position)
|
propertyName.startsWith(VisualObject3D.POSITION_KEY)
|
||||||
|| propertyName.startsWith(VisualObject3D.rotation)
|
|| propertyName.startsWith(VisualObject3D.ROTATION)
|
||||||
|| propertyName.startsWith(VisualObject3D.scale)
|
|| propertyName.startsWith(VisualObject3D.SCALE_KEY)
|
||||||
) {
|
) {
|
||||||
//update position of mesh using this object
|
//update position of mesh using this object
|
||||||
updatePosition(source)
|
updatePosition(source)
|
||||||
|
@ -57,9 +57,9 @@ class ThreePlugin : AbstractPlugin() {
|
|||||||
|
|
||||||
obj.onPropertyChange(this) { name, _, _ ->
|
obj.onPropertyChange(this) { name, _, _ ->
|
||||||
if (
|
if (
|
||||||
name.startsWith(VisualObject3D.position) ||
|
name.startsWith(VisualObject3D.POSITION_KEY) ||
|
||||||
name.startsWith(VisualObject3D.rotation) ||
|
name.startsWith(VisualObject3D.ROTATION) ||
|
||||||
name.startsWith(VisualObject3D.scale)
|
name.startsWith(VisualObject3D.SCALE_KEY)
|
||||||
) {
|
) {
|
||||||
//update position of mesh using this object
|
//update position of mesh using this object
|
||||||
updatePosition(obj)
|
updatePosition(obj)
|
||||||
|
@ -19,12 +19,8 @@ import javafx.scene.transform.Rotate
|
|||||||
import org.fxyz3d.shapes.composites.PolyLine3D
|
import org.fxyz3d.shapes.composites.PolyLine3D
|
||||||
import org.fxyz3d.shapes.primitives.CuboidMesh
|
import org.fxyz3d.shapes.primitives.CuboidMesh
|
||||||
import org.fxyz3d.shapes.primitives.SpheroidMesh
|
import org.fxyz3d.shapes.primitives.SpheroidMesh
|
||||||
import kotlin.collections.HashMap
|
|
||||||
import kotlin.collections.component1
|
import kotlin.collections.component1
|
||||||
import kotlin.collections.component2
|
import kotlin.collections.component2
|
||||||
import kotlin.collections.find
|
|
||||||
import kotlin.collections.map
|
|
||||||
import kotlin.collections.mapNotNull
|
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
@ -91,23 +87,23 @@ class FX3DPlugin : AbstractPlugin() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.apply {
|
}.apply {
|
||||||
translateXProperty().bind(binding[VisualObject3D.xPos].float(obj.x.toFloat()))
|
translateXProperty().bind(binding[VisualObject3D.X_POSITION_KEY].float(obj.x.toFloat()))
|
||||||
translateYProperty().bind(binding[VisualObject3D.yPos].float(obj.y.toFloat()))
|
translateYProperty().bind(binding[VisualObject3D.Y_POSITION_KEY].float(obj.y.toFloat()))
|
||||||
translateZProperty().bind(binding[VisualObject3D.zPos].float(obj.z.toFloat()))
|
translateZProperty().bind(binding[VisualObject3D.Z_POSITION_KEY].float(obj.z.toFloat()))
|
||||||
scaleXProperty().bind(binding[VisualObject3D.xScale].float(obj.scaleX.toFloat()))
|
scaleXProperty().bind(binding[VisualObject3D.X_SCALE_KEY].float(obj.scaleX.toFloat()))
|
||||||
scaleYProperty().bind(binding[VisualObject3D.yScale].float(obj.scaleY.toFloat()))
|
scaleYProperty().bind(binding[VisualObject3D.Y_SCALE_KEY].float(obj.scaleY.toFloat()))
|
||||||
scaleZProperty().bind(binding[VisualObject3D.zScale].float(obj.scaleZ.toFloat()))
|
scaleZProperty().bind(binding[VisualObject3D.Z_SCALE_KEY].float(obj.scaleZ.toFloat()))
|
||||||
|
|
||||||
val rotateX = Rotate(0.0, Rotate.X_AXIS).apply {
|
val rotateX = Rotate(0.0, Rotate.X_AXIS).apply {
|
||||||
angleProperty().bind(binding[VisualObject3D.xRotation].float(obj.rotationX.toFloat()).multiply(180.0 / PI))
|
angleProperty().bind(binding[VisualObject3D.X_ROTATION_KEY].float(obj.rotationX.toFloat()).multiply(180.0 / PI))
|
||||||
}
|
}
|
||||||
|
|
||||||
val rotateY = Rotate(0.0, Rotate.Y_AXIS).apply {
|
val rotateY = Rotate(0.0, Rotate.Y_AXIS).apply {
|
||||||
angleProperty().bind(binding[VisualObject3D.yRotation].float(obj.rotationY.toFloat()).multiply(180.0 / PI))
|
angleProperty().bind(binding[VisualObject3D.Y_ROTATION_KEY].float(obj.rotationY.toFloat()).multiply(180.0 / PI))
|
||||||
}
|
}
|
||||||
|
|
||||||
val rotateZ = Rotate(0.0, Rotate.Z_AXIS).apply {
|
val rotateZ = Rotate(0.0, Rotate.Z_AXIS).apply {
|
||||||
angleProperty().bind(binding[VisualObject3D.zRotation].float(obj.rotationZ.toFloat()).multiply(180.0 / PI))
|
angleProperty().bind(binding[VisualObject3D.Z_ROTATION_KEY].float(obj.rotationZ.toFloat()).multiply(180.0 / PI))
|
||||||
}
|
}
|
||||||
|
|
||||||
when (obj.rotationOrder) {
|
when (obj.rotationOrder) {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import scientifik.*
|
import scientifik.DependencyConfiguration
|
||||||
|
import scientifik.FXModule
|
||||||
|
import scientifik.useFx
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("scientifik.mpp")
|
||||||
@ -16,11 +18,6 @@ kotlin {
|
|||||||
|
|
||||||
js {
|
js {
|
||||||
useCommonJs()
|
useCommonJs()
|
||||||
browser {
|
|
||||||
webpackTask {
|
|
||||||
//sourceMaps = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
@ -7,6 +7,7 @@ import hep.dataforge.vis.VisualGroup
|
|||||||
import hep.dataforge.vis.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.bootstrap.*
|
import hep.dataforge.vis.bootstrap.*
|
||||||
import hep.dataforge.vis.react.component
|
import hep.dataforge.vis.react.component
|
||||||
|
import hep.dataforge.vis.react.configEditor
|
||||||
import hep.dataforge.vis.react.flexColumn
|
import hep.dataforge.vis.react.flexColumn
|
||||||
import hep.dataforge.vis.react.state
|
import hep.dataforge.vis.react.state
|
||||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||||
@ -80,7 +81,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
|
|||||||
classes.add("p-1")
|
classes.add("p-1")
|
||||||
overflow = Overflow.auto
|
overflow = Overflow.auto
|
||||||
}
|
}
|
||||||
gridColumn(3) {
|
gridColumn(3, maxSize= GridMaxSize.XL, classes = "order-2 order-xl-1") {
|
||||||
card("Load data") {
|
card("Load data") {
|
||||||
fileDrop("(drag file here)") { files ->
|
fileDrop("(drag file here)") { files ->
|
||||||
val file = files?.get(0)
|
val file = files?.get(0)
|
||||||
@ -104,7 +105,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gridColumn(6) {
|
gridColumn(6, maxSize= GridMaxSize.XL, classes = "order-1 order-xl-2") {
|
||||||
//canvas
|
//canvas
|
||||||
(visual as? VisualObject3D)?.let { visual3D ->
|
(visual as? VisualObject3D)?.let { visual3D ->
|
||||||
child(ThreeCanvasComponent::class) {
|
child(ThreeCanvasComponent::class) {
|
||||||
@ -120,7 +121,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gridColumn(3) {
|
gridColumn(3, maxSize= GridMaxSize.XL, classes = "order-3") {
|
||||||
container {
|
container {
|
||||||
//settings
|
//settings
|
||||||
canvas?.let {
|
canvas?.let {
|
||||||
|
@ -7,8 +7,10 @@ import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
|
|||||||
import hep.dataforge.vis.spatial.gdml.GDMLTransformer
|
import hep.dataforge.vis.spatial.gdml.GDMLTransformer
|
||||||
import hep.dataforge.vis.spatial.gdml.LUnit
|
import hep.dataforge.vis.spatial.gdml.LUnit
|
||||||
import hep.dataforge.vis.spatial.gdml.toVisual
|
import hep.dataforge.vis.spatial.gdml.toVisual
|
||||||
|
import kotlinx.css.*
|
||||||
import react.child
|
import react.child
|
||||||
import react.dom.render
|
import react.dom.render
|
||||||
|
import styled.injectGlobal
|
||||||
import kotlin.browser.document
|
import kotlin.browser.document
|
||||||
|
|
||||||
|
|
||||||
@ -42,6 +44,15 @@ private class GDMLDemoApp : Application {
|
|||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(state: Map<String, Any>) {
|
||||||
|
|
||||||
|
injectGlobal {
|
||||||
|
body {
|
||||||
|
height = 100.pct
|
||||||
|
width = 100.pct
|
||||||
|
margin(0.px)
|
||||||
|
padding(0.px)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val context = Global.context("demo") {}
|
val context = Global.context("demo") {}
|
||||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@ import hep.dataforge.names.NameToken
|
|||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.names.isEmpty
|
||||||
import hep.dataforge.vis.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.bootstrap.card
|
import hep.dataforge.vis.bootstrap.card
|
||||||
import hep.dataforge.vis.bootstrap.configEditor
|
|
||||||
import hep.dataforge.vis.bootstrap.objectTree
|
import hep.dataforge.vis.bootstrap.objectTree
|
||||||
import hep.dataforge.vis.react.component
|
import hep.dataforge.vis.react.component
|
||||||
|
import hep.dataforge.vis.react.configEditor
|
||||||
import hep.dataforge.vis.react.state
|
import hep.dataforge.vis.react.state
|
||||||
import hep.dataforge.vis.spatial.specifications.Camera
|
import hep.dataforge.vis.spatial.specifications.Camera
|
||||||
import hep.dataforge.vis.spatial.specifications.Canvas
|
import hep.dataforge.vis.spatial.specifications.Canvas
|
||||||
|
@ -11,6 +11,5 @@ kotlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
api(project(":dataforge-vis-common"))
|
|
||||||
api(project(":ui:react"))
|
api(project(":ui:react"))
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import hep.dataforge.meta.descriptors.NodeDescriptor
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.names.isEmpty
|
||||||
import hep.dataforge.vis.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
|
import hep.dataforge.vis.react.configEditor
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
import react.dom.li
|
import react.dom.li
|
||||||
|
@ -11,12 +11,11 @@ kotlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
api(project(":dataforge-vis-common"))
|
|
||||||
api(project(":ui:react"))
|
api(project(":ui:react"))
|
||||||
|
|
||||||
api("subroh0508.net.kotlinmaterialui:core:0.3.16")
|
api("subroh0508.net.kotlinmaterialui:core:0.4.0")
|
||||||
api("subroh0508.net.kotlinmaterialui:lab:0.3.16")
|
api("subroh0508.net.kotlinmaterialui:lab:0.4.0")
|
||||||
api(npm("@material-ui/core","4.9.13"))
|
api(npm("@material-ui/core","4.9.14"))
|
||||||
api(npm("@material-ui/lab","4.0.0-alpha.52"))
|
api(npm("@material-ui/lab","4.0.0-alpha.51"))
|
||||||
//api(npm("@material-ui/icons","4.9.1"))
|
//api(npm("@material-ui/icons","4.9.1"))
|
||||||
}
|
}
|
@ -1,193 +0,0 @@
|
|||||||
package hep.dataforge.vis.material
|
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
|
||||||
import hep.dataforge.meta.descriptors.*
|
|
||||||
import hep.dataforge.names.Name
|
|
||||||
import hep.dataforge.names.NameToken
|
|
||||||
import hep.dataforge.names.isEmpty
|
|
||||||
import hep.dataforge.names.plus
|
|
||||||
import hep.dataforge.vis.react.component
|
|
||||||
import hep.dataforge.vis.react.state
|
|
||||||
import kotlinx.css.Display
|
|
||||||
import kotlinx.css.display
|
|
||||||
import kotlinx.css.flexGrow
|
|
||||||
import kotlinx.css.flexShrink
|
|
||||||
import kotlinx.html.js.onClickFunction
|
|
||||||
import materialui.components.button.button
|
|
||||||
import materialui.components.grid.enums.GridAlignItems
|
|
||||||
import materialui.components.grid.enums.GridJustify
|
|
||||||
import materialui.components.grid.grid
|
|
||||||
import materialui.components.typography.typographyH6
|
|
||||||
import materialui.lab.components.treeItem.treeItem
|
|
||||||
import materialui.lab.components.treeView.treeView
|
|
||||||
import org.w3c.dom.Element
|
|
||||||
import org.w3c.dom.events.Event
|
|
||||||
import react.*
|
|
||||||
import react.dom.render
|
|
||||||
import react.dom.span
|
|
||||||
import styled.css
|
|
||||||
import styled.styledDiv
|
|
||||||
|
|
||||||
interface ConfigEditorProps : RProps {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Root config object - always non null
|
|
||||||
*/
|
|
||||||
var root: Config
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Full path to the displayed node in [root]. Could be empty
|
|
||||||
*/
|
|
||||||
var name: Name
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Root default
|
|
||||||
*/
|
|
||||||
var default: Meta?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Root descriptor
|
|
||||||
*/
|
|
||||||
var descriptor: NodeDescriptor?
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun RBuilder.configEditorItem(
|
|
||||||
root: Config,
|
|
||||||
name: Name,
|
|
||||||
descriptor: NodeDescriptor?,
|
|
||||||
default: Meta?
|
|
||||||
) {
|
|
||||||
val item = root[name]
|
|
||||||
val descriptorItem: ItemDescriptor? = descriptor?.get(name)
|
|
||||||
val defaultItem = default?.get(name)
|
|
||||||
val actualItem: MetaItem<Meta>? = item ?: defaultItem ?: descriptorItem?.defaultItem()
|
|
||||||
|
|
||||||
val token = name.last()?.toString() ?: "Properties"
|
|
||||||
|
|
||||||
val removeClick: (Event) -> Unit = {
|
|
||||||
root.remove(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
treeItem {
|
|
||||||
attrs {
|
|
||||||
nodeId = name.toString()
|
|
||||||
label {
|
|
||||||
row {
|
|
||||||
attrs {
|
|
||||||
alignItems = GridAlignItems.stretch
|
|
||||||
justify = GridJustify.spaceBetween
|
|
||||||
spacing(1)
|
|
||||||
}
|
|
||||||
grid {
|
|
||||||
typographyH6 {
|
|
||||||
+token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (actualItem is MetaItem.ValueItem) {
|
|
||||||
styledDiv {
|
|
||||||
css {
|
|
||||||
display = Display.flex
|
|
||||||
flexGrow = 1.0
|
|
||||||
}
|
|
||||||
valueChooser(root, name, actualItem.value, descriptorItem as? ValueDescriptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!name.isEmpty()) {
|
|
||||||
styledDiv {
|
|
||||||
css {
|
|
||||||
display = Display.flex
|
|
||||||
flexShrink = 1.0
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
+"\u00D7"
|
|
||||||
attrs {
|
|
||||||
if (item == null) {
|
|
||||||
disabled = true
|
|
||||||
} else {
|
|
||||||
onClickFunction = removeClick
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (actualItem is MetaItem.NodeItem) {
|
|
||||||
val keys = buildSet<NameToken> {
|
|
||||||
(descriptorItem as? NodeDescriptor)?.items?.keys?.forEach {
|
|
||||||
add(NameToken(it))
|
|
||||||
}
|
|
||||||
item?.node?.items?.keys?.let { addAll(it) }
|
|
||||||
defaultItem?.node?.items?.keys?.let { addAll(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
keys.forEach { token ->
|
|
||||||
configEditorItem(root, name + token, descriptor, default)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val ConfigEditor: FunctionalComponent<ConfigEditorProps> = component { props ->
|
|
||||||
var kostyl by state { false }
|
|
||||||
|
|
||||||
fun update() {
|
|
||||||
kostyl = !kostyl
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffectWithCleanup(listOf(props.root)) {
|
|
||||||
props.root.onChange(this) { name, _, _ ->
|
|
||||||
if (name == props.name) {
|
|
||||||
update()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return@useEffectWithCleanup { props.root.removeListener(this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
treeView {
|
|
||||||
attrs {
|
|
||||||
defaultCollapseIcon {
|
|
||||||
span {
|
|
||||||
+"-"
|
|
||||||
}
|
|
||||||
//child(ExpandMoreIcon::class) {}
|
|
||||||
}//{<ExpandMoreIcon />}
|
|
||||||
defaultExpandIcon {
|
|
||||||
span {
|
|
||||||
+"+"
|
|
||||||
}
|
|
||||||
//child(ChevronRightIcon::class) {}
|
|
||||||
}//{<ChevronRightIcon />}
|
|
||||||
set("disableSelection", true)
|
|
||||||
}
|
|
||||||
configEditorItem(props.root, props.name, props.descriptor, props.default)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun RBuilder.configEditor(
|
|
||||||
config: Config,
|
|
||||||
name: Name = Name.EMPTY,
|
|
||||||
descriptor: NodeDescriptor? = null,
|
|
||||||
default: Meta? = null
|
|
||||||
) {
|
|
||||||
child(ConfigEditor) {
|
|
||||||
attrs {
|
|
||||||
this.root = config
|
|
||||||
this.name = name
|
|
||||||
this.descriptor = descriptor
|
|
||||||
this.default = default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Element.configEditor(config: Config, descriptor: NodeDescriptor? = null, default: Meta? = null) {
|
|
||||||
render(this) {
|
|
||||||
configEditor(config, Name.EMPTY, descriptor, default)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun RBuilder.configEditor(obj: Configurable, descriptor: NodeDescriptor? = obj.descriptor, default: Meta? = null) {
|
|
||||||
configEditor(obj.config, Name.EMPTY, descriptor ?: obj.descriptor, default)
|
|
||||||
}
|
|
@ -8,7 +8,9 @@ import hep.dataforge.vis.VisualObject
|
|||||||
import hep.dataforge.vis.isEmpty
|
import hep.dataforge.vis.isEmpty
|
||||||
import hep.dataforge.vis.react.component
|
import hep.dataforge.vis.react.component
|
||||||
import hep.dataforge.vis.react.state
|
import hep.dataforge.vis.react.state
|
||||||
|
import kotlinx.html.UL
|
||||||
import materialui.lab.components.treeItem.treeItem
|
import materialui.lab.components.treeItem.treeItem
|
||||||
|
import materialui.lab.components.treeView.SingleSelectTreeViewElementBuilder
|
||||||
import materialui.lab.components.treeView.treeView
|
import materialui.lab.components.treeView.treeView
|
||||||
import react.FunctionalComponent
|
import react.FunctionalComponent
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
@ -49,11 +51,11 @@ private fun RBuilder.treeBranch(name: Name, obj: VisualObject): Unit {
|
|||||||
val ObjectTree: FunctionalComponent<ObjectTreeProps> = component { props ->
|
val ObjectTree: FunctionalComponent<ObjectTreeProps> = component { props ->
|
||||||
var selected: String? by state { props.selected.toString() }
|
var selected: String? by state { props.selected.toString() }
|
||||||
treeView {
|
treeView {
|
||||||
|
this as SingleSelectTreeViewElementBuilder<UL>
|
||||||
attrs {
|
attrs {
|
||||||
this.selected = selected
|
this.selected = selected
|
||||||
this.onNodeSelect = { _, selectedItem ->
|
this.onNodeSelect{ _, selectedItem ->
|
||||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
selected = selectedItem
|
||||||
selected = (selectedItem as? String)
|
|
||||||
val itemName = selected?.toName()
|
val itemName = selected?.toName()
|
||||||
props.clickCallback(itemName)
|
props.clickCallback(itemName)
|
||||||
Unit
|
Unit
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
package hep.dataforge.vis.material
|
|
||||||
|
|
||||||
import hep.dataforge.meta.Config
|
|
||||||
import hep.dataforge.meta.descriptors.ValueDescriptor
|
|
||||||
import hep.dataforge.meta.get
|
|
||||||
import hep.dataforge.meta.number
|
|
||||||
import hep.dataforge.meta.setValue
|
|
||||||
import hep.dataforge.names.Name
|
|
||||||
import hep.dataforge.values.*
|
|
||||||
import hep.dataforge.vis.widgetType
|
|
||||||
import kotlinx.html.InputType
|
|
||||||
import kotlinx.html.js.onChangeFunction
|
|
||||||
import kotlinx.html.js.onKeyDownFunction
|
|
||||||
import materialui.components.input.input
|
|
||||||
import materialui.components.select.select
|
|
||||||
import materialui.components.slider.slider
|
|
||||||
import materialui.components.switches.switch
|
|
||||||
import materialui.components.textfield.textField
|
|
||||||
import org.w3c.dom.HTMLInputElement
|
|
||||||
import org.w3c.dom.HTMLSelectElement
|
|
||||||
import org.w3c.dom.events.Event
|
|
||||||
import org.w3c.dom.events.KeyboardEvent
|
|
||||||
import react.RBuilder
|
|
||||||
import react.dom.option
|
|
||||||
|
|
||||||
internal fun RBuilder.valueChooser(root: Config, name: Name, value: Value, descriptor: ValueDescriptor?) {
|
|
||||||
val onValueChange: (Event) -> Unit = { event ->
|
|
||||||
if (event !is KeyboardEvent || event.key == "Enter") {
|
|
||||||
val res = when (val t = event.target) {
|
|
||||||
// (it.target as HTMLInputElement).value
|
|
||||||
is HTMLInputElement -> if (t.type == "checkbox") {
|
|
||||||
if (t.checked) True else False
|
|
||||||
} else {
|
|
||||||
t.value.asValue()
|
|
||||||
}
|
|
||||||
is HTMLSelectElement -> t.value.asValue()
|
|
||||||
else -> error("Unknown event target: $t")
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
root.setValue(name, res)
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
console.error("Can't set config property ${name} to $res")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val type = descriptor?.type?.firstOrNull()
|
|
||||||
when {
|
|
||||||
descriptor?.widgetType == "slider" -> slider {
|
|
||||||
attrs {
|
|
||||||
descriptor.attributes["step"].number?.let {
|
|
||||||
step = it
|
|
||||||
}
|
|
||||||
descriptor.attributes["min"].number?.let {
|
|
||||||
min = it
|
|
||||||
}
|
|
||||||
descriptor.attributes["max"].number?.let {
|
|
||||||
max = it
|
|
||||||
}
|
|
||||||
this.defaultValue = value.number
|
|
||||||
onChangeFunction = onValueChange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
descriptor?.widgetType == "color" -> input {
|
|
||||||
attrs {
|
|
||||||
fullWidth = true
|
|
||||||
this.type = InputType.color
|
|
||||||
this.value = value.string
|
|
||||||
onChangeFunction = onValueChange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type == ValueType.BOOLEAN -> switch {
|
|
||||||
attrs {
|
|
||||||
defaultChecked = value.boolean
|
|
||||||
onChangeFunction = onValueChange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type == ValueType.NUMBER -> textField {
|
|
||||||
attrs {
|
|
||||||
fullWidth = true
|
|
||||||
this.type = InputType.number
|
|
||||||
defaultValue = value.string
|
|
||||||
onChangeFunction = onValueChange
|
|
||||||
//onKeyDownFunction = onValueChange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
descriptor?.allowedValues?.isNotEmpty() ?: false -> select {
|
|
||||||
descriptor!!.allowedValues.forEach {
|
|
||||||
option {
|
|
||||||
+it.string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attrs {
|
|
||||||
fullWidth = true
|
|
||||||
multiple = false
|
|
||||||
onChangeFunction = onValueChange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> textField {
|
|
||||||
attrs {
|
|
||||||
this.type = InputType.text
|
|
||||||
fullWidth = true
|
|
||||||
this.defaultValue = value.string
|
|
||||||
//onFocusOutFunction = onValueChange
|
|
||||||
onKeyDownFunction = onValueChange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -10,21 +10,12 @@ kotlin {
|
|||||||
|
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
|
api(project(":dataforge-vis-common"))
|
||||||
|
|
||||||
api("org.jetbrains:kotlin-react:16.13.1-pre.104-kotlin-1.3.72")
|
//api("org.jetbrains:kotlin-react:16.13.1-pre.104-kotlin-1.3.72")
|
||||||
api("org.jetbrains:kotlin-react-dom:16.13.1-pre.104-kotlin-1.3.72")
|
api("org.jetbrains:kotlin-react-dom:16.13.1-pre.104-kotlin-1.3.72")
|
||||||
api("org.jetbrains.kotlinx:kotlinx-html:0.6.12")
|
|
||||||
|
|
||||||
api("org.jetbrains:kotlin-extensions:1.0.1-pre.104-kotlin-1.3.72")
|
|
||||||
api("org.jetbrains:kotlin-css-js:1.0.0-pre.94-kotlin-1.3.70")
|
|
||||||
api("org.jetbrains:kotlin-styled:1.0.0-pre.104-kotlin-1.3.72")
|
|
||||||
|
|
||||||
api(npm("core-js", "2.6.5"))
|
|
||||||
|
|
||||||
api(npm("react", "16.13.1"))
|
api(npm("react", "16.13.1"))
|
||||||
api(npm("react-dom", "16.13.1"))
|
api(npm("react-dom", "16.13.1"))
|
||||||
|
api(npm("react-is", "16.13.1"))
|
||||||
api(npm("react-is", "16.13.0"))
|
|
||||||
api(npm("inline-style-prefixer", "5.1.0"))
|
|
||||||
api(npm("styled-components", "4.3.2"))
|
|
||||||
}
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package hep.dataforge.vis.react
|
||||||
|
|
||||||
|
import kotlinx.css.*
|
||||||
|
import kotlinx.css.properties.deg
|
||||||
|
import kotlinx.css.properties.rotate
|
||||||
|
import styled.StyleSheet
|
||||||
|
|
||||||
|
object TreeStyles : StyleSheet("treeStyles", true) {
|
||||||
|
/**
|
||||||
|
* Remove default bullets
|
||||||
|
*/
|
||||||
|
val tree by css {
|
||||||
|
paddingLeft = 8.px
|
||||||
|
marginLeft = 0.px
|
||||||
|
listStyleType = ListStyleType.none
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Style the caret/arrow
|
||||||
|
*/
|
||||||
|
val treeCaret by css {
|
||||||
|
cursor = Cursor.pointer
|
||||||
|
userSelect = UserSelect.none
|
||||||
|
/* Create the caret/arrow with a unicode, and style it */
|
||||||
|
before {
|
||||||
|
content = "\u25B6".quoted
|
||||||
|
color = Color.black
|
||||||
|
display = Display.inlineBlock
|
||||||
|
marginRight = 6.px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val treeItem by css {
|
||||||
|
alignItems = Align.center
|
||||||
|
paddingLeft = 10.px
|
||||||
|
borderLeftStyle = BorderStyle.dashed
|
||||||
|
borderLeftWidth = 1.px
|
||||||
|
borderLeftColor = Color.lightGray
|
||||||
|
}
|
||||||
|
|
||||||
|
val treeLeaf by css {
|
||||||
|
display = Display.flex
|
||||||
|
flexDirection = FlexDirection.row
|
||||||
|
userSelect = UserSelect.none
|
||||||
|
alignItems = Align.center
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate the caret/arrow icon when clicked on (using JavaScript)
|
||||||
|
*/
|
||||||
|
val treeCaredDown by css {
|
||||||
|
before {
|
||||||
|
content = "\u25B6".quoted
|
||||||
|
color = Color.black
|
||||||
|
display = Display.inlineBlock
|
||||||
|
marginRight = 6.px
|
||||||
|
transform.rotate(90.deg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val treeLabel by css {
|
||||||
|
overflow = Overflow.hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
val treeLabelInactive by css {
|
||||||
|
color = Color.lightGray
|
||||||
|
}
|
||||||
|
|
||||||
|
val treeLabelSelected by css {
|
||||||
|
backgroundColor = Color.lightBlue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis.bootstrap
|
package hep.dataforge.vis.react
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.*
|
import hep.dataforge.meta.descriptors.*
|
||||||
@ -6,19 +6,15 @@ import hep.dataforge.names.Name
|
|||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
import hep.dataforge.vis.react.RFBuilder
|
|
||||||
import hep.dataforge.vis.react.component
|
|
||||||
import hep.dataforge.vis.react.flexRow
|
|
||||||
import hep.dataforge.vis.react.state
|
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import kotlinx.html.classes
|
import kotlinx.css.properties.TextDecoration
|
||||||
import kotlinx.html.js.onClickFunction
|
import kotlinx.html.js.onClickFunction
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.events.Event
|
import org.w3c.dom.events.Event
|
||||||
import react.*
|
import react.*
|
||||||
import react.dom.*
|
import react.dom.div
|
||||||
import styled.css
|
import react.dom.render
|
||||||
import styled.styledDiv
|
import styled.*
|
||||||
|
|
||||||
interface ConfigEditorItemProps : RProps {
|
interface ConfigEditorItemProps : RProps {
|
||||||
|
|
||||||
@ -91,25 +87,32 @@ private fun RFBuilder.configEditorItem(props: ConfigEditorItemProps) {
|
|||||||
when (actualItem) {
|
when (actualItem) {
|
||||||
is MetaItem.NodeItem -> {
|
is MetaItem.NodeItem -> {
|
||||||
div {
|
div {
|
||||||
span("tree-caret") {
|
styledSpan {
|
||||||
attrs {
|
css {
|
||||||
|
+TreeStyles.treeCaret
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
classes += "tree-caret-down"
|
+TreeStyles.treeCaredDown
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
attrs {
|
||||||
onClickFunction = expanderClick
|
onClickFunction = expanderClick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span("tree-label") {
|
styledSpan {
|
||||||
+token
|
css {
|
||||||
attrs {
|
+TreeStyles.treeLabel
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
classes += "tree-label-inactive"
|
+TreeStyles.treeLabelInactive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
+token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
ul("tree") {
|
styledUl {
|
||||||
|
css {
|
||||||
|
+TreeStyles.tree
|
||||||
|
}
|
||||||
val keys = buildSet<NameToken> {
|
val keys = buildSet<NameToken> {
|
||||||
(descriptorItem as? NodeDescriptor)?.items?.keys?.forEach {
|
(descriptorItem as? NodeDescriptor)?.items?.keys?.forEach {
|
||||||
add(NameToken(it))
|
add(NameToken(it))
|
||||||
@ -119,7 +122,10 @@ private fun RFBuilder.configEditorItem(props: ConfigEditorItemProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keys.forEach { token ->
|
keys.forEach { token ->
|
||||||
li("tree-item align-middle") {
|
styledLi {
|
||||||
|
css {
|
||||||
|
+TreeStyles.treeItem
|
||||||
|
}
|
||||||
child(ConfigEditorItem) {
|
child(ConfigEditorItem) {
|
||||||
attrs {
|
attrs {
|
||||||
this.key = props.name.toString()
|
this.key = props.name.toString()
|
||||||
@ -136,22 +142,23 @@ private fun RFBuilder.configEditorItem(props: ConfigEditorItemProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is MetaItem.ValueItem -> {
|
is MetaItem.ValueItem -> {
|
||||||
flexRow {
|
styledDiv {
|
||||||
css {
|
css {
|
||||||
alignItems = Align.center
|
+TreeStyles.treeLeaf
|
||||||
justifyContent= JustifyContent.flexEnd
|
justifyContent = JustifyContent.flexEnd
|
||||||
}
|
}
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css{
|
css {
|
||||||
flexGrow = 1.0
|
flexGrow = 1.0
|
||||||
}
|
}
|
||||||
span("tree-label align-self-center") {
|
styledSpan {
|
||||||
+token
|
css {
|
||||||
attrs {
|
+TreeStyles.treeLabel
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
classes += "tree-label-inactive"
|
+TreeStyles.treeLabelInactive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
+token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
styledDiv {
|
styledDiv {
|
||||||
@ -166,7 +173,23 @@ private fun RFBuilder.configEditorItem(props: ConfigEditorItemProps) {
|
|||||||
css {
|
css {
|
||||||
flexShrink = 1.0
|
flexShrink = 1.0
|
||||||
}
|
}
|
||||||
button(classes = "btn btn-link align-self-center") {
|
styledButton {
|
||||||
|
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
|
||||||
|
cursor = Cursor.pointer
|
||||||
|
disabled {
|
||||||
|
cursor = Cursor.auto
|
||||||
|
borderStyle = BorderStyle.dashed
|
||||||
|
color = Color.lightGray
|
||||||
|
}
|
||||||
|
}
|
||||||
+"\u00D7"
|
+"\u00D7"
|
||||||
attrs {
|
attrs {
|
||||||
if (item == null) {
|
if (item == null) {
|
@ -0,0 +1,9 @@
|
|||||||
|
package hep.dataforge.vis.react
|
||||||
|
|
||||||
|
import styled.StyleSheet
|
||||||
|
|
||||||
|
|
||||||
|
class MainStyle: StyleSheet("main", true){
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis.bootstrap
|
package hep.dataforge.vis.react
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.ValueDescriptor
|
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||||
@ -6,6 +6,8 @@ import hep.dataforge.names.Name
|
|||||||
import hep.dataforge.values.*
|
import hep.dataforge.values.*
|
||||||
import hep.dataforge.vis.Colors
|
import hep.dataforge.vis.Colors
|
||||||
import hep.dataforge.vis.widgetType
|
import hep.dataforge.vis.widgetType
|
||||||
|
import kotlinx.css.Align
|
||||||
|
import kotlinx.css.alignSelf
|
||||||
import kotlinx.html.InputType
|
import kotlinx.html.InputType
|
||||||
import kotlinx.html.js.onChangeFunction
|
import kotlinx.html.js.onChangeFunction
|
||||||
import kotlinx.html.js.onKeyDownFunction
|
import kotlinx.html.js.onKeyDownFunction
|
||||||
@ -14,7 +16,12 @@ import org.w3c.dom.HTMLInputElement
|
|||||||
import org.w3c.dom.HTMLSelectElement
|
import org.w3c.dom.HTMLSelectElement
|
||||||
import org.w3c.dom.events.Event
|
import org.w3c.dom.events.Event
|
||||||
import react.*
|
import react.*
|
||||||
import react.dom.*
|
import react.dom.defaultValue
|
||||||
|
import react.dom.input
|
||||||
|
import react.dom.option
|
||||||
|
import react.dom.select
|
||||||
|
import styled.css
|
||||||
|
import styled.styledDiv
|
||||||
|
|
||||||
interface ValueChooserProps : RProps {
|
interface ValueChooserProps : RProps {
|
||||||
var item: MetaItem<*>?
|
var item: MetaItem<*>?
|
||||||
@ -66,9 +73,6 @@ class ValueChooserComponent(props: ValueChooserProps) : RComponent<ValueChooserP
|
|||||||
}
|
}
|
||||||
element.indeterminate = props.item == null
|
element.indeterminate = props.item == null
|
||||||
}
|
}
|
||||||
// (state.element as? HTMLSelectElement)?.let { element ->
|
|
||||||
// state.value?.let { element.value = it.string }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun RBuilder.stringInput() = input(type = InputType.text) {
|
private fun RBuilder.stringInput() = input(type = InputType.text) {
|
||||||
@ -80,7 +84,10 @@ class ValueChooserComponent(props: ValueChooserProps) : RComponent<ValueChooserP
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun RBuilder.render() {
|
override fun RBuilder.render() {
|
||||||
div("align-self-center") {
|
styledDiv {
|
||||||
|
css {
|
||||||
|
alignSelf = Align.center
|
||||||
|
}
|
||||||
val descriptor = props.descriptor
|
val descriptor = props.descriptor
|
||||||
val type = descriptor?.type?.firstOrNull()
|
val type = descriptor?.type?.firstOrNull()
|
||||||
when {
|
when {
|
Loading…
Reference in New Issue
Block a user