From eebda465b9511c26974b048aa0aa757870594a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Thu, 11 Feb 2021 19:36:53 +0100 Subject: [PATCH] [Editor] Create project structure panel scaffolding --- .../base/editor/main/view/MainView.kt | 3 + .../editor/main/view/ProjectStructureView.kt | 60 +++++++++++++++++++ .../base/editor/util/fx/BindingUtil.kt | 27 +++++++++ 3 files changed, 90 insertions(+) create mode 100644 editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/view/ProjectStructureView.kt create mode 100644 editor/src/main/kotlin/com/bartlomiejpluta/base/editor/util/fx/BindingUtil.kt diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/view/MainView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/view/MainView.kt index 8dee97fb..ae769b9b 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/view/MainView.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/view/MainView.kt @@ -13,6 +13,7 @@ class MainView : View("BASE Game Editor") { private val projectContext: ProjectContext by di() private val mainMenuView = find() + private val projectStructureView = find() init { projectContext.projectProperty.addListener { _, _, project -> @@ -35,5 +36,7 @@ class MainView : View("BASE Game Editor") { } } } + + left = projectStructureView.root } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/view/ProjectStructureView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/view/ProjectStructureView.kt new file mode 100644 index 00000000..b2796970 --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/main/view/ProjectStructureView.kt @@ -0,0 +1,60 @@ +package com.bartlomiejpluta.base.editor.main.view + +import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset +import com.bartlomiejpluta.base.editor.project.context.ProjectContext +import com.bartlomiejpluta.base.editor.util.fx.BindingUtil +import javafx.beans.property.SimpleStringProperty +import javafx.collections.ObservableList +import javafx.scene.control.TreeItem +import org.kordamp.ikonli.javafx.FontIcon +import tornadofx.* + + +class ProjectStructureView : View() { + private val projectContext: ProjectContext by di() + + private val structureMaps = StructureCategory("Maps") + + private val structureRoot = StructureCategory(name = "Project", items = observableListOf(structureMaps)) + + init { + projectContext.projectProperty.addListener { _, _, project -> + project?.let { + structureRoot.nameProperty.bind(it.nameProperty) + BindingUtil.bindMapValues(structureMaps.items, project.maps) + root.refresh() + } + } + } + + override val root = treeview { + root = TreeItem(structureRoot) + + cellFormat { + graphic = when(it) { + structureRoot -> FontIcon("fa-cog") + is StructureCategory -> FontIcon("fa-folder") + is GameMapAsset -> FontIcon("fa-map") + else -> null + } + + text = when (it) { + is StructureCategory -> it.name + is GameMapAsset -> it.name + else -> throw IllegalStateException("Unsupported structure item type") + } + } + + populate { + when (val value = it.value) { + is StructureCategory -> value.items + else -> null + } + } + } + + private class StructureCategory(name: String = "", var items: ObservableList = observableListOf()) { + val nameProperty = SimpleStringProperty(name) + val name by nameProperty + } +} diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/util/fx/BindingUtil.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/util/fx/BindingUtil.kt new file mode 100644 index 00000000..db6c8ea1 --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/util/fx/BindingUtil.kt @@ -0,0 +1,27 @@ +package com.bartlomiejpluta.base.editor.util.fx + +import javafx.beans.binding.Bindings +import javafx.collections.MapChangeListener +import javafx.collections.ObservableList +import javafx.collections.ObservableMap +import tornadofx.observableListOf + +object BindingUtil { + fun observableMapValues(map: ObservableMap) = observableListOf().apply { + addAll(map.values) + + // FIXME: + // It's not really efficient way to track map updates by clearing all + // and putting it all over again, however it preserves the original map order. + // The efficiency should be sufficient for the project purposes (there are no any expectations + // to store a very large collections in here - if the need arose it should be immediately improved). + map.addListener(MapChangeListener { + clear() + addAll(map.values) + }) + } + + fun bindMapValues(target: ObservableList, map: ObservableMap) { + Bindings.bindContent(target, observableMapValues(map)) + } +} \ No newline at end of file