[Editor] Enable Assets renaming through Project Structure panel

This commit is contained in:
2021-02-21 16:45:44 +01:00
parent 713ebb1c54
commit 80cff63501

View File

@@ -9,7 +9,12 @@ import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset
import javafx.beans.binding.Bindings
import javafx.beans.property.SimpleStringProperty
import javafx.collections.ObservableList
import javafx.scene.control.ContextMenu
import javafx.scene.control.MenuItem
import javafx.scene.control.TreeCell
import javafx.scene.control.TreeItem
import javafx.scene.control.cell.TextFieldTreeCell
import javafx.util.StringConverter
import org.kordamp.ikonli.javafx.FontIcon
import tornadofx.*
@@ -22,11 +27,13 @@ class ProjectStructureView : View() {
private val structureTileSets = StructureCategory("Tile Sets")
private val structureImages = StructureCategory("Images")
private val structureRoot = StructureCategory(name = "Project", items = observableListOf(
structureMaps,
structureTileSets,
structureImages
))
private val structureRoot = StructureCategory(
name = "Project", items = observableListOf(
structureMaps,
structureTileSets,
structureImages
)
)
init {
projectContext.projectProperty.addListener { _, _, project ->
@@ -44,23 +51,6 @@ class ProjectStructureView : View() {
override val root = treeview<Any> {
root = TreeItem(structureRoot)
cellFormat {
graphic = when (it) {
structureRoot -> FontIcon("fa-cog")
is StructureCategory -> FontIcon("fa-folder")
is GameMapAsset -> FontIcon("fa-map")
is TileSetAsset -> FontIcon("fa-th")
is ImageAsset -> FontIcon("fa-image")
else -> null
}
text = when (it) {
is StructureCategory -> it.name
is Asset -> it.name
else -> throw IllegalStateException("Unsupported structure item type")
}
}
populate {
when (val value = it.value) {
is StructureCategory -> value.items
@@ -68,12 +58,25 @@ class ProjectStructureView : View() {
}
}
setCellFactory {
StructureItemTreeCell { item, name ->
item.apply {
if (this is Asset) {
this.name = name
projectContext.save()
}
}
}
}
setOnMouseClicked { event ->
if (event.clickCount == 2) {
when (val item = selectionModel?.selectedItem?.value) {
is GameMapAsset -> mainController.openMap(item.uid)
}
}
event.consume()
}
}
@@ -81,4 +84,67 @@ class ProjectStructureView : View() {
val nameProperty = SimpleStringProperty(name)
val name by nameProperty
}
private class StructureItemConverter(
private val cell: TreeCell<Any>,
private val onUpdate: (item: Any, name: String) -> Any
) : StringConverter<Any>() {
override fun toString(item: Any?): String = when (item) {
is StructureCategory -> item.name
is Asset -> item.name
else -> ""
}
// Disclaimer:
// Because of the fact that we want to support undo/redo mechanism
// the actual update must be done from the execute() method of the Command object
// so that the Command object has access to the actual as well as the new value of layer name.
// That's why we are running the submission logic in the converter.
override fun fromString(string: String?): Any = string?.let { onUpdate(cell.item, it) } ?: ""
}
private class StructureItemTreeCell(onUpdate: (item: Any, name: String) -> Any) : TextFieldTreeCell<Any>() {
private val assetMenu = ContextMenu()
init {
converter = StructureItemConverter(this, onUpdate)
MenuItem("Rename").apply {
action {
treeView.isEditable = true
startEdit()
treeView.isEditable = false
}
assetMenu.items.add(this)
}
}
override fun updateItem(item: Any?, empty: Boolean) {
super.updateItem(item, empty)
if (empty || item == null) {
text = null
graphic = null
return
}
if (!isEditing && item is Asset) {
contextMenu = assetMenu
}
text = when (item) {
is StructureCategory -> item.name
is Asset -> item.name
else -> null
}
graphic = when (item) {
is StructureCategory -> FontIcon("fa-folder")
is GameMapAsset -> FontIcon("fa-map")
is TileSetAsset -> FontIcon("fa-th")
is ImageAsset -> FontIcon("fa-image")
else -> null
}
}
}
}