[Editor] Refactor brush code #2
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user