From 9c1373434ed91880759ba1561fc08b758ed2c489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Sat, 6 Feb 2021 10:00:20 +0100 Subject: [PATCH] [Editor] Make layer operations undoable --- .../command/model/map/CreateLayerCommand.kt | 23 +++++++++++++++ .../command/model/map/MoveLayerCommand.kt | 22 ++++++++++++++ .../command/model/map/RemoveLayerCommand.kt | 26 +++++++++++++++++ .../command/model/map/RenameLayerCommand.kt | 23 +++++++++++++++ .../base/editor/model/map/layer/Layer.kt | 2 +- .../base/editor/model/map/layer/TileLayer.kt | 8 +++-- .../base/editor/model/map/map/GameMap.kt | 29 ------------------- .../base/editor/view/map/MapLayersView.kt | 28 ++++++++++++++---- 8 files changed, 124 insertions(+), 37 deletions(-) create mode 100755 editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/CreateLayerCommand.kt create mode 100755 editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/MoveLayerCommand.kt create mode 100755 editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/RemoveLayerCommand.kt create mode 100755 editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/RenameLayerCommand.kt diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/CreateLayerCommand.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/CreateLayerCommand.kt new file mode 100755 index 00000000..545bf597 --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/CreateLayerCommand.kt @@ -0,0 +1,23 @@ +package com.bartlomiejpluta.base.editor.command.model.map + +import com.bartlomiejpluta.base.editor.command.model.base.Command +import com.bartlomiejpluta.base.editor.command.model.base.Undoable +import com.bartlomiejpluta.base.editor.model.map.layer.Layer +import com.bartlomiejpluta.base.editor.model.map.map.GameMap + +class CreateLayerCommand(private val map: GameMap, private val layer: Layer): Undoable, Command { + + override fun execute() { + map.layers += layer + } + + override fun undo() { + map.layers -= layer + } + + override fun redo() { + execute() + } + + override val commandName = "Create map layer" +} \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/MoveLayerCommand.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/MoveLayerCommand.kt new file mode 100755 index 00000000..c7c63acf --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/MoveLayerCommand.kt @@ -0,0 +1,22 @@ +package com.bartlomiejpluta.base.editor.command.model.map + +import com.bartlomiejpluta.base.editor.command.model.base.Command +import com.bartlomiejpluta.base.editor.command.model.base.Undoable +import com.bartlomiejpluta.base.editor.model.map.map.GameMap +import tornadofx.swap + +class MoveLayerCommand(private val map: GameMap, private val currentIndex: Int, private val newIndex: Int) : Undoable, Command { + override fun execute() { + map.layers.swap(currentIndex, newIndex) + } + + override fun undo() { + map.layers.swap(newIndex, currentIndex) + } + + override fun redo() { + execute() + } + + override val commandName = "Move layer" +} \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/RemoveLayerCommand.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/RemoveLayerCommand.kt new file mode 100755 index 00000000..bb499e9f --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/RemoveLayerCommand.kt @@ -0,0 +1,26 @@ +package com.bartlomiejpluta.base.editor.command.model.map + +import com.bartlomiejpluta.base.editor.command.model.base.Command +import com.bartlomiejpluta.base.editor.command.model.base.Undoable +import com.bartlomiejpluta.base.editor.model.map.layer.Layer +import com.bartlomiejpluta.base.editor.model.map.map.GameMap +import kotlin.math.min + +class RemoveLayerCommand(private val map: GameMap, private val layerIndex: Int) : Undoable, Command { + private var layer: Layer? = null + + override fun execute() { + layer = map.layers.removeAt(layerIndex) + } + + override fun undo() { + map.layers.add(layerIndex, layer) + layer = null + } + + override fun redo() { + execute() + } + + override val commandName = "Remove layer" +} \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/RenameLayerCommand.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/RenameLayerCommand.kt new file mode 100755 index 00000000..8759701e --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/command/model/map/RenameLayerCommand.kt @@ -0,0 +1,23 @@ +package com.bartlomiejpluta.base.editor.command.model.map + +import com.bartlomiejpluta.base.editor.command.model.base.Command +import com.bartlomiejpluta.base.editor.command.model.base.Undoable +import com.bartlomiejpluta.base.editor.model.map.layer.Layer + +class RenameLayerCommand(private val layer: Layer, private val newName: String) : Undoable, Command { + private val formerName = layer.name + + override fun execute() { + layer.name = newName + } + + override fun undo() { + layer.name = formerName + } + + override fun redo() { + execute() + } + + override val commandName = "Rename layer" +} \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/layer/Layer.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/layer/Layer.kt index 6ae4c33d..164c98e7 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/layer/Layer.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/layer/Layer.kt @@ -3,6 +3,6 @@ package com.bartlomiejpluta.base.editor.model.map.layer import javafx.beans.property.StringProperty interface Layer { - val name: String + var name: String val nameProperty: StringProperty } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/layer/TileLayer.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/layer/TileLayer.kt index b30718bd..e4d1c645 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/layer/TileLayer.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/layer/TileLayer.kt @@ -2,7 +2,7 @@ package com.bartlomiejpluta.base.editor.model.map.layer import com.bartlomiejpluta.base.editor.model.tileset.Tile import javafx.beans.property.SimpleStringProperty -import tornadofx.getValue +import tornadofx.* class TileLayer(name: String, val layer: Array>) : Layer { @@ -10,5 +10,9 @@ class TileLayer(name: String, val layer: Array>) : Layer { override val nameProperty = SimpleStringProperty(name) - override val name: String by nameProperty + override var name: String by nameProperty + + companion object { + fun empty(name: String, rows: Int ,columns: Int) = TileLayer(name, Array(rows) { Array(columns) { null } }) + } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/map/GameMap.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/map/GameMap.kt index 22ffd779..0a977f3e 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/map/GameMap.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/model/map/map/GameMap.kt @@ -1,7 +1,6 @@ package com.bartlomiejpluta.base.editor.model.map.map import com.bartlomiejpluta.base.editor.model.map.layer.Layer -import com.bartlomiejpluta.base.editor.model.map.layer.TileLayer import com.bartlomiejpluta.base.editor.model.tileset.TileSet import tornadofx.observableListOf @@ -12,32 +11,4 @@ class GameMap(val tileSet: TileSet, val rows: Int, val columns: Int) { val width = columns * tileSet.tileWidth val height = columns * tileSet.tileWidth - - fun createTileLayer(name: String, tile: Int) = createTileLayer(name).apply { - val layerId = layers.size - 1 - for (row in 0 until rows) { - for (column in 0 until columns) { - setTile(layerId, row, column, tile) - } - } - } - - fun createTileLayer(name: String, tileRow: Int, tileColumn: Int) = createTileLayer(name).apply { - val layerId = layers.size - 1 - for (row in 0 until rows) { - for (column in 0 until columns) { - setTile(layerId, row, column, tileRow, tileColumn) - } - } - } - - fun createTileLayer(name: String) = apply { layers.add(TileLayer(name, Array(rows) { Array(columns) { null } })) } - - fun setTile(layer: Int, row: Int, column: Int, tile: Int) = apply { - (layers[layer] as TileLayer).setTile(row, column, tileSet.getTile(tile)) - } - - fun setTile(layer: Int, row: Int, column: Int, tileRow: Int, tileColumn: Int) = apply { - (layers[layer] as TileLayer).setTile(row, column, tileSet.getTile(tileRow, tileColumn)) - } } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/map/MapLayersView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/map/MapLayersView.kt index fd78d174..4f452d8c 100755 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/map/MapLayersView.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/view/map/MapLayersView.kt @@ -1,9 +1,14 @@ package com.bartlomiejpluta.base.editor.view.map import com.bartlomiejpluta.base.editor.command.context.UndoableScope +import com.bartlomiejpluta.base.editor.command.model.map.CreateLayerCommand +import com.bartlomiejpluta.base.editor.command.model.map.MoveLayerCommand +import com.bartlomiejpluta.base.editor.command.model.map.RemoveLayerCommand +import com.bartlomiejpluta.base.editor.command.model.map.RenameLayerCommand import com.bartlomiejpluta.base.editor.command.service.UndoRedoService import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent import com.bartlomiejpluta.base.editor.model.map.layer.Layer +import com.bartlomiejpluta.base.editor.model.map.layer.TileLayer import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM import javafx.scene.control.TableView import org.kordamp.ikonli.javafx.FontIcon @@ -17,7 +22,11 @@ class MapLayersView : View() { private val mapVM = find() private var layersPane = TableView(mapVM.layers).apply { - column("Layer Name", Layer::nameProperty).makeEditable() + column("Layer Name", Layer::nameProperty).makeEditable().setOnEditCommit { + val command = RenameLayerCommand(it.rowValue, it.newValue) + command.execute() + undoRedoService.push(command, scope) + } mapVM.selectedLayerProperty.bind(selectionModel.selectedIndexProperty()) } @@ -28,8 +37,11 @@ class MapLayersView : View() { bottom = toolbar { button(graphic = FontIcon("fa-plus")) { action { - mapVM.item.createTileLayer("Layer ${mapVM.layers.size + 1}") + val tileLayer = TileLayer.empty("Layer ${mapVM.layers.size + 1}", mapVM.rows, mapVM.columns) + val command = CreateLayerCommand(mapVM.item, tileLayer) + command.execute() layersPane.selectionModel.select(mapVM.layers.size - 1) + undoRedoService.push(command, scope) } } @@ -37,9 +49,11 @@ class MapLayersView : View() { enableWhen(mapVM.selectedLayerProperty.greaterThan(0)) action { val newIndex = mapVM.selectedLayer - 1 - mapVM.layers.swap(mapVM.selectedLayer, newIndex) + val command = MoveLayerCommand(mapVM.item, mapVM.selectedLayer, newIndex) + command.execute() layersPane.selectionModel.select(newIndex) fire(RedrawMapRequestEvent) + undoRedoService.push(command, scope) } } @@ -50,9 +64,11 @@ class MapLayersView : View() { ) action { val newIndex = mapVM.selectedLayer + 1 - mapVM.layers.swap(mapVM.selectedLayer, newIndex) + val command = MoveLayerCommand(mapVM.item, mapVM.selectedLayer, newIndex) + command.execute() layersPane.selectionModel.select(newIndex) fire(RedrawMapRequestEvent) + undoRedoService.push(command, scope) } } @@ -60,13 +76,15 @@ class MapLayersView : View() { enableWhen(mapVM.selectedLayerProperty.greaterThanOrEqualTo(0)) action { var index = mapVM.selectedLayer - mapVM.layers.removeAt(index) + val command = RemoveLayerCommand(mapVM.item, index) + command.execute() if (--index >= 0) { layersPane.selectionModel.select(index) } fire(RedrawMapRequestEvent) + undoRedoService.push(command, scope) } } }