[Editor] Refactor brush code #3

This commit is contained in:
2021-02-07 14:17:24 +01:00
parent 47d85ddc7e
commit c2bce5dca1
6 changed files with 40 additions and 50 deletions

View File

@@ -20,8 +20,8 @@ class Brush {
var columns by columnsProperty var columns by columnsProperty
private set private set
val brushRangeProperty = SimpleIntegerProperty(1) val rangeProperty = SimpleIntegerProperty(1)
var brushRange by brushRangeProperty var range by rangeProperty
private set private set
val modeProperty = SimpleObjectProperty(BrushMode.PAINTING_MODE) val modeProperty = SimpleObjectProperty(BrushMode.PAINTING_MODE)
@@ -49,16 +49,16 @@ class Brush {
fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) { fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
return when { return when {
brushRange > 1 || mode == BrushMode.ERASING_MODE -> forEachInRangedBrush(consumer) range > 1 || mode == BrushMode.ERASING_MODE -> forEachInRangedBrush(consumer)
else -> forEachInRegularBrush(consumer) else -> forEachInRegularBrush(consumer)
} }
} }
private fun forEachInRangedBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) { private fun forEachInRangedBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
val center = brushRange / 2 val center = range / 2
(0 until brushRange).forEach { row -> (0 until range).forEach { row ->
(0 until brushRange).forEach { column -> (0 until range).forEach { column ->
consumer(row, column, center, center, getTileByMode(brush[0])) consumer(row, column, center, center, getTileByMode(brush[0]))
} }
} }
@@ -79,20 +79,16 @@ class Brush {
} }
private fun clone() = Brush(brush, rows, columns).apply { private fun clone() = Brush(brush, rows, columns).apply {
brushRange = this@Brush.brushRange this.range = this@Brush.range
mode = this@Brush.mode this.mode = this@Brush.mode
} }
fun withBrushRange(range: Int) = clone().apply { fun withRange(range: Int) = clone().apply {
brushRange = range this.range = range
} }
fun withErasingMode() = clone().apply { fun withBrushMode(mode: BrushMode) = clone().apply {
mode = BrushMode.ERASING_MODE this.mode = mode
}
fun withPaintingMode() = clone().apply {
mode = BrushMode.PAINTING_MODE
} }
companion object { companion object {

View File

@@ -9,6 +9,7 @@ import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
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,
@@ -28,21 +29,28 @@ class MapPainter(
gc.globalAlpha = 0.4 gc.globalAlpha = 0.4
brushVM.forEach { row, column, centerRow, centerColumn, tile -> brushVM.forEach { row, column, centerRow, centerColumn, tile ->
tile?.let { renderTile(gc, row, column, centerRow, centerColumn, tile)
renderTile(gc, it, column, row, centerRow, centerColumn)
}
} }
gc.globalAlpha = alpha gc.globalAlpha = alpha
} }
private fun renderTile(gc: GraphicsContext, tile: Tile, column: Int, row: Int, centerRow: Int, centerColumn: Int) { private fun renderTile(gc: GraphicsContext, row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) {
gc.drawImage( val x = tileWidth * (mouseColumn - centerColumn + column)
tile.image, val y = tileHeight * (mouseRow - centerRow + row)
tileWidth * (mouseColumn - centerColumn + column),
tileHeight * (mouseRow - 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) {

View File

@@ -21,10 +21,6 @@ class TileSetSelection(private val gameMapVM: GameMapVM, private val brushVM: Br
private var height = gameMapVM.tileSet.tileHeight.toDouble() private var height = gameMapVM.tileSet.tileHeight.toDouble()
fun shrinkToTopLeftTile() {
proceed(startRow, startColumn)
}
fun begin(row: Double, column: Double) { fun begin(row: Double, column: Double) {
startRow = row startRow = row
offsetRow = 0.0 offsetRow = 0.0

View File

@@ -22,17 +22,8 @@ class TileSetPane(private val gameMapVM: GameMapVM, brushVM: BrushVM) : Canvas()
width = gameMapVM.tileSet.width.toDouble() width = gameMapVM.tileSet.width.toDouble()
height = gameMapVM.tileSet.height.toDouble() height = gameMapVM.tileSet.height.toDouble()
// Shrink the selection just one tile (the top left one)
// when brush range (size) is increased to 2 or more
// (because the range-increased brush can only include
// the tile of one type).
brushVM.itemProperty.addListener { _, _, brush ->
if (brush.brushRange > 1) {
selection.shrinkToTopLeftTile()
}
render() brushVM.itemProperty.addListener { _, _, _ -> render() }
}
render() render()
} }

View File

@@ -80,7 +80,7 @@ class MapToolbarView : View() {
graphic = FontIcon("fa-paint-brush") graphic = FontIcon("fa-paint-brush")
action { action {
brushVM.item = brushVM.withPaintingMode() brushVM.item = brushVM.withMode(BrushMode.PAINTING_MODE)
} }
} }
@@ -88,7 +88,7 @@ class MapToolbarView : View() {
graphic = FontIcon("fa-eraser") graphic = FontIcon("fa-eraser")
action { action {
brushVM.item = brushVM.withErasingMode() brushVM.item = brushVM.withMode(BrushMode.ERASING_MODE)
} }
} }
@@ -100,11 +100,11 @@ class MapToolbarView : View() {
minorTickCount = 0 minorTickCount = 0
valueProperty().addListener { _, _, newValue -> valueProperty().addListener { _, _, newValue ->
brushVM.item = brushVM.withBrushRange(newValue.toInt()) brushVM.item = brushVM.withRange(newValue.toInt())
} }
brushVM.itemProperty.addListener { _, _, brush -> brushVM.itemProperty.addListener { _, _, brush ->
value = brush.brushRange.toDouble() value = brush.range.toDouble()
} }
} }

View File

@@ -1,6 +1,7 @@
package com.bartlomiejpluta.base.editor.viewmodel.map package com.bartlomiejpluta.base.editor.viewmodel.map
import com.bartlomiejpluta.base.editor.model.map.brush.Brush import com.bartlomiejpluta.base.editor.model.map.brush.Brush
import com.bartlomiejpluta.base.editor.model.map.brush.BrushMode
import com.bartlomiejpluta.base.editor.model.tileset.Tile import com.bartlomiejpluta.base.editor.model.tileset.Tile
import tornadofx.ItemViewModel import tornadofx.ItemViewModel
import tornadofx.getValue import tornadofx.getValue
@@ -14,17 +15,15 @@ class BrushVM : ItemViewModel<Brush>(Brush.of(arrayOf(arrayOf()))) {
val columnsProperty = bind(Brush::columnsProperty) val columnsProperty = bind(Brush::columnsProperty)
val columns by columnsProperty val columns by columnsProperty
val brushRangeProperty = bind(Brush::brushRangeProperty) val rangeProperty = bind(Brush::rangeProperty)
val brushRange by brushRangeProperty val range by rangeProperty
val modeProperty = bind(Brush::modeProperty) val modeProperty = bind(Brush::modeProperty)
val mode by modeProperty val mode by modeProperty
fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) = item.forEach(consumer) fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) = item.forEach(consumer)
fun withBrushRange(range: Int) = item.withBrushRange(range) fun withRange(range: Int) = item.withRange(range)
fun withErasingMode() = item.withErasingMode() fun withMode(mode: BrushMode) = item.withBrushMode(mode)
fun withPaintingMode() = item.withPaintingMode()
} }