From 793aa40975c0f7acb2c3a57cfb4785aa7f040c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sat, 18 Mar 2023 19:59:56 +0100 Subject: [PATCH] Add up button und split scrolling in content browser - Add Parent to TreeNode - Start of Rename handling --- GlitchyEditor/src/Assets/AssetHierarchy.bf | 65 +++++++++++++++++- .../src/Assets/MaterialAssetLoader.bf | 2 +- .../src/EditWindows/ContentBrowserWindow.bf | 68 ++++++++++++++++++- GlitchyEditor/src/EditorContentManager.bf | 48 +++---------- GlitchyEngine/src/Collections/TreeNode.bf | 2 + 5 files changed, 142 insertions(+), 43 deletions(-) diff --git a/GlitchyEditor/src/Assets/AssetHierarchy.bf b/GlitchyEditor/src/Assets/AssetHierarchy.bf index c9fdd52..0daf565 100644 --- a/GlitchyEditor/src/Assets/AssetHierarchy.bf +++ b/GlitchyEditor/src/Assets/AssetHierarchy.bf @@ -108,7 +108,8 @@ class AssetHierarchy fsw.OnRenamed.Add(new (oldName, newName) => { Log.EngineLogger.Trace($"File renamed (From \"{oldName}\" to \"{newName}\")"); - _fileSystemDirty = true; + //_fileSystemDirty = true; + FileRenamed(oldName, newName); /*String contentFilePath = scope String(); Path.InternalCombine(contentFilePath, ContentDirectory, oldName); @@ -161,6 +162,7 @@ class AssetHierarchy _assetHierarchy = new TreeNode(new AssetNode()); _assetHierarchy->Path = new String(ContentDirectory); _assetHierarchy->Name = new String("Content"); + _assetHierarchy->IsDirectory = true; Log.EngineLogger.Trace($"Created directory node for: \"{_assetHierarchy->Path}\""); @@ -333,11 +335,70 @@ class AssetHierarchy return; OnFileContentChanged(node.Value); + } - // TODO: Handle file changes (reload asset, etc...) + private void FileRenamed(StringView oldFilePath, StringView newFilePath) + { + var oldFilePath; + + // Ignore Config files. + if (oldFilePath.EndsWith(AssetFile.ConfigFileExtension)) + return; + + + String oldFileNameWithContentRoot = scope .(); + Path.InternalCombine(oldFileNameWithContentRoot, _contentDirectory, oldFilePath); + + String newFileNameWithContentRoot = scope .(); + Path.InternalCombine(newFileNameWithContentRoot, _contentDirectory, newFilePath); + + // Rename config file + { + String oldConfigFileName = scope $"{oldFileNameWithContentRoot}{AssetFile.ConfigFileExtension}"; + String newConfigFileName = scope $"{newFileNameWithContentRoot}{AssetFile.ConfigFileExtension}"; + + if (File.Exists(oldConfigFileName) && !File.Exists(newConfigFileName)) + { + if (File.Move(oldConfigFileName, newConfigFileName) case .Err(let value)) + { + Log.EngineLogger.Error($"Failed to move file {oldConfigFileName} to {newConfigFileName}. Code: {value}"); + } + } + } + + var nodeResult = GetNodeFromPath(oldFileNameWithContentRoot); + + TreeNode node = null; + + if (!(nodeResult case .Ok(out node))) + { + // This happens, when we create new files. + Log.EngineLogger.Trace($"Could not find node for file \"{oldFileNameWithContentRoot}\""); + return; + } + + _pathToAssetNode.Remove(oldFileNameWithContentRoot); + + node->Path.Set(newFileNameWithContentRoot); + _pathToAssetNode.Add(newFileNameWithContentRoot, node); + + node->Name.Clear(); + Path.GetFileName(newFileNameWithContentRoot, node->Name); + + String oldIdentifier = scope .(node->AssetFile.[Friend]_identifier); + + node->AssetFile.[Friend]_path.Set(node->Path); + node->AssetFile.[Friend]_identifier.Set(newFilePath); + node->AssetFile.[Friend]_assetConfigPath..Set(node->Path).Append(AssetFile.ConfigFileExtension); + + OnFileRenamed(node.Value, oldIdentifier); } public delegate void FileContentChangedFunc(AssetNode node); public Event OnFileContentChanged ~ _.Dispose(); + + public delegate void FileRenamedFunc(AssetNode node, StringView oldName); + + public Event OnFileRenamed ~ _.Dispose(); } diff --git a/GlitchyEditor/src/Assets/MaterialAssetLoader.bf b/GlitchyEditor/src/Assets/MaterialAssetLoader.bf index f4fe990..7868331 100644 --- a/GlitchyEditor/src/Assets/MaterialAssetLoader.bf +++ b/GlitchyEditor/src/Assets/MaterialAssetLoader.bf @@ -86,7 +86,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor AssetHandle newTexture = Content.LoadAsset(path); - newTexture.Get().SamplerState = SamplerStateManager.AnisotropicWrap; + //newTexture.Get().SamplerState = SamplerStateManager.AnisotropicWrap; material.SetTexture(texture.key, newTexture.Cast()); } diff --git a/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf b/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf index 43a69ef..2ce8b6a 100644 --- a/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf +++ b/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf @@ -14,9 +14,6 @@ namespace GlitchyEditor.EditWindows class ContentBrowserWindow : EditorWindow { - // TODO: Get from project - //const String ContentDirectory = "./content"; - private append String _currentDirectory = .(); private append String _selectedFile = .(); @@ -58,12 +55,20 @@ namespace GlitchyEditor.EditWindows ImGui.Columns(2); + ImGui.BeginChild("Sidebar"); + DrawDirectorySideBar(); + ImGui.EndChild(); + ImGui.NextColumn(); + + ImGui.BeginChild("Files"); DrawCurrentDirectory(); + ImGui.EndChild(); + ImGui.Columns(1); ImGui.End(); @@ -149,6 +154,24 @@ namespace GlitchyEditor.EditWindows return; } + if (currentDirectoryNode->Parent != null) + { + ImGui.PushID("Back"); + + DrawBackButton(currentDirectoryNode->Parent); + + // X-Coordinate of the right side of the current entry. + float currentButtonRight = ImGui.GetItemRectMax().x; + // Expected right-Coordinate if next entry was on the same line. + float expectedButtonRight = currentButtonRight + style.ItemSpacing.x + DirectoryItemSize.X; + + // If the next button won't fit on the same line we start a new line. + if (expectedButtonRight < window_visible_x2) + ImGui.SameLine(); + + ImGui.PopID(); + } + for (var entry in currentDirectoryNode->Children) { ImGui.PushID(entry->Name); @@ -168,6 +191,45 @@ namespace GlitchyEditor.EditWindows } } + /// Renders the button for the given directory item. + private void DrawBackButton(TreeNode entry) + { + ImGui.BeginChild("item", (.)DirectoryItemSize); + + if (entry->Path == _selectedFile) + { + var color = ImGui.GetStyleColorVec4(.ButtonHovered); + ImGui.PushStyleColor(.Button, *color); + } + else + { + ImGui.PushStyleColor(.Button, ImGui.Vec4(0, 0, 0, 0)); + } + + SubTexture2D image = s_FolderTexture; + + ImGui.ImageButton(image, (.)(DirectoryItemSize - padding)); + + ImGui.PopStyleColor(); + + if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left)) + { + if (_selectedFile != entry->Path) + { + _selectedFile.Set(entry->Path); + } + } + + if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left)) + { + EntryDoubleClicked(entry); + } + + ImGui.TextUnformatted(".."); + + ImGui.EndChild(); + } + /// Renders the button for the given directory item. private void DrawDirectoryItem(TreeNode entry) { diff --git a/GlitchyEditor/src/EditorContentManager.bf b/GlitchyEditor/src/EditorContentManager.bf index 3ccbc29..5c6e592 100644 --- a/GlitchyEditor/src/EditorContentManager.bf +++ b/GlitchyEditor/src/EditorContentManager.bf @@ -34,6 +34,7 @@ class EditorContentManager : IContentManager public this() { _assetHierarchy.OnFileContentChanged.Add(new => OnFileContentChanged); + _assetHierarchy.OnFileRenamed.Add(new => OnFileRenamed); } public ~this() @@ -43,52 +44,25 @@ class EditorContentManager : IContentManager private void OnFileContentChanged(AssetNode assetNode) { - // TODO: update for AssetHandles - - // TODO: Subassets break reloading because we can't find them when we only receive the file that changed... - // Asset isn't loaded so we don't need to reload it. if (assetNode.AssetFile.LoadedAsset == null) return; _reloadQueue.Add(assetNode.AssetFile.LoadedAsset.Handle); - - /*String neededAssetLoaderName = assetNode.AssetFile.AssetConfig?.AssetLoader; - - if (String.IsNullOrWhiteSpace(neededAssetLoaderName)) + } + + public void OnFileRenamed(AssetNode assetNode, StringView oldIdentifier) + { + // Asset isn't loaded so we don't need to reload it. + if (assetNode.AssetFile.LoadedAsset == null) return; - IAssetLoader assetLoader = null; + Asset asset = assetNode.AssetFile.LoadedAsset; - String loaderNameBuffer = scope String(64); + asset.Identifier = assetNode.AssetFile.Identifier; - for (IAssetLoader loader in _assetLoaders) - { - loader.GetType().GetName(loaderNameBuffer..Clear()); - - if (loaderNameBuffer == neededAssetLoaderName) - { - assetLoader = loader; - break; - } - } - - if (assetLoader == null) - { - Log.EngineLogger.Error($"Could not find asset loader \"{neededAssetLoaderName}\""); - return; - }*/ - - /*if (var assetReloader = assetLoader as IReloadingAssetLoader) - { - Stream stream = GetStream(assetNode.Path); - - // TODO: reload asset - - //assetReloader.ReloadAsset(assetNode.AssetFile, stream); - - delete stream; - }*/ + _identiferToHandle.Remove(oldIdentifier); + _identiferToHandle.Add(asset.Identifier, asset.Handle); } public void SetContentDirectory(StringView contentDirectory) diff --git a/GlitchyEngine/src/Collections/TreeNode.bf b/GlitchyEngine/src/Collections/TreeNode.bf index e933631..d4667ff 100644 --- a/GlitchyEngine/src/Collections/TreeNode.bf +++ b/GlitchyEngine/src/Collections/TreeNode.bf @@ -11,6 +11,7 @@ namespace GlitchyEngine.Collections { public T Value; + public Self Parent; public List Children = new .() ~ DeleteContainerAndItems!(_); public this() {} @@ -29,6 +30,7 @@ namespace GlitchyEngine.Collections } Self newChild = new .(value); + newChild.Parent = this; Children.Add(newChild);