[Editor] Enable importing TileSets to project
This commit is contained in:
@@ -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.model.Project
|
||||||
import com.bartlomiejpluta.base.editor.project.view.ProjectSettingsFragment
|
import com.bartlomiejpluta.base.editor.project.view.ProjectSettingsFragment
|
||||||
import com.bartlomiejpluta.base.editor.project.viewmodel.ProjectVM
|
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 javafx.stage.FileChooser
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
@@ -71,4 +73,18 @@ class MainController : Controller() {
|
|||||||
openMaps[scope] = map
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -34,6 +34,16 @@ class MainMenuView : View() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
menu("Project") {
|
||||||
|
item("Import Tile Set...") {
|
||||||
|
enableWhen(projectContext.projectProperty.isNotNull)
|
||||||
|
|
||||||
|
action {
|
||||||
|
mainController.importTileSet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
menu("Edit") {
|
menu("Edit") {
|
||||||
item("Undo")
|
item("Undo")
|
||||||
item("Redo")
|
item("Redo")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.bartlomiejpluta.base.editor.map.view.editor
|
package com.bartlomiejpluta.base.editor.map.view.editor
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
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.*
|
import tornadofx.*
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.model.Project
|
||||||
import com.bartlomiejpluta.base.editor.project.serial.ProjectDeserializer
|
import com.bartlomiejpluta.base.editor.project.serial.ProjectDeserializer
|
||||||
import com.bartlomiejpluta.base.editor.project.serial.ProjectSerializer
|
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 com.bartlomiejpluta.base.editor.util.uid.UID
|
||||||
import javafx.beans.property.ObjectProperty
|
import javafx.beans.property.ObjectProperty
|
||||||
import javafx.beans.property.SimpleObjectProperty
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
@@ -79,4 +81,17 @@ class DefaultProjectContext : ProjectContext {
|
|||||||
|
|
||||||
File(it.mapsDirectory, asset.source).inputStream().use { fis -> mapDeserializer.deserialize(fis) }
|
File(it.mapsDirectory, asset.source).inputStream().use { fis -> mapDeserializer.deserialize(fis) }
|
||||||
} ?: throw IllegalStateException("There is no open project in the context")
|
} ?: 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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.map.model.map.GameMap
|
||||||
import com.bartlomiejpluta.base.editor.project.model.Project
|
import com.bartlomiejpluta.base.editor.project.model.Project
|
||||||
|
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetBuilder
|
||||||
import javafx.beans.property.ObjectProperty
|
import javafx.beans.property.ObjectProperty
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -14,4 +15,6 @@ interface ProjectContext {
|
|||||||
|
|
||||||
fun importMap(name: String, map: GameMap)
|
fun importMap(name: String, map: GameMap)
|
||||||
fun loadMap(uid: String): GameMap
|
fun loadMap(uid: String): GameMap
|
||||||
|
|
||||||
|
fun importTileSet(builder: TileSetAssetBuilder)
|
||||||
}
|
}
|
||||||
@@ -28,5 +28,7 @@ class ProtobufProjectSerializer : ProjectSerializer {
|
|||||||
.setUid(tileSet.uid)
|
.setUid(tileSet.uid)
|
||||||
.setSource(tileSet.source)
|
.setSource(tileSet.source)
|
||||||
.setName(tileSet.name)
|
.setName(tileSet.name)
|
||||||
|
.setRows(tileSet.rows)
|
||||||
|
.setColumns(tileSet.columns)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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.BrushVM
|
||||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||||
|
import com.bartlomiejpluta.base.editor.tileset.component.TileSetPane
|
||||||
import tornadofx.View
|
import tornadofx.View
|
||||||
import tornadofx.plusAssign
|
import tornadofx.plusAssign
|
||||||
import tornadofx.scrollpane
|
import tornadofx.scrollpane
|
||||||
@@ -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() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user