[Editor] Enable importing TileSets to project

This commit is contained in:
2021-02-12 08:35:06 +01:00
parent 1804f7c50e
commit 9589618ca2
10 changed files with 217 additions and 3 deletions

View File

@@ -9,6 +9,8 @@ import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import com.bartlomiejpluta.base.editor.project.model.Project
import com.bartlomiejpluta.base.editor.project.view.ProjectSettingsFragment
import com.bartlomiejpluta.base.editor.project.viewmodel.ProjectVM
import com.bartlomiejpluta.base.editor.tileset.view.importing.ImportTileSetFragment
import com.bartlomiejpluta.base.editor.tileset.viewmodel.TileSetAssetBuilderVM
import javafx.stage.FileChooser
import org.springframework.stereotype.Component
import tornadofx.*
@@ -71,4 +73,18 @@ class MainController : Controller() {
openMaps[scope] = map
}
}
fun importTileSet() {
val vm = TileSetAssetBuilderVM()
val scope = Scope()
setInScope(vm, scope)
find<ImportTileSetFragment>(scope).apply {
onComplete {
projectContext.importTileSet(it)
}
openModal(block = true)
}
}
}

View File

@@ -34,6 +34,16 @@ class MainMenuView : View() {
}
}
menu("Project") {
item("Import Tile Set...") {
enableWhen(projectContext.projectProperty.isNotNull)
action {
mainController.importTileSet()
}
}
}
menu("Edit") {
item("Undo")
item("Redo")

View File

@@ -1,7 +1,7 @@
package com.bartlomiejpluta.base.editor.map.view.editor
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
import com.bartlomiejpluta.base.editor.tileset.view.TileSetView
import com.bartlomiejpluta.base.editor.tileset.view.editor.TileSetView
import tornadofx.*

View File

@@ -8,6 +8,8 @@ import com.bartlomiejpluta.base.editor.map.serial.MapSerializer
import com.bartlomiejpluta.base.editor.project.model.Project
import com.bartlomiejpluta.base.editor.project.serial.ProjectDeserializer
import com.bartlomiejpluta.base.editor.project.serial.ProjectSerializer
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder
import com.bartlomiejpluta.base.editor.util.uid.UID
import javafx.beans.property.ObjectProperty
import javafx.beans.property.SimpleObjectProperty
@@ -79,4 +81,17 @@ class DefaultProjectContext : ProjectContext {
File(it.mapsDirectory, asset.source).inputStream().use { fis -> mapDeserializer.deserialize(fis) }
} ?: throw IllegalStateException("There is no open project in the context")
override fun importTileSet(builder: TileSetAssetBuilder) {
project?.let {
UID.next(it.tileSets.map(Asset::uid)).let { uid ->
val source = "$uid.${builder.file.extension}"
val targetFile = File(it.tileSetsDirectory, source)
builder.file.copyTo(targetFile)
it.tileSets += TileSetAsset(uid, source, builder.name, builder.rows, builder.columns)
save()
}
}
}
}

View File

@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.project.context
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import com.bartlomiejpluta.base.editor.project.model.Project
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder
import javafx.beans.property.ObjectProperty
import java.io.File
@@ -14,4 +15,6 @@ interface ProjectContext {
fun importMap(name: String, map: GameMap)
fun loadMap(uid: String): GameMap
fun importTileSet(builder: TileSetAssetBuilder)
}

View File

@@ -28,5 +28,7 @@ class ProtobufProjectSerializer : ProjectSerializer {
.setUid(tileSet.uid)
.setSource(tileSet.source)
.setName(tileSet.name)
.setRows(tileSet.rows)
.setColumns(tileSet.columns)
.build()
}

View File

@@ -0,0 +1,21 @@
package com.bartlomiejpluta.base.editor.tileset.asset
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty
import java.io.File
import tornadofx.*
class TileSetAssetBuilder {
val nameProperty = SimpleStringProperty()
var name by nameProperty
val rowsProperty = SimpleIntegerProperty(1)
var rows by rowsProperty
val columnsProperty = SimpleIntegerProperty(1)
var columns by columnsProperty
val fileProperty = SimpleObjectProperty<File>()
var file by fileProperty
}

View File

@@ -1,8 +1,8 @@
package com.bartlomiejpluta.base.editor.tileset.view
package com.bartlomiejpluta.base.editor.tileset.view.editor
import com.bartlomiejpluta.base.editor.tileset.component.TileSetPane
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import com.bartlomiejpluta.base.editor.tileset.component.TileSetPane
import tornadofx.View
import tornadofx.plusAssign
import tornadofx.scrollpane

View File

@@ -0,0 +1,127 @@
package com.bartlomiejpluta.base.editor.tileset.view.importing
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder
import com.bartlomiejpluta.base.editor.tileset.viewmodel.TileSetAssetBuilderVM
import javafx.beans.property.SimpleObjectProperty
import javafx.scene.Cursor
import javafx.scene.image.Image
import javafx.stage.FileChooser
import tornadofx.*
class ImportTileSetFragment : Fragment("Import Tile Set") {
private val builderVM = find<TileSetAssetBuilderVM>()
private val imagePreview = SimpleObjectProperty<Image?>()
private var onCompleteConsumer: ((TileSetAssetBuilder) -> Unit)? = null
init {
builderVM.fileProperty.addListener { _, _, file ->
when(file) {
null -> imagePreview.value = null
else -> file.inputStream().use { imagePreview.value = Image(it) }
}
}
}
fun onComplete(consumer: (TileSetAssetBuilder) -> Unit) {
this.onCompleteConsumer = consumer
}
override val root = form {
prefHeight = 480.0
fieldset("Import Tile Set") {
hbox {
vbox {
scrollpane {
prefWidth = 300.0
prefHeightProperty().bind(this@form.heightProperty())
imageview(imagePreview)
tooltip = tooltip("Click to choose sprite file")
cursor = Cursor.HAND
setOnMouseClicked {
builderVM.file = chooseFile(
title = "Select Sprite",
filters = arrayOf(FileChooser.ExtensionFilter("PNG Images (*.png)", "*.png"))
).getOrNull(0)
}
builderVM.validationContext.addValidator(this@vbox, builderVM.fileProperty) {
when {
it == null -> error("This field is required")
!it.exists() -> error("The file must exist")
else -> null
}
}
}
}
vbox {
paddingLeft = 20.0
field("Tile Set Name") {
textfield(builderVM.nameProperty) {
required()
trimWhitespace()
}
}
field("Tile Set Rows") {
textfield(builderVM.rowsProperty) {
stripNonInteger()
required()
trimWhitespace()
validator {
val value = it?.toIntOrNull()
when {
value == null -> error("This field is required")
value < 1 -> error("The value must not be lower than 1")
else -> null
}
}
}
}
field("Tile Set Columns") {
textfield(builderVM.columnsProperty) {
stripNonInteger()
required()
trimWhitespace()
validator {
val value = it?.toIntOrNull()
when {
value == null -> error("This field is required")
value < 1 -> error("The value must not be lower than 1")
else -> null
}
}
}
}
}
}
}
buttonbar {
button("Import") {
action {
if(builderVM.commit()) {
onCompleteConsumer?.let { it(builderVM.item) }
close()
}
}
}
button("Reset") {
action { builderVM.rollback() }
}
button("Cancel") {
action { close() }
}
}
}
}

View File

@@ -0,0 +1,20 @@
package com.bartlomiejpluta.base.editor.tileset.viewmodel
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder
import tornadofx.ItemViewModel
import tornadofx.getValue
import tornadofx.setValue
class TileSetAssetBuilderVM : ItemViewModel<TileSetAssetBuilder>(TileSetAssetBuilder()) {
val nameProperty = bind(TileSetAssetBuilder::nameProperty)
var name by nameProperty
val rowsProperty = bind(TileSetAssetBuilder::rowsProperty)
var rows by rowsProperty
val columnsProperty = bind(TileSetAssetBuilder::columnsProperty)
var columns by columnsProperty
val fileProperty = bind(TileSetAssetBuilder::fileProperty)
var file by fileProperty
}