[Editor] Add icons to layer list

This commit is contained in:
2021-02-15 08:29:38 +01:00
parent af54a7bd81
commit 27ee72713a
3 changed files with 65 additions and 8 deletions

View File

@@ -1,6 +1,8 @@
package com.bartlomiejpluta.base.editor.map.model.layer
import javafx.beans.Observable
import javafx.beans.property.StringProperty
import javafx.util.Callback
interface Layer {
var name: String
@@ -9,4 +11,8 @@ interface Layer {
fun resize(rows: Int, columns: Int)
fun clone(): Layer
companion object {
fun extractor() = Callback<Layer, Array<Observable>> { arrayOf(it.nameProperty) }
}
}

View File

@@ -6,6 +6,7 @@ import javafx.beans.property.ReadOnlyStringWrapper
import javafx.beans.property.SimpleDoubleProperty
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleStringProperty
import javafx.collections.FXCollections
import tornadofx.getValue
import tornadofx.observableListOf
import tornadofx.setValue
@@ -15,7 +16,7 @@ class GameMap(val tileSet: TileSet) {
val uidProperty = SimpleStringProperty()
var uid by uidProperty
val layers = observableListOf<Layer>()
val layers = FXCollections.observableArrayList(Layer.extractor())
val tileWidth = tileSet.tileWidth.toDouble()
val tileHeight = tileSet.tileHeight.toDouble()

View File

@@ -11,7 +11,11 @@ import com.bartlomiejpluta.base.editor.map.model.layer.Layer
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import javafx.scene.control.TableView
import javafx.beans.value.ObservableValue
import javafx.scene.control.ListCell
import javafx.scene.control.ListView
import javafx.scene.control.cell.TextFieldListCell
import javafx.util.StringConverter
import org.kordamp.ikonli.javafx.FontIcon
import tornadofx.*
@@ -24,11 +28,16 @@ class MapLayersView : View() {
private val editorStateVM = find<EditorStateVM>()
private var layersPane = TableView(mapVM.layers).apply {
column("Layer Name", Layer::nameProperty).makeEditable().setOnEditCommit {
val command = RenameLayerCommand(it.rowValue, it.newValue)
command.execute()
undoRedoService.push(command, scope)
private var layersPane = ListView(mapVM.layers).apply {
isEditable = true
setCellFactory {
LayerListViewItem { layer, name ->
RenameLayerCommand(layer, name).let {
it.execute()
undoRedoService.push(it, scope)
}
}
}
editorStateVM.selectedLayerProperty.bind(selectionModel.selectedIndexProperty())
@@ -92,4 +101,45 @@ class MapLayersView : View() {
}
}
}
}
private class LayerListViewItemConverter(
private val cell: ListCell<Layer>,
private val onUpdate: (layer: Layer, name: String) -> Unit
) : StringConverter<Layer>() {
override fun toString(layer: Layer?) = layer?.name ?: ""
// Disclaimer:
// Because of the fact that we want to support undo/redo mechanism
// the actual update must be done from the execute() method of the Command object
// so that the Command object has access to the actual as well as the new value of layer name.
// That's why we are running the submission logic in the converter.
override fun fromString(string: String?): Layer = cell.item.apply {
string?.takeIf { it != name }?.let {
onUpdate(this, it)
}
}
}
private class LayerListViewItem(onUpdate: (layer: Layer, name: String) -> Unit) : TextFieldListCell<Layer>() {
init {
converter = LayerListViewItemConverter(this, onUpdate)
}
override fun updateItem(item: Layer?, empty: Boolean) {
super.updateItem(item, empty)
if (empty || item == null) {
text = null
graphic = null
return
}
text = item.name
graphic = when (item) {
is TileLayer -> FontIcon("fa-th")
else -> throw IllegalStateException("Unknown layer type")
}
}
}
}