[Editor] Enable creating Widgets in Editor
The Editor does not yet support XML syntax highlighting (the Java highlighter is used as temporary replacement), also the tab name of widget asset shows the actual file name (composed of UID) instead of the asset name provided by user.
This commit is contained in:
@@ -4,6 +4,7 @@ import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||
import com.bartlomiejpluta.base.editor.asset.model.AssetCategory
|
||||
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
|
||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAsset
|
||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset
|
||||
@@ -72,6 +73,7 @@ class AssetTreeCell(renameAsset: (asset: Asset, name: String) -> Asset, deleteAs
|
||||
is ImageAsset -> FontIcon("fa-image")
|
||||
is EntitySet -> FontIcon("fa-male")
|
||||
is FontAsset -> FontIcon("fa-font")
|
||||
is WidgetAsset -> FontIcon("fa-tachometer")
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.bartlomiejpluta.base.editor.asset.model
|
||||
|
||||
import com.bartlomiejpluta.base.editor.file.model.FileNode
|
||||
import com.bartlomiejpluta.base.editor.file.model.FileSystemNode
|
||||
import javafx.beans.binding.Bindings.createObjectBinding
|
||||
import javafx.beans.property.ObjectProperty
|
||||
import javafx.beans.property.SimpleStringProperty
|
||||
import javafx.beans.value.ObservableValue
|
||||
import tornadofx.getValue
|
||||
import tornadofx.setValue
|
||||
import java.io.File
|
||||
@@ -14,5 +17,8 @@ abstract class Asset(directory: ObjectProperty<File>, val uid: String, val sourc
|
||||
val fileProperty = createObjectBinding({ File(directory.value, source) }, directory)
|
||||
val file by fileProperty
|
||||
|
||||
val fileNodeProperty: ObservableValue<FileNode> = createObjectBinding({ FileSystemNode(file) }, fileProperty)
|
||||
val fileNode by fileNodeProperty
|
||||
|
||||
override fun toString() = "${this.javaClass.simpleName}[name=$name, uid=$uid]"
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.bartlomiejpluta.base.editor.asset.view.list
|
||||
import com.bartlomiejpluta.base.editor.asset.component.AssetTreeCell
|
||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||
import com.bartlomiejpluta.base.editor.asset.model.AssetCategory
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAsset
|
||||
import com.bartlomiejpluta.base.editor.main.controller.MainController
|
||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||
@@ -35,13 +36,18 @@ class AssetsListView : View() {
|
||||
menuitem("Import Font...") { mainController.importFont() }
|
||||
}
|
||||
|
||||
private val widgets = AssetCategory("Widgets").apply {
|
||||
menuitem("New Widget...") { mainController.createEmptyWidget() }
|
||||
}
|
||||
|
||||
private val rootItem = AssetCategory(
|
||||
name = "Project", items = observableListOf(
|
||||
maps,
|
||||
tileSets,
|
||||
images,
|
||||
entitySet,
|
||||
fonts
|
||||
fonts,
|
||||
widgets
|
||||
)
|
||||
)
|
||||
|
||||
@@ -54,6 +60,7 @@ class AssetsListView : View() {
|
||||
Bindings.bindContent(images.items, it.images)
|
||||
Bindings.bindContent(entitySet.items, it.entitySets)
|
||||
Bindings.bindContent(fonts.items, it.fonts)
|
||||
Bindings.bindContent(widgets.items, it.widgets)
|
||||
root.root.expandAll()
|
||||
}
|
||||
}
|
||||
@@ -79,6 +86,7 @@ class AssetsListView : View() {
|
||||
if (event.clickCount == 2) {
|
||||
when (val item = selectionModel?.selectedItem?.value) {
|
||||
is GameMapAsset -> mainController.openMap(item.uid)
|
||||
is WidgetAsset -> mainController.openScript(item.fileNode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.bartlomiejpluta.base.editor.code.model
|
||||
|
||||
enum class CodeType {
|
||||
JAVA
|
||||
JAVA,
|
||||
XML
|
||||
}
|
||||
@@ -23,6 +23,7 @@ class CodeEditorView : View() {
|
||||
private val highlighter = Bindings.createObjectBinding({
|
||||
when (codeVM.type!!) {
|
||||
CodeType.JAVA -> javaSyntaxHighlighter
|
||||
CodeType.XML -> javaSyntaxHighlighter
|
||||
}
|
||||
}, codeVM.typeProperty)
|
||||
|
||||
@@ -38,6 +39,7 @@ class CodeEditorView : View() {
|
||||
|
||||
fun shutdown() {
|
||||
editor.shutdownHighlighterThread()
|
||||
codeVM.fileNode
|
||||
}
|
||||
|
||||
override val root = borderpane {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.editor.gui.widget.asset
|
||||
|
||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||
import com.bartlomiejpluta.base.editor.project.model.Project
|
||||
|
||||
class WidgetAsset(project: Project, uid: String, name: String) :
|
||||
Asset(project.widgetsDirectoryProperty, uid, "$uid.xml", name)
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.bartlomiejpluta.base.editor.gui.widget.asset
|
||||
|
||||
import tornadofx.getValue
|
||||
import tornadofx.setValue
|
||||
import tornadofx.toProperty
|
||||
|
||||
class WidgetAssetData(name: String) {
|
||||
val nameProperty = name.toProperty()
|
||||
var name by nameProperty
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import com.bartlomiejpluta.base.editor.event.SelectMainViewTabEvent
|
||||
import com.bartlomiejpluta.base.editor.file.model.FileNode
|
||||
import com.bartlomiejpluta.base.editor.gui.font.view.importing.ImportFontFragment
|
||||
import com.bartlomiejpluta.base.editor.gui.font.viewmodel.FontAssetDataVM
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAsset
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAssetData
|
||||
import com.bartlomiejpluta.base.editor.image.view.importing.ImportImageFragment
|
||||
import com.bartlomiejpluta.base.editor.image.viewmodel.ImageAssetDataVM
|
||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||
@@ -24,6 +26,7 @@ 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.TileSetAssetDataVM
|
||||
import javafx.scene.control.TextInputDialog
|
||||
import javafx.stage.FileChooser
|
||||
import org.springframework.stereotype.Component
|
||||
import tornadofx.*
|
||||
@@ -183,6 +186,29 @@ class MainController : Controller() {
|
||||
}
|
||||
}
|
||||
|
||||
fun createEmptyWidget() {
|
||||
TextInputDialog().apply {
|
||||
width = 300.0
|
||||
contentText = "Widget name"
|
||||
title = "New Widget"
|
||||
}
|
||||
.showAndWait()
|
||||
.map(::WidgetAssetData)
|
||||
.map(projectContext::createWidget)
|
||||
.map(WidgetAsset::fileNode)
|
||||
.ifPresent(this::openScript)
|
||||
}
|
||||
|
||||
fun closeAsset(asset: Asset) {
|
||||
when (asset) {
|
||||
is GameMapAsset -> openItems.entries.firstOrNull { (_, item) -> item is GameMap && item.uid == asset.uid }?.key?.let {
|
||||
openItems.remove(it)
|
||||
}
|
||||
|
||||
is WidgetAsset -> closeScript(asset.fileNode)
|
||||
}
|
||||
}
|
||||
|
||||
fun closeScript(fsNode: FileNode) {
|
||||
openItems.entries.firstOrNull { (_, item) -> item is Code && item.fileNode.absolutePath == fsNode.absolutePath }?.key?.let {
|
||||
openItems.remove(it)
|
||||
@@ -195,14 +221,6 @@ class MainController : Controller() {
|
||||
}
|
||||
}
|
||||
|
||||
fun closeAsset(asset: Asset) {
|
||||
when (asset) {
|
||||
is GameMapAsset -> openItems.entries.firstOrNull { (_, item) -> item is GameMap && item.uid == asset.uid }?.key?.let {
|
||||
openItems.remove(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clearResources() {
|
||||
openItems.clear()
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import com.bartlomiejpluta.base.editor.entityset.asset.EntitySetAssetData
|
||||
import com.bartlomiejpluta.base.editor.file.model.FileNode
|
||||
import com.bartlomiejpluta.base.editor.gui.font.asset.FontAsset
|
||||
import com.bartlomiejpluta.base.editor.gui.font.asset.FontAssetData
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAsset
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAssetData
|
||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAsset
|
||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAssetData
|
||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||
@@ -192,6 +194,19 @@ class DefaultProjectContext : ProjectContext {
|
||||
}
|
||||
}
|
||||
|
||||
override fun createWidget(data: WidgetAssetData) = project?.let {
|
||||
UID.next(it.widgets.map(Asset::uid)).let { uid ->
|
||||
val asset = WidgetAsset(it, uid, data.name)
|
||||
val file = File(it.widgetsDirectory, asset.source)
|
||||
file.createNewFile()
|
||||
it.widgets += asset
|
||||
|
||||
save()
|
||||
|
||||
asset
|
||||
}
|
||||
} ?: throw IllegalStateException("There is no open project in the context")
|
||||
|
||||
override fun deleteAsset(asset: Asset) {
|
||||
project?.let {
|
||||
it.assetLists.firstOrNull { assets -> assets.remove(asset) }
|
||||
@@ -206,6 +221,7 @@ class DefaultProjectContext : ProjectContext {
|
||||
bind(createObjectBinding({
|
||||
when (fileNode.extension.toLowerCase()) {
|
||||
"java" -> CodeType.JAVA
|
||||
"xml" -> CodeType.XML
|
||||
else -> throw IllegalStateException("Unsupported script type")
|
||||
}
|
||||
}))
|
||||
|
||||
@@ -5,6 +5,8 @@ import com.bartlomiejpluta.base.editor.code.model.Code
|
||||
import com.bartlomiejpluta.base.editor.entityset.asset.EntitySetAssetData
|
||||
import com.bartlomiejpluta.base.editor.file.model.FileNode
|
||||
import com.bartlomiejpluta.base.editor.gui.font.asset.FontAssetData
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAsset
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAssetData
|
||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAsset
|
||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAssetData
|
||||
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
|
||||
@@ -38,6 +40,8 @@ interface ProjectContext {
|
||||
|
||||
fun importFont(data: FontAssetData)
|
||||
|
||||
fun createWidget(data: WidgetAssetData): WidgetAsset
|
||||
|
||||
fun deleteAsset(asset: Asset)
|
||||
fun loadScript(fileNode: FileNode): Code
|
||||
fun saveScript(code: Code)
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.bartlomiejpluta.base.editor.project.model
|
||||
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
|
||||
import com.bartlomiejpluta.base.editor.gui.widget.asset.WidgetAsset
|
||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAsset
|
||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset
|
||||
@@ -32,8 +33,9 @@ class Project {
|
||||
val images = observableListOf<ImageAsset>()
|
||||
val entitySets = observableListOf<EntitySet>()
|
||||
val fonts = observableListOf<FontAsset>()
|
||||
val widgets = observableListOf<WidgetAsset>()
|
||||
|
||||
val assetLists = listOf(maps, tileSets, images, entitySets, fonts)
|
||||
val assetLists = listOf(maps, tileSets, images, entitySets, fonts, widgets)
|
||||
|
||||
val mapsDirectoryProperty = SimpleObjectProperty<File>()
|
||||
var mapsDirectory by mapsDirectoryProperty
|
||||
@@ -55,6 +57,10 @@ class Project {
|
||||
var fontsDirectory by fontsDirectoryProperty
|
||||
private set
|
||||
|
||||
val widgetsDirectoryProperty = SimpleObjectProperty<File>()
|
||||
var widgetsDirectory by widgetsDirectoryProperty
|
||||
private set
|
||||
|
||||
val codeDirectoryProperty = SimpleObjectProperty<File>()
|
||||
var codeDirectory by codeDirectoryProperty
|
||||
private set
|
||||
@@ -90,6 +96,7 @@ class Project {
|
||||
imagesDirectory = File(it, IMAGES_DIR)
|
||||
entitySetsDirectory = File(it, ENTITY_SETS_DIR)
|
||||
fontsDirectory = File(it, FONTS_DIR)
|
||||
widgetsDirectory = File(it, WIDGETS_DIR)
|
||||
codeDirectory = File(it, CODE_DIR)
|
||||
buildDirectory = File(it, BUILD_DIR)
|
||||
buildClassesDirectory = File(it, BUILD_CLASSES_DIR)
|
||||
@@ -106,6 +113,7 @@ class Project {
|
||||
imagesDirectory?.mkdirs()
|
||||
entitySetsDirectory?.mkdirs()
|
||||
fontsDirectory?.mkdirs()
|
||||
widgetsDirectory?.mkdirs()
|
||||
codeDirectory?.mkdirs()
|
||||
}
|
||||
|
||||
@@ -118,6 +126,7 @@ class Project {
|
||||
const val IMAGES_DIR = "images"
|
||||
const val ENTITY_SETS_DIR = "entsets"
|
||||
const val FONTS_DIR = "fonts"
|
||||
const val WIDGETS_DIR = "widgets"
|
||||
const val CODE_DIR = "code"
|
||||
const val BUILD_DIR = "build"
|
||||
const val BUILD_CLASSES_DIR = "$BUILD_DIR/classes"
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.project.serial
|
||||
|
||||
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
|
||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAsset
|
||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||
import com.bartlomiejpluta.base.editor.project.model.Project
|
||||
@@ -23,6 +24,7 @@ class ProtobufProjectDeserializer : ProjectDeserializer {
|
||||
project.images.addAll(proto.imagesList.map { deserializeImage(project, it) })
|
||||
project.entitySets.addAll(proto.entitySetsList.map { deserializeEntitySet(project, it) })
|
||||
project.fonts.addAll(proto.fontsList.map { deserializeFont(project, it) })
|
||||
project.widgets.addAll(proto.widgetsList.map { deserializeWidget(project, it) })
|
||||
|
||||
return project
|
||||
}
|
||||
@@ -64,4 +66,10 @@ class ProtobufProjectDeserializer : ProjectDeserializer {
|
||||
source = fontAsset.source,
|
||||
name = fontAsset.name
|
||||
)
|
||||
|
||||
private fun deserializeWidget(project: Project, widget: ProjectProto.WidgetAsset) = WidgetAsset(
|
||||
project = project,
|
||||
uid = widget.uid,
|
||||
name = widget.name
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.project.serial
|
||||
|
||||
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
|
||||
import com.bartlomiejpluta.base.editor.image.asset.ImageAsset
|
||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||
import com.bartlomiejpluta.base.editor.project.model.Project
|
||||
@@ -22,6 +23,7 @@ class ProtobufProjectSerializer : ProjectSerializer {
|
||||
proto.addAllImages(item.images.map(this::serializeImage))
|
||||
proto.addAllEntitySets(item.entitySets.map(this::serializeEntitySet))
|
||||
proto.addAllFonts(item.fonts.map(this::serializeFont))
|
||||
proto.addAllWidgets(item.widgets.map(this::serializeWidget))
|
||||
proto.build().writeTo(output)
|
||||
}
|
||||
|
||||
@@ -58,4 +60,9 @@ class ProtobufProjectSerializer : ProjectSerializer {
|
||||
.setSource(font.source)
|
||||
.setName(font.name)
|
||||
.build()
|
||||
|
||||
private fun serializeWidget(widget: WidgetAsset) = ProjectProto.WidgetAsset.newBuilder()
|
||||
.setUid(widget.uid)
|
||||
.setName(widget.name)
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ message Project {
|
||||
repeated ImageAsset images = 5;
|
||||
repeated EntitySetAsset entitySets = 6;
|
||||
repeated FontAsset fonts = 7;
|
||||
repeated WidgetAsset widgets = 8;
|
||||
}
|
||||
|
||||
message GameMapAsset {
|
||||
@@ -45,4 +46,9 @@ message FontAsset {
|
||||
required string uid = 1;
|
||||
required string source = 2;
|
||||
required string name = 3;
|
||||
}
|
||||
|
||||
message WidgetAsset {
|
||||
required string uid = 1;
|
||||
required string name = 3;
|
||||
}
|
||||
Reference in New Issue
Block a user