Fix FX ValueChooser crash

This commit is contained in:
Alexander Nozik 2021-07-22 20:11:14 +03:00
parent e50e266f94
commit a0d62c65d7
9 changed files with 39 additions and 38 deletions

View File

@ -22,7 +22,6 @@ dependencies{
implementation(npm("@jetbrains/icons", "3.14.1")) implementation(npm("@jetbrains/icons", "3.14.1"))
implementation(npm("@jetbrains/ring-ui", "4.0.7")) implementation(npm("@jetbrains/ring-ui", "4.0.7"))
implementation(npm("core-js","3.12.1"))
implementation(npm("file-saver", "2.0.2")) implementation(npm("file-saver", "2.0.2"))
compileOnly(npm("url-loader","4.1.1")) compileOnly(npm("url-loader","4.1.1"))
compileOnly(npm("postcss-loader","5.2.0")) compileOnly(npm("postcss-loader","5.2.0"))

View File

@ -15,7 +15,7 @@ import space.kscience.dataforge.names.asName
import space.kscience.dataforge.values.* import space.kscience.dataforge.values.*
import tornadofx.* import tornadofx.*
class TextValueChooser : ValueChooserBase<TextField>() { public class TextValueChooser : ValueChooserBase<TextField>() {
private val displayText: String private val displayText: String
get() = currentValue().let { get() = currentValue().let {

View File

@ -14,7 +14,6 @@ import space.kscience.dataforge.meta.descriptors.ValueDescriptor
import space.kscience.dataforge.misc.Named import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.misc.Type import space.kscience.dataforge.misc.Type
import space.kscience.dataforge.names.toName import space.kscience.dataforge.names.toName
import space.kscience.dataforge.provider.provideByType
import space.kscience.dataforge.values.Null import space.kscience.dataforge.values.Null
import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.Value
import space.kscience.visionforge.widget import space.kscience.visionforge.widget
@ -63,7 +62,7 @@ public interface ValueChooser {
public fun setCallback(callback: ValueCallback) public fun setCallback(callback: ValueCallback)
@Type("space.kscience.dataforge.vis.fx.valueChooserFactory") @Type("space.kscience..fx.valueChooserFactory")
public interface Factory : Named { public interface Factory : Named {
public operator fun invoke(meta: Meta = Meta.EMPTY): ValueChooser public operator fun invoke(meta: Meta = Meta.EMPTY): ValueChooser
} }
@ -75,7 +74,7 @@ public interface ValueChooser {
TextValueChooser.name -> TextValueChooser TextValueChooser.name -> TextValueChooser
ColorValueChooser.name -> ColorValueChooser ColorValueChooser.name -> ColorValueChooser
ComboBoxValueChooser.name -> ComboBoxValueChooser ComboBoxValueChooser.name -> ComboBoxValueChooser
else -> context.provideByType(type)//Search for additional factories in the plugin else -> null//context.provideByType(type)//Search for additional factories in the plugin
} }
} }
@ -101,7 +100,7 @@ public interface ValueChooser {
} }
} }
fun build( public fun build(
context: Context, context: Context,
value: ObservableValue<Value?>, value: ObservableValue<Value?>,
descriptor: ValueDescriptor? = null, descriptor: ValueDescriptor? = null,

View File

@ -18,16 +18,18 @@ import tornadofx.*
* *
* @author Alexander Nozik * @author Alexander Nozik
*/ */
abstract class ValueChooserBase<out T : Node> : ValueChooser { public abstract class ValueChooserBase<out T : Node> : ValueChooser {
override val node by lazy { buildNode() } override val node: T by lazy { buildNode() }
final override val valueProperty = SimpleObjectProperty<Value>(Null) final override val valueProperty: SimpleObjectProperty<Value> =
final override val descriptorProperty = SimpleObjectProperty<ValueDescriptor>() SimpleObjectProperty<Value>(Null)
final override val descriptorProperty: SimpleObjectProperty<ValueDescriptor> =
SimpleObjectProperty<ValueDescriptor>()
override var descriptor: ValueDescriptor? by descriptorProperty override var descriptor: ValueDescriptor? by descriptorProperty
override var value: Value? by valueProperty override var value: Value? by valueProperty
fun resetValue() { public fun resetValue() {
setDisplayValue(currentValue()) setDisplayValue(currentValue())
} }

View File

@ -13,13 +13,13 @@ import space.kscience.dataforge.meta.update
import space.kscience.visionforge.* import space.kscience.visionforge.*
import tornadofx.* import tornadofx.*
class VisualObjectEditorFragment(val selector: (Vision) -> Meta) : Fragment() { public class VisualObjectEditorFragment(public val selector: (Vision) -> Meta) : Fragment() {
val itemProperty = SimpleObjectProperty<Vision>() public val itemProperty: SimpleObjectProperty<Vision> = SimpleObjectProperty<Vision>()
var item: Vision? by itemProperty public var item: Vision? by itemProperty
val descriptorProperty = SimpleObjectProperty<NodeDescriptor>() public val descriptorProperty: SimpleObjectProperty<NodeDescriptor> = SimpleObjectProperty<NodeDescriptor>()
constructor( public constructor(
item: Vision?, item: Vision?,
descriptor: NodeDescriptor?, descriptor: NodeDescriptor?,
selector: (Vision) -> MutableItemProvider = { it.allProperties() }, selector: (Vision) -> MutableItemProvider = { it.allProperties() },
@ -30,13 +30,13 @@ class VisualObjectEditorFragment(val selector: (Vision) -> Meta) : Fragment() {
private var currentConfig: Config? = null private var currentConfig: Config? = null
private val configProperty: Binding<Config?> = itemProperty.objectBinding { visualObject -> private val configProperty: Binding<Config?> = itemProperty.objectBinding { vision ->
if (visualObject == null) return@objectBinding null if (vision == null) return@objectBinding null
val meta = selector(visualObject) val meta = selector(vision)
val config = Config().apply { val config = Config().apply {
update(meta) update(meta)
onChange(this@VisualObjectEditorFragment) { key, _, after -> onChange(this@VisualObjectEditorFragment) { key, _, after ->
visualObject.setProperty(key, after) vision.setProperty(key, after)
} }
} }
//remember old config reference to cleanup listeners //remember old config reference to cleanup listeners
@ -51,7 +51,7 @@ class VisualObjectEditorFragment(val selector: (Vision) -> Meta) : Fragment() {
} }
} }
private val styleBoxProperty: Binding<Node?> = configProperty.objectBinding() { private val styleBoxProperty: Binding<Node?> = configProperty.objectBinding {
VBox().apply { VBox().apply {
item?.styles?.forEach { styleName -> item?.styles?.forEach { styleName ->
val styleMeta = item?.getStyle(styleName) val styleMeta = item?.getStyle(styleName)

View File

@ -3,6 +3,7 @@ package space.kscience.visionforge.editor
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.scene.control.SelectionMode import javafx.scene.control.SelectionMode
import javafx.scene.control.TreeItem import javafx.scene.control.TreeItem
import javafx.scene.layout.VBox
import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.VisionGroup
import tornadofx.* import tornadofx.*
@ -29,13 +30,13 @@ private fun toTreeItem(vision: Vision, title: String): TreeItem<Pair<String, Vis
} }
class VisualObjectTreeFragment : Fragment() { public class VisualObjectTreeFragment : Fragment() {
val itemProperty = SimpleObjectProperty<Vision>() public val itemProperty: SimpleObjectProperty<Vision> = SimpleObjectProperty<Vision>()
var item: Vision? by itemProperty public var item: Vision? by itemProperty
val selectedProperty = SimpleObjectProperty<Vision>() public val selectedProperty: SimpleObjectProperty<Vision> = SimpleObjectProperty<Vision>()
override val root = vbox { override val root: VBox = vbox {
titledpane("Object tree", collapsible = false) { titledpane("Object tree", collapsible = false) {
treeview<Pair<String, Vision>> { treeview<Pair<String, Vision>> {
cellFormat { cellFormat {
@ -47,7 +48,9 @@ class VisualObjectTreeFragment : Fragment() {
} }
} }
selectionModel.selectionMode = SelectionMode.SINGLE selectionModel.selectionMode = SelectionMode.SINGLE
val selectedValue = selectionModel.selectedItemProperty().objectBinding { it?.value?.second } val selectedValue = selectionModel.selectedItemProperty().objectBinding {
it?.value?.second
}
selectedProperty.bind(selectedValue) selectedProperty.bind(selectedValue)
} }
} }

View File

@ -23,7 +23,7 @@ import kotlin.collections.set
import kotlin.math.PI import kotlin.math.PI
import kotlin.reflect.KClass import kotlin.reflect.KClass
class FX3DPlugin : AbstractPlugin() { public class FX3DPlugin : AbstractPlugin() {
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
private val objectFactories = HashMap<KClass<out Solid>, FX3DFactory<*>>() private val objectFactories = HashMap<KClass<out Solid>, FX3DFactory<*>>()
@ -42,7 +42,7 @@ class FX3DPlugin : AbstractPlugin() {
as FX3DFactory<Solid>? as FX3DFactory<Solid>?
} }
fun buildNode(obj: Solid): Node { public fun buildNode(obj: Solid): Node {
val binding = VisualObjectFXBinding(this, obj) val binding = VisualObjectFXBinding(this, obj)
return when (obj) { return when (obj) {
is SolidReferenceGroup -> referenceFactory(obj, binding) is SolidReferenceGroup -> referenceFactory(obj, binding)
@ -149,7 +149,7 @@ public interface FX3DFactory<in T : Solid> {
public operator fun invoke(obj: T, binding: VisualObjectFXBinding): Node public operator fun invoke(obj: T, binding: VisualObjectFXBinding): Node
public companion object { public companion object {
public const val TYPE = "fx3DFactory" public const val TYPE: String = "fx3DFactory"
} }
} }

View File

@ -7,7 +7,7 @@ import space.kscience.visionforge.Vision
import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.onPropertyChange
import kotlin.reflect.KClass import kotlin.reflect.KClass
class FXReferenceFactory(val plugin: FX3DPlugin) : FX3DFactory<SolidReferenceGroup> { public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory<SolidReferenceGroup> {
override val type: KClass<in SolidReferenceGroup> get() = SolidReferenceGroup::class override val type: KClass<in SolidReferenceGroup> get() = SolidReferenceGroup::class
override fun invoke(obj: SolidReferenceGroup, binding: VisualObjectFXBinding): Node { override fun invoke(obj: SolidReferenceGroup, binding: VisualObjectFXBinding): Node {

View File

@ -14,7 +14,7 @@ import tornadofx.*
/** /**
* A caching binding collection for [Vision] properties * A caching binding collection for [Vision] properties
*/ */
public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vision) { public class VisualObjectFXBinding(private val fx: FX3DPlugin, public val obj: Vision) {
private val bindings = HashMap<Name, ObjectBinding<MetaItem?>>() private val bindings = HashMap<Name, ObjectBinding<MetaItem?>>()
init { init {
@ -33,15 +33,13 @@ public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vi
} }
} }
public operator fun get(key: Name): ObjectBinding<MetaItem?> { public operator fun get(key: Name): ObjectBinding<MetaItem?> = 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)
}
} }
} }
public operator fun get(key: String) = get(key.toName()) public operator fun get(key: String): ObjectBinding<TypedMetaItem<*>?> = get(key.toName())
} }
public fun ObjectBinding<MetaItem?>.value(): Binding<Value?> = objectBinding { it.value } public fun ObjectBinding<MetaItem?>.value(): Binding<Value?> = objectBinding { it.value }