[Editor] Add support for object and image layers in editor

This commit is contained in:
2021-02-17 08:13:55 +01:00
parent 0003e5b42a
commit 78e11029e5
14 changed files with 209 additions and 75 deletions

View File

@@ -2,9 +2,9 @@ package com.bartlomiejpluta.base.editor.map.canvas
import com.bartlomiejpluta.base.editor.map.model.layer.Layer import com.bartlomiejpluta.base.editor.map.model.layer.Layer
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
import com.bartlomiejpluta.base.editor.render.model.Renderable
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import com.bartlomiejpluta.base.editor.render.model.Renderable
import javafx.scene.canvas.GraphicsContext import javafx.scene.canvas.GraphicsContext
import javafx.scene.paint.Color import javafx.scene.paint.Color
@@ -27,7 +27,7 @@ class MapCanvas(val map: GameMapVM, private val editorStateVM: EditorStateVM, pr
} }
private fun renderSelectedLayer(gc: GraphicsContext) { private fun renderSelectedLayer(gc: GraphicsContext) {
map.layers.getOrNull(editorStateVM.selectedLayer) ?. let { dispatchLayerRender(gc, it) } map.layers.getOrNull(editorStateVM.selectedLayerIndex)?.let { dispatchLayerRender(gc, it) }
} }
private fun renderCover(gc: GraphicsContext) { private fun renderCover(gc: GraphicsContext) {
@@ -40,7 +40,7 @@ class MapCanvas(val map: GameMapVM, private val editorStateVM: EditorStateVM, pr
} }
private fun renderUnderlyingLayers(gc: GraphicsContext) { private fun renderUnderlyingLayers(gc: GraphicsContext) {
for(layer in map.layers.dropLast(if(editorStateVM.selectedLayer < 0) 0 else map.layers.size - editorStateVM.selectedLayer)) { for (layer in map.layers.dropLast(if (editorStateVM.selectedLayerIndex < 0) 0 else map.layers.size - editorStateVM.selectedLayerIndex)) {
dispatchLayerRender(gc, layer) dispatchLayerRender(gc, layer)
} }
} }

View File

@@ -1,57 +1,46 @@
package com.bartlomiejpluta.base.editor.map.canvas package com.bartlomiejpluta.base.editor.map.canvas
import com.bartlomiejpluta.base.editor.tileset.model.Tile import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
import com.bartlomiejpluta.base.editor.render.input.MapMouseEvent
import com.bartlomiejpluta.base.editor.render.input.MapMouseEventHandler
import com.bartlomiejpluta.base.editor.render.model.Renderable
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import com.bartlomiejpluta.base.editor.render.input.MapMouseEvent
import com.bartlomiejpluta.base.editor.render.input.MapMouseEventHandler
import com.bartlomiejpluta.base.editor.render.model.Renderable
import javafx.scene.canvas.GraphicsContext import javafx.scene.canvas.GraphicsContext
import javafx.scene.input.MouseButton import javafx.scene.input.MouseButton
import javafx.scene.input.MouseEvent import javafx.scene.input.MouseEvent
import javafx.scene.paint.Color
class MapPainter( class MapPainter(
private val mapVM: GameMapVM, private val mapVM: GameMapVM,
private val brushVM: BrushVM, private val brushVM: BrushVM,
private val editorStateVM: EditorStateVM, private val editorStateVM: EditorStateVM,
private val paintingCallback: (MapPaintingTrace) -> Unit private val paintingCallback: (PaintingTrace) -> Unit
) : Renderable, MapMouseEventHandler { ) : Renderable, MapMouseEventHandler {
private val tileWidth = mapVM.tileSet.tileWidth.toDouble() private val tileWidth = mapVM.tileSet.tileWidth.toDouble()
private val tileHeight = mapVM.tileSet.tileHeight.toDouble() private val tileHeight = mapVM.tileSet.tileHeight.toDouble()
private var currentTrace: MapPaintingTrace? = null private var cursor: PaintingCursor? = null
private var currentTrace: PaintingTrace? = null
init {
editorStateVM.selectedLayerProperty.addListener { _, _, layer ->
cursor = when (layer) {
is TileLayer -> TilePaintingCursor(tileWidth, tileHeight, editorStateVM, brushVM)
else -> null
}
}
}
override fun render(gc: GraphicsContext) { override fun render(gc: GraphicsContext) {
val alpha = gc.globalAlpha val alpha = gc.globalAlpha
gc.globalAlpha = 0.4 gc.globalAlpha = 0.4
brushVM.forEach { row, column, centerRow, centerColumn, tile -> cursor?.render(gc)
renderTile(gc, row, column, centerRow, centerColumn, tile)
}
gc.globalAlpha = alpha gc.globalAlpha = alpha
} }
private fun renderTile(gc: GraphicsContext, row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) {
val x = tileWidth * (editorStateVM.cursorColumn - centerColumn + column)
val y = tileHeight * (editorStateVM.cursorRow - centerRow + row)
when {
tile != null -> renderPaintingBrushTile(gc, tile, x, y)
else -> renderEraserTile(gc, x, y)
}
}
private fun renderPaintingBrushTile(gc: GraphicsContext, tile: Tile, x: Double, y: Double) =
gc.drawImage(tile.image, x, y)
private fun renderEraserTile(gc: GraphicsContext, x: Double, y: Double) {
gc.fill = Color.WHITE
gc.fillRect(x, y, tileWidth, tileHeight)
}
override fun handleMouseInput(event: MapMouseEvent) { override fun handleMouseInput(event: MapMouseEvent) {
editorStateVM.cursorRowProperty.value = event.row editorStateVM.cursorRowProperty.value = event.row
editorStateVM.cursorColumnProperty.value = event.column editorStateVM.cursorColumnProperty.value = event.column
@@ -64,28 +53,24 @@ class MapPainter(
} }
private fun beginTrace(event: MapMouseEvent) { private fun beginTrace(event: MapMouseEvent) {
if (event.button == MouseButton.PRIMARY && editorStateVM.selectedLayer >= 0) { if (event.button == MouseButton.PRIMARY && editorStateVM.selectedLayerIndex >= 0) {
currentTrace = MapPaintingTrace(mapVM, "Paint trace").apply { currentTrace = when (editorStateVM.selectedLayer) {
brushVM.forEach { row, column, centerRow, centerColumn, tile -> is TileLayer -> TilePaintingTrace(mapVM, "Paint trace")
paint(editorStateVM.selectedLayer, editorStateVM.cursorRow - centerRow + row, editorStateVM.cursorColumn - centerColumn + column, tile) else -> null
} }?.apply { beginTrace(editorStateVM, brushVM) }
}
} }
} }
private fun proceedTrace(event: MapMouseEvent) { private fun proceedTrace(event: MapMouseEvent) {
if (event.button == MouseButton.PRIMARY) { if (event.button == MouseButton.PRIMARY) {
currentTrace?.apply { currentTrace?.proceedTrace(editorStateVM, brushVM)
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
paint(editorStateVM.selectedLayer, editorStateVM.cursorRow - centerRow + row, editorStateVM.cursorColumn - centerColumn + column, tile)
}
}
} }
} }
private fun commitTrace(event: MapMouseEvent) { private fun commitTrace(event: MapMouseEvent) {
if (event.button == MouseButton.PRIMARY) { if (event.button == MouseButton.PRIMARY) {
currentTrace?.let { currentTrace?.let {
it.commitTrace(editorStateVM, brushVM)
paintingCallback(it) paintingCallback(it)
currentTrace = null currentTrace = null
} }

View File

@@ -0,0 +1,5 @@
package com.bartlomiejpluta.base.editor.map.canvas
import com.bartlomiejpluta.base.editor.render.model.Renderable
interface PaintingCursor : Renderable

View File

@@ -0,0 +1,11 @@
package com.bartlomiejpluta.base.editor.map.canvas
import com.bartlomiejpluta.base.editor.command.model.base.Undoable
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
interface PaintingTrace : Undoable {
fun beginTrace(editorStateVM: EditorStateVM, brushVM: BrushVM)
fun proceedTrace(editorStateVM: EditorStateVM, brushVM: BrushVM)
fun commitTrace(editorStateVM: EditorStateVM, brushVM: BrushVM)
}

View File

@@ -0,0 +1,39 @@
package com.bartlomiejpluta.base.editor.map.canvas
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
import com.bartlomiejpluta.base.editor.tileset.model.Tile
import javafx.scene.canvas.GraphicsContext
import javafx.scene.paint.Color
class TilePaintingCursor(
private val tileWidth: Double,
private val tileHeight: Double,
private val editorStateVM: EditorStateVM,
private val brushVM: BrushVM
) : PaintingCursor {
override fun render(gc: GraphicsContext) {
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
renderTile(gc, row, column, centerRow, centerColumn, tile)
}
}
private fun renderTile(gc: GraphicsContext, row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) {
val x = tileWidth * (editorStateVM.cursorColumn - centerColumn + column)
val y = tileHeight * (editorStateVM.cursorRow - centerRow + row)
when {
tile != null -> renderPaintingBrushTile(gc, tile, x, y)
else -> renderEraserTile(gc, x, y)
}
}
private fun renderPaintingBrushTile(gc: GraphicsContext, tile: Tile, x: Double, y: Double) =
gc.drawImage(tile.image, x, y)
private fun renderEraserTile(gc: GraphicsContext, x: Double, y: Double) {
gc.fill = Color.WHITE
gc.fillRect(x, y, tileWidth, tileHeight)
}
}

View File

@@ -1,15 +1,16 @@
package com.bartlomiejpluta.base.editor.map.canvas package com.bartlomiejpluta.base.editor.map.canvas
import com.bartlomiejpluta.base.editor.command.model.base.Undoable
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
import com.bartlomiejpluta.base.editor.tileset.model.Tile import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import com.bartlomiejpluta.base.editor.tileset.model.Tile
data class MapPaintingTrace(val map: GameMapVM, override val commandName: String) : Undoable { data class TilePaintingTrace(val map: GameMapVM, override val commandName: String) : PaintingTrace {
private val trace = mutableListOf<Element>() private val trace = mutableListOf<Element>()
fun paint(layerIndex: Int, row: Int, column: Int, tile: Tile?) { private fun paint(layerIndex: Int, row: Int, column: Int, tile: Tile?) {
if (row >= map.rows || column >= map.columns || row < 0 || column < 0 || layerIndex < 0) { if (row >= map.rows || column >= map.columns || row < 0 || column < 0 || layerIndex < 0) {
return return
} }
@@ -32,6 +33,32 @@ data class MapPaintingTrace(val map: GameMapVM, override val commandName: String
} }
} }
override fun beginTrace(editorStateVM: EditorStateVM, brushVM: BrushVM) {
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
paint(
editorStateVM.selectedLayerIndex,
editorStateVM.cursorRow - centerRow + row,
editorStateVM.cursorColumn - centerColumn + column,
tile
)
}
}
override fun proceedTrace(editorStateVM: EditorStateVM, brushVM: BrushVM) {
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
paint(
editorStateVM.selectedLayerIndex,
editorStateVM.cursorRow - centerRow + row,
editorStateVM.cursorColumn - centerColumn + column,
tile
)
}
}
override fun commitTrace(editorStateVM: EditorStateVM, brushVM: BrushVM) {
}
override fun undo() { override fun undo() {
trace.forEach { trace.forEach {
(map.layers[it.layerIndex] as TileLayer).layer[it.row][it.column] = it.formerTile (map.layers[it.layerIndex] as TileLayer).layer[it.row][it.column] = it.formerTile

View File

@@ -2,11 +2,11 @@ package com.bartlomiejpluta.base.editor.map.component
import com.bartlomiejpluta.base.editor.map.canvas.MapCanvas import com.bartlomiejpluta.base.editor.map.canvas.MapCanvas
import com.bartlomiejpluta.base.editor.map.canvas.MapPainter import com.bartlomiejpluta.base.editor.map.canvas.MapPainter
import com.bartlomiejpluta.base.editor.map.canvas.MapPaintingTrace import com.bartlomiejpluta.base.editor.map.canvas.PaintingTrace
import com.bartlomiejpluta.base.editor.render.input.MapMouseEvent
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import com.bartlomiejpluta.base.editor.render.input.MapMouseEvent
import javafx.event.EventHandler import javafx.event.EventHandler
import javafx.scene.canvas.Canvas import javafx.scene.canvas.Canvas
import javafx.scene.input.MouseEvent import javafx.scene.input.MouseEvent
@@ -15,7 +15,7 @@ class MapPane(
private val mapVM: GameMapVM, private val mapVM: GameMapVM,
brushVM: BrushVM, brushVM: BrushVM,
editorStateVM: EditorStateVM, editorStateVM: EditorStateVM,
paintingCallback: (MapPaintingTrace) -> Unit paintingCallback: (PaintingTrace) -> Unit
) : Canvas(), EventHandler<MouseEvent> { ) : Canvas(), EventHandler<MouseEvent> {
private val painter = MapPainter(mapVM, brushVM, editorStateVM, paintingCallback) private val painter = MapPainter(mapVM, brushVM, editorStateVM, paintingCallback)
private val mapCanvas = MapCanvas(mapVM, editorStateVM, painter) private val mapCanvas = MapCanvas(mapVM, editorStateVM, painter)
@@ -33,7 +33,7 @@ class MapPane(
mapVM.item.columnsProperty.addListener { _, _, _ -> render() } mapVM.item.columnsProperty.addListener { _, _, _ -> render() }
editorStateVM.showGridProperty.addListener { _, _, _ -> render() } editorStateVM.showGridProperty.addListener { _, _, _ -> render() }
editorStateVM.selectedLayerProperty.addListener { _, _, _ -> render() } editorStateVM.selectedLayerIndexProperty.addListener { _, _, _ -> render() }
editorStateVM.coverUnderlyingLayersProperty.addListener { _, _, _ -> render() } editorStateVM.coverUnderlyingLayersProperty.addListener { _, _, _ -> render() }
render() render()

View File

@@ -0,0 +1,15 @@
package com.bartlomiejpluta.base.editor.map.model.layer
import javafx.beans.property.SimpleStringProperty
import tornadofx.getValue
import tornadofx.setValue
class ImageLayer(name: String) : Layer {
override val nameProperty = SimpleStringProperty(name)
override fun resize(rows: Int, columns: Int) {
// We essentially need to do nothing
}
override var name by nameProperty
}

View File

@@ -10,8 +10,6 @@ interface Layer {
fun resize(rows: Int, columns: Int) fun resize(rows: Int, columns: Int)
fun clone(): Layer
companion object { companion object {
fun extractor() = Callback<Layer, Array<Observable>> { arrayOf(it.nameProperty) } fun extractor() = Callback<Layer, Array<Observable>> { arrayOf(it.nameProperty) }
} }

View File

@@ -0,0 +1,15 @@
package com.bartlomiejpluta.base.editor.map.model.layer
import javafx.beans.property.SimpleStringProperty
import tornadofx.getValue
import tornadofx.setValue
class ObjectLayer(name: String) : Layer {
override val nameProperty = SimpleStringProperty(name)
override fun resize(rows: Int, columns: Int) {
// We essentially need to do nothing
}
override var name by nameProperty
}

View File

@@ -24,8 +24,4 @@ class TileLayer(
} }
} }
} }
override fun clone() = TileLayer(name, 0, 0).apply {
layer = this@TileLayer.layer
}
} }

View File

@@ -1,19 +1,29 @@
package com.bartlomiejpluta.base.editor.map.view.editor package com.bartlomiejpluta.base.editor.map.view.editor
import com.bartlomiejpluta.base.editor.command.context.UndoableScope import com.bartlomiejpluta.base.editor.command.context.UndoableScope
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
import com.bartlomiejpluta.base.editor.tileset.view.editor.TileSetView import com.bartlomiejpluta.base.editor.tileset.view.editor.TileSetView
import javafx.beans.binding.Bindings
import tornadofx.* import tornadofx.*
class MapFragment : Fragment() { class MapFragment : Fragment() {
override val scope = super.scope as UndoableScope override val scope = super.scope as UndoableScope
private val editorStateVM = find<EditorStateVM>()
private val mapView = find<MapView>() private val mapView = find<MapView>()
private val layersView = find<MapLayersView>() private val layersView = find<MapLayersView>()
private val tileSetView = find<TileSetView>() private val tileSetView = find<TileSetView>()
private val toolbarView = find<MapToolbarView>() private val toolbarView = find<MapToolbarView>()
private val statusBarView = find<MapStatusBarView>() private val statusBarView = find<MapStatusBarView>()
private val isTileLayerSelected = Bindings.createBooleanBinding(
{ editorStateVM.selectedLayer is TileLayer },
editorStateVM.selectedLayerProperty
)
override val root = borderpane { override val root = borderpane {
top = toolbarView.root top = toolbarView.root
@@ -25,6 +35,8 @@ class MapFragment : Fragment() {
} }
item("Tile Set", expanded = true) { item("Tile Set", expanded = true) {
enableWhen(isTileLayerSelected)
this += tileSetView.root.apply { this += tileSetView.root.apply {
maxHeightProperty().bind(this@item.heightProperty()) maxHeightProperty().bind(this@item.heightProperty())
} }

View File

@@ -7,11 +7,12 @@ import com.bartlomiejpluta.base.editor.command.model.map.RemoveLayerCommand
import com.bartlomiejpluta.base.editor.command.model.map.RenameLayerCommand 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.map.model.layer.ImageLayer
import com.bartlomiejpluta.base.editor.map.model.layer.Layer import com.bartlomiejpluta.base.editor.map.model.layer.Layer
import com.bartlomiejpluta.base.editor.map.model.layer.ObjectLayer
import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer import com.bartlomiejpluta.base.editor.map.model.layer.TileLayer
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import javafx.beans.value.ObservableValue
import javafx.scene.control.ListCell import javafx.scene.control.ListCell
import javafx.scene.control.ListView import javafx.scene.control.ListView
import javafx.scene.control.cell.TextFieldListCell import javafx.scene.control.cell.TextFieldListCell
@@ -40,28 +41,51 @@ class MapLayersView : View() {
} }
} }
editorStateVM.selectedLayerProperty.bind(selectionModel.selectedIndexProperty()) editorStateVM.selectedLayerIndexProperty.bind(selectionModel.selectedIndexProperty())
editorStateVM.selectedLayerProperty.bind(selectionModel.selectedItemProperty())
} }
override val root = borderpane { override val root = borderpane {
center = layersPane center = layersPane
bottom = toolbar { bottom = toolbar {
button(graphic = FontIcon("fa-plus")) { menubutton(graphic = FontIcon("fa-plus")) {
action { item("Tile Layer", graphic = FontIcon("fa-th")) {
val tileLayer = TileLayer("Layer ${mapVM.layers.size + 1}", mapVM.rows, mapVM.columns) action {
val command = CreateLayerCommand(mapVM.item, tileLayer) val layer = TileLayer("Layer ${mapVM.layers.size + 1}", mapVM.rows, mapVM.columns)
command.execute() val command = CreateLayerCommand(mapVM.item, layer)
layersPane.selectionModel.select(mapVM.layers.size - 1) command.execute()
undoRedoService.push(command, scope) layersPane.selectionModel.select(mapVM.layers.size - 1)
undoRedoService.push(command, scope)
}
}
item("Object Layer", graphic = FontIcon("fa-cube")) {
action {
val layer = ObjectLayer("Layer ${mapVM.layers.size + 1}")
val command = CreateLayerCommand(mapVM.item, layer)
command.execute()
layersPane.selectionModel.select(mapVM.layers.size - 1)
undoRedoService.push(command, scope)
}
}
item("Image Layer", graphic = FontIcon("fa-image")) {
action {
val layer = ImageLayer("Layer ${mapVM.layers.size + 1}")
val command = CreateLayerCommand(mapVM.item, layer)
command.execute()
layersPane.selectionModel.select(mapVM.layers.size - 1)
undoRedoService.push(command, scope)
}
} }
} }
button(graphic = FontIcon("fa-chevron-up")) { button(graphic = FontIcon("fa-chevron-up")) {
enableWhen(editorStateVM.selectedLayerProperty.greaterThan(0)) enableWhen(editorStateVM.selectedLayerIndexProperty.greaterThan(0))
action { action {
val newIndex = editorStateVM.selectedLayer - 1 val newIndex = editorStateVM.selectedLayerIndex - 1
val command = MoveLayerCommand(mapVM.item, editorStateVM.selectedLayer, newIndex) val command = MoveLayerCommand(mapVM.item, editorStateVM.selectedLayerIndex, newIndex)
command.execute() command.execute()
layersPane.selectionModel.select(newIndex) layersPane.selectionModel.select(newIndex)
fire(RedrawMapRequestEvent) fire(RedrawMapRequestEvent)
@@ -71,12 +95,12 @@ class MapLayersView : View() {
button(graphic = FontIcon("fa-chevron-down")) { button(graphic = FontIcon("fa-chevron-down")) {
enableWhen( enableWhen(
editorStateVM.selectedLayerProperty.lessThan(mapVM.layers.sizeProperty().minus(1)) editorStateVM.selectedLayerIndexProperty.lessThan(mapVM.layers.sizeProperty().minus(1))
.and(editorStateVM.selectedLayerProperty.greaterThanOrEqualTo(0)) .and(editorStateVM.selectedLayerIndexProperty.greaterThanOrEqualTo(0))
) )
action { action {
val newIndex = editorStateVM.selectedLayer + 1 val newIndex = editorStateVM.selectedLayerIndex + 1
val command = MoveLayerCommand(mapVM.item, editorStateVM.selectedLayer, newIndex) val command = MoveLayerCommand(mapVM.item, editorStateVM.selectedLayerIndex, newIndex)
command.execute() command.execute()
layersPane.selectionModel.select(newIndex) layersPane.selectionModel.select(newIndex)
fire(RedrawMapRequestEvent) fire(RedrawMapRequestEvent)
@@ -85,9 +109,9 @@ class MapLayersView : View() {
} }
button(graphic = FontIcon("fa-trash")) { button(graphic = FontIcon("fa-trash")) {
enableWhen(editorStateVM.selectedLayerProperty.greaterThanOrEqualTo(0)) enableWhen(editorStateVM.selectedLayerIndexProperty.greaterThanOrEqualTo(0))
action { action {
var index = editorStateVM.selectedLayer var index = editorStateVM.selectedLayerIndex
val command = RemoveLayerCommand(mapVM.item, index) val command = RemoveLayerCommand(mapVM.item, index)
command.execute() command.execute()
@@ -138,6 +162,8 @@ class MapLayersView : View() {
graphic = when (item) { graphic = when (item) {
is TileLayer -> FontIcon("fa-th") is TileLayer -> FontIcon("fa-th")
is ObjectLayer -> FontIcon("fa-cube")
is ImageLayer -> FontIcon("fa-image")
else -> throw IllegalStateException("Unknown layer type") else -> throw IllegalStateException("Unknown layer type")
} }
} }

View File

@@ -1,14 +1,19 @@
package com.bartlomiejpluta.base.editor.map.viewmodel package com.bartlomiejpluta.base.editor.map.viewmodel
import com.bartlomiejpluta.base.editor.map.model.layer.Layer
import javafx.beans.property.SimpleBooleanProperty import javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleDoubleProperty import javafx.beans.property.SimpleDoubleProperty
import javafx.beans.property.SimpleIntegerProperty import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleObjectProperty
import tornadofx.ViewModel import tornadofx.ViewModel
import tornadofx.getValue import tornadofx.getValue
import tornadofx.setValue import tornadofx.setValue
class EditorStateVM : ViewModel() { class EditorStateVM : ViewModel() {
val selectedLayerProperty = SimpleIntegerProperty(0) val selectedLayerIndexProperty = SimpleIntegerProperty(0)
var selectedLayerIndex by selectedLayerIndexProperty
val selectedLayerProperty = SimpleObjectProperty<Layer>()
var selectedLayer by selectedLayerProperty var selectedLayer by selectedLayerProperty
val showGridProperty = SimpleBooleanProperty(true) val showGridProperty = SimpleBooleanProperty(true)