add basic winui menu implementation newapi

Tue, 23 May 2023 14:19:06 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 23 May 2023 14:19:06 +0200
branch
newapi
changeset 180
f34953bf4ac7
parent 179
34f4d78647be
child 181
c52d88ea020b

add basic winui menu implementation

make/vs/testapp/main.c file | annotate | diff | comparison | revisions
make/vs/ucx/ucx.vcxproj file | annotate | diff | comparison | revisions
ui/winui/appmenu.cpp file | annotate | diff | comparison | revisions
ui/winui/appmenu.h file | annotate | diff | comparison | revisions
ui/winui/util.cpp file | annotate | diff | comparison | revisions
ui/winui/util.h 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
ui/winui/winui.vcxproj.user file | annotate | diff | comparison | revisions
--- a/make/vs/testapp/main.c	Tue May 23 11:42:39 2023 +0200
+++ b/make/vs/testapp/main.c	Tue May 23 14:19:06 2023 +0200
@@ -47,6 +47,13 @@
     ui_init("app1", 0, NULL);
     ui_onstartup(application_startup, NULL);
 
+    ui_menu("File");
+    ui_menuitem("Test", NULL, NULL);
+    ui_submenu("Sub");
+    ui_menuitem("subitem", NULL, NULL);
+    ui_submenu_end();
+    ui_menuitem("Exit", NULL, NULL);
+
     ui_main();
 
     return (EXIT_SUCCESS);
--- a/make/vs/ucx/ucx.vcxproj	Tue May 23 11:42:39 2023 +0200
+++ b/make/vs/ucx/ucx.vcxproj	Tue May 23 14:19:06 2023 +0200
@@ -40,7 +40,7 @@
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <PlatformToolset>v143</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/winui/appmenu.cpp	Tue May 23 14:19:06 2023 +0200
@@ -0,0 +1,162 @@
+/*
+ * 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 "appmenu.h"
+
+#include <Windows.h>
+#undef GetCurrentTime
+#include <winrt/Windows.Foundation.Collections.h>
+#include <winrt/Windows.UI.Xaml.Interop.h>
+#include <winrt/Microsoft.UI.Xaml.Controls.h>
+#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
+#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
+#include <winrt/Microsoft.UI.Xaml.Markup.h>
+
+#include <cx/linked_list.h>
+#include <cx/array_list.h>
+
+#include "util.h"
+
+
+using namespace winrt;
+using namespace Microsoft::UI::Xaml;
+using namespace Microsoft::UI::Xaml::Controls;
+using namespace Microsoft::UI::Xaml::XamlTypeInfo;
+using namespace Microsoft::UI::Xaml::Markup;
+using namespace Windows::UI::Xaml::Interop;
+
+static void add_top_menu_widget(MenuBar &parent, int i, UiMenuItemI* item, UiObject* obj);
+
+static void add_menu_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj);
+static void add_menuitem_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj);
+static void add_menuitem_st_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj);
+static void add_menuseparator_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj);
+static void add_checkitem_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj);
+static void add_checkitemnv_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj);
+static void add_menuitem_list_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj);
+
+static ui_menu_add_f createMenuItem[] = {
+    /* UI_MENU                 */ add_menu_widget,
+    /* UI_MENU_SUBMENU         */ add_menu_widget,
+    /* UI_MENU_ITEM            */ add_menuitem_widget,
+    /* UI_MENU_STOCK_ITEM      */ add_menuitem_st_widget,
+    /* UI_MENU_CHECK_ITEM      */ add_checkitem_widget,
+    /* UI_MENU_CHECK_ITEM_NV   */ add_checkitemnv_widget,
+    /* UI_MENU_ITEM_LIST       */ add_menuitem_list_widget,
+    /* UI_MENU_ITEM_LIST_NV    */ NULL, // TODO
+    /* UI_MENU_SEPARATOR       */ add_menuseparator_widget
+};
+
+winrt::Microsoft::UI::Xaml::Controls::MenuBar ui_create_menubar(UiObject* obj) {
+	MenuBar mb = MenuBar();
+
+    UiMenu* menus_begin = uic_get_menu_list();
+
+    UiMenu* ls = menus_begin;
+    while (ls) {
+        UiMenu* menu = ls;
+        add_top_menu_widget(mb, 0, &menu->item, obj);
+
+        ls = (UiMenu*)ls->item.next;
+    }
+
+	return mb;
+}
+
+static void add_top_menu_widget(MenuBar& parent, int i, UiMenuItemI* item, UiObject* obj) {
+    UiMenu* menu = (UiMenu*)item;
+
+    MenuBarItem mi = MenuBarItem();
+    wchar_t* wlabel = str2wstr(menu->label, NULL);
+    mi.Title(wlabel);
+    free(wlabel);
+
+    UiMenuItemI* it = menu->items_begin;
+    int index = 0;
+    while (it) {
+        createMenuItem[it->type](mi.Items(), index, it, obj);
+
+        it = it->next;
+        index++;
+    }
+
+    parent.Items().Append(mi);
+}
+
+static void add_menu_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj) {
+    UiMenu* menu = (UiMenu*)item;
+
+    MenuFlyoutSubItem mi = MenuFlyoutSubItem();
+    wchar_t* wlabel = str2wstr(menu->label, NULL);
+    mi.Text(wlabel);
+    free(wlabel);
+
+    parent.Append(mi);
+
+    UiMenuItemI* it = menu->items_begin;
+    int index = 0;
+    while (it) {
+        createMenuItem[it->type](mi.Items(), index, it, obj);
+
+        it = it->next;
+        index++;
+    }
+
+    
+}
+
+static void add_menuitem_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj) {
+    UiMenuItem* it = (UiMenuItem*)item;
+    
+    MenuFlyoutItem mi = MenuFlyoutItem();
+    wchar_t* wlabel = str2wstr(it->label, NULL);
+    mi.Text(wlabel);
+    free(wlabel);
+
+    parent.Append(mi);
+}
+
+static void add_menuitem_st_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj) {
+
+}
+
+static void add_menuseparator_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj) {
+
+}
+
+static void add_checkitem_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj) {
+
+}
+
+static void add_checkitemnv_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj) {
+
+}
+
+static void add_menuitem_list_widget(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int i, UiMenuItemI* item, UiObject* obj) {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/winui/appmenu.h	Tue May 23 14:19:06 2023 +0200
@@ -0,0 +1,48 @@
+/*
+ * 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 "toolkit.h"
+#include "../common/menu.h"
+
+#include <Windows.h>
+#undef GetCurrentTime
+#include <winrt/Windows.Foundation.Collections.h>
+#include <winrt/Windows.UI.Xaml.Interop.h>
+#include <winrt/Microsoft.UI.Xaml.Controls.h>
+#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
+#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
+#include <winrt/Microsoft.UI.Xaml.Markup.h>
+
+
+
+typedef void(*ui_menu_add_f)(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::UI::Xaml::Controls::MenuFlyoutItemBase> parent, int, UiMenuItemI*, UiObject*);
+
+winrt::Microsoft::UI::Xaml::Controls::MenuBar ui_create_menubar(UiObject* obj);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/winui/util.cpp	Tue May 23 14:19:06 2023 +0200
@@ -0,0 +1,29 @@
+
+
+#include "util.h"
+
+#include <stdlib.h>
+
+#include <Windows.h>
+
+
+wchar_t* str2wstr(const char* str, int* newlen) {
+    size_t len = strlen(str);
+
+
+    wchar_t* wstr = (wchar_t*)calloc(len + 1, sizeof(wchar_t));
+    int wlen = MultiByteToWideChar(
+        CP_UTF8,
+        0,
+        str,
+        len,
+        wstr,
+        len + 1
+    );
+    if (newlen) {
+        *newlen = wlen;
+    }
+    wstr[wlen] = 0;
+
+    return wstr;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/winui/util.h	Tue May 23 14:19:06 2023 +0200
@@ -0,0 +1,3 @@
+#pragma once
+
+wchar_t* str2wstr(const char* str, int* newlen);
--- a/ui/winui/window.cpp	Tue May 23 11:42:39 2023 +0200
+++ b/ui/winui/window.cpp	Tue May 23 14:19:06 2023 +0200
@@ -37,6 +37,8 @@
 #include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
 #include <winrt/Microsoft.UI.Xaml.Markup.h>
 
+#include "appmenu.h"
+
 #include <stdlib.h>
 
 using namespace winrt;
@@ -49,8 +51,17 @@
 
 class UiWindow : UiWidget {
 public:
-	UiWindow(const char* title) {
+	UiWindow(const char* title, UiObject *obj) {
 		window = Window();
+
+		grid = Grid();
+		window.Content(grid);
+
+		if (uic_get_menu_list()) {
+			MenuBar mb = ui_create_menubar(obj);
+			mb.VerticalAlignment(VerticalAlignment::Top);
+			grid.Children().Append(mb);
+		}
 	}
 
 	virtual void show() {
@@ -58,12 +69,13 @@
 	}
 
 	Window window{ nullptr };
+	Grid grid;
 };
 
 UiObject* ui_window(const char* title, void* window_data) {
 	UiObject* obj = (UiObject*)malloc(sizeof(UiObject));
 
-	UiWindow* window = new UiWindow(title);
+	UiWindow* window = new UiWindow(title, obj);
 	obj->widget = window;
 
 	return obj;
--- a/ui/winui/winui.vcxproj	Tue May 23 11:42:39 2023 +0200
+++ b/ui/winui/winui.vcxproj	Tue May 23 14:19:06 2023 +0200
@@ -148,7 +148,9 @@
     <ClCompile Include="..\common\properties.c" />
     <ClCompile Include="..\common\types.c" />
     <ClCompile Include="..\common\ucx_properties.c" />
+    <ClCompile Include="appmenu.cpp" />
     <ClCompile Include="toolkit.cpp" />
+    <ClCompile Include="util.cpp" />
     <ClCompile Include="window.cpp" />
   </ItemGroup>
   <ItemGroup>
@@ -162,7 +164,9 @@
     <ClInclude Include="..\common\properties.h" />
     <ClInclude Include="..\common\types.h" />
     <ClInclude Include="..\common\ucx_properties.h" />
+    <ClInclude Include="appmenu.h" />
     <ClInclude Include="toolkit.h" />
+    <ClInclude Include="util.h" />
     <ClInclude Include="window.h" />
   </ItemGroup>
   <ItemGroup>
--- a/ui/winui/winui.vcxproj.filters	Tue May 23 11:42:39 2023 +0200
+++ b/ui/winui/winui.vcxproj.filters	Tue May 23 14:19:06 2023 +0200
@@ -48,6 +48,12 @@
     <ClCompile Include="..\common\ucx_properties.c">
       <Filter>Quelldateien\common</Filter>
     </ClCompile>
+    <ClCompile Include="appmenu.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="util.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
@@ -80,5 +86,11 @@
     <ClInclude Include="..\common\ucx_properties.h">
       <Filter>Headerdateien\common</Filter>
     </ClInclude>
+    <ClInclude Include="appmenu.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="util.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/winui/winui.vcxproj.user	Tue May 23 14:19:06 2023 +0200
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file

mercurial