[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
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
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
private val cell: TreeCell<FileSystemNode>,
private val onUpdate: (item: FileSystemNode, name: String) -> FileSystemNode
) : StringConverter<FileSystemNode>() {
override fun toString(item: FileSystemNode?): String = when (item) {
is FileSystemNode -> item.file.name
else -> ""
}

View File

@@ -1,58 +1,95 @@
package com.bartlomiejpluta.base.editor.code.component
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
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
import tornadofx.enableWhen
import tornadofx.item
import tornadofx.toProperty
class CodeStructureItemTreeCell(renameFile: (file: File, name: String) -> File, deleteFile: (file: File) -> Unit) :
TextFieldTreeCell<File>() {
private val fileMenu = ContextMenu()
class CodeStructureItemTreeCell : TextFieldTreeCell<FileSystemNode>() {
private val isRoot = true.toProperty()
private val isNotRoot = isRoot.not()
private val fileMenu = ContextMenu().apply {
item("Rename") {
enableWhen(isNotRoot)
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)
item("Delete") {
enableWhen(isNotRoot)
action { item.delete() }
}
}
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)
if (empty || item == null) {
text = null
graphic = null
contextMenu = null
isRoot.value = true
return
}
contextMenu = if (isEditing) null else fileMenu
text = item.name
graphic = FontIcon(getFileIcon(item))
text = item.file.name
graphic = FontIcon(getFileSystemNodeIcon(item))
contextMenu = when {
isEditing -> null
item.isFile -> fileMenu
item.isDirectory -> directoryMenu
else -> null
}
isRoot.value = (item.parent == null)
}
companion object {
private fun getFileIcon(file: File): String {
private fun getFileSystemNodeIcon(file: FileSystemNode): String {
if (file.isDirectory) {
return "fa-folder"
}
return when (file.extension.toLowerCase()) {
return when (file.file.extension.toLowerCase()) {
"java" -> "fa-code"
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
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.TreeItem
import javafx.scene.control.TreeView
import tornadofx.*
import java.io.File
import javafx.scene.input.MouseButton
import tornadofx.View
import tornadofx.expandAll
import tornadofx.populate
import tornadofx.treeview
class CodeStructureView : View() {
private val projectContext: ProjectContext by di()
@@ -15,36 +19,26 @@ class CodeStructureView : View() {
init {
projectContext.projectProperty.addListener { _, _, project ->
project?.let {
treeView.root = TreeItem(it.codeDirectory)
treeView.populate { item -> item.value?.listFiles()?.toList() }
treeView.root = TreeItem(FileSystemNode(it.codeDirectory))
treeView.populate { item -> item.value?.children }
root.root.expandAll()
}
}
}
private val treeView: TreeView<File> = treeview {
setCellFactory {
CodeStructureItemTreeCell(this@CodeStructureView::renameFile, this@CodeStructureView::deleteFile)
}
private val treeView: TreeView<FileSystemNode> = treeview {
setCellFactory { CodeStructureItemTreeCell() }
setOnMouseClicked { event ->
if (event.clickCount == 2) {
if (event.button == MouseButton.PRIMARY && event.clickCount == 2) {
selectionModel?.selectedItem?.value
.takeIf { it?.isFile ?: false }
?.let { mainController.openScript(it) }
}
?.let { mainController.openScript(it.file) }
event.consume()
event.consume()
}
}
}
override val root = treeView
private fun renameFile(file: File, name: String) = file.apply {
// TODO
}
private fun deleteFile(file: File) {
// TODO
}
}