added menus (WPF)

Sun, 25 Jan 2015 15:01:04 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 25 Jan 2015 15:01:04 +0100
changeset 81
5eb765a7a793
parent 80
40be5c189e2e
child 82
0cdb8089a29f

added menus (WPF)

application/main.c file | annotate | diff | comparison | revisions
config.mk file | annotate | diff | comparison | revisions
ui/wpf/UIcore/Application.cs file | annotate | diff | comparison | revisions
ui/wpf/UIcore/Menu.cs file | annotate | diff | comparison | revisions
ui/wpf/UIcore/UIcore.csproj file | annotate | diff | comparison | revisions
ui/wpf/UIcore/Window.cs file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper.sln file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper.v12.suo file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper/UIwrapper.vcxproj file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper/UIwrapper.vcxproj.filters file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper/UIwrapper.vcxproj.user file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper/menu.cpp file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper/menu.h file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper/toolkit.cpp file | annotate | diff | comparison | revisions
ui/wpf/UIwrapper/UIwrapper/toolkit.h file | annotate | diff | comparison | revisions
ui/wpf/menu.c file | annotate | diff | comparison | revisions
ui/wpf/menu.h file | annotate | diff | comparison | revisions
ui/wpf/objs.mk file | annotate | diff | comparison | revisions
--- a/application/main.c	Sat Jan 24 19:17:35 2015 +0100
+++ b/application/main.c	Sun Jan 25 15:01:04 2015 +0100
@@ -95,6 +95,9 @@
 int main(int argc, char** argv) { 
     ui_init("app1", argc, argv);
     
+    ui_menu("File");
+    ui_menuitem("Hello", NULL, NULL);
+    
     UiObject *obj = ui_window("Test", NULL);
     ui_show(obj);
     ui_main();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.mk	Sun Jan 25 15:01:04 2015 +0100
@@ -0,0 +1,17 @@
+#
+# config.mk generated by configure
+#
+
+PREFIX = /opt/mk12
+
+include $(BUILD_ROOT)/make/mingw.mk
+
+
+# toolkit configuration
+CFLAGS += -DUI_WPF 
+
+LDFLAGS += $(BUILD_ROOT)/build/UIwrapper/UIwrapper.lib
+LDFLAGS += -mwindows
+
+TOOLKIT = wpf
+
--- a/ui/wpf/UIcore/Application.cs	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/UIcore/Application.cs	Sun Jan 25 15:01:04 2015 +0100
@@ -4,6 +4,7 @@
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
+using System.Windows;
 
 namespace UI
 {  
@@ -17,9 +18,11 @@
         private Queue<Action> queue = new Queue<Action>();
         private object sync = new object();
         private object result = new object();
+        private Boolean main = false;
 
-        private Boolean Running = false;
         public String Name;
+        public List<Window> Windows = new List<Window>();
+        public ApplicationMenu AppMenu = new ApplicationMenu();
         
         private Application() : base()
         {
@@ -51,6 +54,7 @@
         private void RunApplication()
         {
             application = new System.Windows.Application();
+            main = true;
             application.Run();
         }
 
@@ -67,6 +71,11 @@
                     {
                         Monitor.Pulse(result);
                     }
+                    if (main)
+                    {
+                        // end loop after shutdown
+                        break;
+                    }
                 }
             }
         }
@@ -116,6 +125,20 @@
                 }
             }
         }
+
+        public void AddWindow(Window window)
+        {
+            Windows.Add(window);
+        }
+
+        public void RemoveWindow(Window window)
+        {
+            Windows.Remove(window);
+            if (Windows.Count == 0)
+            {
+                application.Shutdown();
+            }
+        }
     }
 
     public class ResultExec<T>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/wpf/UIcore/Menu.cs	Sun Jan 25 15:01:04 2015 +0100
@@ -0,0 +1,115 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace UI
+{
+    public class ApplicationMenu
+    {
+        private List<Menu> current = new List<Menu>();
+
+        public List<Menu> Menus = new List<Menu>();
+
+        public void AddMenu(String label)
+        {
+            current.Clear();
+            Menu menu = new Menu(label);
+            current.Add(menu);
+            Menus.Add(menu);
+        }
+
+        public Boolean IsEmpty()
+        {
+            return Menus.Count == 0 ? true : false;
+        }
+
+        public void AddSubMenu(String label)
+        {
+            Menu menu = new Menu(label);
+            current.Last().Items.Add(menu);
+            current.Add(menu);
+        }
+
+        public void EndMenu()
+        {
+            current.Remove(current.Last());
+        }
+
+        public void AddMenuItem(String label, Action action)
+        {
+            if(current.Count != 0)
+            {
+                MenuItem item = new MenuItem(label, action);
+                current.Last().Items.Add(item);
+            }
+        }
+
+        public System.Windows.Controls.Menu CreateMenu()
+        {
+            System.Windows.Controls.Menu menu = new System.Windows.Controls.Menu();
+            foreach (Menu m in Menus)
+            {
+                System.Windows.Controls.MenuItem i = new System.Windows.Controls.MenuItem();
+                i.Header = m.Label;
+                m.AddItems(i);
+                menu.Items.Add(i);
+            }
+            return menu;
+        }
+    }
+
+    public interface IMenuItem
+    {
+        void AddTo(System.Windows.Controls.MenuItem menu);
+    }
+
+    public class Menu : IMenuItem
+    {
+        public String Label;
+        public List<IMenuItem> Items = new List<IMenuItem>();
+
+        public Menu(String label)
+        {
+            Label = label;
+        }
+
+        public void AddItems(System.Windows.Controls.MenuItem i)
+        {
+            foreach (IMenuItem item in Items)
+            {
+                item.AddTo(i);
+            }
+        }
+
+        void IMenuItem.AddTo(System.Windows.Controls.MenuItem menu)
+        {
+            System.Windows.Controls.MenuItem i = new System.Windows.Controls.MenuItem();
+            i.Header = Label;
+            AddItems(i);
+            menu.Items.Add(i);
+        }
+    }
+
+    public class MenuItem : IMenuItem
+    {
+        String Label;
+        Action Action;
+
+        public MenuItem(String label, Action action)
+        {
+            Label = label;
+            Action = action;
+        }
+
+        void IMenuItem.AddTo(System.Windows.Controls.MenuItem menu)
+        {
+            System.Windows.Controls.MenuItem i = new System.Windows.Controls.MenuItem();
+            i.Header = Label;
+            menu.Items.Add(i);
+        }
+    }
+}
--- a/ui/wpf/UIcore/UIcore.csproj	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/UIcore/UIcore.csproj	Sun Jan 25 15:01:04 2015 +0100
@@ -25,7 +25,7 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
+    <OutputPath>..\..\..\build\UIcore\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
@@ -46,6 +46,7 @@
     <Reference Include="WindowsBase" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Menu.cs" />
     <Compile Include="Toolkit.cs" />
     <Compile Include="Window.cs" />
     <Compile Include="Application.cs" />
--- a/ui/wpf/UIcore/Window.cs	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/UIcore/Window.cs	Sun Jan 25 15:01:04 2015 +0100
@@ -10,15 +10,23 @@
 namespace UI
 {
     public class MainWindow : Window
-    {
-        private Label label1;
-        
+    { 
         public MainWindow(String title)
         {
             Title = title;
             Width = 300;
             Height = 300;
-            GC.KeepAlive(this); // remove KeepAlive and add the Window to the application
+
+            // menu
+            Application app = Application.GetInstance();
+            if (!app.AppMenu.IsEmpty())
+            {
+                System.Windows.Controls.Menu menu = app.AppMenu.CreateMenu();
+                this.AddChild(menu);
+            }
+
+            GC.KeepAlive(this); // TODO: remove KeepAlive and add the Window to the application
+            Closed += CloseEvent;
         }
 
         public static MainWindow CreateMainWindow(String title)
@@ -29,6 +37,12 @@
         public void ShowWindow()
         {
             Application.GetInstance().Exec(() => this.Show());
+            Application.GetInstance().AddWindow(this);
+        }
+
+        public void CloseEvent(object sender, System.EventArgs e)
+        {
+            Application.GetInstance().RemoveWindow(this);
         }
     }
 }
--- a/ui/wpf/UIwrapper/UIwrapper.sln	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/UIwrapper/UIwrapper.sln	Sun Jan 25 15:01:04 2015 +0100
@@ -49,6 +49,7 @@
 		{8573F7D8-F05F-4195-9005-1C219B976146}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 		{8573F7D8-F05F-4195-9005-1C219B976146}.Release|Win32.ActiveCfg = Release|Any CPU
 		{8573F7D8-F05F-4195-9005-1C219B976146}.Release|x64.ActiveCfg = Release|Any CPU
+		{8573F7D8-F05F-4195-9005-1C219B976146}.Release|x64.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
Binary file ui/wpf/UIwrapper/UIwrapper.v12.suo has changed
--- a/ui/wpf/UIwrapper/UIwrapper/UIwrapper.vcxproj	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/UIwrapper/UIwrapper/UIwrapper.vcxproj	Sun Jan 25 15:01:04 2015 +0100
@@ -82,6 +82,8 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)..\..\..\build\UIwrapper\</OutDir>
+    <IntDir>$(SolutionDir)..\..\..\build\UIwrapper\$(Configuration)\</IntDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -128,6 +130,8 @@
       <WarningLevel>Level3</WarningLevel>
       <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeader>Use</PrecompiledHeader>
+      <AdditionalUsingDirectories>$(SolutionDir)..\..\..\build\UIcore\;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <DebugInformationFormat>None</DebugInformationFormat>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
@@ -147,6 +151,7 @@
     <Reference Include="WindowsBase" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="menu.h" />
     <ClInclude Include="resource.h" />
     <ClInclude Include="Stdafx.h" />
     <ClInclude Include="toolkit.h" />
@@ -154,6 +159,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="AssemblyInfo.cpp" />
+    <ClCompile Include="menu.cpp" />
     <ClCompile Include="window.cpp" />
     <ClCompile Include="Stdafx.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
--- a/ui/wpf/UIwrapper/UIwrapper/UIwrapper.vcxproj.filters	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/UIwrapper/UIwrapper/UIwrapper.vcxproj.filters	Sun Jan 25 15:01:04 2015 +0100
@@ -27,6 +27,9 @@
     <ClInclude Include="window.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
+    <ClInclude Include="menu.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="AssemblyInfo.cpp">
@@ -41,6 +44,9 @@
     <ClCompile Include="toolkit.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="menu.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Text Include="ReadMe.txt" />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/wpf/UIwrapper/UIwrapper/UIwrapper.vcxproj.user	Sun Jan 25 15:01:04 2015 +0100
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/wpf/UIwrapper/UIwrapper/menu.cpp	Sun Jan 25 15:01:04 2015 +0100
@@ -0,0 +1,17 @@
+
+#include "stdafx.h"
+#include <stdio.h>
+
+#include "menu.h"
+
+#using "UIcore.dll"
+
+UI_EXPORT void __stdcall UImenu(char *label) {
+	UI::Application::GetInstance()->AppMenu->AddMenu(gcnew String(label));
+}
+
+
+UI_EXPORT void __stdcall UImenuitem(char *label, UIcallback f, void *userdata) {
+	EventWrapper ^e = gcnew EventWrapper(f, userdata);
+	UI::Application::GetInstance()->AppMenu->AddMenuItem(gcnew String(label), e->GetAction());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/wpf/UIwrapper/UIwrapper/menu.h	Sun Jan 25 15:01:04 2015 +0100
@@ -0,0 +1,4 @@
+
+#pragma once
+
+#include "toolkit.h"
\ No newline at end of file
--- a/ui/wpf/UIwrapper/UIwrapper/toolkit.cpp	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/UIwrapper/UIwrapper/toolkit.cpp	Sun Jan 25 15:01:04 2015 +0100
@@ -21,6 +21,21 @@
 	return object;
 }
 
+// EventWrapper
+
+EventWrapper::EventWrapper(UIcallback callback, void *userdata) {
+	this->callback = callback;
+	this->userdata = userdata;
+	action = gcnew Action(this, &EventWrapper::Callback);
+}
+
+Action^ EventWrapper::GetAction() {
+	return action;
+}
+
+void EventWrapper::Callback() {
+	callback(NULL, NULL);
+}
 
 UI_EXPORT void __stdcall UIinit(char *appname) {
 	UI::Application ^app = UI::Application::GetInstance();
--- a/ui/wpf/UIwrapper/UIwrapper/toolkit.h	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/UIwrapper/UIwrapper/toolkit.h	Sun Jan 25 15:01:04 2015 +0100
@@ -10,4 +10,19 @@
 
 #define UI_EXPORT extern "C" __declspec(dllexport)
 
+extern "C" typedef void(*UIcallback)(void*, void*);
+
 void* ObjectToPtr(Object ^obj);
+
+public ref class EventWrapper {
+	UIcallback callback = NULL;
+	void *userdata = NULL;
+	Action ^action;
+
+public:
+	EventWrapper(UIcallback callback, void *userdata);
+
+	Action^ GetAction();
+
+	void Callback();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/wpf/menu.c	Sun Jan 25 15:01:04 2015 +0100
@@ -0,0 +1,49 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2014 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "menu.h"
+
+void ui_menu(char *label) {
+    UImenu(label);
+}
+
+void ui_submenu(char *label) {
+    
+}
+
+void ui_submenu_end() {
+    
+}
+
+void ui_menuitem(char *label, ui_callback f, void *userdata) {
+    UImenuitem(label, f, userdata);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/wpf/menu.h	Sun Jan 25 15:01:04 2015 +0100
@@ -0,0 +1,28 @@
+/* 
+ * File:   menu.h
+ * Author: Olaf
+ *
+ * Created on 25. Januar 2015, 13:37
+ */
+
+#ifndef MENU_H
+#define	MENU_H
+
+#include "../ui/menu.h"
+#include "toolkit.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+UI_IMPORT void __stdcall UImenu(char *label);
+
+UI_IMPORT void __stdcall UImenuitem(char *label, ui_callback f, void *udata);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* MENU_H */
+
--- a/ui/wpf/objs.mk	Sat Jan 24 19:17:35 2015 +0100
+++ b/ui/wpf/objs.mk	Sun Jan 25 15:01:04 2015 +0100
@@ -31,6 +31,7 @@
 
 WPFOBJ = toolkit.o
 WPFOBJ += window.o
+WPFOBJ += menu.o
 
 TOOLKITOBJS += $(WPFOBJ:%=$(WPF_OBJPRE)%)
 TOOLKITSOURCE += $(WPFOBJ:%.o=wpf/%.c)

mercurial