From 3f8c5054f45c1c2c5a46a87340048c8c99b2c101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Wed, 24 Feb 2021 14:18:16 +0100 Subject: [PATCH] [Editor] Enable creating and deleting Java files --- .../component/CodeStructureItemTreeCell.kt | 19 +++++++++++--- .../base/editor/code/model/FileSystemNode.kt | 25 +++++++++++++++++++ .../base/editor/code/view/CodeEditorView.kt | 2 +- .../editor/code/view/CodeStructureView.kt | 22 +++++++++++++++- .../editor/main/controller/MainController.kt | 12 +++++++++ 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/component/CodeStructureItemTreeCell.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/component/CodeStructureItemTreeCell.kt index 1955cd04..630241a7 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/component/CodeStructureItemTreeCell.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/component/CodeStructureItemTreeCell.kt @@ -9,7 +9,8 @@ import tornadofx.enableWhen import tornadofx.item import tornadofx.toProperty -class CodeStructureItemTreeCell : TextFieldTreeCell() { +class CodeStructureItemTreeCell(onCreate: (FileSystemNode) -> Unit, onDelete: (FileSystemNode) -> Unit) : + TextFieldTreeCell() { private val isRoot = true.toProperty() private val isNotRoot = isRoot.not() @@ -26,11 +27,19 @@ class CodeStructureItemTreeCell : TextFieldTreeCell() { item("Delete") { enableWhen(isNotRoot) - action { item.delete() } + + action { + item.delete() + onDelete(item) + } } } private val directoryMenu = ContextMenu().apply { + item("New Class...") { + action { onCreate(item) } + } + item("Refresh") { action { item.refresh() } } @@ -47,7 +56,11 @@ class CodeStructureItemTreeCell : TextFieldTreeCell() { item("Delete") { enableWhen(isNotRoot) - action { item.delete() } + + action { + item.delete() + onDelete(item) + } } } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/model/FileSystemNode.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/model/FileSystemNode.kt index d7732ec8..cc06225a 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/model/FileSystemNode.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/model/FileSystemNode.kt @@ -5,6 +5,7 @@ import tornadofx.observableListOf import tornadofx.setValue import tornadofx.toProperty import java.io.File +import java.nio.file.Path class FileSystemNode(file: File, val parent: FileSystemNode? = null) { val fileProperty = file.toProperty() @@ -15,6 +16,8 @@ class FileSystemNode(file: File, val parent: FileSystemNode? = null) { val isDirectory = file.isDirectory val children = observableListOf() + val allChildren: List + get() = children + children.flatMap { it.allChildren } init { refreshChildren() @@ -48,4 +51,26 @@ class FileSystemNode(file: File, val parent: FileSystemNode? = null) { fun refresh() { 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 } + } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/view/CodeEditorView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/view/CodeEditorView.kt index 3830b464..2a05c526 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/view/CodeEditorView.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/view/CodeEditorView.kt @@ -35,7 +35,7 @@ class CodeEditorView : View() { action { codeVM.item?.let { - codeVM.commit() + codeVM.commit(codeVM.codeProperty) projectContext.saveScript(it) } } diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/view/CodeStructureView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/view/CodeStructureView.kt index a5faeab7..b86f83a8 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/view/CodeStructureView.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/code/view/CodeStructureView.kt @@ -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.main.controller.MainController import com.bartlomiejpluta.base.editor.project.context.ProjectContext +import javafx.scene.control.TextInputDialog import javafx.scene.control.TreeItem import javafx.scene.control.TreeView import javafx.scene.input.MouseButton @@ -11,6 +12,7 @@ import tornadofx.View import tornadofx.expandAll import tornadofx.populate import tornadofx.treeview +import java.io.File class CodeStructureView : View() { private val projectContext: ProjectContext by di() @@ -27,7 +29,9 @@ class CodeStructureView : View() { } private val treeView: TreeView = treeview { - setCellFactory { CodeStructureItemTreeCell() } + setCellFactory { + CodeStructureItemTreeCell(this@CodeStructureView::onCreate, mainController::closeScript) + } setOnMouseClicked { event -> if (event.button == MouseButton.PRIMARY && event.clickCount == 2) { @@ -41,4 +45,20 @@ class CodeStructureView : View() { } 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) + } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/controller/MainController.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/controller/MainController.kt index 34fc0226..5dbf22d6 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/controller/MainController.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/controller/MainController.kt @@ -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) { when (asset) { is GameMapAsset -> openItems.entries.firstOrNull { (_, item) -> item is GameMap && item.uid == asset.uid }?.key?.let {