[Editor] Add support for importing SoundAssets
This commit is contained in:
@@ -3,6 +3,7 @@ package com.bartlomiejpluta.base.editor.asset.component
|
||||
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAsset
|
||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||
import com.bartlomiejpluta.base.editor.asset.model.AssetCategory
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAsset
|
||||
import com.bartlomiejpluta.base.editor.entityset.asset.EntitySet
|
||||
import com.bartlomiejpluta.base.editor.gui.font.asset.FontAsset
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAsset
|
||||
@@ -76,6 +77,7 @@ class AssetTreeCell(renameAsset: (asset: Asset, name: String) -> Asset, deleteAs
|
||||
is AnimationAsset -> FontIcon("fa-film")
|
||||
is FontAsset -> FontIcon("fa-font")
|
||||
is WidgetAsset -> FontIcon("fa-tachometer")
|
||||
is SoundAsset -> FontIcon("fa-music")
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.bartlomiejpluta.base.editor.file.model.ScriptAssetFileNode
|
||||
import com.bartlomiejpluta.base.editor.main.controller.MainController
|
||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||
import javafx.beans.binding.Bindings
|
||||
import javafx.beans.binding.Bindings.bindContent
|
||||
import javafx.scene.control.TreeItem
|
||||
import javafx.scene.control.TreeView
|
||||
import tornadofx.*
|
||||
@@ -44,6 +44,10 @@ class AssetsListView : View() {
|
||||
menuitem("New Widget...") { mainController.createEmptyWidget() }
|
||||
}
|
||||
|
||||
private val audio = AssetCategory("Audio").apply {
|
||||
menuitem("Import Sound...") { mainController.importSound() }
|
||||
}
|
||||
|
||||
private val rootItem = AssetCategory(
|
||||
name = "Project", items = observableListOf(
|
||||
maps,
|
||||
@@ -52,7 +56,8 @@ class AssetsListView : View() {
|
||||
entitySet,
|
||||
animations,
|
||||
fonts,
|
||||
widgets
|
||||
widgets,
|
||||
audio
|
||||
)
|
||||
)
|
||||
|
||||
@@ -60,13 +65,14 @@ class AssetsListView : View() {
|
||||
projectContext.projectProperty.addListener { _, _, project ->
|
||||
project?.let {
|
||||
rootItem.nameProperty.bind(it.nameProperty)
|
||||
Bindings.bindContent(maps.items, it.maps)
|
||||
Bindings.bindContent(tileSets.items, it.tileSets)
|
||||
Bindings.bindContent(images.items, it.images)
|
||||
Bindings.bindContent(entitySet.items, it.entitySets)
|
||||
Bindings.bindContent(animations.items, it.animations)
|
||||
Bindings.bindContent(fonts.items, it.fonts)
|
||||
Bindings.bindContent(widgets.items, it.widgets)
|
||||
bindContent(maps.items, it.maps)
|
||||
bindContent(tileSets.items, it.tileSets)
|
||||
bindContent(images.items, it.images)
|
||||
bindContent(entitySet.items, it.entitySets)
|
||||
bindContent(animations.items, it.animations)
|
||||
bindContent(fonts.items, it.fonts)
|
||||
bindContent(widgets.items, it.widgets)
|
||||
bindContent(audio.items, it.sounds)
|
||||
root.root.expandAll()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.editor.audio.asset
|
||||
|
||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||
import com.bartlomiejpluta.base.editor.project.model.Project
|
||||
|
||||
class SoundAsset(project: Project, uid: String, source: String, name: String) :
|
||||
Asset(project.audioDirectoryProperty, uid, source, name)
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.bartlomiejpluta.base.editor.audio.asset
|
||||
|
||||
import javafx.beans.property.SimpleObjectProperty
|
||||
import javafx.beans.property.SimpleStringProperty
|
||||
import tornadofx.getValue
|
||||
import tornadofx.setValue
|
||||
import java.io.File
|
||||
|
||||
class SoundAssetData {
|
||||
val nameProperty = SimpleStringProperty()
|
||||
var name by nameProperty
|
||||
|
||||
val fileProperty = SimpleObjectProperty<File>()
|
||||
var file by fileProperty
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.bartlomiejpluta.base.editor.audio.view.importing
|
||||
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAssetData
|
||||
import com.bartlomiejpluta.base.editor.audio.viewmodel.SoundAssetDataVM
|
||||
import com.bartlomiejpluta.base.editor.common.component.SingleFileChooserField
|
||||
import javafx.stage.FileChooser
|
||||
import tornadofx.*
|
||||
|
||||
class ImportSoundFragment : Fragment("Import Sound") {
|
||||
private val dataVM = find<SoundAssetDataVM>()
|
||||
|
||||
private var onCompleteConsumer: ((SoundAssetData) -> Unit)? = null
|
||||
|
||||
fun onComplete(consumer: (SoundAssetData) -> Unit) {
|
||||
this.onCompleteConsumer = consumer
|
||||
}
|
||||
|
||||
override val root = form {
|
||||
fieldset("Import Sound") {
|
||||
field("Sound Name") {
|
||||
textfield(dataVM.nameProperty) {
|
||||
requestFocus()
|
||||
required()
|
||||
trimWhitespace()
|
||||
}
|
||||
}
|
||||
|
||||
field("Sound File") {
|
||||
this += SingleFileChooserField(dataVM.fileProperty) {
|
||||
type = SingleFileChooserField.Type.FILE
|
||||
validationContext = dataVM.validationContext
|
||||
|
||||
dialogFormat {
|
||||
chooseFile("Sound File Location", arrayOf(FileChooser.ExtensionFilter("OGG Vorbis File", "*.ogg")))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buttonbar {
|
||||
button("Ok") {
|
||||
action {
|
||||
if (dataVM.commit()) {
|
||||
onCompleteConsumer?.let { it(dataVM.item) }
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button("Cancel") {
|
||||
action { close() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.bartlomiejpluta.base.editor.audio.viewmodel
|
||||
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAssetData
|
||||
import tornadofx.ItemViewModel
|
||||
import tornadofx.getValue
|
||||
import tornadofx.setValue
|
||||
|
||||
class SoundAssetDataVM : ItemViewModel<SoundAssetData>(SoundAssetData()) {
|
||||
val nameProperty = bind(SoundAssetData::nameProperty)
|
||||
var name by nameProperty
|
||||
|
||||
val fileProperty = bind(SoundAssetData::fileProperty)
|
||||
var file by fileProperty
|
||||
}
|
||||
@@ -30,6 +30,7 @@ class DefaultProjectAssembler : ProjectAssembler {
|
||||
packager.pack(project.animationsDirectory, targetJar, "BOOT-INF/classes/project/animations")
|
||||
packager.pack(project.fontsDirectory, targetJar, "BOOT-INF/classes/project/fonts")
|
||||
packager.pack(project.widgetsDirectory, targetJar, "BOOT-INF/classes/project/widgets")
|
||||
packager.pack(project.audioDirectory, targetJar, "BOOT-INF/classes/project/audio")
|
||||
packager.copy(project.projectFile, targetJar, "BOOT-INF/classes/project")
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.bartlomiejpluta.base.editor.main.controller
|
||||
import com.bartlomiejpluta.base.editor.animation.view.importing.ImportAnimationFragment
|
||||
import com.bartlomiejpluta.base.editor.animation.viewmodel.AnimationAssetDataVM
|
||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||
import com.bartlomiejpluta.base.editor.audio.view.importing.ImportSoundFragment
|
||||
import com.bartlomiejpluta.base.editor.audio.viewmodel.SoundAssetDataVM
|
||||
import com.bartlomiejpluta.base.editor.code.model.Code
|
||||
import com.bartlomiejpluta.base.editor.code.model.CodeScope
|
||||
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
||||
@@ -214,6 +216,20 @@ class MainController : Controller() {
|
||||
.ifPresent(this::openScript)
|
||||
}
|
||||
|
||||
fun importSound() {
|
||||
val vm = SoundAssetDataVM()
|
||||
val scope = Scope()
|
||||
setInScope(vm, scope)
|
||||
|
||||
find<ImportSoundFragment>(scope).apply {
|
||||
onComplete {
|
||||
projectContext.importSound(it)
|
||||
}
|
||||
|
||||
openModal(block = true, resizable = true)
|
||||
}
|
||||
}
|
||||
|
||||
fun closeAsset(asset: Asset) {
|
||||
when (asset) {
|
||||
is GameMapAsset -> openItems.entries.firstOrNull { (_, item) -> item is GameMap && item.uid == asset.uid }?.key?.let {
|
||||
@@ -236,6 +252,7 @@ class MainController : Controller() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun clearResources() {
|
||||
openItems.clear()
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.bartlomiejpluta.base.editor.project.context
|
||||
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAsset
|
||||
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAssetData
|
||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAsset
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAssetData
|
||||
import com.bartlomiejpluta.base.editor.code.model.Code
|
||||
import com.bartlomiejpluta.base.editor.code.model.CodeType
|
||||
import com.bartlomiejpluta.base.editor.code.service.JavaClassService
|
||||
@@ -222,6 +224,19 @@ class DefaultProjectContext : ProjectContext {
|
||||
}
|
||||
} ?: throw IllegalStateException("There is no open project in the context")
|
||||
|
||||
override fun importSound(data: SoundAssetData) {
|
||||
project?.let {
|
||||
UID.next(it.sounds.map(Asset::uid)).let { uid ->
|
||||
val source = "$uid.${data.file.extension}"
|
||||
val targetFile = File(it.audioDirectory, source)
|
||||
data.file.copyTo(targetFile)
|
||||
it.sounds += SoundAsset(it, uid, source, data.name)
|
||||
|
||||
save()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun deleteAsset(asset: Asset) {
|
||||
project?.let {
|
||||
it.assetLists.firstOrNull { assets -> assets.remove(asset) }
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.project.context
|
||||
|
||||
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAssetData
|
||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAssetData
|
||||
import com.bartlomiejpluta.base.editor.code.model.Code
|
||||
import com.bartlomiejpluta.base.editor.entityset.asset.EntitySetAssetData
|
||||
import com.bartlomiejpluta.base.editor.file.model.FileNode
|
||||
@@ -45,6 +46,8 @@ interface ProjectContext {
|
||||
|
||||
fun createWidget(data: WidgetAssetData): WidgetAsset
|
||||
|
||||
fun importSound(data: SoundAssetData)
|
||||
|
||||
fun deleteAsset(asset: Asset)
|
||||
fun loadScript(fileNode: FileNode): Code
|
||||
fun saveScript(code: Code)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.bartlomiejpluta.base.editor.project.model
|
||||
|
||||
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAsset
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAsset
|
||||
import com.bartlomiejpluta.base.editor.entityset.asset.EntitySet
|
||||
import com.bartlomiejpluta.base.editor.file.model.FileSystemNode
|
||||
import com.bartlomiejpluta.base.editor.gui.font.asset.FontAsset
|
||||
@@ -36,8 +37,9 @@ class Project {
|
||||
val animations = observableListOf<AnimationAsset>()
|
||||
val fonts = observableListOf<FontAsset>()
|
||||
val widgets = observableListOf<WidgetAsset>()
|
||||
val sounds = observableListOf<SoundAsset>()
|
||||
|
||||
val assetLists = listOf(maps, tileSets, images, entitySets, animations, fonts, widgets)
|
||||
val assetLists = listOf(maps, tileSets, images, entitySets, animations, fonts, widgets, sounds)
|
||||
|
||||
val mapsDirectoryProperty = SimpleObjectProperty<File>()
|
||||
var mapsDirectory by mapsDirectoryProperty
|
||||
@@ -67,6 +69,10 @@ class Project {
|
||||
var widgetsDirectory by widgetsDirectoryProperty
|
||||
private set
|
||||
|
||||
val audioDirectoryProperty = SimpleObjectProperty<File>()
|
||||
var audioDirectory by audioDirectoryProperty
|
||||
private set
|
||||
|
||||
val codeDirectoryProperty = SimpleObjectProperty<File>()
|
||||
var codeDirectory by codeDirectoryProperty
|
||||
private set
|
||||
@@ -104,6 +110,7 @@ class Project {
|
||||
animationsDirectory = File(it, ANIMATIONS_DIR)
|
||||
fontsDirectory = File(it, FONTS_DIR)
|
||||
widgetsDirectory = File(it, WIDGETS_DIR)
|
||||
audioDirectory = File(it, AUDIO_DIR)
|
||||
codeDirectory = File(it, CODE_DIR)
|
||||
buildDirectory = File(it, BUILD_DIR)
|
||||
buildClassesDirectory = File(it, BUILD_CLASSES_DIR)
|
||||
@@ -122,6 +129,7 @@ class Project {
|
||||
animationsDirectory?.mkdirs()
|
||||
fontsDirectory?.mkdirs()
|
||||
widgetsDirectory?.mkdirs()
|
||||
audioDirectory?.mkdirs()
|
||||
codeDirectory?.mkdirs()
|
||||
}
|
||||
|
||||
@@ -136,6 +144,7 @@ class Project {
|
||||
const val ANIMATIONS_DIR = "animations"
|
||||
const val FONTS_DIR = "fonts"
|
||||
const val WIDGETS_DIR = "widgets"
|
||||
const val AUDIO_DIR = "audio"
|
||||
const val CODE_DIR = "code"
|
||||
const val BUILD_DIR = "build"
|
||||
const val BUILD_CLASSES_DIR = "$BUILD_DIR/classes"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.bartlomiejpluta.base.editor.project.serial
|
||||
|
||||
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAsset
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAsset
|
||||
import com.bartlomiejpluta.base.editor.entityset.asset.EntitySet
|
||||
import com.bartlomiejpluta.base.editor.gui.font.asset.FontAsset
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAsset
|
||||
@@ -17,18 +18,19 @@ class ProtobufProjectDeserializer : ProjectDeserializer {
|
||||
|
||||
override fun deserialize(input: InputStream): Project {
|
||||
val proto = ProjectProto.Project.parseFrom(input)
|
||||
val project = Project()
|
||||
project.name = proto.name
|
||||
project.runner = proto.runner
|
||||
project.maps.addAll(proto.mapsList.map { deserializeMap(project, it) })
|
||||
project.tileSets.addAll(proto.tileSetsList.map { deserializeTileSet(project, it) })
|
||||
project.images.addAll(proto.imagesList.map { deserializeImage(project, it) })
|
||||
project.entitySets.addAll(proto.entitySetsList.map { deserializeEntitySet(project, it) })
|
||||
project.animations.addAll(proto.animationsList.map { deserializeAnimation(project, it) })
|
||||
project.fonts.addAll(proto.fontsList.map { deserializeFont(project, it) })
|
||||
project.widgets.addAll(proto.widgetsList.map { deserializeWidget(project, it) })
|
||||
|
||||
return project
|
||||
return Project().apply {
|
||||
name = proto.name
|
||||
runner = proto.runner
|
||||
maps.addAll(proto.mapsList.map { deserializeMap(this, it) })
|
||||
tileSets.addAll(proto.tileSetsList.map { deserializeTileSet(this, it) })
|
||||
images.addAll(proto.imagesList.map { deserializeImage(this, it) })
|
||||
entitySets.addAll(proto.entitySetsList.map { deserializeEntitySet(this, it) })
|
||||
animations.addAll(proto.animationsList.map { deserializeAnimation(this, it) })
|
||||
fonts.addAll(proto.fontsList.map { deserializeFont(this, it) })
|
||||
widgets.addAll(proto.widgetsList.map { deserializeWidget(this, it) })
|
||||
sounds.addAll(proto.soundsList.map { deserializeSound(this, it) })
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserializeMap(project: Project, map: ProjectProto.GameMapAsset) = GameMapAsset(
|
||||
@@ -83,4 +85,11 @@ class ProtobufProjectDeserializer : ProjectDeserializer {
|
||||
uid = widget.uid,
|
||||
name = widget.name
|
||||
)
|
||||
|
||||
private fun deserializeSound(project: Project, sound: ProjectProto.SoundAsset) = SoundAsset(
|
||||
project = project,
|
||||
uid = sound.uid,
|
||||
source = sound.source,
|
||||
name = sound.name
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.bartlomiejpluta.base.editor.project.serial
|
||||
|
||||
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAsset
|
||||
import com.bartlomiejpluta.base.editor.audio.asset.SoundAsset
|
||||
import com.bartlomiejpluta.base.editor.entityset.asset.EntitySet
|
||||
import com.bartlomiejpluta.base.editor.gui.font.asset.FontAsset
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAsset
|
||||
@@ -26,6 +27,7 @@ class ProtobufProjectSerializer : ProjectSerializer {
|
||||
proto.addAllAnimations(item.animations.map(this::serializeAnimation))
|
||||
proto.addAllFonts(item.fonts.map(this::serializeFont))
|
||||
proto.addAllWidgets(item.widgets.map(this::serializeWidget))
|
||||
proto.addAllSounds(item.sounds.map(this::serializeSound))
|
||||
proto.build().writeTo(output)
|
||||
}
|
||||
|
||||
@@ -76,4 +78,10 @@ class ProtobufProjectSerializer : ProjectSerializer {
|
||||
.setSource(widget.source)
|
||||
.setName(widget.name)
|
||||
.build()
|
||||
|
||||
private fun serializeSound(sound: SoundAsset) = ProjectProto.SoundAsset.newBuilder()
|
||||
.setUid(sound.uid)
|
||||
.setSource(sound.source)
|
||||
.setName(sound.name)
|
||||
.build()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user