implement table dnd drop newapi

Thu, 01 Feb 2024 19:45:17 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 01 Feb 2024 19:45:17 +0100
branch
newapi
changeset 243
9f66c31a27ed
parent 242
4ff7361dce95
child 244
33c0a3797a0d

implement table dnd drop

ui/common/types.c file | annotate | diff | comparison | revisions
ui/ui/dnd.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
ui/ui/window.h file | annotate | diff | comparison | revisions
ui/winui/dnd.cpp file | annotate | diff | comparison | revisions
ui/winui/dnd.h file | annotate | diff | comparison | revisions
ui/winui/table.cpp file | annotate | diff | comparison | revisions
--- a/ui/common/types.c	Wed Jan 31 19:15:41 2024 +0100
+++ b/ui/common/types.c	Thu Feb 01 19:45:17 2024 +0100
@@ -466,3 +466,19 @@
 UiStr ui_str_free(char *str, void (*freefunc)(void *v)) {
     return (UiStr) { str, freefunc };
 }
+
+
+UiFileList ui_filelist_copy(UiFileList list) {
+    char **newlist = calloc(sizeof(char*), list.nfiles);
+    for (int i = 0; i < list.nfiles; i++) {
+        newlist[i] = strdup(list.files[i]);
+    }
+    return (UiFileList) { newlist, list.nfiles };
+}
+
+void ui_filelist_free(UiFileList list) {
+    for (int i = 0; i < list.nfiles; i++) {
+        free(list.files[i]);
+    }
+    free(list.files);
+}
--- a/ui/ui/dnd.h	Wed Jan 31 19:15:41 2024 +0100
+++ b/ui/ui/dnd.h	Thu Feb 01 19:45:17 2024 +0100
@@ -41,7 +41,7 @@
 UIEXPORT void ui_selection_seturis(UiDnD *sel, char **uris, int nelm);
 
 UIEXPORT char* ui_selection_gettext(UiDnD *sel);
-UIEXPORT char** ui_selection_geturis(UiDnD *sel, size_t *nelm);
+UIEXPORT UiFileList ui_selection_geturis(UiDnD *sel);
 
 
 #ifdef __cplusplus
--- a/ui/ui/toolkit.h	Wed Jan 31 19:15:41 2024 +0100
+++ b/ui/ui/toolkit.h	Thu Feb 01 19:45:17 2024 +0100
@@ -155,6 +155,8 @@
 
 typedef struct UiStr        UiStr;
 
+typedef struct UiFileList   UiFileList;
+
 /* begin opaque types */
 typedef struct UiContext    UiContext;
 typedef struct UiContainer  UiContainer;
@@ -356,6 +358,11 @@
     UI_OFF
 };
 
+struct UiFileList {
+    char **files;
+    size_t nfiles;
+};
+
 
 UIEXPORT void ui_init(const char *appname, int argc, char **argv);
 UIEXPORT const char* ui_appname();
@@ -453,6 +460,9 @@
 UIEXPORT void  ui_list_addobsv(UiList *list, ui_callback f, void *data);
 UIEXPORT void  ui_list_notify(UiList *list);
 
+UiFileList ui_filelist_copy(UiFileList list);
+void ui_filelist_free(UiFileList list);
+
 UIEXPORT void ui_clipboard_set(char *str);
 UIEXPORT char* ui_clipboard_get();
 
--- a/ui/ui/window.h	Wed Jan 31 19:15:41 2024 +0100
+++ b/ui/ui/window.h	Thu Feb 01 19:45:17 2024 +0100
@@ -39,11 +39,6 @@
 #define UI_FILEDIALOG_SELECT_MULTI        1
 #define UI_FILEDIALOG_SELECT_FOLDER       2
 
-typedef struct UiFileList {
-    char **files;
-    size_t nfiles;
-} UiFileList;
-
 UIEXPORT UiObject* ui_window(const char *title, void *window_data);
 UIEXPORT UiObject* ui_simplewindow(char *title, void *window_data);
 
@@ -52,6 +47,8 @@
 UIEXPORT void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata);
 UIEXPORT void ui_savefiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata);
 
+
+
 #ifdef	__cplusplus
 }
 #endif
--- a/ui/winui/dnd.cpp	Wed Jan 31 19:15:41 2024 +0100
+++ b/ui/winui/dnd.cpp	Thu Feb 01 19:45:17 2024 +0100
@@ -31,6 +31,13 @@
 #include "dnd.h"
 #include "util.h"
 
+#include <thread>
+
+using namespace winrt;
+using namespace Windows::ApplicationModel::DataTransfer;
+using namespace Windows::Storage;
+using namespace Windows::Storage::Streams;
+
 UIEXPORT void ui_selection_settext(UiDnD* dnd, char* str, int len) {
 	if (dnd->data) {
 		if (len < 0) {
@@ -54,6 +61,31 @@
 	return nullptr;
 }
 
-UIEXPORT char** ui_selection_geturis(UiDnD* dnd, size_t* nelm) {
-	return nullptr;
+
+UIEXPORT UiFileList ui_selection_geturis(UiDnD *dnd) {
+	UiFileList flist;
+	flist.files = nullptr;
+	flist.nfiles = 0;
+
+    if (dnd->dataview.Contains(StandardDataFormats::StorageItems())) {
+		UiFileList *flist_ptr = &flist;
+
+		// we need to execute this in a different thread
+		// this could block the main gui thread, but shouldn't happen with a simple uri list
+		std::thread getDataThread([dnd, flist_ptr]() {
+				auto items = dnd->dataview.GetStorageItemsAsync().get();
+
+				char **uris = (char**)calloc(items.Size(), sizeof(char*));
+				flist_ptr->files = uris;
+				flist_ptr->nfiles = items.Size();
+
+				int i = 0;
+				for (IStorageItem const& item : items) {
+					winrt::hstring path = item.Path();
+					uris[i++] = wchar2utf8(path.c_str(), path.size());
+				}
+			});
+		getDataThread.join();
+    }
+	return flist;
 }
--- a/ui/winui/dnd.h	Wed Jan 31 19:15:41 2024 +0100
+++ b/ui/winui/dnd.h	Thu Feb 01 19:45:17 2024 +0100
@@ -36,4 +36,5 @@
 	winrt::Microsoft::UI::Xaml::DropCompletedEventArgs dndcompletedargs = { nullptr };
 	winrt::Microsoft::UI::Xaml::DragEventArgs drageventargs = { nullptr };
 	winrt::Windows::ApplicationModel::DataTransfer::DataPackage data = { nullptr };
+	winrt::Windows::ApplicationModel::DataTransfer::DataPackageView dataview = { nullptr };
 };
--- a/ui/winui/table.cpp	Wed Jan 31 19:15:41 2024 +0100
+++ b/ui/winui/table.cpp	Thu Feb 01 19:45:17 2024 +0100
@@ -385,7 +385,7 @@
 						dnd.dndstartargs = { nullptr };
 						dnd.dndcompletedargs = { nullptr };
 						dnd.drageventargs = args;
-						dnd.data = args.Data();
+						dnd.dataview = args.DataView();
 
 						UiListDnd dndevt;
 						dndevt.selection = uiselection();
@@ -404,6 +404,9 @@
 							free(dndevt.selection.rows);
 						}
 					}));
+				cellBorder.DragOver(DragEventHandler([this](winrt::Windows::Foundation::IInspectable const& sender, DragEventArgs const& args){
+					args.AcceptedOperation(winrt::Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy);
+					}));
 			}
 
 			// set the cell value

mercurial