forked from kscience/visionforge
Refactor ObjectTree to functional component
This commit is contained in:
parent
ac86832616
commit
28ca287ccd
@ -1,17 +1,17 @@
|
|||||||
package hep.dataforge.js
|
package hep.dataforge.js
|
||||||
|
|
||||||
import react.RComponent
|
import react.RBuilder
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
fun <T> RComponent<*, *>.initState(init: () -> T): ReadWriteProperty<RComponent<*, *>, T> =
|
fun <T> RBuilder.initState(init: () -> T): ReadWriteProperty<Any?, T> =
|
||||||
object : ReadWriteProperty<RComponent<*, *>, T> {
|
object : ReadWriteProperty<Any?, T> {
|
||||||
val pair = react.useState(init)
|
val pair = react.useState(init)
|
||||||
override fun getValue(thisRef: RComponent<*, *>, property: KProperty<*>): T {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
return pair.first
|
return pair.first
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: RComponent<*, *>, property: KProperty<*>, value: T) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||||
pair.second(value)
|
pair.second(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package hep.dataforge.vis.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.js.card
|
import hep.dataforge.js.card
|
||||||
|
import hep.dataforge.js.initState
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.names.startsWith
|
import hep.dataforge.names.startsWith
|
||||||
@ -25,20 +26,14 @@ interface TreeState : RState {
|
|||||||
var expanded: Boolean
|
var expanded: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class ObjectTree : RComponent<ObjectTreeProps, TreeState>() {
|
private fun RBuilder.objectTree(props: ObjectTreeProps): Unit {
|
||||||
|
var expanded: Boolean by initState{ props.selected?.startsWith(props.name) ?: false }
|
||||||
|
|
||||||
override fun TreeState.init(props: ObjectTreeProps) {
|
val onClick: (Event) -> Unit = {
|
||||||
expanded = props.selected?.startsWith(props.name) ?: false
|
expanded = !expanded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun RBuilder.treeLabel(text: String) {
|
||||||
private val onClick: (Event) -> Unit = {
|
|
||||||
setState {
|
|
||||||
expanded = !expanded
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun RBuilder.treeLabel(text: String) {
|
|
||||||
button(classes = "btn btn-link tree-label p-0") {
|
button(classes = "btn btn-link tree-label p-0") {
|
||||||
+text
|
+text
|
||||||
attrs {
|
attrs {
|
||||||
@ -50,59 +45,61 @@ class ObjectTree : RComponent<ObjectTreeProps, TreeState>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun RBuilder.render() {
|
val token = props.name.last()?.toString() ?: "World"
|
||||||
val token = props.name.last()?.toString() ?: "World"
|
val obj = props.obj
|
||||||
val obj = props.obj
|
|
||||||
|
|
||||||
//display as node if any child is visible
|
//display as node if any child is visible
|
||||||
if (obj is VisualGroup) {
|
if (obj is VisualGroup) {
|
||||||
div("d-inline-block text-truncate") {
|
div("d-inline-block text-truncate") {
|
||||||
if (obj.children.any { !it.key.body.startsWith("@") }) {
|
if (obj.children.any { !it.key.body.startsWith("@") }) {
|
||||||
span("tree-caret") {
|
span("tree-caret") {
|
||||||
attrs {
|
attrs {
|
||||||
if (state.expanded) {
|
if (expanded) {
|
||||||
classes += "tree-caret-down"
|
classes += "tree-caret-down"
|
||||||
}
|
|
||||||
onClickFunction = onClick
|
|
||||||
}
|
}
|
||||||
|
onClickFunction = onClick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
treeLabel(token)
|
|
||||||
}
|
}
|
||||||
if (state.expanded) {
|
treeLabel(token)
|
||||||
ul("tree") {
|
}
|
||||||
obj.children.entries
|
if (expanded) {
|
||||||
.filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children
|
ul("tree") {
|
||||||
.sortedBy { (it.value as? VisualGroup)?.isEmpty ?: true }
|
obj.children.entries
|
||||||
.forEach { (childToken, child) ->
|
.filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children
|
||||||
li("tree-item") {
|
.sortedBy { (it.value as? VisualGroup)?.isEmpty ?: true }
|
||||||
child(ObjectTree::class) {
|
.forEach { (childToken, child) ->
|
||||||
attrs {
|
li("tree-item") {
|
||||||
name = props.name + childToken
|
child(ObjectTree) {
|
||||||
this.obj = child
|
attrs {
|
||||||
this.selected = props.selected
|
name = props.name + childToken
|
||||||
clickCallback = props.clickCallback
|
this.obj = child
|
||||||
}
|
this.selected = props.selected
|
||||||
|
clickCallback = props.clickCallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
div("d-inline-block text-truncate") {
|
|
||||||
span("tree-leaf") {}
|
|
||||||
treeLabel(token)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
div("d-inline-block text-truncate") {
|
||||||
|
span("tree-leaf") {}
|
||||||
|
treeLabel(token)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ObjectTree: FunctionalComponent<ObjectTreeProps> = functionalComponent { props ->
|
||||||
|
objectTree(props)
|
||||||
|
}
|
||||||
|
|
||||||
fun Element.renderObjectTree(
|
fun Element.renderObjectTree(
|
||||||
visualObject: VisualObject,
|
visualObject: VisualObject,
|
||||||
clickCallback: (Name) -> Unit = {}
|
clickCallback: (Name) -> Unit = {}
|
||||||
) = render(this){
|
) = render(this) {
|
||||||
card("Object tree") {
|
card("Object tree") {
|
||||||
child(ObjectTree::class) {
|
child(ObjectTree) {
|
||||||
attrs {
|
attrs {
|
||||||
this.name = Name.EMPTY
|
this.name = Name.EMPTY
|
||||||
this.obj = visualObject
|
this.obj = visualObject
|
||||||
@ -117,8 +114,8 @@ fun RBuilder.objectTree(
|
|||||||
visualObject: VisualObject,
|
visualObject: VisualObject,
|
||||||
selected: Name? = null,
|
selected: Name? = null,
|
||||||
clickCallback: (Name) -> Unit = {}
|
clickCallback: (Name) -> Unit = {}
|
||||||
){
|
) {
|
||||||
child(ObjectTree::class) {
|
child(ObjectTree) {
|
||||||
attrs {
|
attrs {
|
||||||
this.name = Name.EMPTY
|
this.name = Name.EMPTY
|
||||||
this.obj = visualObject
|
this.obj = visualObject
|
||||||
|
Loading…
Reference in New Issue
Block a user