[Editor] Enable base script management
This commit is contained in:
@@ -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 -> ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user