[Editor] Enable opening the code scripts via double-click in the Project Structure panel
This commit is contained in:
@@ -3,11 +3,24 @@ package com.bartlomiejpluta.base.editor.code.model
|
|||||||
import tornadofx.getValue
|
import tornadofx.getValue
|
||||||
import tornadofx.setValue
|
import tornadofx.setValue
|
||||||
import tornadofx.toProperty
|
import tornadofx.toProperty
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class Code(codeType: CodeType, code: String) {
|
class Code(file: File) {
|
||||||
val typeProperty = codeType.toProperty()
|
val fileProperty = file.toProperty()
|
||||||
var type by typeProperty
|
val file by fileProperty
|
||||||
|
|
||||||
val codeProperty = code.toProperty()
|
val typeProperty = deduceCodeType(file).toProperty()
|
||||||
|
val type by typeProperty
|
||||||
|
|
||||||
|
val codeProperty = file.readText().toProperty()
|
||||||
var code by codeProperty
|
var code by codeProperty
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun deduceCodeType(file: File): CodeType {
|
||||||
|
return when (file.extension.toLowerCase()) {
|
||||||
|
"java" -> CodeType.JAVA
|
||||||
|
else -> throw IllegalStateException("Unsupported script type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ import javafx.scene.control.MenuItem
|
|||||||
import javafx.scene.control.cell.TextFieldTreeCell
|
import javafx.scene.control.cell.TextFieldTreeCell
|
||||||
import org.kordamp.ikonli.javafx.FontIcon
|
import org.kordamp.ikonli.javafx.FontIcon
|
||||||
import tornadofx.action
|
import tornadofx.action
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class StructureItemTreeCell(renameAsset: (asset: Asset, name: String) -> Asset, deleteAsset: (asset: Asset) -> Unit) :
|
class StructureItemTreeCell(renameAsset: (asset: Asset, name: String) -> Asset, deleteAsset: (asset: Asset) -> Unit) :
|
||||||
TextFieldTreeCell<Any>() {
|
TextFieldTreeCell<Any>() {
|
||||||
@@ -54,6 +55,7 @@ class StructureItemTreeCell(renameAsset: (asset: Asset, name: String) -> Asset,
|
|||||||
text = when (item) {
|
text = when (item) {
|
||||||
is StructureCategory -> item.name
|
is StructureCategory -> item.name
|
||||||
is Asset -> item.name
|
is Asset -> item.name
|
||||||
|
is File -> item.name
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +64,21 @@ class StructureItemTreeCell(renameAsset: (asset: Asset, name: String) -> Asset,
|
|||||||
is GameMapAsset -> FontIcon("fa-map")
|
is GameMapAsset -> FontIcon("fa-map")
|
||||||
is TileSetAsset -> FontIcon("fa-th")
|
is TileSetAsset -> FontIcon("fa-th")
|
||||||
is ImageAsset -> FontIcon("fa-image")
|
is ImageAsset -> FontIcon("fa-image")
|
||||||
|
is File -> FontIcon(getFileIcon(item))
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun getFileIcon(file: File): String {
|
||||||
|
if (file.isDirectory) {
|
||||||
|
return "fa-folder"
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (file.extension.toLowerCase()) {
|
||||||
|
"java" -> "fa-code"
|
||||||
|
else -> "fa-file"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.bartlomiejpluta.base.editor.main.controller
|
package com.bartlomiejpluta.base.editor.main.controller
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||||
|
import com.bartlomiejpluta.base.editor.code.model.Code
|
||||||
|
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
||||||
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
||||||
import com.bartlomiejpluta.base.editor.image.view.importing.ImportImageFragment
|
import com.bartlomiejpluta.base.editor.image.view.importing.ImportImageFragment
|
||||||
import com.bartlomiejpluta.base.editor.image.viewmodel.ImageAssetDataVM
|
import com.bartlomiejpluta.base.editor.image.viewmodel.ImageAssetDataVM
|
||||||
@@ -18,6 +20,7 @@ import com.bartlomiejpluta.base.editor.tileset.viewmodel.TileSetAssetDataVM
|
|||||||
import javafx.stage.FileChooser
|
import javafx.stage.FileChooser
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
import java.io.File
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -82,6 +85,17 @@ class MainController : Controller() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun openScript(file: File) {
|
||||||
|
if (openItems.count { (_, item) -> item is Code && item.file.absolutePath == file.absolutePath } == 0) {
|
||||||
|
val code = Code(file)
|
||||||
|
val vm = CodeVM(code)
|
||||||
|
val scope = UndoableScope()
|
||||||
|
setInScope(vm, scope)
|
||||||
|
|
||||||
|
openItems[scope] = code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun importTileSet() {
|
fun importTileSet() {
|
||||||
val vm = TileSetAssetDataVM()
|
val vm = TileSetAssetDataVM()
|
||||||
val scope = Scope()
|
val scope = Scope()
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ import javafx.collections.ObservableList
|
|||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
||||||
import javafx.scene.control.ContextMenu
|
import javafx.scene.control.ContextMenu
|
||||||
import javafx.scene.control.MenuItem
|
import javafx.scene.control.MenuItem
|
||||||
import tornadofx.*
|
import tornadofx.action
|
||||||
|
import tornadofx.getValue
|
||||||
|
import tornadofx.observableListOf
|
||||||
|
import tornadofx.toProperty
|
||||||
|
|
||||||
class StructureCategory(name: String = "", var items: ObservableList<out Any> = observableListOf()) {
|
class StructureCategory(name: String = "", var items: ObservableList<in Any> = observableListOf()) {
|
||||||
val nameProperty = name.toProperty()
|
val nameProperty = name.toProperty()
|
||||||
val name by nameProperty
|
val name by nameProperty
|
||||||
val menu = ContextMenu()
|
val menu = ContextMenu()
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class MainView : View("BASE Game Editor") {
|
|||||||
val vm = CodeVM(item)
|
val vm = CodeVM(item)
|
||||||
setInScope(vm, scope)
|
setInScope(vm, scope)
|
||||||
content = find<CodeEditorFragment>(scope).root
|
content = find<CodeEditorFragment>(scope).root
|
||||||
text = "Test.java"
|
textProperty().bindBidirectional(item.fileProperty.select { it.name.toProperty() })
|
||||||
graphic = FontIcon("fa-code")
|
graphic = FontIcon("fa-code")
|
||||||
setOnClosed { mainController.openItems.remove(scope) }
|
setOnClosed { mainController.openItems.remove(scope) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
|||||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||||
import javafx.beans.binding.Bindings
|
import javafx.beans.binding.Bindings
|
||||||
import javafx.scene.control.TreeItem
|
import javafx.scene.control.TreeItem
|
||||||
|
import javafx.scene.control.TreeView
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
class ProjectStructureView : View() {
|
class ProjectStructureView : View() {
|
||||||
@@ -27,11 +29,16 @@ class ProjectStructureView : View() {
|
|||||||
menuitem("Import Image...") { mainController.importImage() }
|
menuitem("Import Image...") { mainController.importImage() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val structureCode = StructureCategory("Code").apply {
|
||||||
|
menuitem("Refresh") { this@ProjectStructureView.treeView.refresh() }
|
||||||
|
}
|
||||||
|
|
||||||
private val structureRoot = StructureCategory(
|
private val structureRoot = StructureCategory(
|
||||||
name = "Project", items = observableListOf(
|
name = "Project", items = observableListOf(
|
||||||
structureMaps,
|
structureMaps,
|
||||||
structureTileSets,
|
structureTileSets,
|
||||||
structureImages
|
structureImages,
|
||||||
|
structureCode
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,18 +49,23 @@ class ProjectStructureView : View() {
|
|||||||
Bindings.bindContent(structureMaps.items, it.maps)
|
Bindings.bindContent(structureMaps.items, it.maps)
|
||||||
Bindings.bindContent(structureTileSets.items, it.tileSets)
|
Bindings.bindContent(structureTileSets.items, it.tileSets)
|
||||||
Bindings.bindContent(structureImages.items, it.images)
|
Bindings.bindContent(structureImages.items, it.images)
|
||||||
|
|
||||||
|
structureCode.items.clear()
|
||||||
|
structureCode.items.add(it.codeDirectory)
|
||||||
|
|
||||||
root.root.expandAll()
|
root.root.expandAll()
|
||||||
root.refresh()
|
root.refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val root = treeview<Any> {
|
private val treeView: TreeView<Any> = treeview<Any> {
|
||||||
root = TreeItem(structureRoot)
|
root = TreeItem(structureRoot)
|
||||||
|
|
||||||
populate {
|
populate {
|
||||||
when (val value = it.value) {
|
when (val value = it.value) {
|
||||||
is StructureCategory -> value.items
|
is StructureCategory -> value.items
|
||||||
|
is File -> value.listFiles()?.toList() ?: observableListOf()
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,6 +78,7 @@ class ProjectStructureView : View() {
|
|||||||
if (event.clickCount == 2) {
|
if (event.clickCount == 2) {
|
||||||
when (val item = selectionModel?.selectedItem?.value) {
|
when (val item = selectionModel?.selectedItem?.value) {
|
||||||
is GameMapAsset -> mainController.openMap(item.uid)
|
is GameMapAsset -> mainController.openMap(item.uid)
|
||||||
|
is File -> item.takeIf { it.isFile }?.let { mainController.openScript(item) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +86,8 @@ class ProjectStructureView : View() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val root = treeView
|
||||||
|
|
||||||
private fun renameAsset(asset: Asset, name: String) = asset.apply {
|
private fun renameAsset(asset: Asset, name: String) = asset.apply {
|
||||||
this.name = name
|
this.name = name
|
||||||
projectContext.save()
|
projectContext.save()
|
||||||
|
|||||||
@@ -35,12 +35,17 @@ class Project {
|
|||||||
var imagesDirectory by imagesDirectoryProperty
|
var imagesDirectory by imagesDirectoryProperty
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
val codeDirectoryProperty = SimpleObjectProperty<File>()
|
||||||
|
var codeDirectory by codeDirectoryProperty
|
||||||
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
sourceDirectoryProperty.addListener { _, _, dir ->
|
sourceDirectoryProperty.addListener { _, _, dir ->
|
||||||
dir?.let {
|
dir?.let {
|
||||||
mapsDirectory = File(it, MAPS_DIR)
|
mapsDirectory = File(it, MAPS_DIR)
|
||||||
tileSetsDirectory = File(it, TILESETS_DIR)
|
tileSetsDirectory = File(it, TILESETS_DIR)
|
||||||
imagesDirectory = File(it, IMAGES_DIR)
|
imagesDirectory = File(it, IMAGES_DIR)
|
||||||
|
codeDirectory = File(it, CODE_DIR)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,11 +55,13 @@ class Project {
|
|||||||
mapsDirectory?.mkdirs()
|
mapsDirectory?.mkdirs()
|
||||||
tileSetsDirectory?.mkdirs()
|
tileSetsDirectory?.mkdirs()
|
||||||
imagesDirectory?.mkdirs()
|
imagesDirectory?.mkdirs()
|
||||||
|
codeDirectory?.mkdirs()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MAPS_DIR = "maps"
|
const val MAPS_DIR = "maps"
|
||||||
const val TILESETS_DIR = "tilesets"
|
const val TILESETS_DIR = "tilesets"
|
||||||
const val IMAGES_DIR = "images"
|
const val IMAGES_DIR = "images"
|
||||||
|
const val CODE_DIR = "code"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user