[Editor] Improve Parameter<T> binding to backing properties
This commit is contained in:
@@ -12,17 +12,31 @@ abstract class Parameter<T>(
|
|||||||
private val autocommit: Boolean = false,
|
private val autocommit: Boolean = false,
|
||||||
private val onCommit: (oldValue: T, newValue: T, submit: () -> Unit) -> Unit = { _, _, submit -> submit() }
|
private val onCommit: (oldValue: T, newValue: T, submit: () -> Unit) -> Unit = { _, _, submit -> submit() }
|
||||||
) {
|
) {
|
||||||
|
private var other: Property<T>? = null
|
||||||
|
|
||||||
val keyProperty = ReadOnlyStringWrapper(key)
|
val keyProperty = ReadOnlyStringWrapper(key)
|
||||||
|
|
||||||
val key by keyProperty
|
val key by keyProperty
|
||||||
|
|
||||||
val editableProperty: BooleanProperty = SimpleBooleanProperty(editable)
|
val editableProperty: BooleanProperty = SimpleBooleanProperty(editable)
|
||||||
var editable by editableProperty
|
|
||||||
|
|
||||||
|
var editable by editableProperty
|
||||||
val valueProperty: ObjectProperty<T> = SimpleObjectProperty(initialValue)
|
val valueProperty: ObjectProperty<T> = SimpleObjectProperty(initialValue)
|
||||||
|
|
||||||
var value by valueProperty
|
var value by valueProperty
|
||||||
|
|
||||||
fun commit() = onCommit(value, editorValueProperty.value, if (autocommit) NOOP else this::submit)
|
fun commit() = onCommit(value, editorValueProperty.value, if (autocommit) NOOP else this::submit)
|
||||||
|
|
||||||
|
fun bindBidirectional(other: Property<T>) {
|
||||||
|
unbindBidirectional()
|
||||||
|
this.value = other.value
|
||||||
|
this.other = other.apply { bindBidirectional(valueProperty) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unbindBidirectional() {
|
||||||
|
this.other?.unbindBidirectional(valueProperty)
|
||||||
|
this.other = null
|
||||||
|
}
|
||||||
|
|
||||||
private fun submit() {
|
private fun submit() {
|
||||||
value = editorValueProperty.value
|
value = editorValueProperty.value
|
||||||
}
|
}
|
||||||
@@ -30,7 +44,17 @@ abstract class Parameter<T>(
|
|||||||
protected fun init() {
|
protected fun init() {
|
||||||
if (autocommit) {
|
if (autocommit) {
|
||||||
editorValueProperty.bindBidirectional(valueProperty)
|
editorValueProperty.bindBidirectional(valueProperty)
|
||||||
valueProperty.addListener { _, oldValue, newValue -> onCommit(oldValue, newValue, NOOP) }
|
valueProperty.addListener { _, oldValue, newValue ->
|
||||||
|
|
||||||
|
// Disclaimer:
|
||||||
|
// This ugly hack enforces the onCommit() listener to be fired, when
|
||||||
|
// `other` Property has been updated with current value.
|
||||||
|
// Without that hack, even if `other` is bidirectionally bound to `valueProperty`,
|
||||||
|
// it is updated right after the onCommit() listener, which is not very useful.
|
||||||
|
other?.value = newValue
|
||||||
|
|
||||||
|
onCommit(oldValue, newValue, NOOP)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
editorValueProperty.value = value
|
editorValueProperty.value = value
|
||||||
valueProperty.addListener { _, _, v -> editorValueProperty.value = v }
|
valueProperty.addListener { _, _, v -> editorValueProperty.value = v }
|
||||||
|
|||||||
@@ -9,10 +9,6 @@ import org.springframework.stereotype.Component
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
class ColorLayerParametersBinder : LayerParametersBinder<ColorLayer> {
|
class ColorLayerParametersBinder : LayerParametersBinder<ColorLayer> {
|
||||||
private var red: IntegerParameter? = null
|
|
||||||
private var green: IntegerParameter? = null
|
|
||||||
private var blue: IntegerParameter? = null
|
|
||||||
private var alpha: IntegerParameter? = null
|
|
||||||
|
|
||||||
override fun bind(
|
override fun bind(
|
||||||
layer: ColorLayer,
|
layer: ColorLayer,
|
||||||
@@ -21,24 +17,15 @@ class ColorLayerParametersBinder : LayerParametersBinder<ColorLayer> {
|
|||||||
onCommit: () -> Unit
|
onCommit: () -> Unit
|
||||||
) {
|
) {
|
||||||
val red = IntegerParameter("red", 100, 0, 100, autocommit = true) { _, _, _ -> onCommit() }
|
val red = IntegerParameter("red", 100, 0, 100, autocommit = true) { _, _, _ -> onCommit() }
|
||||||
.apply { valueProperty.bindBidirectional(layer.redProperty) }
|
|
||||||
|
|
||||||
val green = IntegerParameter("green", 100, 0, 100, autocommit = true) { _, _, _ -> onCommit() }
|
val green = IntegerParameter("green", 100, 0, 100, autocommit = true) { _, _, _ -> onCommit() }
|
||||||
.apply { valueProperty.bindBidirectional(layer.greenProperty) }
|
|
||||||
|
|
||||||
val blue = IntegerParameter("blue", 100, 0, 100, autocommit = true) { _, _, _ -> onCommit() }
|
val blue = IntegerParameter("blue", 100, 0, 100, autocommit = true) { _, _, _ -> onCommit() }
|
||||||
.apply { valueProperty.bindBidirectional(layer.blueProperty) }
|
|
||||||
|
|
||||||
val alpha = IntegerParameter("alpha", 100, 0, 100, autocommit = true) { _, _, _ -> onCommit() }
|
val alpha = IntegerParameter("alpha", 100, 0, 100, autocommit = true) { _, _, _ -> onCommit() }
|
||||||
.apply { valueProperty.bindBidirectional(layer.alphaProperty) }
|
|
||||||
|
red.bindBidirectional(layer.redProperty)
|
||||||
|
green.bindBidirectional(layer.greenProperty)
|
||||||
|
blue.bindBidirectional(layer.blueProperty)
|
||||||
|
alpha.bindBidirectional(layer.alphaProperty)
|
||||||
|
|
||||||
parameters.addAll(red, green, blue, alpha)
|
parameters.addAll(red, green, blue, alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun unbind(layer: ColorLayer, parameters: ObservableList<Parameter<*>>) {
|
|
||||||
red?.valueProperty?.unbindBidirectional(layer.redProperty)
|
|
||||||
green?.valueProperty?.unbindBidirectional(layer.greenProperty)
|
|
||||||
blue?.valueProperty?.unbindBidirectional(layer.blueProperty)
|
|
||||||
alpha?.valueProperty?.unbindBidirectional(layer.alphaProperty)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,6 @@ package com.bartlomiejpluta.base.editor.map.parameter.layer
|
|||||||
import com.bartlomiejpluta.base.editor.common.parameter.model.GraphicAssetParameter
|
import com.bartlomiejpluta.base.editor.common.parameter.model.GraphicAssetParameter
|
||||||
import com.bartlomiejpluta.base.editor.common.parameter.model.IntegerParameter
|
import com.bartlomiejpluta.base.editor.common.parameter.model.IntegerParameter
|
||||||
import com.bartlomiejpluta.base.editor.common.parameter.model.Parameter
|
import com.bartlomiejpluta.base.editor.common.parameter.model.Parameter
|
||||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAsset
|
|
||||||
import com.bartlomiejpluta.base.editor.map.model.layer.ImageLayer
|
import com.bartlomiejpluta.base.editor.map.model.layer.ImageLayer
|
||||||
import com.bartlomiejpluta.base.editor.project.model.Project
|
import com.bartlomiejpluta.base.editor.project.model.Project
|
||||||
import javafx.collections.ObservableList
|
import javafx.collections.ObservableList
|
||||||
@@ -11,8 +10,6 @@ import org.springframework.stereotype.Component
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
class ImageLayerParametersBinder : LayerParametersBinder<ImageLayer> {
|
class ImageLayerParametersBinder : LayerParametersBinder<ImageLayer> {
|
||||||
private var image: GraphicAssetParameter<ImageAsset>? = null
|
|
||||||
private var opacity: IntegerParameter? = null
|
|
||||||
|
|
||||||
override fun bind(
|
override fun bind(
|
||||||
layer: ImageLayer,
|
layer: ImageLayer,
|
||||||
@@ -20,20 +17,18 @@ class ImageLayerParametersBinder : LayerParametersBinder<ImageLayer> {
|
|||||||
project: Project,
|
project: Project,
|
||||||
onCommit: () -> Unit
|
onCommit: () -> Unit
|
||||||
) {
|
) {
|
||||||
image = GraphicAssetParameter("image", layer.imageAsset, true, project.images) { _, _, submit ->
|
val image = GraphicAssetParameter("image", layer.imageAsset, true, project.images) { _, _, submit ->
|
||||||
onCommit()
|
onCommit()
|
||||||
submit()
|
submit()
|
||||||
}.apply { valueProperty.bindBidirectional(layer.imageAssetProperty) }
|
}
|
||||||
|
|
||||||
opacity = IntegerParameter("opacity", 100, 0, 100, autocommit = true) { _, _, _ ->
|
val opacity = IntegerParameter("opacity", 100, 0, 100, autocommit = true) { _, _, _ ->
|
||||||
onCommit()
|
onCommit()
|
||||||
}.apply { valueProperty.bindBidirectional(layer.opacityProperty) }
|
}
|
||||||
|
|
||||||
|
image.bindBidirectional(layer.imageAssetProperty)
|
||||||
|
opacity.bindBidirectional(layer.opacityProperty)
|
||||||
|
|
||||||
parameters.addAll(image, opacity)
|
parameters.addAll(image, opacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun unbind(layer: ImageLayer, parameters: ObservableList<Parameter<*>>) {
|
|
||||||
image?.valueProperty?.unbindBidirectional(layer.imageAssetProperty)
|
|
||||||
opacity?.valueProperty?.unbindBidirectional(layer.opacityProperty)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,4 @@ import javafx.collections.ObservableList
|
|||||||
|
|
||||||
interface LayerParametersBinder<T : Layer> {
|
interface LayerParametersBinder<T : Layer> {
|
||||||
fun bind(layer: T, parameters: ObservableList<Parameter<*>>, project: Project, onCommit: () -> Unit)
|
fun bind(layer: T, parameters: ObservableList<Parameter<*>>, project: Project, onCommit: () -> Unit)
|
||||||
fun unbind(layer: T, parameters: ObservableList<Parameter<*>>)
|
|
||||||
}
|
}
|
||||||
@@ -24,17 +24,21 @@ class MapLayerParameters : View() {
|
|||||||
private val parameters = observableListOf<Parameter<*>>()
|
private val parameters = observableListOf<Parameter<*>>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
editorStateVM.selectedLayerProperty.addListener { _, previousLayer, layer ->
|
editorStateVM.selectedLayerProperty.addListener { _, _, layer ->
|
||||||
when (previousLayer) {
|
parameters.forEach(Parameter<*>::unbindBidirectional)
|
||||||
is ColorLayer -> colorLayerParametersBinder.unbind(previousLayer, parameters)
|
|
||||||
is ImageLayer -> imageLayerParametersBinder.unbind(previousLayer, parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
parameters.clear()
|
parameters.clear()
|
||||||
|
|
||||||
when (layer) {
|
when (layer) {
|
||||||
is ColorLayer -> colorLayerParametersBinder.bind(layer, parameters, projectContext.project!!) { fire(RedrawMapRequestEvent) }
|
is ColorLayer -> colorLayerParametersBinder.bind(layer, parameters, projectContext.project!!) {
|
||||||
is ImageLayer -> imageLayerParametersBinder.bind(layer, parameters, projectContext.project!!) { fire(RedrawMapRequestEvent) }
|
fire(
|
||||||
|
RedrawMapRequestEvent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is ImageLayer -> imageLayerParametersBinder.bind(layer, parameters, projectContext.project!!) {
|
||||||
|
fire(
|
||||||
|
RedrawMapRequestEvent
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user