[Editor] Extract the Scripts tree view from the Project Structure panel

This commit is contained in:
2021-02-24 08:51:02 +01:00
parent 1d3f612924
commit f5c5b82a8b
6 changed files with 142 additions and 30 deletions

View File

@@ -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) }
}

View File

@@ -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"
}
}
}
}

View 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
}
}

View File

@@ -10,7 +10,6 @@ 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>() {
@@ -55,7 +54,6 @@ 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
} }
@@ -64,21 +62,7 @@ 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"
}
}
}
} }

View 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.model.Code
import com.bartlomiejpluta.base.editor.code.view.CodeEditorFragment 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.code.viewmodel.CodeVM
import com.bartlomiejpluta.base.editor.main.controller.MainController import com.bartlomiejpluta.base.editor.main.controller.MainController
import com.bartlomiejpluta.base.editor.map.model.map.GameMap 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 mainMenuView = find<MainMenuView>()
private val projectStructureView = find<ProjectStructureView>() private val projectStructureView = find<ProjectStructureView>()
private val codeStructure = find<CodeStructureView>()
init { init {
projectContext.projectProperty.addListener { _, _, project -> projectContext.projectProperty.addListener { _, _, project ->
@@ -68,6 +70,10 @@ class MainView : View("BASE Game Editor") {
} }
left = drawer(multiselect = true) { left = drawer(multiselect = true) {
item("Code Structure", expanded = true) {
this += codeStructure
}
item("Project Structure", expanded = true) { item("Project Structure", expanded = true) {
this += projectStructureView this += projectStructureView
} }

View File

@@ -10,7 +10,6 @@ import javafx.beans.binding.Bindings
import javafx.scene.control.TreeItem import javafx.scene.control.TreeItem
import javafx.scene.control.TreeView import javafx.scene.control.TreeView
import tornadofx.* import tornadofx.*
import java.io.File
class ProjectStructureView : View() { class ProjectStructureView : View() {
@@ -29,16 +28,11 @@ 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
) )
) )
@@ -49,12 +43,7 @@ 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()
} }
} }
} }
@@ -62,10 +51,11 @@ class ProjectStructureView : View() {
private val treeView: TreeView<Any> = treeview<Any> { private val treeView: TreeView<Any> = treeview<Any> {
root = TreeItem(structureRoot) root = TreeItem(structureRoot)
isShowRoot = false
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
} }
} }
@@ -78,7 +68,6 @@ 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) }
} }
} }