[Editor] Refactor brush code #2
This commit is contained in:
@@ -14,21 +14,19 @@ class Brush {
|
|||||||
|
|
||||||
val rowsProperty = SimpleIntegerProperty(this, "", 0)
|
val rowsProperty = SimpleIntegerProperty(this, "", 0)
|
||||||
var rows by rowsProperty
|
var rows by rowsProperty
|
||||||
|
private set
|
||||||
|
|
||||||
val columnsProperty = SimpleIntegerProperty(0)
|
val columnsProperty = SimpleIntegerProperty(0)
|
||||||
var columns by columnsProperty
|
var columns by columnsProperty
|
||||||
|
private set
|
||||||
val centerRowProperty = SimpleIntegerProperty(0)
|
|
||||||
var centerRow by centerRowProperty
|
|
||||||
|
|
||||||
val centerColumnProperty = SimpleIntegerProperty(0)
|
|
||||||
var centerColumn by centerColumnProperty
|
|
||||||
|
|
||||||
val brushRangeProperty = SimpleIntegerProperty(1)
|
val brushRangeProperty = SimpleIntegerProperty(1)
|
||||||
var brushRange by brushRangeProperty
|
var brushRange by brushRangeProperty
|
||||||
|
private set
|
||||||
|
|
||||||
val modeProperty = SimpleObjectProperty(BrushMode.PAINTING_MODE)
|
val modeProperty = SimpleObjectProperty(BrushMode.PAINTING_MODE)
|
||||||
var mode by modeProperty
|
var mode by modeProperty
|
||||||
|
private set
|
||||||
|
|
||||||
private constructor(brushArray: Array<Array<Tile>>) {
|
private constructor(brushArray: Array<Array<Tile>>) {
|
||||||
rowsProperty.value = brushArray.size
|
rowsProperty.value = brushArray.size
|
||||||
@@ -40,9 +38,6 @@ class Brush {
|
|||||||
if (rowsProperty.value > 0) {
|
if (rowsProperty.value > 0) {
|
||||||
columns = brush.size / rowsProperty.value
|
columns = brush.size / rowsProperty.value
|
||||||
}
|
}
|
||||||
|
|
||||||
centerRow = rows / 2
|
|
||||||
centerColumn = columns / 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(brush: List<Tile>, rows: Int, columns: Int) {
|
private constructor(brush: List<Tile>, rows: Int, columns: Int) {
|
||||||
@@ -50,32 +45,53 @@ class Brush {
|
|||||||
this.columns = columns
|
this.columns = columns
|
||||||
|
|
||||||
this.brush = brush.asObservable()
|
this.brush = brush.asObservable()
|
||||||
|
|
||||||
centerRow = rows / 2
|
|
||||||
centerColumn = columns / 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun forEach(consumer: (row: Int, column: Int, tile: Tile?) -> Unit) {
|
fun forEach(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
|
||||||
brush.forEachIndexed { id, tile ->
|
return when {
|
||||||
consumer(id / columns, id % columns, when(mode) {
|
brushRange > 1 || mode == BrushMode.ERASING_MODE -> forEachInRangedBrush(consumer)
|
||||||
BrushMode.PAINTING_MODE -> tile
|
else -> forEachInRegularBrush(consumer)
|
||||||
BrushMode.ERASING_MODE -> null
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun withBrushRange(range: Int) = Brush(Array(range) { Array(range) { brush[0] } }).apply {
|
private fun forEachInRangedBrush(consumer: (row: Int, column: Int, centerRow: Int, centerColumn: Int, tile: Tile?) -> Unit) {
|
||||||
brushRange = range
|
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
|
mode = this@Brush.mode
|
||||||
}
|
}
|
||||||
|
|
||||||
fun withErasingMode() = Brush(brush, rows, columns).apply {
|
fun withBrushRange(range: Int) = clone().apply {
|
||||||
brushRange = this@Brush.brushRange
|
brushRange = range
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withErasingMode() = clone().apply {
|
||||||
mode = BrushMode.ERASING_MODE
|
mode = BrushMode.ERASING_MODE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun withPaintingMode() = Brush(brush, rows, columns).apply {
|
fun withPaintingMode() = clone().apply {
|
||||||
brushRange = this@Brush.brushRange
|
|
||||||
mode = BrushMode.PAINTING_MODE
|
mode = BrushMode.PAINTING_MODE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,17 +27,21 @@ class MapPainter(
|
|||||||
val alpha = gc.globalAlpha
|
val alpha = gc.globalAlpha
|
||||||
gc.globalAlpha = 0.4
|
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
|
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(
|
gc.drawImage(
|
||||||
tile.image,
|
tile.image,
|
||||||
tileWidth * (mouseColumn - brushVM.centerColumn + column),
|
tileWidth * (mouseColumn - centerColumn + column),
|
||||||
tileHeight * (mouseRow - brushVM.centerRow + row)
|
tileHeight * (mouseRow - centerRow + row)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,13 +59,8 @@ class MapPainter(
|
|||||||
private fun beginTrace(event: MapMouseEvent) {
|
private fun beginTrace(event: MapMouseEvent) {
|
||||||
if (event.button == MouseButton.PRIMARY && mapVM.selectedLayer >= 0) {
|
if (event.button == MouseButton.PRIMARY && mapVM.selectedLayer >= 0) {
|
||||||
currentTrace = MapPaintingTrace(mapVM, "Paint trace").apply {
|
currentTrace = MapPaintingTrace(mapVM, "Paint trace").apply {
|
||||||
brushVM.forEach { row, column, tile ->
|
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
|
||||||
paint(
|
paint(map.selectedLayer, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile)
|
||||||
map.selectedLayer,
|
|
||||||
mouseRow - brushVM.centerRow + row,
|
|
||||||
mouseColumn - brushVM.centerColumn + column,
|
|
||||||
tile
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,13 +69,8 @@ class MapPainter(
|
|||||||
private fun proceedTrace(event: MapMouseEvent) {
|
private fun proceedTrace(event: MapMouseEvent) {
|
||||||
if (event.button == MouseButton.PRIMARY) {
|
if (event.button == MouseButton.PRIMARY) {
|
||||||
currentTrace?.apply {
|
currentTrace?.apply {
|
||||||
brushVM.forEach { row, column, tile ->
|
brushVM.forEach { row, column, centerRow, centerColumn, tile ->
|
||||||
paint(
|
paint(map.selectedLayer, mouseRow - centerRow + row, mouseColumn - centerColumn + column, tile)
|
||||||
map.selectedLayer,
|
|
||||||
mouseRow - brushVM.centerRow + row,
|
|
||||||
mouseColumn - brushVM.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
|
// when brush range (size) is increased to 2 or more
|
||||||
// (because the range-increased brush can only include
|
// (because the range-increased brush can only include
|
||||||
// the tile of one type).
|
// the tile of one type).
|
||||||
brushVM.brushRangeProperty.addListener { _, _, newValue ->
|
brushVM.itemProperty.addListener { _, _, brush ->
|
||||||
if (newValue.toInt() > 1) {
|
if (brush.brushRange > 1) {
|
||||||
selection.shrinkToTopLeftTile()
|
selection.shrinkToTopLeftTile()
|
||||||
render()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render()
|
||||||
}
|
}
|
||||||
|
|
||||||
render()
|
render()
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import com.bartlomiejpluta.base.editor.viewmodel.map.BrushVM
|
|||||||
import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
|
import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
|
||||||
import javafx.scene.control.ToggleGroup
|
import javafx.scene.control.ToggleGroup
|
||||||
import org.kordamp.ikonli.javafx.FontIcon
|
import org.kordamp.ikonli.javafx.FontIcon
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
import java.util.*
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
class MapToolbarView : View() {
|
class MapToolbarView : View() {
|
||||||
@@ -20,8 +22,8 @@ class MapToolbarView : View() {
|
|||||||
private val brushVM = find<BrushVM>()
|
private val brushVM = find<BrushVM>()
|
||||||
|
|
||||||
private val brushMode = ToggleGroup().apply {
|
private val brushMode = ToggleGroup().apply {
|
||||||
brushVM.erasingProperty.addListener { _, _, newValue ->
|
brushVM.itemProperty.addListener { _, _, brush ->
|
||||||
selectedValueProperty<BrushMode>().value = newValue
|
selectedValueProperty<BrushMode>().value = brush.mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,8 +103,8 @@ class MapToolbarView : View() {
|
|||||||
brushVM.item = brushVM.withBrushRange(newValue.toInt())
|
brushVM.item = brushVM.withBrushRange(newValue.toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
brushVM.brushRangeProperty.addListener { _, _, newValue ->
|
brushVM.itemProperty.addListener { _, _, brush ->
|
||||||
value = newValue.toDouble()
|
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.map.brush.Brush
|
||||||
import com.bartlomiejpluta.base.editor.model.tileset.Tile
|
import com.bartlomiejpluta.base.editor.model.tileset.Tile
|
||||||
import tornadofx.*
|
import tornadofx.ItemViewModel
|
||||||
|
import tornadofx.getValue
|
||||||
|
|
||||||
class BrushVM : ItemViewModel<Brush>(Brush.of(arrayOf(arrayOf()))) {
|
class BrushVM : ItemViewModel<Brush>(Brush.of(arrayOf(arrayOf()))) {
|
||||||
val brush = bind(Brush::brush)
|
val brush = bind(Brush::brush)
|
||||||
@@ -13,19 +14,13 @@ 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 centerRowProperty = bind(Brush::centerRowProperty)
|
|
||||||
val centerRow by centerRowProperty
|
|
||||||
|
|
||||||
val centerColumnProperty = bind(Brush::centerColumnProperty)
|
|
||||||
val centerColumn by centerColumnProperty
|
|
||||||
|
|
||||||
val brushRangeProperty = bind(Brush::brushRangeProperty)
|
val brushRangeProperty = bind(Brush::brushRangeProperty)
|
||||||
var brushRange by brushRangeProperty
|
val brushRange by brushRangeProperty
|
||||||
|
|
||||||
val erasingProperty = bind(Brush::modeProperty)
|
val modeProperty = bind(Brush::modeProperty)
|
||||||
var erasing by erasingProperty
|
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)
|
fun withBrushRange(range: Int) = item.withBrushRange(range)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user