Wed, 31 Jan 2024 19:15:41 +0100
add file open dialog (WinUI3)
ui/ui/window.h | file | annotate | diff | comparison | revisions | |
ui/winui/pch.h | file | annotate | diff | comparison | revisions | |
ui/winui/window.cpp | file | annotate | diff | comparison | revisions |
--- a/ui/ui/window.h Tue Jan 30 13:10:16 2024 +0100 +++ b/ui/ui/window.h Wed Jan 31 19:15:41 2024 +0100 @@ -35,13 +35,22 @@ extern "C" { #endif +#define UI_FILEDIALOG_SELECT_SINGLE 0 +#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); UIEXPORT void ui_window_size(UiObject *obj, int width, int height); -char* ui_openfiledialog(UiObject *obj); -char* ui_savefiledialog(UiObject *obj); +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 }
--- a/ui/winui/pch.h Tue Jan 30 13:10:16 2024 +0100 +++ b/ui/winui/pch.h Wed Jan 31 19:15:41 2024 +0100 @@ -34,6 +34,12 @@ #include <winrt/Microsoft.UI.Input.h> #include <winrt/Windows.UI.Core.h> #include <winrt/Windows.ApplicationModel.h> +#include <winrt/Windows.Storage.Pickers.h> + #include <winrt\Microsoft.UI.Dispatching.h> #include <winrt/Windows.Storage.Streams.h> + +#include <Microsoft.UI.Xaml.Window.h> + +#include <shobjidl_core.h>
--- a/ui/winui/window.cpp Tue Jan 30 13:10:16 2024 +0100 +++ b/ui/winui/window.cpp Wed Jan 31 19:15:41 2024 +0100 @@ -28,6 +28,7 @@ #include "pch.h" + #include "window.h" #include "appmenu.h" @@ -52,6 +53,7 @@ using namespace Microsoft::UI::Xaml::Markup; using namespace Windows::UI::Xaml::Interop; using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Storage::Pickers; UiWindow::UiWindow(winrt::Microsoft::UI::Xaml::Window& win) : window(win) {} @@ -185,3 +187,99 @@ win->window.AppWindow().Resize(wsize); } } + +static void filedialog_callback( + UiObject *obj, + ui_callback file_selected_callback, + void *cbdata, + winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Storage::StorageFile> result) +{ + UiFileList flist; + flist.nfiles = result.Size(); + flist.files = new char*[flist.nfiles]; + + int i = 0; + for (auto const& file : result) { + winrt::hstring path = file.Path(); + flist.files[i++] = wchar2utf8(path.c_str(), path.size()); + } + + UiEvent evt; + evt.obj = obj; + evt.document = obj->ctx->document; + evt.window = obj->window; + evt.eventdata = &flist; + evt.intval = 0; + file_selected_callback(&evt, cbdata); + + for (int i = 0; i < flist.nfiles;i++) { + free(flist.files[i]); + } + delete[] flist.files; +} + +static Windows::Foundation::IAsyncAction open_filedialog_async(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { + FileOpenPicker openFileDialog = FileOpenPicker(); + auto initializeWithWindow { openFileDialog.as<::IInitializeWithWindow>() + }; + + HWND hwnd{ nullptr }; + winrt::check_hresult(obj->wobj->window.as<IWindowNative>()->get_WindowHandle(&hwnd)); + + initializeWithWindow->Initialize(hwnd); + + openFileDialog.FileTypeFilter().Append(L"*"); + + if ((mode & UI_FILEDIALOG_SELECT_MULTI) == UI_FILEDIALOG_SELECT_MULTI) { + auto files = co_await openFileDialog.PickMultipleFilesAsync(); + filedialog_callback(obj, file_selected_callback, cbdata, files); + } else { + auto file = co_await openFileDialog.PickSingleFileAsync(); + auto files = single_threaded_vector<winrt::Windows::Storage::StorageFile>(); + files.Append(file); + filedialog_callback(obj, file_selected_callback, cbdata, files.GetView()); + } +} + +static Windows::Foundation::IAsyncAction folderdialog_async(UiObject *obj, ui_callback file_selected_callback, void *cbdata) { + FolderPicker folderPicker = FolderPicker(); + auto initializeWithWindow { folderPicker.as<::IInitializeWithWindow>() + }; + + HWND hwnd{ nullptr }; + winrt::check_hresult(obj->wobj->window.as<IWindowNative>()->get_WindowHandle(&hwnd)); + + initializeWithWindow->Initialize(hwnd); + + folderPicker.FileTypeFilter().Append(L"*"); + + auto folder = co_await folderPicker.PickSingleFolderAsync(); + if (folder) { + winrt::hstring hpath = folder.Path(); + char *cpath = wchar2utf8(hpath.c_str(), hpath.size()); + + UiFileList flist; + flist.nfiles = 1; + flist.files = &cpath; + + UiEvent evt; + evt.obj = obj; + evt.document = obj->ctx->document; + evt.window = obj->window; + evt.eventdata = &flist; + evt.intval = 0; + file_selected_callback(&evt, cbdata); + } +} + +UIEXPORT void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { + if ((mode & UI_FILEDIALOG_SELECT_FOLDER) == UI_FILEDIALOG_SELECT_FOLDER) { + folderdialog_async(obj, file_selected_callback, cbdata); + } else { + open_filedialog_async(obj, mode, file_selected_callback, cbdata); + } +} + +UIEXPORT void ui_savefiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { + +}