[Editor] Create eraser

This commit is contained in:
2021-02-07 12:34:03 +01:00
parent a2bffd3840
commit 24437d9760
6 changed files with 71 additions and 16 deletions

View File

@@ -1,13 +1,17 @@
package com.bartlomiejpluta.base.editor.model.map.brush package com.bartlomiejpluta.base.editor.model.map.brush
import com.bartlomiejpluta.base.editor.model.tileset.Tile import com.bartlomiejpluta.base.editor.model.tileset.Tile
import javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleIntegerProperty import javafx.beans.property.SimpleIntegerProperty
import javafx.collections.FXCollections
import javafx.collections.ObservableList
import tornadofx.asObservable
import tornadofx.getValue import tornadofx.getValue
import tornadofx.observableListOf import tornadofx.observableListOf
import tornadofx.setValue import tornadofx.setValue
class Brush(newBrush: Array<Array<Tile>>) { class Brush {
val brush = observableListOf<Tile>() val brush: ObservableList<Tile>
val rowsProperty = SimpleIntegerProperty(this, "", 0) val rowsProperty = SimpleIntegerProperty(this, "", 0)
var rows by rowsProperty var rows by rowsProperty
@@ -24,10 +28,15 @@ class Brush(newBrush: Array<Array<Tile>>) {
val brushRangeProperty = SimpleIntegerProperty(1) val brushRangeProperty = SimpleIntegerProperty(1)
var brushRange by brushRangeProperty var brushRange by brushRangeProperty
init { val erasingProperty = SimpleBooleanProperty(false)
rowsProperty.value = newBrush.size var erasing by erasingProperty
newBrush.forEach { brush.addAll(it) } private constructor(brushArray: Array<Array<Tile>>) {
rowsProperty.value = brushArray.size
brush = observableListOf()
brushArray.forEach { brush.addAll(it) }
if (rowsProperty.value > 0) { if (rowsProperty.value > 0) {
columns = brush.size / rowsProperty.value columns = brush.size / rowsProperty.value
@@ -37,11 +46,38 @@ class Brush(newBrush: Array<Array<Tile>>) {
centerColumn = columns / 2 centerColumn = columns / 2
} }
fun forEach(consumer: (row: Int, column: Int, tile: Tile) -> Unit) { private constructor(brush: List<Tile>, rows: Int, columns: Int) {
this.rows = rows
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 -> brush.forEachIndexed { id, tile ->
consumer(id / columns, id % columns, tile) consumer(id / columns, id % columns, if(erasing) null else tile)
} }
} }
fun withBrushRange(range: Int) = Brush(Array(range) { Array(range) { brush[0] } }).apply { brushRange = range } fun withBrushRange(range: Int) = Brush(Array(range) { Array(range) { brush[0] } }).apply {
brushRange = range
erasing = this@Brush.erasing
}
fun withErasingMode() = Brush(brush, rows, columns).apply {
brushRange = this@Brush.brushRange
erasing = true
}
fun withPaintingMode() = Brush(brush, rows, columns).apply {
brushRange = this@Brush.brushRange
erasing = false
}
companion object {
fun of(brushArray: Array<Array<Tile>>) = Brush(brushArray)
}
} }

View File

@@ -32,7 +32,7 @@ class TileSet(private val image: Image, rows: Int, columns: Int) {
val tiles = (0 until rows * columns).map { cropTile(it / columns, it % columns) }.toObservable() val tiles = (0 until rows * columns).map { cropTile(it / columns, it % columns) }.toObservable()
val baseBrush: Brush val baseBrush: Brush
get() = Brush(arrayOf(arrayOf(tiles[0]))) get() = Brush.of(arrayOf(arrayOf(tiles[0])))
private fun cropTile(row: Int, column: Int): Tile { private fun cropTile(row: Int, column: Int): Tile {
val reader = image.pixelReader val reader = image.pixelReader

View File

@@ -27,7 +27,7 @@ class MapPainter(
val alpha = gc.globalAlpha val alpha = gc.globalAlpha
gc.globalAlpha = 0.4 gc.globalAlpha = 0.4
brushVM.forEach { row, column, tile -> renderTile(gc, tile, column, row) } brushVM.forEach { row, column, tile -> tile?.let { renderTile(gc, it, column, row) } }
gc.globalAlpha = alpha gc.globalAlpha = alpha

View File

@@ -71,7 +71,7 @@ class TileSetSelection(private val gameMapVM: GameMapVM, private val brushVM: Br
} }
} }
brushVM.item = Brush(brushArray) brushVM.item = Brush.of(brushArray)
} }
override fun render(gc: GraphicsContext) { override fun render(gc: GraphicsContext) {

View File

@@ -18,7 +18,11 @@ class MapToolbarView : View() {
private val mapVM = find<GameMapVM>() private val mapVM = find<GameMapVM>()
private val brushVM = find<BrushVM>() private val brushVM = find<BrushVM>()
private val tool = ToggleGroup() private val tool = ToggleGroup().apply {
brushVM.erasingProperty.addListener { observable, oldValue, newValue ->
selectedValueProperty<Boolean>().value = newValue
}
}
override val root = toolbar { override val root = toolbar {
button(graphic = FontIcon("fa-undo")) { button(graphic = FontIcon("fa-undo")) {
@@ -69,12 +73,20 @@ class MapToolbarView : View() {
} }
} }
togglebutton(tool) { togglebutton(value = false, group = tool) {
graphic = FontIcon("fa-paint-brush") graphic = FontIcon("fa-paint-brush")
action {
brushVM.item = brushVM.withPaintingMode()
}
} }
togglebutton(tool) { togglebutton(value = true, group = tool) {
graphic = FontIcon("fa-eraser") graphic = FontIcon("fa-eraser")
action {
brushVM.item = brushVM.withErasingMode()
}
} }
this += FontIcon("fa-paint-brush").apply { iconSize = 10 } this += FontIcon("fa-paint-brush").apply { iconSize = 10 }

View File

@@ -4,7 +4,7 @@ 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.*
class BrushVM : ItemViewModel<Brush>(Brush(arrayOf(arrayOf()))) { class BrushVM : ItemViewModel<Brush>(Brush.of(arrayOf(arrayOf()))) {
val brush = bind(Brush::brush) val brush = bind(Brush::brush)
val rowsProperty = bind(Brush::rowsProperty) val rowsProperty = bind(Brush::rowsProperty)
@@ -22,7 +22,14 @@ class BrushVM : ItemViewModel<Brush>(Brush(arrayOf(arrayOf()))) {
val brushRangeProperty = bind(Brush::brushRangeProperty) val brushRangeProperty = bind(Brush::brushRangeProperty)
var brushRange by brushRangeProperty var brushRange by brushRangeProperty
fun forEach(consumer: (row: Int, column: Int, tile: Tile) -> Unit) = item.forEach(consumer) val erasingProperty = bind(Brush::erasingProperty)
var erasing by erasingProperty
fun forEach(consumer: (row: Int, column: Int, tile: Tile?) -> Unit) = item.forEach(consumer)
fun withBrushRange(range: Int) = item.withBrushRange(range) fun withBrushRange(range: Int) = item.withBrushRange(range)
fun withErasingMode() = item.withErasingMode()
fun withPaintingMode() = item.withPaintingMode()
} }