[Editor] Enable creating and deleting Java files
This commit is contained in:
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user