[Editor] Create working base for brush range selection
Also: "brush size" has been renamed to "brush range" for the sake of clarity
This commit is contained in:
@@ -8,15 +8,22 @@ import tornadofx.setValue
|
|||||||
|
|
||||||
class Brush(newBrush: Array<Array<Tile>>) {
|
class Brush(newBrush: Array<Array<Tile>>) {
|
||||||
val brush = observableListOf<Tile>()
|
val brush = observableListOf<Tile>()
|
||||||
|
|
||||||
val rowsProperty = SimpleIntegerProperty(this, "", 0)
|
val rowsProperty = SimpleIntegerProperty(this, "", 0)
|
||||||
var rows by rowsProperty
|
var rows by rowsProperty
|
||||||
|
|
||||||
val columnsProperty = SimpleIntegerProperty(0)
|
val columnsProperty = SimpleIntegerProperty(0)
|
||||||
var columns by columnsProperty
|
var columns by columnsProperty
|
||||||
|
|
||||||
val centerRowProperty = SimpleIntegerProperty(0)
|
val centerRowProperty = SimpleIntegerProperty(0)
|
||||||
var centerRow by centerRowProperty
|
var centerRow by centerRowProperty
|
||||||
|
|
||||||
val centerColumnProperty = SimpleIntegerProperty(0)
|
val centerColumnProperty = SimpleIntegerProperty(0)
|
||||||
var centerColumn by centerColumnProperty
|
var centerColumn by centerColumnProperty
|
||||||
|
|
||||||
|
val brushRangeProperty = SimpleIntegerProperty(1)
|
||||||
|
var brushRange by brushRangeProperty
|
||||||
|
|
||||||
init {
|
init {
|
||||||
rowsProperty.value = newBrush.size
|
rowsProperty.value = newBrush.size
|
||||||
|
|
||||||
@@ -35,4 +42,6 @@ class Brush(newBrush: Array<Array<Tile>>) {
|
|||||||
consumer(id / columns, id % columns, tile)
|
consumer(id / columns, id % columns, tile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun withBrushRange(range: Int) = Brush(Array(range) { Array(range) { brush[0] } }).apply { brushRange = range }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ class MapCanvas(val map: GameMapVM, private val painter: MapPainter) : Renderabl
|
|||||||
|
|
||||||
|
|
||||||
override fun render(gc: GraphicsContext) {
|
override fun render(gc: GraphicsContext) {
|
||||||
log.debug("vm.dim = ${map.rows}x${map.columns} | map.dim = ${map.item.rows}x${map.item.columns}")
|
|
||||||
log.debug("vm.size = ${map.width}x${map.height} | map.size = ${map.item.width}x${map.item.height}")
|
|
||||||
gc.clearRect(0.0, 0.0, gc.canvas.width, gc.canvas.height)
|
gc.clearRect(0.0, 0.0, gc.canvas.width, gc.canvas.height)
|
||||||
|
|
||||||
renderBackground(gc)
|
renderBackground(gc)
|
||||||
@@ -72,7 +70,6 @@ class MapCanvas(val map: GameMapVM, private val painter: MapPainter) : Renderabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = LoggerFactory.getLogger(MapCanvas::class.java)
|
|
||||||
private val BACKGROUND_COLOR1 = Color.color(1.0, 1.0, 1.0, 1.0)
|
private val BACKGROUND_COLOR1 = Color.color(1.0, 1.0, 1.0, 1.0)
|
||||||
private val BACKGROUND_COLOR2 = Color.color(0.95, 0.95, 0.95, 0.95)
|
private val BACKGROUND_COLOR2 = Color.color(0.95, 0.95, 0.95, 0.95)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ import javafx.scene.input.MouseButton
|
|||||||
import javafx.scene.input.MouseEvent
|
import javafx.scene.input.MouseEvent
|
||||||
import javafx.scene.paint.Color
|
import javafx.scene.paint.Color
|
||||||
|
|
||||||
class TileSetCanvas(private val gameMapVM: GameMapVM, brushVM: BrushVM) : Renderable, MapMouseEventHandler {
|
class TileSetCanvas(private val gameMapVM: GameMapVM, private val selection: TileSetSelection) : Renderable, MapMouseEventHandler {
|
||||||
private var selection = TileSetSelection(gameMapVM, brushVM)
|
|
||||||
|
|
||||||
private var mouseRow = -1
|
private var mouseRow = -1
|
||||||
private var mouseColumn = -1
|
private var mouseColumn = -1
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package com.bartlomiejpluta.base.editor.render.canvas.tileset
|
package com.bartlomiejpluta.base.editor.render.canvas.tileset
|
||||||
|
|
||||||
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.TileSet
|
|
||||||
import com.bartlomiejpluta.base.editor.render.model.Renderable
|
import com.bartlomiejpluta.base.editor.render.model.Renderable
|
||||||
import com.bartlomiejpluta.base.editor.viewmodel.map.BrushVM
|
import com.bartlomiejpluta.base.editor.viewmodel.map.BrushVM
|
||||||
import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
|
import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
|
||||||
@@ -23,7 +21,13 @@ 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) {
|
||||||
|
resetBrushRange()
|
||||||
|
|
||||||
startRow = row
|
startRow = row
|
||||||
offsetRow = 0.0
|
offsetRow = 0.0
|
||||||
startColumn = column
|
startColumn = column
|
||||||
@@ -32,6 +36,10 @@ class TileSetSelection(private val gameMapVM: GameMapVM, private val brushVM: Br
|
|||||||
updateRect(row, column)
|
updateRect(row, column)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun resetBrushRange() {
|
||||||
|
brushVM.brushRange = 1
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateRect(row: Double, column: Double) {
|
private fun updateRect(row: Double, column: Double) {
|
||||||
x = min(column, startColumn) * gameMapVM.tileSet.tileWidth
|
x = min(column, startColumn) * gameMapVM.tileSet.tileWidth
|
||||||
y = min(row, startRow) * gameMapVM.tileSet.tileHeight
|
y = min(row, startRow) * gameMapVM.tileSet.tileHeight
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.view.component.tileset
|
|||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.render.canvas.input.MapMouseEvent
|
import com.bartlomiejpluta.base.editor.render.canvas.input.MapMouseEvent
|
||||||
import com.bartlomiejpluta.base.editor.render.canvas.tileset.TileSetCanvas
|
import com.bartlomiejpluta.base.editor.render.canvas.tileset.TileSetCanvas
|
||||||
|
import com.bartlomiejpluta.base.editor.render.canvas.tileset.TileSetSelection
|
||||||
import com.bartlomiejpluta.base.editor.viewmodel.map.BrushVM
|
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.event.EventHandler
|
import javafx.event.EventHandler
|
||||||
@@ -9,7 +10,8 @@ import javafx.scene.canvas.Canvas
|
|||||||
import javafx.scene.input.MouseEvent
|
import javafx.scene.input.MouseEvent
|
||||||
|
|
||||||
class TileSetPane(private val gameMapVM: GameMapVM, brushVM: BrushVM) : Canvas(), EventHandler<MouseEvent> {
|
class TileSetPane(private val gameMapVM: GameMapVM, brushVM: BrushVM) : Canvas(), EventHandler<MouseEvent> {
|
||||||
private val tileSetCanvas = TileSetCanvas(gameMapVM, brushVM)
|
private val selection = TileSetSelection(gameMapVM, brushVM)
|
||||||
|
private val tileSetCanvas = TileSetCanvas(gameMapVM, selection)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
onMouseMoved = this
|
onMouseMoved = this
|
||||||
@@ -20,6 +22,17 @@ 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.brushRangeProperty.addListener { _, _, newValue ->
|
||||||
|
if (newValue.toInt() > 1) {
|
||||||
|
selection.shrinkToTopLeftTile()
|
||||||
|
render()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render()
|
render()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
package com.bartlomiejpluta.base.editor.view.map
|
package com.bartlomiejpluta.base.editor.view.map
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
||||||
import com.bartlomiejpluta.base.editor.command.service.UndoRedoService
|
|
||||||
import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent
|
|
||||||
import com.bartlomiejpluta.base.editor.model.map.map.GameMap
|
import com.bartlomiejpluta.base.editor.model.map.map.GameMap
|
||||||
import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
|
import com.bartlomiejpluta.base.editor.viewmodel.map.GameMapVM
|
||||||
import org.kordamp.ikonli.javafx.FontIcon
|
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
import kotlin.math.max
|
|
||||||
|
|
||||||
|
|
||||||
class MapFragment : Fragment() {
|
class MapFragment : Fragment() {
|
||||||
private val undoRedoService: UndoRedoService by di()
|
|
||||||
|
|
||||||
override val scope = super.scope as UndoableScope
|
override val scope = super.scope as UndoableScope
|
||||||
|
|
||||||
val map: GameMap by param()
|
val map: GameMap by param()
|
||||||
|
|
||||||
private val mapVM = find<GameMapVM>().apply { item = map }
|
private val mapVM = find<GameMapVM>().apply { item = map }
|
||||||
@@ -21,57 +16,11 @@ class MapFragment : Fragment() {
|
|||||||
private val mapView = find<MapView>()
|
private val mapView = find<MapView>()
|
||||||
private val layersView = find<MapLayersView>()
|
private val layersView = find<MapLayersView>()
|
||||||
private val tileSetView = find<TileSetView>()
|
private val tileSetView = find<TileSetView>()
|
||||||
|
private val toolbarView = find<MapToolbarView>()
|
||||||
|
|
||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
top = toolbar {
|
top = toolbarView.root
|
||||||
button(graphic = FontIcon("fa-undo")) {
|
|
||||||
shortcut("Ctrl+Z")
|
|
||||||
action {
|
|
||||||
undoRedoService.undo(scope)
|
|
||||||
fire(RedrawMapRequestEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button(graphic = FontIcon("fa-repeat")) {
|
|
||||||
shortcut("Ctrl+Shift+Z")
|
|
||||||
action {
|
|
||||||
undoRedoService.redo(scope)
|
|
||||||
fire(RedrawMapRequestEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button(text = "Rows", graphic = FontIcon("fa-minus")) {
|
|
||||||
action {
|
|
||||||
mapVM.rows = max(mapVM.rows - 1, 1)
|
|
||||||
mapVM.commit()
|
|
||||||
fire(RedrawMapRequestEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button(text = "Columns", graphic = FontIcon("fa-minus")) {
|
|
||||||
action {
|
|
||||||
mapVM.columns = max(mapVM.columns - 1, 1)
|
|
||||||
mapVM.commit()
|
|
||||||
fire(RedrawMapRequestEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button(text = "Rows", graphic = FontIcon("fa-plus")) {
|
|
||||||
action {
|
|
||||||
++mapVM.rows
|
|
||||||
mapVM.commit()
|
|
||||||
fire(RedrawMapRequestEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button(text = "Columns", graphic = FontIcon("fa-plus")) {
|
|
||||||
action {
|
|
||||||
++mapVM.columns
|
|
||||||
mapVM.commit()
|
|
||||||
fire(RedrawMapRequestEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
center = mapView.root
|
center = mapView.root
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.view.map
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
||||||
|
import com.bartlomiejpluta.base.editor.command.service.UndoRedoService
|
||||||
|
import com.bartlomiejpluta.base.editor.event.RedrawMapRequestEvent
|
||||||
|
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 tornadofx.*
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
class MapToolbarView : View() {
|
||||||
|
private val undoRedoService: UndoRedoService by di()
|
||||||
|
|
||||||
|
override val scope = super.scope as UndoableScope
|
||||||
|
|
||||||
|
private val mapVM = find<GameMapVM>()
|
||||||
|
private val brushVM = find<BrushVM>()
|
||||||
|
|
||||||
|
private val tool = ToggleGroup()
|
||||||
|
|
||||||
|
|
||||||
|
override val root = toolbar {
|
||||||
|
button(graphic = FontIcon("fa-undo")) {
|
||||||
|
shortcut("Ctrl+Z")
|
||||||
|
action {
|
||||||
|
undoRedoService.undo(scope)
|
||||||
|
fire(RedrawMapRequestEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button(graphic = FontIcon("fa-repeat")) {
|
||||||
|
shortcut("Ctrl+Shift+Z")
|
||||||
|
action {
|
||||||
|
undoRedoService.redo(scope)
|
||||||
|
fire(RedrawMapRequestEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button(text = "Rows", graphic = FontIcon("fa-minus")) {
|
||||||
|
action {
|
||||||
|
mapVM.rows = max(mapVM.rows - 1, 1)
|
||||||
|
mapVM.commit()
|
||||||
|
fire(RedrawMapRequestEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button(text = "Columns", graphic = FontIcon("fa-minus")) {
|
||||||
|
action {
|
||||||
|
mapVM.columns = max(mapVM.columns - 1, 1)
|
||||||
|
mapVM.commit()
|
||||||
|
fire(RedrawMapRequestEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button(text = "Rows", graphic = FontIcon("fa-plus")) {
|
||||||
|
action {
|
||||||
|
++mapVM.rows
|
||||||
|
mapVM.commit()
|
||||||
|
fire(RedrawMapRequestEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button(text = "Columns", graphic = FontIcon("fa-plus")) {
|
||||||
|
action {
|
||||||
|
++mapVM.columns
|
||||||
|
mapVM.commit()
|
||||||
|
fire(RedrawMapRequestEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
togglebutton(tool) {
|
||||||
|
graphic = FontIcon("fa-paint-brush")
|
||||||
|
}
|
||||||
|
|
||||||
|
togglebutton(tool) {
|
||||||
|
graphic = FontIcon("fa-eraser")
|
||||||
|
}
|
||||||
|
|
||||||
|
this += FontIcon("fa-paint-brush")
|
||||||
|
|
||||||
|
button(graphic = FontIcon("fa-plus")) {
|
||||||
|
enableWhen(brushVM.brushRangeProperty.lessThan(5))
|
||||||
|
action {
|
||||||
|
brushVM.item = brushVM.withBrushRange(brushVM.brushRange + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button(graphic = FontIcon("fa-minus")) {
|
||||||
|
enableWhen(brushVM.brushRangeProperty.greaterThan(1))
|
||||||
|
action {
|
||||||
|
brushVM.item = brushVM.withBrushRange(brushVM.brushRange - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,7 @@ 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.ItemViewModel
|
import tornadofx.*
|
||||||
import tornadofx.getValue
|
|
||||||
|
|
||||||
class BrushVM : ItemViewModel<Brush>(Brush(arrayOf(arrayOf()))) {
|
class BrushVM : ItemViewModel<Brush>(Brush(arrayOf(arrayOf()))) {
|
||||||
val brush = bind(Brush::brush)
|
val brush = bind(Brush::brush)
|
||||||
@@ -20,5 +19,10 @@ class BrushVM : ItemViewModel<Brush>(Brush(arrayOf(arrayOf()))) {
|
|||||||
val centerColumnProperty = bind(Brush::centerColumnProperty)
|
val centerColumnProperty = bind(Brush::centerColumnProperty)
|
||||||
val centerColumn by centerColumnProperty
|
val centerColumn by centerColumnProperty
|
||||||
|
|
||||||
|
val brushRangeProperty = bind(Brush::brushRangeProperty)
|
||||||
|
var brushRange by brushRangeProperty
|
||||||
|
|
||||||
fun forEach(consumer: (row: Int, column: Int, tile: Tile) -> Unit) = item.forEach(consumer)
|
fun forEach(consumer: (row: Int, column: Int, tile: Tile) -> Unit) = item.forEach(consumer)
|
||||||
|
|
||||||
|
fun withBrushRange(range: Int) = item.withBrushRange(range)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user