From f654a4f379b9556beea4891cfb2d234b4faebd31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Wed, 2 Aug 2023 13:48:06 +0200 Subject: [PATCH] Fixed AssetHierarchy not updating + Drag'n'drop Files in Asset Browser --- GlitchyEditor/src/Assets/AssetHierarchy.bf | 58 ++++++++++++++++++- .../src/EditWindows/ContentBrowserWindow.bf | 52 +++++++++++++---- 2 files changed, 98 insertions(+), 12 deletions(-) diff --git a/GlitchyEditor/src/Assets/AssetHierarchy.bf b/GlitchyEditor/src/Assets/AssetHierarchy.bf index 60de1e2..44e1701 100644 --- a/GlitchyEditor/src/Assets/AssetHierarchy.bf +++ b/GlitchyEditor/src/Assets/AssetHierarchy.bf @@ -187,6 +187,60 @@ class AssetHierarchy // We don't need to rename the .ass file, because the filesystem watcher will handle this for us! } + + public Result MoveFileToNode(StringView assetIdentifierToMove, TreeNode newParentEntry) + { + TreeNode fileToMove = GetNodeFromIdentifier(assetIdentifierToMove).GetValueOrDefault(); + + if (fileToMove == null) + { + Log.EngineLogger.Error($"Couldn't find asset node for asset {assetIdentifierToMove}"); + return .Err; + } + + String newPathName = scope .(); + Path.Combine(newPathName, newParentEntry->Path, fileToMove->Name); + + if (File.Exists(newPathName)) + { + Log.EngineLogger.Error("Can't move file. Target already exists."); + return .Err; + } + + if (fileToMove->IsDirectory) + { + if (Directory.Move(fileToMove->Path, newPathName) case .Err(let error)) + { + Log.EngineLogger.Error($"Couldn't move directory from {fileToMove->Path} to {newPathName} ({error})."); + return .Err; + } + } + else + { + if (File.Move(fileToMove->Path, newPathName) case .Err(let error)) + { + Log.EngineLogger.Error($"Couldn't move file from {fileToMove->Path} to {newPathName} ({error})."); + return .Err; + } + } + + if (fileToMove->AssetFile != null) + { + if (File.Exists(fileToMove->AssetFile.AssetConfigPath)) + { + String newConfigPathName = scope .(newPathName); + newConfigPathName.Append(AssetFile.ConfigFileExtension); + + if (File.Move(fileToMove->AssetFile.AssetConfigPath, newConfigPathName) case .Err(let error)) + { + Log.EngineLogger.Error($"Couldn't move asset description file from {fileToMove->AssetFile.AssetConfigPath} to {newConfigPathName} ({error}). Sorry :("); + return .Err; + } + } + } + + return .Ok; + } /// Sets path to the directory that contains the engine assets. public void SetResourcesDirectory(StringView fileName) @@ -269,10 +323,10 @@ class AssetHierarchy /// Invokes the the file tree update on the mainthread. private void DeferFileTreeUpdate() { - _fileTreeUpdateRequested = true; - if (!_fileTreeUpdateRequested) { + _fileTreeUpdateRequested = true; + Application.Instance.InvokeOnMainThread(new () => { UpdateFiles(); diff --git a/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf b/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf index 65efe0f..d56a098 100644 --- a/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf +++ b/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf @@ -328,7 +328,7 @@ namespace GlitchyEditor.EditWindows files = currentDirectoryNode->Children; // show back button (".."-File) - if (currentDirectoryNode->Parent != null) + if (currentDirectoryNode->Parent != _manager.AssetHierarchy.RootNode) { ImGui.PushID("Back"); @@ -403,11 +403,14 @@ namespace GlitchyEditor.EditWindows ImGui.PopStyleColor(); + FileDropTarget(entry); + if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left)) { if (_selectedFile != entry->Path) { _selectedFile.Set(entry->Path); + _assetToRename.Clear(); } } @@ -421,6 +424,38 @@ namespace GlitchyEditor.EditWindows ImGui.EndChild(); } + /// Makes a drop target for the given asset node that files and directories can be dropped on, so that Files can be moved + private void FileDropTarget(TreeNode dropTarget) + { + if (dropTarget->IsDirectory && ImGui.BeginDragDropTarget()) + { + bool allowDrop = false; + + ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.ContentBrowserItem, .AcceptPeekOnly); + + if (peekPayload != null) + { + StringView assetIdentifier = .((char8*)peekPayload.Data, (int)peekPayload.DataSize); + + allowDrop = assetIdentifier != dropTarget->Identifier; + } + + if (allowDrop) + { + ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem); + + if (payload != null) + { + StringView movedChild = .((char8*)payload.Data, (int)payload.DataSize); + + _manager.AssetHierarchy.MoveFileToNode(movedChild, dropTarget); + } + } + + ImGui.EndDragDropTarget(); + } + } + /// Renders the button for the given directory item. private void DrawDirectoryItem(TreeNode entry) { @@ -458,11 +493,14 @@ namespace GlitchyEditor.EditWindows ImGui.EndDragDropSource(); } + FileDropTarget(entry); + if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left)) { if (_selectedFile != entry->Path) { _selectedFile.Set(entry->Path); + _assetToRename.Clear(); } } @@ -475,11 +513,11 @@ namespace GlitchyEditor.EditWindows { ImGui.PushItemWidth((.)IconSize.X); - if (ImGui.InputText("##renameBox", &_renameFileNameBuffer, _renameFileNameBuffer.Count - 1, .AutoSelectAll | .EnterReturnsTrue)) - { - } + ImGui.InputText("##renameBox", &_renameFileNameBuffer, _renameFileNameBuffer.Count - 1, .AutoSelectAll); ImGui.PopItemWidth(); + + ImGui.SetKeyboardFocusHere(-1); if (ImGui.IsKeyDown(.Escape)) { @@ -498,12 +536,6 @@ namespace GlitchyEditor.EditWindows { _assetToRename.Clear(); } - - // TODO: Textbox - // TODO: Save when focus lost - // TODO: Abort on escape - - //ImGui.TextUnformatted(entry->Name); } else {