diff --git a/BeefLibs/Beefy2D/src/BFWindow.bf b/BeefLibs/Beefy2D/src/BFWindow.bf index bfaf0339..42cd4de1 100644 --- a/BeefLibs/Beefy2D/src/BFWindow.bf +++ b/BeefLibs/Beefy2D/src/BFWindow.bf @@ -48,6 +48,7 @@ namespace Beefy ShowMinimized = 0x0200'0000, ShowMaximized = 0x0400'0000, AllowFullscreen = 0x0800'0000, + AcceptFiles = 0x1000'0000 }; [AllowDuplicates] @@ -127,7 +128,8 @@ namespace Beefy delegate void NativeMouseUpDelegate(void* window, int32 x, int32 y, int32 btn); delegate void NativeMouseWheelDelegate(void* window, int32 x, int32 y, float deltaX, float deltaY); delegate void NativeMouseLeaveDelegate(void* window); - delegate void NativeMenuItemSelectedDelegate(void* window, void* menu); + delegate void NativeMenuItemSelectedDelegate(void* window, void* menu); + delegate void NativeDragDropFileDelegate(void* window, char8* filePath); public void* mNativeWindow; public bool mNativeWindowClosed; @@ -178,6 +180,7 @@ namespace Beefy static NativeMouseWheelDelegate sNativeMouseWheelDelegate ~ delete _; static NativeMouseLeaveDelegate sNativeMouseLeaveDelegate ~ delete _; static NativeMenuItemSelectedDelegate sNativeMenuItemSelectedDelegate ~ delete _; + static NativeDragDropFileDelegate sNativeDragDropFileDelegate ~ delete _; [CallingConvention(.Stdcall), CLink] static extern void* BFApp_CreateWindow(void* parent, char8* title, int32 x, int32 y, int32 width, int32 height, int32 windowFlags); @@ -190,7 +193,7 @@ namespace Beefy void* gotFocusDelegate, void* lostFocusDelegate, void* keyCharDelegate, void* keyDownDelegate, void* keyUpDelegate, void* hitTestDelegate, void* mouseMoveDelegate, void* mouseProxyMoveDelegate, void* mouseDownDelegate, void* mouseUpDelegate, void* mouseWheelDelegate, void* mouseLeaveDelegate, - void* menuItemSelectedDelegate); + void* menuItemSelectedDelegate, void* dragDropFileDelegate); [CallingConvention(.Stdcall), CLink] static extern void BFWindow_SetTitle(void* window, char8* title); @@ -299,6 +302,7 @@ namespace Beefy static void Static_NativeMouseWheelDelegate(void* window, int32 mouseX, int32 mouseY, float deltaX, float deltaY) { GetBFWindow(window).MouseWheel(mouseX, mouseY, deltaX, deltaY); } static void Static_NativeMouseLeaveDelegate(void* window) { GetBFWindow(window).MouseLeave(); } static void Static_NativeMenuItemSelectedDelegate(void* window, void* item) { GetBFWindow(window).NativeMenuItemSelected(item); } + static void Static_NativeDragDropFileDelegate(void* window, char8* filePath) { GetBFWindow(window).DragDropFile(StringView(filePath)); } #endif public this() @@ -351,12 +355,13 @@ namespace Beefy sNativeMouseWheelDelegate = new => Static_NativeMouseWheelDelegate; sNativeMouseLeaveDelegate = new => Static_NativeMouseLeaveDelegate; sNativeMenuItemSelectedDelegate = new => Static_NativeMenuItemSelectedDelegate; + sNativeDragDropFileDelegate = new => Static_NativeDragDropFileDelegate; } BFWindow_SetCallbacks(mNativeWindow, sNativeMovedDelegate.GetFuncPtr(), sNativeCloseQueryDelegate.GetFuncPtr(), sNativeClosedDelegate.GetFuncPtr(), sNativeGotFocusDelegate.GetFuncPtr(), sNativeLostFocusDelegate.GetFuncPtr(), sNativeKeyCharDelegate.GetFuncPtr(), sNativeKeyDownDelegate.GetFuncPtr(), sNativeKeyUpDelegate.GetFuncPtr(), sNativeHitTestDelegate.GetFuncPtr(), sNativeMouseMoveDelegate.GetFuncPtr(), sNativeMouseProxyMoveDelegate.GetFuncPtr(), sNativeMouseDownDelegate.GetFuncPtr(), sNativeMouseUpDelegate.GetFuncPtr(), sNativeMouseWheelDelegate.GetFuncPtr(), sNativeMouseLeaveDelegate.GetFuncPtr(), - sNativeMenuItemSelectedDelegate.GetFuncPtr()); + sNativeMenuItemSelectedDelegate.GetFuncPtr(), sNativeDragDropFileDelegate.GetFuncPtr()); BFApp.sApp.mWindows.Add(this); mDefaultDrawLayer = new DrawLayer(this); @@ -575,6 +580,10 @@ namespace Beefy MenuItemSelected(aSysMenu); } + public virtual void DragDropFile(StringView filePath) + { + } + public virtual SysBitmap LoadSysBitmap(String path) { return null; diff --git a/BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf b/BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf index 9aa86a93..f800a16e 100644 --- a/BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf +++ b/BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf @@ -17,6 +17,7 @@ namespace Beefy.widgets public delegate void MouseWheelHandler(MouseEvent mouseEvent); public delegate void KeyDownHandler(KeyDownEvent keyboardEvent); //public delegate void CloseTemporaryHandler(WidgetWindow window); + public delegate void DragDropFileHandler(StringView filePath); public class WidgetWindow : BFWindow { @@ -31,6 +32,7 @@ namespace Beefy.widgets public Event mOnMenuItemSelected ~ _.Dispose(); public Event mOnWindowKeyDown ~ _.Dispose(); public Event mOnHitTest ~ _.Dispose(); + public Event mOnDragDropFile ~ _.Dispose(); public static Event sOnMouseLeftWindow ~ _.Dispose(); public static Event sOnWindowLostFocus ~ _.Dispose(); @@ -811,6 +813,12 @@ namespace Beefy.widgets sOnMenuItemSelected(sysMenu); base.MenuItemSelected(sysMenu); } + + public override void DragDropFile(StringView filePath) + { + mOnDragDropFile(filePath); + base.DragDropFile(filePath); + } public void TransferMouse(WidgetWindow newMouseWindow) { diff --git a/BeefySysLib/BFWindow.cpp b/BeefySysLib/BFWindow.cpp index e892a418..582d9118 100644 --- a/BeefySysLib/BFWindow.cpp +++ b/BeefySysLib/BFWindow.cpp @@ -153,7 +153,8 @@ BFWindow::BFWindow() mMouseUpFunc = NULL; mMouseWheelFunc = NULL; mMouseLeaveFunc = NULL; - mMenuItemSelectedFunc = NULL; + mMenuItemSelectedFunc = NULL; + mDragDropFileFunc = NULL; mHitTestFunc = NULL; mFlags = 0; diff --git a/BeefySysLib/BFWindow.h b/BeefySysLib/BFWindow.h index 602e4cfe..b1b2a1e2 100644 --- a/BeefySysLib/BFWindow.h +++ b/BeefySysLib/BFWindow.h @@ -23,6 +23,7 @@ typedef void (*BFWindow_MouseUp)(BFWindow* window, int x, int y, int btn); typedef void (*BFWindow_MouseWheel)(BFWindow* window, int x, int y, float deltaX, float deltaY); typedef void (*BFWindow_MouseLeave)(BFWindow* window); typedef void (*BFWindow_MenuItemSelectedFunc)(BFWindow* window, BFMenu* menu); +typedef void (*BFWindow_DragDropFileFunc)(BFWindow* window, const char* filePath); enum { @@ -53,7 +54,8 @@ enum BFWINDOW_FAKEFOCUS = 0x1000000, BFWINDOW_SHOWMINIMIZED = 0x2000000, BFWINDOW_SHOWMAXIMIZED = 0x4000000, - BFWINDOW_ALLOW_FULLSCREEN = 0x8000000 + BFWINDOW_ALLOW_FULLSCREEN = 0x8000000, + BFWINDOW_ACCEPTFILES = 0x10000000 }; @@ -103,7 +105,7 @@ public: uint32 mMouseDownTicks[MOUSEBUTTON_MAX]; BFMenu* mMenu; - RenderWindow* mRenderWindow; + RenderWindow* mRenderWindow; bool mNonExclusiveMouseCapture; BFWindow_MovedFunc mMovedFunc; BFWindow_CloseQueryFunc mCloseQueryFunc; @@ -120,7 +122,8 @@ public: BFWindow_MouseUp mMouseUpFunc; BFWindow_MouseWheel mMouseWheelFunc; BFWindow_MouseLeave mMouseLeaveFunc; - BFWindow_MenuItemSelectedFunc mMenuItemSelectedFunc; + BFWindow_MenuItemSelectedFunc mMenuItemSelectedFunc; + BFWindow_DragDropFileFunc mDragDropFileFunc; public: BFWindow(); diff --git a/BeefySysLib/BeefySysLib.cpp b/BeefySysLib/BeefySysLib.cpp index d75ef692..6abda980 100644 --- a/BeefySysLib/BeefySysLib.cpp +++ b/BeefySysLib/BeefySysLib.cpp @@ -283,7 +283,7 @@ BF_EXPORT void BF_CALLTYPE BFWindow_SetCallbacks(BFWindow* window, BFWindow_Move BFWindow_KeyCharFunc keyCharFunc, BFWindow_KeyDownFunc keyDownFunc, BFWindow_KeyUpFunc keyUpFunc, BFWindow_HitTestFunc hitTestFunc, BFWindow_MouseMove mouseMoveFunc, BFWindow_MouseProxyMove mouseProxyMoveFunc, BFWindow_MouseDown mouseDownFunc, BFWindow_MouseUp mouseUpFunc, BFWindow_MouseWheel mouseWheelFunc, BFWindow_MouseLeave mouseLeaveFunc, - BFWindow_MenuItemSelectedFunc menuItemSelectedFunc) + BFWindow_MenuItemSelectedFunc menuItemSelectedFunc, BFWindow_DragDropFileFunc dragDropFileFunc) { window->mMovedFunc = movedFunc; window->mCloseQueryFunc = closeQueryFunc; @@ -300,7 +300,8 @@ BF_EXPORT void BF_CALLTYPE BFWindow_SetCallbacks(BFWindow* window, BFWindow_Move window->mMouseUpFunc = mouseUpFunc; window->mMouseWheelFunc = mouseWheelFunc; window->mMouseLeaveFunc = mouseLeaveFunc; - window->mMenuItemSelectedFunc = menuItemSelectedFunc; + window->mMenuItemSelectedFunc = menuItemSelectedFunc; + window->mDragDropFileFunc = dragDropFileFunc; } BF_EXPORT void* BFWindow_GetNativeUnderlying(BFWindow* window) diff --git a/BeefySysLib/platform/win/WinBFApp.cpp b/BeefySysLib/platform/win/WinBFApp.cpp index fb7e3c99..4e1574f1 100644 --- a/BeefySysLib/platform/win/WinBFApp.cpp +++ b/BeefySysLib/platform/win/WinBFApp.cpp @@ -162,7 +162,10 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y if (windowFlags & BFWINDOW_MAXIMIZE) aWindowFlags |= WS_MAXIMIZEBOX; if ((windowFlags & BFWINDOW_TOPMOST) && (parent == NULL)) - windowFlagsEx |= WS_EX_TOPMOST; + windowFlagsEx |= WS_EX_TOPMOST; + if ((windowFlags & BFWINDOW_ACCEPTFILES)) + windowFlagsEx |= WS_EX_ACCEPTFILES; + if (windowFlags & BFWINDOW_CLIENT_SIZED) { RECT rect = {0, 0, width, height}; @@ -1123,6 +1126,18 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar case WM_INPUTLANGCHANGE: mKeyLayoutHasAltGr = (KeyboardLayoutHasAltGr((HKL)lParam) == TRUE); break; + + case WM_DROPFILES: + { + HDROP hDropInfo = (HDROP)wParam; + char sItem[MAX_PATH]; + + for(int i = 0; DragQueryFileA(hDropInfo, i, (LPSTR)sItem, sizeof(sItem)); i++) + mDragDropFileFunc(this, sItem); + + DragFinish(hDropInfo); + } + break; } app->mInMsgProc = false; diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index ba7e9e55..43a5a317 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -846,6 +846,17 @@ namespace IDE public void DoOpenFile() { #if !CLI + if (mDeferredOpenFileName != null) + { + for (let filePath in mDeferredOpenFileName.Split('|')) + { + AddRecentFile(.OpenedFile, filePath); + ShowSourceFile(scope String()..Reference(filePath)); + } + DeleteAndNullify!(mDeferredOpenFileName); + return; + } + String fullDir = scope .(); let sourceViewPanel = GetActiveSourceViewPanel(); if (sourceViewPanel != null) @@ -7093,6 +7104,11 @@ namespace IDE public override void UnhandledCommandLine(String key, String value) { + if (File.Exists(key)) + { + DragDropFile(key); + return; + } Fail(StackStringFormat!("Unhandled command line param: {0}", key)); } @@ -7238,13 +7254,7 @@ namespace IDE else mWorkspace.mDir = fullDir; case "-file": - String.NewOrSet!(mDeferredOpenFileName, value); - if (mDeferredOpenFileName.EndsWith(".bfdbg", .OrdinalIgnoreCase)) - mDeferredOpen = .DebugSession; - else if (mDeferredOpenFileName.EndsWith(".dmp", .OrdinalIgnoreCase)) - mDeferredOpen = .CrashDump; - else - mDeferredOpen = .File; + DragDropFile(value); default: return false; } @@ -7252,6 +7262,34 @@ namespace IDE } } + public void DragDropFile(StringView filePath) + { + let prevDeferredOpen = mDeferredOpen; + + if (filePath.EndsWith(".bfdbg", .OrdinalIgnoreCase)) + mDeferredOpen = .DebugSession; + else if (filePath.EndsWith(".dmp", .OrdinalIgnoreCase)) + mDeferredOpen = .CrashDump; + else + mDeferredOpen = .File; + + if (prevDeferredOpen == .File && mDeferredOpen == .File) + { + if (String.IsNullOrEmpty(mDeferredOpenFileName)) + String.NewOrSet!(mDeferredOpenFileName, filePath); + else + mDeferredOpenFileName.AppendF("|{}", filePath); + } + else if (prevDeferredOpen != .None && prevDeferredOpen != .File && mDeferredOpen == .File) + { + // Do nothing + } + else + { + String.NewOrSet!(mDeferredOpenFileName, filePath); + } + } + class Board : Widget { public override void Draw(Graphics g) @@ -11498,7 +11536,7 @@ namespace IDE // { BFWindow.Flags flags = .Border | .ThickFrame | .Resizable | .SysMenu | - .Caption | .Minimize | .Maximize | .QuitOnClose | .Menu | .PopupPosition; + .Caption | .Minimize | .Maximize | .QuitOnClose | .Menu | .PopupPosition | .AcceptFiles; if (mRunningTestScript) flags |= .NoActivate; @@ -11528,6 +11566,7 @@ namespace IDE mMainWindow.mOnMouseUp.Add(new => MouseUp); mMainWindow.mOnWindowKeyDown.Add(new => SysKeyDown); mMainWindow.mOnWindowCloseQuery.Add(new => AllowClose); + mMainWindow.mOnDragDropFile.Add(new => DragDropFile); CreateMenu(); UpdateRecentDisplayedFilesMenuItems(); if (mRecentlyDisplayedFiles.Count > 0)