[Editor] Extract the Scripts tree view from the Project Structure panel
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
package com.bartlomiejpluta.base.editor.code.component
|
||||
|
||||
import javafx.scene.control.TreeCell
|
||||
import javafx.util.StringConverter
|
||||
import java.io.File
|
||||
|
||||
class CodeStructureItemStringConverter(
|
||||
private val cell: TreeCell<File>,
|
||||
private val onUpdate: (item: File, name: String) -> File
|
||||
) : StringConverter<File>() {
|
||||
override fun toString(item: File?): String = when (item) {
|
||||
is File -> item.name
|
||||
else -> ""
|
||||
}
|
||||
|
||||
// Disclaimer:
|
||||
// Because of the fact that we want to support undo/redo mechanism
|
||||
// the actual update must be done from the execute() method of the Command object
|
||||
// so that the Command object has access to the actual as well as the new value of layer name.
|
||||
// That's why we are running the submission logic in the converter.
|
||||
override fun fromString(string: String?) = string?.let { onUpdate(cell.item, it) }
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.bartlomiejpluta.base.editor.code.component
|
||||
|
||||
import javafx.scene.control.ContextMenu
|
||||
import javafx.scene.control.MenuItem
|
||||
import javafx.scene.control.cell.TextFieldTreeCell
|
||||
import org.kordamp.ikonli.javafx.FontIcon
|
||||
import tornadofx.action
|
||||
import java.io.File
|
||||
|
||||
class CodeStructureItemTreeCell(renameFile: (file: File, name: String) -> File, deleteFile: (file: File) -> Unit) :
|
||||
TextFieldTreeCell<File>() {
|
||||
private val fileMenu = ContextMenu()
|
||||
|
||||
init {
|
||||
converter = CodeStructureItemStringConverter(this, renameFile)
|
||||
MenuItem("Rename").apply {
|
||||
action {
|
||||
treeView.isEditable = true
|
||||
startEdit()
|
||||
treeView.isEditable = false
|
||||
}
|
||||
|
||||
fileMenu.items.add(this)
|
||||
}
|
||||
|
||||
MenuItem("Delete").apply {
|
||||
action {
|
||||
deleteFile(item as File)
|
||||
}
|
||||
|
||||
fileMenu.items.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateItem(item: File?, empty: Boolean) {
|
||||
super.updateItem(item, empty)
|
||||
|
||||
if (empty || item == null) {
|
||||
text = null
|
||||
graphic = null
|
||||
return
|
||||
}
|
||||
|
||||
contextMenu = if (isEditing) null else fileMenu
|
||||
text = item.name
|
||||
graphic = FontIcon(getFileIcon(item))
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.bartlomiejpluta.base.editor.code.view
|
||||
|
||||
import com.bartlomiejpluta.base.editor.code.component.CodeStructureItemTreeCell
|
||||
import com.bartlomiejpluta.base.editor.main.controller.MainController
|
||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||
import javafx.scene.control.TreeItem
|
||||
import javafx.scene.control.TreeView
|
||||
import tornadofx.*
|
||||
import java.io.File
|
||||
|
||||
class CodeStructureView : View() {
|
||||
private val projectContext: ProjectContext by di()
|
||||
private val mainController: MainController by di()
|
||||
|
||||
init {
|
||||
projectContext.projectProperty.addListener { _, _, project ->
|
||||
project?.let {
|
||||
treeView.root = TreeItem(it.codeDirectory)
|
||||
treeView.populate { item -> item.value?.listFiles()?.toList() }
|
||||
root.root.expandAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val treeView: TreeView<File> = treeview {
|
||||
setCellFactory {
|
||||
CodeStructureItemTreeCell(this@CodeStructureView::renameFile, this@CodeStructureView::deleteFile)
|
||||
}
|
||||
|
||||
setOnMouseClicked { event ->
|
||||
if (event.clickCount == 2) {
|
||||
selectionModel?.selectedItem?.value
|
||||
.takeIf { it?.isFile ?: false }
|
||||
?.let { mainController.openScript(it) }
|
||||
}
|
||||
|
||||
event.consume()
|
||||
}
|
||||
}
|
||||
|
||||
override val root = treeView
|
||||
|
||||
private fun renameFile(file: File, name: String) = file.apply {
|
||||
// TODO
|
||||
}
|
||||
|
||||
private fun deleteFile(file: File) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import javafx.scene.control.MenuItem
|
||||
import javafx.scene.control.cell.TextFieldTreeCell
|
||||
import org.kordamp.ikonli.javafx.FontIcon
|
||||
import tornadofx.action
|
||||
import java.io.File
|
||||
|
||||
class StructureItemTreeCell(renameAsset: (asset: Asset, name: String) -> Asset, deleteAsset: (asset: Asset) -> Unit) :
|
||||
TextFieldTreeCell<Any>() {
|
||||
@@ -55,7 +54,6 @@ class StructureItemTreeCell(renameAsset: (asset: Asset, name: String) -> Asset,
|
||||
text = when (item) {
|
||||
is StructureCategory -> item.name
|
||||
is Asset -> item.name
|
||||
is File -> item.name
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -64,21 +62,7 @@ class StructureItemTreeCell(renameAsset: (asset: Asset, name: String) -> Asset,
|
||||
is GameMapAsset -> FontIcon("fa-map")
|
||||
is TileSetAsset -> FontIcon("fa-th")
|
||||
is ImageAsset -> FontIcon("fa-image")
|
||||
is File -> FontIcon(getFileIcon(item))
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.main.view
|
||||
|
||||
import com.bartlomiejpluta.base.editor.code.model.Code
|
||||
import com.bartlomiejpluta.base.editor.code.view.CodeEditorFragment
|
||||
import com.bartlomiejpluta.base.editor.code.view.CodeStructureView
|
||||
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
||||
import com.bartlomiejpluta.base.editor.main.controller.MainController
|
||||
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
|
||||
@@ -20,6 +21,7 @@ class MainView : View("BASE Game Editor") {
|
||||
|
||||
private val mainMenuView = find<MainMenuView>()
|
||||
private val projectStructureView = find<ProjectStructureView>()
|
||||
private val codeStructure = find<CodeStructureView>()
|
||||
|
||||
init {
|
||||
projectContext.projectProperty.addListener { _, _, project ->
|
||||
@@ -68,6 +70,10 @@ class MainView : View("BASE Game Editor") {
|
||||
}
|
||||
|
||||
left = drawer(multiselect = true) {
|
||||
item("Code Structure", expanded = true) {
|
||||
this += codeStructure
|
||||
}
|
||||
|
||||
item("Project Structure", expanded = true) {
|
||||
this += projectStructureView
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import javafx.beans.binding.Bindings
|
||||
import javafx.scene.control.TreeItem
|
||||
import javafx.scene.control.TreeView
|
||||
import tornadofx.*
|
||||
import java.io.File
|
||||
|
||||
|
||||
class ProjectStructureView : View() {
|
||||
@@ -29,16 +28,11 @@ class ProjectStructureView : View() {
|
||||
menuitem("Import Image...") { mainController.importImage() }
|
||||
}
|
||||
|
||||
private val structureCode = StructureCategory("Code").apply {
|
||||
menuitem("Refresh") { this@ProjectStructureView.treeView.refresh() }
|
||||
}
|
||||
|
||||
private val structureRoot = StructureCategory(
|
||||
name = "Project", items = observableListOf(
|
||||
structureMaps,
|
||||
structureTileSets,
|
||||
structureImages,
|
||||
structureCode
|
||||
structureImages
|
||||
)
|
||||
)
|
||||
|
||||
@@ -49,12 +43,7 @@ class ProjectStructureView : View() {
|
||||
Bindings.bindContent(structureMaps.items, it.maps)
|
||||
Bindings.bindContent(structureTileSets.items, it.tileSets)
|
||||
Bindings.bindContent(structureImages.items, it.images)
|
||||
|
||||
structureCode.items.clear()
|
||||
structureCode.items.add(it.codeDirectory)
|
||||
|
||||
root.root.expandAll()
|
||||
root.refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,10 +51,11 @@ class ProjectStructureView : View() {
|
||||
private val treeView: TreeView<Any> = treeview<Any> {
|
||||
root = TreeItem(structureRoot)
|
||||
|
||||
isShowRoot = false
|
||||
|
||||
populate {
|
||||
when (val value = it.value) {
|
||||
is StructureCategory -> value.items
|
||||
is File -> value.listFiles()?.toList() ?: observableListOf()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -78,7 +68,6 @@ class ProjectStructureView : View() {
|
||||
if (event.clickCount == 2) {
|
||||
when (val item = selectionModel?.selectedItem?.value) {
|
||||
is GameMapAsset -> mainController.openMap(item.uid)
|
||||
is File -> item.takeIf { it.isFile }?.let { mainController.openScript(item) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user