summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2024-03-12 21:45:35 +0100
committerAldrik Ramaekers <aldrikboy@gmail.com>2024-03-12 21:45:35 +0100
commite72c327a84d1937c05cc14a5e2ab232584e2cb9d (patch)
tree96d58fa0f0065c577bcc87bc094498d2348b3ca3
parente4d2929604792b135cbf8dad22179a5dec60e365 (diff)
dragdrop file work
-rw-r--r--src/main.cpp20
-rw-r--r--src/platform.h10
-rw-r--r--src/windows/DropManager.h106
-rw-r--r--src/windows/main_windows.cpp10
4 files changed, 145 insertions, 1 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 4520d9c..4365f2a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -500,7 +500,25 @@ void ts_create_gui(int window_w, int window_h) {
}
pos_y += textbox_area_height + 7;
- if (current_search_result)
+ if (dragdrop_data.did_drop) {
+ printf("Do loading..\n");
+ dragdrop_data.did_drop = false;
+ }
+
+ if (dragdrop_data.is_dragging_file)
+ {
+ if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceExtern)) // we use an external source (i.e. not ImGui-created)
+ {
+ ImGui::SetDragDropPayload("FILES", nullptr, 0);
+ ImGui::BeginTooltip();
+ ImGui::Text("Drop to load file");
+ ImGui::EndTooltip();
+ ImGui::EndDragDropSource();
+ }
+
+ ImGui::Text("Drag test");
+ }
+ else if (current_search_result)
{ // Results
ImGui::SetNextWindowPos({5, pos_y});
diff --git a/src/platform.h b/src/platform.h
index 3f41e4f..5926aeb 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -4,6 +4,7 @@
#include "array.h"
#include "memory_bucket.h"
#include "search.h"
+#include "config.h"
#include "../utf8.h"
typedef struct t_ts_file_content
@@ -29,7 +30,16 @@ typedef enum t_ts_file_open_error
FILE_ERROR_TOO_BIG = 11,
} ts_file_open_error;
+typedef struct t_ts_dragdrop_data
+{
+ bool did_drop;
+ utf8_int8_t path[MAX_INPUT_LENGTH];
+ bool is_dragging_file;
+} ts_dragdrop_data;
+
+
extern bool program_running;
+extern ts_dragdrop_data dragdrop_data;
bool ts_platform_dir_exists(utf8_int8_t* dir);
ts_file_content ts_platform_read_file(char *path, const char *mode);
diff --git a/src/windows/DropManager.h b/src/windows/DropManager.h
new file mode 100644
index 0000000..32b6922
--- /dev/null
+++ b/src/windows/DropManager.h
@@ -0,0 +1,106 @@
+#pragma once
+
+#include "platform.h"
+
+#include <oleidl.h>
+
+// create a class inheriting from IDropTarget
+class DropManager : public IDropTarget
+{
+public:
+ //--- implement the IUnknown parts
+ // you could do this the proper way with InterlockedIncrement etc,
+ // but I've left out stuff that's not exactly necessary for brevity
+ ULONG AddRef() { return 1; }
+ ULONG Release() { return 0; }
+
+ // we handle drop targets, let others know
+ HRESULT QueryInterface(REFIID riid, void **ppvObject)
+ {
+ if (riid == IID_IDropTarget)
+ {
+ *ppvObject = this; // or static_cast<IUnknown*> if preferred
+ // AddRef() if doing things properly
+ // but then you should probably handle IID_IUnknown as well;
+ return S_OK;
+ }
+
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ };
+
+
+ //--- implement the IDropTarget parts
+
+ // occurs when we drag files into our applications view
+ HRESULT DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
+ {
+ // TODO: check whether we can handle this type of object at all and set *pdwEffect &= DROPEFFECT_NONE if not;
+
+ // do something useful to flag to our application that files have been dragged from the OS into our application
+ //...
+ dragdrop_data.is_dragging_file = true;
+
+ // trigger MouseDown for button 1 within ImGui
+ //...
+
+ *pdwEffect &= DROPEFFECT_COPY;
+ return S_OK;
+ }
+
+ // occurs when we drag files out from our applications view
+ HRESULT DragLeave() {
+ dragdrop_data.is_dragging_file = false;
+ return S_OK;
+ }
+
+ // occurs when we drag the mouse over our applications view whilst carrying files (post Enter, pre Leave)
+ HRESULT DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
+ {
+ // trigger MouseMove within ImGui, position is within pt.x and pt.y
+ // grfKeyState contains flags for control, alt, shift etc
+ //...
+
+ *pdwEffect &= DROPEFFECT_COPY;
+ return S_OK;
+ }
+
+ // occurs when we release the mouse button to finish the drag-drop operation
+ HRESULT Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
+ {
+ dragdrop_data.is_dragging_file = false;
+ // grfKeyState contains flags for control, alt, shift etc
+
+ // render the data into stgm using the data description in fmte
+ FORMATETC fmte = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM stgm;
+
+ if (SUCCEEDED(pDataObj->GetData(&fmte, &stgm)))
+ {
+ HDROP hdrop = (HDROP)stgm.hGlobal; // or reinterpret_cast<HDROP> if preferred
+ UINT file_count = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
+
+ // We only accept 1 file for now..
+ for (UINT i = 0; i < 1; i++)
+ {
+ TCHAR szFile[MAX_PATH];
+ UINT cch = DragQueryFile(hdrop, i, szFile, MAX_PATH);
+ if (cch > 0 && cch < MAX_PATH)
+ {
+ WideCharToMultiByte(CP_UTF8,0,szFile,-1,(LPSTR)dragdrop_data.path, MAX_INPUT_LENGTH, NULL, NULL);
+ }
+ }
+
+ // we have to release the data when we're done with it
+ ReleaseStgMedium(&stgm);
+
+ dragdrop_data.did_drop = true;
+ }
+
+ // trigger MouseUp for button 1 within ImGui
+ //...
+
+ *pdwEffect &= DROPEFFECT_COPY;
+ return S_OK;
+ }
+}; \ No newline at end of file
diff --git a/src/windows/main_windows.cpp b/src/windows/main_windows.cpp
index fa55d9c..00a8bc2 100644
--- a/src/windows/main_windows.cpp
+++ b/src/windows/main_windows.cpp
@@ -19,6 +19,7 @@
#include <Shlobj.h>
#include <GL/GL.h>
#include <tchar.h>
+#include "DropManager.h"
#ifdef TS_RELEASE
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
@@ -27,6 +28,7 @@
#define IDI_LOGO 123
char config_path[MAX_INPUT_LENGTH];
+ts_dragdrop_data dragdrop_data = {0};
void ts_create_gui(int window_w, int window_h);
void ts_load_images();
@@ -108,7 +110,9 @@ void ts_platform_set_window_title(utf8_int8_t* str) {
int main(int, char**)
{
+ OleInitialize(NULL);
CoInitializeEx(0, COINIT_MULTITHREADED|COINIT_DISABLE_OLE1DDE);
+
ts_init();
// Create application window
@@ -157,6 +161,9 @@ int main(int, char**)
ts_load_images();
ts_load_config();
+ DropManager dm;
+ RegisterDragDrop(hwnd, &dm);
+
while (program_running)
{
MSG msg;
@@ -177,11 +184,14 @@ int main(int, char**)
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
+ RevokeDragDrop(hwnd);
+
CleanupDeviceWGL(hwnd, &g_MainWindow);
wglDeleteContext(g_hRC);
::DestroyWindow(hwnd);
::UnregisterClassW(wc.lpszClassName, wc.hInstance);
+ OleUninitialize();
CoUninitialize();
return 0;