mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Delete hotkey, delte files in background, Alt Up to go back a folder, basic multi select files
This commit is contained in:
@@ -66,6 +66,30 @@ class AssetHierarchy
|
|||||||
Log.EngineLogger.Trace($"Created root node");
|
Log.EngineLogger.Trace($"Created root node");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeletePathsBackground(Span<StringView> paths)
|
||||||
|
{
|
||||||
|
DeleteBackgroundTask deleteTask = new .(paths);
|
||||||
|
deleteTask.DeleteWhenEnded = true;
|
||||||
|
|
||||||
|
for (StringView path in paths)
|
||||||
|
{
|
||||||
|
Result<TreeNode<AssetNode>> nodeResult = GetNodeFromPath(path);
|
||||||
|
|
||||||
|
if (nodeResult case .Ok(TreeNode<AssetNode> assetNode))
|
||||||
|
{
|
||||||
|
StringView assetDescriptorPath = assetNode->AssetFile?.AssetConfigPath ?? "";
|
||||||
|
|
||||||
|
// If it exists, also try to delete the .ass file
|
||||||
|
if (File.Exists(assetDescriptorPath))
|
||||||
|
{
|
||||||
|
deleteTask.AddPath(assetDescriptorPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorApp.Instance.BackgroundTaskManager.StartBackgroundTask(deleteTask);
|
||||||
|
}
|
||||||
|
|
||||||
/// Deletes the file that belongs to the given assetNode
|
/// Deletes the file that belongs to the given assetNode
|
||||||
public void DeleteFile(AssetNode assetNode)
|
public void DeleteFile(AssetNode assetNode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,7 +61,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
private append String _currentDirectory = .();
|
private append String _currentDirectory = .();
|
||||||
|
|
||||||
private append String _selectedFile = .();
|
//private append String _selectedFile = .();
|
||||||
|
|
||||||
|
private append List<String> _selectedFiles = .() ~ ClearAndDeleteItems!(_);
|
||||||
|
|
||||||
private append String _assetToRename = .();
|
private append String _assetToRename = .();
|
||||||
private char8[128] _renameFileNameBuffer;
|
private char8[128] _renameFileNameBuffer;
|
||||||
@@ -73,7 +75,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
public EditorContentManager _manager;
|
public EditorContentManager _manager;
|
||||||
|
|
||||||
public StringView SelectedFile => _selectedFile;
|
// TODO: Update
|
||||||
|
public StringView SelectedFile => _selectedFiles.First();
|
||||||
|
|
||||||
char8[256] _newFileName = .();
|
char8[256] _newFileName = .();
|
||||||
bool _showNewFile = false;
|
bool _showNewFile = false;
|
||||||
@@ -125,6 +128,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
parent.AddChild(("", null));
|
parent.AddChild(("", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SelectionMode _selectionMode;
|
||||||
|
private bool _addToSelection;
|
||||||
|
|
||||||
|
bool _wantsDelete = false;
|
||||||
|
|
||||||
protected override void InternalShow()
|
protected override void InternalShow()
|
||||||
{
|
{
|
||||||
_manager.Update();
|
_manager.Update();
|
||||||
@@ -135,10 +143,51 @@ namespace GlitchyEditor.EditWindows
|
|||||||
_currentDirectory.Set(_manager.AssetDirectory);
|
_currentDirectory.Set(_manager.AssetDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ImGui.Begin(s_WindowTitle, &_open, .None))
|
// Update selection modifies
|
||||||
{
|
{
|
||||||
ImGui.End();
|
if(!ImGui.Begin(s_WindowTitle, &_open, .None))
|
||||||
return;
|
{
|
||||||
|
ImGui.End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_addToSelection = Input.IsKeyPressed(.Control);
|
||||||
|
|
||||||
|
if (Input.IsKeyPressed(.Shift))
|
||||||
|
{
|
||||||
|
_selectionMode = .Range;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_selectionMode = .SingleFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove paths that no longer exist.
|
||||||
|
for (String path in _selectedFiles)
|
||||||
|
{
|
||||||
|
Result<TreeNode<AssetNode>> node = _manager.AssetHierarchy.GetNodeFromPath(path);
|
||||||
|
if (node case .Err)
|
||||||
|
{
|
||||||
|
@path.Remove();
|
||||||
|
delete path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deletion
|
||||||
|
{
|
||||||
|
if (Input.IsKeyPressing(.Delete) && _selectedFiles.Count > 0)
|
||||||
|
{
|
||||||
|
_wantsDelete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_wantsDelete)
|
||||||
|
{
|
||||||
|
ImGui.OpenPopup("Delete?");
|
||||||
|
_wantsDelete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawDeleteItemPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
||||||
@@ -198,36 +247,52 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private void ExternalFileDropTarget()
|
private bool IsFileSelected(StringView fullFilePath)
|
||||||
{
|
{
|
||||||
if (ImGui.BeginDragDropTarget())
|
return _selectedFiles.ContainsAlt(fullFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SelectionMode
|
||||||
|
{
|
||||||
|
SingleFile,
|
||||||
|
Range
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectFile(StringView fullFilePath, bool clearOldSelection, SelectionMode mode)
|
||||||
|
{
|
||||||
|
if (clearOldSelection)
|
||||||
{
|
{
|
||||||
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.ExternFiles, .AcceptBeforeDelivery);
|
_selectedFiles.ClearAndDeleteItems();
|
||||||
|
|
||||||
if (peekPayload != null)
|
|
||||||
{
|
|
||||||
if (peekPayload.IsDelivery())
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Info("Buup!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EditorLayer.SetDropEffect(.Copy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
private void SelectFile(StringView fullFileName)
|
if (mode == .SingleFile)
|
||||||
{
|
{
|
||||||
if (_selectedFile == fullFileName)
|
if (IsFileSelected(fullFilePath))
|
||||||
return;
|
{
|
||||||
|
String oldPath = _selectedFiles.GetAndRemoveAlt(fullFilePath);
|
||||||
|
delete oldPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_selectedFiles.Add(new String(fullFilePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == .Range)
|
||||||
|
{
|
||||||
|
if (IsFileSelected(fullFilePath))
|
||||||
|
{
|
||||||
|
String oldPath = _selectedFiles.GetAndRemoveAlt(fullFilePath);
|
||||||
|
delete oldPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_selectedFiles.Add(new String(fullFilePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_selectedFile.Set(fullFileName);
|
// TODO: Update event to also provide all selected paths?
|
||||||
|
OnFileSelected(this, fullFilePath);
|
||||||
OnFileSelected(this, _selectedFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawSearchBar()
|
private void DrawSearchBar()
|
||||||
@@ -431,6 +496,18 @@ namespace GlitchyEditor.EditWindows
|
|||||||
/// Renders the contents of _currentDirectory. Returns the node of the current directory, or null if the browser isn't in a directory.
|
/// Renders the contents of _currentDirectory. Returns the node of the current directory, or null if the browser isn't in a directory.
|
||||||
private void DrawCurrentDirectory(TreeNode<AssetNode> currentDirectoryNode)
|
private void DrawCurrentDirectory(TreeNode<AssetNode> currentDirectoryNode)
|
||||||
{
|
{
|
||||||
|
var currentDirectoryNode;
|
||||||
|
if (Input.IsKeyPressed(.Alt) && Input.IsKeyPressing(.Up))
|
||||||
|
{
|
||||||
|
if (currentDirectoryNode.Parent != _manager.AssetHierarchy.RootNode)
|
||||||
|
{
|
||||||
|
_currentDirectory.Set(currentDirectoryNode.Parent->Path);
|
||||||
|
|
||||||
|
_selectedFiles.ClearAndDeleteItems();
|
||||||
|
currentDirectoryNode = currentDirectoryNode.Parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<TreeNode<AssetNode>> directoryEntries = null;
|
List<TreeNode<AssetNode>> directoryEntries = null;
|
||||||
|
|
||||||
ImGui.Style* style = ImGui.GetStyle();
|
ImGui.Style* style = ImGui.GetStyle();
|
||||||
@@ -619,7 +696,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
ImGui.BeginChild("item", (.)DirectoryItemSize, .None, .NoScrollbar);
|
ImGui.BeginChild("item", (.)DirectoryItemSize, .None, .NoScrollbar);
|
||||||
|
|
||||||
if (entry->Path == _selectedFile)
|
if (IsFileSelected(entry->Path))
|
||||||
{
|
{
|
||||||
var color = ImGui.GetStyleColorVec4(.ButtonHovered);
|
var color = ImGui.GetStyleColorVec4(.ButtonHovered);
|
||||||
ImGui.PushStyleColor(.Button, *color);
|
ImGui.PushStyleColor(.Button, *color);
|
||||||
@@ -658,11 +735,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left))
|
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left))
|
||||||
{
|
{
|
||||||
if (_selectedFile != entry->Path)
|
SelectFile(entry->Path, !_addToSelection, _selectionMode);
|
||||||
{
|
// TODO: WHY?
|
||||||
SelectFile(entry->Path);
|
_assetToRename.Clear();
|
||||||
_assetToRename.Clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left))
|
if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left))
|
||||||
@@ -706,17 +781,12 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.TextUnformatted(itemType == .ParentDirectory ? ".." : entry->Name);
|
ImGui.TextUnformatted(itemType == .ParentDirectory ? ".." : entry->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wantsDelete = false;
|
|
||||||
|
|
||||||
if (ImGui.BeginPopupContextWindow())
|
if (ImGui.BeginPopupContextWindow())
|
||||||
{
|
{
|
||||||
ShowItemContextMenu(entry, itemType, ref wantsDelete);
|
ShowItemContextMenu(entry, itemType, ref _wantsDelete);
|
||||||
ImGui.EndPopup();
|
ImGui.EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantsDelete)
|
|
||||||
ImGui.OpenPopup("Delete?");
|
|
||||||
|
|
||||||
// TODO: Sub assets are probably borked now... I don't know if they ever worked, didn't test them
|
// TODO: Sub assets are probably borked now... I don't know if they ever worked, didn't test them
|
||||||
if (entry->SubAssets?.Count > 0)
|
if (entry->SubAssets?.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -746,9 +816,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
ImGui.EndPopup();
|
ImGui.EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteItemPopup(entry);
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
|
|
||||||
ImGui.AttachTooltip(entry->Name);
|
ImGui.AttachTooltip(entry->Name);
|
||||||
@@ -807,8 +875,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteItemPopup(TreeNode<AssetNode> fileOrFolder)
|
private void DrawDeleteItemPopup()
|
||||||
{
|
{
|
||||||
|
if (_selectedFiles.IsEmpty)
|
||||||
|
return;
|
||||||
|
|
||||||
// Always center this window when appearing
|
// Always center this window when appearing
|
||||||
ImGui.Vec2 center = ImGui.GetMainViewport().GetCenter();
|
ImGui.Vec2 center = ImGui.GetMainViewport().GetCenter();
|
||||||
ImGui.SetNextWindowPos(center, .Appearing, ImGui.Vec2(0.5f, 0.5f));
|
ImGui.SetNextWindowPos(center, .Appearing, ImGui.Vec2(0.5f, 0.5f));
|
||||||
@@ -817,17 +888,42 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginPopupModal("Delete?", null, .AlwaysAutoResize))
|
if (ImGui.BeginPopupModal("Delete?", null, .AlwaysAutoResize))
|
||||||
{
|
{
|
||||||
ImGui.Text($"""
|
if (_selectedFiles.Count == 1)
|
||||||
Delete "{fileOrFolder->Name}"?
|
{
|
||||||
|
Result<TreeNode<AssetNode>> nodeResult = _manager.AssetHierarchy.GetNodeFromPath(_selectedFiles[0]);
|
||||||
|
|
||||||
|
if (nodeResult case .Ok(TreeNode<AssetNode> node))
|
||||||
|
{
|
||||||
|
ImGui.Text(
|
||||||
|
$"""
|
||||||
|
Do you really want to delete "{node->Name}"?
|
||||||
|
|
||||||
|
|
||||||
""");
|
""");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.Text(
|
||||||
|
$"""
|
||||||
|
Do you really want to delete {_selectedFiles.Count} directories/assets?
|
||||||
|
|
||||||
|
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
if (ImGui.Button("Yes", ImGui.Vec2(120, 0)))
|
if (ImGui.Button("Yes", ImGui.Vec2(120, 0)))
|
||||||
{
|
{
|
||||||
_manager.AssetHierarchy.DeleteFile(fileOrFolder.Value);
|
List<StringView> paths = scope .();
|
||||||
|
for (String path in _selectedFiles)
|
||||||
|
{
|
||||||
|
paths.Add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
_manager.AssetHierarchy.DeletePathsBackground(paths);
|
||||||
|
|
||||||
ImGui.CloseCurrentPopup();
|
ImGui.CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,13 +238,14 @@ class CopyBackgroundTask : BackgroundTask
|
|||||||
|
|
||||||
while (!_pathsToCopy.IsEmpty && Running)
|
while (!_pathsToCopy.IsEmpty && Running)
|
||||||
{
|
{
|
||||||
CopyInfo currentPath = _pathsToCopy.PopFront();
|
CopyInfo currentPath = _pathsToCopy.Peek();
|
||||||
|
|
||||||
if (CopyPath(currentPath) case .Err(out _currentError) || Paused)
|
if (CopyPath(currentPath) case .Err(out _currentError) || Paused)
|
||||||
{
|
{
|
||||||
return .Pause;
|
return .Pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_pathsToCopy.PopFront();
|
||||||
delete currentPath;
|
delete currentPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,285 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using ImGui;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace GlitchyEditor.Multithreading;
|
||||||
|
|
||||||
|
class DeleteBackgroundTask : BackgroundTask
|
||||||
|
{
|
||||||
|
private List<String> _sourcePath ~ {ClearAndDeleteItems!(_); delete:append _;};
|
||||||
|
|
||||||
|
private int _totalEntriesToDelete;
|
||||||
|
private append Queue<String> _pathsToDelete = .() ~ ClearAndDeleteItems!(_);
|
||||||
|
private append Queue<String> _scanQueue = .() ~ ClearAndDeleteItems!(_);
|
||||||
|
|
||||||
|
enum ConflictResolutionMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
IgnoreUnexpectedErrors = 1,
|
||||||
|
SkipNotFound = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConflictResolutionMode _nextFileMode;
|
||||||
|
private ConflictResolutionMode _allFilesMode;
|
||||||
|
|
||||||
|
private ConflictResolutionMode CurrentFileMode => _nextFileMode | _allFilesMode;
|
||||||
|
|
||||||
|
public bool ScanningFiles => !_scanQueue.IsEmpty;
|
||||||
|
|
||||||
|
[AllowAppend]
|
||||||
|
public this(Span<StringView> sourcePaths)
|
||||||
|
{
|
||||||
|
List<String> sourcePathList = append List<String>(sourcePaths.Length);
|
||||||
|
|
||||||
|
_sourcePath = sourcePathList;
|
||||||
|
|
||||||
|
for (StringView path in sourcePaths)
|
||||||
|
{
|
||||||
|
AddPath(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPath(StringView pathToDelete)
|
||||||
|
{
|
||||||
|
_sourcePath.Add(new String(pathToDelete));
|
||||||
|
_scanQueue.Add(new String(pathToDelete));
|
||||||
|
_totalEntriesToDelete++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DeleteError : IDisposable
|
||||||
|
{
|
||||||
|
case None;
|
||||||
|
case EntryNotFound(String SourcePath);
|
||||||
|
case UnexpectedError(String Message);
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
switch (this)
|
||||||
|
{
|
||||||
|
case .None:
|
||||||
|
case .EntryNotFound(let SourcePath):
|
||||||
|
delete SourcePath;
|
||||||
|
case .UnexpectedError(let Message):
|
||||||
|
delete Message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<void, DeleteError> CollectFiles()
|
||||||
|
{
|
||||||
|
String currentPath = null;
|
||||||
|
defer
|
||||||
|
{
|
||||||
|
if (currentPath != null && @return case .Err)
|
||||||
|
{
|
||||||
|
_scanQueue.AddFront(currentPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddToDeleteStack(String path)
|
||||||
|
{
|
||||||
|
_pathsToDelete.Add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!_scanQueue.IsEmpty && Running)
|
||||||
|
{
|
||||||
|
Thread.Sleep(500);
|
||||||
|
|
||||||
|
// Pop from back, so that we delete children before parent directories
|
||||||
|
currentPath = _scanQueue.PopBack();
|
||||||
|
|
||||||
|
let fileName = scope String();
|
||||||
|
Path.GetFileName(currentPath, fileName);
|
||||||
|
|
||||||
|
if (Directory.Exists(currentPath))
|
||||||
|
{
|
||||||
|
// Current node is ready, add it to delete-queue.
|
||||||
|
AddToDeleteStack(currentPath);
|
||||||
|
|
||||||
|
// Add nested files and directories to the scan-queue.
|
||||||
|
for (FileFindEntry e in Directory.Enumerate(currentPath))
|
||||||
|
{
|
||||||
|
let entryPath = new String();
|
||||||
|
e.GetFilePath(entryPath);
|
||||||
|
|
||||||
|
_scanQueue.Add(entryPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (File.Exists(currentPath))
|
||||||
|
{
|
||||||
|
AddToDeleteStack(currentPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_totalEntriesToDelete = _pathsToDelete.Count;
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeleteError _currentError = .None ~ _.Dispose();
|
||||||
|
|
||||||
|
public override RunResult Run()
|
||||||
|
{
|
||||||
|
_currentError.Dispose();
|
||||||
|
_currentError = .None;
|
||||||
|
if (CollectFiles() case .Err(out _currentError) || Paused)
|
||||||
|
{
|
||||||
|
return .Pause;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!_pathsToDelete.IsEmpty && Running)
|
||||||
|
{
|
||||||
|
Thread.Sleep(500);
|
||||||
|
|
||||||
|
String currentPath = _pathsToDelete.Back;
|
||||||
|
|
||||||
|
if (DeletePath(currentPath) case .Err(out _currentError) || Paused)
|
||||||
|
{
|
||||||
|
return .Pause;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pathsToDelete.PopBack();
|
||||||
|
delete currentPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<void, DeleteError> DeletePath(StringView deletePath)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(deletePath))
|
||||||
|
{
|
||||||
|
if (Directory.Delete(deletePath) case .Err(let err) &&
|
||||||
|
!CurrentFileMode.HasFlag(.IgnoreUnexpectedErrors))
|
||||||
|
{
|
||||||
|
return .Err(.UnexpectedError(new $"Failed to delete directory {deletePath}: {err}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (File.Exists(deletePath))
|
||||||
|
{
|
||||||
|
if (File.Delete(deletePath) case .Err(let err) &&
|
||||||
|
!CurrentFileMode.HasFlag(.IgnoreUnexpectedErrors))
|
||||||
|
{
|
||||||
|
return .Err(.UnexpectedError(new $"Failed to delete file {deletePath}: {err}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!CurrentFileMode.HasFlag(.SkipNotFound))
|
||||||
|
return .Err(.EntryNotFound(new String(deletePath)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRenderPopup()
|
||||||
|
{
|
||||||
|
String title = scope .("Deleting files...");
|
||||||
|
|
||||||
|
if (ImGui.Begin(title, null, .NoDocking | .NoCollapse | .Modal | .NoResize | .AlwaysAutoResize))
|
||||||
|
{
|
||||||
|
if (ScanningFiles)
|
||||||
|
{
|
||||||
|
ImGui.ProgressBar(-1.0f * (float)ImGui.GetTime(), .(-1, 0), scope $"Found {_pathsToDelete.Count} files...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int deletedEntries = _totalEntriesToDelete - _pathsToDelete.Count;
|
||||||
|
|
||||||
|
ImGui.ProgressBar(deletedEntries / _totalEntriesToDelete, .(-1, 0), scope $"Deleted {deletedEntries} / {_totalEntriesToDelete} files.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch (_currentError)
|
||||||
|
{
|
||||||
|
case .EntryNotFound(let SourcePath):
|
||||||
|
ImGui.PushStyleColor(.Text, 0xFF0000FF);
|
||||||
|
ImGui.TextUnformatted(scope $"\"{SourcePath}\" doesn't exist.");
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
case .UnexpectedError(let Message):
|
||||||
|
ImGui.PushStyleColor(.Text, 0xFF0000FF);
|
||||||
|
ImGui.TextUnformatted(scope $"Unexpected error: {Message}");
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
default:
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginTable("buttonTable", 2))
|
||||||
|
{
|
||||||
|
switch (_currentError)
|
||||||
|
{
|
||||||
|
case .None:
|
||||||
|
// Do nothing
|
||||||
|
case .EntryNotFound(let SourcePath):
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
if (ImGui.Button("Skip"))
|
||||||
|
{
|
||||||
|
_nextFileMode |= .SkipNotFound;
|
||||||
|
Continue();
|
||||||
|
}
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
if (ImGui.Button("Skip all"))
|
||||||
|
{
|
||||||
|
_allFilesMode |= .SkipNotFound;
|
||||||
|
Continue();
|
||||||
|
}
|
||||||
|
case .UnexpectedError(let Message):
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
if (ImGui.Button("Retry"))
|
||||||
|
{
|
||||||
|
Continue();
|
||||||
|
}
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
if (ImGui.Button("Ignore"))
|
||||||
|
{
|
||||||
|
_nextFileMode |= .IgnoreUnexpectedErrors;
|
||||||
|
Continue();
|
||||||
|
}
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
if (ImGui.Button("Ignore all unexpected"))
|
||||||
|
{
|
||||||
|
_allFilesMode |= .IgnoreUnexpectedErrors;
|
||||||
|
Continue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
if (_currentError case .None)
|
||||||
|
{
|
||||||
|
if (Paused)
|
||||||
|
{
|
||||||
|
if (ImGui.Button("Continue"))
|
||||||
|
{
|
||||||
|
Continue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ImGui.Button("Pause"))
|
||||||
|
{
|
||||||
|
Pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.Button("Cancel"))
|
||||||
|
{
|
||||||
|
Abort();
|
||||||
|
}
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -301,37 +301,6 @@ abstract class IDropTargetImplBase : IUnknownImplBase<IDropTarget, IDropTarget.V
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct S
|
|
||||||
{
|
|
||||||
bool b1;
|
|
||||||
int32 i32;
|
|
||||||
bool b2;
|
|
||||||
int64 i64;
|
|
||||||
int32 i322;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SB
|
|
||||||
{
|
|
||||||
int64 i64;
|
|
||||||
int32 i32;
|
|
||||||
int32 i322;
|
|
||||||
bool b1;
|
|
||||||
bool b2;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SC
|
|
||||||
{
|
|
||||||
bool b1;
|
|
||||||
//filler 56
|
|
||||||
int32 i32;
|
|
||||||
//filler 32
|
|
||||||
bool b2;
|
|
||||||
//filler 56
|
|
||||||
int64 i64;
|
|
||||||
int32 i322;
|
|
||||||
//filler 32
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum DragDropType
|
public enum DragDropType
|
||||||
{
|
{
|
||||||
Enter,
|
Enter,
|
||||||
|
|||||||
Reference in New Issue
Block a user