implement ui_dialog_window (WINUI) newapi

Tue, 12 Nov 2024 14:58:03 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 12 Nov 2024 14:58:03 +0100
branch
newapi
changeset 379
958bae372271
parent 378
d41b1ffc5f77
child 380
aad99285865c

implement ui_dialog_window (WINUI)

make/vs/testapp/main.c file | annotate | diff | comparison | revisions
make/vs/toolkit.sln file | annotate | diff | comparison | revisions
ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/document.c file | annotate | diff | comparison | revisions
ui/common/menu.c file | annotate | diff | comparison | revisions
ui/common/properties.c file | annotate | diff | comparison | revisions
ui/gtk/text.c file | annotate | diff | comparison | revisions
ui/gtk/text.h file | annotate | diff | comparison | revisions
ui/ui/properties.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
ui/winui/button.cpp file | annotate | diff | comparison | revisions
ui/winui/button.h file | annotate | diff | comparison | revisions
ui/winui/text.cpp file | annotate | diff | comparison | revisions
ui/winui/text.h file | annotate | diff | comparison | revisions
ui/winui/toolkit.cpp file | annotate | diff | comparison | revisions
ui/winui/window.cpp 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	Sun Nov 10 15:27:44 2024 +0100
+++ b/make/vs/testapp/main.c	Tue Nov 12 14:58:03 2024 +0100
@@ -121,7 +121,7 @@
 
 void action_toolbar_dialog(UiEvent *event, void *userdata) {
 
-    UiObject *dialog = ui_dialog_window(event->obj, .title  = "Dialog Window", .lbutton1 = "Cancel 1", .lbutton2 = "Btn2", .rbutton3 = "Btn3", .rbutton4 = "Login 4", .onclick = action_dialog_button, .default_button = 4, .show_closebutton = UI_OFF);
+    UiObject *dialog = ui_dialog_window(event->obj, .title  = "Dialog Window", .lbutton1 = "Cancel 1", .lbutton2 = "Btn 2", .rbutton3 = "Btn3", .rbutton4 = "Login 4", .onclick = action_dialog_button, .default_button = 4, .show_closebutton = UI_OFF);
 
     ui_vbox(dialog, .margin = 10, .spacing = 10) {
         ui_label(dialog, .label = "Enter password:");
--- a/make/vs/toolkit.sln	Sun Nov 10 15:27:44 2024 +0100
+++ b/make/vs/toolkit.sln	Tue Nov 12 14:58:03 2024 +0100
@@ -9,8 +9,6 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winui", "..\..\ui\winui\winui.vcxproj", "{59F97886-BF49-4B3F-9EF6-FA7A84F3AB56}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uicommon", "uicommon\uicommon.vcxproj", "{8B88698E-C185-4383-99FE-0C34D6DEED2E}"
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|ARM64 = Debug|ARM64
@@ -63,18 +61,6 @@
 		{59F97886-BF49-4B3F-9EF6-FA7A84F3AB56}.Release|x86.ActiveCfg = Release|Win32
 		{59F97886-BF49-4B3F-9EF6-FA7A84F3AB56}.Release|x86.Build.0 = Release|Win32
 		{59F97886-BF49-4B3F-9EF6-FA7A84F3AB56}.Release|x86.Deploy.0 = Release|Win32
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Debug|ARM64.ActiveCfg = Debug|x64
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Debug|ARM64.Build.0 = Debug|x64
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Debug|x64.ActiveCfg = Debug|x64
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Debug|x64.Build.0 = Debug|x64
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Debug|x86.ActiveCfg = Debug|Win32
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Debug|x86.Build.0 = Debug|Win32
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Release|ARM64.ActiveCfg = Release|x64
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Release|ARM64.Build.0 = Release|x64
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Release|x64.ActiveCfg = Release|x64
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Release|x64.Build.0 = Release|x64
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Release|x86.ActiveCfg = Release|Win32
-		{8B88698E-C185-4383-99FE-0C34D6DEED2E}.Release|x86.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
--- a/ui/common/context.c	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/common/context.c	Tue Nov 12 14:58:03 2024 +0100
@@ -41,6 +41,7 @@
 #include "document.h"
 #include "types.h"
 
+
 static UiContext* global_context;
 
 void uic_init_global_context(void) {
--- a/ui/common/document.c	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/common/document.c	Tue Nov 12 14:58:03 2024 +0100
@@ -35,6 +35,7 @@
 #include <cx/hash_map.h>
 #include <cx/mempool.h>
 
+
 static CxMap *documents;
 
 void uic_docmgr_init() {
--- a/ui/common/menu.c	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/common/menu.c	Tue Nov 12 14:58:03 2024 +0100
@@ -34,6 +34,7 @@
 #include <cx/linked_list.h>
 #include <cx/array_list.h>
 
+
 static UiMenu *menus_begin;
 static UiMenu *menus_end;
 static CxList *current;
--- a/ui/common/properties.c	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/common/properties.c	Tue Nov 12 14:58:03 2024 +0100
@@ -39,6 +39,7 @@
 #include <cx/string.h>
 #include <cx/buffer.h>
 
+#include <cx/hash_map.h>
 #include "ucx_properties.h"
 
 static CxMap *application_properties;
@@ -60,6 +61,14 @@
     return ui_configfile(NULL);
 }
 
+#ifndef _WIN32
+#define UI_PATH_SEPARATOR '/'
+#define UI_ENV_HOME "HOME"
+#else
+#define UI_PATH_SEPARATOR '\\'
+#define UI_ENV_HOME "USERPROFILE"
+#endif
+
 char* ui_configfile(char *name) {
     const char *appname = ui_appname();
     if(!appname) {
@@ -70,7 +79,7 @@
     cxBufferInit(&buf, NULL, 128, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
     
     // add base dir
-    char *homeenv = getenv("HOME");
+    char *homeenv = getenv(UI_ENV_HOME);
     if(homeenv == NULL) {
         cxBufferDestroy(&buf);
         return NULL;
@@ -78,19 +87,22 @@
     cxstring home = cx_str(homeenv);
     
     cxBufferWrite(home.ptr, 1, home.length, &buf);
-    if(home.ptr[home.length-1] != '/') {
-        cxBufferPut(&buf, '/');
+    if(home.ptr[home.length-1] != UI_PATH_SEPARATOR) {
+        cxBufferPut(&buf, UI_PATH_SEPARATOR);
     }
     
 #ifdef UI_COCOA
     // on OS X the app dir is $HOME/Library/Application Support/$APPNAME/
-    ucx_buffer_puts(buf, "Library/Application Support/");
+    cxBufferPutString(&buf, "Library/Application Support/");
+#elif defined(_WIN32)
+    // on Windows the app dir is $USERPROFILE/AppData/Local/$APPNAME/
+    cxBufferPutString(&buf, "AppData\\Local\\");
 #else
     // app dir is $HOME/.$APPNAME/
     cxBufferPut(&buf, '.');
 #endif
     cxBufferPutString(&buf, appname);
-    cxBufferPut(&buf, '/');
+    cxBufferPut(&buf, UI_PATH_SEPARATOR);
     
     // add file name
     if(name) {
--- a/ui/gtk/text.c	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/gtk/text.c	Tue Nov 12 14:58:03 2024 +0100
@@ -78,9 +78,12 @@
             NULL);
     
     UiTextArea *uitext = malloc(sizeof(UiTextArea));
+    uitext->obj = obj;
     uitext->ctx = obj->ctx;
     uitext->var = var;
     uitext->last_selection_state = 0;
+    uitext->onchange = args.onchange;
+    uitext->onchangedata = args.onchangedata;
     
     g_signal_connect(
                 text_area,
@@ -266,13 +269,19 @@
 
 void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea) {
     UiText *value = textarea->var->value;
+    
+    UiEvent e;
+    e.obj = textarea->obj;
+    e.window = e.obj->window;
+    e.document = textarea->ctx->document;
+    e.eventdata = value;
+    e.intval = 0;
+    
+    if(textarea->onchange) {
+        textarea->onchange(&e, textarea->onchangedata);
+    }
+    
     if(value->observers) {
-        UiEvent e;
-        e.obj = textarea->ctx->obj;
-        e.window = e.obj->window;
-        e.document = textarea->ctx->document;
-        e.eventdata = value;
-        e.intval = 0;
         ui_notify_evt(value->observers, &e);
     }
 }
--- a/ui/gtk/text.h	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/gtk/text.h	Tue Nov 12 14:58:03 2024 +0100
@@ -61,9 +61,12 @@
 } UiUndoMgr;
 
 typedef struct UiTextArea {
-    UiContext *ctx;
-    UiVar    *var;
-    int       last_selection_state;
+    UiObject    *obj;
+    UiContext   *ctx;
+    UiVar       *var;
+    int         last_selection_state;
+    ui_callback onchange;
+    void        *onchangedata;
 } UiTextArea;
 
 typedef struct UiTextField {
--- a/ui/ui/properties.h	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/ui/properties.h	Tue Nov 12 14:58:03 2024 +0100
@@ -35,8 +35,6 @@
 extern "C" {
 #endif
 
-typedef struct CxMap UiProperties;
-
 char* ui_get_property(char *name);
 void  ui_set_property(char *name, char *value);
 
--- a/ui/ui/toolkit.h	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/ui/toolkit.h	Tue Nov 12 14:58:03 2024 +0100
@@ -84,6 +84,7 @@
 
 #ifdef __cplusplus
 
+#include <functional>
 #ifndef UI_WINUI_PCH
 #include <Windows.h>
 #undef GetCurrentTime
@@ -105,6 +106,7 @@
     void* data1 = nullptr;
     void* data2 = nullptr;
     void* data3 = nullptr;
+    std::function<void()> Show;
     UiWidget(winrt::Microsoft::UI::Xaml::UIElement& elm);
 
 };
--- a/ui/winui/button.cpp	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/winui/button.cpp	Tue Nov 12 14:58:03 2024 +0100
@@ -46,7 +46,7 @@
 
 
 
-static void set_button_label(ButtonBase button, const char* label, const char* stockid, const char *icon, UiLabelType type) {
+void ui_set_button_label(ButtonBase button, const char* label, const char* stockid, const char *icon, UiLabelType type) {
 	// TODO: stockid
 
 	if (type == UI_LABEL_ICON) {
@@ -92,7 +92,7 @@
 
 	// create button with label
 	Button button = Button();
-	set_button_label(button, args.label, args.stockid, args.icon, args.labeltype);
+	ui_set_button_label(button, args.label, args.stockid, args.icon, args.labeltype);
 
 	// create toolkit wrapper object and register destructor
 	UIElement elm = button;
@@ -180,7 +180,7 @@
 	UiObject* current = uic_current_obj(obj);
 
 	// set label
-	set_button_label(button, args.label, args.stockid, args.icon, args.labeltype);
+	ui_set_button_label(button, args.label, args.stockid, args.icon, args.labeltype);
 	togglebutton_register_callback(button, obj, args);
 
 	// create toolkit wrapper object and register destructor
@@ -267,7 +267,7 @@
 	UiObject* current = uic_current_obj(obj);
 
 	// set label
-	set_button_label(button, args.label, args.stockid, args.icon, args.labeltype);
+	ui_set_button_label(button, args.label, args.stockid, args.icon, args.labeltype);
 	togglebutton_register_callback(button, obj, args);
 
 	// create toolkit wrapper object and register destructor
--- a/ui/winui/button.h	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/winui/button.h	Tue Nov 12 14:58:03 2024 +0100
@@ -35,6 +35,7 @@
 
 #include "../common/context.h"
 
+void ui_set_button_label(winrt::Microsoft::UI::Xaml::Controls::Primitives::ButtonBase button, const char* label, const char* stockid, const char *icon, UiLabelType type);
 
 void togglebutton_register_checked_observers(winrt::Microsoft::UI::Xaml::Controls::Primitives::ToggleButton button, UiObject* obj, UiVar* var);
 void togglebutton_register_unchecked_observers(winrt::Microsoft::UI::Xaml::Controls::Primitives::ToggleButton button, UiObject* obj, UiVar* var);
--- a/ui/winui/text.cpp	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/winui/text.cpp	Tue Nov 12 14:58:03 2024 +0100
@@ -56,7 +56,9 @@
     UiObject* current = uic_current_obj(obj);
 
     // create textarea and toolkit wrapper
-    RichEditBox textarea = RichEditBox();
+    TextBox textarea = TextBox();
+    textarea.AcceptsReturn(true);
+    ScrollViewer::SetVerticalScrollBarVisibility(textarea, ScrollBarVisibility::Auto);
     UIElement elm = textarea;
     UiWidget* widget = new UiWidget(elm);
     ui_context_add_widget_destructor(current->ctx, widget);
@@ -97,14 +99,46 @@
 
 }
 
+// -------------------------- getter/setter for textarea UiText --------------------------
 
+char* ui_wtext_get(UiText *text, std::wstring &value) {
+    if (text->value.ptr) {
+        text->value.free(text->value.ptr);
+    }
+
+    text->value.ptr = wchar2utf8(value.c_str(), value.length());
+    text->value.free = free;
+
+    return text->value.ptr;
+}
+
+std::wstring ui_wtext_set(UiText *text, const char* value) {
+    if (text->value.ptr) {
+        text->value.free(text->value.ptr);
+    }
+
+    text->value.ptr = _strdup(value);
+    text->value.free = free;
+
+    int len;
+    wchar_t* wstr = str2wstr(value, &len);
+    std::wstring s(wstr);
+    free(wstr);
+
+    return s;
+}
 
 extern "C" char* ui_textarea_get(UiText *text) {
-    return NULL;
+    UiWidget* widget = (UiWidget*)text->obj;
+    TextBox box = widget->uielement.as<TextBox>();
+    std::wstring wstr(box.Text());
+    return ui_wtext_get(text, wstr);
 }
 
 extern "C" void  ui_textarea_set(UiText *text, const char *newvalue) {
-
+    UiWidget* widget = (UiWidget*)text->obj;
+    TextBox box = widget->uielement.as<TextBox>();
+    box.Text(ui_wtext_set(text, newvalue));
 }
 
 extern "C" char* ui_textarea_getsubstr(UiText *text, int begin, int end) {
--- a/ui/winui/text.h	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/winui/text.h	Tue Nov 12 14:58:03 2024 +0100
@@ -60,6 +60,9 @@
     void* ondropdata;
 };
 
+char* ui_wtext_get(UiText *text, std::wstring &value);
+std::wstring ui_wtext_set(UiText *text, const char* value);
+
 char* ui_wstring_get(UiString* str, std::wstring& value);
 std::wstring ui_wstring_set(UiString* str, const char* value);
 
--- a/ui/winui/toolkit.cpp	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/winui/toolkit.cpp	Tue Nov 12 14:58:03 2024 +0100
@@ -36,6 +36,7 @@
 #include "../common/context.h"
 #include "../common/document.h"
 #include "../common/toolbar.h"
+#include "../common/properties.h"
 
 #include "icons.h"
 
@@ -166,6 +167,8 @@
 	uic_init_global_context();
 	uic_docmgr_init();
 	uic_toolbar_init();
+	
+	uic_load_app_properties();
 }
 
 const char* ui_appname() {
@@ -229,8 +232,8 @@
 void ui_show(UiObject* obj) {
 	if (obj->wobj) {
 		obj->wobj->window.Activate();
-	} else {
-		// TODO
+	} else if(obj->widget && obj->widget->Show) {
+		obj->widget->Show();
 	}
 }
 
--- a/ui/winui/window.cpp	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/winui/window.cpp	Tue Nov 12 14:58:03 2024 +0100
@@ -35,6 +35,7 @@
 #include "commandbar.h"
 #include "container.h"
 #include "util.h"
+#include "button.h"
 
 #include "../common/context.h"
 #include "../common/object.h"
@@ -201,8 +202,168 @@
 	return obj;
 }
 
+static void dialog_button_add_callback(ContentDialog dialog, Button button, int num, UiObject *obj, ui_callback onclick, void *onclickdata) {
+	button.Click([dialog, num, obj, onclick, onclickdata](IInspectable const& sender, RoutedEventArgs) {
+		if (onclick) {
+			UiEvent evt;
+			evt.obj = obj;
+			evt.window = obj->window;
+			evt.document = obj->ctx->document;
+			evt.eventdata = nullptr;
+			evt.intval = num;
+			onclick(&evt, onclickdata);
+		}
+		dialog.Hide();
+	});
+}
+
 UIEXPORT UiObject* ui_dialog_window_create(UiObject *parent, UiDialogWindowArgs args) {
-	return NULL;
+	UiWindow *window = parent->wobj;
+	if (!window) {
+		return NULL;
+	}
+	
+	CxMempool* mp = cxBasicMempoolCreate(256);
+	UiObject* obj = (UiObject*)cxCalloc(mp->allocator, 1, sizeof(UiObject));
+	
+	obj->ctx = uic_context(obj, mp);
+	
+	ContentDialog dialog = ContentDialog();
+	UIElement elm = dialog;
+	UiWidget* widget = new UiWidget(elm);
+	ui_context_add_widget_destructor(obj->ctx, widget);
+	obj->widget = widget;
+
+	if (args.title) {
+		wchar_t* wtitle = str2wstr(args.title, nullptr);
+		dialog.Title(box_value(wtitle));
+		free(wtitle);
+	}
+
+	
+	Grid dialogContent = Grid();
+	GridLength gl;
+
+	// content row
+	gl.Value = 1;
+	gl.GridUnitType = GridUnitType::Star;
+	RowDefinition rowdef0 = RowDefinition();
+	rowdef0.Height(gl);
+	dialogContent.RowDefinitions().Append(rowdef0);
+
+	// button row
+	gl.Value = 0;
+	gl.GridUnitType = GridUnitType::Auto;
+	RowDefinition rowdef1 = RowDefinition();
+	rowdef1.Height(gl);
+	dialogContent.RowDefinitions().Append(rowdef1);
+
+	// coldef
+	gl.Value = 1;
+	gl.GridUnitType = GridUnitType::Star;
+	ColumnDefinition coldef = ColumnDefinition();
+	coldef.Width(gl);
+	dialogContent.ColumnDefinitions().Append(coldef);
+
+	// content
+	Grid grid = Grid();
+	grid.SetRow(grid, 0);
+	grid.SetColumn(grid, 0);
+	dialogContent.Children().Append(grid);
+	obj->container = new UiBoxContainer(grid, UI_BOX_CONTAINER_VBOX, 0, 0);
+
+	// buttons
+	Grid buttons = Grid();
+	Thickness btnsMargin = { (double)0, (double)10, (double)0, (double)0 };
+	buttons.Margin(btnsMargin);
+
+	RowDefinition btnrowdef = RowDefinition();
+	gl.Value = 0;
+	gl.GridUnitType = GridUnitType::Auto;
+	btnrowdef.Height(gl);
+	buttons.RowDefinitions().Append(btnrowdef);
+
+	gl.Value = 1;
+	gl.GridUnitType = GridUnitType::Auto;
+	int c = 0;
+	if (args.lbutton1) {
+		ColumnDefinition bcoldef = ColumnDefinition();
+		bcoldef.Width(gl);
+		buttons.ColumnDefinitions().Append(bcoldef);
+
+		Button btn = Button();
+		ui_set_button_label(btn, args.lbutton1, NULL, NULL, UI_LABEL_TEXT);
+		Thickness margin = { (double)5, (double)5, (double)5, (double)5 };
+		btn.Margin(margin);
+		btn.HorizontalAlignment(HorizontalAlignment::Stretch);
+		dialog_button_add_callback(dialog, btn, 1, obj, args.onclick, args.onclickdata);
+
+		buttons.SetRow(btn, 0);
+		buttons.SetColumn(btn, c++);
+		buttons.Children().Append(btn);
+	}
+	if (args.lbutton2) {
+		ColumnDefinition bcoldef = ColumnDefinition();
+		bcoldef.Width(gl);
+		buttons.ColumnDefinitions().Append(bcoldef);
+
+		Button btn = Button();
+		ui_set_button_label(btn, args.lbutton2, NULL, NULL, UI_LABEL_TEXT);
+		Thickness margin = { (double)5, (double)5, (double)5, (double)5 };
+		btn.Margin(margin);
+		btn.HorizontalAlignment(HorizontalAlignment::Stretch);
+		dialog_button_add_callback(dialog, btn, 2, obj, args.onclick, args.onclickdata);
+
+		buttons.SetRow(btn, 0);
+		buttons.SetColumn(btn, c++);
+		buttons.Children().Append(btn);
+	}
+	if (args.rbutton3) {
+		ColumnDefinition bcoldef = ColumnDefinition();
+		bcoldef.Width(gl);
+		buttons.ColumnDefinitions().Append(bcoldef);
+
+		Button btn = Button();
+		ui_set_button_label(btn, args.rbutton3, NULL, NULL, UI_LABEL_TEXT);
+		Thickness margin = { (double)5, (double)5, (double)5, (double)5 };
+		btn.Margin(margin);
+		btn.HorizontalAlignment(HorizontalAlignment::Stretch);
+		dialog_button_add_callback(dialog, btn, 3, obj, args.onclick, args.onclickdata);
+
+		buttons.SetRow(btn, 0);
+		buttons.SetColumn(btn, c++);
+		buttons.Children().Append(btn);
+	}
+	if (args.rbutton4) {
+		ColumnDefinition bcoldef = ColumnDefinition();
+		bcoldef.Width(gl);
+		buttons.ColumnDefinitions().Append(bcoldef);
+
+		Button btn = Button();
+		ui_set_button_label(btn, args.rbutton4, NULL, NULL, UI_LABEL_TEXT);
+		Thickness margin = { (double)5, (double)5, (double)5, (double)5 };
+		btn.Margin(margin);
+		btn.HorizontalAlignment(HorizontalAlignment::Stretch);
+		dialog_button_add_callback(dialog, btn, 4, obj, args.onclick, args.onclickdata);
+
+		buttons.SetRow(btn, 0);
+		buttons.SetColumn(btn, c++);
+		buttons.Children().Append(btn);
+	}
+
+	dialogContent.SetRow(buttons, 1);
+	dialogContent.SetColumn(buttons, 0);
+	dialogContent.Children().Append(buttons);
+
+
+	dialog.Content(dialogContent);
+	dialog.XamlRoot(window->window.Content().XamlRoot());
+
+	obj->widget->Show = [dialog]() {
+		dialog.ShowAsync();
+	};
+
+	return obj;
 }
 
 void ui_window_size(UiObject *obj, int width, int height) {
--- a/ui/winui/winui.vcxproj	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/winui/winui.vcxproj	Tue Nov 12 14:58:03 2024 +0100
@@ -88,8 +88,9 @@
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
     <ClCompile>
-      <PreprocessorDefinitions>_DEBUG;DISABLE_XAML_GENERATED_MAIN__;UI_WINUI;UI_WINUI_PCH;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;DISABLE_XAML_GENERATED_MAIN__;UI_WINUI;UI_WINUI_PCH;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\ucx;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <LanguageStandard_C Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">stdc17</LanguageStandard_C>
     </ClCompile>
     <Link>
       <AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">shell32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -113,6 +114,14 @@
     <Manifest Include="app.manifest" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="..\common\context.h" />
+    <ClInclude Include="..\common\document.h" />
+    <ClInclude Include="..\common\menu.h" />
+    <ClInclude Include="..\common\object.h" />
+    <ClInclude Include="..\common\properties.h" />
+    <ClInclude Include="..\common\toolbar.h" />
+    <ClInclude Include="..\common\types.h" />
+    <ClInclude Include="..\common\ucx_properties.h" />
     <ClInclude Include="..\ui\button.h" />
     <ClInclude Include="..\ui\container.h" />
     <ClInclude Include="..\ui\display.h" />
@@ -160,6 +169,30 @@
     <Page Include="MainWindow.xaml" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\common\context.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\common\document.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\common\menu.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\common\object.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\common\properties.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\common\toolbar.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\common\types.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\common\ucx_properties.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
     <ClCompile Include="appmenu.cpp" />
     <ClCompile Include="button.cpp" />
     <ClCompile Include="commandbar.cpp" />
@@ -226,9 +259,6 @@
     <ProjectReference Include="..\..\make\vs\ucx\ucx.vcxproj">
       <Project>{27da0164-3475-43e2-a1a4-a5d07d305749}</Project>
     </ProjectReference>
-    <ProjectReference Include="..\..\make\vs\uicommon\uicommon.vcxproj">
-      <Project>{8b88698e-c185-4383-99fe-0c34d6deed2e}</Project>
-    </ProjectReference>
   </ItemGroup>
   <!--
     Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
--- a/ui/winui/winui.vcxproj.filters	Sun Nov 10 15:27:44 2024 +0100
+++ b/ui/winui/winui.vcxproj.filters	Tue Nov 12 14:58:03 2024 +0100
@@ -29,6 +29,30 @@
     <ClCompile Include="dnd.cpp" />
     <ClCompile Include="condvar.cpp" />
     <ClCompile Include="image.cpp" />
+    <ClCompile Include="..\common\context.c">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\common\document.c">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\common\menu.c">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\common\object.c">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\common\properties.c">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\common\toolbar.c">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\common\types.c">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\common\ucx_properties.c">
+      <Filter>common</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="pch.h" />
@@ -102,6 +126,30 @@
     <ClInclude Include="..\ui\icons.h">
       <Filter>public</Filter>
     </ClInclude>
+    <ClInclude Include="..\common\context.h">
+      <Filter>common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\common\document.h">
+      <Filter>common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\common\menu.h">
+      <Filter>common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\common\object.h">
+      <Filter>common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\common\properties.h">
+      <Filter>common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\common\toolbar.h">
+      <Filter>common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\common\types.h">
+      <Filter>common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\common\ucx_properties.h">
+      <Filter>common</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Image Include="Assets\Wide310x150Logo.scale-200.png">
@@ -133,6 +181,9 @@
     <Filter Include="public">
       <UniqueIdentifier>{2b58fe46-d27b-4335-b63c-13ec2204fa24}</UniqueIdentifier>
     </Filter>
+    <Filter Include="common">
+      <UniqueIdentifier>{35c88d5c-b36f-41b3-86c0-784227845ae9}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <Text Include="readme.txt" />

mercurial