forked from kscience/visionforge
New Proxy child styling and json editor
This commit is contained in:
parent
2fcfd767c1
commit
d1e2d8d60b
@ -1,18 +1,16 @@
|
||||
package hep.dataforge.vis.common
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.names.*
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
|
||||
/**
|
||||
* Abstract implementation of group of [VisualObject]
|
||||
*/
|
||||
abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup {
|
||||
abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup {
|
||||
|
||||
//protected abstract val _children: MutableMap<NameToken, T>
|
||||
|
||||
@ -21,6 +19,32 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup {
|
||||
*/
|
||||
abstract override val children: Map<NameToken, VisualObject> //get() = _children
|
||||
|
||||
//TODO replace by custom object with get/set functionality
|
||||
protected abstract val styles: MutableMap<Name, Meta>
|
||||
|
||||
override fun getStyle(name: Name): Meta? = styles[name]
|
||||
|
||||
override fun setStyle(name: Name, meta: Meta) {
|
||||
fun VisualObject.applyStyle(name: Name, meta: Meta) {
|
||||
if (style.contains(name.toString())) {
|
||||
//full update
|
||||
//TODO do a fine grained update
|
||||
if (this is AbstractVisualObject) {
|
||||
styleChanged()
|
||||
} else {
|
||||
propertyChanged(EmptyName)
|
||||
}
|
||||
}
|
||||
if (this is VisualGroup) {
|
||||
this.children.forEach { (_, child) ->
|
||||
child.applyStyle(name, meta)
|
||||
}
|
||||
}
|
||||
}
|
||||
styles[name] = meta
|
||||
applyStyle(name, meta)
|
||||
}
|
||||
|
||||
|
||||
// init {
|
||||
// //Do after deserialization
|
||||
@ -75,12 +99,13 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup {
|
||||
/**
|
||||
* Add a static child. Statics could not be found by name, removed or replaced
|
||||
*/
|
||||
protected abstract fun addStatic(child: VisualObject)
|
||||
protected open fun addStatic(child: VisualObject) =
|
||||
setChild(NameToken("@static(${child.hashCode()})"), child)
|
||||
|
||||
/**
|
||||
* Recursively create a child group
|
||||
*/
|
||||
protected abstract fun createGroup(name: Name): VisualGroup
|
||||
protected abstract fun createGroup(name: Name): MutableVisualGroup
|
||||
|
||||
/**
|
||||
* Add named or unnamed child to the group. If key is [null] the child is considered unnamed. Both key and value are not
|
||||
@ -103,7 +128,7 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup {
|
||||
}
|
||||
else -> {
|
||||
//TODO add safety check
|
||||
val parent = (get(name.cutLast()) as? VisualGroup) ?: createGroup(name.cutLast())
|
||||
val parent = (get(name.cutLast()) as? MutableVisualGroup) ?: createGroup(name.cutLast())
|
||||
parent[name.last()!!.asName()] = child
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,13 @@ abstract class AbstractVisualObject : VisualObject {
|
||||
@Transient
|
||||
override var parent: VisualObject? = null
|
||||
|
||||
protected abstract var properties: Config?
|
||||
abstract override var properties: Config?
|
||||
|
||||
override var style: List<String>
|
||||
get() = properties?.let { it[STYLE_KEY].stringList } ?: emptyList()
|
||||
set(value) {
|
||||
setProperty(VisualObject.STYLE_KEY, value)
|
||||
setProperty(STYLE_KEY, value)
|
||||
styleChanged()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,12 +58,11 @@ abstract class AbstractVisualObject : VisualObject {
|
||||
|
||||
private var styleCache: Laminate? = null
|
||||
|
||||
private fun styles(): Laminate {
|
||||
return styleCache ?: kotlin.run {
|
||||
protected val actualStyles: Laminate
|
||||
get() = styleCache ?: run {
|
||||
Laminate(style.map { it.toName() }.mapNotNull(::findStyle))
|
||||
.also { styleCache = it }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to reset style cache
|
||||
@ -74,9 +74,9 @@ abstract class AbstractVisualObject : VisualObject {
|
||||
|
||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||
return if (inherit) {
|
||||
properties?.get(name) ?: parent?.getProperty(name, inherit) ?: styles()[name]
|
||||
properties?.get(name) ?: parent?.getProperty(name, inherit) ?: actualStyles[name]
|
||||
} else {
|
||||
properties?.get(name) ?: styles()[name]
|
||||
properties?.get(name) ?: actualStyles[name]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.provider.Provider
|
||||
|
||||
interface VisualGroup : VisualObject, Provider, Iterable<VisualObject> {
|
||||
interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
|
||||
/**
|
||||
* A map of top level named children
|
||||
*/
|
||||
@ -26,6 +26,7 @@ interface VisualGroup : VisualObject, Provider, Iterable<VisualObject> {
|
||||
else -> emptyMap()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over children of this group
|
||||
*/
|
||||
@ -42,6 +43,17 @@ interface VisualGroup : VisualObject, Provider, Iterable<VisualObject> {
|
||||
*/
|
||||
fun setStyle(name: Name, meta: Meta)
|
||||
|
||||
operator fun get(name: Name): VisualObject? {
|
||||
return when {
|
||||
name.isEmpty() -> this
|
||||
name.length == 1 -> children[name.first()!!]
|
||||
else -> (children[name.first()!!] as? VisualGroup)?.get(name.cutFirst())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface MutableVisualGroup : VisualGroup {
|
||||
|
||||
/**
|
||||
* Add listener for children structure change.
|
||||
* @param owner the handler to properly remove listeners
|
||||
@ -54,14 +66,6 @@ interface VisualGroup : VisualObject, Provider, Iterable<VisualObject> {
|
||||
*/
|
||||
fun removeChildrenChangeListener(owner: Any?)
|
||||
|
||||
operator fun get(name: Name): VisualObject? {
|
||||
return when {
|
||||
name.isEmpty() -> this
|
||||
name.length == 1 -> children[name.first()!!]
|
||||
else -> (children[name.first()!!] as? VisualGroup)?.get(name.cutFirst())
|
||||
}
|
||||
}
|
||||
|
||||
operator fun set(name: Name, child: VisualObject?)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package hep.dataforge.vis.common
|
||||
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.Configurable
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.MetaRepr
|
||||
@ -25,6 +26,11 @@ interface VisualObject : MetaRepr, Configurable {
|
||||
@Transient
|
||||
var parent: VisualObject?
|
||||
|
||||
/**
|
||||
* Direct properties access
|
||||
*/
|
||||
val properties: Config?
|
||||
|
||||
/**
|
||||
* Set property for this object
|
||||
*/
|
||||
@ -63,3 +69,7 @@ interface VisualObject : MetaRepr, Configurable {
|
||||
|
||||
fun VisualObject.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? = getProperty(key.toName(), inherit)
|
||||
fun VisualObject.setProperty(key: String, value: Any?) = setProperty(key.toName(), value)
|
||||
|
||||
fun VisualObject.applyStyle(name: String) {
|
||||
style = style + name
|
||||
}
|
@ -1,13 +1,18 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.meta.buildMeta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.applyStyle
|
||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||
import hep.dataforge.vis.spatial.VisualObject3D
|
||||
import hep.dataforge.vis.spatial.material
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.COLOR_KEY
|
||||
import scientifik.gdml.*
|
||||
import kotlin.collections.set
|
||||
import kotlin.random.Random
|
||||
|
||||
class GDMLTransformer(val root: GDML) {
|
||||
@ -24,25 +29,33 @@ class GDMLTransformer(val root: GDML) {
|
||||
* A special group for local templates
|
||||
*/
|
||||
val templates by lazy { VisualGroup3D() }
|
||||
private val styles = HashMap<Name, Meta>()
|
||||
|
||||
var lUnit: LUnit = LUnit.MM
|
||||
|
||||
var solidAction: (GDMLSolid) -> Action = { Action.CACHE }
|
||||
var volumeAction: (GDMLGroup) -> Action = { Action.ACCEPT }
|
||||
var volumeAction: (GDMLGroup) -> Action = { Action.CACHE }
|
||||
|
||||
|
||||
var solidConfiguration: VisualObject3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { _, _ -> }
|
||||
|
||||
fun VisualObject.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
|
||||
styles.getOrPut(name.toName()){
|
||||
buildMeta(builder)
|
||||
}
|
||||
applyStyle(name)
|
||||
}
|
||||
|
||||
internal fun configureSolid(obj: VisualObject3D, parent: GDMLVolume, solid: GDMLSolid) {
|
||||
val material = parent.materialref.resolve(root) ?: GDMLElement(parent.materialref.ref)
|
||||
|
||||
val materialColor = materialCache.getOrPut(material) {
|
||||
buildMeta {
|
||||
"color" to Colors.rgbToString(random.nextInt(0, Int.MAX_VALUE))
|
||||
val styleName = "material[${material.name}]"
|
||||
|
||||
obj.useStyle(styleName){
|
||||
COLOR_KEY to Colors.rgbToString(random.nextInt(0, Int.MAX_VALUE))
|
||||
"gdml.material" to material.name
|
||||
}
|
||||
}
|
||||
obj.setProperty("gdml.material".toName(), material.name)
|
||||
obj.material = materialColor
|
||||
|
||||
obj.solidConfiguration(parent, solid)
|
||||
}
|
||||
|
||||
@ -72,6 +85,9 @@ class GDMLTransformer(val root: GDML) {
|
||||
// res = it(res)
|
||||
// }
|
||||
final.templates = templates
|
||||
styles.forEach {
|
||||
final.setStyle(it.key, it.value)
|
||||
}
|
||||
onFinish(this@GDMLTransformer)
|
||||
return final
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.meta.update
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.MutableVisualGroup
|
||||
import hep.dataforge.vis.spatial.Point3D
|
||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||
import hep.dataforge.vis.spatial.VisualObject3D
|
||||
@ -16,7 +16,7 @@ typealias GDMLOptimization = GDMLTransformer.(VisualGroup3D) -> VisualGroup3D
|
||||
* Collapse nodes with single child
|
||||
*/
|
||||
val optimizeSingleChild: GDMLOptimization = { tree ->
|
||||
fun VisualGroup.replaceChildren() {
|
||||
fun MutableVisualGroup.replaceChildren() {
|
||||
children.forEach { (key, child) ->
|
||||
if (child is VisualGroup3D && child.children.size == 1) {
|
||||
val newChild = child.children.values.first().apply {
|
||||
@ -40,13 +40,13 @@ val optimizeSingleChild: GDMLOptimization = { tree ->
|
||||
}
|
||||
}
|
||||
|
||||
if (newChild is VisualGroup) {
|
||||
if (newChild is MutableVisualGroup) {
|
||||
newChild.replaceChildren()
|
||||
}
|
||||
|
||||
//actual replacement
|
||||
set(key.asName(), newChild)
|
||||
} else if (child is VisualGroup) {
|
||||
} else if (child is MutableVisualGroup) {
|
||||
child.replaceChildren()
|
||||
}
|
||||
}
|
||||
|
@ -57,11 +57,11 @@ private class GDMLDemoApp : ApplicationBase() {
|
||||
onload = {
|
||||
val string = result as String
|
||||
|
||||
try {
|
||||
// try {
|
||||
block(file.name, string)
|
||||
} catch (ex: Exception) {
|
||||
console.error(ex)
|
||||
}
|
||||
// } catch (ex: Exception) {
|
||||
// console.error(ex)
|
||||
// }
|
||||
|
||||
}
|
||||
readAsText(file)
|
||||
@ -190,7 +190,7 @@ private class GDMLDemoApp : ApplicationBase() {
|
||||
|
||||
if (visual is VisualGroup) {
|
||||
visual.toTree(editor::propertyEditor).render(tree as HTMLElement) {
|
||||
showCheckboxes = true
|
||||
showCheckboxes = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,748 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="240"
|
||||
height="144"
|
||||
id="svg4136"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="jsoneditor-icons.svg">
|
||||
<title
|
||||
id="title6512">JSON Editor Icons</title>
|
||||
<metadata
|
||||
id="metadata4148">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>JSON Editor Icons</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs4146" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ff63ff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1026"
|
||||
id="namedview4144"
|
||||
showgrid="true"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="13.229181"
|
||||
inkscape:cy="119.82429"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4136"
|
||||
showguides="false"
|
||||
borderlayer="false"
|
||||
inkscape:showpageshadow="true"
|
||||
showborder="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4640"
|
||||
empspacing="24" />
|
||||
</sodipodi:namedview>
|
||||
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0"
|
||||
id="svg_1"
|
||||
height="16"
|
||||
width="16"
|
||||
y="4"
|
||||
x="4" />
|
||||
<rect
|
||||
id="svg_1-7"
|
||||
height="16"
|
||||
width="16"
|
||||
y="3.999995"
|
||||
x="28.000006"
|
||||
style="fill:#ec3f29;fill-opacity:0.94117647;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0"
|
||||
x="52.000004"
|
||||
y="3.999995"
|
||||
width="16"
|
||||
height="16"
|
||||
id="rect4165" />
|
||||
<rect
|
||||
id="rect4175"
|
||||
height="16"
|
||||
width="16"
|
||||
y="3.9999852"
|
||||
x="172.00002"
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4175-3"
|
||||
height="16"
|
||||
width="16"
|
||||
y="3.999995"
|
||||
x="196"
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0" />
|
||||
<g
|
||||
id="g4299"
|
||||
style="stroke:none">
|
||||
<rect
|
||||
x="7.0000048"
|
||||
y="10.999998"
|
||||
width="9.9999924"
|
||||
height="1.9999986"
|
||||
id="svg_1-1"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
x="11.000005"
|
||||
y="7.0000114"
|
||||
width="1.9999955"
|
||||
height="9.9999838"
|
||||
id="svg_1-1-1"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0" />
|
||||
</g>
|
||||
<g
|
||||
id="g4299-3"
|
||||
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001)"
|
||||
style="stroke:none">
|
||||
<rect
|
||||
x="7.0000048"
|
||||
y="10.999998"
|
||||
width="9.9999924"
|
||||
height="1.9999986"
|
||||
id="svg_1-1-0"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
x="11.000005"
|
||||
y="7.0000114"
|
||||
width="1.9999955"
|
||||
height="9.9999838"
|
||||
id="svg_1-1-1-9"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0" />
|
||||
</g>
|
||||
<rect
|
||||
id="svg_1-7-5"
|
||||
height="6.9999905"
|
||||
width="6.9999909"
|
||||
y="7.0000048"
|
||||
x="55.000004"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#4c4c4c;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="58"
|
||||
y="10.00001"
|
||||
width="6.9999909"
|
||||
height="6.9999905"
|
||||
id="rect4354" />
|
||||
<rect
|
||||
id="svg_1-7-5-7"
|
||||
height="6.9999905"
|
||||
width="6.9999909"
|
||||
y="10.000005"
|
||||
x="58.000004"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#3c80df;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.94117647" />
|
||||
<g
|
||||
id="g4378">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
|
||||
x="198"
|
||||
y="10.999999"
|
||||
width="7.9999909"
|
||||
height="1.9999965"
|
||||
id="svg_1-7-5-3" />
|
||||
<rect
|
||||
id="rect4374"
|
||||
height="1.9999946"
|
||||
width="11.999995"
|
||||
y="7.0000005"
|
||||
x="198"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4376"
|
||||
height="1.9999995"
|
||||
width="3.9999928"
|
||||
y="14.999996"
|
||||
x="198"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1,0,0,-1,-23.999995,23.999995)"
|
||||
id="g4383">
|
||||
<rect
|
||||
id="rect4385"
|
||||
height="1.9999965"
|
||||
width="7.9999909"
|
||||
y="10.999999"
|
||||
x="198"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
|
||||
x="198"
|
||||
y="7.0000005"
|
||||
width="11.999995"
|
||||
height="1.9999946"
|
||||
id="rect4387" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
|
||||
x="198"
|
||||
y="14.999996"
|
||||
width="3.9999928"
|
||||
height="1.9999995"
|
||||
id="rect4389" />
|
||||
</g>
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none"
|
||||
id="rect3754-4"
|
||||
width="16"
|
||||
height="16"
|
||||
x="76"
|
||||
y="3.9999199" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z"
|
||||
id="path4351"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z"
|
||||
id="path4351-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none"
|
||||
id="rect3754-25"
|
||||
width="16"
|
||||
height="16"
|
||||
x="100"
|
||||
y="3.9999199" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
d="m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z"
|
||||
id="path2987"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
d="m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z"
|
||||
id="path2987-1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none"
|
||||
id="rect3754-73"
|
||||
width="16"
|
||||
height="16"
|
||||
x="124"
|
||||
y="3.9999199" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
d="m 126.2824,17.602938 1.78957,0 1.14143,-2.8641 5.65364,0 1.14856,2.8641 1.76565,0 -4.78687,-11.1610996 -1.91903,0 z"
|
||||
id="path3780"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none"
|
||||
d="m 129.72704,13.478838 4.60852,0.01 -2.30426,-5.5497996 z"
|
||||
id="path3782"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none"
|
||||
id="rect3754-35"
|
||||
width="16"
|
||||
height="16"
|
||||
x="148"
|
||||
y="3.9999199" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
d="m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z"
|
||||
id="path5008-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
d="m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z"
|
||||
id="path5008-2-8"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<rect
|
||||
id="svg_1-7-2"
|
||||
height="1.9999961"
|
||||
width="11.999996"
|
||||
y="64"
|
||||
x="54"
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="svg_1-7-2-2"
|
||||
height="2.9999905"
|
||||
width="2.9999907"
|
||||
y="52"
|
||||
x="80.000008"
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
|
||||
x="85.000008"
|
||||
y="52"
|
||||
width="2.9999907"
|
||||
height="2.9999905"
|
||||
id="rect4561" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
|
||||
x="80.000008"
|
||||
y="58"
|
||||
width="2.9999907"
|
||||
height="2.9999905"
|
||||
id="rect4563" />
|
||||
<rect
|
||||
id="rect4565"
|
||||
height="2.9999905"
|
||||
width="2.9999907"
|
||||
y="58"
|
||||
x="85.000008"
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4567"
|
||||
height="2.9999905"
|
||||
width="2.9999907"
|
||||
y="64"
|
||||
x="80.000008"
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
|
||||
x="85.000008"
|
||||
y="64"
|
||||
width="2.9999907"
|
||||
height="2.9999905"
|
||||
id="rect4569" />
|
||||
<circle
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#4c4c4c;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="path4571"
|
||||
cx="110.06081"
|
||||
cy="57.939209"
|
||||
r="4.7438836" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
|
||||
x="116.64566"
|
||||
y="-31.79752"
|
||||
width="4.229713"
|
||||
height="6.4053884"
|
||||
id="rect4563-2"
|
||||
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)" />
|
||||
<path
|
||||
style="fill:#4c4c4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 125,56 138.77027,56.095 132,64 Z"
|
||||
id="path4613"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4615"
|
||||
d="M 149,64 162.77027,63.905 156,56 Z"
|
||||
style="fill:#4c4c4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
|
||||
x="54"
|
||||
y="53"
|
||||
width="11.999996"
|
||||
height="1.9999961"
|
||||
id="rect4638" />
|
||||
<rect
|
||||
id="svg_1-7-2-24"
|
||||
height="1.9999957"
|
||||
width="12.99999"
|
||||
y="-56"
|
||||
x="53"
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
|
||||
transform="matrix(0,1,-1,0,0,0)" />
|
||||
<rect
|
||||
transform="matrix(0,1,-1,0,0,0)"
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
|
||||
x="53"
|
||||
y="-66"
|
||||
width="12.99999"
|
||||
height="1.9999957"
|
||||
id="rect4657" />
|
||||
<rect
|
||||
id="rect4659"
|
||||
height="0.99999291"
|
||||
width="11.999999"
|
||||
y="57"
|
||||
x="54"
|
||||
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
|
||||
x="54"
|
||||
y="88.000122"
|
||||
width="11.999996"
|
||||
height="1.9999961"
|
||||
id="rect4661" />
|
||||
<rect
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
|
||||
x="80.000008"
|
||||
y="76.000122"
|
||||
width="2.9999907"
|
||||
height="2.9999905"
|
||||
id="rect4663" />
|
||||
<rect
|
||||
id="rect4665"
|
||||
height="2.9999905"
|
||||
width="2.9999907"
|
||||
y="76.000122"
|
||||
x="85.000008"
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1" />
|
||||
<rect
|
||||
id="rect4667"
|
||||
height="2.9999905"
|
||||
width="2.9999907"
|
||||
y="82.000122"
|
||||
x="80.000008"
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
|
||||
x="85.000008"
|
||||
y="82.000122"
|
||||
width="2.9999907"
|
||||
height="2.9999905"
|
||||
id="rect4669" />
|
||||
<rect
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
|
||||
x="80.000008"
|
||||
y="88.000122"
|
||||
width="2.9999907"
|
||||
height="2.9999905"
|
||||
id="rect4671" />
|
||||
<rect
|
||||
id="rect4673"
|
||||
height="2.9999905"
|
||||
width="2.9999907"
|
||||
y="88.000122"
|
||||
x="85.000008"
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1" />
|
||||
<circle
|
||||
r="4.7438836"
|
||||
cy="81.939331"
|
||||
cx="110.06081"
|
||||
id="circle4675"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#d3d3d3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)"
|
||||
id="rect4677"
|
||||
height="6.4053884"
|
||||
width="4.229713"
|
||||
y="-14.826816"
|
||||
x="133.6163"
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:#d3d3d3;stroke-width:0;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4679"
|
||||
d="m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z"
|
||||
style="fill:#d3d3d3;fill-opacity:1;fill-rule:evenodd;stroke:#d3d3d3;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#d3d3d3;fill-opacity:1;fill-rule:evenodd;stroke:#d3d3d3;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 149,88.0002 162.77027,87.9052 156,80.0002 Z"
|
||||
id="path4681"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<rect
|
||||
id="rect4683"
|
||||
height="1.9999961"
|
||||
width="11.999996"
|
||||
y="77.000122"
|
||||
x="54"
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1" />
|
||||
<rect
|
||||
transform="matrix(0,1,-1,0,0,0)"
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
|
||||
x="77.000122"
|
||||
y="-56"
|
||||
width="12.99999"
|
||||
height="1.9999957"
|
||||
id="rect4685" />
|
||||
<rect
|
||||
id="rect4687"
|
||||
height="1.9999957"
|
||||
width="12.99999"
|
||||
y="-66"
|
||||
x="77.000122"
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
|
||||
transform="matrix(0,1,-1,0,0,0)" />
|
||||
<rect
|
||||
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
|
||||
x="54"
|
||||
y="81.000122"
|
||||
width="11.999999"
|
||||
height="0.99999291"
|
||||
id="rect4689" />
|
||||
<rect
|
||||
id="rect4761-1"
|
||||
height="1.9999945"
|
||||
width="15.99999"
|
||||
y="101"
|
||||
x="76.000008"
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4761-0"
|
||||
height="1.9999945"
|
||||
width="15.99999"
|
||||
y="105"
|
||||
x="76.000008"
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4761-7"
|
||||
height="1.9999945"
|
||||
width="9"
|
||||
y="109"
|
||||
x="76.000008"
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4761-1-1"
|
||||
height="1.9999945"
|
||||
width="12"
|
||||
y="125"
|
||||
x="76.000008"
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4761-1-1-4"
|
||||
height="1.9999945"
|
||||
width="10"
|
||||
y="137"
|
||||
x="76.000008"
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4761-1-1-4-4"
|
||||
height="1.9999945"
|
||||
width="10"
|
||||
y="129"
|
||||
x="82"
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:none;stroke-width:0" />
|
||||
<rect
|
||||
id="rect4761-1-1-4-4-3"
|
||||
height="1.9999945"
|
||||
width="9"
|
||||
y="133"
|
||||
x="82"
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:none;stroke-width:0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.8;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.66157866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z"
|
||||
id="path4138" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.8;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.66157866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z"
|
||||
id="path4138-1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.96599996;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z"
|
||||
id="path3055-0-77" />
|
||||
<path
|
||||
style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.96599996;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 4.9850574,108.015 14.0298856,-0.03"
|
||||
id="path5244-5-0-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.96599996;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 4.9849874,132.015 14.0298866,-0.03"
|
||||
id="path5244-5-0-5-8"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.4;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.66157866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z"
|
||||
id="path4138-12" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.4;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.66157866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z"
|
||||
id="path4138-1-3" />
|
||||
<path
|
||||
id="path6191"
|
||||
d="m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z"
|
||||
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.96599996;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.96599996;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z"
|
||||
id="path6193" />
|
||||
<path
|
||||
id="path6195"
|
||||
d="m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z"
|
||||
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.96599996;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#4d4d4d;fill-opacity:0.90196078;stroke:#d3d3d3;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="path4500"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="11.55581"
|
||||
sodipodi:cy="60.073242"
|
||||
sodipodi:r1="5.1116104"
|
||||
sodipodi:r2="2.5558052"
|
||||
sodipodi:arg1="0"
|
||||
sodipodi:arg2="1.0471976"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z"
|
||||
inkscape:transform-center-x="-1.2779026" />
|
||||
<path
|
||||
inkscape:transform-center-x="1.277902"
|
||||
d="m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z"
|
||||
inkscape:randomized="0"
|
||||
inkscape:rounded="0"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:arg2="1.0471976"
|
||||
sodipodi:arg1="0"
|
||||
sodipodi:r2="2.5558052"
|
||||
sodipodi:r1="5.1116104"
|
||||
sodipodi:cy="60.073242"
|
||||
sodipodi:cx="-36.611614"
|
||||
sodipodi:sides="3"
|
||||
id="path4502"
|
||||
style="fill:#4d4d4d;fill-opacity:0.90196078;stroke:#d3d3d3;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
sodipodi:type="star"
|
||||
transform="scale(-1,1)" />
|
||||
<path
|
||||
d="m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z"
|
||||
inkscape:randomized="0"
|
||||
inkscape:rounded="0"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:arg2="1.0471976"
|
||||
sodipodi:arg1="0"
|
||||
sodipodi:r2="2.5558052"
|
||||
sodipodi:r1="5.1116104"
|
||||
sodipodi:cy="60.073212"
|
||||
sodipodi:cx="11.55581"
|
||||
sodipodi:sides="3"
|
||||
id="path4504"
|
||||
style="fill:#4d4d4d;fill-opacity:0.90196078;stroke:#d3d3d3;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
sodipodi:type="star"
|
||||
transform="matrix(0,1,-1,0,72.0074,71.7877)"
|
||||
inkscape:transform-center-y="1.2779029" />
|
||||
<path
|
||||
inkscape:transform-center-y="-1.2779026"
|
||||
transform="matrix(0,-1,-1,0,96,96)"
|
||||
sodipodi:type="star"
|
||||
style="fill:#4d4d4d;fill-opacity:0.90196078;stroke:#d3d3d3;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="path4506"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="11.55581"
|
||||
sodipodi:cy="60.073212"
|
||||
sodipodi:r1="5.1116104"
|
||||
sodipodi:r2="2.5558052"
|
||||
sodipodi:arg1="0"
|
||||
sodipodi:arg2="1.0471976"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4615-5"
|
||||
d="m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z"
|
||||
style="fill:#fbb917;fill-opacity:1;fill-rule:evenodd;stroke:#fbb917;stroke-width:1.65161395;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 179,55 0,6 2,0 0,-6"
|
||||
id="path4300"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 179,62 0,2 2,0 0,-2"
|
||||
id="path4300-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:0.8;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:0.8"
|
||||
d="M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z"
|
||||
id="path4268"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccccccc" />
|
||||
<rect
|
||||
id="rect4175-3-5"
|
||||
height="16"
|
||||
width="16"
|
||||
y="4"
|
||||
x="220"
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2"
|
||||
id="path3546"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<g
|
||||
transform="matrix(1.3333328,0,0,-1.5999992,-139.9999,127.19999)"
|
||||
id="g4383-6">
|
||||
<rect
|
||||
id="rect4385-2"
|
||||
height="1.2499905"
|
||||
width="5.9999924"
|
||||
y="12.625005"
|
||||
x="198.00002"
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:#000000;stroke-width:0" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:#000000;stroke-width:0"
|
||||
x="198.00002"
|
||||
y="15.125007"
|
||||
width="7.4999928"
|
||||
height="1.2499949"
|
||||
id="rect4387-9" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:#000000;stroke-width:0"
|
||||
x="198.00002"
|
||||
y="7.6250024"
|
||||
width="2.9999909"
|
||||
height="1.2499905"
|
||||
id="rect4389-1-0" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:0.8;stroke:#000000;stroke-width:0"
|
||||
x="198.00002"
|
||||
y="10.125004"
|
||||
width="4.4999919"
|
||||
height="1.2499905"
|
||||
id="rect4389-1-9" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:0.8;fill-rule:evenodd;stroke:none;stroke-width:0.68465352px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0"
|
||||
id="path4402"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:0.8;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3"
|
||||
id="path3546-2-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<rect
|
||||
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0"
|
||||
id="svg_1-3"
|
||||
height="16"
|
||||
width="16"
|
||||
y="28"
|
||||
x="4" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4402-5-7"
|
||||
d="m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.68465352px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</svg>
|
After Width: | Height: | Size: 31 KiB |
6
dataforge-vis-spatial-gdml/src/jsMain/web/css/jsoneditor.min.css
vendored
Normal file
6
dataforge-vis-spatial-gdml/src/jsMain/web/css/jsoneditor.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -11,6 +11,7 @@
|
||||
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
<link rel="stylesheet" href="css/inspire-tree-light.min.css">
|
||||
<link rel="stylesheet" href="css/jsoneditor.min.css">
|
||||
<script type="text/javascript" src="main.bundle.js"></script>
|
||||
</head>
|
||||
<body class="testApp">
|
||||
|
@ -15,32 +15,19 @@ fun main() {
|
||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||
val visual = xml.toVisual {
|
||||
lUnit = LUnit.CM
|
||||
volumeAction = { volume ->
|
||||
when {
|
||||
volume.name.startsWith("ecal01lay") -> GDMLTransformer.Action.REJECT
|
||||
volume.name.startsWith("ecal") -> GDMLTransformer.Action.CACHE
|
||||
volume.name.startsWith("UPBL") -> GDMLTransformer.Action.REJECT
|
||||
volume.name.startsWith("USCL") -> GDMLTransformer.Action.REJECT
|
||||
volume.name.startsWith("U") -> GDMLTransformer.Action.CACHE
|
||||
volume.name.startsWith("VPBL") -> GDMLTransformer.Action.REJECT
|
||||
volume.name.startsWith("VSCL") -> GDMLTransformer.Action.REJECT
|
||||
volume.name.startsWith("V") -> GDMLTransformer.Action.CACHE
|
||||
else -> GDMLTransformer.Action.ACCEPT
|
||||
}
|
||||
}
|
||||
|
||||
solidConfiguration = { parent, solid ->
|
||||
if (parent.physVolumes.isNotEmpty()) {
|
||||
opacity = 0.3
|
||||
}
|
||||
if (solid.name.startsWith("Coil")
|
||||
if (parent.physVolumes.isNotEmpty()
|
||||
|| solid.name.startsWith("Coil")
|
||||
|| solid.name.startsWith("Yoke")
|
||||
|| solid.name.startsWith("Magnet")
|
||||
|| solid.name.startsWith("Pole")
|
||||
) {
|
||||
useStyle("opaque") {
|
||||
opacity = 0.3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// optimizeSingleChild = true
|
||||
//optimizations = listOf(optimizeSingleChild)
|
||||
|
@ -33,6 +33,7 @@ kotlin {
|
||||
implementation(npm("element-resize-event"))
|
||||
implementation(npm("inspire-tree","6.0.1"))
|
||||
implementation(npm("inspire-tree-dom","4.0.6"))
|
||||
implementation(npm("jsoneditor"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,16 @@ package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.ConfigSerializer
|
||||
import hep.dataforge.io.NameSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.MutableVisualGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import kotlinx.serialization.UseSerializers
|
||||
|
||||
/**
|
||||
@ -34,21 +32,22 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
||||
/**
|
||||
* Recursively search for defined template in the parent
|
||||
*/
|
||||
val template: VisualObject3D
|
||||
val prototype: VisualObject3D
|
||||
get() = (parent as? VisualGroup3D)?.getTemplate(templateName)
|
||||
?: error("Template with name $templateName not found in $parent")
|
||||
|
||||
override fun getStyle(name: Name): Meta? = null
|
||||
override fun getStyle(name: Name): Meta? = (parent as VisualGroup?)?.getStyle(name)
|
||||
|
||||
override fun setStyle(name: Name, meta: Meta) {
|
||||
(parent as VisualGroup?)?.setStyle(name, meta)
|
||||
//do nothing
|
||||
}
|
||||
|
||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||
return if (inherit) {
|
||||
super.getProperty(name, false) ?: template.getProperty(name, false) ?: parent?.getProperty(name, inherit)
|
||||
super.getProperty(name, false) ?: prototype.getProperty(name, false) ?: parent?.getProperty(name, inherit)
|
||||
} else {
|
||||
super.getProperty(name, false) ?: template.getProperty(name, false)
|
||||
super.getProperty(name, false) ?: prototype.getProperty(name, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,48 +57,55 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
||||
}
|
||||
|
||||
override val children: Map<NameToken, ProxyChild>
|
||||
get() = (template as? VisualGroup)?.children?.mapValues {
|
||||
get() = (prototype as? MutableVisualGroup)?.children?.mapValues {
|
||||
ProxyChild(it.key.asName())
|
||||
} ?: emptyMap()
|
||||
|
||||
private data class ProxyChangeListeners(val owner: Any?, val callback: (Name, VisualObject?) -> Unit)
|
||||
|
||||
@Transient
|
||||
private val listeners = HashSet<ProxyChangeListeners>()
|
||||
|
||||
override fun onChildrenChange(owner: Any?, action: (Name, VisualObject?) -> Unit) {
|
||||
listeners.add(ProxyChangeListeners(owner, action))
|
||||
}
|
||||
|
||||
override fun removeChildrenChangeListener(owner: Any?) {
|
||||
listeners.removeAll { it.owner == owner }
|
||||
}
|
||||
|
||||
override fun set(name: Name, child: VisualObject?) {
|
||||
error("Content change not supported for proxy")
|
||||
}
|
||||
|
||||
private val propertyCache: HashMap<Name, Config> = HashMap()
|
||||
|
||||
private fun Config.attachListener(obj: VisualObject) {
|
||||
onChange(this@Proxy) { name, before, after ->
|
||||
listeners.forEach { listener ->
|
||||
listener.callback(name, obj)
|
||||
}
|
||||
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
|
||||
|
||||
override val children: Map<NameToken, VisualObject>
|
||||
get() = ((prototype as? MutableVisualGroup)?.get(name) as? MutableVisualGroup)
|
||||
?.children
|
||||
?.mapValues { (key, _) ->
|
||||
ProxyChild(
|
||||
name + key.asName()
|
||||
)
|
||||
}
|
||||
?: emptyMap()
|
||||
|
||||
override fun getStyle(name: Name): Meta? = this@Proxy.getStyle(name)
|
||||
|
||||
override fun setStyle(name: Name, meta: Meta) {
|
||||
this@Proxy.setStyle(name, meta)
|
||||
}
|
||||
|
||||
inner class ProxyChild(val name: Name) : AbstractVisualObject() {
|
||||
val prototype: VisualObject
|
||||
get() = (this@Proxy.prototype as? VisualGroup)?.get(name)
|
||||
?: error("Prototype with name $name not found in ${this@Proxy}")
|
||||
|
||||
override var properties: Config?
|
||||
get() = propertyCache[name]
|
||||
set(value) {
|
||||
if (value == null) {
|
||||
propertyCache.remove(name)?.removeListener(this@Proxy)
|
||||
propertyCache.remove(name)
|
||||
} else {
|
||||
propertyCache[name] = value.apply {
|
||||
attachListener(this@ProxyChild)
|
||||
propertyCache[name] = value
|
||||
}
|
||||
}
|
||||
|
||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||
return if (inherit) {
|
||||
properties?.get(name)
|
||||
?: parent?.getProperty(name, inherit)
|
||||
?: actualStyles[name]
|
||||
?: prototype.getProperty(name, inherit)
|
||||
} else {
|
||||
properties?.get(name)
|
||||
?: actualStyles[name]
|
||||
?: prototype.getProperty(name, inherit)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class Visual3DPlugin(meta: Meta) : AbstractPlugin(meta) {
|
||||
contextual(Point2DSerializer)
|
||||
contextual(NameSerializer)
|
||||
contextual(NameTokenSerializer)
|
||||
contextual(MetaSerializer)
|
||||
contextual(Meta::class, MetaSerializer)
|
||||
contextual(ConfigSerializer)
|
||||
|
||||
polymorphic(VisualObject::class, VisualObject3D::class) {
|
||||
|
@ -2,27 +2,29 @@
|
||||
Point3DSerializer::class,
|
||||
ConfigSerializer::class,
|
||||
NameTokenSerializer::class,
|
||||
NameSerializer::class
|
||||
NameSerializer::class,
|
||||
MetaSerializer::class
|
||||
)
|
||||
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.ConfigSerializer
|
||||
import hep.dataforge.io.MetaSerializer
|
||||
import hep.dataforge.io.NameSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.meta.set
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.vis.common.AbstractVisualGroup
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.MutableVisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
|
||||
@Serializable
|
||||
@ -37,32 +39,8 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
||||
}
|
||||
|
||||
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
|
||||
public override var properties: Config? = null
|
||||
|
||||
private val styles = HashMap<Name, Meta>()
|
||||
|
||||
override fun getStyle(name: Name): Meta? = styles[name]
|
||||
|
||||
override fun setStyle(name: Name, meta: Meta) {
|
||||
fun VisualObject.applyStyle(name: Name, meta: Meta) {
|
||||
if (style.contains(name.toString())) {
|
||||
//full update
|
||||
//TODO do a fine grained update
|
||||
if(this is AbstractVisualObject){
|
||||
styleChanged()
|
||||
} else {
|
||||
propertyChanged(EmptyName)
|
||||
}
|
||||
}
|
||||
if (this is VisualGroup) {
|
||||
this.children.forEach { (_, child) ->
|
||||
child.applyStyle(name, meta)
|
||||
}
|
||||
}
|
||||
}
|
||||
styles[name] = meta
|
||||
applyStyle(name, meta)
|
||||
}
|
||||
override var properties: Config? = null
|
||||
override val styles = HashMap<Name, Meta>()
|
||||
|
||||
override var position: Point3D? = null
|
||||
override var rotation: Point3D? = null
|
||||
@ -87,10 +65,10 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
||||
childrenChanged(token.asName(), child)
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO add special static group to hold statics without propagation
|
||||
*/
|
||||
override fun addStatic(child: VisualObject) = setChild(NameToken("@static(${child.hashCode()})"), child)
|
||||
// /**
|
||||
// * TODO add special static group to hold statics without propagation
|
||||
// */
|
||||
// override fun addStatic(child: VisualObject) = setChild(NameToken("@static(${child.hashCode()})"), child)
|
||||
|
||||
override fun createGroup(name: Name): VisualGroup3D {
|
||||
return when {
|
||||
@ -125,10 +103,10 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
||||
/**
|
||||
* A fix for serialization bug that writes all proper parents inside the tree after deserialization
|
||||
*/
|
||||
fun VisualGroup.attachChildren() {
|
||||
fun MutableVisualGroup.attachChildren() {
|
||||
this.children.values.forEach {
|
||||
it.parent = this
|
||||
(it as? VisualGroup)?.attachChildren()
|
||||
(it as? MutableVisualGroup)?.attachChildren()
|
||||
}
|
||||
if (this is VisualGroup3D) {
|
||||
templates?.apply {
|
||||
|
@ -9,9 +9,11 @@ import hep.dataforge.names.plus
|
||||
import hep.dataforge.output.Output
|
||||
import hep.dataforge.vis.common.Colors.rgbToString
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.COLOR_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.DETAIL_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.LAYER_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.MATERIAL_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.OPACITY_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.SELECTED_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@ -40,6 +42,9 @@ interface VisualObject3D : VisualObject {
|
||||
val DETAIL_KEY = "detail".asName()
|
||||
val LAYER_KEY = "layer".asName()
|
||||
|
||||
val COLOR_KEY = MATERIAL_KEY + "color"
|
||||
val OPACITY_KEY = MATERIAL_KEY + "opacity"
|
||||
|
||||
val x = "x".asName()
|
||||
val y = "y".asName()
|
||||
val z = "z".asName()
|
||||
@ -109,11 +114,9 @@ var VisualObject.material: Meta?
|
||||
set(value) = setProperty(MATERIAL_KEY, value)
|
||||
|
||||
var VisualObject.opacity: Double
|
||||
get() = material?.get("opacity").double ?: 1.0
|
||||
get() = getProperty(OPACITY_KEY).double ?: 1.0
|
||||
set(value) {
|
||||
material = (material?.builder() ?: MetaBuilder()).apply {
|
||||
"opacity" to value
|
||||
}
|
||||
setProperty(OPACITY_KEY, value)
|
||||
}
|
||||
|
||||
var VisualObject.visible: Boolean?
|
||||
@ -125,15 +128,15 @@ var VisualObject.selected: Boolean?
|
||||
set(value) = setProperty(SELECTED_KEY, value)
|
||||
|
||||
fun VisualObject.color(rgb: Int) {
|
||||
material = (material?.builder() ?: MetaBuilder()).apply { "color" to rgbToString(rgb) }
|
||||
setProperty(COLOR_KEY, rgbToString(rgb))
|
||||
}
|
||||
|
||||
fun VisualObject.color(rgb: String) {
|
||||
material = (material?.builder() ?: MetaBuilder()).apply { "color" to rgb }
|
||||
setProperty(COLOR_KEY, rgb)
|
||||
}
|
||||
|
||||
var VisualObject.color: String?
|
||||
get() = material["color"].string
|
||||
get() = getProperty(COLOR_KEY).string
|
||||
set(value) {
|
||||
if (value != null) {
|
||||
color(value)
|
||||
|
@ -20,7 +20,7 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
|
||||
}
|
||||
|
||||
override fun invoke(obj: Proxy): Object3D {
|
||||
val template = obj.template
|
||||
val template = obj.prototype
|
||||
val cachedObject = cache.getOrPut(template) {
|
||||
three.buildObject3D(template)
|
||||
}
|
||||
@ -45,11 +45,6 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
|
||||
}
|
||||
}
|
||||
|
||||
obj.onChildrenChange(this) { name, propertyHolder ->
|
||||
val child = object3D.findChild(name)
|
||||
(child as? Mesh)?.updateProperties(propertyHolder)
|
||||
}
|
||||
|
||||
return object3D
|
||||
}
|
||||
}
|
@ -10,7 +10,6 @@ import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.getProperty
|
||||
import hep.dataforge.vis.spatial.Proxy
|
||||
import hep.dataforge.vis.spatial.selected
|
||||
import hep.dataforge.vis.spatial.visible
|
||||
import org.w3c.dom.HTMLElement
|
||||
import kotlin.js.json
|
||||
@ -40,7 +39,7 @@ fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { obj, name -
|
||||
fun generateNodeConfig(item: VisualObject, fullName: Name): NodeConfig {
|
||||
val title = item.getProperty("title").string ?: fullName.last()?.toString() ?: "root"
|
||||
val className = if (item is Proxy) {
|
||||
item.template::class.toString()
|
||||
item.prototype::class.toString()
|
||||
} else {
|
||||
item::class.toString()
|
||||
}.replace("class ", "")
|
||||
@ -88,15 +87,15 @@ fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { obj, name -
|
||||
map[rootNode.id] = this
|
||||
rootNode.fillChildren(this, EmptyName)
|
||||
|
||||
inspireTree.on("node.selected") { node: TreeNode, isLoadEvent: Boolean ->
|
||||
if (!isLoadEvent) {
|
||||
map[node.id]?.selected = node.selected()
|
||||
}
|
||||
}
|
||||
|
||||
inspireTree.on("node.deselect") { node: TreeNode ->
|
||||
map[node.id]?.selected = node.selected()
|
||||
}
|
||||
// inspireTree.on("node.selected") { node: TreeNode, isLoadEvent: Boolean ->
|
||||
// if (!isLoadEvent) {
|
||||
// map[node.id]?.selected = node.selected()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// inspireTree.on("node.deselect") { node: TreeNode ->
|
||||
// map[node.id]?.selected = node.selected()
|
||||
// }
|
||||
|
||||
inspireTree.on("node.checked") { node: TreeNode, isLoadEvent: Boolean ->
|
||||
if (!isLoadEvent) {
|
||||
|
@ -0,0 +1,185 @@
|
||||
@file:Suppress(
|
||||
"INTERFACE_WITH_SUPERCLASS",
|
||||
"OVERRIDING_FINAL_MEMBER",
|
||||
"RETURN_TYPE_MISMATCH_ON_OVERRIDE",
|
||||
"CONFLICTING_OVERLOADS",
|
||||
"EXTERNAL_DELEGATION"
|
||||
)
|
||||
|
||||
package hep.dataforge.vis.spatial.tree
|
||||
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
external interface Node {
|
||||
var field: String
|
||||
var value: String? get() = definedExternally; set(value) = definedExternally
|
||||
var path: dynamic
|
||||
}
|
||||
|
||||
external interface NodeName {
|
||||
var path: Array<String>
|
||||
var type: dynamic /* 'object' | 'array' */
|
||||
var size: Number
|
||||
}
|
||||
|
||||
external interface ValidationError {
|
||||
var path: dynamic
|
||||
var message: String
|
||||
}
|
||||
|
||||
external interface Template {
|
||||
var text: String
|
||||
var title: String
|
||||
var className: String? get() = definedExternally; set(value) = definedExternally
|
||||
var field: String
|
||||
var value: Any
|
||||
}
|
||||
|
||||
external interface `T$6` {
|
||||
var startFrom: Number
|
||||
var options: Array<String>
|
||||
}
|
||||
|
||||
external interface AutoCompleteOptions {
|
||||
var confirmKeys: Array<Number>? get() = definedExternally; set(value) = definedExternally
|
||||
var caseSensitive: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
// var getOptions: AutoCompleteOptionsGetter? get() = definedExternally; set(value) = definedExternally
|
||||
}
|
||||
|
||||
external interface SelectionPosition {
|
||||
var row: Number
|
||||
var column: Number
|
||||
}
|
||||
|
||||
external interface SerializableNode {
|
||||
var value: Any
|
||||
var path: dynamic
|
||||
}
|
||||
|
||||
external interface Color {
|
||||
var rgba: Array<Number>
|
||||
var hsla: Array<Number>
|
||||
var rgbString: String
|
||||
var rgbaString: String
|
||||
var hslString: String
|
||||
var hslaString: String
|
||||
var hex: String
|
||||
}
|
||||
|
||||
//external interface `T$0` {
|
||||
// var field: Boolean
|
||||
// var value: Boolean
|
||||
//}
|
||||
//
|
||||
//external interface `T$1` {
|
||||
// @nativeGetter
|
||||
// operator fun get(key: String): String?
|
||||
//
|
||||
// @nativeSetter
|
||||
// operator fun set(key: String, value: String)
|
||||
//}
|
||||
|
||||
//external interface Languages {
|
||||
// @nativeGetter
|
||||
// operator fun get(lang: String): `T$1`?
|
||||
//
|
||||
// @nativeSetter
|
||||
// operator fun set(lang: String, value: `T$1`)
|
||||
//}
|
||||
|
||||
external interface JSONEditorOptions {
|
||||
// var ace: AceAjax.Ace? get() = definedExternally; set(value) = definedExternally
|
||||
// var ajv: Ajv? get() = definedExternally; set(value) = definedExternally
|
||||
var onChange: (() -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var onChangeJSON: ((json: Any) -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var onChangeText: ((jsonString: String) -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var onEditable: ((node: Node) -> dynamic)? get() = definedExternally; set(value) = definedExternally
|
||||
var onError: ((error: Error) -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var onModeChange: ((newMode: dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */, oldMode: dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */) -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var onNodeName: ((nodeName: NodeName) -> String?)? get() = definedExternally; set(value) = definedExternally
|
||||
var onValidate: ((json: Any) -> dynamic)? get() = definedExternally; set(value) = definedExternally
|
||||
var escapeUnicode: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var sortObjectKeys: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var history: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var mode: dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */
|
||||
var modes: Array<dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */>? get() = definedExternally; set(value) = definedExternally
|
||||
var name: String? get() = definedExternally; set(value) = definedExternally
|
||||
var schema: Any? get() = definedExternally; set(value) = definedExternally
|
||||
var schemaRefs: Any? get() = definedExternally; set(value) = definedExternally
|
||||
var search: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var indentation: Number? get() = definedExternally; set(value) = definedExternally
|
||||
var theme: String? get() = definedExternally; set(value) = definedExternally
|
||||
var templates: Array<Template>? get() = definedExternally; set(value) = definedExternally
|
||||
var autocomplete: AutoCompleteOptions? get() = definedExternally; set(value) = definedExternally
|
||||
var mainMenuBar: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var navigationBar: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var statusBar: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var onTextSelectionChange: ((start: SelectionPosition, end: SelectionPosition, text: String) -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var onSelectionChange: ((start: SerializableNode, end: SerializableNode) -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var onEvent: ((node: Node, event: String) -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var colorPicker: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var onColorPicker: ((parent: HTMLElement, color: String, onChange: (color: Color) -> Unit) -> Unit)? get() = definedExternally; set(value) = definedExternally
|
||||
var timestampTag: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var language: String? get() = definedExternally; set(value) = definedExternally
|
||||
//var languages: Languages? get() = definedExternally; set(value) = definedExternally
|
||||
var modalAnchor: HTMLElement? get() = definedExternally; set(value) = definedExternally
|
||||
var enableSort: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var enableTransform: Boolean? get() = definedExternally; set(value) = definedExternally
|
||||
var maxVisibleChilds: Number? get() = definedExternally; set(value) = definedExternally
|
||||
}
|
||||
|
||||
external interface JsonPath {
|
||||
var path: dynamic
|
||||
}
|
||||
|
||||
external interface EditorSelection {
|
||||
var start: SerializableNode
|
||||
var end: SerializableNode
|
||||
}
|
||||
|
||||
external interface TextSelection {
|
||||
var start: SelectionPosition
|
||||
var end: SelectionPosition
|
||||
var text: String
|
||||
}
|
||||
|
||||
@JsModule("jsoneditor")
|
||||
@JsNonModule
|
||||
external open class JSONEditor(
|
||||
container: HTMLElement,
|
||||
options: JSONEditorOptions? = definedExternally /* null */,
|
||||
json: dynamic = definedExternally /* null */
|
||||
) {
|
||||
open fun collapseAll()
|
||||
open fun destroy()
|
||||
open fun expandAll()
|
||||
open fun focus()
|
||||
open fun get(): Any
|
||||
open fun getMode(): dynamic /* 'tree' | 'view' | 'form' | 'code' | 'text' */
|
||||
open fun getName(): String?
|
||||
open fun getNodesByRange(start: JsonPath, end: JsonPath): Array<SerializableNode>
|
||||
open fun getSelection(): EditorSelection
|
||||
open fun getText(): String
|
||||
open fun getTextSelection(): TextSelection
|
||||
open fun refresh()
|
||||
open fun set(json: Any)
|
||||
open fun setMode(mode: String /* 'tree' */)
|
||||
open fun setMode(mode: String /* 'view' */)
|
||||
open fun setMode(mode: String /* 'form' */)
|
||||
open fun setMode(mode: String /* 'code' */)
|
||||
open fun setMode(mode: String /* 'text' */)
|
||||
open fun setName(name: String? = definedExternally /* null */)
|
||||
open fun setSchema(schema: Any?, schemaRefs: Any? = definedExternally /* null */)
|
||||
open fun setSelection(start: JsonPath, end: JsonPath)
|
||||
open fun setText(jsonString: String)
|
||||
open fun setTextSelection(start: SelectionPosition, end: SelectionPosition)
|
||||
open fun update(json: Any)
|
||||
open fun updateText(jsonString: String)
|
||||
|
||||
companion object {
|
||||
var VALID_OPTIONS: Array<String>
|
||||
// var ace: AceAjax.Ace
|
||||
// var Ajv: Ajv
|
||||
var VanillaPicker: Any
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package hep.dataforge.vis.spatial.tree
|
||||
|
||||
import hep.dataforge.io.toJson
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.spatial.Proxy
|
||||
import hep.dataforge.vis.spatial.color
|
||||
import hep.dataforge.vis.spatial.opacity
|
||||
import hep.dataforge.vis.spatial.visible
|
||||
@ -62,6 +64,21 @@ fun Element.propertyEditor(item: VisualObject?, name: String?) {
|
||||
}
|
||||
}
|
||||
}
|
||||
(item.properties ?: (item as? Proxy)?.prototype?.properties
|
||||
?: (item as? Proxy.ProxyChild)?.prototype?.properties)
|
||||
?.let { config ->
|
||||
|
||||
div("card") {
|
||||
div("card-body") {
|
||||
h3(classes = "card-title") { +"Properties" }
|
||||
}.apply {
|
||||
val options = (js("{}") as JSONEditorOptions).apply {
|
||||
mode = "view"
|
||||
}
|
||||
JSONEditor(this, options, JSON.parse(config.toJson().toString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user