[Editor] Refactor brush code #2

This commit is contained in:
2021-02-07 13:42:19 +01:00
parent 6028ae27fb
commit 47d85ddc7e
5 changed files with 68 additions and 60 deletions

View File

@@ -14,21 +14,19 @@ class Brush {
val rowsProperty = SimpleIntegerProperty(this, "", 0)
var rows by rowsProperty
private set
val columnsProperty = SimpleIntegerProperty(0)
var columns by columnsProperty
val centerRowProperty = SimpleIntegerProperty(0)
var centerRow by centerRowProperty
val centerColumnProperty = SimpleIntegerProperty(0)
var centerColumn by centerColumnProperty
private set
val brushRangeProperty = SimpleIntegerProperty(1)
var brushRange by brushRangeProperty
private set
val modeProperty = SimpleObjectProperty(BrushMode.PAINTING_MODE)
var mode by modeProperty
private set
private constructor(brushArray: Array<Array<Tile>>) {
rowsProperty.value = brushArray.size
@@ -40,9 +38,6 @@ class Brush {
if (rowsProperty.value > 0) {
columns = brush.size / rowsProperty.value
}
centerRow = rows / 2
centerColumn = columns / 2
}
private constructor(brush: List<Tile>, rows: Int, columns: Int) {
@@ -50,32 +45,53 @@ class Brush {
this.columns = columns
this.brush = brush.asObservable()
centerRow = rows / 2
centerColumn = columns / 2
}
fun forEach(consumer: (row: Int, column: Int, tile: Tile?) -> Unit) {
brush.forEachIndexed { id, tile ->
consumer(id / columns, id % columns, when(mode) {
BrushMode.PAINTING_MODE -> tile
BrushMode.ERASING_MODE -> null
})
fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
return when {
brushRange > 1 || mode == BrushMode.ERASING_MODE -> forEachInRangedBrush(consumer)
else -> forEachInRegularBrush(consumer)
}
}
fun withBrushRange(range: Int) = Brush(Array(range) { Array(range) { brush[0] } }).apply {
brushRange = range
private fun forEachInRangedBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
val center = brushRange / 2
(0 until brushRange).forEach { row ->
(0 until brushRange).forEach { column ->
consumer(row, column, center, center, getTileByMode(brush[0]))
}
}
}
private fun getTileByMode(tile: Tile) = when (mode) {
BrushMode.PAINTING_MODE -> tile
BrushMode.ERASING_MODE -> null
}
private fun forEachInRegularBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
val centerRow = rows / 2
val centerColumn = columns / 2
brush.forEachIndexed { id, tile ->
consumer(id / columns, id % columns, centerRow, centerColumn, getTileByMode(tile))
}
}
private fun clone() = Brush(brush, rows, columns).apply {
brushRange = this@Brush.brushRange
mode = this@Brush.mode
}
fun withErasingMode() = Brush(brush, rows, columns).apply {
brushRange = this@Brush.brushRange
fun withBrushRange(range: Int) = clone().apply {
brushRange = range
}
fun withErasingMode() = clone().apply {
mode = BrushMode.ERASING_MODE
}
fun withPaintingMode() = Brush(brush, rows, columns).apply {
brushRange = this@Brush.brushRange
fun withPaintingMode() = clone().apply {
mode = BrushMode.PAINTING_MODE
}

View File

@@ -27,17 +27,21 @@ class MapPainter(
val alpha = gc.globalAlpha
gc.globalAlpha = 0.4
brushVM.forEach { row, column, tile -> tile?.let { renderTile(gc, it, column, row) } }
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
tile?.let {
renderTile(gc, it, column, row, centerRow, centerColumn)
}
}
gc.globalAlpha = alpha
}
private fun renderTile(gc: GraphicsContext, tile: Tile, column: Int, row: Int) {
private fun renderTile(gc: GraphicsContext, tile: Tile, column: Int, row: Int, centerRow: Int, centerColumn: Int) {
gc.drawImage(
tile.image,
tileWidth * (mouseColumn - brushVM.centerColumn + column),
tileHeight * (mouseRow - brushVM.centerRow + row)
tileWidth * (mouseColumn - centerColumn + column),
tileHeight * (mouseRow - centerRow + row)
)
}
@@ -55,13 +59,8 @@ class MapPainter(
private fun beginTrace(event: MapMouseEvent) {
if (event.button == MouseButton.PRIMARY && mapVM.selectedLayer >= 0) {
currentTrace = MapPaintingTrace(mapVM, "Paint trace").apply {
brushVM.forEach { row, column, tile ->
paint(
map.selectedLayer,
mouseRow - brushVM.centerRow + row,
mouseColumn - brushVM.centerColumn + column,
tile
)
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
paint(map.selectedLayer, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile)
}
}
}
@@ -70,13 +69,8 @@ class MapPainter(
private fun proceedTrace(event: MapMouseEvent) {
if (event.button == MouseButton.PRIMARY) {
currentTrace?.apply {
brushVM.forEach { row, column, tile ->
paint(
map.selectedLayer,
mouseRow - brushVM.centerRow + row,
mouseColumn - brushVM.centerColumn + column,
tile
)
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
paint(map.selectedLayer, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile)
}
}
}

View File

@@ -26,11 +26,12 @@ class TileSetPane(private val gameMapVM: GameMapVM, brushVM: BrushVM) : Canvas()
// when brush range (size) is increased to 2 or more
// (because the range-increased brush can only include
// the tile of one type).
brushVM.brushRangeProperty.addListener { _, _, newValue ->
if (newValue.toInt() > 1) {
brushVM.itemProperty.addListener { _, _, brush ->
if (brush.brushRange > 1) {
selection.shrinkToTopLeftTile()
render()
}
render()
}
render()

View File

@@ -8,7 +8,9 @@ import com.bartlomiejpluta.base.editor.viewmodel.map.BrushVM
import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
import javafx.scene.control.ToggleGroup
import org.kordamp.ikonli.javafx.FontIcon
import org.slf4j.LoggerFactory
import tornadofx.*
import java.util.*
import kotlin.math.max
class MapToolbarView : View() {
@@ -20,8 +22,8 @@ class MapToolbarView : View() {
private val brushVM = find<BrushVM>()
private val brushMode = ToggleGroup().apply {
brushVM.erasingProperty.addListener { _, _, newValue ->
selectedValueProperty<BrushMode>().value = newValue
brushVM.itemProperty.addListener { _, _, brush ->
selectedValueProperty<BrushMode>().value = brush.mode
}
}
@@ -101,8 +103,8 @@ class MapToolbarView : View() {
brushVM.item = brushVM.withBrushRange(newValue.toInt())
}
brushVM.brushRangeProperty.addListener { _, _, newValue ->
value = newValue.toDouble()
brushVM.itemProperty.addListener { _, _, brush ->
value = brush.brushRange.toDouble()
}
}

View File

@@ -2,7 +2,8 @@ package com.bartlomiejpluta.base.editor.viewmodel.map
import com.bartlomiejpluta.base.editor.model.map.brush.Brush
import com.bartlomiejpluta.base.editor.model.tileset.Tile
import tornadofx.*
import tornadofx.ItemViewModel
import tornadofx.getValue
class BrushVM : ItemViewModel<Brush>(Brush.of(arrayOf(arrayOf()))) {
val brush = bind(Brush::brush)
@@ -13,19 +14,13 @@ class BrushVM : ItemViewModel<Brush>(Brush.of(arrayOf(arrayOf()))) {
val columnsProperty = bind(Brush::columnsProperty)
val columns by columnsProperty
val centerRowProperty = bind(Brush::centerRowProperty)
val centerRow by centerRowProperty
val centerColumnProperty = bind(Brush::centerColumnProperty)
val centerColumn by centerColumnProperty
val brushRangeProperty = bind(Brush::brushRangeProperty)
var brushRange by brushRangeProperty
val brushRange by brushRangeProperty
val erasingProperty = bind(Brush::modeProperty)
var erasing by erasingProperty
val modeProperty = bind(Brush::modeProperty)
val mode by modeProperty
fun forEach(consumer: (row: Int, column: 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)