mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Basic copy for drag'n'drop
This commit is contained in:
@@ -646,4 +646,101 @@ class AssetHierarchy
|
|||||||
public delegate void FileRenamedFunc(AssetNode node, StringView oldName);
|
public delegate void FileRenamedFunc(AssetNode node, StringView oldName);
|
||||||
|
|
||||||
public Event<FileRenamedFunc> OnFileRenamed ~ _.Dispose();
|
public Event<FileRenamedFunc> OnFileRenamed ~ _.Dispose();
|
||||||
|
|
||||||
|
public enum CopyError
|
||||||
|
{
|
||||||
|
TargetDirectoryIsNotDirectory,
|
||||||
|
SourceDoesntExist,
|
||||||
|
TargetExists
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum OverwriteMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Overwrite,
|
||||||
|
KeepBoth,
|
||||||
|
Combine
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<void, CopyError> CopyExternFileToNode(TreeNode<AssetNode> targetDirectory, String sourcePath, OverwriteMode overwrite)
|
||||||
|
{
|
||||||
|
if (!targetDirectory->IsDirectory)
|
||||||
|
return .Err(.TargetDirectoryIsNotDirectory);
|
||||||
|
|
||||||
|
if (!File.Exists(sourcePath))
|
||||||
|
return .Err(.SourceDoesntExist);
|
||||||
|
|
||||||
|
|
||||||
|
FileInfo sourceInfo = scope FileInfo(sourcePath);
|
||||||
|
|
||||||
|
String fileName = scope .();
|
||||||
|
Path.GetFileName(sourcePath, fileName);
|
||||||
|
|
||||||
|
String targetPath = scope .();
|
||||||
|
Path.Combine(targetPath, targetDirectory->Path, fileName);
|
||||||
|
|
||||||
|
FileInfo targetInfo = scope FileInfo(targetPath);
|
||||||
|
|
||||||
|
if (sourceInfo.IsDirectory)
|
||||||
|
{
|
||||||
|
bool forceOverwrite = false;
|
||||||
|
if (targetInfo.Exists)
|
||||||
|
{
|
||||||
|
switch (overwrite)
|
||||||
|
{
|
||||||
|
case .KeepBoth:
|
||||||
|
String fileExtension = scope .();
|
||||||
|
Path.GetExtension(targetPath, fileExtension);
|
||||||
|
FindFreePath(targetDirectory->Path, fileName.Substring(0..<^fileExtension.Length), fileExtension, targetPath..Clear());
|
||||||
|
case .Overwrite:
|
||||||
|
forceOverwrite = true;
|
||||||
|
default:
|
||||||
|
return .Err(.TargetExists);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool forceOverwrite = false;
|
||||||
|
if (targetInfo.Exists)
|
||||||
|
{
|
||||||
|
switch (overwrite)
|
||||||
|
{
|
||||||
|
case .KeepBoth:
|
||||||
|
String fileExtension = scope .();
|
||||||
|
Path.GetExtension(targetPath, fileExtension);
|
||||||
|
FindFreePath(targetDirectory->Path, fileName.Substring(0..<^fileExtension.Length), fileExtension, targetPath..Clear());
|
||||||
|
case .Overwrite:
|
||||||
|
forceOverwrite = true;
|
||||||
|
default:
|
||||||
|
return .Err(.TargetExists);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Copy(sourcePath, targetPath, forceOverwrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FindFreePath(StringView directory, StringView wantedName, StringView fileExtension, String outFreePath)
|
||||||
|
{
|
||||||
|
int fileNumber = 0;
|
||||||
|
|
||||||
|
String currentFileName = scope $"{wantedName}{fileExtension}";
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Path.Combine(outFreePath..Clear(), directory, currentFileName);
|
||||||
|
|
||||||
|
FileInfo targetInfo = scope FileInfo(outFreePath);
|
||||||
|
|
||||||
|
if (!targetInfo.Exists)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileNumber++;
|
||||||
|
currentFileName..Clear().AppendF($"{wantedName} ({fileNumber}){fileExtension}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,7 +174,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (ImGui.BeginChild("Files"))
|
if (ImGui.BeginChild("Files"))
|
||||||
{
|
{
|
||||||
DrawCurrentDirectory();
|
TreeNode<AssetNode> currentDirectoryNode = TrySilent!(_manager.AssetHierarchy.GetNodeFromPath(_currentDirectory));
|
||||||
|
|
||||||
|
DrawCurrentDirectory(currentDirectoryNode);
|
||||||
|
|
||||||
// Context menu when clicking on the background.
|
// Context menu when clicking on the background.
|
||||||
if (ImGui.BeginPopupContextWindow())
|
if (ImGui.BeginPopupContextWindow())
|
||||||
@@ -184,28 +186,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
|
|
||||||
|
FileDropTarget(currentDirectoryNode, .External);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndTable();
|
ImGui.EndTable();
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.ExternFiles, .AcceptBeforeDelivery);
|
|
||||||
|
|
||||||
if (peekPayload != null)
|
|
||||||
{
|
|
||||||
if (peekPayload.IsDelivery())
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Info("Buup!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EditorLayer.SetDropEffect(.Copy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.PopStyleVar(1);
|
ImGui.PopStyleVar(1);
|
||||||
@@ -213,6 +198,28 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*private void ExternalFileDropTarget()
|
||||||
|
{
|
||||||
|
if (ImGui.BeginDragDropTarget())
|
||||||
|
{
|
||||||
|
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.ExternFiles, .AcceptBeforeDelivery);
|
||||||
|
|
||||||
|
if (peekPayload != null)
|
||||||
|
{
|
||||||
|
if (peekPayload.IsDelivery())
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Info("Buup!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorLayer.SetDropEffect(.Copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndDragDropTarget();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
private void SelectFile(StringView fullFileName)
|
private void SelectFile(StringView fullFileName)
|
||||||
{
|
{
|
||||||
if (_selectedFile == fullFileName)
|
if (_selectedFile == fullFileName)
|
||||||
@@ -399,6 +406,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
bool isOpen = ImGui.TreeNodeEx(name, flags, $"{name}");
|
bool isOpen = ImGui.TreeNodeEx(name, flags, $"{name}");
|
||||||
|
|
||||||
|
FileDropTarget(tree, .Internal | .External);
|
||||||
|
|
||||||
if (!ImGui.IsItemToggledOpen() && ImGui.IsItemClicked(.Left))
|
if (!ImGui.IsItemToggledOpen() && ImGui.IsItemClicked(.Left))
|
||||||
{
|
{
|
||||||
_currentDirectory.Set(tree->Path);
|
_currentDirectory.Set(tree->Path);
|
||||||
@@ -419,8 +428,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
const float2 padding = .(24, 24);
|
const float2 padding = .(24, 24);
|
||||||
|
|
||||||
/// Renders the contents of _currentDirectory.
|
/// 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()
|
private void DrawCurrentDirectory(TreeNode<AssetNode> currentDirectoryNode)
|
||||||
{
|
{
|
||||||
List<TreeNode<AssetNode>> files = null;
|
List<TreeNode<AssetNode>> files = null;
|
||||||
|
|
||||||
@@ -443,27 +452,20 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_currentDirectory.IsEmpty)
|
if (currentDirectoryNode == null)
|
||||||
return;
|
|
||||||
|
|
||||||
// Get the node of the current directory.
|
|
||||||
var currentDirectoryNode = _manager.AssetHierarchy.GetNodeFromPath(_currentDirectory);
|
|
||||||
|
|
||||||
if (currentDirectoryNode case .Err)
|
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"No node exists for {_currentDirectory}.");
|
|
||||||
ImGui.TextUnformatted("Failed to display contents of directory.");
|
ImGui.TextUnformatted("Failed to display contents of directory.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
files = currentDirectoryNode->Children;
|
files = currentDirectoryNode.Children;
|
||||||
|
|
||||||
// show back button (".."-File)
|
// show back button (".."-File)
|
||||||
if (currentDirectoryNode->Parent != _manager.AssetHierarchy.RootNode)
|
if (currentDirectoryNode.Parent != _manager.AssetHierarchy.RootNode)
|
||||||
{
|
{
|
||||||
ImGui.PushID("Back");
|
ImGui.PushID("Back");
|
||||||
|
|
||||||
DrawBackButton(currentDirectoryNode->Parent);
|
DrawBackButton(currentDirectoryNode.Parent);
|
||||||
|
|
||||||
// X-Coordinate of the right side of the current entry.
|
// X-Coordinate of the right side of the current entry.
|
||||||
float currentButtonRight = ImGui.GetItemRectMax().x;
|
float currentButtonRight = ImGui.GetItemRectMax().x;
|
||||||
@@ -543,7 +545,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
FileDropTarget(entry);
|
FileDropTarget(entry, .Internal | .External);
|
||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left))
|
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left))
|
||||||
{
|
{
|
||||||
@@ -564,31 +566,68 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.EndChild();
|
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
|
enum DropTargetMode
|
||||||
private void FileDropTarget(TreeNode<AssetNode> dropTarget)
|
|
||||||
{
|
{
|
||||||
if (dropTarget->IsDirectory && ImGui.BeginDragDropTarget())
|
Internal = 1,
|
||||||
|
External = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<AssetNode> dropTarget, DropTargetMode mode)
|
||||||
|
{
|
||||||
|
if (dropTarget != null && dropTarget->IsDirectory && ImGui.BeginDragDropTarget())
|
||||||
{
|
{
|
||||||
bool allowDrop = false;
|
bool allowDrop = false;
|
||||||
|
|
||||||
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.ContentBrowserItem, .AcceptPeekOnly);
|
if (mode.HasFlag(.Internal))
|
||||||
|
|
||||||
if (peekPayload != null)
|
|
||||||
{
|
{
|
||||||
StringView assetIdentifier = .((char8*)peekPayload.Data, (int)peekPayload.DataSize);
|
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.ContentBrowserItem, .AcceptBeforeDelivery);
|
||||||
|
|
||||||
allowDrop = assetIdentifier != dropTarget->Identifier;
|
if (peekPayload != null)
|
||||||
|
{
|
||||||
|
StringView assetIdentifier = .((char8*)peekPayload.Data, (int)peekPayload.DataSize);
|
||||||
|
|
||||||
|
allowDrop = assetIdentifier != dropTarget->Identifier;
|
||||||
|
|
||||||
|
if (allowDrop && peekPayload.IsDelivery())
|
||||||
|
{
|
||||||
|
_manager.AssetHierarchy.MoveFileToNode(assetIdentifier, dropTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowDrop)
|
if (mode.HasFlag(.External))
|
||||||
{
|
{
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.ExternFiles, .AcceptBeforeDelivery);
|
||||||
|
|
||||||
if (payload != null)
|
if (peekPayload != null)
|
||||||
{
|
{
|
||||||
StringView movedChild = .((char8*)payload.Data, (int)payload.DataSize);
|
if (peekPayload.IsDelivery())
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Info($"Dropping into {dropTarget->Path}");
|
||||||
|
|
||||||
_manager.AssetHierarchy.MoveFileToNode(movedChild, dropTarget);
|
List<String> droppedFiles = (.)Internal.UnsafeCastToObject(*(void**)peekPayload.Data);
|
||||||
|
|
||||||
|
for (String path in droppedFiles)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Info($"Dropping file {path}");
|
||||||
|
|
||||||
|
_manager.AssetHierarchy.CopyExternFileToNode(dropTarget, path, .None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorLayer.SetDropEffect(.Copy);
|
||||||
|
|
||||||
|
if (dropTarget->Path == _currentDirectory)
|
||||||
|
{
|
||||||
|
ImGui.SetTooltip($"Copy here ({dropTarget->Name})");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.SetTooltip($"Copy to {dropTarget->Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,7 +682,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.EndDragDropSource();
|
ImGui.EndDragDropSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDropTarget(entry);
|
FileDropTarget(entry, .Internal | .External);
|
||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left))
|
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -140,9 +140,10 @@ namespace GlitchyEditor
|
|||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result<DropEffect> OnDrop(int2 cursorPosition)
|
public override Result<DropEffect> OnDrop(int2 cursorPosition, List<String> fileNames)
|
||||||
{
|
{
|
||||||
DragDropEvent event = scope DragDropEvent(.Drop, cursorPosition);
|
DragDropEvent event = scope DragDropEvent(.Drop, cursorPosition);
|
||||||
|
event.FileNames = fileNames;
|
||||||
Application.Instance.OnEvent(event);
|
Application.Instance.OnEvent(event);
|
||||||
return event.OutDropEffect;
|
return event.OutDropEffect;
|
||||||
}
|
}
|
||||||
@@ -1204,16 +1205,29 @@ namespace GlitchyEditor
|
|||||||
ImGui.Viewport* viewport = ImGui.GetMainViewport();
|
ImGui.Viewport* viewport = ImGui.GetMainViewport();
|
||||||
ImGui.DockSpaceOverViewport(viewport);
|
ImGui.DockSpaceOverViewport(viewport);
|
||||||
|
|
||||||
if (_isDraggingFromOutside)
|
if (_isDraggingFromOutside not case .None)
|
||||||
{
|
{
|
||||||
// Reset drop effect, so the drop targets have to set it themselves (and don't "leak" it).
|
// Reset drop effect, so the drop targets have to set it themselves (and don't "leak" it).
|
||||||
SetDropEffect(.None);
|
SetDropEffect(.None);
|
||||||
|
|
||||||
if (ImGui.BeginDragDropSource(.SourceExtern | .SourceAutoExpirePayload | .SourceNoPreviewTooltip))
|
if (ImGui.BeginDragDropSource(.SourceExtern | .SourceAutoExpirePayload | .SourceNoPreviewTooltip))
|
||||||
{
|
{
|
||||||
ImGui.SetDragDropPayload(.ExternFiles, null, 0);
|
void* ptr = Internal.UnsafeCastToPtr(_droppedFiles);
|
||||||
|
ImGui.SetDragDropPayload(.ExternFiles, &ptr, sizeof(int));
|
||||||
|
|
||||||
ImGui.EndDragDropSource();
|
ImGui.EndDragDropSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_isDraggingFromOutside case .Dropping)
|
||||||
|
{
|
||||||
|
_isDraggingFromOutside = .None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Can Imgui handle this, somehow?
|
||||||
|
DeleteContainerAndItems!(_droppedFiles);
|
||||||
|
_droppedFiles = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawMainMenuBar();
|
DrawMainMenuBar();
|
||||||
@@ -1671,14 +1685,23 @@ namespace GlitchyEditor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _isDraggingFromOutside;
|
enum DragDropState
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Dragging,
|
||||||
|
Dropping
|
||||||
|
}
|
||||||
|
|
||||||
|
private DragDropState _isDraggingFromOutside;
|
||||||
private DropEffect _effectWhenDropping = .None;
|
private DropEffect _effectWhenDropping = .None;
|
||||||
|
|
||||||
private static EditorLayer _layer;
|
private static EditorLayer _layer;
|
||||||
|
|
||||||
|
private List<String> _droppedFiles;
|
||||||
|
|
||||||
public static void SetDropEffect(DropEffect effect)
|
public static void SetDropEffect(DropEffect effect)
|
||||||
{
|
{
|
||||||
if (!_layer._isDraggingFromOutside)
|
if (_layer._isDraggingFromOutside == .None)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Warning("Setting drop effect, eventhou the user is currently not dragging.");
|
Log.EngineLogger.Warning("Setting drop effect, eventhou the user is currently not dragging.");
|
||||||
}
|
}
|
||||||
@@ -1688,24 +1711,43 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
private bool OnDragDrop(DragDropEvent e)
|
private bool OnDragDrop(DragDropEvent e)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Info($"D'n'D: {e.DragDropType} {e.CursorPosition.X} {e.CursorPosition.Y}");
|
|
||||||
|
|
||||||
if (all(e.CursorPosition != .(-1,-1)))
|
if (all(e.CursorPosition != .(-1,-1)))
|
||||||
{
|
{
|
||||||
ImGui.GetIO().MousePos = .(e.CursorPosition.X, e.CursorPosition.Y);
|
ImGui.GetIO().MousePos = .(e.CursorPosition.X, e.CursorPosition.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.FileNames == null)
|
||||||
|
{
|
||||||
|
DeleteContainerAndItems!(_droppedFiles);
|
||||||
|
_droppedFiles = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_droppedFiles == null)
|
||||||
|
{
|
||||||
|
_droppedFiles = new List<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String fileName in e.FileNames)
|
||||||
|
{
|
||||||
|
if (!_droppedFiles.Contains(fileName, .Ordinal))
|
||||||
|
{
|
||||||
|
_droppedFiles.Add(new String(fileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (e.DragDropType)
|
switch (e.DragDropType)
|
||||||
{
|
{
|
||||||
case .Enter:
|
case .Enter:
|
||||||
_isDraggingFromOutside = true;
|
_isDraggingFromOutside = .Dragging;
|
||||||
ImGui.GetIO().MouseDown[0] = true;
|
ImGui.GetIO().MouseDown[0] = true;
|
||||||
case .Over:
|
case .Over:
|
||||||
case .Leave:
|
case .Leave:
|
||||||
_isDraggingFromOutside = false;
|
_isDraggingFromOutside = .None;
|
||||||
ImGui.ClearDragDrop();
|
ImGui.ClearDragDrop();
|
||||||
case .Drop:
|
case .Drop:
|
||||||
_isDraggingFromOutside = false;
|
_isDraggingFromOutside = .Dropping;
|
||||||
ImGui.GetIO().MouseDown[0] = false;
|
ImGui.GetIO().MouseDown[0] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ abstract class IDropTargetImplBase : RefCounted
|
|||||||
public abstract Result<DropEffect> OnDragEnter(int2 cursorPosition);
|
public abstract Result<DropEffect> OnDragEnter(int2 cursorPosition);
|
||||||
public abstract Result<DropEffect> OnDragOver(int2 cursorPosition);
|
public abstract Result<DropEffect> OnDragOver(int2 cursorPosition);
|
||||||
public abstract Result<void> OnDragLeave();
|
public abstract Result<void> OnDragLeave();
|
||||||
public abstract Result<DropEffect> OnDrop(int2 cursorPosition);
|
public abstract Result<DropEffect> OnDrop(int2 cursorPosition, List<String> fileNames);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall)]
|
[CallingConvention(.Stdcall)]
|
||||||
private static HResult DragEnterImpl(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect)
|
private static HResult DragEnterImpl(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect)
|
||||||
@@ -338,11 +338,16 @@ abstract class IDropTargetImplBase : RefCounted
|
|||||||
tymed = (.)TYMED.HGLOBAL
|
tymed = (.)TYMED.HGLOBAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
List<String> files = null;
|
||||||
|
defer {DeleteContainerAndItems!(files);}
|
||||||
|
|
||||||
if (dataObject.GetData(ref format, var stgm).Succeeded)
|
if (dataObject.GetData(ref format, var stgm).Succeeded)
|
||||||
{
|
{
|
||||||
HDROP hdrop = (HDROP)stgm.hGlobal;
|
HDROP hdrop = (HDROP)stgm.hGlobal;
|
||||||
uint32 fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, null, 0);
|
uint32 fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, null, 0);
|
||||||
|
|
||||||
|
files = new List<String>(fileCount);
|
||||||
|
|
||||||
List<char16> buffer = scope List<char16>();
|
List<char16> buffer = scope List<char16>();
|
||||||
buffer.Resize(256);
|
buffer.Resize(256);
|
||||||
|
|
||||||
@@ -354,15 +359,15 @@ abstract class IDropTargetImplBase : RefCounted
|
|||||||
uint32 retrievedSize = DragQueryFileW(hdrop, i, buffer.Ptr, (.)buffer.Count);
|
uint32 retrievedSize = DragQueryFileW(hdrop, i, buffer.Ptr, (.)buffer.Count);
|
||||||
if (retrievedSize > 0 && retrievedSize < buffer.Count)
|
if (retrievedSize > 0 && retrievedSize < buffer.Count)
|
||||||
{
|
{
|
||||||
String str = scope String(buffer.Ptr);
|
String str = new String(buffer.Ptr);
|
||||||
Log.EngineLogger.Info($"Dropped File: {str}");
|
files.Add(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseStgMedium(ref stgm);
|
ReleaseStgMedium(ref stgm);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<DropEffect> result = instance.OnDrop(point);
|
Result<DropEffect> result = instance.OnDrop(point, files);
|
||||||
|
|
||||||
if (result case .Ok(out effect))
|
if (result case .Ok(out effect))
|
||||||
return .S_OK;
|
return .S_OK;
|
||||||
@@ -425,6 +430,9 @@ public class DragDropEvent : Event, IEvent
|
|||||||
|
|
||||||
public DropEffect OutDropEffect { get; set; }
|
public DropEffect OutDropEffect { get; set; }
|
||||||
|
|
||||||
|
// Do not keep references to this list or any of it's items outside of the event handler, they will not survive it.
|
||||||
|
public List<String> FileNames { get; set; }
|
||||||
|
|
||||||
// TODO: Keys, or perhaps just make the listeners query them...
|
// TODO: Keys, or perhaps just make the listeners query them...
|
||||||
|
|
||||||
public this(DragDropType dragDropType, int2 cursorPosition)
|
public this(DragDropType dragDropType, int2 cursorPosition)
|
||||||
|
|||||||
Reference in New Issue
Block a user