mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Retrieve filenames from drop event
This commit is contained in:
@@ -1206,9 +1206,10 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
if (_isDraggingFromOutside)
|
if (_isDraggingFromOutside)
|
||||||
{
|
{
|
||||||
|
// 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))
|
if (ImGui.BeginDragDropSource(.SourceExtern | .SourceAutoExpirePayload | .SourceNoPreviewTooltip))
|
||||||
{
|
{
|
||||||
ImGui.SetDragDropPayload(.ExternFiles, null, 0);
|
ImGui.SetDragDropPayload(.ExternFiles, null, 0);
|
||||||
ImGui.EndDragDropSource();
|
ImGui.EndDragDropSource();
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using GlitchyEngine;
|
|||||||
using GlitchyEngine.Events;
|
using GlitchyEngine.Events;
|
||||||
using static System.Windows;
|
using static System.Windows;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
|
using System.Collections;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace GlitchyEditor.Platform.Windows;
|
namespace GlitchyEditor.Platform.Windows;
|
||||||
|
|
||||||
@@ -18,6 +20,8 @@ static
|
|||||||
public static extern void OleUninitialize();
|
public static extern void OleUninitialize();
|
||||||
[Import("Ole32.lib"), CLink]
|
[Import("Ole32.lib"), CLink]
|
||||||
public static extern HResult RegisterDragDrop(HWnd windowHandle, IDropTarget* dropTarget);
|
public static extern HResult RegisterDragDrop(HWnd windowHandle, IDropTarget* dropTarget);
|
||||||
|
[Import("Ole32.lib"), CLink]
|
||||||
|
public static extern HResult RevokeDragDrop(HWnd windowHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
[CRepr]
|
[CRepr]
|
||||||
@@ -31,7 +35,7 @@ struct IDropTarget : IUnknown
|
|||||||
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) DragEnter;
|
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) DragEnter;
|
||||||
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self, uint32 grfKeyState, int2 point, ref DropEffect effect) DragOver;
|
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self, uint32 grfKeyState, int2 point, ref DropEffect effect) DragOver;
|
||||||
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self) DragLeave;
|
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self) DragLeave;
|
||||||
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) Drop;
|
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self, IDataObject* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) Drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public new VTable* VT => (VTable*)mVT;
|
public new VTable* VT => (VTable*)mVT;
|
||||||
@@ -51,11 +55,87 @@ struct IDropTarget : IUnknown
|
|||||||
return VT.DragLeave(&this);
|
return VT.DragLeave(&this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HResult Drop(/*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) mut
|
public HResult Drop(IDataObject* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) mut
|
||||||
{
|
{
|
||||||
return VT.Drop(&this, dataObject, grfKeyState, point, ref effect);
|
return VT.Drop(&this, dataObject, grfKeyState, point, ref effect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[CRepr]
|
||||||
|
public struct DVTARGETDEVICE
|
||||||
|
{
|
||||||
|
public uint32 tdSize;
|
||||||
|
public uint16 tdDriverNameOffset;
|
||||||
|
public uint16 tdDeviceNameOffset;
|
||||||
|
public uint16 tdPortNameOffset;
|
||||||
|
public uint16 tdExtDevmodeOffset;
|
||||||
|
public uint8[1] tdData_array;
|
||||||
|
|
||||||
|
public uint8* tdData mut => &tdData_array[0];
|
||||||
|
}
|
||||||
|
[CRepr]
|
||||||
|
public struct FORMATETC
|
||||||
|
{
|
||||||
|
public uint16 cfFormat;
|
||||||
|
public DVTARGETDEVICE* ptd;
|
||||||
|
public uint32 dwAspect;
|
||||||
|
public int32 lindex;
|
||||||
|
public uint32 tymed;
|
||||||
|
}
|
||||||
|
public typealias HDROP = int;
|
||||||
|
public typealias HBITMAP = int;
|
||||||
|
public typealias HENHMETAFILE = int;
|
||||||
|
public typealias PWSTR = char16*;
|
||||||
|
public typealias BOOL = int32;
|
||||||
|
[CRepr]
|
||||||
|
public struct STGMEDIUM
|
||||||
|
{
|
||||||
|
public uint32 tymed;
|
||||||
|
public using _Anonymous_e__Union Anonymous;
|
||||||
|
public IUnknown* pUnkForRelease;
|
||||||
|
|
||||||
|
[CRepr, Union]
|
||||||
|
public struct _Anonymous_e__Union
|
||||||
|
{
|
||||||
|
public HBITMAP hBitmap;
|
||||||
|
public void* hMetaFilePict;
|
||||||
|
public HENHMETAFILE hEnhMetaFile;
|
||||||
|
public int hGlobal;
|
||||||
|
public PWSTR lpszFileName;
|
||||||
|
public /*IStream*/IUnknown* pstm;
|
||||||
|
public /*IStorage*/IUnknown* pstg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[CRepr]
|
||||||
|
public struct IDataObject : IUnknown
|
||||||
|
{
|
||||||
|
public const new Guid IID = .(0x0000010e, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
|
||||||
|
|
||||||
|
public new VTable* VT { get => (.)mVT; }
|
||||||
|
|
||||||
|
public HResult GetData(ref FORMATETC pformatetcIn, out STGMEDIUM pmedium) mut => VT.GetData(ref this, ref pformatetcIn, out pmedium);
|
||||||
|
public HResult GetDataHere(ref FORMATETC pformatetc, out STGMEDIUM pmedium) mut => VT.GetDataHere(ref this, ref pformatetc, out pmedium);
|
||||||
|
public HResult QueryGetData(ref FORMATETC pformatetc) mut => VT.QueryGetData(ref this, ref pformatetc);
|
||||||
|
public HResult GetCanonicalFormatEtc(ref FORMATETC pformatectIn, out FORMATETC pformatetcOut) mut => VT.GetCanonicalFormatEtc(ref this, ref pformatectIn, out pformatetcOut);
|
||||||
|
public HResult SetData(ref FORMATETC pformatetc, ref STGMEDIUM pmedium, BOOL fRelease) mut => VT.SetData(ref this, ref pformatetc, ref pmedium, fRelease);
|
||||||
|
public HResult EnumFormatEtc(uint32 dwDirection, out /*IEnumFORMATETC*/ IUnknown* ppenumFormatEtc) mut => VT.EnumFormatEtc(ref this, dwDirection, out ppenumFormatEtc);
|
||||||
|
public HResult DAdvise(ref FORMATETC pformatetc, uint32 advf, ref /*IAdviseSink*/ IUnknown* pAdvSink, out uint32 pdwConnection) mut => VT.DAdvise(ref this, ref pformatetc, advf, ref pAdvSink, out pdwConnection);
|
||||||
|
public HResult DUnadvise(uint32 dwConnection) mut => VT.DUnadvise(ref this, dwConnection);
|
||||||
|
public HResult EnumDAdvise(out /*IEnumSTATDATA*/ IUnknown* ppenumAdvise) mut => VT.EnumDAdvise(ref this, out ppenumAdvise);
|
||||||
|
|
||||||
|
[CRepr]
|
||||||
|
public struct VTable : IUnknown.VTable
|
||||||
|
{
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, ref FORMATETC pformatetcIn, out STGMEDIUM pmedium) GetData;
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, ref FORMATETC pformatetc, out STGMEDIUM pmedium) GetDataHere;
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, ref FORMATETC pformatetc) QueryGetData;
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, ref FORMATETC pformatectIn, out FORMATETC pformatetcOut) GetCanonicalFormatEtc;
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, ref FORMATETC pformatetc, ref STGMEDIUM pmedium, BOOL fRelease) SetData;
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, uint32 dwDirection, out /*IEnumFORMATETC*/ IUnknown* ppenumFormatEtc) EnumFormatEtc;
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, ref FORMATETC pformatetc, uint32 advf, ref /*IAdviseSink*/ IUnknown* pAdvSink, out uint32 pdwConnection) DAdvise;
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, uint32 dwConnection) DUnadvise;
|
||||||
|
public new function [CallingConvention(.Stdcall)] HResult(ref IDataObject self, out /*IEnumSTATDATA*/ IUnknown* ppenumAdvise) EnumDAdvise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[CRepr]
|
[CRepr]
|
||||||
enum DropEffect
|
enum DropEffect
|
||||||
@@ -67,6 +147,49 @@ enum DropEffect
|
|||||||
Scroll = 0x80000000,
|
Scroll = 0x80000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum CLIPBOARD_FORMATS : uint32
|
||||||
|
{
|
||||||
|
TEXT = 1,
|
||||||
|
BITMAP = 2,
|
||||||
|
METAFILEPICT = 3,
|
||||||
|
SYLK = 4,
|
||||||
|
DIF = 5,
|
||||||
|
TIFF = 6,
|
||||||
|
OEMTEXT = 7,
|
||||||
|
DIB = 8,
|
||||||
|
PALETTE = 9,
|
||||||
|
PENDATA = 10,
|
||||||
|
RIFF = 11,
|
||||||
|
WAVE = 12,
|
||||||
|
UNICODETEXT = 13,
|
||||||
|
ENHMETAFILE = 14,
|
||||||
|
HDROP = 15,
|
||||||
|
LOCALE = 16,
|
||||||
|
DIBV5 = 17,
|
||||||
|
MAX = 18,
|
||||||
|
OWNERDISPLAY = 128,
|
||||||
|
DSPTEXT = 129,
|
||||||
|
DSPBITMAP = 130,
|
||||||
|
DSPMETAFILEPICT = 131,
|
||||||
|
DSPENHMETAFILE = 142,
|
||||||
|
PRIVATEFIRST = 512,
|
||||||
|
PRIVATELAST = 767,
|
||||||
|
GDIOBJFIRST = 768,
|
||||||
|
GDIOBJLAST = 1023,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TYMED : int32
|
||||||
|
{
|
||||||
|
HGLOBAL = 1,
|
||||||
|
FILE = 2,
|
||||||
|
ISTREAM = 4,
|
||||||
|
ISTORAGE = 8,
|
||||||
|
GDI = 16,
|
||||||
|
MFPICT = 32,
|
||||||
|
ENHMF = 64,
|
||||||
|
NULL = 0,
|
||||||
|
}
|
||||||
|
|
||||||
abstract class IDropTargetImplBase : RefCounted
|
abstract class IDropTargetImplBase : RefCounted
|
||||||
{
|
{
|
||||||
[CRepr]
|
[CRepr]
|
||||||
@@ -102,6 +225,12 @@ abstract class IDropTargetImplBase : RefCounted
|
|||||||
Log.EngineLogger.Assert(result case .S_OK);
|
Log.EngineLogger.Assert(result case .S_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Unregister()
|
||||||
|
{
|
||||||
|
HResult result = RevokeDragDrop(Application.Instance.Window.[Friend]_windowHandle);
|
||||||
|
Log.EngineLogger.Assert(result case .S_OK);
|
||||||
|
}
|
||||||
|
|
||||||
private static IDropTargetImplBase GetInstance(IUnknown* self)
|
private static IDropTargetImplBase GetInstance(IUnknown* self)
|
||||||
{
|
{
|
||||||
IDropTargetImpl* impl = (.)self;
|
IDropTargetImpl* impl = (.)self;
|
||||||
@@ -188,11 +317,51 @@ abstract class IDropTargetImplBase : RefCounted
|
|||||||
|
|
||||||
return .E_FAIL;
|
return .E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Import("shell32.dll"), CLink, CallingConvention(.Stdcall)]
|
||||||
|
public static extern uint32 DragQueryFileW(HDROP hDrop, uint32 iFile, char16* lpszFile, uint32 cch);
|
||||||
|
|
||||||
|
[Import("ole32.dll"), CLink, CallingConvention(.Stdcall)]
|
||||||
|
public static extern void ReleaseStgMedium(ref STGMEDIUM param0);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall)]
|
[CallingConvention(.Stdcall)]
|
||||||
private static HResult DropImpl(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect)
|
private static HResult DropImpl(IDropTarget* self, IDataObject* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect)
|
||||||
{
|
{
|
||||||
Self instance = GetInstance(self);
|
Self instance = GetInstance(self);
|
||||||
|
|
||||||
|
// render the data into stgm using the data description in fmte
|
||||||
|
FORMATETC format = .()
|
||||||
|
{
|
||||||
|
cfFormat = (.)CLIPBOARD_FORMATS.HDROP,
|
||||||
|
ptd = null,
|
||||||
|
lindex = -1,
|
||||||
|
tymed = (.)TYMED.HGLOBAL
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dataObject.GetData(ref format, var stgm).Succeeded)
|
||||||
|
{
|
||||||
|
HDROP hdrop = (HDROP)stgm.hGlobal;
|
||||||
|
uint32 fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, null, 0);
|
||||||
|
|
||||||
|
List<char16> buffer = scope List<char16>();
|
||||||
|
buffer.Resize(256);
|
||||||
|
|
||||||
|
for (uint32 i < fileCount)
|
||||||
|
{
|
||||||
|
uint32 requiredSize = DragQueryFileW(hdrop, i, null, 0);
|
||||||
|
buffer.Resize(requiredSize + 1);
|
||||||
|
|
||||||
|
uint32 retrievedSize = DragQueryFileW(hdrop, i, buffer.Ptr, (.)buffer.Count);
|
||||||
|
if (retrievedSize > 0 && retrievedSize < buffer.Count)
|
||||||
|
{
|
||||||
|
String str = scope String(buffer.Ptr);
|
||||||
|
Log.EngineLogger.Info($"Dropped File: {str}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseStgMedium(ref stgm);
|
||||||
|
}
|
||||||
|
|
||||||
Result<DropEffect> result = instance.OnDrop(point);
|
Result<DropEffect> result = instance.OnDrop(point);
|
||||||
|
|
||||||
if (result case .Ok(out effect))
|
if (result case .Ok(out effect))
|
||||||
|
|||||||
Reference in New Issue
Block a user