应用框架
尽管noesisGUI可以完全集成到您的应用程序中,但是如集成教程中所示,还提供了一个Application Framework。该框架是一个开放源代码库,提供了用于创建多平台应用程序的抽象。该框架是有关如何使用Noesis的一个很好的示例,它提供了许多有用的帮助程序。我们所有的开放示例都使用该应用程序框架。
提供的扩展(例如Application和Window)与WPF兼容,因此与Microsoft Blend兼容。使用应用程序框架,您可以设计将在Windows窗口,macOS窗口,iPhone屏幕或Xbox TV中兼容运行的应用程序。该框架支持NoesisGUI可用的所有平台。
spacer.png以下是应用程序框架公开的功能列表:
注意
Application Framework提供了我们的示例和教程所需的功能。永远不要将其用作“生产就绪”库。客户应将代码作为起点,必须针对每种特定情况进行适配和调整。
头文件和命名空间
应用程序框架的头文件包含在NsApp和NsRender模块中。该API在NoesisApp命名空间中公开。
#include <NsApp/EntryPoint.h>
#include <NsApp/Application.h>
#include <NsApp/ApplicationLauncher.h>
#include <NsApp/Window.h>
#include <NsApp/EmbeddedXamlProvider.h>
#include <NsApp/EmbeddedFontProvider.h>
using namespace Noesis;
using namespace NoesisApp;
注意
请注意,框架头文件不在标准NoesisGUI的内部,也不包含“ Noesis_pch.h”预编译头文件。
入口点
由于main()并非在所有平台上都可用,因此该框架提供了一个可移植的入口点NsMain。通常,您将在此处创建一个Launcher,对其进行配置并对其进行Run()。
int NsMain(int argc, char **argv)
{
AppLauncher launcher;
launcher.SetArguments(argc, argv);
launcher.SetApplicationFile("App.xaml");
return launcher.Run();
}
启动器(Launcher)
该启动器是你创建的第一个实例。它负责应用程序初始化和主消息循环。它还提供了一些重要的可重写功能:
- RegisterComponents:用于在组件工厂中注册类。需要在XAML实例化的每个扩展类都需要在此处注册,如扩展NoesisGUI教程中所述。对于框架,您至少需要注册Application和Window类。
- GetXamlProvider,GetFontProvider和GetTextureProvider:用于自定义如何加载资源。您可以按照“ 自定义资源加载”教程中的说明安装XAML,字体和纹理的自定义处理程序。
class AppLauncher final: public ApplicationLauncher
{
private:
void RegisterComponents() const override
{
NsRegisterComponent<RssReader::App>();
NsRegisterComponent<RssReader::MainWindow>();
}
Ptr<XamlProvider> GetXamlProvider() const override
{
EmbeddedXaml xamls[] =
{
{ "App.xaml", App_xaml, sizeof(App_xaml) },
{ "MainWindow.xaml", MainWindow_xaml, sizeof(MainWindow_xaml) }
};
return *new EmbeddedXamlProvider(xamls, NS_COUNTOF(xamls));
}
Ptr<FontProvider> GetFontProvider() const override
{
EmbeddedFont fonts[] =
{
{ "", Roboto_Regular_ttf, sizeof(Roboto_Regular_ttf) },
{ "", Roboto_Bold_ttf, sizeof(Roboto_Bold_ttf) }
};
return *new EmbeddedFontProvider(fonts, NS_COUNTOF(fonts));
}
};
注意
在框架中找到的Embedded *系列资源提供程序使您可以将资源嵌入可执行文件中。每次编辑项目中包含的资源时,都会使用“ bin2h”将其自动转换为头文件,bin2h是随每个示例一起分发的工具。例如,每次您触摸“ Roboto-Regular.ttf”时,将自动重新生成“ Roboto-Regular.ttf.bin.h”。其余资源相同。
应用
应用Application类直接对应于WPF应用程序类。每个应用程序都提供从Application基类继承的自己的实现。
namespace RssReader
{
class App final: public Application
{
NS_IMPLEMENT_INLINE_REFLECTION(App, Application)
{
NsMeta<TypeId>("RssReader.App");
}
};
}
该应用程序的主要目的是提供全局资源字典并设置主窗口StartupUri。
应用程式
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
x:Class="RssReader.App">
<Application.Resources>
<SolidColorBrush x:Key="Background0" Color="#FF2F3F4F" />
<SolidColorBrush x:Key="Background1" Color="SlateGray" />
<SolidColorBrush x:Key="Foreground0" Color="White" />
<SolidColorBrush x:Key="Foreground1" Color="SkyBlue" />
<SolidColorBrush x:Key="Foreground2" Color="Black" />
<SolidColorBrush x:Key="Border" Color="LightSlateGray" />
<FontFamily x:Key="DefaultFont">./#Roboto</FontFamily>
</Application.Resources>
</Application>
窗口Window
该窗口Window类模仿WPF窗口类。它是一个在操作系统窗口内显示其内容的容器。诸如Title,ResizeMode,WindowStyle,Width和Height的公共属性控制本机窗口的外观。
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="NoesisGUI - RSS Reader" Width="487" Height="630" ResizeMode="NoResize"
Background="{StaticResource Background0}"
Foreground="{StaticResource Foreground0}"
FontFamily="{StaticResource DefaultFont}"
x:Class="RssReader.MainWindow">
<Viewbox>
<DockPanel Background="{StaticResource Background0}" LastChildFill="True"
KeyboardNavigation.TabNavigation="Contained"
KeyboardNavigation.DirectionalNavigation="Contained" Width="325" Height="420">
<TextBlock DockPanel.Dock="Top" Text="RSS Reader" FontSize="32" FontWeight="Bold"
TextAlignment="Center" Margin="0,10,0,0"/>
<Border DockPanel.Dock="Top" Background="{StaticResource Background1}"
BorderBrush="{StaticResource Border}" BorderThickness="1" CornerRadius="2"
Margin="10" Padding="15,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="URL: " VerticalAlignment="Center"/>
<TextBox x:Name="Address" Grid.Column="1" Text="http://www.metacritic.com/"/>
<Button x:Name="GoTo" Grid.Column="2" Content="Go" Click="OnGoToClicked" Margin="2,0,0,0"/>
</Grid>
</Border>
<Grid DockPanel.Dock="Bottom" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="BorderBrush" Value="{StaticResource Background1}"/>
</Style>
</Grid.Resources>
<Button x:Name="Prev" Grid.Column="0" Content="Prev" Click="OnPrevClicked"/>
<Button x:Name="Next" Grid.Column="1" Content="Next" Click="OnNextClicked"/>
</Grid>
<Border Background="{StaticResource Background1}" BorderBrush="{StaticResource Border}"
BorderThickness="1" CornerRadius="2" Margin="10,0" Padding="5">
<Grid x:Name="ContentPanel" Margin="10,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="EntryTitle" Grid.Row="0" FontSize="20" FontWeight="Bold"
Foreground="{StaticResource Foreground1}" TextAlignment="Center" Margin="0,5,0,5"/>
<ScrollViewer Grid.Row="1" Margin="0,10" Focusable="False"
HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<TextBlock x:Name="EntryDesc" TextWrapping="Wrap" Margin="10,0"
Foreground="{StaticResource Foreground2}" FontSize="14"/>
</ScrollViewer>
</Grid>
</Border>
</DockPanel>
</Viewbox>
</Window>
通常将窗口基类扩展为实现代码隐藏code-behind功能。
namespace RssReader
{
class MainWindow final: public Window
{
public:
MainWindow(): _index(0)
{
InitializeComponent();
_title = FindName<TextBlock>("EntryTitle");
_title->SetText(gTitles[0]);
_desc = FindName<TextBlock>("EntryDesc");
_desc->SetText(gBodies[0]);
}
private:
void InitializeComponent()
{
Noesis::GUI::LoadComponent(this, "MainWindow.xaml");
}
bool ConnectEvent(BaseComponent* source, const char* event, const char* handler) override
{
NS_CONNECT_EVENT(Button, Click, OnGoToClicked);
NS_CONNECT_EVENT(Button, Click, OnPrevClicked);
NS_CONNECT_EVENT(Button, Click, OnNextClicked);
return false;
}
void OnGoToClicked(BaseComponent* /*sender*/, const RoutedEventArgs& /*e*/)
{
}
void OnPrevClicked(BaseComponent* /*sender*/, const RoutedEventArgs& /*e*/)
{
_index = _index == 0 ? 2 : _index - 1;
_title->SetText(gTitles[_index]);
_desc->SetText(gBodies[_index]);
}
void OnNextClicked(BaseComponent* /*sender*/, const RoutedEventArgs& /*e*/)
{
_index = _index == 2 ? 0 : _index + 1;
_title->SetText(gTitles[_index]);
_desc->SetText(gBodies[_index]);
}
private:
int _index;
TextBlock* _title;
TextBlock* _desc;
NS_IMPLEMENT_INLINE_REFLECTION(MainWindow, Window)
{
NsMeta<TypeId>("RssReader.MainWindow");
}
};
}
命令行开关
使用应用程序框架创建的所有应用程序都支持以下命令行开关:
- --render [D3D11 | GL | Metal | ...]:覆盖默认渲染器。
- --vsync [0 | 1]:禁用垂直同步。
- --samples N:启用多重采样抗锯齿(MSAA),默认情况下处于关闭状态。
- --linear:用于切换到线性渲染,默认情况下,渲染发生在gamma空间中。
- --log_binding:使用数据绑定时增加日志记录的详细程度。
快捷键
以下快捷方式使调试功能可以检查应用程序的性能:
- CTRL + W:渲染三角形时切换线框模式。
- CTRL + B:提交给GPU的每个批处理都具有唯一的纯色。
- CTRL + O:使用混合图层显示像素覆盖。每种类型的三角形使用不同的颜色:绿色表示正常,红色表示不透明,蓝色表示剪贴蒙版。
- CTRL + P:每个基本抗锯齿拉伸几何图形的轮廓并将其平滑。未启用GPU多重采样时很有用。
- CTRL + F:显示性能统计信息面板。
网友评论