mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Basic drag & drop
This commit is contained in:
@@ -5,6 +5,8 @@ using GlitchyEditor.Assets;
|
|||||||
using GlitchyEditor.Assets.Importers;
|
using GlitchyEditor.Assets.Importers;
|
||||||
using GlitchyEditor.Assets.Processors;
|
using GlitchyEditor.Assets.Processors;
|
||||||
using GlitchyEditor.Assets.Exporters;
|
using GlitchyEditor.Assets.Exporters;
|
||||||
|
using DirectX.Common;
|
||||||
|
using GlitchyEditor.Platform.Windows;
|
||||||
|
|
||||||
namespace GlitchyEditor
|
namespace GlitchyEditor
|
||||||
{
|
{
|
||||||
@@ -17,7 +19,17 @@ namespace GlitchyEditor
|
|||||||
Log.ClientLogger = new EditorLogger();
|
Log.ClientLogger = new EditorLogger();
|
||||||
Log.EngineLogger = new EditorLogger() { IsEngineLogger = true };
|
Log.EngineLogger = new EditorLogger() { IsEngineLogger = true };
|
||||||
|
|
||||||
|
// TODO: Windows only
|
||||||
|
HResult result = OleInitialize(null);
|
||||||
|
Log.EngineLogger.Assert(result case .S_OK);
|
||||||
|
|
||||||
PushLayer(new EditorLayer(args, _contentManager));
|
PushLayer(new EditorLayer(args, _contentManager));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
OleUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IContentManager InitContentManager()
|
protected override IContentManager InitContentManager()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using System.IO;
|
|||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
using GlitchyEditor.Assets;
|
using GlitchyEditor.Assets;
|
||||||
using GlitchyEngine.Scripting;
|
using GlitchyEngine.Scripting;
|
||||||
|
using GlitchyEditor.Platform.Windows;
|
||||||
|
|
||||||
namespace GlitchyEditor
|
namespace GlitchyEditor
|
||||||
{
|
{
|
||||||
@@ -115,13 +116,50 @@ namespace GlitchyEditor
|
|||||||
private bool _showImguiDemoWindow;
|
private bool _showImguiDemoWindow;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Registers a drag'n'drop target that will fire corresponding DragDropEvent using the engine's event system.
|
||||||
|
class GlobalDragDropTarget : IDropTargetImplBase
|
||||||
|
{
|
||||||
|
public override Result<DropEffect> OnDragEnter(int2 cursorPosition)
|
||||||
|
{
|
||||||
|
DragDropEvent event = scope DragDropEvent(.Enter, cursorPosition);
|
||||||
|
Application.Instance.OnEvent(event);
|
||||||
|
return event.OutDropEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<DropEffect> OnDragOver(int2 cursorPosition)
|
||||||
|
{
|
||||||
|
DragDropEvent event = scope DragDropEvent(.Over, cursorPosition);
|
||||||
|
Application.Instance.OnEvent(event);
|
||||||
|
return event.OutDropEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<void> OnDragLeave()
|
||||||
|
{
|
||||||
|
DragDropEvent event = scope DragDropEvent(.Over, .(-1, -1));
|
||||||
|
Application.Instance.OnEvent(event);
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<DropEffect> OnDrop(int2 cursorPosition)
|
||||||
|
{
|
||||||
|
DragDropEvent event = scope DragDropEvent(.Drop, cursorPosition);
|
||||||
|
Application.Instance.OnEvent(event);
|
||||||
|
return event.OutDropEffect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GlobalDragDropTarget _dragDropTarget ~ _?.ReleaseRef();
|
||||||
|
|
||||||
[AllowAppend]
|
[AllowAppend]
|
||||||
public this(String[] args, EditorContentManager contentManager) : base("Editor")
|
public this(String[] args, EditorContentManager contentManager) : base("Editor")
|
||||||
{
|
{
|
||||||
Application.Get().Window.IsVSync = true;
|
Application.Instance.Window.IsVSync = true;
|
||||||
|
|
||||||
ScriptEngine.ApplicationInfo.IsEditor = true;
|
ScriptEngine.ApplicationInfo.IsEditor = true;
|
||||||
|
|
||||||
|
_dragDropTarget = new .();
|
||||||
|
_dragDropTarget.Register();
|
||||||
|
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
|
|
||||||
InitGraphics();
|
InitGraphics();
|
||||||
@@ -676,6 +714,13 @@ namespace GlitchyEditor
|
|||||||
ImGui.TextUnformatted("Project Name:");
|
ImGui.TextUnformatted("Project Name:");
|
||||||
ImGui.InputText("##projectName", &projectNameBuffer, projectNameBuffer.Count - 1);
|
ImGui.InputText("##projectName", &projectNameBuffer, projectNameBuffer.Count - 1);
|
||||||
|
|
||||||
|
StringView projectName = StringView(&projectNameBuffer);
|
||||||
|
|
||||||
|
if (projectName.IsWhiteSpace)
|
||||||
|
{
|
||||||
|
ImGui.TextColored(.(1, 0, 0, 1), "Project Name required!");
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
||||||
ImGui.TextUnformatted("Directory:");
|
ImGui.TextUnformatted("Directory:");
|
||||||
@@ -693,7 +738,6 @@ namespace GlitchyEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView projectName = StringView(&projectNameBuffer);
|
|
||||||
StringView directory = StringView(&projectDirectoryBuffer);
|
StringView directory = StringView(&projectDirectoryBuffer);
|
||||||
|
|
||||||
String target = scope String();
|
String target = scope String();
|
||||||
@@ -703,9 +747,9 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
ImGui.Text($"The Project will be in:\n{target}");
|
ImGui.Text($"The Project will be in:\n{target}");
|
||||||
|
|
||||||
if (Directory.Exists(target))
|
if (Directory.Exists(target) && !Directory.IsEmpty(target))
|
||||||
{
|
{
|
||||||
ImGui.TextColored(.(1, 0, 0, 1), "The directory is not empty!");
|
ImGui.TextColored(.(1, 1, 0, 1), "The directory is not empty!");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
@@ -1521,6 +1565,7 @@ namespace GlitchyEditor
|
|||||||
dispatcher.Dispatch<WindowResizeEvent>(scope (e) => OnWindowResize(e));
|
dispatcher.Dispatch<WindowResizeEvent>(scope (e) => OnWindowResize(e));
|
||||||
dispatcher.Dispatch<KeyPressedEvent>(scope (e) => OnKeyPressed(e));
|
dispatcher.Dispatch<KeyPressedEvent>(scope (e) => OnKeyPressed(e));
|
||||||
dispatcher.Dispatch<MouseScrolledEvent>(scope (e) => OnMouseScrolled(e));
|
dispatcher.Dispatch<MouseScrolledEvent>(scope (e) => OnMouseScrolled(e));
|
||||||
|
dispatcher.Dispatch<DragDropEvent>(scope (e) => OnDragDrop(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool OnWindowResize(WindowResizeEvent e)
|
private bool OnWindowResize(WindowResizeEvent e)
|
||||||
@@ -1611,6 +1656,31 @@ namespace GlitchyEditor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _isDraggingFromOutside;
|
||||||
|
private bool _droppedFromOutside;
|
||||||
|
private DropEffect _effectWhenDropping = .None;
|
||||||
|
|
||||||
|
private bool OnDragDrop(DragDropEvent e)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Info($"D'n'D: {e.DragDropType} {e.CursorPosition.X} {e.CursorPosition.Y}");
|
||||||
|
|
||||||
|
switch (e.DragDropType)
|
||||||
|
{
|
||||||
|
case .Enter:
|
||||||
|
_isDraggingFromOutside = true;
|
||||||
|
_droppedFromOutside = false;
|
||||||
|
case .Over:
|
||||||
|
case .Leave:
|
||||||
|
_isDraggingFromOutside = false;
|
||||||
|
case .Drop:
|
||||||
|
_droppedFromOutside = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.OutDropEffect = _effectWhenDropping;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,274 @@
|
|||||||
|
using System;
|
||||||
|
using DirectX.Common;
|
||||||
|
using DirectX.Math;
|
||||||
|
using GlitchyEngine;
|
||||||
|
using GlitchyEngine.Events;
|
||||||
|
using static System.Windows;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
|
namespace GlitchyEditor.Platform.Windows;
|
||||||
|
|
||||||
|
// This entire thing is so platform dependent, that it really doesn't make sense to abstract while we are windows only.
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
[Import("Ole32.lib"), CLink]
|
||||||
|
public static extern HResult OleInitialize(void* reserved);
|
||||||
|
[Import("Ole32.lib"), CLink]
|
||||||
|
public static extern void OleUninitialize();
|
||||||
|
[Import("Ole32.lib"), CLink]
|
||||||
|
public static extern HResult RegisterDragDrop(HWnd windowHandle, IDropTarget* dropTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CRepr]
|
||||||
|
struct IDropTarget : IUnknown
|
||||||
|
{
|
||||||
|
public static new Guid IID => .("00000122-0000-0000-C000-000000000046");
|
||||||
|
|
||||||
|
[CRepr]
|
||||||
|
public struct VTable : IUnknown.VTable
|
||||||
|
{
|
||||||
|
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) DragLeave;
|
||||||
|
public function [CallingConvention(.Stdcall)] HResult(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) Drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new VTable* VT => (VTable*)mVT;
|
||||||
|
|
||||||
|
public HResult DragEnter(/*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) mut
|
||||||
|
{
|
||||||
|
return VT.DragEnter(&this, dataObject, grfKeyState, point, ref effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HResult DragOver(uint32 grfKeyState, int2 point, ref DropEffect effect) mut
|
||||||
|
{
|
||||||
|
return VT.DragOver(&this, grfKeyState, point, ref effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HResult DragLeave() mut
|
||||||
|
{
|
||||||
|
return VT.DragLeave(&this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HResult Drop(/*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect) mut
|
||||||
|
{
|
||||||
|
return VT.Drop(&this, dataObject, grfKeyState, point, ref effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CRepr]
|
||||||
|
enum DropEffect
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Copy = 1,
|
||||||
|
Move = 2,
|
||||||
|
Link = 4,
|
||||||
|
Scroll = 0x80000000,
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class IDropTargetImplBase : RefCounted
|
||||||
|
{
|
||||||
|
[CRepr]
|
||||||
|
private struct IDropTargetImpl : IDropTarget
|
||||||
|
{
|
||||||
|
public void* ClassPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDropTargetImpl impl;
|
||||||
|
|
||||||
|
IDropTarget.VTable vTable;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
impl = .();
|
||||||
|
impl.[Friend]mVT = &vTable;
|
||||||
|
impl.ClassPtr = Internal.UnsafeCastToPtr(this);
|
||||||
|
|
||||||
|
vTable.QueryInterface = => QueryInterfaceImpl;
|
||||||
|
vTable.AddRef = => AddRefImpl;
|
||||||
|
vTable.Release = => ReleaseImpl;
|
||||||
|
|
||||||
|
vTable.DragEnter = => DragEnterImpl;
|
||||||
|
vTable.DragOver = => DragOverImpl;
|
||||||
|
vTable.DragLeave = => DragLeaveImpl;
|
||||||
|
vTable.Drop = => DropImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Register()
|
||||||
|
{
|
||||||
|
HResult result = RegisterDragDrop(Application.Instance.Window.[Friend]_windowHandle, &impl);
|
||||||
|
Log.EngineLogger.Assert(result not case .E_OUTOFMEMORY, "Failed to register drag drop handler (E_OUTOFMEMORY). Make sure you called OleInitialize and not CoInitialize[Ex]");
|
||||||
|
Log.EngineLogger.Assert(result case .S_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IDropTargetImplBase GetInstance(IUnknown* self)
|
||||||
|
{
|
||||||
|
IDropTargetImpl* impl = (.)self;
|
||||||
|
|
||||||
|
return (.)Internal.UnsafeCastToObject(impl.ClassPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HResult QueryInterfaceImpl(IUnknown* self, ref Guid riid, void** output)
|
||||||
|
{
|
||||||
|
Self instance = GetInstance(self);
|
||||||
|
|
||||||
|
HResult result = .E_NOINTERFACE;
|
||||||
|
*output = null;
|
||||||
|
|
||||||
|
if (riid == IUnknown.IID || riid == IDropTarget.IID)
|
||||||
|
{
|
||||||
|
*output = (IUnknown*)&instance.impl;
|
||||||
|
instance.AddRef();
|
||||||
|
result = .S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint32 AddRefImpl(IUnknown* self)
|
||||||
|
{
|
||||||
|
Self instance = GetInstance(self);
|
||||||
|
|
||||||
|
instance.AddRef();
|
||||||
|
return (uint32)instance.RefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint32 ReleaseImpl(IUnknown* self)
|
||||||
|
{
|
||||||
|
Self instance = GetInstance(self);
|
||||||
|
|
||||||
|
uint32 count = (uint32)instance.ReleaseRefNoDelete();
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
delete instance;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Data object? KeyState?
|
||||||
|
public abstract Result<DropEffect> OnDragEnter(int2 cursorPosition);
|
||||||
|
public abstract Result<DropEffect> OnDragOver(int2 cursorPosition);
|
||||||
|
public abstract Result<void> OnDragLeave();
|
||||||
|
public abstract Result<DropEffect> OnDrop(int2 cursorPosition);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall)]
|
||||||
|
private static HResult DragEnterImpl(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect)
|
||||||
|
{
|
||||||
|
Self instance = GetInstance(self);
|
||||||
|
|
||||||
|
Result<DropEffect> result = instance.OnDragEnter(point);
|
||||||
|
|
||||||
|
if (result case .Ok(out effect))
|
||||||
|
return .S_OK;
|
||||||
|
|
||||||
|
return .E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall)]
|
||||||
|
private static HResult DragOverImpl(IDropTarget* self, uint32 grfKeyState, int2 point, ref DropEffect effect)
|
||||||
|
{
|
||||||
|
Self instance = GetInstance(self);
|
||||||
|
Result<DropEffect> result = instance.OnDragOver(point);
|
||||||
|
|
||||||
|
if (result case .Ok(out effect))
|
||||||
|
return .S_OK;
|
||||||
|
|
||||||
|
return .E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall)]
|
||||||
|
private static HResult DragLeaveImpl(IDropTarget* self)
|
||||||
|
{
|
||||||
|
Self instance = GetInstance(self);
|
||||||
|
Result<void> result = instance.OnDragLeave();
|
||||||
|
|
||||||
|
if (result case .Ok)
|
||||||
|
return .S_OK;
|
||||||
|
|
||||||
|
return .E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall)]
|
||||||
|
private static HResult DropImpl(IDropTarget* self, /*IDataObject*/ IUnknown* dataObject, uint32 grfKeyState, int2 point, ref DropEffect effect)
|
||||||
|
{
|
||||||
|
Self instance = GetInstance(self);
|
||||||
|
Result<DropEffect> result = instance.OnDrop(point);
|
||||||
|
|
||||||
|
if (result case .Ok(out effect))
|
||||||
|
return .S_OK;
|
||||||
|
|
||||||
|
return .E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
Enter,
|
||||||
|
Over,
|
||||||
|
Leave,
|
||||||
|
Drop
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DragDropEvent : Event, IEvent
|
||||||
|
{
|
||||||
|
public override EventType EventType => .DragDropEvent;
|
||||||
|
|
||||||
|
public override StringView Name => "DragDropEvent";
|
||||||
|
|
||||||
|
public override EventCategory Category => .Application;
|
||||||
|
|
||||||
|
public static EventType StaticType => .DragDropEvent;
|
||||||
|
|
||||||
|
public DragDropType DragDropType { get; private set; }
|
||||||
|
public int2 CursorPosition { get; private set; }
|
||||||
|
|
||||||
|
public DropEffect OutDropEffect { get; set; }
|
||||||
|
|
||||||
|
// TODO: Keys, or perhaps just make the listeners query them...
|
||||||
|
|
||||||
|
public this(DragDropType dragDropType, int2 cursorPosition)
|
||||||
|
{
|
||||||
|
DragDropType = dragDropType;
|
||||||
|
CursorPosition = cursorPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Events
|
||||||
|
{
|
||||||
|
public extension EventType
|
||||||
|
{
|
||||||
|
case DragDropEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+1
-1
Submodule GlitchyEngine/vendor/directx updated: a973c396ea...65f5bbbf01
Reference in New Issue
Block a user