[Editor] Enable creating and deleting Java files

This commit is contained in:
2021-02-24 14:18:16 +01:00
parent af9cb39c95
commit 3f8c5054f4
5 changed files with 75 additions and 5 deletions

View File

@@ -9,7 +9,8 @@ import tornadofx.enableWhen
import tornadofx.item import tornadofx.item
import tornadofx.toProperty import tornadofx.toProperty
class CodeStructureItemTreeCell : TextFieldTreeCell<FileSystemNode>() { class CodeStructureItemTreeCell(onCreate: (FileSystemNode) -> Unit, onDelete: (FileSystemNode) -> Unit) :
TextFieldTreeCell<FileSystemNode>() {
private val isRoot = true.toProperty() private val isRoot = true.toProperty()
private val isNotRoot = isRoot.not() private val isNotRoot = isRoot.not()
@@ -26,11 +27,19 @@ class CodeStructureItemTreeCell : TextFieldTreeCell<FileSystemNode>() {
item("Delete") { item("Delete") {
enableWhen(isNotRoot) enableWhen(isNotRoot)
action { item.delete() }
action {
item.delete()
onDelete(item)
}
} }
} }
private val directoryMenu = ContextMenu().apply { private val directoryMenu = ContextMenu().apply {
item("New Class...") {
action { onCreate(item) }
}
item("Refresh") { item("Refresh") {
action { item.refresh() } action { item.refresh() }
} }
@@ -47,7 +56,11 @@ class CodeStructureItemTreeCell : TextFieldTreeCell<FileSystemNode>() {
item("Delete") { item("Delete") {
enableWhen(isNotRoot) enableWhen(isNotRoot)
action { item.delete() }
action {
item.delete()
onDelete(item)
}
} }
} }

View File

@@ -5,6 +5,7 @@ import tornadofx.observableListOf
import tornadofx.setValue import tornadofx.setValue
import tornadofx.toProperty import tornadofx.toProperty
import java.io.File import java.io.File
import java.nio.file.Path
class FileSystemNode(file: File, val parent: FileSystemNode? = null) { class FileSystemNode(file: File, val parent: FileSystemNode? = null) {
val fileProperty = file.toProperty() val fileProperty = file.toProperty()
@@ -15,6 +16,8 @@ class FileSystemNode(file: File, val parent: FileSystemNode? = null) {
val isDirectory = file.isDirectory val isDirectory = file.isDirectory
val children = observableListOf<FileSystemNode>() val children = observableListOf<FileSystemNode>()
val allChildren: List<FileSystemNode>
get() = children + children.flatMap { it.allChildren }
init { init {
refreshChildren() refreshChildren()
@@ -48,4 +51,26 @@ class FileSystemNode(file: File, val parent: FileSystemNode? = null) {
fun refresh() { fun refresh() {
refreshChildren() refreshChildren()
} }
fun createNode(path: String): FileSystemNode {
val segments = Path.of(path.replace("..", "."))
return segments.foldIndexed(this) { index, parent, segment ->
val file = File(parent.file, segment.toString())
when {
index < segments.count() - 1 -> file.mkdirs()
else -> file.createNewFile()
}
when (val child = findChild(file)) {
null -> FileSystemNode(file, parent).also { parent.children += it }
else -> child
}
}
}
private fun findChild(file: File): FileSystemNode? {
return children.firstOrNull { it.file.name == file.name }
}
} }

View File

@@ -35,7 +35,7 @@ class CodeEditorView : View() {
action { action {
codeVM.item?.let { codeVM.item?.let {
codeVM.commit() codeVM.commit(codeVM.codeProperty)
projectContext.saveScript(it) projectContext.saveScript(it)
} }
} }

View File

@@ -4,6 +4,7 @@ import com.bartlomiejpluta.base.editor.code.component.CodeStructureItemTreeCell
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
import com.bartlomiejpluta.base.editor.main.controller.MainController import com.bartlomiejpluta.base.editor.main.controller.MainController
import com.bartlomiejpluta.base.editor.project.context.ProjectContext import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import javafx.scene.control.TextInputDialog
import javafx.scene.control.TreeItem import javafx.scene.control.TreeItem
import javafx.scene.control.TreeView import javafx.scene.control.TreeView
import javafx.scene.input.MouseButton import javafx.scene.input.MouseButton
@@ -11,6 +12,7 @@ import tornadofx.View
import tornadofx.expandAll import tornadofx.expandAll
import tornadofx.populate import tornadofx.populate
import tornadofx.treeview import tornadofx.treeview
import java.io.File
class CodeStructureView : View() { class CodeStructureView : View() {
private val projectContext: ProjectContext by di() private val projectContext: ProjectContext by di()
@@ -27,7 +29,9 @@ class CodeStructureView : View() {
} }
private val treeView: TreeView<FileSystemNode> = treeview { private val treeView: TreeView<FileSystemNode> = treeview {
setCellFactory { CodeStructureItemTreeCell() } setCellFactory {
CodeStructureItemTreeCell(this@CodeStructureView::onCreate, mainController::closeScript)
}
setOnMouseClicked { event -> setOnMouseClicked { event ->
if (event.button == MouseButton.PRIMARY && event.clickCount == 2) { if (event.button == MouseButton.PRIMARY && event.clickCount == 2) {
@@ -41,4 +45,20 @@ class CodeStructureView : View() {
} }
override val root = treeView override val root = treeView
private fun onCreate(fsNode: FileSystemNode) {
TextInputDialog().apply {
width = 300.0
contentText = "Class name"
title = "New class"
}
.showAndWait()
.map { it.replace(".", File.separator) + ".java" }
.map { fsNode.createNode(it) }
.ifPresent { mainController.openScript(it) }
}
private fun onDelete(fsNode: FileSystemNode) {
mainController.closeScript(fsNode)
}
} }

View File

@@ -124,6 +124,18 @@ class MainController : Controller() {
} }
} }
fun closeScript(fsNode: FileSystemNode) {
openItems.entries.firstOrNull { (_, item) -> item is Code && item.file.absolutePath == fsNode.file.absolutePath }?.key?.let {
openItems.remove(it)
}
fsNode.allChildren.forEach { child ->
openItems.entries.firstOrNull { (_, item) -> item is Code && item.file.absolutePath == child.file.absolutePath }?.key?.let {
openItems.remove(it)
}
}
}
fun closeAsset(asset: Asset) { fun closeAsset(asset: Asset) {
when (asset) { when (asset) {
is GameMapAsset -> openItems.entries.firstOrNull { (_, item) -> item is GameMap && item.uid == asset.uid }?.key?.let { is GameMapAsset -> openItems.entries.firstOrNull { (_, item) -> item is GameMap && item.uid == asset.uid }?.key?.let {