add minimal working dnd implementation (WinUI3) newapi

Fri, 20 Oct 2023 16:34:33 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 20 Oct 2023 16:34:33 +0200
branch
newapi
changeset 224
88bc21b19213
parent 223
8d7ca1b320e2
child 225
097f45f9c1fa

add minimal working dnd implementation (WinUI3)

make/vs/testapp/main.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/tree.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/pch.h file | annotate | diff | comparison | revisions
ui/winui/table.cpp file | annotate | diff | comparison | revisions
ui/winui/table.h file | annotate | diff | comparison | revisions
ui/winui/util.cpp file | annotate | diff | comparison | revisions
ui/winui/util.h file | annotate | diff | comparison | revisions
ui/winui/winui.vcxproj file | annotate | diff | comparison | revisions
ui/winui/winui.vcxproj.filters file | annotate | diff | comparison | revisions
--- a/make/vs/testapp/main.c	Thu Oct 19 21:19:19 2023 +0200
+++ b/make/vs/testapp/main.c	Fri Oct 20 16:34:33 2023 +0200
@@ -144,10 +144,15 @@
 }
 
 void dragstart(UiEvent* event, void* data) {
+    UiListDnd* ldnd = event->eventdata;
+    ui_selection_settext(ldnd->dnd, "Hello World!", -1);
+}
+
+void dragcomplete(UiEvent* event, void* data) {
 
 }
 
-void dragcomplete(UiEvent* event, void* data) {
+void dragover(UiEvent* event, void* data) {
 
 }
 
@@ -306,7 +311,7 @@
             UiModel* model = ui_model(obj->ctx, UI_ICON_TEXT, "Col 1", UI_STRING, "Col 2", UI_STRING, "Col 3", -1);
             model->getvalue = table_getvalue;
             ui_table(obj,   .colspan = 3, .model = model, .list = wdata->list2, .onactivate = action_onactivate,
-                            .onselection = action_listselection_changed, .enabledrag = true, .enabledrop = true,
+                            .onselection = action_listselection_changed,
                             .ondragstart = dragstart, .ondragcomplete = dragcomplete, .ondrop = drop);
             ui_model_free(obj->ctx, model);
         }
--- a/ui/ui/dnd.h	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/ui/dnd.h	Fri Oct 20 16:34:33 2023 +0200
@@ -37,11 +37,11 @@
     
 #define UI_DND_FILE_TARGET "XdndDirectSave0"
     
-void ui_selection_settext(UiSelection *sel, char *str, int len);
-void ui_selection_seturis(UiSelection *sel, char **uris, int nelm);
+UIEXPORT void ui_selection_settext(UiDnD *sel, char *str, int len);
+UIEXPORT void ui_selection_seturis(UiDnD *sel, char **uris, int nelm);
 
-char* ui_selection_gettext(UiSelection *sel);
-char** ui_selection_geturis(UiSelection *sel, size_t *nelm);
+UIEXPORT char* ui_selection_gettext(UiDnD *sel);
+UIEXPORT char** ui_selection_geturis(UiDnD *sel, size_t *nelm);
 
 
 #ifdef __cplusplus
--- a/ui/ui/toolkit.h	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/ui/toolkit.h	Fri Oct 20 16:34:33 2023 +0200
@@ -162,7 +162,7 @@
 typedef struct UiIcon       UiIcon;
 typedef struct UiImage      UiImage;
 
-typedef struct UiSelection  UiSelection;
+typedef struct UiDnD        UiDnD;
 /* end opaque types */
 
 typedef struct UiTabbedPane UiTabbedPane;
--- a/ui/ui/tree.h	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/ui/tree.h	Fri Oct 20 16:34:33 2023 +0200
@@ -38,6 +38,7 @@
 typedef struct UiModel         UiModel;
 typedef struct UiListCallbacks UiListCallbacks;
 typedef struct UiListSelection UiListSelection;
+typedef struct UiListDnd       UiListDnd;
 
 typedef struct UiListArgs      UiListArgs;
 typedef struct UiPathBarArgs   UiPathBarArgs;
@@ -74,12 +75,6 @@
      * TODO: return
      */
     void*(*getvalue)(void*, int);
-    
-    UiBool(*candrop)(UiEvent*, UiSelection*, UiList*, int);
-    void(*drop)(UiEvent*, UiSelection*, UiList*, int);
-    UiBool(*candrag)(UiEvent*, UiList*, int);
-    void(*data_get)(UiEvent*, UiSelection*, UiList*, int);
-    void(*data_delete)(UiEvent*, UiList*, int);
 };
 
 struct UiListCallbacks {
@@ -111,9 +106,9 @@
     int *rows;
 };
 
-struct UiTableDndEvent {
+struct UiListDnd {
     UiListSelection selection;
-    void* dnd;
+    UiDnD *dnd;
 };
 
 struct UiListArgs {
@@ -138,8 +133,6 @@
     ui_callback ondrop;
     void* ondropsdata;
     UiBool multiselection;
-    UiBool enabledrag;
-    UiBool enabledrop;
 };
 
 struct UiPathBarArgs {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/winui/dnd.cpp	Fri Oct 20 16:34:33 2023 +0200
@@ -0,0 +1,59 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2023 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "pch.h"
+
+#include "dnd.h"
+#include "util.h"
+
+UIEXPORT void ui_selection_settext(UiDnD* dnd, char* str, int len) {
+	if (dnd->data) {
+		if (len < 0) {
+			len = strlen(str);
+		}
+		wchar_t *wstr = str2wstr_len(str, len, nullptr);
+
+		dnd->data.SetText(wstr);
+
+		free(wstr);
+
+	}
+}
+
+UIEXPORT void ui_selection_seturis(UiDnD* dnd, char** uris, int nelm) {
+
+}
+
+
+UIEXPORT char* ui_selection_gettext(UiDnD* dnd) {
+	return nullptr;
+}
+
+UIEXPORT char** ui_selection_geturis(UiDnD* dnd, size_t* nelm) {
+	return nullptr;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/winui/dnd.h	Fri Oct 20 16:34:33 2023 +0200
@@ -0,0 +1,39 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2023 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "../ui/dnd.h"
+
+struct UiDnD {
+	int evttype = 0;
+	winrt::Microsoft::UI::Xaml::DragStartingEventArgs dndstartargs = { nullptr };
+	winrt::Microsoft::UI::Xaml::DropCompletedEventArgs dndcompletedargs = { nullptr };
+	winrt::Microsoft::UI::Xaml::DragEventArgs drageventargs = { nullptr };
+	winrt::Windows::ApplicationModel::DataTransfer::DataPackage data = { nullptr };
+};
--- a/ui/winui/pch.h	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/winui/pch.h	Fri Oct 20 16:34:33 2023 +0200
@@ -27,6 +27,7 @@
 #include <winrt/Microsoft.UI.Xaml.Shapes.h>
 #include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
 #include <winrt/Microsoft.UI.Dispatching.h>
+#include <winrt/Windows.ApplicationModel.DataTransfer.h>
 #include <wil/cppwinrt_helpers.h>
 
 #include <winrt/Windows.Storage.Streams.h>
--- a/ui/winui/table.cpp	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/winui/table.cpp	Fri Oct 20 16:34:33 2023 +0200
@@ -83,8 +83,6 @@
 	uitable->ondragcomplete = args.ondragcomplete;
 	uitable->ondrop = args.ondrop;
 	uitable->ondropdata = args.ondropsdata;
-	uitable->enabledrag = args.enabledrag;
-	uitable->enabledrop = args.enabledrop;
 
 	// grid styling
 	winrt::Windows::UI::Color bg = { 255, 255, 255, 255 }; // test color
@@ -272,11 +270,16 @@
 			if (ondragstart) {
 				cellBorder.CanDrag(true);
 				cellBorder.DragStarting([this](IInspectable const& sender, DragStartingEventArgs args) {
-						UiWinuiTableDnd dndevt;
-						dndevt.evtobj.selection = uiselection();
-						dndevt.evtobj.dnd = &dndevt;
-						dndevt.evttype = 0;
-						dndevt.dndstartargs = args;
+						UiDnD dnd;
+						dnd.evttype = 0;
+						dnd.dndstartargs = args;
+						dnd.dndcompletedargs = { nullptr };
+						dnd.drageventargs = { nullptr };
+						dnd.data = args.Data();
+
+						UiListDnd dndevt;
+						dndevt.selection = uiselection();
+						dndevt.dnd = &dnd;
 
 						UiEvent evt;
 						evt.obj = this->obj;
@@ -287,16 +290,21 @@
 					
 						this->ondragstart(&evt, this->ondragstartdata);
 
-						if (dndevt.evtobj.selection.rows) {
-							free(dndevt.evtobj.selection.rows);
+						if (dndevt.selection.rows) {
+							free(dndevt.selection.rows);
 						}
 					});
 				cellBorder.DropCompleted([this](IInspectable const& sender, DropCompletedEventArgs args) {
-						UiWinuiTableDnd dndevt;
-						dndevt.evtobj.selection = uiselection();
-						dndevt.evtobj.dnd = &dndevt;
-						dndevt.evttype = 1;
-						dndevt.dndcompletedargs = args;
+						UiDnD dnd;
+						dnd.evttype = 1;
+						dnd.dndstartargs = { nullptr };
+						dnd.dndcompletedargs = args;
+						dnd.drageventargs = { nullptr };
+						dnd.data = { nullptr };
+
+						UiListDnd dndevt;
+						dndevt.selection = uiselection();
+						dndevt.dnd = &dnd;
 
 						UiEvent evt;
 						evt.obj = this->obj;
@@ -308,19 +316,24 @@
 						if (this->ondragcomplete) {
 							this->ondragcomplete(&evt, this->ondragcompletedata);
 						}
-						if (dndevt.evtobj.selection.rows) {
-							free(dndevt.evtobj.selection.rows);
+						if (dndevt.selection.rows) {
+							free(dndevt.selection.rows);
 						}
 					});
 			}
 			if (ondrop) {
-				cellBorder.AllowDrop(enabledrop);
+				cellBorder.AllowDrop(true);
 				cellBorder.Drop(DragEventHandler([this](winrt::Windows::Foundation::IInspectable const& sender, DragEventArgs const& args){
-						UiWinuiTableDnd dndevt;
-						dndevt.evtobj.selection = uiselection();
-						dndevt.evtobj.dnd = &dndevt;
-						dndevt.evttype = 2;
-						dndevt.drageventargs = args;
+						UiDnD dnd;
+						dnd.evttype = 2;
+						dnd.dndstartargs = { nullptr };
+						dnd.dndcompletedargs = { nullptr };
+						dnd.drageventargs = args;
+						dnd.data = args.Data();
+
+						UiListDnd dndevt;
+						dndevt.selection = uiselection();
+						dndevt.dnd = &dnd;
 
 						UiEvent evt;
 						evt.obj = this->obj;
@@ -331,8 +344,8 @@
 
 						this->ondrop(&evt, this->ondropdata);
 
-						if (dndevt.evtobj.selection.rows) {
-							free(dndevt.evtobj.selection.rows);
+						if (dndevt.selection.rows) {
+							free(dndevt.selection.rows);
 						}
 					}));
 			}
--- a/ui/winui/table.h	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/winui/table.h	Fri Oct 20 16:34:33 2023 +0200
@@ -30,6 +30,7 @@
 
 #include "../ui/tree.h"
 #include "toolkit.h"
+#include "dnd.h"
 
 #include "../ui/container.h"
 
@@ -39,14 +40,6 @@
 
 } UiTableColumn;
 
-struct UiWinuiTableDnd {
-	UiTableDndEvent evtobj;
-	int evttype = 0;
-	winrt::Microsoft::UI::Xaml::DragStartingEventArgs dndstartargs = { nullptr };
-	winrt::Microsoft::UI::Xaml::DropCompletedEventArgs dndcompletedargs = { nullptr };
-	winrt::Microsoft::UI::Xaml::DragEventArgs drageventargs = { nullptr };
-};
-
 typedef struct UiTable {
 	winrt::Microsoft::UI::Xaml::Controls::ScrollViewer scrollw;
 	winrt::Microsoft::UI::Xaml::Controls::Grid grid;
@@ -72,8 +65,6 @@
 	int lastSelection = 0;
 	ULONG64 lastPointerPress = 0;
 	std::vector<int> selection;
-	bool enabledrag = false; // TODO: remove
-	bool enabledrop = false; // TODO: remove
 
 	UiTable(UiObject *obj, winrt::Microsoft::UI::Xaml::Controls::ScrollViewer scrollW, winrt::Microsoft::UI::Xaml::Controls::Grid grid);
 
--- a/ui/winui/util.cpp	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/winui/util.cpp	Fri Oct 20 16:34:33 2023 +0200
@@ -8,7 +8,10 @@
 wchar_t* str2wstr(const char* str, int* newlen) {
     size_t len = strlen(str);
 
+    return str2wstr_len(str, len, newlen);
+}
 
+wchar_t* str2wstr_len(const char* str, size_t len, int* newlen) {
     wchar_t* wstr = (wchar_t*)calloc(len + 1, sizeof(wchar_t));
     int wlen = MultiByteToWideChar(
         CP_UTF8,
--- a/ui/winui/util.h	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/winui/util.h	Fri Oct 20 16:34:33 2023 +0200
@@ -2,4 +2,6 @@
 
 wchar_t* str2wstr(const char* str, int* newlen);
 
+wchar_t* str2wstr_len(const char* str, size_t len, int* newlen);
+
 char* wchar2utf8(const wchar_t* wstr, size_t wlen);
--- a/ui/winui/winui.vcxproj	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/winui/winui.vcxproj	Fri Oct 20 16:34:33 2023 +0200
@@ -134,6 +134,7 @@
     <ClInclude Include="button.h" />
     <ClInclude Include="commandbar.h" />
     <ClInclude Include="container.h" />
+    <ClInclude Include="dnd.h" />
     <ClInclude Include="icons.h" />
     <ClInclude Include="label.h" />
     <ClInclude Include="list.h" />
@@ -160,6 +161,7 @@
     <ClCompile Include="button.cpp" />
     <ClCompile Include="commandbar.cpp" />
     <ClCompile Include="container.cpp" />
+    <ClCompile Include="dnd.cpp" />
     <ClCompile Include="icons.cpp" />
     <ClCompile Include="label.cpp" />
     <ClCompile Include="list.cpp" />
--- a/ui/winui/winui.vcxproj.filters	Thu Oct 19 21:19:19 2023 +0200
+++ b/ui/winui/winui.vcxproj.filters	Fri Oct 20 16:34:33 2023 +0200
@@ -26,6 +26,7 @@
     <ClCompile Include="stock.cpp" />
     <ClCompile Include="icons.cpp" />
     <ClCompile Include="label.cpp" />
+    <ClCompile Include="dnd.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="pch.h" />
@@ -93,6 +94,7 @@
     <ClInclude Include="stock.h" />
     <ClInclude Include="icons.h" />
     <ClInclude Include="label.h" />
+    <ClInclude Include="dnd.h" />
   </ItemGroup>
   <ItemGroup>
     <Image Include="Assets\Wide310x150Logo.scale-200.png">

mercurial