Thu, 01 Feb 2024 19:45:17 +0100
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