# HG changeset patch # User Olaf Wintermann # Date 1697812473 -7200 # Node ID 88bc21b19213fd81dff07ebc29039777cc6c05bc # Parent 8d7ca1b320e2e8e0b714548662b1fb8ffab97d6c add minimal working dnd implementation (WinUI3) diff -r 8d7ca1b320e2 -r 88bc21b19213 make/vs/testapp/main.c --- 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); } diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/ui/dnd.h --- 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 diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/ui/toolkit.h --- 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; diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/ui/tree.h --- 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 { diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/dnd.cpp --- /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; +} diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/dnd.h --- /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 }; +}; diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/pch.h --- 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 #include #include +#include #include #include diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/table.cpp --- 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); } })); } diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/table.h --- 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 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); diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/util.cpp --- 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, diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/util.h --- 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); diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/winui.vcxproj --- 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 @@ + @@ -160,6 +161,7 @@ + diff -r 8d7ca1b320e2 -r 88bc21b19213 ui/winui/winui.vcxproj.filters --- 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 @@ + @@ -93,6 +94,7 @@ +