ui/winui/window.cpp

changeset 18
af411868ab9b
parent 13
5a8762fcfecc
child 21
3060a5a1d5fd
--- a/ui/winui/window.cpp	Wed Jan 31 12:55:11 2024 +0100
+++ b/ui/winui/window.cpp	Tue Feb 06 14:17:22 2024 +0100
@@ -28,6 +28,7 @@
 
 #include "pch.h"
 
+
 #include "window.h"
 
 #include "appmenu.h"
@@ -52,54 +53,12 @@
 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) {}
 
 UiObject* ui_window(const char* title, void* window_data) {
-	CxMempool* mp = cxBasicMempoolCreate(256);
-	UiObject* obj = (UiObject*)cxCalloc(mp->allocator, 1, sizeof(UiObject));
-
-	obj->ctx = uic_context(obj, mp);
-	obj->window = window_data;
-
-	Window window = Window();
-	//Window window = make<winui::implementation::MainWindow>();
-
-	winrt::Windows::Foundation::Uri resourceLocator{ L"ms-appx:///MainWindow.xaml" };
-	Application::LoadComponent(window, resourceLocator, ComponentResourceLocation::Nested);
-
-	window.ExtendsContentIntoTitleBar(true);
-
-	Grid grid = Grid();
-	window.Content(grid);
-
-	StackPanel titleBar = StackPanel();
-	Thickness titleBarPadding = { 10, 5, 5, 10 };
-	titleBar.Padding(titleBarPadding);
-	titleBar.Orientation(Orientation::Horizontal);
-	TextBlock titleLabel = TextBlock();
-	titleBar.Children().Append(titleLabel);
-
-	if (title) {
-		wchar_t* wtitle = str2wstr(title, nullptr);
-		window.Title(wtitle);
-		titleLabel.Text(hstring(wtitle));
-		free(wtitle);
-	}
-
-	window.SetTitleBar(titleBar);
-
-	obj->wobj = new UiWindow(window);
-	ui_context_add_window_destructor(obj->ctx, obj->wobj);
-
-	window.Closed([obj](IInspectable const& sender, WindowEventArgs) {
-		cxMempoolDestroy(obj->ctx->mp);
-	});
-
-	obj->container = new UiBoxContainer(grid, UI_BOX_CONTAINER_VBOX, 0, 0);
-
-	titleBar.VerticalAlignment(VerticalAlignment::Top);
-	obj->container->Add(titleBar, false);
+	UiObject* obj = ui_simple_window(title, window_data);
 
 	if (uic_get_menu_list()) {
 		// create/add menubar
@@ -171,6 +130,55 @@
 		obj->container->Add(toolbar_grid, false);
 	}
 
+	return obj;
+}
+
+UIEXPORT UiObject* ui_simple_window(const char *title, void *window_data) {
+	CxMempool* mp = cxBasicMempoolCreate(256);
+	UiObject* obj = (UiObject*)cxCalloc(mp->allocator, 1, sizeof(UiObject));
+
+	obj->ctx = uic_context(obj, mp);
+	obj->window = window_data;
+
+	Window window = Window();
+	//Window window = make<winui::implementation::MainWindow>();
+
+	winrt::Windows::Foundation::Uri resourceLocator{ L"ms-appx:///MainWindow.xaml" };
+	Application::LoadComponent(window, resourceLocator, ComponentResourceLocation::Nested);
+
+	window.ExtendsContentIntoTitleBar(true);
+
+	Grid grid = Grid();
+	window.Content(grid);
+
+	StackPanel titleBar = StackPanel();
+	Thickness titleBarPadding = { 10, 5, 5, 10 };
+	titleBar.Padding(titleBarPadding);
+	titleBar.Orientation(Orientation::Horizontal);
+	TextBlock titleLabel = TextBlock();
+	titleBar.Children().Append(titleLabel);
+
+	if (title) {
+		wchar_t* wtitle = str2wstr(title, nullptr);
+		window.Title(wtitle);
+		titleLabel.Text(hstring(wtitle));
+		free(wtitle);
+	}
+
+	window.SetTitleBar(titleBar);
+
+	obj->wobj = new UiWindow(window);
+	ui_context_add_window_destructor(obj->ctx, obj->wobj);
+
+	window.Closed([obj](IInspectable const& sender, WindowEventArgs) {
+		cxMempoolDestroy(obj->ctx->mp);
+		});
+
+	obj->container = new UiBoxContainer(grid, UI_BOX_CONTAINER_VBOX, 0, 0);
+
+	titleBar.VerticalAlignment(VerticalAlignment::Top);
+	obj->container->Add(titleBar, false);
+
 	obj->window = window_data;
 
 	return obj;
@@ -185,3 +193,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) {
+
+}

mercurial