[Editor] Enable base script management

This commit is contained in:
2021-02-24 10:55:42 +01:00
parent f5c5b82a8b
commit 2633c89ade
4 changed files with 126 additions and 48 deletions

View File

@@ -1,15 +1,15 @@
package com.bartlomiejpluta.base.editor.code.component package com.bartlomiejpluta.base.editor.code.component
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
import javafx.scene.control.TreeCell import javafx.scene.control.TreeCell
import javafx.util.StringConverter import javafx.util.StringConverter
import java.io.File
class CodeStructureItemStringConverter( class CodeStructureItemStringConverter(
private val cell: TreeCell<File>, private val cell: TreeCell<FileSystemNode>,
private val onUpdate: (item: File, name: String) -> File private val onUpdate: (item: FileSystemNode, name: String) -> FileSystemNode
) : StringConverter<File>() { ) : StringConverter<FileSystemNode>() {
override fun toString(item: File?): String = when (item) { override fun toString(item: FileSystemNode?): String = when (item) {
is File -> item.name is FileSystemNode -> item.file.name
else -> "" else -> ""
} }

View File

@@ -1,58 +1,95 @@
package com.bartlomiejpluta.base.editor.code.component package com.bartlomiejpluta.base.editor.code.component
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
import javafx.scene.control.ContextMenu import javafx.scene.control.ContextMenu
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 import tornadofx.enableWhen
import tornadofx.item
import tornadofx.toProperty
class CodeStructureItemTreeCell(renameFile: (file: File, name: String) -> File, deleteFile: (file: File) -> Unit) : class CodeStructureItemTreeCell : TextFieldTreeCell<FileSystemNode>() {
TextFieldTreeCell<File>() { private val isRoot = true.toProperty()
private val fileMenu = ContextMenu() private val isNotRoot = isRoot.not()
private val fileMenu = ContextMenu().apply {
item("Rename") {
enableWhen(isNotRoot)
init {
converter = CodeStructureItemStringConverter(this, renameFile)
MenuItem("Rename").apply {
action { action {
treeView.isEditable = true treeView.isEditable = true
startEdit() startEdit()
treeView.isEditable = false treeView.isEditable = false
} }
fileMenu.items.add(this)
} }
MenuItem("Delete").apply { item("Delete") {
action { enableWhen(isNotRoot)
deleteFile(item as File) action { item.delete() }
}
fileMenu.items.add(this)
} }
} }
override fun updateItem(item: File?, empty: Boolean) { private val directoryMenu = ContextMenu().apply {
item("Refresh") {
action { item.refresh() }
}
item("Rename") {
enableWhen(isNotRoot)
action {
treeView.isEditable = true
startEdit()
treeView.isEditable = false
}
}
item("Delete") {
enableWhen(isNotRoot)
action { item.delete() }
}
}
init {
converter = CodeStructureItemStringConverter(this, this::renameFile)
}
private fun renameFile(file: FileSystemNode, name: String) = file.apply {
file.rename(name)
}
override fun updateItem(item: FileSystemNode?, empty: Boolean) {
super.updateItem(item, empty) super.updateItem(item, empty)
if (empty || item == null) { if (empty || item == null) {
text = null text = null
graphic = null graphic = null
contextMenu = null
isRoot.value = true
return return
} }
contextMenu = if (isEditing) null else fileMenu text = item.file.name
text = item.name graphic = FontIcon(getFileSystemNodeIcon(item))
graphic = FontIcon(getFileIcon(item))
contextMenu = when {
isEditing -> null
item.isFile -> fileMenu
item.isDirectory -> directoryMenu
else -> null
}
isRoot.value = (item.parent == null)
} }
companion object { companion object {
private fun getFileIcon(file: File): String { private fun getFileSystemNodeIcon(file: FileSystemNode): String {
if (file.isDirectory) { if (file.isDirectory) {
return "fa-folder" return "fa-folder"
} }
return when (file.extension.toLowerCase()) { return when (file.file.extension.toLowerCase()) {
"java" -> "fa-code" "java" -> "fa-code"
else -> "fa-file" else -> "fa-file"
} }

View File

@@ -0,0 +1,47 @@
package com.bartlomiejpluta.base.editor.code.model
import tornadofx.observableListOf
import java.io.File
class FileSystemNode(file: File, val parent: FileSystemNode? = null) {
var file = file
private set
val isFile = file.isFile
val isDirectory = file.isDirectory
val children = observableListOf<FileSystemNode>()
init {
refreshChildren()
}
private fun refreshChildren() {
if (isDirectory) {
children.clear()
file.listFiles()?.map { FileSystemNode(it, this) }?.let { children.addAll(it) }
}
}
fun rename(name: String) {
val newFile = File(file.parent, name)
file.renameTo(newFile)
file = newFile
}
fun delete() {
val deleted = when {
isFile -> file.delete()
isDirectory -> file.deleteRecursively()
else -> false
}
if (deleted) {
parent?.children?.remove(this)
}
}
fun refresh() {
refreshChildren()
}
}

View File

@@ -1,12 +1,16 @@
package com.bartlomiejpluta.base.editor.code.view package com.bartlomiejpluta.base.editor.code.view
import com.bartlomiejpluta.base.editor.code.component.CodeStructureItemTreeCell 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.main.controller.MainController
import com.bartlomiejpluta.base.editor.project.context.ProjectContext import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import javafx.scene.control.TreeItem import javafx.scene.control.TreeItem
import javafx.scene.control.TreeView import javafx.scene.control.TreeView
import tornadofx.* import javafx.scene.input.MouseButton
import java.io.File import tornadofx.View
import tornadofx.expandAll
import tornadofx.populate
import tornadofx.treeview
class CodeStructureView : View() { class CodeStructureView : View() {
private val projectContext: ProjectContext by di() private val projectContext: ProjectContext by di()
@@ -15,36 +19,26 @@ class CodeStructureView : View() {
init { init {
projectContext.projectProperty.addListener { _, _, project -> projectContext.projectProperty.addListener { _, _, project ->
project?.let { project?.let {
treeView.root = TreeItem(it.codeDirectory) treeView.root = TreeItem(FileSystemNode(it.codeDirectory))
treeView.populate { item -> item.value?.listFiles()?.toList() } treeView.populate { item -> item.value?.children }
root.root.expandAll() root.root.expandAll()
} }
} }
} }
private val treeView: TreeView<File> = treeview { private val treeView: TreeView<FileSystemNode> = treeview {
setCellFactory { setCellFactory { CodeStructureItemTreeCell() }
CodeStructureItemTreeCell(this@CodeStructureView::renameFile, this@CodeStructureView::deleteFile)
}
setOnMouseClicked { event -> setOnMouseClicked { event ->
if (event.clickCount == 2) { if (event.button == MouseButton.PRIMARY && event.clickCount == 2) {
selectionModel?.selectedItem?.value selectionModel?.selectedItem?.value
.takeIf { it?.isFile ?: false } .takeIf { it?.isFile ?: false }
?.let { mainController.openScript(it) } ?.let { mainController.openScript(it.file) }
}
event.consume() event.consume()
}
} }
} }
override val root = treeView override val root = treeView
private fun renameFile(file: File, name: String) = file.apply {
// TODO
}
private fun deleteFile(file: File) {
// TODO
}
} }