[Editor] Add support for object and image layers in editor
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.map.canvas
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.editor.render.model.Renderable
|
||||||
|
|
||||||
|
interface PaintingCursor : Renderable
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -24,8 +24,4 @@ class TileLayer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clone() = TileLayer(name, 0, 0).apply {
|
|
||||||
layer = this@TileLayer.layer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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")) {
|
||||||
|
item("Tile Layer", graphic = FontIcon("fa-th")) {
|
||||||
action {
|
action {
|
||||||
val tileLayer = TileLayer("Layer ${mapVM.layers.size + 1}", mapVM.rows, mapVM.columns)
|
val layer = TileLayer("Layer ${mapVM.layers.size + 1}", mapVM.rows, mapVM.columns)
|
||||||
val command = CreateLayerCommand(mapVM.item, tileLayer)
|
val command = CreateLayerCommand(mapVM.item, layer)
|
||||||
command.execute()
|
command.execute()
|
||||||
layersPane.selectionModel.select(mapVM.layers.size - 1)
|
layersPane.selectionModel.select(mapVM.layers.size - 1)
|
||||||
undoRedoService.push(command, scope)
|
undoRedoService.push(command, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button(graphic = FontIcon("fa-chevron-up")) {
|
item("Object Layer", graphic = FontIcon("fa-cube")) {
|
||||||
enableWhen(editorStateVM.selectedLayerProperty.greaterThan(0))
|
|
||||||
action {
|
action {
|
||||||
val newIndex = editorStateVM.selectedLayer - 1
|
val layer = ObjectLayer("Layer ${mapVM.layers.size + 1}")
|
||||||
val command = MoveLayerCommand(mapVM.item, editorStateVM.selectedLayer, newIndex)
|
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")) {
|
||||||
|
enableWhen(editorStateVM.selectedLayerIndexProperty.greaterThan(0))
|
||||||
|
action {
|
||||||
|
val newIndex = editorStateVM.selectedLayerIndex - 1
|
||||||
|
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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user