[Editor] Make layer operations undoable
This commit is contained in:
@@ -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"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -3,6 +3,6 @@ package com.bartlomiejpluta.base.editor.model.map.layer
|
|||||||
import javafx.beans.property.StringProperty
|
import javafx.beans.property.StringProperty
|
||||||
|
|
||||||
interface Layer {
|
interface Layer {
|
||||||
val name: String
|
var name: String
|
||||||
val nameProperty: StringProperty
|
val nameProperty: StringProperty
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ package com.bartlomiejpluta.base.editor.model.map.layer
|
|||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.model.tileset.Tile
|
import com.bartlomiejpluta.base.editor.model.tileset.Tile
|
||||||
import javafx.beans.property.SimpleStringProperty
|
import javafx.beans.property.SimpleStringProperty
|
||||||
import tornadofx.getValue
|
import tornadofx.*
|
||||||
|
|
||||||
class TileLayer(name: String, val layer: Array<Array<Tile?>>) : Layer {
|
class TileLayer(name: String, val layer: Array<Array<Tile?>>) : Layer {
|
||||||
|
|
||||||
@@ -10,5 +10,9 @@ class TileLayer(name: String, val layer: Array<Array<Tile?>>) : Layer {
|
|||||||
|
|
||||||
override val nameProperty = SimpleStringProperty(name)
|
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 } })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.bartlomiejpluta.base.editor.model.map.map
|
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.Layer
|
||||||
import com.bartlomiejpluta.base.editor.model.map.layer.TileLayer
|
|
||||||
import com.bartlomiejpluta.base.editor.model.tileset.TileSet
|
import com.bartlomiejpluta.base.editor.model.tileset.TileSet
|
||||||
import tornadofx.observableListOf
|
import tornadofx.observableListOf
|
||||||
|
|
||||||
@@ -12,32 +11,4 @@ class GameMap(val tileSet: TileSet, val rows: Int, val columns: Int) {
|
|||||||
val width = columns * tileSet.tileWidth
|
val width = columns * tileSet.tileWidth
|
||||||
|
|
||||||
val height = 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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package com.bartlomiejpluta.base.editor.view.map
|
package com.bartlomiejpluta.base.editor.view.map
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
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.command.service.UndoRedoService
|
||||||
import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent
|
import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent
|
||||||
import com.bartlomiejpluta.base.editor.model.map.layer.Layer
|
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 com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
|
||||||
import javafx.scene.control.TableView
|
import javafx.scene.control.TableView
|
||||||
import org.kordamp.ikonli.javafx.FontIcon
|
import org.kordamp.ikonli.javafx.FontIcon
|
||||||
@@ -17,7 +22,11 @@ class MapLayersView : View() {
|
|||||||
private val mapVM = find<GameMapVM>()
|
private val mapVM = find<GameMapVM>()
|
||||||
|
|
||||||
private var layersPane = TableView(mapVM.layers).apply {
|
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())
|
mapVM.selectedLayerProperty.bind(selectionModel.selectedIndexProperty())
|
||||||
}
|
}
|
||||||
@@ -28,8 +37,11 @@ class MapLayersView : View() {
|
|||||||
bottom = toolbar {
|
bottom = toolbar {
|
||||||
button(graphic = FontIcon("fa-plus")) {
|
button(graphic = FontIcon("fa-plus")) {
|
||||||
action {
|
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)
|
layersPane.selectionModel.select(mapVM.layers.size - 1)
|
||||||
|
undoRedoService.push(command, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,9 +49,11 @@ class MapLayersView : View() {
|
|||||||
enableWhen(mapVM.selectedLayerProperty.greaterThan(0))
|
enableWhen(mapVM.selectedLayerProperty.greaterThan(0))
|
||||||
action {
|
action {
|
||||||
val newIndex = mapVM.selectedLayer - 1
|
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)
|
layersPane.selectionModel.select(newIndex)
|
||||||
fire(RedrawMapRequestEvent)
|
fire(RedrawMapRequestEvent)
|
||||||
|
undoRedoService.push(command, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,9 +64,11 @@ class MapLayersView : View() {
|
|||||||
)
|
)
|
||||||
action {
|
action {
|
||||||
val newIndex = mapVM.selectedLayer + 1
|
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)
|
layersPane.selectionModel.select(newIndex)
|
||||||
fire(RedrawMapRequestEvent)
|
fire(RedrawMapRequestEvent)
|
||||||
|
undoRedoService.push(command, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,13 +76,15 @@ class MapLayersView : View() {
|
|||||||
enableWhen(mapVM.selectedLayerProperty.greaterThanOrEqualTo(0))
|
enableWhen(mapVM.selectedLayerProperty.greaterThanOrEqualTo(0))
|
||||||
action {
|
action {
|
||||||
var index = mapVM.selectedLayer
|
var index = mapVM.selectedLayer
|
||||||
mapVM.layers.removeAt(index)
|
val command = RemoveLayerCommand(mapVM.item, index)
|
||||||
|
command.execute()
|
||||||
|
|
||||||
if (--index >= 0) {
|
if (--index >= 0) {
|
||||||
layersPane.selectionModel.select(index)
|
layersPane.selectionModel.select(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fire(RedrawMapRequestEvent)
|
fire(RedrawMapRequestEvent)
|
||||||
|
undoRedoService.push(command, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user