New properties #34
@ -2,8 +2,8 @@ plugins {
|
|||||||
id("ru.mipt.npm.project")
|
id("ru.mipt.npm.project")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion by extra("0.2.1-dev-5")
|
val dataforgeVersion by extra("0.3.0-dev")
|
||||||
val ktorVersion by extra("1.4.3")
|
val ktorVersion by extra("1.5.0")
|
||||||
val htmlVersion by extra("0.7.2")
|
val htmlVersion by extra("0.7.2")
|
||||||
val kotlinWrappersVersion by extra("pre.129-kotlin-1.4.20")
|
val kotlinWrappersVersion by extra("pre.129-kotlin-1.4.20")
|
||||||
val fxVersion by extra("14")
|
val fxVersion by extra("14")
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package hep.dataforge.vision.gdml.demo
|
package hep.dataforge.vision.gdml.demo
|
||||||
|
|
||||||
import hep.dataforge.meta.DFExperimental
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.meta.setItem
|
|
||||||
import hep.dataforge.values.asValue
|
import hep.dataforge.values.asValue
|
||||||
import hep.dataforge.vision.gdml.readFile
|
import hep.dataforge.vision.gdml.readFile
|
||||||
import hep.dataforge.vision.gdml.toVision
|
import hep.dataforge.vision.gdml.toVision
|
||||||
|
@ -39,15 +39,18 @@ fun Page<Solid>.showcase() {
|
|||||||
demo("shapes", "Basic shapes") {
|
demo("shapes", "Basic shapes") {
|
||||||
box(100.0, 100.0, 100.0) {
|
box(100.0, 100.0, 100.0) {
|
||||||
z = -110.0
|
z = -110.0
|
||||||
|
color("teal")
|
||||||
}
|
}
|
||||||
sphere(50.0) {
|
sphere(50.0) {
|
||||||
x = 110
|
x = 110
|
||||||
detail = 16
|
detail = 16
|
||||||
|
color("red")
|
||||||
}
|
}
|
||||||
tube(50, height = 10, innerRadius = 25, angle = PI) {
|
tube(50, height = 10, innerRadius = 25, angle = PI) {
|
||||||
y = 110
|
y = 110
|
||||||
detail = 16
|
detail = 16
|
||||||
rotationX = PI / 4
|
rotationX = PI / 4
|
||||||
|
color("blue")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +58,7 @@ fun Page<Solid>.showcase() {
|
|||||||
val group = group {
|
val group = group {
|
||||||
box(100, 100, 100) {
|
box(100, 100, 100) {
|
||||||
z = 110.0
|
z = 110.0
|
||||||
|
opacity = 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
box(100, 100, 100) {
|
box(100, 100, 100) {
|
||||||
@ -155,7 +159,7 @@ fun Page<Solid>.showcaseCSG() {
|
|||||||
detail = 32
|
detail = 32
|
||||||
}
|
}
|
||||||
color(Colors.lightgreen)
|
color(Colors.lightgreen)
|
||||||
opacity = 0.3
|
opacity = 0.5
|
||||||
}
|
}
|
||||||
composite(CompositeType.SUBTRACT) {
|
composite(CompositeType.SUBTRACT) {
|
||||||
y = -300
|
y = -300
|
||||||
@ -173,9 +177,11 @@ fun Page<Solid>.showcaseCSG() {
|
|||||||
demo("CSG.custom", "CSG with manually created object") {
|
demo("CSG.custom", "CSG with manually created object") {
|
||||||
intersect {
|
intersect {
|
||||||
tube(60, 10) {
|
tube(60, 10) {
|
||||||
detail = 64
|
detail = 32
|
||||||
}
|
}
|
||||||
box(100, 100, 100)
|
box(100, 100, 100)
|
||||||
|
color("red")
|
||||||
|
opacity = 0.5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,7 +9,6 @@ import hep.dataforge.vision.set
|
|||||||
import hep.dataforge.vision.setProperty
|
import hep.dataforge.vision.setProperty
|
||||||
import hep.dataforge.vision.solid.*
|
import hep.dataforge.vision.solid.*
|
||||||
import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
|
import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
|
||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
|
||||||
import hep.dataforge.vision.solid.three.*
|
import hep.dataforge.vision.solid.three.*
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.BufferGeometry
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
@ -30,8 +29,6 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
|||||||
scaleX = xSize
|
scaleX = xSize
|
||||||
scaleY = ySize
|
scaleY = ySize
|
||||||
scaleZ = zSize
|
scaleZ = zSize
|
||||||
// getProperty(MeshThreeFactory.EDGES_ENABLED_KEY, inherit = false, includeStyles = false)
|
|
||||||
// getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY, inherit = false, includeStyles = false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun render(three: ThreePlugin): Object3D {
|
override fun render(three: ThreePlugin): Object3D {
|
||||||
@ -69,11 +66,8 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
|||||||
mesh.scale.set(newXSize, newYSize, newZSize)
|
mesh.scale.set(newXSize, newYSize, newZSize)
|
||||||
mesh.updateMatrix()
|
mesh.updateMatrix()
|
||||||
}
|
}
|
||||||
//name.startsWith(MeshThreeFactory.WIREFRAME_KEY) -> mesh.applyWireFrame(this@VariableBox)
|
|
||||||
name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
||||||
name.startsWith(MATERIAL_COLOR_KEY) -> {
|
//name.startsWith(MATERIAL_COLOR_KEY) -> mesh.updateMaterialProperty(this, name)
|
||||||
mesh.updateMaterial(this)
|
|
||||||
}
|
|
||||||
else -> mesh.updateProperty(this@VariableBox, name)
|
else -> mesh.updateProperty(this@VariableBox, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package hep.dataforge.vision.react
|
package hep.dataforge.vision.react
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.NodeItem
|
||||||
|
import hep.dataforge.meta.ValueItem
|
||||||
import hep.dataforge.meta.descriptors.ItemDescriptor
|
import hep.dataforge.meta.descriptors.ItemDescriptor
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.meta.descriptors.defaultItem
|
import hep.dataforge.meta.descriptors.defaultItem
|
||||||
@ -51,7 +52,7 @@ private fun RBuilder.metaViewerItem(props: MetaViewerProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (actualItem) {
|
when (actualItem) {
|
||||||
is MetaItem.NodeItem -> {
|
is NodeItem -> {
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css {
|
css {
|
||||||
+TreeStyles.treeLeaf
|
+TreeStyles.treeLeaf
|
||||||
@ -108,7 +109,7 @@ private fun RBuilder.metaViewerItem(props: MetaViewerProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is MetaItem.ValueItem -> {
|
is ValueItem -> {
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css {
|
css {
|
||||||
+TreeStyles.treeLeaf
|
+TreeStyles.treeLeaf
|
||||||
|
@ -9,6 +9,7 @@ import hep.dataforge.names.plus
|
|||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
import hep.dataforge.vision.hidden
|
import hep.dataforge.vision.hidden
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -65,12 +66,12 @@ private val PropertyEditorItem: FunctionalComponent<PropertyEditorProps> =
|
|||||||
private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
||||||
var expanded: Boolean by useState { true }
|
var expanded: Boolean by useState { true }
|
||||||
val itemName by useState { props.name ?: Name.EMPTY }
|
val itemName by useState { props.name ?: Name.EMPTY }
|
||||||
var item: MetaItem<*>? by useState { props.provider.getItem(itemName) }
|
var item: MetaItem? by useState { props.provider.getItem(itemName) }
|
||||||
val descriptorItem: ItemDescriptor? = props.descriptor?.get(itemName)
|
val descriptorItem: ItemDescriptor? = props.descriptor?.get(itemName)
|
||||||
|
|
||||||
if(descriptorItem?.hidden == true) return //fail fast for hidden property
|
if(descriptorItem?.hidden == true) return //fail fast for hidden property
|
||||||
|
|
||||||
var actualItem: MetaItem<Meta>? by useState {
|
var actualItem: MetaItem? by useState {
|
||||||
item ?: props.defaultProvider?.getItem(itemName) ?: descriptorItem?.defaultItem()
|
item ?: props.defaultProvider?.getItem(itemName) ?: descriptorItem?.defaultItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
|||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actualItem is MetaItem.NodeItem) {
|
if (actualItem is NodeItem) {
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css {
|
css {
|
||||||
+TreeStyles.treeLeaf
|
+TreeStyles.treeLeaf
|
||||||
@ -248,6 +249,7 @@ public fun RBuilder.propertyEditor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
private fun Config.flowUpdates(): Flow<Name> = callbackFlow {
|
private fun Config.flowUpdates(): Flow<Name> = callbackFlow {
|
||||||
onChange(this) { name, _, _ ->
|
onChange(this) { name, _, _ ->
|
||||||
launch {
|
launch {
|
||||||
|
@ -17,7 +17,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
|||||||
/**
|
/**
|
||||||
* Style the caret/arrow
|
* Style the caret/arrow
|
||||||
*/
|
*/
|
||||||
public val treeCaret by css {
|
public val treeCaret: RuleSet by css {
|
||||||
cursor = Cursor.pointer
|
cursor = Cursor.pointer
|
||||||
userSelect = UserSelect.none
|
userSelect = UserSelect.none
|
||||||
/* Create the caret/arrow with a unicode, and style it */
|
/* Create the caret/arrow with a unicode, and style it */
|
||||||
@ -32,7 +32,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
|||||||
/**
|
/**
|
||||||
* Rotate the caret/arrow icon when clicked on (using JavaScript)
|
* Rotate the caret/arrow icon when clicked on (using JavaScript)
|
||||||
*/
|
*/
|
||||||
val treeCaredDown by css {
|
public val treeCaredDown:RuleSet by css {
|
||||||
before {
|
before {
|
||||||
content = "\u25B6".quoted
|
content = "\u25B6".quoted
|
||||||
color = Color.black
|
color = Color.black
|
||||||
@ -42,7 +42,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val treeItem by css {
|
public val treeItem:RuleSet by css {
|
||||||
alignItems = Align.center
|
alignItems = Align.center
|
||||||
paddingLeft = 10.px
|
paddingLeft = 10.px
|
||||||
borderLeftStyle = BorderStyle.dashed
|
borderLeftStyle = BorderStyle.dashed
|
||||||
@ -53,27 +53,27 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
|||||||
borderBottomColor = Color.lightGray
|
borderBottomColor = Color.lightGray
|
||||||
}
|
}
|
||||||
|
|
||||||
val treeLeaf by css {
|
public val treeLeaf:RuleSet by css {
|
||||||
display = Display.flex
|
display = Display.flex
|
||||||
flexDirection = FlexDirection.row
|
flexDirection = FlexDirection.row
|
||||||
flexWrap = FlexWrap.nowrap
|
flexWrap = FlexWrap.nowrap
|
||||||
//alignItems = Align.center
|
//alignItems = Align.center
|
||||||
}
|
}
|
||||||
|
|
||||||
val treeLabel by css {
|
public val treeLabel:RuleSet by css {
|
||||||
overflow = Overflow.hidden
|
overflow = Overflow.hidden
|
||||||
flex(flexGrow = 1.0, flexShrink = 1.0)
|
flex(flexGrow = 1.0, flexShrink = 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
val treeLabelInactive by css {
|
public val treeLabelInactive: RuleSet by css {
|
||||||
color = Color.lightGray
|
color = Color.lightGray
|
||||||
}
|
}
|
||||||
|
|
||||||
val treeLabelSelected by css {
|
public val treeLabelSelected:RuleSet by css {
|
||||||
backgroundColor = Color.lightBlue
|
backgroundColor = Color.lightBlue
|
||||||
}
|
}
|
||||||
|
|
||||||
val linkButton by css {
|
public val linkButton:RuleSet by css {
|
||||||
backgroundColor = Color.white
|
backgroundColor = Color.white
|
||||||
border = "none"
|
border = "none"
|
||||||
padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt)
|
padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt)
|
||||||
@ -86,7 +86,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val removeButton by css {
|
public val removeButton:RuleSet by css {
|
||||||
backgroundColor = Color.white
|
backgroundColor = Color.white
|
||||||
borderStyle = BorderStyle.solid
|
borderStyle = BorderStyle.solid
|
||||||
borderRadius = 2.px
|
borderRadius = 2.px
|
||||||
@ -104,7 +104,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val resizeableInput by css {
|
public val resizeableInput: RuleSet by css {
|
||||||
overflow = Overflow.hidden
|
overflow = Overflow.hidden
|
||||||
maxWidth = 120.pt
|
maxWidth = 120.pt
|
||||||
flex(flexGrow = 2.0, flexShrink = 2.0, flexBasis = 60.pt)
|
flex(flexGrow = 2.0, flexShrink = 2.0, flexBasis = 60.pt)
|
||||||
|
@ -20,7 +20,7 @@ import styled.styledInput
|
|||||||
import styled.styledSelect
|
import styled.styledSelect
|
||||||
|
|
||||||
public external interface ValueChooserProps : RProps {
|
public external interface ValueChooserProps : RProps {
|
||||||
var item: MetaItem<*>?
|
var item: MetaItem?
|
||||||
var descriptor: ValueDescriptor?
|
var descriptor: ValueDescriptor?
|
||||||
var valueChanged: ((Value?) -> Unit)?
|
var valueChanged: ((Value?) -> Unit)?
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ class ValueChooserComponent(props: ValueChooserProps) : RComponent<ValueChooserP
|
|||||||
|
|
||||||
internal fun RBuilder.valueChooser(
|
internal fun RBuilder.valueChooser(
|
||||||
name: Name,
|
name: Name,
|
||||||
item: MetaItem<*>?,
|
item: MetaItem?,
|
||||||
descriptor: ValueDescriptor? = null,
|
descriptor: ValueDescriptor? = null,
|
||||||
callback: (Value?) -> Unit
|
callback: (Value?) -> Unit
|
||||||
) {
|
) {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.get
|
|
||||||
import hep.dataforge.meta.number
|
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.values.int
|
import hep.dataforge.values.int
|
||||||
import hep.dataforge.values.string
|
import hep.dataforge.values.string
|
||||||
@ -192,9 +190,9 @@ public object Colors {
|
|||||||
/**
|
/**
|
||||||
* Convert color represented as Meta to string of format #rrggbb
|
* Convert color represented as Meta to string of format #rrggbb
|
||||||
*/
|
*/
|
||||||
fun fromMeta(item: MetaItem<*>): String {
|
fun fromMeta(item: MetaItem): String {
|
||||||
return when (item) {
|
return when (item) {
|
||||||
is MetaItem.NodeItem<*> -> {
|
is NodeItem -> {
|
||||||
val node = item.node
|
val node = item.node
|
||||||
rgbToString(
|
rgbToString(
|
||||||
node[RED_KEY].number?.toByte()?.toUByte() ?: 0u,
|
node[RED_KEY].number?.toByte()?.toUByte() ?: 0u,
|
||||||
@ -202,7 +200,7 @@ public object Colors {
|
|||||||
node[BLUE_KEY].number?.toByte()?.toUByte() ?: 0u
|
node[BLUE_KEY].number?.toByte()?.toUByte() ?: 0u
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is MetaItem.ValueItem -> {
|
is ValueItem -> {
|
||||||
if (item.value.type == ValueType.NUMBER) {
|
if (item.value.type == ValueType.NUMBER) {
|
||||||
rgbToString(item.value.int)
|
rgbToString(item.value.int)
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,7 +40,7 @@ public inline class StyleSheet(private val owner: VisionGroup) {
|
|||||||
* Create and set a style
|
* Create and set a style
|
||||||
*/
|
*/
|
||||||
public operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
|
public operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
|
||||||
val newStyle = get(key)?.edit(builder) ?: Meta(builder)
|
val newStyle = get(key)?.builder()?.apply(builder) ?: Meta(builder)
|
||||||
set(key, newStyle.seal())
|
set(key, newStyle.seal())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ public tailrec fun Vision.getStyle(name: String): Meta? =
|
|||||||
/**
|
/**
|
||||||
* Resolve an item in all style layers
|
* Resolve an item in all style layers
|
||||||
*/
|
*/
|
||||||
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem<*>> {
|
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem> {
|
||||||
return styles.asSequence().map {
|
return styles.asSequence().map {
|
||||||
getStyle(it)
|
getStyle(it)
|
||||||
}.map {
|
}.map {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.MetaItem
|
||||||
import hep.dataforge.meta.MutableItemProvider
|
import hep.dataforge.meta.MutableItemProvider
|
||||||
import hep.dataforge.meta.descriptors.Described
|
import hep.dataforge.meta.descriptors.Described
|
||||||
@ -28,6 +29,12 @@ public interface Vision : Described {
|
|||||||
@Transient
|
@Transient
|
||||||
public var parent: VisionGroup?
|
public var parent: VisionGroup?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Properties belonging to this [Vision] potentially including artificial properties
|
||||||
|
*/
|
||||||
|
@Transient
|
||||||
|
public val meta: Meta
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A coroutine scope for asynchronous calls and locks
|
* A coroutine scope for asynchronous calls and locks
|
||||||
*/
|
*/
|
||||||
@ -37,7 +44,7 @@ public interface Vision : Described {
|
|||||||
* A fast accessor method to get own property (no inheritance or styles).
|
* A fast accessor method to get own property (no inheritance or styles).
|
||||||
* Should be equivalent to `getProperty(name,false,false,false)`.
|
* Should be equivalent to `getProperty(name,false,false,false)`.
|
||||||
*/
|
*/
|
||||||
public fun getOwnProperty(name: Name): MetaItem<*>?
|
public fun getOwnProperty(name: Name): MetaItem?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get property.
|
* Get property.
|
||||||
@ -49,13 +56,13 @@ public interface Vision : Described {
|
|||||||
inherit: Boolean = false,
|
inherit: Boolean = false,
|
||||||
includeStyles: Boolean = true,
|
includeStyles: Boolean = true,
|
||||||
includeDefaults: Boolean = true,
|
includeDefaults: Boolean = true,
|
||||||
): MetaItem<*>?
|
): MetaItem?
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the property value
|
* Set the property value
|
||||||
*/
|
*/
|
||||||
public fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean = true)
|
public fun setProperty(name: Name, item: MetaItem?, notify: Boolean = true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe on property updates. The subscription is bound to the given [scope] and canceled when the scope is canceled
|
* Subscribe on property updates. The subscription is bound to the given [scope] and canceled when the scope is canceled
|
||||||
@ -109,8 +116,8 @@ public fun Vision.asyncNotifyPropertyChange(propertyName: Name) {
|
|||||||
*/
|
*/
|
||||||
public val Vision.ownProperties: MutableItemProvider
|
public val Vision.ownProperties: MutableItemProvider
|
||||||
get() = object : MutableItemProvider {
|
get() = object : MutableItemProvider {
|
||||||
override fun getItem(name: Name): MetaItem<*>? = getOwnProperty(name)
|
override fun getItem(name: Name): MetaItem? = getOwnProperty(name)
|
||||||
override fun setItem(name: Name, item: MetaItem<*>?): Unit = setProperty(name, item)
|
override fun setItem(name: Name, item: MetaItem?): Unit = setProperty(name, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -123,14 +130,14 @@ public fun Vision.allProperties(
|
|||||||
includeStyles: Boolean? = null,
|
includeStyles: Boolean? = null,
|
||||||
includeDefaults: Boolean = true,
|
includeDefaults: Boolean = true,
|
||||||
): MutableItemProvider = object : MutableItemProvider {
|
): MutableItemProvider = object : MutableItemProvider {
|
||||||
override fun getItem(name: Name): MetaItem<*>? = getProperty(
|
override fun getItem(name: Name): MetaItem? = getProperty(
|
||||||
name,
|
name,
|
||||||
inherit = inherit ?: (descriptor?.get(name)?.inherited != false),
|
inherit = inherit ?: (descriptor?.get(name)?.inherited != false),
|
||||||
includeStyles = includeStyles ?: (descriptor?.get(name)?.usesStyles == true),
|
includeStyles = includeStyles ?: (descriptor?.get(name)?.usesStyles == true),
|
||||||
includeDefaults = includeDefaults
|
includeDefaults = includeDefaults
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun setItem(name: Name, item: MetaItem<*>?): Unit = setProperty(name, item)
|
override fun setItem(name: Name, item: MetaItem?): Unit = setProperty(name, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,7 +148,7 @@ public fun Vision.getProperty(
|
|||||||
inherit: Boolean = false,
|
inherit: Boolean = false,
|
||||||
includeStyles: Boolean = true,
|
includeStyles: Boolean = true,
|
||||||
includeDefaults: Boolean = true,
|
includeDefaults: Boolean = true,
|
||||||
): MetaItem<*>? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
|
): MetaItem? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenience method to pair [getProperty]
|
* A convenience method to pair [getProperty]
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.MetaItem
|
|
||||||
import hep.dataforge.meta.MutableMeta
|
|
||||||
import hep.dataforge.meta.asMetaItem
|
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.meta.descriptors.defaultItem
|
import hep.dataforge.meta.descriptors.defaultItem
|
||||||
import hep.dataforge.meta.descriptors.get
|
import hep.dataforge.meta.descriptors.get
|
||||||
@ -40,14 +37,14 @@ public open class VisionBase : Vision {
|
|||||||
/**
|
/**
|
||||||
* Object own properties excluding styles and inheritance
|
* Object own properties excluding styles and inheritance
|
||||||
*/
|
*/
|
||||||
public var properties: Config? = null
|
internal var properties: Config? = null
|
||||||
private set
|
|
||||||
|
override val meta: Meta get() = properties ?: Meta.EMPTY
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun getOrCreateConfig(): Config {
|
private fun getOrCreateConfig(): Config {
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
val newProperties = Config()
|
val newProperties = Config()
|
||||||
properties = newProperties
|
|
||||||
newProperties.onChange(this) { name, oldItem, newItem ->
|
newProperties.onChange(this) { name, oldItem, newItem ->
|
||||||
if (oldItem != newItem) {
|
if (oldItem != newItem) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@ -55,6 +52,7 @@ public open class VisionBase : Vision {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
properties = newProperties
|
||||||
}
|
}
|
||||||
return properties!!
|
return properties!!
|
||||||
}
|
}
|
||||||
@ -62,7 +60,7 @@ public open class VisionBase : Vision {
|
|||||||
/**
|
/**
|
||||||
* A fast accessor method to get own property (no inheritance or styles
|
* A fast accessor method to get own property (no inheritance or styles
|
||||||
*/
|
*/
|
||||||
override fun getOwnProperty(name: Name): MetaItem<*>? {
|
override fun getOwnProperty(name: Name): MetaItem? {
|
||||||
return properties?.getItem(name)
|
return properties?.getItem(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +69,7 @@ public open class VisionBase : Vision {
|
|||||||
inherit: Boolean,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? = sequence {
|
): MetaItem? = sequence {
|
||||||
yield(getOwnProperty(name))
|
yield(getOwnProperty(name))
|
||||||
if (includeStyles) {
|
if (includeStyles) {
|
||||||
yieldAll(getStyleItems(name))
|
yieldAll(getStyleItems(name))
|
||||||
@ -83,7 +81,7 @@ public open class VisionBase : Vision {
|
|||||||
}.merge()
|
}.merge()
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
|
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||||
getOrCreateConfig().setItem(name, item)
|
getOrCreateConfig().setItem(name, item)
|
||||||
if (notify) {
|
if (notify) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@ -121,23 +119,17 @@ public open class VisionBase : Vision {
|
|||||||
propertyInvalidationFlow.emit(propertyName)
|
propertyInvalidationFlow.emit(propertyName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun configure(block: suspend MutableMeta<*>.() -> Unit) {
|
|
||||||
scope.launch {
|
|
||||||
getOrCreateConfig().block()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun update(change: VisionChange) {
|
override fun update(change: VisionChange) {
|
||||||
|
|
||||||
fun updateProperties(at: Name, item: MetaItem<*>) {
|
fun updateProperties(at: Name, item: MetaItem) {
|
||||||
when (item) {
|
when (item) {
|
||||||
is MetaItem.ValueItem -> {
|
is ValueItem -> {
|
||||||
if (item.value == Null) {
|
if (item.value == Null) {
|
||||||
setProperty(at, null)
|
setProperty(at, null)
|
||||||
} else
|
} else
|
||||||
setProperty(at, item)
|
setProperty(at, item)
|
||||||
}
|
}
|
||||||
is MetaItem.NodeItem -> item.node.items.forEach { (token, childItem) ->
|
is NodeItem -> item.node.items.forEach { (token, childItem) ->
|
||||||
updateProperties(at + token, childItem)
|
updateProperties(at + token, childItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public class VisionChangeBuilder : VisionContainerBuilder<Vision> {
|
|||||||
private fun getOrPutChild(visionName: Name): VisionChangeBuilder =
|
private fun getOrPutChild(visionName: Name): VisionChangeBuilder =
|
||||||
children.getOrPut(visionName) { VisionChangeBuilder() }
|
children.getOrPut(visionName) { VisionChangeBuilder() }
|
||||||
|
|
||||||
public fun propertyChanged(visionName: Name, propertyName: Name, item: MetaItem<*>?) {
|
public fun propertyChanged(visionName: Name, propertyName: Name, item: MetaItem?) {
|
||||||
if (visionName == Name.EMPTY) {
|
if (visionName == Name.EMPTY) {
|
||||||
//Write property removal as [Null]
|
//Write property removal as [Null]
|
||||||
propertyChange[propertyName] = (item ?: Null.asMetaItem())
|
propertyChange[propertyName] = (item ?: Null.asMetaItem())
|
||||||
|
@ -12,7 +12,7 @@ public interface VisionPropertyContainer<out T> {
|
|||||||
inherit: Boolean = false,
|
inherit: Boolean = false,
|
||||||
includeStyles: Boolean = true,
|
includeStyles: Boolean = true,
|
||||||
includeDefaults: Boolean = true,
|
includeDefaults: Boolean = true,
|
||||||
): MetaItem<*>?
|
): MetaItem?
|
||||||
|
|
||||||
public fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean = true)
|
public fun setProperty(name: Name, item: MetaItem?, notify: Boolean = true)
|
||||||
}
|
}
|
@ -6,20 +6,16 @@ import hep.dataforge.values.asValue
|
|||||||
@DslMarker
|
@DslMarker
|
||||||
public annotation class VisionBuilder
|
public annotation class VisionBuilder
|
||||||
|
|
||||||
public fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? = when (val first = firstOrNull { it != null }) {
|
public fun Sequence<MetaItem?>.merge(): MetaItem? = when (val first = firstOrNull { it != null }) {
|
||||||
null -> null
|
null -> null
|
||||||
is MetaItem.ValueItem -> first //fast search for first entry if it is value
|
is ValueItem -> first //fast search for first entry if it is value
|
||||||
is MetaItem.NodeItem -> {
|
is NodeItem -> {
|
||||||
//merge nodes if first encountered node is meta
|
//merge nodes if first encountered node is meta
|
||||||
val laminate: Laminate = Laminate(mapNotNull { it.node }.toList())
|
val laminate: Laminate = Laminate(mapNotNull { it.node }.toList())
|
||||||
MetaItem.NodeItem(laminate)
|
NodeItem(laminate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
|
||||||
public val Vision.properties: Config?
|
|
||||||
get() = (this as? VisionBase)?.properties
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control visibility of the element
|
* Control visibility of the element
|
||||||
*/
|
*/
|
||||||
@ -29,4 +25,4 @@ public var Vision.visible: Boolean?
|
|||||||
|
|
||||||
public fun Vision.configure(meta: Meta?): Unit = update(VisionChange(properties = meta))
|
public fun Vision.configure(meta: Meta?): Unit = update(VisionChange(properties = meta))
|
||||||
|
|
||||||
public fun Vision.configure(block: MutableMeta<*>.() -> Unit): Unit = configure(Meta(block))
|
public fun Vision.configure(block: MetaBuilder.() -> Unit): Unit = configure(Meta(block))
|
@ -3,6 +3,7 @@ package hep.dataforge.vision.html
|
|||||||
import hep.dataforge.meta.DFExperimental
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.meta.set
|
import hep.dataforge.meta.set
|
||||||
import hep.dataforge.vision.VisionBase
|
import hep.dataforge.vision.VisionBase
|
||||||
|
import hep.dataforge.vision.configure
|
||||||
import kotlinx.html.*
|
import kotlinx.html.*
|
||||||
import kotlinx.html.stream.createHTML
|
import kotlinx.html.stream.createHTML
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
@ -34,7 +35,7 @@ class HtmlTagTest {
|
|||||||
div {
|
div {
|
||||||
h2 { +"Properties" }
|
h2 { +"Properties" }
|
||||||
ul {
|
ul {
|
||||||
(vision as? VisionBase)?.properties?.items?.forEach {
|
(vision as? VisionBase)?.meta?.items?.forEach {
|
||||||
li {
|
li {
|
||||||
a { +it.key.toString() }
|
a { +it.key.toString() }
|
||||||
p { +it.value.toString() }
|
p { +it.value.toString() }
|
||||||
|
@ -134,11 +134,11 @@ public class VisionClient : AbstractPlugin() {
|
|||||||
stringData
|
stringData
|
||||||
)
|
)
|
||||||
|
|
||||||
if(change.vision!= null){
|
if (change.vision != null) {
|
||||||
renderVision(element, change.vision, outputMeta)
|
renderVision(element, change.vision, outputMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info { "Got update ${change.toString()} for output with name $name" }
|
logger.debug { "Got update $change for output with name $name" }
|
||||||
visionMap[element]?.update(change)
|
visionMap[element]?.update(change)
|
||||||
?: console.info("Target vision for element $element with name $name not found")
|
?: console.info("Target vision for element $element with name $name not found")
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,7 +18,7 @@ import tornadofx.*
|
|||||||
/**
|
/**
|
||||||
* A display for meta and descriptor
|
* A display for meta and descriptor
|
||||||
*/
|
*/
|
||||||
sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
|
sealed class FXMeta<M : TypedMeta<M>> : Comparable<FXMeta<*>> {
|
||||||
abstract val name: NameToken
|
abstract val name: NameToken
|
||||||
abstract val parent: FXMetaNode<M>?
|
abstract val parent: FXMetaNode<M>?
|
||||||
abstract val descriptionProperty: ObservableStringValue
|
abstract val descriptionProperty: ObservableStringValue
|
||||||
@ -35,7 +35,7 @@ sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun <M : MetaNode<M>> root(
|
fun <M : TypedMeta<M>> root(
|
||||||
node: M,
|
node: M,
|
||||||
descriptor: NodeDescriptor? = null,
|
descriptor: NodeDescriptor? = null,
|
||||||
rootName: String = "root"
|
rootName: String = "root"
|
||||||
@ -47,7 +47,7 @@ sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FXMetaNode<M : MetaNode<M>>(
|
class FXMetaNode<M : TypedMeta<M>>(
|
||||||
override val name: NameToken,
|
override val name: NameToken,
|
||||||
override val parent: FXMetaNode<M>?,
|
override val parent: FXMetaNode<M>?,
|
||||||
nodeValue: M? = null,
|
nodeValue: M? = null,
|
||||||
@ -89,7 +89,7 @@ class FXMetaNode<M : MetaNode<M>>(
|
|||||||
init {
|
init {
|
||||||
bind(nodeProperty, descriptorProperty)
|
bind(nodeProperty, descriptorProperty)
|
||||||
|
|
||||||
val listener: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit = { name, _, _ ->
|
val listener: (Name, MetaItem?, MetaItem?) -> Unit = { name, _, _ ->
|
||||||
if (name.length == 1) invalidate()
|
if (name.length == 1) invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ class FXMetaNode<M : MetaNode<M>>(
|
|||||||
val actualItem = node?.items?.get(token)
|
val actualItem = node?.items?.get(token)
|
||||||
val actualDescriptor = descriptor?.items?.get(token.body)
|
val actualDescriptor = descriptor?.items?.get(token.body)
|
||||||
|
|
||||||
if (actualItem is MetaItem.NodeItem || actualDescriptor is NodeDescriptor) {
|
if (actualItem is NodeItem || actualDescriptor is NodeDescriptor) {
|
||||||
FXMetaNode(token, this@FXMetaNode)
|
FXMetaNode(token, this@FXMetaNode)
|
||||||
} else {
|
} else {
|
||||||
FXMetaValue(token, this@FXMetaNode)
|
FXMetaValue(token, this@FXMetaNode)
|
||||||
@ -134,7 +134,7 @@ class FXMetaNode<M : MetaNode<M>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FXMetaValue<M : MetaNode<M>>(
|
public class FXMetaValue<M : TypedMeta<M>>(
|
||||||
override val name: NameToken,
|
override val name: NameToken,
|
||||||
override val parent: FXMetaNode<M>
|
override val parent: FXMetaNode<M>
|
||||||
) : FXMeta<M>() {
|
) : FXMeta<M>() {
|
||||||
@ -151,10 +151,10 @@ public class FXMetaValue<M : MetaNode<M>>(
|
|||||||
//private val innerValueProperty = SimpleObjectProperty(value)
|
//private val innerValueProperty = SimpleObjectProperty(value)
|
||||||
|
|
||||||
public val valueProperty = descriptorProperty.objectBinding { descriptor ->
|
public val valueProperty = descriptorProperty.objectBinding { descriptor ->
|
||||||
parent.node[name].value ?: descriptor?.default
|
parent.node?.get(name).value ?: descriptor?.default
|
||||||
}
|
}
|
||||||
|
|
||||||
override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it[name] != null }
|
override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it?.get(name) != null }
|
||||||
|
|
||||||
public val value by valueProperty
|
public val value by valueProperty
|
||||||
|
|
||||||
@ -169,12 +169,12 @@ public fun <M : MutableMeta<M>> FXMetaNode<M>.remove(name: NameToken) {
|
|||||||
private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boolean): M {
|
private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boolean): M {
|
||||||
return if (append && token.hasIndex()) {
|
return if (append && token.hasIndex()) {
|
||||||
val name = token.asName()
|
val name = token.asName()
|
||||||
val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
val index = (getIndexed(name).keys.mapNotNull { it?.toIntOrNull() }.maxOrNull() ?: -1) + 1
|
||||||
val newName = name.withIndex(index.toString())
|
val newName = name.withIndex(index.toString())
|
||||||
set(newName, Meta.EMPTY)
|
set(newName, Meta.EMPTY)
|
||||||
get(newName).node!!
|
get(newName).node!!
|
||||||
} else {
|
} else {
|
||||||
this.setNode(token.asName(), Meta.EMPTY)
|
this.set(token.asName(), Meta.EMPTY)
|
||||||
//FIXME possible concurrency bug
|
//FIXME possible concurrency bug
|
||||||
get(token).node!!
|
get(token).node!!
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.double
|
|
||||||
import hep.dataforge.meta.get
|
|
||||||
import hep.dataforge.meta.int
|
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.values.int
|
import hep.dataforge.values.int
|
||||||
import hep.dataforge.values.string
|
import hep.dataforge.values.string
|
||||||
@ -35,9 +32,9 @@ public object FXMaterials {
|
|||||||
* Infer color based on meta item
|
* Infer color based on meta item
|
||||||
* @param opacity default opacity
|
* @param opacity default opacity
|
||||||
*/
|
*/
|
||||||
public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
|
public fun MetaItem.color(opacity: Double = 1.0): Color {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is MetaItem.ValueItem -> if (this.value.type == ValueType.NUMBER) {
|
is ValueItem -> if (this.value.type == ValueType.NUMBER) {
|
||||||
val int = value.int
|
val int = value.int
|
||||||
val red = int and 0x00ff0000 shr 16
|
val red = int and 0x00ff0000 shr 16
|
||||||
val green = int and 0x0000ff00 shr 8
|
val green = int and 0x0000ff00 shr 8
|
||||||
@ -46,7 +43,7 @@ public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
|
|||||||
} else {
|
} else {
|
||||||
Color.web(this.value.string)
|
Color.web(this.value.string)
|
||||||
}
|
}
|
||||||
is MetaItem.NodeItem -> {
|
is NodeItem -> {
|
||||||
Color.rgb(
|
Color.rgb(
|
||||||
node[Colors.RED_KEY]?.int ?: 0,
|
node[Colors.RED_KEY]?.int ?: 0,
|
||||||
node[Colors.GREEN_KEY]?.int ?: 0,
|
node[Colors.GREEN_KEY]?.int ?: 0,
|
||||||
@ -60,11 +57,11 @@ public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
|
|||||||
/**
|
/**
|
||||||
* Infer FX material based on meta item
|
* Infer FX material based on meta item
|
||||||
*/
|
*/
|
||||||
public fun MetaItem<*>?.material(): Material {
|
public fun MetaItem?.material(): Material {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
null -> FXMaterials.GREY
|
null -> FXMaterials.GREY
|
||||||
is MetaItem.ValueItem -> PhongMaterial(color())
|
is ValueItem -> PhongMaterial(color())
|
||||||
is MetaItem.NodeItem -> PhongMaterial().apply {
|
is NodeItem -> PhongMaterial().apply {
|
||||||
val opacity = node[SolidMaterial.OPACITY_KEY].double ?: 1.0
|
val opacity = node[SolidMaterial.OPACITY_KEY].double ?: 1.0
|
||||||
diffuseColor = node[SolidMaterial.COLOR_KEY]?.color(opacity) ?: Color.DARKGREY
|
diffuseColor = node[SolidMaterial.COLOR_KEY]?.color(opacity) ?: Color.DARKGREY
|
||||||
specularColor = node[SolidMaterial.SPECULAR_COLOR_KEY]?.color(opacity) ?: Color.WHITE
|
specularColor = node[SolidMaterial.SPECULAR_COLOR_KEY]?.color(opacity) ?: Color.WHITE
|
||||||
|
@ -13,7 +13,7 @@ import tornadofx.*
|
|||||||
* A caching binding collection for [Vision] properties
|
* A caching binding collection for [Vision] properties
|
||||||
*/
|
*/
|
||||||
class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
|
class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
|
||||||
private val bindings = HashMap<Name, ObjectBinding<MetaItem<*>?>>()
|
private val bindings = HashMap<Name, ObjectBinding<MetaItem?>>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
obj.onPropertyChange(fx.context) { name ->
|
obj.onPropertyChange(fx.context) { name ->
|
||||||
@ -31,10 +31,10 @@ class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(key: Name): ObjectBinding<MetaItem<*>?> {
|
operator fun get(key: Name): ObjectBinding<MetaItem?> {
|
||||||
return bindings.getOrPut(key) {
|
return bindings.getOrPut(key) {
|
||||||
object : ObjectBinding<MetaItem<*>?>() {
|
object : ObjectBinding<MetaItem?>() {
|
||||||
override fun computeValue(): MetaItem<*>? = obj.getProperty(key)
|
override fun computeValue(): MetaItem? = obj.getProperty(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,19 +42,19 @@ class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
|
|||||||
operator fun get(key: String) = get(key.toName())
|
operator fun get(key: String) = get(key.toName())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ObjectBinding<MetaItem<*>?>.value() = objectBinding { it.value }
|
fun ObjectBinding<MetaItem?>.value() = objectBinding { it.value }
|
||||||
fun ObjectBinding<MetaItem<*>?>.string() = stringBinding { it.string }
|
fun ObjectBinding<MetaItem?>.string() = stringBinding { it.string }
|
||||||
fun ObjectBinding<MetaItem<*>?>.number() = objectBinding { it.number }
|
fun ObjectBinding<MetaItem?>.number() = objectBinding { it.number }
|
||||||
fun ObjectBinding<MetaItem<*>?>.double() = objectBinding { it.double }
|
fun ObjectBinding<MetaItem?>.double() = objectBinding { it.double }
|
||||||
fun ObjectBinding<MetaItem<*>?>.float() = objectBinding { it.float }
|
fun ObjectBinding<MetaItem?>.float() = objectBinding { it.float }
|
||||||
fun ObjectBinding<MetaItem<*>?>.int() = objectBinding { it.int }
|
fun ObjectBinding<MetaItem?>.int() = objectBinding { it.int }
|
||||||
fun ObjectBinding<MetaItem<*>?>.long() = objectBinding { it.long }
|
fun ObjectBinding<MetaItem?>.long() = objectBinding { it.long }
|
||||||
fun ObjectBinding<MetaItem<*>?>.node() = objectBinding { it.node }
|
fun ObjectBinding<MetaItem?>.node() = objectBinding { it.node }
|
||||||
|
|
||||||
fun ObjectBinding<MetaItem<*>?>.string(default: String) = stringBinding { it.string ?: default }
|
fun ObjectBinding<MetaItem?>.string(default: String) = stringBinding { it.string ?: default }
|
||||||
fun ObjectBinding<MetaItem<*>?>.double(default: Double) = doubleBinding { it.double ?: default }
|
fun ObjectBinding<MetaItem?>.double(default: Double) = doubleBinding { it.double ?: default }
|
||||||
fun ObjectBinding<MetaItem<*>?>.float(default: Float) = floatBinding { it.float ?: default }
|
fun ObjectBinding<MetaItem?>.float(default: Float) = floatBinding { it.float ?: default }
|
||||||
fun ObjectBinding<MetaItem<*>?>.int(default: Int) = integerBinding { it.int ?: default }
|
fun ObjectBinding<MetaItem?>.int(default: Int) = integerBinding { it.int ?: default }
|
||||||
fun ObjectBinding<MetaItem<*>?>.long(default: Long) = longBinding { it.long ?: default }
|
fun ObjectBinding<MetaItem?>.long(default: Long) = longBinding { it.long ?: default }
|
||||||
|
|
||||||
fun <T> ObjectBinding<MetaItem<*>?>.transform(transform: (MetaItem<*>) -> T) = objectBinding { it?.let(transform) }
|
fun <T> ObjectBinding<MetaItem?>.transform(transform: (MetaItem) -> T) = objectBinding { it?.let(transform) }
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package hep.dataforge.vision.gdml
|
package hep.dataforge.vision.gdml
|
||||||
|
|
||||||
import hep.dataforge.meta.DFExperimental
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.meta.sequence
|
import hep.dataforge.meta.itemSequence
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.properties
|
|
||||||
import hep.dataforge.vision.solid.*
|
import hep.dataforge.vision.solid.*
|
||||||
|
|
||||||
public expect class Counter() {
|
public expect class Counter() {
|
||||||
@ -27,7 +26,7 @@ internal fun Vision.updateFrom(other: Vision): Vision {
|
|||||||
scaleY = scaleY.toDouble() * other.scaleY.toDouble()
|
scaleY = scaleY.toDouble() * other.scaleY.toDouble()
|
||||||
scaleZ = scaleZ.toDouble() * other.scaleZ.toDouble()
|
scaleZ = scaleZ.toDouble() * other.scaleZ.toDouble()
|
||||||
}
|
}
|
||||||
other.properties?.sequence()?.forEach { (name, item) ->
|
other.meta.itemSequence().forEach { (name, item) ->
|
||||||
if (getProperty(name) == null) {
|
if (getProperty(name) == null) {
|
||||||
setProperty(name, item)
|
setProperty(name, item)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
|
||||||
import hep.dataforge.meta.update
|
import hep.dataforge.meta.update
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.vision.*
|
import hep.dataforge.vision.*
|
||||||
@ -39,18 +38,20 @@ public inline fun VisionContainerBuilder<Solid>.composite(
|
|||||||
val group = SolidGroup().apply(builder)
|
val group = SolidGroup().apply(builder)
|
||||||
val children = group.children.values.filterIsInstance<Solid>()
|
val children = group.children.values.filterIsInstance<Solid>()
|
||||||
if (children.size != 2) error("Composite requires exactly two children")
|
if (children.size != 2) error("Composite requires exactly two children")
|
||||||
return Composite(type, children[0], children[1]).also {
|
return Composite(type, children[0], children[1]).also { composite ->
|
||||||
it.configure { update(group.properties ?: Meta.EMPTY) }
|
composite.configure {
|
||||||
|
update(group.meta)
|
||||||
|
}
|
||||||
if (group.position != null) {
|
if (group.position != null) {
|
||||||
it.position = group.position
|
composite.position = group.position
|
||||||
}
|
}
|
||||||
if (group.rotation != null) {
|
if (group.rotation != null) {
|
||||||
it.rotation = group.rotation
|
composite.rotation = group.rotation
|
||||||
}
|
}
|
||||||
if (group.scale != null) {
|
if (group.scale != null) {
|
||||||
it.scale = group.scale
|
composite.scale = group.scale
|
||||||
}
|
}
|
||||||
set(name, it)
|
set(name, composite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public interface Solid : Vision {
|
|||||||
if (first.position != second.position) return false
|
if (first.position != second.position) return false
|
||||||
if (first.rotation != second.rotation) return false
|
if (first.rotation != second.rotation) return false
|
||||||
if (first.scale != second.scale) return false
|
if (first.scale != second.scale) return false
|
||||||
if (first.properties != second.properties) return false
|
if (first.meta != second.meta) return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,16 +106,16 @@ internal class Prototypes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getOwnProperty(name: Name): MetaItem<*>? = null
|
override fun getOwnProperty(name: Name): MetaItem? = null
|
||||||
|
|
||||||
override fun getProperty(
|
override fun getProperty(
|
||||||
name: Name,
|
name: Name,
|
||||||
inherit: Boolean,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? = null
|
): MetaItem? = null
|
||||||
|
|
||||||
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
|
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||||
error("Can't ser property of prototypes container")
|
error("Can't ser property of prototypes container")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,12 +19,12 @@ public class SolidMaterial : Scheme() {
|
|||||||
/**
|
/**
|
||||||
* Primary web-color for the material
|
* Primary web-color for the material
|
||||||
*/
|
*/
|
||||||
public var color: ColorAccessor = ColorAccessor(config, COLOR_KEY)
|
public var color: ColorAccessor = ColorAccessor(items, COLOR_KEY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specular color for phong material
|
* Specular color for phong material
|
||||||
*/
|
*/
|
||||||
public var specularColor: ColorAccessor = ColorAccessor(config, SPECULAR_COLOR_KEY)
|
public var specularColor: ColorAccessor = ColorAccessor(items, SPECULAR_COLOR_KEY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opacity
|
* Opacity
|
||||||
@ -100,16 +100,17 @@ public val Solid.color: ColorAccessor
|
|||||||
|
|
||||||
public var Solid.material: SolidMaterial?
|
public var Solid.material: SolidMaterial?
|
||||||
get() = getProperty(MATERIAL_KEY, inherit = true).node?.let { SolidMaterial.read(it) }
|
get() = getProperty(MATERIAL_KEY, inherit = true).node?.let { SolidMaterial.read(it) }
|
||||||
set(value) = setProperty(MATERIAL_KEY, value?.config)
|
set(value) = setProperty(MATERIAL_KEY, value?.rootNode)
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public fun Solid.material(builder: SolidMaterial.() -> Unit) {
|
public fun Solid.material(builder: SolidMaterial.() -> Unit) {
|
||||||
val node = allProperties(inherit = true).getItem(MATERIAL_KEY).node
|
|
||||||
if (node != null) {
|
|
||||||
SolidMaterial.update(node, builder)
|
|
||||||
} else {
|
|
||||||
setProperty(MATERIAL_KEY, SolidMaterial(builder))
|
setProperty(MATERIAL_KEY, SolidMaterial(builder))
|
||||||
}
|
// val node = getOwnProperty(MATERIAL_KEY).node
|
||||||
|
// if (node != null) {
|
||||||
|
// configure(SolidMaterial(builder).config)
|
||||||
|
// } else {
|
||||||
|
// setProperty(MATERIAL_KEY, SolidMaterial(builder))
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public var Solid.opacity: Number?
|
public var Solid.opacity: Number?
|
||||||
|
@ -17,7 +17,7 @@ private fun SolidReference.getRefProperty(
|
|||||||
inherit: Boolean,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? {
|
): MetaItem? {
|
||||||
return sequence {
|
return sequence {
|
||||||
yield(getOwnProperty(name))
|
yield(getOwnProperty(name))
|
||||||
if (includeStyles) {
|
if (includeStyles) {
|
||||||
@ -59,11 +59,11 @@ public class SolidReferenceGroup(
|
|||||||
private fun childPropertyName(childName: Name, propertyName: Name): Name =
|
private fun childPropertyName(childName: Name, propertyName: Name): Name =
|
||||||
childToken(childName) + propertyName
|
childToken(childName) + propertyName
|
||||||
|
|
||||||
private fun getChildProperty(childName: Name, propertyName: Name): MetaItem<*>? {
|
private fun getChildProperty(childName: Name, propertyName: Name): MetaItem? {
|
||||||
return getOwnProperty(childPropertyName(childName, propertyName))
|
return getOwnProperty(childPropertyName(childName, propertyName))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setChildProperty(childName: Name, propertyName: Name, item: MetaItem<*>?, notify: Boolean) {
|
private fun setChildProperty(childName: Name, propertyName: Name, item: MetaItem?, notify: Boolean) {
|
||||||
setProperty(childPropertyName(childName, propertyName), item, notify)
|
setProperty(childPropertyName(childName, propertyName), item, notify)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ public class SolidReferenceGroup(
|
|||||||
inherit: Boolean,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
): MetaItem? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||||
|
|
||||||
override val descriptor: NodeDescriptor get() = prototype.descriptor
|
override val descriptor: NodeDescriptor get() = prototype.descriptor
|
||||||
|
|
||||||
@ -99,9 +99,11 @@ public class SolidReferenceGroup(
|
|||||||
ReferenceChild(childName + key.asName())
|
ReferenceChild(childName + key.asName())
|
||||||
} ?: emptyMap()
|
} ?: emptyMap()
|
||||||
|
|
||||||
override fun getOwnProperty(name: Name): MetaItem<*>? = getChildProperty(childName, name)
|
override val meta: Meta get() =TODO()// getChildProperty(childName, Name.EMPTY).node ?: Meta.EMPTY
|
||||||
|
|
||||||
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
|
override fun getOwnProperty(name: Name): MetaItem? = getChildProperty(childName, name)
|
||||||
|
|
||||||
|
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||||
setChildProperty(childName, name, item, notify)
|
setChildProperty(childName, name, item, notify)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +112,7 @@ public class SolidReferenceGroup(
|
|||||||
inherit: Boolean,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
): MetaItem? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||||
|
|
||||||
override var parent: VisionGroup?
|
override var parent: VisionGroup?
|
||||||
get() {
|
get() {
|
||||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vision.solid.specifications
|
|||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
|
||||||
public class Axes : Scheme() {
|
public class Axes : Scheme() {
|
||||||
public var visible: Boolean by boolean(!config.isEmpty())
|
public var visible: Boolean by boolean(rootNode?.isEmpty() != false)
|
||||||
public var size: Double by double(AXIS_SIZE)
|
public var size: Double by double(AXIS_SIZE)
|
||||||
public var width: Double by double(AXIS_WIDTH)
|
public var width: Double by double(AXIS_WIDTH)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import hep.dataforge.vision.solid.*
|
|||||||
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
||||||
return child.apply {
|
return child.apply {
|
||||||
|
|
||||||
configure(parent.properties)
|
configure(parent.meta)
|
||||||
|
|
||||||
//parent.properties?.let { config.update(it) }
|
//parent.properties?.let { config.update(it) }
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class ConvexTest {
|
|||||||
val json = SolidManager.jsonForSolids.encodeToJsonElement(Convex.serializer(), convex)
|
val json = SolidManager.jsonForSolids.encodeToJsonElement(Convex.serializer(), convex)
|
||||||
val meta = json.toMetaItem().node!!
|
val meta = json.toMetaItem().node!!
|
||||||
|
|
||||||
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() }
|
val points = meta.getIndexed("points").values.map { (it as NodeItem<*>).node.point3D() }
|
||||||
assertEquals(8, points.count())
|
assertEquals(8, points.count())
|
||||||
|
|
||||||
assertEquals(8, convex.points.size)
|
assertEquals(8, convex.points.size)
|
||||||
|
@ -4,7 +4,6 @@ import hep.dataforge.names.Name
|
|||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
import hep.dataforge.vision.get
|
import hep.dataforge.vision.get
|
||||||
import hep.dataforge.vision.properties
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ class SerializationTest {
|
|||||||
val string = SolidManager.encodeToString(cube)
|
val string = SolidManager.encodeToString(cube)
|
||||||
println(string)
|
println(string)
|
||||||
val newCube = SolidManager.decodeFromString(string)
|
val newCube = SolidManager.decodeFromString(string)
|
||||||
assertEquals(cube.properties, newCube.properties)
|
assertEquals(cube.meta, newCube.meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -54,7 +53,7 @@ class SerializationTest {
|
|||||||
val string = SolidManager.encodeToString(group)
|
val string = SolidManager.encodeToString(group)
|
||||||
println(string)
|
println(string)
|
||||||
val reconstructed = SolidManager.decodeFromString(string) as SolidGroup
|
val reconstructed = SolidManager.decodeFromString(string) as SolidGroup
|
||||||
assertEquals(group["cube"]?.properties, reconstructed["cube"]?.properties)
|
assertEquals(group["cube"]?.meta, reconstructed["cube"]?.meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package hep.dataforge.vision.solid.three
|
package hep.dataforge.vision.solid.three
|
||||||
|
|
||||||
import hep.dataforge.meta.getItem
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.meta.string
|
import hep.dataforge.meta.string
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
@ -177,7 +177,7 @@ public class ThreeCanvas(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun addControls(element: Node, controls: Controls) {
|
private fun addControls(element: Node, controls: Controls) {
|
||||||
when (controls.getItem("type").string) {
|
when (controls.get("type").string) {
|
||||||
"trackball" -> TrackballControls(camera, element)
|
"trackball" -> TrackballControls(camera, element)
|
||||||
else -> OrbitControls(camera, element)
|
else -> OrbitControls(camera, element)
|
||||||
}
|
}
|
||||||
|
@ -109,15 +109,15 @@ public object ThreeMaterials {
|
|||||||
/**
|
/**
|
||||||
* Infer color based on meta item
|
* Infer color based on meta item
|
||||||
*/
|
*/
|
||||||
public fun MetaItem<*>.getColor(): Color {
|
public fun MetaItem.getColor(): Color {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is MetaItem.ValueItem -> if (this.value.type == ValueType.NUMBER) {
|
is ValueItem -> if (this.value.type == ValueType.NUMBER) {
|
||||||
val int = value.int
|
val int = value.int
|
||||||
Color(int)
|
Color(int)
|
||||||
} else {
|
} else {
|
||||||
Color(this.value.string)
|
Color(this.value.string)
|
||||||
}
|
}
|
||||||
is MetaItem.NodeItem -> {
|
is NodeItem -> {
|
||||||
Color(
|
Color(
|
||||||
node[Colors.RED_KEY]?.int ?: 0,
|
node[Colors.RED_KEY]?.int ?: 0,
|
||||||
node[Colors.GREEN_KEY]?.int ?: 0,
|
node[Colors.GREEN_KEY]?.int ?: 0,
|
||||||
@ -160,7 +160,7 @@ public fun Mesh.updateMaterial(vision: Vision) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
|
public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
|
||||||
if (material.cached) {
|
if (material.cached || propertyName == SolidMaterial.MATERIAL_KEY) {
|
||||||
//generate a new material since cached material should not be changed
|
//generate a new material since cached material should not be changed
|
||||||
updateMaterial(vision)
|
updateMaterial(vision)
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,7 +17,7 @@ import kotlin.math.PI
|
|||||||
|
|
||||||
public val Solid.euler: Euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
|
public val Solid.euler: Euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
|
||||||
|
|
||||||
public val MetaItem<*>.vector: Vector3 get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)
|
public val MetaItem.vector: Vector3 get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)
|
||||||
|
|
||||||
public fun Geometry.toBufferGeometry(): BufferGeometry = BufferGeometry().apply { fromGeometry(this@toBufferGeometry) }
|
public fun Geometry.toBufferGeometry(): BufferGeometry = BufferGeometry().apply { fromGeometry(this@toBufferGeometry) }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user