Commit Inicial

This commit is contained in:
Thulio Bittencourt 2020-07-17 11:02:05 -03:00
parent 1908af67b8
commit 805f109609
53 changed files with 10096 additions and 0 deletions

223
README.md
View File

@ -1,2 +1,225 @@
# Router4Delphi
Framework para Criação de Rotas de Telas para FMX
O Router4Delphi tem o objetivo de facilitar a chamada de telas e embed de Layouts em aplicações FMX, reduzindo o acoplamento das telas de dando mais dinâmismo e práticidade na construção de interfaces ricas em Delphi
## Instalação
Basta registrar no Library Path do seu Delphi o caminho da pasta SRC da Biblioteca
## Primeiros Passos
Para utilizar o Router4Delphi para criar suas rotas, você deve realizar a uses do Router4D.
## Criação de uma Tela para Roteamento
Para que o sistema de Rotas funcione você deve criar um novo formulário FMX e Implementar a Interface iRouter4DComponent ela pertence a unit Router4D.Interfaces portanto a mesma deve ser incluida nas suas Units.
Toda a construção das telas baseadas em rotas utilizar TLayouts para embedar as chamadas das telas, dessa forma é preciso que sua nova tela tenha um TLayout principal e todos os demais componentes devem ser incluídos dentro desse layout.
A Implementação da Interface iRouter4DComponent requer a declaração de dois métodos ( Render e UnRender ), o Render é chamado sempre que uma rota aciona a tela, e o UnRender sempre que ela saí de exibição.
Abaixo o Código de uma tela simples implementando a interface iRouter4DComponent e pronta para ser utilizada.
Crie um Novo Formulario na sua Aplicação, inclua nele um Layout alinhado AlClient e implemente os métodos como abaixo.
```delphi
unit PrimeiraTela;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
Router4D.Interfaces;
type
TPrimeiraTela = class(TForm, iRouter4DComponent)
Layout1: TLayout;
private
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
procedure UnRender;
end;
var
PrimeiraTela: TPrimeiraTela;
implementation
{$R *.fmx}
{ TForm3 }
function TPrimeiraTela.Render: TFMXObject;
begin
Result := Layout1;
end;
procedure TPrimeiraTela.UnRender;
begin
end;
end.
```
Perceba que no método Render nós definimos como Result o Layout1, isso é necessário pois esse layout será embedado sempre que a rota for acionada.
## Registrando a Rota para a Tela
Agora que já temos uma tela pronta para ser registrada vamos ao processo que deixará a nossa tela pronta para ser acionada a qualquer momento.
Para registrar uma rota é necessário declarar a Uses Router4D ela fornece acesso a todos os métodos da biblioteca e em muito dos casos será o único acoplamento necessário nas suas Views.
Uma vez declarada basta acionar o método abaixo para declarar o form que criamos anteriormente como uma rota.
No formPrincipal da sua Aplicação, dentro do método onCreate execute o método abaixo para registrar a Rota para o Form TPrimeiraTela
```delphi
procedure TformPrincipal.FormCreate(Sender: TObject);
begin
TRouter4D.Switch.Router('Inicio', TPrimeiraTela);
end;
```
Pronto já temos uma Rota criada, dessa forma os nossos forms não precisam mais conhecer a uses da nossa tela, basta acionar nosso sistema de rotas e pedir a criação da rota "Inicio" que a mesma será exibida no LayoutMain da aplicação.
Você pode criar uma Unit Separada somente para Registrar as Rotas ou então chamar um metodo no onCreate do seu formulario principal para isso.
## Definindo o Render Principal
Já temos uma tela e uma rota para utilizarmos, agora precisamos definir apenas onde está rota renderizará o layout, ou seja, qual será o nosso Objeto que vai receber as telas embedadas.
Para isso no formPrincipal da sua aplicação, declare a uses Router4D e no onCreate do mesmo faça a seguinte chamada.
Lembrando que no passo anterios nós já tinhamos usado o onCreate do formPrincipal para Registrar a Rota.
```delphi
procedure TformPrincipal.FormCreate(Sender: TObject);
begin
TRouter4D.Switch.Router('Inicio', TPrimeiraTela);
TRouter4D.Render<TPrimeiraTela>.SetElement(Layout1, Layout1);
end;
```
O método Render é responsável por definir na biblioteca quais serão os LayoutsMain e Index da Aplicação.
O Render recebe como genéric o nome da Classe da nossa tela inicial, ela será renderizada quando a aplicação abrir dentro do Layout que foi informado como primeiro parametro do SetElement
O primeiro parametro do SetElement está definindo em qual Layout a biblioteca irá renderizar uma nova tela sempre que um Link da rota for chamado.
O Segundo parametro do SetElement está definindo qual é o layout Index da aplicação, assim quando um IndexLink for chamado ele será renderizado nesse layout, mais para frente explicarei sobre o IndexLink.
Pronto, agora ao abrir a sua aplicação você já terá o Layout do Formulario TPrimeiraTela sendo renderizado dentro do Layout1 do formPrincipal da sua aplicação.
## Criando uma Segunda Tela
Para que possamos ver o componente em ação de fato e todos os seus benefícios, crie uma nova tela semelhante a que fizemos no inicio, adicionando um Layout alClient nela e implementando os métodos Render e UnRender.
Coloque dentro do Layout um Label por exemplo, escrito segunda tela apenas para termos a certeza que tudo funcionou corretamente.
```delphi
unit SegundaTela;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
Router4D.Interfaces;
type
TSegundaTela = class(TForm, iRouter4DComponent)
Layout1: TLayout;
private
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
procedure UnRender;
end;
var
SegundaTela: TSegundaTela;
implementation
{$R *.fmx}
{ TSegundaTela }
function TSegundaTela.Render: TFMXObject;
begin
Result := Layout1;
end;
procedure TSegundaTela.UnRender;
begin
end;
end.
```
## Registrando a Segunda tela na Rota
Agora que criamos uma nova tela precisamos registrar ela no sistema de Rotas, então vamos voltar ao onCreate e fazer esse registros, vamos chamar essa tela de Tela2.
```delphi
procedure TformPrincipal.FormCreate(Sender: TObject);
begin
TRouter4D.Switch.Router('Inicio', TPrimeiraTela);
TRouter4D.Switch.Router('Tela2', TSegundaTela);
TRouter4D.Render<TPrimeiraTela>.SetElement(Layout1, Layout1);
end;
```
## Acionando a nova tela atráves da Rota utilizando o Link
Agora que vem a mágica, volte na TPrimeiraTela e coloque um botão lá e vamos usar o sistema de Links do Router4D para chamar a TSegundaTela sem precisar dar uses nela.
Basta chamar o método abaixo no Evento de Clique do Botão.
```delphi
procedure TPrimeiraTela.Button1Click(Sender: TObject);
begin
TRouter4D.Link.&To('Tela2');
end;
```
Perceba que a TPrimeiraTela não conhece a TSegundaTela pois o uses da mesma foi dado apenas no formPrincipal onde é necessário para o Registro das Rotas.
Se você deseja deixar isso mais organizado, eu sugiro inclusive que você crie uma Unit separada apenas para registro das Rotas com um class procedure e faça a chamada desse método no onCreate do formPrincipal.
Dessa forma damos fim a um monte de referencias cruzadas e acoplamento entre as telas.

57
Router4Delphi.dpk Normal file
View File

@ -0,0 +1,57 @@
package Router4Delphi;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO OFF}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$IMPLICITBUILD ON}
requires
rtl,
xmlrtl,
fmx,
soaprtl,
dbrtl,
DbxCommonDriver,
FireDAC,
FireDACCommonDriver,
FireDACCommon;
contains
Router4D.History in 'src\Router4D.History.pas',
Router4D.Interfaces in 'src\Router4D.Interfaces.pas',
Router4D.Link in 'src\Router4D.Link.pas',
Router4D in 'src\Router4D.pas',
Router4D.Props in 'src\Router4D.Props.pas',
Router4D.Switch in 'src\Router4D.Switch.pas',
Router4D.Utils in 'src\Router4D.Utils.pas',
DuckListU in 'src\DuckListU.pas',
EventBus.Core in 'src\EventBus.Core.pas',
EventBus.Subscribers in 'src\EventBus.Subscribers.pas',
ObjectsMappers in 'src\ObjectsMappers.pas',
RTTIUtilsU in 'src\RTTIUtilsU.pas',
Router4D.Sidebar in 'src\Router4D.Sidebar.pas',
Router4D.Render in 'src\Router4D.Render.pas';
end.

724
Router4Delphi.dproj Normal file
View File

@ -0,0 +1,724 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{3810FA8C-A44A-4F47-AEB3-80819D3485B2}</ProjectGuid>
<MainSource>Router4Delphi.dpk</MainSource>
<ProjectVersion>19.0</ProjectVersion>
<FrameworkType>FMX</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Package</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
<Base_Android64>true</Base_Android64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<GenDll>true</GenDll>
<GenPackage>true</GenPackage>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_CBuilderOutput>All</DCC_CBuilderOutput>
<SanitizedProjectName>Router4Delphi</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<DCC_CBuilderOutput>None</DCC_CBuilderOutput>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android64)'!=''">
<DCC_CBuilderOutput>None</DCC_CBuilderOutput>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="rtl.dcp"/>
<DCCReference Include="xmlrtl.dcp"/>
<DCCReference Include="fmx.dcp"/>
<DCCReference Include="soaprtl.dcp"/>
<DCCReference Include="dbrtl.dcp"/>
<DCCReference Include="DbxCommonDriver.dcp"/>
<DCCReference Include="FireDAC.dcp"/>
<DCCReference Include="FireDACCommonDriver.dcp"/>
<DCCReference Include="FireDACCommon.dcp"/>
<DCCReference Include="src\Router4D.History.pas"/>
<DCCReference Include="src\Router4D.Interfaces.pas"/>
<DCCReference Include="src\Router4D.Link.pas"/>
<DCCReference Include="src\Router4D.pas"/>
<DCCReference Include="src\Router4D.Props.pas"/>
<DCCReference Include="src\Router4D.Switch.pas"/>
<DCCReference Include="src\Router4D.Utils.pas"/>
<DCCReference Include="src\DuckListU.pas"/>
<DCCReference Include="src\EventBus.Core.pas"/>
<DCCReference Include="src\EventBus.Subscribers.pas"/>
<DCCReference Include="src\ObjectsMappers.pas"/>
<DCCReference Include="src\RTTIUtilsU.pas"/>
<DCCReference Include="src\Router4D.Sidebar.pas"/>
<DCCReference Include="src\Router4D.Render.pas"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Package</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">Router4Delphi.dpk</Source>
</Source>
</Delphi.Personality>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="Linux64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="C:\Users\Public\Documents\Embarcadero\Studio\21.0\Bpl\Router4Delphi.bpl" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>Router4Delphi.bpl</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules"/>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSLaunchScreen"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
</Deployment>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

32
Router4Delphi.dproj.local Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
<Transactions>
<Transaction>2020/07/13 22:38:51.000.784,=rtl.dcp</Transaction>
<Transaction>2020/07/13 22:38:58.000.612,C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Router4Delphi.dproj=C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Package1.dproj</Transaction>
<Transaction>2020/07/13 22:39:07.000.751,D:\Projetos\Frameworks\Router4Delphi\Router4Delphi.dproj=C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Router4Delphi.dproj</Transaction>
<Transaction>2020/07/13 22:39:18.000.950,=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.pas</Transaction>
<Transaction>2020/07/13 22:39:18.000.846,=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.History.pas</Transaction>
<Transaction>2020/07/13 22:39:18.000.879,=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.Interfaces.pas</Transaction>
<Transaction>2020/07/13 22:39:18.000.985,=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.Props.pas</Transaction>
<Transaction>2020/07/13 22:39:18.000.922,=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.Link.pas</Transaction>
<Transaction>2020/07/13 22:39:19.000.075,=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.Utils.pas</Transaction>
<Transaction>2020/07/13 22:39:19.000.046,=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.Switch.pas</Transaction>
<Transaction>2020/07/13 22:39:42.000.878,=D:\Projetos\Frameworks\Router4Delphi\src\EventBus.Core.pas</Transaction>
<Transaction>2020/07/13 22:39:42.000.911,=D:\Projetos\Frameworks\Router4Delphi\src\EventBus.Subscribers.pas</Transaction>
<Transaction>2020/07/13 22:39:42.000.975,=D:\Projetos\Frameworks\Router4Delphi\src\ObjectsMappers.pas</Transaction>
<Transaction>2020/07/13 22:39:42.000.838,=D:\Projetos\Frameworks\Router4Delphi\src\DuckListU.pas</Transaction>
<Transaction>2020/07/13 22:39:43.000.018,=D:\Projetos\Frameworks\Router4Delphi\src\RTTIUtilsU.pas</Transaction>
<Transaction>2020/07/13 22:39:54.000.821,=FireDAC.dcp</Transaction>
<Transaction>2020/07/13 22:39:54.000.880,=FireDACCommonDriver.dcp</Transaction>
<Transaction>2020/07/13 22:39:54.000.735,=dbrtl.dcp</Transaction>
<Transaction>2020/07/13 22:39:54.000.681,=soaprtl.dcp</Transaction>
<Transaction>2020/07/13 22:39:54.000.780,=DbxCommonDriver.dcp</Transaction>
<Transaction>2020/07/13 22:39:54.000.598,=xmlrtl.dcp</Transaction>
<Transaction>2020/07/13 22:39:54.000.644,=fmx.dcp</Transaction>
<Transaction>2020/07/13 22:39:54.000.918,=FireDACCommon.dcp</Transaction>
<Transaction>2020/07/14 20:23:48.000.027,=D:\Projetos\Frameworks\Router4Delphi\Unit1.pas</Transaction>
<Transaction>2020/07/14 20:23:58.000.724,D:\Projetos\Frameworks\Router4Delphi\Unit1.pas=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.Sidebar.pas</Transaction>
<Transaction>2020/07/14 20:52:39.000.123,=D:\Projetos\Frameworks\Router4Delphi\Unit1.pas</Transaction>
<Transaction>2020/07/14 20:52:54.000.533,D:\Projetos\Frameworks\Router4Delphi\Unit1.pas=D:\Projetos\Frameworks\Router4Delphi\src\Router4D.Render.pas</Transaction>
</Transactions>
</BorlandProject>

BIN
Router4Delphi.identcache Normal file

Binary file not shown.

BIN
Router4Delphi.res Normal file

Binary file not shown.

View File

@ -0,0 +1,11 @@
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 537
ClientWidth = 921
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
end

View File

@ -0,0 +1,24 @@
unit Router4DelphiDemo.View.Principal;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;
type
TForm2 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
end.

View File

@ -0,0 +1,19 @@
program Router4DelphiDemo;
uses
System.StartUpCopy,
FMX.Forms,
Router4DelphiDemo.View.Principal in 'Views\Router4DelphiDemo.View.Principal.pas' {ViewPrincipal},
Router4DelphiDemo.Views.Layouts.Main in 'Views\Layouts\Router4DelphiDemo.Views.Layouts.Main.pas' {MainLayout},
Router4DelphiDemo.View.Components.Sidebar in 'Views\Components\Router4DelphiDemo.View.Components.Sidebar.pas' {ComponentSideBar},
Router4DelphiDemo.View.Router in 'Views\Routers\Router4DelphiDemo.View.Router.pas',
Router4DelphiDemo.View.Pages.Index in 'Views\Pages\Router4DelphiDemo.View.Pages.Index.pas' {PageIndex},
Router4DelphiDemo.View.Pages.Cadastros in 'Views\Pages\Router4DelphiDemo.View.Pages.Cadastros.pas' {PageCadastros};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TViewPrincipal, ViewPrincipal);
Application.Run;
end.

View File

@ -0,0 +1,910 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{4B24F7C2-9744-436B-9B23-4088395571E2}</ProjectGuid>
<ProjectVersion>19.0</ProjectVersion>
<FrameworkType>FMX</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>32787</TargetedPlatforms>
<AppType>Application</AppType>
<MainSource>Router4DelphiDemo.dpr</MainSource>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
<Base_Android64>true</Base_Android64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
<Cfg_1_Win64>true</Cfg_1_Win64>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
<Cfg_2_Win64>true</Cfg_2_Win64>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<AUP_ACCESS_COARSE_LOCATION>true</AUP_ACCESS_COARSE_LOCATION>
<AUP_ACCESS_FINE_LOCATION>true</AUP_ACCESS_FINE_LOCATION>
<AUP_CALL_PHONE>true</AUP_CALL_PHONE>
<AUP_CAMERA>true</AUP_CAMERA>
<AUP_INTERNET>true</AUP_INTERNET>
<AUP_READ_EXTERNAL_STORAGE>true</AUP_READ_EXTERNAL_STORAGE>
<AUP_WRITE_EXTERNAL_STORAGE>true</AUP_WRITE_EXTERNAL_STORAGE>
<AUP_READ_PHONE_STATE>true</AUP_READ_PHONE_STATE>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
<SanitizedProjectName>Router4DelphiDemo</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;tethering;DataSnapFireDAC;bindcompfmx;fmx;FireDACIBDriver;FireDACDBXDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;soaprtl;DbxCommonDriver;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage>
<VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36>
<Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
<Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72>
<Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96>
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
<Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426>
<Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470>
<Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640>
<Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960>
<Android_NotificationIcon24>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png</Android_NotificationIcon24>
<Android_NotificationIcon36>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png</Android_NotificationIcon36>
<Android_NotificationIcon48>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png</Android_NotificationIcon48>
<Android_NotificationIcon72>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png</Android_NotificationIcon72>
<Android_NotificationIcon96>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png</Android_NotificationIcon96>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android64)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;tethering;DataSnapFireDAC;bindcompfmx;fmx;FireDACIBDriver;FireDACDBXDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;soaprtl;DbxCommonDriver;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage>
<VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36>
<Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
<Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72>
<Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96>
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
<Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426>
<Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470>
<Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640>
<Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960>
<Android_NotificationIcon24>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png</Android_NotificationIcon24>
<Android_NotificationIcon36>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png</Android_NotificationIcon36>
<Android_NotificationIcon48>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png</Android_NotificationIcon48>
<Android_NotificationIcon72>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png</Android_NotificationIcon72>
<Android_NotificationIcon96>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png</Android_NotificationIcon96>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;bindcompvclsmp;emsclientfiredac;tethering;svnui;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;inetdb;emsedge;fmx;FireDACIBDriver;fmxdae;vcledge;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;emsclient;DataSnapCommon;IWBootstrapD104;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;Intraweb_15_D10_4;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;TBGWebCharts;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;IWBootstrap4D104;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;bindcompvclsmp;emsclientfiredac;tethering;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;DBXOracleDriver;inetdb;emsedge;fmx;FireDACIBDriver;fmxdae;vcledge;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Views\Router4DelphiDemo.View.Principal.pas">
<Form>ViewPrincipal</Form>
<FormType>fmx</FormType>
</DCCReference>
<DCCReference Include="Views\Layouts\Router4DelphiDemo.Views.Layouts.Main.pas">
<Form>MainLayout</Form>
<FormType>fmx</FormType>
</DCCReference>
<DCCReference Include="Views\Components\Router4DelphiDemo.View.Components.Sidebar.pas">
<Form>ComponentSideBar</Form>
<FormType>fmx</FormType>
</DCCReference>
<DCCReference Include="Views\Routers\Router4DelphiDemo.View.Router.pas"/>
<DCCReference Include="Views\Pages\Router4DelphiDemo.View.Pages.Index.pas">
<Form>PageIndex</Form>
<FormType>fmx</FormType>
</DCCReference>
<DCCReference Include="Views\Pages\Router4DelphiDemo.View.Pages.Cadastros.pas">
<Form>PageCadastros</Form>
<FormType>fmx</FormType>
</DCCReference>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Application</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">Router4DelphiDemo.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Android">True</Platform>
<Platform value="Android64">True</Platform>
<Platform value="iOSDevice32">False</Platform>
<Platform value="iOSDevice64">False</Platform>
<Platform value="iOSSimulator">False</Platform>
<Platform value="OSX32">False</Platform>
<Platform value="OSX64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Debug\Router4DelphiDemo.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>Router4DelphiDemo.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSLaunchScreen">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug">
<Platform Name="OSX64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList">
<Platform Name="OSX32">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
</Deployment>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
<Transactions>
<Transaction>2020/07/13 22:40:47.000.564,=C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Unit2.pas</Transaction>
<Transaction>2020/07/13 22:41:12.000.007,C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Unit2.pas=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.pas</Transaction>
<Transaction>2020/07/13 22:41:12.000.007,C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Unit2.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.fmx</Transaction>
<Transaction>2020/07/13 22:41:42.000.814,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.pas=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.View.Principal.pas</Transaction>
<Transaction>2020/07/13 22:41:42.000.814,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.View.Principal.fmx</Transaction>
<Transaction>2020/07/13 22:41:54.000.760,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.View.Principal.pas=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Router4DelphiDemo.View.Principal.pas</Transaction>
<Transaction>2020/07/13 22:41:54.000.760,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.View.Principal.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Router4DelphiDemo.View.Principal.fmx</Transaction>
<Transaction>2020/07/13 22:42:04.000.058,C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Project2.dproj=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Router4DelphiDemo.dproj</Transaction>
<Transaction>2020/07/13 22:42:27.000.848,=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit3.pas</Transaction>
<Transaction>2020/07/13 22:42:53.000.920,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit3.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Layouts\Router4DelphiDemo.Views.Layouts.Main.fmx</Transaction>
<Transaction>2020/07/13 22:42:53.000.920,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit3.pas=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Layouts\Router4DelphiDemo.Views.Layouts.Main.pas</Transaction>
<Transaction>2020/07/13 22:44:45.000.704,=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit4.pas</Transaction>
<Transaction>2020/07/13 22:45:07.000.515,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit4.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Components\Router4DelphiDemo.View.Components.Sidebar.fmx</Transaction>
<Transaction>2020/07/13 22:45:07.000.515,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit4.pas=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Components\Router4DelphiDemo.View.Components.Sidebar.pas</Transaction>
<Transaction>2020/07/13 22:47:11.000.672,=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit2.pas</Transaction>
<Transaction>2020/07/13 22:47:40.000.630,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit2.pas=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Routers\Router4DelphiDemo.View.Router.pas</Transaction>
<Transaction>2020/07/13 22:49:19.000.504,=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit5.pas</Transaction>
<Transaction>2020/07/13 22:50:07.000.641,=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit5.pas</Transaction>
<Transaction>2020/07/13 22:50:27.000.287,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit5.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Pages\Router4DelphiDemo.View.Pages.Index.fmx</Transaction>
<Transaction>2020/07/13 22:50:27.000.287,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit5.pas=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Pages\Router4DelphiDemo.View.Pages.Index.pas</Transaction>
<Transaction>2020/07/13 23:17:06.000.185,=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit2.pas</Transaction>
<Transaction>2020/07/13 23:17:48.000.792,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit2.pas=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Pages\Router4DelphiDemo.View.Pages.Cadastros.pas</Transaction>
<Transaction>2020/07/13 23:17:48.000.792,D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Unit2.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\Demo\Views\Pages\Router4DelphiDemo.View.Pages.Cadastros.fmx</Transaction>
</Transactions>
</BorlandProject>

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,60 @@
object ComponentSideBar: TComponentSideBar
Left = 0
Top = 0
Caption = 'Form4'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Layout1: TLayout
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
object Rectangle1: TRectangle
Align = Contents
Fill.Color = xFF36414A
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
end
object ListBox1: TListBox
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'transparentlistboxstyle'
OnClick = ListBox1Click
DisableFocusEffect = True
ItemHeight = 60.000000000000000000
DefaultItemStyles.ItemStyle = ''
DefaultItemStyles.GroupHeaderStyle = ''
DefaultItemStyles.GroupFooterStyle = ''
Viewport.Width = 640.000000000000000000
Viewport.Height = 480.000000000000000000
object ListBoxItem1: TListBoxItem
TextSettings.Font.Size = 15.000000000000000000
TextSettings.FontColor = claWhite
StyledSettings = [Family, Style, Other]
Padding.Left = 15.000000000000000000
Size.Width = 640.000000000000000000
Size.Height = 60.000000000000000000
Size.PlatformDefault = False
Text = 'Home'
end
object ListBoxItem2: TListBoxItem
TextSettings.Font.Size = 15.000000000000000000
TextSettings.FontColor = claWhite
StyledSettings = [Family, Style, Other]
Position.Y = 60.000000000000000000
Size.Width = 640.000000000000000000
Size.Height = 60.000000000000000000
Size.PlatformDefault = False
Text = 'Cadastros'
end
end
end
end

View File

@ -0,0 +1,39 @@
unit Router4DelphiDemo.View.Components.Sidebar;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
FMX.ListBox, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects;
type
TComponentSideBar = class(TForm)
Layout1: TLayout;
ListBox1: TListBox;
ListBoxItem1: TListBoxItem;
ListBoxItem2: TListBoxItem;
Rectangle1: TRectangle;
procedure ListBox1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
ComponentSideBar: TComponentSideBar;
implementation
uses
Router4D;
{$R *.fmx}
procedure TComponentSideBar.ListBox1Click(Sender: TObject);
begin
TRouter4D.Link.&To(ListBox1.Items[ListBox1.ItemIndex])
end;
end.

View File

@ -0,0 +1,56 @@
object MainLayout: TMainLayout
Left = 0
Top = 0
Caption = 'Form3'
ClientHeight = 577
ClientWidth = 860
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object LayoutIndex: TLayout
Align = Contents
Size.Width = 860.000000000000000000
Size.Height = 577.000000000000000000
Size.PlatformDefault = False
object Layout1: TLayout
Align = Top
Size.Width = 860.000000000000000000
Size.Height = 65.000000000000000000
Size.PlatformDefault = False
object Rectangle1: TRectangle
Align = Contents
Fill.Color = xFF2D2F32
Size.Width = 860.000000000000000000
Size.Height = 65.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
end
object Label1: TLabel
Align = Left
StyledSettings = [Family, Style]
Margins.Left = 15.000000000000000000
Position.X = 15.000000000000000000
Size.Width = 554.000000000000000000
Size.Height = 65.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 25.000000000000000000
TextSettings.FontColor = claWhite
Text = 'Layout Principal'
end
end
object Layout2: TLayout
Align = Left
Position.Y = 65.000000000000000000
Size.Width = 225.000000000000000000
Size.Height = 512.000000000000000000
Size.PlatformDefault = False
end
object Layout3: TLayout
Align = Client
Size.Width = 635.000000000000000000
Size.Height = 512.000000000000000000
Size.PlatformDefault = False
end
end
end

View File

@ -0,0 +1,61 @@
unit Router4DelphiDemo.Views.Layouts.Main;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
FMX.Layouts,
FMX.Controls.Presentation,
FMX.StdCtrls,
Router4D.Interfaces, FMX.Objects;
type
TMainLayout = class(TForm, iRouter4DComponent)
Layout1: TLayout;
Layout2: TLayout;
Layout3: TLayout;
Label1: TLabel;
LayoutIndex: TLayout;
Rectangle1: TRectangle;
private
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
end;
var
MainLayout: TMainLayout;
implementation
uses
Router4DelphiDemo.View.Pages.Index,
Router4D,
Router4DelphiDemo.View.Components.Sidebar;
{$R *.fmx}
{ TMainLayout }
function TMainLayout.Render: TFMXObject;
begin
Result := LayoutIndex;
TRouter4D.Render<TPageIndex>.SetElement(Layout3);
Layout2.RemoveObject(0);
Layout2.AddObject(
TComponentSideBar.Create(Self).Layout1
)
end;
end.

View File

@ -0,0 +1,27 @@
object PageCadastros: TPageCadastros
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Layout1: TLayout
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
object Label1: TLabel
Align = Client
StyledSettings = [Family, Style, FontColor]
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 30.000000000000000000
TextSettings.HorzAlign = Center
Text = 'Cadastros'
end
end
end

View File

@ -0,0 +1,36 @@
unit Router4DelphiDemo.View.Pages.Cadastros;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts,
Router4D.Interfaces;
type
TPageCadastros = class(TForm, iRouter4DComponent)
Layout1: TLayout;
Label1: TLabel;
private
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
end;
var
PageCadastros: TPageCadastros;
implementation
{$R *.fmx}
{ TForm2 }
function TPageCadastros.Render: TFMXObject;
begin
Result := Layout1;
end;
end.

View File

@ -0,0 +1,27 @@
object PageIndex: TPageIndex
Left = 0
Top = 0
Caption = 'Form5'
ClientHeight = 609
ClientWidth = 940
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Layout1: TLayout
Align = Contents
Size.Width = 940.000000000000000000
Size.Height = 609.000000000000000000
Size.PlatformDefault = False
object Label1: TLabel
Align = Client
StyledSettings = [Family, Style, FontColor]
Size.Width = 940.000000000000000000
Size.Height = 609.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 30.000000000000000000
TextSettings.HorzAlign = Center
Text = 'Home'
end
end
end

View File

@ -0,0 +1,47 @@
unit Router4DelphiDemo.View.Pages.Index;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
FMX.Layouts,
Router4D.Interfaces, FMX.Controls.Presentation, FMX.StdCtrls;
type
TPageIndex = class(TForm, iRouter4DComponent)
Layout1: TLayout;
Label1: TLabel;
private
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
end;
var
PageIndex: TPageIndex;
implementation
uses
Router4D,
Router4DelphiDemo.Views.Layouts.Main;
{$R *.fmx}
function TPageIndex.Render: TFMXObject;
begin
Result := Layout1;
//TRouter4D.Render<TMainLayout>.GetElement(Layout1);
end;
end.

View File

@ -0,0 +1,18 @@
object ViewPrincipal: TViewPrincipal
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 612
ClientWidth = 925
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
DesignerMasterStyle = 0
object Layout1: TLayout
Align = Contents
Size.Width = 925.000000000000000000
Size.Height = 612.000000000000000000
Size.PlatformDefault = False
end
end

View File

@ -0,0 +1,36 @@
unit Router4DelphiDemo.View.Principal;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts;
type
TViewPrincipal = class(TForm)
Layout1: TLayout;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
ViewPrincipal: TViewPrincipal;
implementation
uses
Router4D,
Router4DelphiDemo.Views.Layouts.Main,
Router4DelphiDemo.View.Router;
{$R *.fmx}
procedure TViewPrincipal.FormCreate(Sender: TObject);
begin
TRouter4D.Render<TMainLayout>.SetElement(Layout1, Layout1);
end;
end.

View File

@ -0,0 +1,45 @@
unit Router4DelphiDemo.View.Router;
interface
type
TRouters = class
private
public
constructor Create;
destructor Destroy; override;
end;
var
Routers : TRouters;
implementation
uses
Router4D,
Router4DelphiDemo.View.Pages.Index,
Router4DelphiDemo.Views.Layouts.Main,
Router4DelphiDemo.View.Pages.Cadastros;
{ TRouters }
constructor TRouters.Create;
begin
TRouter4D.Switch.Router('Home', TPageIndex);
TRouter4D.Switch.Router('Cadastros', TPageCadastros);
TRouter4D.Switch.Router('main', TMainLayout);
end;
destructor TRouters.Destroy;
begin
inherited;
end;
initialization
Routers := TRouters.Create;
finalization
Routers.Free;
end.

View File

@ -0,0 +1,47 @@
object ComponentButton01: TComponentButton01
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
DesignerMasterStyle = 0
object Layout1: TLayout
Position.X = 232.000000000000000000
Position.Y = 120.000000000000000000
Size.Width = 121.000000000000000000
Size.Height = 81.000000000000000000
Size.PlatformDefault = False
object Line1: TLine
Align = Bottom
LineType = Bottom
Position.Y = 80.000000000000000000
Size.Width = 121.000000000000000000
Size.Height = 1.000000000000000000
Size.PlatformDefault = False
Stroke.Thickness = 5.000000000000000000
end
object Label1: TLabel
Align = Contents
StyledSettings = [Family, Style, FontColor]
Size.Width = 121.000000000000000000
Size.Height = 81.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 20.000000000000000000
TextSettings.HorzAlign = Center
Text = 'Button'
end
object SpeedButton1: TSpeedButton
Align = Contents
Opacity = 0.000000000000000000
Size.Width = 121.000000000000000000
Size.Height = 81.000000000000000000
Size.PlatformDefault = False
Text = 'SpeedButton1'
OnClick = SpeedButton1Click
end
end
end

View File

@ -0,0 +1,85 @@
unit SimpleDemo.View.Components.Button01;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, FMX.Layouts,
Router4D.Interfaces,
Router4D.Props;
type
TComponentButton01 = class(TForm, iRouter4DComponent)
Layout1: TLayout;
Line1: TLine;
Label1: TLabel;
SpeedButton1: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
procedure UnRender;
[Subscribe]
procedure Props ( aValue : TProps);
function createButton(aLabel : String) : TFMXObject;
end;
var
ComponentButton01: TComponentButton01;
implementation
{$R *.fmx}
{ TComponentButton01 }
function TComponentButton01.createButton(aLabel: String): TFMXObject;
begin
Result := Layout1;
Label1.Text := aLabel;
Layout1.Align := TAlignLayout.Left;
Line1.Visible := False;
Self.TagString := aLabel;
end;
procedure TComponentButton01.FormCreate(Sender: TObject);
begin
GlobalEventBus.RegisterSubscriber(Self);
end;
procedure TComponentButton01.Props(aValue: TProps);
begin
Line1.Visible := False;
if (aValue.PropString = Label1.Text) and
(aValue.Key = 'Button01') then
Line1.Visible := True;
aValue.Free;
end;
function TComponentButton01.Render: TFMXObject;
begin
Result := Layout1;
end;
procedure TComponentButton01.SpeedButton1Click(Sender: TObject);
begin
Line1.Visible := True;
GlobalEventBus.Post(
TProps.Create
.PropString(Label1.Text)
.Key('Button01')
);
end;
procedure TComponentButton01.UnRender;
begin
//
end;
end.

View File

@ -0,0 +1,27 @@
object SubCadastros: TSubCadastros
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Layout1: TLayout
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
object Label1: TLabel
Align = Contents
StyledSettings = [Family, Style, FontColor]
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 30.000000000000000000
TextSettings.HorzAlign = Center
Text = 'Sub-Cadastros'
end
end
end

View File

@ -0,0 +1,45 @@
unit SimpleDemo.View.Page.Cadastros.Sub;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts,
Router4D.Interfaces;
type
TSubCadastros = class(TForm, iRouter4DComponent)
Layout1: TLayout;
Label1: TLabel;
private
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
procedure UnRender;
end;
var
SubCadastros: TSubCadastros;
implementation
uses
Router4D.History;
{$R *.fmx}
{ TSubCadastros }
function TSubCadastros.Render: TFMXObject;
begin
Result := Layout1;
end;
procedure TSubCadastros.UnRender;
begin
//
end;
end.

View File

@ -0,0 +1,74 @@
object PageCadastros: TPageCadastros
Left = 0
Top = 0
Caption = 'Form3'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
DesignerMasterStyle = 0
object Layout1: TLayout
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
object Layout2: TLayout
Align = Left
Size.Width = 177.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
Visible = False
object Rectangle1: TRectangle
Align = Contents
Fill.Color = xFF36414A
Size.Width = 177.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
end
end
object Layout3: TLayout
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 399.000000000000000000
Size.PlatformDefault = False
object Label1: TLabel
Align = Contents
StyledSettings = [Family, Style, FontColor]
Size.Width = 640.000000000000000000
Size.Height = 399.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 30.000000000000000000
TextSettings.HorzAlign = Center
Text = 'Cadastros'
end
object Button1: TButton
Anchors = []
Position.X = 243.682922363281300000
Position.Y = 215.990631103515600000
Size.Width = 145.000000000000000000
Size.Height = 41.000000000000000000
Size.PlatformDefault = False
Text = 'Voltar para Home'
OnClick = Button1Click
end
object Edit1: TEdit
Touch.InteractiveGestures = [LongTap, DoubleTap]
Anchors = []
Position.X = 243.682922363281300000
Position.Y = 257.240631103515600000
Size.Width = 145.000000000000000000
Size.Height = 25.000000000000000000
Size.PlatformDefault = False
end
end
object Layout4: TLayout
Align = Top
Size.Width = 640.000000000000000000
Size.Height = 81.000000000000000000
Size.PlatformDefault = False
end
end
end

View File

@ -0,0 +1,114 @@
unit SimpleDemo.View.Page.Cadastros;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
FMX.Controls.Presentation,
FMX.StdCtrls,
FMX.Layouts,
Router4D.Interfaces,
Router4D.Props, FMX.Edit, FMX.Objects;
type
TPageCadastros = class(TForm, iRouter4DComponent)
Layout1: TLayout;
Label1: TLabel;
Button1: TButton;
Edit1: TEdit;
Layout2: TLayout;
Layout3: TLayout;
Rectangle1: TRectangle;
Layout4: TLayout;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure CreateMenuSuperior;
procedure CreateRouters;
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
procedure UnRender;
[Subscribe]
procedure Props ( aValue : TProps);
end;
var
PageCadastros: TPageCadastros;
implementation
uses
Router4D, SimpleDemo.View.Page.Cadastros.Sub, SimpleDemo.View.Page.Principal,
SimpleDemo.View.Components.Button01;
{$R *.fmx}
{ TPageCadastros }
procedure TPageCadastros.Button1Click(Sender: TObject);
begin
TRouter4D.Link.&To('Inicio');
end;
procedure TPageCadastros.FormCreate(Sender: TObject);
begin
CreateRouters;
CreateMenuSuperior;
end;
procedure TPageCadastros.Props(aValue: TProps);
begin
if (aValue.PropString <> '') and (aValue.Key = 'TelaCadastro') then
Label1.Text := aValue.PropString;
aValue.Free;
end;
procedure TPageCadastros.CreateRouters;
begin
TRouter4D.Switch.Router('Clientes', TPagePrincipal, 'cadastros');
TRouter4D.Switch.Router('Fornecedores', TSubCadastros, 'cadastros');
TRouter4D.Switch.Router('Produtos', TSubCadastros, 'cadastros');
end;
procedure TPageCadastros.CreateMenuSuperior;
begin
Layout4.AddObject(
TComponentButton01.Create(Self)
.createButton('Clientes')
);
Layout4.AddObject(
TComponentButton01.Create(Self)
.createButton('Produtos')
);
Layout4.AddObject(
TComponentButton01.Create(Self)
.createButton('Fornecedores')
);
end;
function TPageCadastros.Render: TFMXObject;
begin
Label1.Text := 'Cadastros';
Result := Layout1;
end;
procedure TPageCadastros.UnRender;
begin
//
end;
end.

View File

@ -0,0 +1,47 @@
object PagePrincipal: TPagePrincipal
Left = 0
Top = 0
Caption = 'Form3'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Layout1: TLayout
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
object Label1: TLabel
Align = Client
StyledSettings = [Family, Style, FontColor]
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 30.000000000000000000
TextSettings.HorzAlign = Center
Text = 'Home'
end
object Button1: TButton
Anchors = []
Position.X = 240.000000000000000000
Position.Y = 264.000000000000000000
Size.Width = 169.000000000000000000
Size.Height = 33.000000000000000000
Size.PlatformDefault = False
Text = 'Cadastros Simples'
OnClick = Button1Click
end
object Button2: TButton
Anchors = []
Position.X = 240.000000000000000000
Position.Y = 304.000000000000000000
Size.Width = 169.000000000000000000
Size.Height = 33.000000000000000000
Size.PlatformDefault = False
Text = 'Cadastros com Props'
OnClick = Button2Click
end
end
end

View File

@ -0,0 +1,69 @@
unit SimpleDemo.View.Page.Principal;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts,
Router4D.Interfaces;
type
TPagePrincipal = class(TForm, iRouter4DComponent)
Layout1: TLayout;
Label1: TLabel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
function Render : TFMXObject;
procedure UnRender;
end;
var
PagePrincipal: TPagePrincipal;
implementation
uses
Router4D,
Router4D.Props;
{$R *.fmx}
{ TPagePrincipal }
procedure TPagePrincipal.Button1Click(Sender: TObject);
begin
TRouter4D.Link.&To('Cadastros');
end;
procedure TPagePrincipal.Button2Click(Sender: TObject);
begin
TRouter4D.Link
.&To(
'Cadastros',
TProps
.Create
.PropString(
'Olá Router4D, Seu Cadastro Recebeu as Props'
)
.Key('TelaCadastro')
);
end;
function TPagePrincipal.Render: TFMXObject;
begin
Result := Layout1;
end;
procedure TPagePrincipal.UnRender;
begin
//
end;
end.

View File

@ -0,0 +1,71 @@
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 586
ClientWidth = 875
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnShow = FormShow
DesignerMasterStyle = 0
object Layout1: TLayout
Align = Client
Size.Width = 875.000000000000000000
Size.Height = 586.000000000000000000
Size.PlatformDefault = False
object Layout2: TLayout
Align = Top
Size.Width = 875.000000000000000000
Size.Height = 50.000000000000000000
Size.PlatformDefault = False
object Rectangle1: TRectangle
Align = Contents
Fill.Color = xFF36414A
Size.Width = 875.000000000000000000
Size.Height = 50.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
end
object Label1: TLabel
Align = Contents
StyledSettings = [Family, Style]
Margins.Right = 10.000000000000000000
Size.Width = 865.000000000000000000
Size.Height = 50.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 15.000000000000000000
TextSettings.FontColor = claWhite
TextSettings.HorzAlign = Trailing
Text = 'Router4D - SimpleDemo'
end
end
object Layout4: TLayout
Align = Client
Size.Width = 705.000000000000000000
Size.Height = 536.000000000000000000
Size.PlatformDefault = False
end
object Layout3: TLayout
Align = Left
Position.Y = 50.000000000000000000
Size.Width = 170.000000000000000000
Size.Height = 536.000000000000000000
Size.PlatformDefault = False
object Rectangle2: TRectangle
Align = Contents
Fill.Color = xFF2D2F32
Size.Width = 170.000000000000000000
Size.Height = 536.000000000000000000
Size.PlatformDefault = False
Stroke.Kind = None
end
object Layout5: TLayout
Align = Client
Size.Width = 170.000000000000000000
Size.Height = 536.000000000000000000
Size.PlatformDefault = False
end
end
end
end

View File

@ -0,0 +1,79 @@
unit SimpleDemo.View.Principal;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
FMX.Controls.Presentation,
FMX.StdCtrls,
FMX.ListBox,
FMX.Layouts,
FMX.Objects, FMX.Edit, FMX.SearchBox, FMX.MultiView;
type
TForm2 = class(TForm)
Layout1: TLayout;
Layout2: TLayout;
Layout3: TLayout;
Layout4: TLayout;
Rectangle1: TRectangle;
Rectangle2: TRectangle;
Label1: TLabel;
Layout5: TLayout;
procedure FormShow(Sender: TObject);
private
procedure RegisterRouters;
procedure createSideBar;
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses
Router4D,
SimpleDemo.View.Page.Cadastros,
SimpleDemo.View.Page.Principal;
{$R *.fmx}
procedure TForm2.FormShow(Sender: TObject);
begin
RegisterRouters;
TRouter4D.Render<TPagePrincipal>.SetElement(Layout4, Layout1);
end;
procedure TForm2.RegisterRouters;
begin
TRouter4D.Switch.Router('Inicio', TPagePrincipal);
TRouter4D.Switch.Router('Cadastros', TPageCadastros);
TRouter4D.Switch.Router('Configuracoes', TPageCadastros);
createSideBar;
end;
procedure TForm2.createSideBar;
begin
TRouter4D
.SideBar
.MainContainer(Layout5)
.LinkContainer(Layout4)
.FontSize(15)
.FontColor(4294967295)
.ItemHeigth(60)
.RenderToListBox;
end;
end.

View File

@ -0,0 +1,19 @@
program SimpleDemo;
uses
System.StartUpCopy,
FMX.Forms,
SimpleDemo.View.Principal in 'SimpleDemo.View.Principal.pas' {Form2},
SimpleDemo.View.Page.Principal in 'SimpleDemo.View.Page.Principal.pas' {PagePrincipal},
SimpleDemo.View.Page.Cadastros in 'SimpleDemo.View.Page.Cadastros.pas' {PageCadastros},
SimpleDemo.View.Page.Cadastros.Sub in 'SimpleDemo.View.Page.Cadastros.Sub.pas' {SubCadastros},
SimpleDemo.View.Components.Button01 in 'SimpleDemo.View.Components.Button01.pas' {ComponentButton01};
{$R *.res}
begin
ReportMemoryLeaksOnShutdown := True;
Application.Initialize;
Application.CreateForm(TForm2, Form2);
Application.Run;
end.

View File

@ -0,0 +1,904 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{3AD0DA23-7F3C-401B-92FF-B74A312EBB37}</ProjectGuid>
<ProjectVersion>19.0</ProjectVersion>
<FrameworkType>FMX</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>32787</TargetedPlatforms>
<AppType>Application</AppType>
<MainSource>SimpleDemo.dpr</MainSource>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
<Base_Android64>true</Base_Android64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
<Cfg_1_Win64>true</Cfg_1_Win64>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
<Cfg_2_Win64>true</Cfg_2_Win64>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<AUP_ACCESS_COARSE_LOCATION>true</AUP_ACCESS_COARSE_LOCATION>
<AUP_ACCESS_FINE_LOCATION>true</AUP_ACCESS_FINE_LOCATION>
<AUP_CALL_PHONE>true</AUP_CALL_PHONE>
<AUP_CAMERA>true</AUP_CAMERA>
<AUP_INTERNET>true</AUP_INTERNET>
<AUP_READ_EXTERNAL_STORAGE>true</AUP_READ_EXTERNAL_STORAGE>
<AUP_WRITE_EXTERNAL_STORAGE>true</AUP_WRITE_EXTERNAL_STORAGE>
<AUP_READ_PHONE_STATE>true</AUP_READ_PHONE_STATE>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
<SanitizedProjectName>SimpleDemo</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;tethering;DataSnapFireDAC;bindcompfmx;fmx;FireDACIBDriver;FireDACDBXDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;soaprtl;DbxCommonDriver;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage>
<VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36>
<Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
<Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72>
<Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96>
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
<Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426>
<Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470>
<Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640>
<Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960>
<Android_NotificationIcon24>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png</Android_NotificationIcon24>
<Android_NotificationIcon36>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png</Android_NotificationIcon36>
<Android_NotificationIcon48>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png</Android_NotificationIcon48>
<Android_NotificationIcon72>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png</Android_NotificationIcon72>
<Android_NotificationIcon96>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png</Android_NotificationIcon96>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android64)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;tethering;DataSnapFireDAC;bindcompfmx;fmx;FireDACIBDriver;FireDACDBXDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;soaprtl;DbxCommonDriver;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage>
<VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36>
<Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
<Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72>
<Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96>
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
<Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426>
<Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470>
<Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640>
<Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960>
<Android_NotificationIcon24>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png</Android_NotificationIcon24>
<Android_NotificationIcon36>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png</Android_NotificationIcon36>
<Android_NotificationIcon48>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png</Android_NotificationIcon48>
<Android_NotificationIcon72>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png</Android_NotificationIcon72>
<Android_NotificationIcon96>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png</Android_NotificationIcon96>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;bindcompvclsmp;emsclientfiredac;tethering;svnui;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;inetdb;emsedge;fmx;FireDACIBDriver;fmxdae;vcledge;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;emsclient;DataSnapCommon;IWBootstrapD104;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;Intraweb_15_D10_4;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;TBGWebCharts;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;IWBootstrap4D104;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;bindcompvclsmp;emsclientfiredac;tethering;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;DBXOracleDriver;inetdb;emsedge;fmx;FireDACIBDriver;fmxdae;vcledge;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="SimpleDemo.View.Principal.pas">
<Form>Form2</Form>
<FormType>fmx</FormType>
</DCCReference>
<DCCReference Include="SimpleDemo.View.Page.Principal.pas">
<Form>PagePrincipal</Form>
<FormType>fmx</FormType>
</DCCReference>
<DCCReference Include="SimpleDemo.View.Page.Cadastros.pas">
<Form>PageCadastros</Form>
<FormType>fmx</FormType>
</DCCReference>
<DCCReference Include="SimpleDemo.View.Page.Cadastros.Sub.pas">
<Form>SubCadastros</Form>
<FormType>fmx</FormType>
</DCCReference>
<DCCReference Include="SimpleDemo.View.Components.Button01.pas">
<Form>ComponentButton01</Form>
<FormType>fmx</FormType>
</DCCReference>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>Application</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">SimpleDemo.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Android">True</Platform>
<Platform value="Android64">True</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Debug\SimpleDemo.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>SimpleDemo.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSLaunchScreen">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug">
<Platform Name="OSX64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList">
<Platform Name="OSX32">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
</Deployment>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
<Transactions>
<Transaction>2020/07/13 23:31:02.000.010,=C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Unit2.pas</Transaction>
<Transaction>2020/07/13 23:31:25.000.893,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Principal.pas=C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Unit2.pas</Transaction>
<Transaction>2020/07/13 23:31:25.000.893,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Principal.fmx=C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Unit2.fmx</Transaction>
<Transaction>2020/07/13 23:31:29.000.939,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.dproj=C:\Users\thuli\Documents\Embarcadero\Studio\Projects\Project2.dproj</Transaction>
<Transaction>2020/07/13 23:34:29.000.476,=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit3.pas</Transaction>
<Transaction>2020/07/13 23:35:18.000.719,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Page.Principal.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit3.fmx</Transaction>
<Transaction>2020/07/13 23:35:18.000.719,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Page.Principal.pas=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit3.pas</Transaction>
<Transaction>2020/07/13 23:35:59.000.833,=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit3.pas</Transaction>
<Transaction>2020/07/13 23:36:34.000.131,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Page.Cadastros.pas=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit3.pas</Transaction>
<Transaction>2020/07/13 23:36:34.000.131,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Page.Cadastros.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit3.fmx</Transaction>
<Transaction>2020/07/15 11:34:37.000.719,=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit1.pas</Transaction>
<Transaction>2020/07/15 11:35:34.000.042,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit1.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Page.Cadastros.Sub.fmx</Transaction>
<Transaction>2020/07/15 11:35:34.000.042,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit1.pas=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Page.Cadastros.Sub.pas</Transaction>
<Transaction>2020/07/16 23:06:18.753,=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit1.pas</Transaction>
<Transaction>2020/07/16 23:07:42.491,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Components.Button01.pas=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit1.pas</Transaction>
<Transaction>2020/07/16 23:07:42.491,D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\SimpleDemo.View.Components.Button01.fmx=D:\Projetos\Frameworks\Router4Delphi\sample\SimpleDemo\Unit1.fmx</Transaction>
</Transactions>
</BorlandProject>

Binary file not shown.

Binary file not shown.

337
src/DuckListU.pas Normal file
View File

@ -0,0 +1,337 @@
// ***************************************************************************
//
// Delphi MVC Framework
//
// Copyright (c) 2010-2016 Daniele Teti and the DMVCFramework Team
//
// https://github.com/danieleteti/delphimvcframework
//
// ***************************************************************************
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ***************************************************************************
unit DuckListU;
interface
uses
RTTI,
Classes,
// superobject,
Generics.Collections,
SysUtils,
TypInfo;
type
TDuckTypedList=class;
TdormObjectStatus=(osDirty=0, osClean, osUnknown, osDeleted);
EdormException=class(Exception)
end;
EdormValidationException=class(EdormException)
end;
TdormEnvironment=(deDevelopment, deTest, deRelease);
TdormObjectOwner=(ooItself, ooParent);
TdormSaveType=(stAllGraph, stSingleObject);
TdormRelations=set of (drBelongsTo, drHasMany, drHasOne);
TdormFillOptions=set of (CallAfterLoadEvent);
IList=interface
['{2A1BCB3C-17A2-4F8D-B6FB-32B2A1BFE840}']
function Add(const Value: TObject): Integer;
procedure Clear;
function Count: Integer;
function GetItem(index: Integer): TObject;
end;
TdormListEnumerator=class(TEnumerator<TObject>)
protected
FPosition: Int64;
FDuckTypedList: TDuckTypedList;
protected
function DoGetCurrent: TObject; override;
function DoMoveNext: boolean; override;
public
constructor Create(ADuckTypedList: TDuckTypedList);
end;
TSortingType=(soAscending, soDescending);
IWrappedList=interface
['{B60AF5A6-7C31-4EAA-8DFB-D8BD3E112EE7}']
function Count: Integer;
function GetItem(const index: Integer): TObject;
procedure Add(const AObject: TObject);
procedure Clear;
function GetEnumerator: TdormListEnumerator;
function WrappedObject: TObject;
procedure Sort(const PropertyName: string; Order: TSortingType=soAscending);
function GetOwnsObjects: boolean;
procedure SetOwnsObjects(const Value: boolean);
property OwnsObjects: boolean read GetOwnsObjects write SetOwnsObjects;
end;
TDuckTypedList=class(TInterfacedObject, IWrappedList)
protected
FCTX: TRTTIContext;
FObjectAsDuck: TObject;
FAddMethod: TRttiMethod;
FClearMethod: TRttiMethod;
FCountProperty: TRttiProperty;
FGetItemMethod: TRttiMethod;
FGetCountMethod: TRttiMethod;
function Count: Integer;
function GetItem(const index: Integer): TObject;
procedure Add(const AObject: TObject);
procedure Clear;
function WrappedObject: TObject;
procedure QuickSort(List: IWrappedList; L, R: Integer; SCompare: TFunc<TObject, TObject, Integer>); overload;
procedure QuickSort(List: IWrappedList; SCompare: TFunc<TObject, TObject, Integer>); overload;
procedure Sort(const PropertyName: string; Order: TSortingType=soAscending);
public
constructor Create(AObjectAsDuck: TObject);
destructor Destroy; override;
function GetEnumerator: TdormListEnumerator;
function GetOwnsObjects: boolean;
procedure SetOwnsObjects(const Value: boolean);
property OwnsObjects: boolean read GetOwnsObjects write SetOwnsObjects;
class function CanBeWrappedAsList(const AObjectAsDuck: TObject): boolean;
end;
function WrapAsList(const AObject: TObject): IWrappedList;
implementation
uses System.Math,
RTTIUtilsU;
constructor TdormListEnumerator.Create(ADuckTypedList: TDuckTypedList);
begin
inherited Create;
FDuckTypedList := ADuckTypedList;
FPosition := -1;
end;
function TdormListEnumerator.DoGetCurrent: TObject;
begin
if FPosition>-1 then
Result := FDuckTypedList.GetItem(FPosition)
else
raise Exception.Create('Enumerator error: Call MoveNext first');
end;
function TdormListEnumerator.DoMoveNext: boolean;
begin
if FPosition<FDuckTypedList.Count-1 then
begin
Inc(FPosition);
Result := True;
end
else
Result := false;
end;
function TDuckTypedList.GetEnumerator: TdormListEnumerator;
begin
Result := TdormListEnumerator.Create(self);
end;
procedure TDuckTypedList.Add(const AObject: TObject);
begin
FAddMethod.Invoke(FObjectAsDuck, [AObject]);
end;
class function TDuckTypedList.CanBeWrappedAsList(const AObjectAsDuck: TObject): boolean;
var
FCTX: TRTTIContext;
begin
Result := (FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('Add')<>nil)and(FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('Clear')<>nil)
{$IF CompilerVersion >= 23}
and(FCTX.GetType(AObjectAsDuck.ClassInfo).GetIndexedProperty('Items').ReadMethod<>nil)
{$IFEND}
and((FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('GetItem')<>nil)or(FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('GetElement')<>
nil))and(FCTX.GetType(AObjectAsDuck.ClassInfo).GetProperty('Count')<>nil)
end;
procedure TDuckTypedList.Clear;
begin
FClearMethod.Invoke(FObjectAsDuck, []);
end;
function TDuckTypedList.Count: Integer;
begin
if Assigned(FCountProperty) then
Result := FCountProperty.GetValue(FObjectAsDuck).AsInteger
else
Result := FGetCountMethod.Invoke(FObjectAsDuck, []).AsInteger;
end;
constructor TDuckTypedList.Create(AObjectAsDuck: TObject);
begin
inherited Create;
FObjectAsDuck := AObjectAsDuck;
FAddMethod := FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('Add');
if not Assigned(FAddMethod) then
raise EdormException.Create('Cannot find method "Add" in the duck object');
FClearMethod := FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('Clear');
if not Assigned(FClearMethod) then
raise EdormException.Create('Cannot find method "Clear" in the duck object');
FGetItemMethod := nil;
{$IF CompilerVersion >= 23}
FGetItemMethod := FCTX.GetType(AObjectAsDuck.ClassInfo).GetIndexedProperty('Items').ReadMethod;
{$IFEND}
if not Assigned(FGetItemMethod) then
FGetItemMethod := FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('GetItem');
if not Assigned(FGetItemMethod) then
FGetItemMethod := FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('GetElement');
if not Assigned(FGetItemMethod) then
raise EdormException.Create
('Cannot find method Indexed property "Items" or method "GetItem" or method "GetElement" in the duck object');
FCountProperty := FCTX.GetType(AObjectAsDuck.ClassInfo).GetProperty('Count');
if not Assigned(FCountProperty) then
begin
FGetCountMethod := FCTX.GetType(AObjectAsDuck.ClassInfo).GetMethod('Count');
if not Assigned(FGetCountMethod) then
raise EdormException.Create('Cannot find property/method "Count" in the duck object');
end;
end;
destructor TDuckTypedList.Destroy;
begin
inherited;
end;
function TDuckTypedList.GetItem(const index: Integer): TObject;
begin
Result := FGetItemMethod.Invoke(FObjectAsDuck, [index]).AsObject;
end;
function TDuckTypedList.GetOwnsObjects: boolean;
begin
Result := TRTTIUtils.GetProperty(FObjectAsDuck, 'OwnsObjects').AsBoolean
end;
function TDuckTypedList.WrappedObject: TObject;
begin
Result := FObjectAsDuck;
end;
function WrapAsList(const AObject: TObject): IWrappedList;
begin
try
Result := TDuckTypedList.Create(AObject);
except
Result := nil;
end;
end;
procedure TDuckTypedList.QuickSort(List: IWrappedList; L, R: Integer; SCompare: TFunc<TObject, TObject, Integer>);
var
I, J: Integer;
p: TObject;
begin
{ 07/08/2013: This method is based on QuickSort procedure from
Classes.pas, (c) Borland Software Corp.
but modified to be part of TDuckListU unit. It implements the
standard quicksort algorithm,
delegating comparison operation to an anonimous.
The Borland version delegates to a pure function
pointer, which is problematic in some cases. }
repeat
I := L;
J := R;
p := List.GetItem((L+R) shr 1);
repeat
while SCompare(TObject(List.GetItem(I)), p)<0 do
Inc(I);
while SCompare(TObject(List.GetItem(J)), p)>0 do
Dec(J);
if I<=J then
begin
TRTTIUtils.MethodCall(List.WrappedObject, 'Exchange', [I, J]);
Inc(I);
Dec(J);
end;
until I>J;
if L<J then
QuickSort(List, L, J, SCompare);
L := I;
until I>=R;
end;
procedure TDuckTypedList.QuickSort(List: IWrappedList; SCompare: TFunc<TObject, TObject, Integer>);
begin
QuickSort(List, 0, List.Count-1, SCompare);
end;
function CompareValue(const Left, Right: TValue): Integer;
begin
if Left.IsOrdinal then
begin
Result := System.Math.CompareValue(Left.AsOrdinal, Right.AsOrdinal);
end
else if Left.Kind=tkFloat then
begin
Result := System.Math.CompareValue(Left.AsExtended, Right.AsExtended);
end
else if Left.Kind in [tkString, tkUString, tkWString, tkLString] then
begin
Result := CompareText(Left.AsString, Right.AsString);
end
else
begin
Result := 0;
end;
end;
procedure TDuckTypedList.SetOwnsObjects(const Value: boolean);
begin
TRTTIUtils.SetProperty(FObjectAsDuck, 'OwnsObjects', Value);
end;
procedure TDuckTypedList.Sort(const PropertyName: string; Order: TSortingType);
begin
if Order=soAscending then
QuickSort(self,
function(Left, Right: TObject): Integer
begin
Result := CompareValue(TRTTIUtils.GetProperty(Left, PropertyName), TRTTIUtils.GetProperty(Right, PropertyName));
end)
else
QuickSort(self,
function(Left, Right: TObject): Integer
begin
Result := -1*CompareValue(TRTTIUtils.GetProperty(Left, PropertyName), TRTTIUtils.GetProperty(Right, PropertyName));
end);
end;
end.

362
src/EventBus.Core.pas Normal file
View File

@ -0,0 +1,362 @@
{ *******************************************************************************
Copyright 2016-2019 Daniele Spinetti
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
******************************************************************************** }
unit EventBus.Core;
interface
uses
System.SyncObjs, EventBus.Subscribers, Generics.Collections,
System.SysUtils, System.Classes, Router4D.Props;
type
TEventBus = class(TInterfacedObject, IEventBus)
var
FTypesOfGivenSubscriber: TObjectDictionary<TObject, TList<TClass>>;
FSubscriptionsOfGivenEventType
: TObjectDictionary<TClass, TObjectList<TSubscription>>;
FCustomClonerDict: TDictionary<String, TCloneEventMethod>;
FOnCloneEvent: TCloneEventCallback;
procedure Subscribe(ASubscriber: TObject;
ASubscriberMethod: TSubscriberMethod);
procedure UnsubscribeByEventType(ASubscriber: TObject; AEventType: TClass);
procedure InvokeSubscriber(ASubscription: TSubscription; AEvent: TObject);
function GenerateTProc(ASubscription: TSubscription;
AEvent: TObject): TProc;
function GenerateThreadProc(ASubscription: TSubscription; AEvent: TObject)
: TThreadProcedure;
protected
procedure SetOnCloneEvent(const aCloneEvent: TCloneEventCallback);
function CloneEvent(AEvent: TObject): TObject; virtual;
procedure PostToSubscription(ASubscription: TSubscription; AEvent: TObject;
AIsMainThread: Boolean); virtual;
public
constructor Create; virtual;
destructor Destroy; override;
procedure RegisterSubscriber(ASubscriber: TObject); virtual;
function IsRegistered(ASubscriber: TObject): Boolean;
procedure Unregister(ASubscriber: TObject); virtual;
procedure Post(AEvent: TObject; const AContext: String = '';
AEventOwner: Boolean = true); virtual;
property TypesOfGivenSubscriber: TObjectDictionary < TObject,
TList < TClass >> read FTypesOfGivenSubscriber;
property SubscriptionsOfGivenEventType: TObjectDictionary < TClass,
TObjectList < TSubscription >> read FSubscriptionsOfGivenEventType;
property OnCloneEvent: TCloneEventCallback write SetOnCloneEvent;
procedure AddCustomClassCloning(const AQualifiedClassName: String;
const aCloneEvent: TCloneEventMethod);
procedure RemoveCustomClassCloning(const AQualifiedClassName: String);
end;
implementation
uses
System.Rtti,
{$IF CompilerVersion >= 28.0}
System.Threading,
{$ENDIF}
RTTIUtilsU;
var
FMREWSync: TMultiReadExclusiveWriteSynchronizer;
{ TEventBus }
constructor TEventBus.Create;
begin
inherited Create;
FSubscriptionsOfGivenEventType := TObjectDictionary < TClass,
TObjectList < TSubscription >>.Create([doOwnsValues]);
FTypesOfGivenSubscriber := TObjectDictionary < TObject,
TList < TClass >>.Create([doOwnsValues]);
FCustomClonerDict := TDictionary<String, TCloneEventMethod>.Create;
end;
destructor TEventBus.Destroy;
begin
FreeAndNil(FSubscriptionsOfGivenEventType);
FreeAndNil(FTypesOfGivenSubscriber);
FreeAndNil(FCustomClonerDict);
inherited;
end;
procedure TEventBus.AddCustomClassCloning(const AQualifiedClassName: String;
const aCloneEvent: TCloneEventMethod);
begin
FCustomClonerDict.Add(AQualifiedClassName, aCloneEvent);
end;
function TEventBus.CloneEvent(AEvent: TObject): TObject;
var
LCloneEvent: TCloneEventMethod;
begin
if FCustomClonerDict.TryGetValue(AEvent.QualifiedClassName, LCloneEvent) then
Result := LCloneEvent(AEvent)
else if Assigned(FOnCloneEvent) then
Result := FOnCloneEvent(AEvent)
else
Result := TRTTIUtils.Clone(AEvent);
end;
function TEventBus.GenerateThreadProc(ASubscription: TSubscription;
AEvent: TObject): TThreadProcedure;
begin
Result := procedure
begin
if ASubscription.Active then
begin
ASubscription.SubscriberMethod.Method.Invoke(ASubscription.Subscriber,
[AEvent]);
end;
end;
end;
function TEventBus.GenerateTProc(ASubscription: TSubscription;
AEvent: TObject): TProc;
begin
Result := procedure
begin
if ASubscription.Active then
begin
ASubscription.SubscriberMethod.Method.Invoke(ASubscription.Subscriber,
[AEvent]);
end;
end;
end;
procedure TEventBus.InvokeSubscriber(ASubscription: TSubscription;
AEvent: TObject);
begin
try
ASubscription.SubscriberMethod.Method.Invoke(ASubscription.Subscriber,
[AEvent]);
except
on E: Exception do
begin
raise Exception.CreateFmt
('Error invoking subscriber method. Subscriber class: %s. Event type: %s. Original exception: %s: %s',
[ASubscription.Subscriber.ClassName,
ASubscription.SubscriberMethod.EventType.ClassName, E.ClassName,
E.Message]);
end;
end;
end;
function TEventBus.IsRegistered(ASubscriber: TObject): Boolean;
begin
FMREWSync.BeginRead;
try
Result := FTypesOfGivenSubscriber.ContainsKey(ASubscriber);
finally
FMREWSync.EndRead;
end;
end;
procedure TEventBus.Post(AEvent: TObject; const AContext: String = '';
AEventOwner: Boolean = true);
var
LSubscriptions: TObjectList<TSubscription>;
LSubscription: TSubscription;
LEvent: TObject;
LIsMainThread: Boolean;
begin
FMREWSync.BeginRead;
try
try
LIsMainThread := MainThreadID = TThread.CurrentThread.ThreadID;
FSubscriptionsOfGivenEventType.TryGetValue(AEvent.ClassType,
LSubscriptions);
if (not Assigned(LSubscriptions)) then
Exit;
for LSubscription in LSubscriptions do
begin
if not LSubscription.Active then
continue;
if ((not AContext.IsEmpty) and (LSubscription.Context <> AContext)) then
continue;
LEvent := CloneEvent(AEvent);
PostToSubscription(LSubscription, LEvent, LIsMainThread);
end;
finally
if (AEventOwner and Assigned(AEvent)) then
AEvent.Free;
end;
finally
FMREWSync.EndRead;
end;
end;
procedure TEventBus.PostToSubscription(ASubscription: TSubscription;
AEvent: TObject; AIsMainThread: Boolean);
begin
if not Assigned(ASubscription.Subscriber) then
Exit;
case ASubscription.SubscriberMethod.ThreadMode of
Posting:
InvokeSubscriber(ASubscription, AEvent);
Main:
if (AIsMainThread) then
InvokeSubscriber(ASubscription, AEvent)
else
TThread.Queue(nil, GenerateThreadProc(ASubscription, AEvent));
Background:
if (AIsMainThread) then
{$IF CompilerVersion >= 28.0}
TTask.Run(GenerateTProc(ASubscription, AEvent))
{$ELSE}
TThread.CreateAnonymousThread(GenerateTProc(ASubscription,
AEvent)).Start
{$ENDIF}
else
InvokeSubscriber(ASubscription, AEvent);
Async:
{$IF CompilerVersion >= 28.0}
TTask.Run(GenerateTProc(ASubscription, AEvent));
{$ELSE}
TThread.CreateAnonymousThread(GenerateTProc(ASubscription, AEvent)).Start;
{$ENDIF}
else
raise Exception.Create('Unknown thread mode');
end;
end;
procedure TEventBus.RegisterSubscriber(ASubscriber: TObject);
var
LSubscriberClass: TClass;
LSubscriberMethods: TArray<TSubscriberMethod>;
LSubscriberMethod: TSubscriberMethod;
begin
FMREWSync.BeginWrite;
try
LSubscriberClass := ASubscriber.ClassType;
LSubscriberMethods := TSubscribersFinder.FindSubscriberMethods
(LSubscriberClass, true);
for LSubscriberMethod in LSubscriberMethods do
Subscribe(ASubscriber, LSubscriberMethod);
finally
FMREWSync.EndWrite;
end;
end;
procedure TEventBus.RemoveCustomClassCloning(const AQualifiedClassName: String);
begin
// No exception is thrown if the key is not in the dictionary
FCustomClonerDict.Remove(AQualifiedClassName);
end;
procedure TEventBus.SetOnCloneEvent(const aCloneEvent: TCloneEventCallback);
begin
FOnCloneEvent := aCloneEvent;
end;
procedure TEventBus.Subscribe(ASubscriber: TObject;
ASubscriberMethod: TSubscriberMethod);
var
LEventType: TClass;
LNewSubscription: TSubscription;
LSubscriptions: TObjectList<TSubscription>;
LSubscribedEvents: TList<TClass>;
begin
LEventType := ASubscriberMethod.EventType;
LNewSubscription := TSubscription.Create(ASubscriber, ASubscriberMethod);
if (not FSubscriptionsOfGivenEventType.ContainsKey(LEventType)) then
begin
LSubscriptions := TObjectList<TSubscription>.Create();
FSubscriptionsOfGivenEventType.Add(LEventType, LSubscriptions);
end
else
begin
LSubscriptions := FSubscriptionsOfGivenEventType.Items[LEventType];
if (LSubscriptions.Contains(LNewSubscription)) then
raise Exception.CreateFmt('Subscriber %s already registered to event %s ',
[ASubscriber.ClassName, LEventType.ClassName]);
end;
LSubscriptions.Add(LNewSubscription);
if (not FTypesOfGivenSubscriber.TryGetValue(ASubscriber, LSubscribedEvents))
then
begin
LSubscribedEvents := TList<TClass>.Create;
FTypesOfGivenSubscriber.Add(ASubscriber, LSubscribedEvents);
end;
LSubscribedEvents.Add(LEventType);
end;
procedure TEventBus.Unregister(ASubscriber: TObject);
var
LSubscribedTypes: TList<TClass>;
LEventType: TClass;
begin
FMREWSync.BeginWrite;
try
if FTypesOfGivenSubscriber.TryGetValue(ASubscriber, LSubscribedTypes) then
begin
for LEventType in LSubscribedTypes do
UnsubscribeByEventType(ASubscriber, LEventType);
FTypesOfGivenSubscriber.Remove(ASubscriber);
end;
// else {
// Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
// }
finally
FMREWSync.EndWrite;
end;
end;
procedure TEventBus.UnsubscribeByEventType(ASubscriber: TObject;
AEventType: TClass);
var
LSubscriptions: TObjectList<TSubscription>;
LSize, I: Integer;
LSubscription: TSubscription;
begin
LSubscriptions := FSubscriptionsOfGivenEventType.Items[AEventType];
if (not Assigned(LSubscriptions)) or (LSubscriptions.Count < 1) then
Exit;
LSize := LSubscriptions.Count;
for I := LSize - 1 downto 0 do
begin
LSubscription := LSubscriptions[I];
// Notes: In case the subscriber has been freed but it didn't unregister itself, calling
// LSubscription.Subscriber.Equals() will cause Access Violation, so we use '=' instead.
if LSubscription.Subscriber = ASubscriber then
begin
LSubscription.Active := false;
LSubscriptions.Delete(I);
end;
end;
end;
initialization
FMREWSync := TMultiReadExclusiveWriteSynchronizer.Create;
finalization
FMREWSync.Free;
end.

View File

@ -0,0 +1,241 @@
{ *******************************************************************************
Copyright 2016-2019 Daniele Spinetti
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
******************************************************************************** }
unit EventBus.Subscribers;
interface
uses
System.RTTI, Router4D.Props;
type
TSubscriberMethod = class(TObject)
private
FEventType: TClass;
FThreadMode: TThreadMode;
FMethod: TRttiMethod;
FContext: string;
procedure SetEventType(const Value: TClass);
procedure SetMethod(const Value: TRttiMethod);
procedure SetThreadMode(const Value: TThreadMode);
procedure SetContext(const Value: String);
public
constructor Create(ARttiMethod: TRttiMethod; AEventType: TClass;
AThreadMode: TThreadMode; const AContext: String = '';
APriority: Integer = 1);
destructor Destroy; override;
property EventType: TClass read FEventType write SetEventType;
property Method: TRttiMethod read FMethod write SetMethod;
property ThreadMode: TThreadMode read FThreadMode write SetThreadMode;
property Context: String read FContext write SetContext;
function Equals(Obj: TObject): Boolean; override;
end;
TSubscription = class(TObject)
private
FSubscriberMethod: TSubscriberMethod;
FSubscriber: TObject;
FActive: Boolean;
procedure SetActive(const Value: Boolean);
function GetActive: Boolean;
procedure SetSubscriberMethod(const Value: TSubscriberMethod);
procedure SetSubscriber(const Value: TObject);
function GetContext: String;
public
constructor Create(ASubscriber: TObject;
ASubscriberMethod: TSubscriberMethod);
destructor Destroy; override;
property Active: Boolean read GetActive write SetActive;
property Subscriber: TObject read FSubscriber write SetSubscriber;
property SubscriberMethod: TSubscriberMethod read FSubscriberMethod
write SetSubscriberMethod;
property Context: String read GetContext;
function Equals(Obj: TObject): Boolean; override;
end;
TSubscribersFinder = class(TObject)
class function FindSubscriberMethods(ASubscriberClass: TClass;
ARaiseExcIfEmpty: Boolean = false): TArray<TSubscriberMethod>;
end;
implementation
uses
RTTIUtilsU, System.SysUtils, System.TypInfo;
{ TSubscriberMethod }
constructor TSubscriberMethod.Create(ARttiMethod: TRttiMethod;
AEventType: TClass; AThreadMode: TThreadMode; const AContext: String = '';
APriority: Integer = 1);
begin
FMethod := ARttiMethod;
FEventType := AEventType;
FThreadMode := AThreadMode;
FContext := AContext;
end;
destructor TSubscriberMethod.Destroy;
begin
inherited;
end;
function TSubscriberMethod.Equals(Obj: TObject): Boolean;
var
OtherSubscriberMethod: TSubscriberMethod;
begin
if (inherited Equals(Obj)) then
exit(true)
else if (Obj is TSubscriberMethod) then
begin
OtherSubscriberMethod := TSubscriberMethod(Obj);
exit(OtherSubscriberMethod.Method.ToString = Method.ToString);
end
else
exit(false);
end;
procedure TSubscriberMethod.SetContext(const Value: String);
begin
FContext := Value;
end;
procedure TSubscriberMethod.SetEventType(const Value: TClass);
begin
FEventType := Value;
end;
procedure TSubscriberMethod.SetMethod(const Value: TRttiMethod);
begin
FMethod := Value;
end;
procedure TSubscriberMethod.SetThreadMode(const Value: TThreadMode);
begin
FThreadMode := Value;
end;
{ TSubscribersFinder }
class function TSubscribersFinder.FindSubscriberMethods(ASubscriberClass
: TClass; ARaiseExcIfEmpty: Boolean = false): TArray<TSubscriberMethod>;
var
LRttiType: TRttiType;
LSubscribeAttribute: SubscribeAttribute;
LRttiMethods: TArray<System.RTTI.TRttiMethod>;
LMethod: TRttiMethod;
LParamsLength: Integer;
LEventType: TClass;
LSubMethod: TSubscriberMethod;
begin
LRttiType := TRTTIUtils.ctx.GetType(ASubscriberClass);
LRttiMethods := LRttiType.GetMethods;
for LMethod in LRttiMethods do
if TRTTIUtils.HasAttribute<SubscribeAttribute>(LMethod, LSubscribeAttribute)
then
begin
LParamsLength := Length(LMethod.GetParameters);
if (LParamsLength <> 1) then
raise Exception.CreateFmt
('Method %s has Subscribe attribute but requires %d arguments. Methods must require a single argument.',
[LMethod.Name, LParamsLength]);
LEventType := LMethod.GetParameters[0].ParamType.Handle.TypeData.
ClassType;
LSubMethod := TSubscriberMethod.Create(LMethod, LEventType,
LSubscribeAttribute.ThreadMode, LSubscribeAttribute.Context);
{$IF CompilerVersion >= 28.0}
Result := Result + [LSubMethod];
{$ELSE}
SetLength(Result, Length(Result) + 1);
Result[High(Result)] := LSubMethod;
{$ENDIF}
end;
//if (Length(Result) < 1) and ARaiseExcIfEmpty then
// raise Exception.CreateFmt
// ('The class %s and its super classes have no public methods with the Subscribe attributes',
// [ASubscriberClass.QualifiedClassName]);
end;
{ TSubscription }
constructor TSubscription.Create(ASubscriber: TObject;
ASubscriberMethod: TSubscriberMethod);
begin
inherited Create;
FSubscriber := ASubscriber;
FSubscriberMethod := ASubscriberMethod;
FActive := true;
end;
destructor TSubscription.Destroy;
begin
if Assigned(FSubscriberMethod) then
FreeAndNil(FSubscriberMethod);
inherited;
end;
function TSubscription.Equals(Obj: TObject): Boolean;
var
LOtherSubscription: TSubscription;
begin
if (Obj is TSubscription) then
begin
LOtherSubscription := TSubscription(Obj);
exit((Subscriber = LOtherSubscription.Subscriber) and
(SubscriberMethod.Equals(LOtherSubscription.SubscriberMethod)));
end
else
exit(false);
end;
function TSubscription.GetActive: Boolean;
begin
TMonitor.Enter(self);
try
Result := FActive;
finally
TMonitor.exit(self);
end;
end;
function TSubscription.GetContext: String;
begin
Result := SubscriberMethod.Context;
end;
procedure TSubscription.SetActive(const Value: Boolean);
begin
TMonitor.Enter(self);
try
FActive := Value;
finally
TMonitor.exit(self);
end;
end;
procedure TSubscription.SetSubscriberMethod(const Value: TSubscriberMethod);
begin
FSubscriberMethod := Value;
end;
procedure TSubscription.SetSubscriber(const Value: TObject);
begin
FSubscriber := Value;
end;
end.

3033
src/ObjectsMappers.pas Normal file

File diff suppressed because it is too large Load Diff

850
src/RTTIUtilsU.pas Normal file
View File

@ -0,0 +1,850 @@
// ***************************************************************************
//
// Delphi MVC Framework
//
// Copyright (c) 2010-2016 Daniele Teti and the DMVCFramework Team
//
// https://github.com/danieleteti/delphimvcframework
//
// ***************************************************************************
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ***************************************************************************
unit RTTIUtilsU;
interface
uses
RTTI,
DB,
Generics.Collections,
System.SysUtils;
type
TRTTIUtils = class sealed
public
class var ctx: TRttiContext;
class var TValueToStringFormatSettings: TFormatSettings;
public
class function MethodCall(AObject: TObject; AMethodName: string; AParameters: array of TValue;
RaiseExceptionIfNotFound: boolean = true): TValue;
class function GetMethod(AObject: TObject; AMethodName: string): TRttiMethod;
class procedure SetProperty(Obj: TObject; const PropertyName: string; const Value: TValue); overload; static;
class function GetFieldType(AProp: TRttiProperty): string;
class function GetPropertyType(AObject: TObject; APropertyName: string): string;
class procedure ObjectToDataSet(Obj: TObject; Field: TField; var Value: Variant);
class function ExistsProperty(AObject: TObject; const APropertyName: string; out AProperty: TRttiProperty): boolean;
class procedure DatasetToObject(Dataset: TDataset; Obj: TObject);
class function GetProperty(Obj: TObject; const PropertyName: string): TValue;
class function GetPropertyAsString(Obj: TObject; const PropertyName: string): string; overload;
class function GetPropertyAsString(Obj: TObject; AProperty: TRttiProperty): string; overload;
class function GetField(Obj: TObject; const PropertyName: string): TValue; overload;
class procedure SetField(Obj: TObject; const PropertyName: string; const Value: TValue); overload;
class function Clone(Obj: TObject): TObject; static;
class procedure CopyObject(SourceObj, TargetObj: TObject); static;
{$IF CompilerVersion >= 24.0} // not supported in xe3
class procedure CopyObjectAS<T: class>(SourceObj, TargetObj: TObject); static;
{$IFEND}
class function CreateObject(ARttiType: TRttiType): TObject; overload; static;
class function CreateObject(AQualifiedClassName: string): TObject; overload; static;
class function GetAttribute<T: TCustomAttribute>(const Obj: TRttiObject): T; overload;
class function GetAttribute<T: TCustomAttribute>(const Obj: TRttiType): T; overload;
class function HasAttribute<T: TCustomAttribute>(const Obj: TRttiObject): boolean; overload;
class function HasAttribute<T: TCustomAttribute>(const Obj: TRttiObject; out AAttribute: T): boolean; overload;
class function HasAttribute<T: class>(aObj: TObject; out AAttribute: T): boolean; overload;
class function HasAttribute<T: class>(ARTTIMember: TRttiMember; out AAttribute: T): boolean; overload;
class function HasAttribute<T: class>(ARTTIMember: TRttiType; out AAttribute: T): boolean; overload;
class function TValueAsString(const Value: TValue; const PropertyType, CustomFormat: string): string;
class function EqualValues(source, destination: TValue): boolean;
class function FindByProperty<T: class>(List: TObjectList<T>; PropertyName: string; PropertyValue: TValue): T;
class procedure ForEachProperty(Clazz: TClass; Proc: TProc<TRttiProperty>);
class function HasStringValueAttribute<T: class>(ARTTIMember: TRttiMember; out Value: string): boolean;
class function BuildClass(AQualifiedName: string; Params: array of TValue): TObject;
class function FindType(QualifiedName: string): TRttiType;
class function GetGUID<T>: TGUID;
end;
function FieldFor(const PropertyName: string): string; inline;
implementation
uses
Classes,
TypInfo,
ObjectsMappers,
DuckListU;
class function TRTTIUtils.MethodCall(AObject: TObject; AMethodName: string; AParameters: array of TValue;
RaiseExceptionIfNotFound: boolean): TValue;
var
m: TRttiMethod;
T: TRttiType;
Found: boolean;
ParLen: Integer;
MethodParamsLen: Integer;
begin
Found := False;
T := ctx.GetType(AObject.ClassInfo);
ParLen := Length(AParameters);
m := nil;
for m in T.GetMethods do
begin
MethodParamsLen := Length(m.GetParameters);
if m.Name.Equals(AMethodName) and (MethodParamsLen = ParLen) then
begin
Found := true;
Break;
end;
end;
if Found then
Result := m.Invoke(AObject, AParameters)
else if RaiseExceptionIfNotFound then
raise Exception.CreateFmt('Cannot find compatible method "%s" in the object', [AMethodName]);
end;
function FieldFor(const PropertyName: string): string; inline;
begin
Result := 'F' + PropertyName;
end;
class function TRTTIUtils.GetAttribute<T>(const Obj: TRttiObject): T;
var
Attr: TCustomAttribute;
begin
Result := nil;
for Attr in Obj.GetAttributes do
begin
if Attr.ClassType.InheritsFrom(T) then
Exit(T(Attr));
end;
end;
class function TRTTIUtils.GetAttribute<T>(const Obj: TRttiType): T;
var
Attr: TCustomAttribute;
begin
Result := nil;
for Attr in Obj.GetAttributes do
begin
if Attr.ClassType.InheritsFrom(T) then
Exit(T(Attr));
end;
end;
class function TRTTIUtils.GetField(Obj: TObject; const PropertyName: string): TValue;
var
Field: TRttiField;
Prop: TRttiProperty;
ARttiType: TRttiType;
begin
ARttiType := ctx.GetType(Obj.ClassType);
if not Assigned(ARttiType) then
raise Exception.CreateFmt('Cannot get RTTI for type [%s]', [ARttiType.ToString]);
Field := ARttiType.GetField(FieldFor(PropertyName));
if Assigned(Field) then
Result := Field.GetValue(Obj)
else
begin
Prop := ARttiType.GetProperty(PropertyName);
if not Assigned(Prop) then
raise Exception.CreateFmt('Cannot get RTTI for property [%s.%s]', [ARttiType.ToString, PropertyName]);
Result := Prop.GetValue(Obj);
end;
end;
class function TRTTIUtils.GetProperty(Obj: TObject; const PropertyName: string): TValue;
var
Prop: TRttiProperty;
ARttiType: TRttiType;
begin
ARttiType := ctx.GetType(Obj.ClassType);
if not Assigned(ARttiType) then
raise Exception.CreateFmt('Cannot get RTTI for type [%s]', [ARttiType.ToString]);
Prop := ARttiType.GetProperty(PropertyName);
if not Assigned(Prop) then
raise Exception.CreateFmt('Cannot get RTTI for property [%s.%s]', [ARttiType.ToString, PropertyName]);
if Prop.IsReadable then
Result := Prop.GetValue(Obj)
else
raise Exception.CreateFmt('Property is not readable [%s.%s]', [ARttiType.ToString, PropertyName]);
end;
class function TRTTIUtils.GetPropertyAsString(Obj: TObject; AProperty: TRttiProperty): string;
var
P: TValue;
FT: string;
CustomFormat: string;
begin
if AProperty.IsReadable then
begin
P := AProperty.GetValue(Obj);
FT := GetFieldType(AProperty);
HasStringValueAttribute<StringValueAttribute>(AProperty, CustomFormat);
Result := TValueAsString(P, FT, CustomFormat);
end
else
Result := '';
end;
class function TRTTIUtils.GetPropertyAsString(Obj: TObject; const PropertyName: string): string;
var
Prop: TRttiProperty;
begin
Prop := ctx.GetType(Obj.ClassType).GetProperty(PropertyName);
if Assigned(Prop) then
Result := GetPropertyAsString(Obj, Prop)
else
Result := '';
end;
class function TRTTIUtils.GetPropertyType(AObject: TObject; APropertyName: string): string;
begin
Result := GetFieldType(ctx.GetType(AObject.ClassInfo).GetProperty(APropertyName));
end;
class function TRTTIUtils.HasAttribute<T>(const Obj: TRttiObject): boolean;
begin
Result := Assigned(GetAttribute<T>(Obj));
end;
class function TRTTIUtils.HasAttribute<T>(ARTTIMember: TRttiMember; out AAttribute: T): boolean;
var
attrs: TArray<TCustomAttribute>;
Attr: TCustomAttribute;
begin
AAttribute := nil;
Result := False;
attrs := ARTTIMember.GetAttributes;
for Attr in attrs do
if Attr is T then
begin
AAttribute := T(Attr);
Exit(true);
end;
end;
class function TRTTIUtils.HasAttribute<T>(ARTTIMember: TRttiType; out AAttribute: T): boolean;
var
attrs: TArray<TCustomAttribute>;
Attr: TCustomAttribute;
begin
AAttribute := nil;
Result := False;
attrs := ARTTIMember.GetAttributes;
for Attr in attrs do
if Attr is T then
begin
AAttribute := T(Attr);
Exit(true);
end;
end;
class function TRTTIUtils.HasAttribute<T>(const Obj: TRttiObject; out AAttribute: T): boolean;
begin
AAttribute := GetAttribute<T>(Obj);
Result := Assigned(AAttribute);
end;
class function TRTTIUtils.HasStringValueAttribute<T>(ARTTIMember: TRttiMember; out Value: string): boolean;
var
Attr: T; // StringValueAttribute;
begin
Result := HasAttribute<T>(ARTTIMember, Attr);
if Result then
Value := StringValueAttribute(Attr).Value
else
Value := '';
end;
class procedure TRTTIUtils.SetField(Obj: TObject; const PropertyName: string; const Value: TValue);
var
Field: TRttiField;
Prop: TRttiProperty;
ARttiType: TRttiType;
begin
ARttiType := ctx.GetType(Obj.ClassType);
if not Assigned(ARttiType) then
raise Exception.CreateFmt('Cannot get RTTI for type [%s]', [ARttiType.ToString]);
Field := ARttiType.GetField(FieldFor(PropertyName));
if Assigned(Field) then
Field.SetValue(Obj, Value)
else
begin
Prop := ARttiType.GetProperty(PropertyName);
if Assigned(Prop) then
begin
if Prop.IsWritable then
Prop.SetValue(Obj, Value)
end
else
raise Exception.CreateFmt('Cannot get RTTI for field or property [%s.%s]', [ARttiType.ToString, PropertyName]);
end;
end;
class procedure TRTTIUtils.SetProperty(Obj: TObject; const PropertyName: string; const Value: TValue);
var
Prop: TRttiProperty;
ARttiType: TRttiType;
begin
ARttiType := ctx.GetType(Obj.ClassType);
if not Assigned(ARttiType) then
raise Exception.CreateFmt('Cannot get RTTI for type [%s]', [ARttiType.ToString]);
Prop := ARttiType.GetProperty(PropertyName);
if not Assigned(Prop) then
raise Exception.CreateFmt('Cannot get RTTI for property [%s.%s]', [ARttiType.ToString, PropertyName]);
if Prop.IsWritable then
Prop.SetValue(Obj, Value)
else
raise Exception.CreateFmt('Property is not writeable [%s.%s]', [ARttiType.ToString, PropertyName]);
end;
class function TRTTIUtils.TValueAsString(const Value: TValue; const PropertyType, CustomFormat: string): string;
begin
case Value.Kind of
tkUnknown:
Result := '';
tkInteger:
Result := IntToStr(Value.AsInteger);
tkChar:
Result := Value.AsString;
tkEnumeration:
if PropertyType = 'boolean' then
Result := BoolToStr(Value.AsBoolean, true)
else
Result := '(enumeration)';
tkFloat:
begin
if PropertyType = 'datetime' then
begin
if CustomFormat = '' then
Exit(DateTimeToStr(Value.AsExtended))
else
Exit(FormatDateTime(CustomFormat, Value.AsExtended))
end
else if PropertyType = 'date' then
begin
if CustomFormat = '' then
Exit(DateToStr(Value.AsExtended))
else
Exit(FormatDateTime(CustomFormat, Trunc(Value.AsExtended)))
end
else if PropertyType = 'time' then
begin
if CustomFormat = '' then
Exit(TimeToStr(Value.AsExtended))
else
Exit(FormatDateTime(CustomFormat, Frac(Value.AsExtended)))
end;
if CustomFormat.IsEmpty then
Result := FloatToStr(Value.AsExtended)
else
Result := FormatFloat(CustomFormat, Value.AsExtended);
end;
tkString:
Result := Value.AsString;
tkSet:
;
tkClass:
Result := Value.AsObject.QualifiedClassName;
tkMethod:
;
tkWChar:
Result := Value.AsString;
tkLString:
Result := Value.AsString;
tkWString:
Result := Value.AsString;
tkVariant:
Result := string(Value.AsVariant);
tkArray:
Result := '(array)';
tkRecord:
Result := '(record)';
tkInterface:
Result := '(interface)';
tkInt64:
Result := IntToStr(Value.AsInt64);
tkDynArray:
Result := '(array)';
tkUString:
Result := Value.AsString;
tkClassRef:
Result := '(classref)';
tkPointer:
Result := '(pointer)';
tkProcedure:
Result := '(procedure)';
end;
end;
class function TRTTIUtils.GetFieldType(AProp: TRttiProperty): string;
var
_PropInfo: PTypeInfo;
begin
_PropInfo := AProp.PropertyType.Handle;
if _PropInfo.Kind in [tkString, tkWString, tkChar, tkWChar, tkLString, tkUString] then
Result := 'string'
else if _PropInfo.Kind in [tkInteger, tkInt64] then
Result := 'integer'
else if _PropInfo = TypeInfo(TDate) then
Result := 'date'
else if _PropInfo = TypeInfo(TDateTime) then
Result := 'datetime'
else if _PropInfo = TypeInfo(Currency) then
Result := 'decimal'
else if _PropInfo = TypeInfo(TTime) then
begin
Result := 'time'
end
else if _PropInfo.Kind = tkFloat then
begin
Result := 'float'
end
else if (_PropInfo.Kind = tkEnumeration) { and (_PropInfo.Name = 'Boolean') } then
Result := 'boolean'
else if AProp.PropertyType.IsInstance and AProp.PropertyType.AsInstance.MetaclassType.InheritsFrom(TStream) then
Result := 'blob'
else
Result := EmptyStr;
end;
class function TRTTIUtils.GetGUID<T>: TGUID;
var
Tp: TRttiType;
begin
Tp := ctx.GetType(TypeInfo(T));
if not (Tp.TypeKind = tkInterface) then
raise Exception.Create('Type is no interface');
Result := TRttiInterfaceType(Tp).GUID;
end;
class function TRTTIUtils.GetMethod(AObject: TObject; AMethodName: string): TRttiMethod;
var
T: TRttiType;
begin
T := ctx.GetType(AObject.ClassInfo);
Result := T.GetMethod(AMethodName);
end;
class procedure TRTTIUtils.ObjectToDataSet(Obj: TObject; Field: TField; var Value: Variant);
begin
Value := GetProperty(Obj, Field.FieldName).AsVariant;
end;
class procedure TRTTIUtils.DatasetToObject(Dataset: TDataset; Obj: TObject);
var
ARttiType: TRttiType;
props: TArray<TRttiProperty>;
Prop: TRttiProperty;
f: TField;
begin
ARttiType := ctx.GetType(Obj.ClassType);
props := ARttiType.GetProperties;
for Prop in props do
if not SameText(Prop.Name, 'ID') then
begin
f := Dataset.FindField(Prop.Name);
if Assigned(f) and not f.ReadOnly then
begin
if f is TIntegerField then
SetProperty(Obj, Prop.Name, TIntegerField(f).Value)
else
SetProperty(Obj, Prop.Name, TValue.From<Variant>(f.Value))
end;
end;
end;
class function TRTTIUtils.EqualValues(source, destination: TValue): boolean;
begin
// Really UniCodeCompareStr (Annoying VCL Name for backwards compatablity)
Result := AnsiCompareStr(source.ToString, destination.ToString) = 0;
end;
class function TRTTIUtils.ExistsProperty(AObject: TObject; const APropertyName: string; out AProperty: TRttiProperty): boolean;
begin
AProperty := ctx.GetType(AObject.ClassInfo).GetProperty(APropertyName);
Result := Assigned(AProperty);
end;
class function TRTTIUtils.FindByProperty<T>(List: TObjectList<T>; PropertyName: string; PropertyValue: TValue): T;
var
elem: T;
V: TValue;
Found: boolean;
begin
Found := False;
for elem in List do
begin
V := GetProperty(elem, PropertyName);
case V.Kind of
tkInteger:
Found := V.AsInteger = PropertyValue.AsInteger;
tkFloat:
Found := abs(V.AsExtended - PropertyValue.AsExtended) < 0.001;
tkString, tkLString, tkWString, tkUString:
Found := V.AsString = PropertyValue.AsString;
tkInt64:
Found := V.AsInt64 = PropertyValue.AsInt64;
else
raise Exception.Create('Property type not supported');
end;
if Found then
Exit(elem);
end;
Result := nil;
end;
class function TRTTIUtils.FindType(QualifiedName: string): TRttiType;
begin
Result := ctx.FindType(QualifiedName);
end;
class procedure TRTTIUtils.ForEachProperty(Clazz: TClass; Proc: TProc<TRttiProperty>);
var
_rtti: TRttiType;
P: TRttiProperty;
begin
_rtti := ctx.GetType(Clazz);
if Assigned(_rtti) then
begin
for P in _rtti.GetProperties do
Proc(P);
end;
end;
class procedure TRTTIUtils.CopyObject(SourceObj, TargetObj: TObject);
var
_ARttiType: TRttiType;
Field: TRttiField;
master, cloned: TObject;
Src: TObject;
sourceStream: TStream;
SavedPosition: Int64;
targetStream: TStream;
targetCollection: IWrappedList;
sourceCollection: IWrappedList;
I: Integer;
sourceObject: TObject;
targetObject: TObject;
Tar: TObject;
begin
if not Assigned(TargetObj) then
Exit;
_ARttiType := ctx.GetType(SourceObj.ClassType);
cloned := TargetObj;
master := SourceObj;
for Field in _ARttiType.GetFields do
begin
if not Field.FieldType.IsInstance then
Field.SetValue(cloned, Field.GetValue(master))
else
begin
Src := Field.GetValue(SourceObj).AsObject;
if Src is TStream then
begin
sourceStream := TStream(Src);
SavedPosition := sourceStream.Position;
sourceStream.Position := 0;
if Field.GetValue(cloned).IsEmpty then
begin
targetStream := TMemoryStream.Create;
Field.SetValue(cloned, targetStream);
end
else
targetStream := Field.GetValue(cloned).AsObject as TStream;
targetStream.Position := 0;
targetStream.CopyFrom(sourceStream, sourceStream.Size);
targetStream.Position := SavedPosition;
sourceStream.Position := SavedPosition;
end
else if TDuckTypedList.CanBeWrappedAsList(Src) then
begin
sourceCollection := WrapAsList(Src);
Tar := Field.GetValue(cloned).AsObject;
if Assigned(Tar) then
begin
targetCollection := WrapAsList(Tar);
targetCollection.Clear;
for I := 0 to sourceCollection.Count - 1 do
targetCollection.Add(TRTTIUtils.Clone(sourceCollection.GetItem(I)));
end;
end
else
begin
sourceObject := Src;
if Field.GetValue(cloned).IsEmpty then
begin
targetObject := TRTTIUtils.Clone(sourceObject);
Field.SetValue(cloned, targetObject);
end
else
begin
targetObject := Field.GetValue(cloned).AsObject;
TRTTIUtils.CopyObject(sourceObject, targetObject);
end;
end;
end;
end;
end;
{$IF CompilerVersion >= 24.0}
class procedure TRTTIUtils.CopyObjectAS<T>(SourceObj, TargetObj: TObject);
var
_ARttiType: TRttiType;
_ARttiTypeTarget: TRttiType;
Field, FieldDest: TRttiField;
master, cloned: TObject;
Src: TObject;
sourceStream: TStream;
SavedPosition: Int64;
targetStream: TStream;
targetCollection: IWrappedList;
sourceCollection: IWrappedList;
I: Integer;
sourceObject: TObject;
targetObject: TObject;
Tar: TObject;
begin
if not Assigned(TargetObj) then
Exit;
_ARttiType := ctx.GetType(SourceObj.ClassType);
_ARttiTypeTarget := ctx.GetType(TargetObj.ClassType);
cloned := TargetObj;
master := SourceObj;
for Field in _ARttiType.GetFields do
begin
FieldDest := _ARttiTypeTarget.GetField(Field.Name);
if not Assigned(FieldDest) then
continue;
if not Field.FieldType.IsInstance then
begin
FieldDest.SetValue(cloned, Field.GetValue(master));
end
else
begin
Src := Field.GetValue(SourceObj).AsObject;
if not Assigned(Src) then
begin
FieldDest.SetValue(cloned, Src);
end
else if Src is TStream then
begin
sourceStream := TStream(Src);
SavedPosition := sourceStream.Position;
sourceStream.Position := 0;
if FieldDest.GetValue(cloned).IsEmpty then
begin
targetStream := TMemoryStream.Create;
FieldDest.SetValue(cloned, targetStream);
end
else
targetStream := FieldDest.GetValue(cloned).AsObject as TStream;
targetStream.Position := 0;
targetStream.CopyFrom(sourceStream, sourceStream.Size);
targetStream.Position := SavedPosition;
sourceStream.Position := SavedPosition;
end
else if TDuckTypedList.CanBeWrappedAsList(Src) then
begin
sourceCollection := WrapAsList(Src);
Tar := FieldDest.GetValue(cloned).AsObject;
if Assigned(Tar) then
begin
targetCollection := WrapAsList(Tar);
targetCollection.Clear;
for I := 0 to sourceCollection.Count - 1 do
targetCollection.Add(TRTTIUtils.Clone(sourceCollection.GetItem(I)));
end;
end
else
begin
sourceObject := Src;
if FieldDest.GetValue(cloned).IsEmpty then
begin
targetObject := TRTTIUtils.Clone(sourceObject);
FieldDest.SetValue(cloned, targetObject);
end
else
begin
targetObject := FieldDest.GetValue(cloned).AsObject;
TRTTIUtils.CopyObject(sourceObject, targetObject);
end;
end;
end;
end;
end;
{$IFEND}
class function TRTTIUtils.CreateObject(AQualifiedClassName: string): TObject;
var
rttitype: TRttiType;
begin
rttitype := ctx.FindType(AQualifiedClassName);
if Assigned(rttitype) then
Result := CreateObject(rttitype)
else
raise Exception.Create('Cannot find RTTI for ' + AQualifiedClassName + '. Hint: Is the specified classtype linked in the module?');
end;
class function TRTTIUtils.CreateObject(ARttiType: TRttiType): TObject;
var
Method: TRttiMethod;
metaClass: TClass;
begin
{ First solution, clear and slow }
metaClass := nil;
Method := nil;
for Method in ARttiType.GetMethods do
if Method.HasExtendedInfo and Method.IsConstructor then
if Length(Method.GetParameters) = 0 then
begin
metaClass := ARttiType.AsInstance.MetaclassType;
Break;
end;
if Assigned(metaClass) then
Result := Method.Invoke(metaClass, []).AsObject
else
raise Exception.Create('Cannot find a propert constructor for ' + ARttiType.ToString);
{ Second solution, dirty and fast }
// Result := TObject(ARttiType.GetMethod('Create')
// .Invoke(ARttiType.AsInstance.MetaclassType, []).AsObject);
end;
class function TRTTIUtils.BuildClass(AQualifiedName: string; Params: array of TValue): TObject;
var
T: TRttiType;
V: TValue;
begin
T := FindType(AQualifiedName);
V := T.GetMethod('Create').Invoke(T.AsInstance.MetaclassType, Params);
Result := V.AsObject;
end;
class function TRTTIUtils.Clone(Obj: TObject): TObject;
var
_ARttiType: TRttiType;
Field: TRttiField;
master, cloned: TObject;
Src: TObject;
sourceStream: TStream;
SavedPosition: Int64;
targetStream: TStream;
targetCollection: TObjectList<TObject>;
sourceCollection: TObjectList<TObject>;
I: Integer;
sourceObject: TObject;
targetObject: TObject;
begin
Result := nil;
if not Assigned(Obj) then
Exit;
_ARttiType := ctx.GetType(Obj.ClassType);
cloned := CreateObject(_ARttiType);
master := Obj;
for Field in _ARttiType.GetFields do
begin
if not Field.FieldType.IsInstance then
Field.SetValue(cloned, Field.GetValue(master))
else
begin
Src := Field.GetValue(Obj).AsObject;
if Src is TStream then
begin
sourceStream := TStream(Src);
SavedPosition := sourceStream.Position;
sourceStream.Position := 0;
if Field.GetValue(cloned).IsEmpty then
begin
targetStream := TMemoryStream.Create;
Field.SetValue(cloned, targetStream);
end
else
targetStream := Field.GetValue(cloned).AsObject as TStream;
targetStream.Position := 0;
targetStream.CopyFrom(sourceStream, sourceStream.Size);
targetStream.Position := SavedPosition;
sourceStream.Position := SavedPosition;
end
else if Src is TObjectList<TObject> then
begin
sourceCollection := TObjectList<TObject>(Src);
if Field.GetValue(cloned).IsEmpty then
begin
targetCollection := TObjectList<TObject>.Create;
Field.SetValue(cloned, targetCollection);
end
else
targetCollection := Field.GetValue(cloned).AsObject as TObjectList<TObject>;
for I := 0 to sourceCollection.Count - 1 do
begin
targetCollection.Add(TRTTIUtils.Clone(sourceCollection[I]));
end;
end
else
begin
sourceObject := Src;
if Field.GetValue(cloned).IsEmpty then
begin
targetObject := TRTTIUtils.Clone(sourceObject);
Field.SetValue(cloned, targetObject);
end
else
begin
targetObject := Field.GetValue(cloned).AsObject;
TRTTIUtils.CopyObject(sourceObject, targetObject);
end;
Field.SetValue(cloned, targetObject);
end;
end;
end;
Result := cloned;
end;
{ TListDuckTyping }
class function TRTTIUtils.HasAttribute<T>(aObj: TObject; out AAttribute: T): boolean;
begin
Result := HasAttribute<T>(ctx.GetType(aObj.ClassType), AAttribute)
end;
end.

216
src/Router4D.History.pas Normal file
View File

@ -0,0 +1,216 @@
unit Router4D.History;
interface
uses
Classes,
SysUtils,
FMX.Forms,
System.Generics.Collections,
Router4D.Interfaces,
FMX.Types,
Router4D.Props;
type
TCachePersistent = record
FPatch : String;
FisVisible : Boolean;
FSBKey : String;
FPersistentClass : TPersistentClass;
end;
TRouter4DHistory = class
private
FListCache : TObjectDictionary<String, TObject>;
FListCacheContainer : TObjectDictionary<String, TFMXObject>;
FListCache2 : TDictionary<String, TCachePersistent>;
FMainRouter : TFMXObject;
FIndexRouter : TFMXObject;
FInstanteObject : iRouter4DComponent;
procedure CreateInstancePersistent( aPath : String);
public
constructor Create;
destructor Destroy; override;
function MainRouter ( aValue : TFMXObject ) : TRouter4DHistory; overload;
function MainRouter : TFMXObject; overload;
function IndexRouter ( aValue : TFMXObject ) : TRouter4DHistory; overload;
function IndexRouter : TFMXObject; overload;
function AddHistory ( aKey : String; aObject : TObject ) : iRouter4DComponent; overload;
function AddHistory ( aKey : String; aObject : TPersistentClass ) : iRouter4DComponent; overload;
function AddHistory ( aKey : String; aObject : TPersistentClass; aSBKey : String; isVisible : Boolean ) : iRouter4DComponent; overload;
function AddHistoryConteiner ( aKey : String; aObject : TFMXObject) : TRouter4DHistory; overload;
function GetHistoryContainer ( aKey : String ) : TFMXObject;
function RemoveHistory ( aKey : String ) : TRouter4DHistory;
function GetHistory ( aKey : String ) : iRouter4DComponent;
function RoutersList : TDictionary<String, TObject>;
function RoutersListPersistent : TDictionary<String, TCachePersistent>;
function InstanteObject : iRouter4DComponent;
end;
var
Router4DHistory : TRouter4DHistory;
implementation
{ TRouter4DHistory }
function TRouter4DHistory.AddHistory( aKey : String; aObject : TObject ) : iRouter4DComponent;
var
mKey : String;
begin
if not Supports(aObject, iRouter4DComponent, Result) then
raise Exception.Create('Form not Implement iRouter4DelphiComponent Interface');
try GlobalEventBus.RegisterSubscriber(aObject); except end;
if FListCache.Count > 25 then
for mKey in FListCache.Keys do
begin
FListCache.Remove(aKey);
exit;
end;
FListCache.TryAdd(aKey, aObject);
end;
function TRouter4DHistory.AddHistory(aKey: String;
aObject: TPersistentClass): iRouter4DComponent;
var
CachePersistent : TCachePersistent;
begin
//if not Supports(aObject, iRouter4DComponent, Result) then
//raise Exception.Create('Form not Implement iRouter4DelphiComponent Interface');
CachePersistent.FPatch := aKey;
CachePersistent.FisVisible := True;
CachePersistent.FPersistentClass := aObject;
CachePersistent.FSBKey := 'SBIndex';
try FListCache2.Add(aKey, CachePersistent); except end;
end;
function TRouter4DHistory.AddHistory(aKey: String; aObject: TPersistentClass;
aSBKey : String; isVisible: Boolean): iRouter4DComponent;
var
CachePersistent : TCachePersistent;
begin
CachePersistent.FPatch := aKey;
CachePersistent.FisVisible := isVisible;
CachePersistent.FPersistentClass := aObject;
CachePersistent.FSBKey := aSBKey;
try FListCache2.TryAdd(aKey, CachePersistent); except end;
end;
function TRouter4DHistory.AddHistoryConteiner( aKey : String; aObject : TFMXObject) : TRouter4DHistory;
var
auxObject : TFMXObject;
begin
Result := Self;
if not FListCacheContainer.TryGetValue(aKey, auxObject) then
FListCacheContainer.TryAdd(aKey, aObject);
end;
constructor TRouter4DHistory.Create;
begin
FListCache := TObjectDictionary<String, TObject>.Create;
FListCache2 := TDictionary<String, TCachePersistent>.Create;
FListCacheContainer := TObjectDictionary<String, TFMXObject>.Create;
end;
procedure TRouter4DHistory.CreateInstancePersistent( aPath : String);
var
aPersistentClass : TCachePersistent;
begin
if not FListCache2.TryGetValue(aPath, aPersistentClass) then
raise Exception.Create('Not Register Router ' + aPath);
Self.AddHistory(
aPath,
TComponentClass(
FindClass(
aPersistentClass
.FPersistentClass
.ClassName
)
).Create(Application)
);
end;
destructor TRouter4DHistory.Destroy;
begin
FListCache.Free;
FListCache2.Free;
FListCacheContainer.Free;
inherited;
end;
function TRouter4DHistory.GetHistory(aKey: String): iRouter4DComponent;
var
aObject : TObject;
begin
if not FListCache.TryGetValue(aKey, aObject) then
Self.CreateInstancePersistent(aKey);
if not Supports(FListCache.Items[aKey], iRouter4DComponent, Result) then
raise Exception.Create('Object not Implements Interface Component');
FInstanteObject := Result;
end;
function TRouter4DHistory.GetHistoryContainer(aKey: String): TFMXObject;
begin
FListCacheContainer.TryGetValue(aKey, Result);
end;
function TRouter4DHistory.IndexRouter: TFMXObject;
begin
Result := FIndexRouter;
end;
function TRouter4DHistory.InstanteObject: iRouter4DComponent;
begin
Result := FInstanteObject;
end;
function TRouter4DHistory.IndexRouter(aValue: TFMXObject): TRouter4DHistory;
begin
Result := Self;
FIndexRouter := aValue;
end;
function TRouter4DHistory.MainRouter: TFMXObject;
begin
Result := FMainRouter;
end;
function TRouter4DHistory.RemoveHistory(aKey: String): TRouter4DHistory;
begin
Result := Self;
FListCache.Remove(aKey);
end;
function TRouter4DHistory.RoutersList: TDictionary<String, TObject>;
begin
Result := FListCache;
end;
function TRouter4DHistory.RoutersListPersistent: TDictionary<String, TCachePersistent>;
begin
Result := FListCache2;
end;
function TRouter4DHistory.MainRouter(aValue: TFMXObject): TRouter4DHistory;
begin
Result := Self;
FMainRouter := aValue;
end;
initialization
Router4DHistory := TRouter4DHistory.Create;
finalization
Router4DHistory.Free;
end.

View File

@ -0,0 +1,67 @@
unit Router4D.Interfaces;
interface
uses
System.Classes,
System.Generics.Collections,
System.UITypes,
SysUtils,
FMX.Types,
Router4D.Props;
type
iRouter4D = interface
['{56BF88E9-25AB-49C7-8CB2-F89C95F34816}']
end;
iRouter4DComponent = interface
['{C605AEFB-36DC-4952-A3D9-BA372B998BC3}']
function Render : TFMXObject;
procedure UnRender;
end;
iRouter4DComponentProps = interface
['{FAF5DD55-924F-4A8B-A436-208891FFE30A}']
procedure Props ( aProps : TProps );
end;
iRouter4DLink = interface
['{3C80F86A-D6B8-470C-A30E-A82E620F6F1D}']
function &To ( aPatch : String; aComponent : TFMXObject ) : iRouter4DLink; overload;
function &To ( aPatch : String) : iRouter4DLink; overload;
function &To ( aPatch : String; aProps : TProps; aKey : String = '') : iRouter4DLink; overload;
function &To ( aPatch : String; aNameContainer : String) : iRouter4DLink; overload;
function Animation ( aAnimation : TProc<TFMXObject> ) : iRouter4DLink;
function IndexLink ( aPatch : String ) : iRouter4DLink;
end;
iRouter4DRender = interface
['{2BD026ED-3A92-44E9-8CD4-38E80CB2F000}']
function SetElement ( aComponent : TFMXObject; aIndexComponent : TFMXObject = nil ) : iRouter4DRender;
end;
iRouter4DSwitch = interface
['{0E49AFE7-9329-4F0C-B289-A713FA3DFE45}']
function Router(aPath : String; aRouter : TPersistentClass; aSidebarKey : String = 'SBIndex'; isVisible : Boolean = True) : iRouter4DSwitch;
function UnRouter(aPath : String) : iRouter4DSwitch;
end;
iRouter4DSidebar = interface
['{B4E8C229-A801-4FCA-AF7B-DEF8D0EE5DFE}']
function Name ( aValue : String ) : iRouter4DSidebar; overload;
function MainContainer ( aValue : TFMXObject ) : iRouter4DSidebar; overload;
function Name : String; overload;
function MainContainer : TFMXObject; overload;
function FontSize ( aValue : Integer ) : iRouter4DSidebar;
function FontColor ( aValue : TAlphaColor ) : iRouter4DSidebar;
function ItemHeigth ( aValue : Integer ) : iRouter4DSidebar;
function LinkContainer ( aValue : TFMXObject ) : iRouter4DSidebar;
function RenderToListBox : iRouter4DSidebar;
function Animation ( aAnimation : TProc<TFMXObject> ) : iRouter4DSidebar;
end;
implementation
end.

147
src/Router4D.Link.pas Normal file
View File

@ -0,0 +1,147 @@
unit Router4D.Link;
interface
uses
FMX.Types,
FMX.Layouts,
SysUtils,
Router4D.Interfaces,
Router4D.Props;
type
TRouter4DLink = class(TInterfacedObject, iRouter4DLink)
private
FAnimation : TProc<TFMXObject>;
public
constructor Create;
destructor Destroy; override;
class function New : iRouter4DLink;
function Animation ( aAnimation : TProc<TFMXObject> ) : iRouter4DLink;
function &To ( aPatch : String; aComponent : TFMXObject ) : iRouter4DLink; overload;
function &To ( aPatch : String) : iRouter4DLink; overload;
function &To ( aPatch : String; aProps : TProps; aKey : String = '') : iRouter4DLink; overload;
function &To ( aPatch : String; aNameContainer : String) : iRouter4DLink; overload;
function IndexLink ( aPatch : String ) : iRouter4DLink;
end;
implementation
{ TRouter4DLink }
uses Router4D.History;
function TRouter4DLink.&To( aPatch : String; aComponent : TFMXObject ) : iRouter4DLink;
begin
Result := Self;
aComponent.RemoveObject(0);
Router4DHistory.InstanteObject.UnRender;
aComponent
.AddObject(
Router4DHistory
.GetHistory(aPatch)
.Render
);
end;
function TRouter4DLink.&To(aPatch, aNameContainer: String): iRouter4DLink;
var
aContainer : TFMXObject;
begin
Result := Self;
Router4DHistory.InstanteObject.UnRender;
aContainer := Router4DHistory.GetHistoryContainer(aNameContainer);
aContainer.RemoveObject(0);
aContainer
.AddObject(
Router4DHistory
.GetHistory(aPatch)
.Render
);
if Assigned(FAnimation) then
FAnimation(aContainer);
end;
function TRouter4DLink.Animation(aAnimation: TProc<TFMXObject>): iRouter4DLink;
begin
Result := Self;
FAnimation := aAnimation;
end;
constructor TRouter4DLink.Create;
begin
end;
destructor TRouter4DLink.Destroy;
begin
inherited;
end;
function TRouter4DLink.IndexLink(aPatch: String): iRouter4DLink;
begin
Result := Self;
Router4DHistory.IndexRouter.RemoveObject(0);
Router4DHistory.InstanteObject.UnRender;
Router4DHistory
.IndexRouter
.AddObject(
Router4DHistory
.GetHistory(aPatch)
.Render
);
if Assigned(FAnimation) then
FAnimation(Router4DHistory.IndexRouter);
end;
function TRouter4DLink.&To(aPatch: String) : iRouter4DLink;
begin
Result := Self;
Router4DHistory.MainRouter.RemoveObject(0);
Router4DHistory.InstanteObject.UnRender;
Router4DHistory
.MainRouter
.AddObject(
Router4DHistory
.GetHistory(aPatch)
.Render
);
if Assigned(FAnimation) then
FAnimation(Router4DHistory.MainRouter);
end;
function TRouter4DLink.&To(aPatch: String; aProps: TProps; aKey : String = '') : iRouter4DLink;
begin
Result := Self;
Router4DHistory.MainRouter.RemoveObject(0);
Router4DHistory.InstanteObject.UnRender;
Router4DHistory
.MainRouter
.AddObject(
Router4DHistory
.GetHistory(aPatch)
.Render
);
if Assigned(FAnimation) then
FAnimation(Router4DHistory.MainRouter);
if aKey <> '' then aProps.Key(aKey);
GlobalEventBus.Post(aProps);
end;
class function TRouter4DLink.New: iRouter4DLink;
begin
Result := Self.Create;
end;
end.

273
src/Router4D.Props.pas Normal file
View File

@ -0,0 +1,273 @@
{ *******************************************************************************
Copyright 2016-2019 Daniele Spinetti
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
******************************************************************************** }
unit Router4D.Props;
interface
uses
System.Classes,
System.SysUtils,
System.Rtti;
type
TThreadMode = (Posting, Main, Async, Background);
TCloneEventCallback = function(const AObject: TObject): TObject of object;
TCloneEventMethod = TFunc<TObject, TObject>;
IEventBus = Interface
['{7BDF4536-F2BA-4FBA-B186-09E1EE6C7E35}']
procedure RegisterSubscriber(ASubscriber: TObject);
function IsRegistered(ASubscriber: TObject): Boolean;
procedure Unregister(ASubscriber: TObject);
procedure Post(AEvent: TObject; const AContext: String = '';
AEventOwner: Boolean = true);
procedure SetOnCloneEvent(const aCloneEvent: TCloneEventCallback);
procedure AddCustomClassCloning(const AQualifiedClassName: String;
const aCloneEvent: TCloneEventMethod);
procedure RemoveCustomClassCloning(const AQualifiedClassName: String);
property OnCloneEvent: TCloneEventCallback write SetOnCloneEvent;
end;
SubscribeAttribute = class(TCustomAttribute)
private
FContext: String;
FThreadMode: TThreadMode;
public
constructor Create(AThreadMode: TThreadMode = TThreadMode.Posting;
const AContext: String = '');
property ThreadMode: TThreadMode read FThreadMode;
property Context: String read FContext;
end;
TDEBEvent<T> = class(TObject)
private
FDataOwner: Boolean;
FData: T;
procedure SetData(const Value: T);
procedure SetDataOwner(const Value: Boolean);
public
constructor Create; overload;
constructor Create(AData: T); overload;
destructor Destroy; override;
property DataOwner: Boolean read FDataOwner write SetDataOwner;
property Data: T read FData write SetData;
end;
TProps = class
private
FPropString: String;
FPropInteger: Integer;
FPropCurrency : Currency;
FPropDouble : Double;
FPropValue : TValue;
FPropObject : TObject;
FPropDateTime : TDateTime;
FKey : String;
public
constructor Create;
destructor Destroy; override;
function PropString ( aProp : String ) : TProps; overload;
function PropString : String; overload;
function PropInteger ( aProp : Integer ) : TProps; overload;
function PropInteger : Integer; overload;
function PropCurrency ( aProp : Currency ) : TProps; overload;
function PropCurrency : Currency; overload;
function PropDouble ( aProp : Double ) : TProps; overload;
function PropDouble : Double; overload;
function PropValue ( aProp : TValue ) : TProps; overload;
function PropValue : TValue; overload;
function PropObject ( aProp : TObject ) : TProps; overload;
function PropObject : TObject; overload;
function PropDateTime ( aProp : TDateTime ) : TProps; overload;
function PropDateTime : TDateTime; overload;
function Key ( aKey : String ) : TProps; overload;
function Key : String; overload;
end;
function GlobalEventBus: IEventBus;
implementation
uses
EventBus.Core, RTTIUtilsU;
var
FGlobalEventBus: IEventBus;
{ SubscribeAttribute }
constructor SubscribeAttribute.Create(AThreadMode
: TThreadMode = TThreadMode.Posting; const AContext: String = '');
begin
inherited Create;
FContext := AContext;
FThreadMode := AThreadMode;
end;
{ TDEBSimpleEvent<T> }
constructor TDEBEvent<T>.Create(AData: T);
begin
inherited Create;
DataOwner := true;
Data := AData;
end;
constructor TDEBEvent<T>.Create;
begin
inherited Create;
end;
destructor TDEBEvent<T>.Destroy;
var
LValue: TValue;
begin
LValue := TValue.From<T>(Data);
if (LValue.IsObject) and DataOwner then
LValue.AsObject.Free;
inherited;
end;
procedure TDEBEvent<T>.SetData(const Value: T);
begin
FData := Value;
end;
procedure TDEBEvent<T>.SetDataOwner(const Value: Boolean);
begin
FDataOwner := Value;
end;
function GlobalEventBus: IEventBus;
begin
if not Assigned(FGlobalEventBus) then
FGlobalEventBus := TEventBus.Create;
Result := FGlobalEventBus;
end;
{ TProps }
constructor TProps.Create;
begin
end;
destructor TProps.Destroy;
begin
inherited;
end;
function TProps.Key(aKey: String): TProps;
begin
Result := Self;
FKey := aKey;
end;
function TProps.Key: String;
begin
Result := FKey;
end;
function TProps.PropCurrency: Currency;
begin
Result := FPropCurrency;
end;
function TProps.PropDateTime: TDateTime;
begin
Result := FPropDateTime;
end;
function TProps.PropDateTime(aProp: TDateTime): TProps;
begin
Result := Self;
FPropDateTime := aProp;
end;
function TProps.PropDouble: Double;
begin
Result := FPropDouble;
end;
function TProps.PropDouble(aProp: Double): TProps;
begin
Result := Self;
FPropDouble := aProp;
end;
function TProps.PropCurrency(aProp: Currency): TProps;
begin
Result := Self;
FPropCurrency := aProp;
end;
function TProps.PropInteger: Integer;
begin
Result := FPropInteger;
end;
function TProps.PropObject: TObject;
begin
Result := FPropObject;
end;
function TProps.PropObject(aProp: TObject): TProps;
begin
Result := Self;
FPropObject := aProp;
end;
function TProps.PropInteger(aProp: Integer): TProps;
begin
Result := Self;
FPropInteger := aProp;
end;
function TProps.PropString(aProp: String): TProps;
begin
Result := Self;
FPropString := aProp;
end;
function TProps.PropString: String;
begin
Result := FPropString;
end;
function TProps.PropValue: TValue;
begin
Result := FPropValue;
end;
function TProps.PropValue(aProp: TValue): TProps;
begin
Result := Self;
FPropValue := aProp;
end;
initialization
GlobalEventBus;
finalization
end.

61
src/Router4D.Render.pas Normal file
View File

@ -0,0 +1,61 @@
unit Router4D.Render;
interface
uses
Router4D.Interfaces,
FMX.Types;
type
TRouter4DRender = class(TInterfacedObject, iRouter4DRender)
private
[weak]
FParent : iRouter4DComponent;
public
constructor Create(Parent : iRouter4DComponent);
destructor Destroy; override;
class function New(Parent : iRouter4DComponent) : iRouter4DRender;
function SetElement ( aComponent : TFMXObject; aIndexComponent : TFMXObject = nil ) : iRouter4DRender;
end;
implementation
uses
Router4D.History;
{ TRouter4DelphiRender }
constructor TRouter4DRender.Create(Parent: iRouter4DComponent);
begin
FParent := Parent;
end;
destructor TRouter4DRender.Destroy;
begin
inherited;
end;
function TRouter4DRender.SetElement( aComponent : TFMXObject; aIndexComponent : TFMXObject = nil ) : iRouter4DRender;
begin
Result := Self;
Router4DHistory.MainRouter(aComponent);
if aIndexComponent <> nil then
Router4DHistory.IndexRouter(aIndexComponent);
if Assigned(FParent) then
begin
aComponent.RemoveObject(0);
aComponent.AddObject(FParent.Render);
end;
end;
class function TRouter4DRender.New(
Parent: iRouter4DComponent): iRouter4DRender;
begin
Result := Self.Create(Parent);
end;
end.

182
src/Router4D.Sidebar.pas Normal file
View File

@ -0,0 +1,182 @@
unit Router4D.Sidebar;
interface
uses
Classes,
SysUtils,
FMX.Types,
Router4D.Interfaces,
System.UITypes;
type
TRouter4DSidebar = class(TInterfacedObject, iRouter4DSidebar)
private
FName : String;
FMainContainer : TFMXObject;
FFontSize : Integer;
FFontColor : TAlphaColor;
FItemHeigth : Integer;
FLinkContainer : TFMXObject;
FAnimation : TProc<TFMXObject>;
public
constructor Create;
destructor Destroy; override;
class function New : iRouter4DSidebar;
function Animation ( aAnimation : TProc<TFMXObject> ) : iRouter4DSidebar;
function Name ( aValue : String ) : iRouter4DSidebar; overload;
function MainContainer ( aValue : TFMXObject ) : iRouter4DSidebar; overload;
function Name : String; overload;
function MainContainer : TFMXObject; overload;
function FontSize ( aValue : Integer ) : iRouter4DSidebar;
function FontColor ( aValue : TAlphaColor ) : iRouter4DSidebar;
function ItemHeigth ( aValue : Integer ) : iRouter4DSidebar;
function LinkContainer ( aValue : TFMXObject ) : iRouter4DSidebar;
function RenderToListBox : iRouter4DSidebar;
end;
implementation
uses
FMX.ListBox,
FMX.SearchBox,
FMX.Layouts,
Router4D,
Router4D.History,
Router4D.Utils;
{ TRouter4DSidebar }
function TRouter4DSidebar.Animation(
aAnimation: TProc<TFMXObject>): iRouter4DSidebar;
begin
Result := Self;
FAnimation := aAnimation;
end;
constructor TRouter4DSidebar.Create;
begin
FName := 'SBIndex';
FLinkContainer := Router4DHistory.MainRouter;
end;
destructor TRouter4DSidebar.Destroy;
begin
inherited;
end;
function TRouter4DSidebar.FontColor(aValue: TAlphaColor): iRouter4DSidebar;
begin
Result := Self;
FFontColor := aValue;
end;
function TRouter4DSidebar.FontSize(aValue: Integer): iRouter4DSidebar;
begin
Result := Self;
FFontSize := aValue;
end;
function TRouter4DSidebar.ItemHeigth(aValue: Integer): iRouter4DSidebar;
begin
Result := Self;
FItemHeigth := aValue;
end;
function TRouter4DSidebar.LinkContainer(aValue: TFMXObject): iRouter4DSidebar;
begin
Result := Self;
FLinkContainer := aValue;
end;
function TRouter4DSidebar.MainContainer(aValue: TFMXObject): iRouter4DSidebar;
begin
Result := Self;
FMainContainer := aValue;
end;
function TRouter4DSidebar.MainContainer: TFMXObject;
begin
Result := FMainContainer;
end;
function TRouter4DSidebar.Name(aValue: String): iRouter4DSidebar;
begin
Result := Self;
FName := aValue;
end;
function TRouter4DSidebar.Name: String;
begin
Result := FName;
end;
class function TRouter4DSidebar.New: iRouter4DSidebar;
begin
Result := Self.Create;
end;
function TRouter4DSidebar.RenderToListBox: iRouter4DSidebar;
var
aListBox : TListBox;
aListBoxItem : TListBoxItem;
aItem : TCachePersistent;
AListBoxSearch : TSearchBox;
begin
aListBox := TListBox.Create(FMainContainer);
aListBox.Align := TAlignLayout.Client;
aListBox.ItemHeight := FItemHeigth;
aListBox.StyleLookup := 'transparentlistboxstyle';
aListBox.BeginUpdate;
AListBoxSearch := TSearchBox.Create(aListBox);
AListBoxSearch.Height := FItemHeigth - 25;
aListBox.AddObject(AListBoxSearch);
for aItem in Router4DHistory.RoutersListPersistent.Values do
begin
if AItem.FisVisible and (AItem.FSBKey = FName) then
begin
aListBoxItem := TListBoxItem.Create(aListBox);
aListBoxItem.Parent := aListBox;
aListBoxItem.StyledSettings:=[TStyledSetting.Other];
aListBoxItem.TextSettings.Font.Size := FFontSize;
aListBoxItem.FontColor := FFontColor;
aListBoxItem.Text := aItem.FPatch;
aListBox.AddObject(aListBoxItem);
end;
end;
aListBox.EndUpdate;
Router4DHistory.AddHistoryConteiner(FName, FLinkContainer);
aListBox.OnClick :=
TNotifyEventWrapper
.AnonProc2NotifyEvent(
aListBox,
procedure(Sender: TObject; Aux : String)
begin
TRouter4D
.Link
.Animation(
procedure ( aObject : TFMXObject )
begin
TLayout(aObject).Opacity := 0;
TLayout(aObject).AnimateFloat('Opacity', 1, 0.2);
end)
.&To(
(Sender as TListBox).Items[(Sender as TListBox).ItemIndex],
Aux
)
end,
FName
);
FMainContainer.AddObject(aListBox);
end;
end.

73
src/Router4D.Switch.pas Normal file
View File

@ -0,0 +1,73 @@
unit Router4D.Switch;
interface
uses
Classes,
System.Generics.Collections,
Router4D.Interfaces,
Router4D.History;
type
TRouter4DSwitch = class(TInterfacedObject, iRouter4DSwitch)
private
FSideBarList : TDictionary<String, iRouter4DSidebar>;
public
constructor Create;
destructor Destroy; override;
class function New : iRouter4DSwitch;
function Router(aPath : String; aRouter : TPersistentClass; aSidebarKey : String = 'SBIndex'; isVisible : Boolean = True) : iRouter4DSwitch;
function UnRouter(aPath : String) : iRouter4DSwitch;
function SidebarAdd ( aPatch : String; aSideBar : iRouter4DSidebar) : iRouter4DSwitch;
function SideBarList : TDictionary<String, iRouter4DSidebar>;
end;
implementation
{ TRouter4DSwitch }
uses
Router4D.Utils;
constructor TRouter4DSwitch.Create;
begin
FSideBarList := TDictionary<String, iRouter4DSidebar>.Create;
end;
destructor TRouter4DSwitch.Destroy;
begin
FSideBarList.Free;
inherited;
end;
class function TRouter4DSwitch.New: iRouter4DSwitch;
begin
Result := Self.Create;
end;
function TRouter4DSwitch.Router(aPath : String; aRouter : TPersistentClass; aSidebarKey : String = 'SBIndex'; isVisible : Boolean = True) : iRouter4DSwitch;
begin
Result := Self;
RegisterClass(aRouter);
Router4DHistory.AddHistory(aPath, aRouter, aSidebarKey, isVisible);
end;
function TRouter4DSwitch.SidebarAdd(aPatch: String;
aSideBar: iRouter4DSidebar): iRouter4DSwitch;
begin
Result := Self;
FSideBarList.Add(aPatch, aSideBar);
end;
function TRouter4DSwitch.SideBarList: TDictionary<String, iRouter4DSidebar>;
begin
Result := FSideBarList;
end;
function TRouter4DSwitch.UnRouter(aPath: String) : iRouter4DSwitch;
begin
Result := Self;
Router4DHistory.RemoveHistory(aPath);
end;
end.

82
src/Router4D.Utils.pas Normal file
View File

@ -0,0 +1,82 @@
unit Router4D.Utils;
interface
uses
System.Rtti,
Router4D.Props,
SysUtils,
Classes;
type
TRouter4DUtils = class
private
public
class function CreateInstance<T> : T;
end;
TNotifyEventWrapper = class(TComponent)
private
FProc: TProc<TObject, String>;
FAux : String;
public
constructor Create(Owner: TComponent; Proc: TProc<TObject, String>; Aux : String = ''); virtual;
class function AnonProc2NotifyEvent(Owner: TComponent; Proc: TProc<TObject, String>; Aux : String = ''): TNotifyEvent;
published
procedure Event(Sender: TObject);
end;
implementation
{ TRouter4DUtils }
class function TRouter4DUtils.CreateInstance<T>: T;
var
AValue: TValue;
ctx: TRttiContext;
rType: TRttiType;
AMethCreate: TRttiMethod;
instanceType: TRttiInstanceType;
begin
ctx := TRttiContext.Create;
rType := ctx.GetType(TypeInfo(T));
for AMethCreate in rType.GetMethods do
begin
if (AMethCreate.IsConstructor) and (Length(AMethCreate.GetParameters) = 1) then
begin
instanceType := rType.AsInstance;
AValue := AMethCreate.Invoke(instanceType.MetaclassType, [nil]);
Result := AValue.AsType<T>;
try
GlobalEventBus.RegisterSubscriber(AValue.AsType<TObject>);
except
end;
Exit;
end;
end;
end;
{ TNotifyEventWrapper }
class function TNotifyEventWrapper.AnonProc2NotifyEvent(Owner: TComponent; Proc: TProc<TObject, String>; Aux : String = ''): TNotifyEvent;
begin
Result := Self.Create(Owner, Proc, Aux).Event;
end;
constructor TNotifyEventWrapper.Create(Owner: TComponent; Proc: TProc<TObject, String>; Aux : String = '');
begin
inherited Create(Owner);
FProc := Proc;
FAux := Aux;
end;
procedure TNotifyEventWrapper.Event(Sender: TObject);
begin
FProc(Sender, FAux);
end;
end.

90
src/Router4D.pas Normal file
View File

@ -0,0 +1,90 @@
unit Router4D;
interface
uses
System.Generics.Collections,
System.Classes,
System.Rtti,
System.TypInfo,
SysUtils,
FMX.Types,
Router4D.Interfaces,
Router4D.History,
Router4D.Render,
Router4D.Link;
type
TRouter4D = class(TInterfacedObject, iRouter4D)
private
public
constructor Create;
destructor Destroy; override;
class function New : iRouter4D;
class function Render<T : class, constructor> : iRouter4DRender;
class function Link : iRouter4DLink;
class function Switch : iRouter4DSwitch;
class function SideBar : iRouter4DSidebar;
end;
implementation
{ TRouter4Delphi }
uses
Router4D.Utils,
Router4D.Switch,
Router4D.Sidebar;
constructor TRouter4D.Create;
begin
end;
destructor TRouter4D.Destroy;
begin
inherited;
end;
class function TRouter4D.Link: iRouter4DLink;
begin
Result := TRouter4DLink.New;
end;
class function TRouter4D.New: iRouter4D;
begin
Result := Self.Create;
end;
class function TRouter4D.Render<T>: iRouter4DRender;
begin
Router4DHistory
.AddHistory(
TPersistentClass(T).ClassName,
TPersistentClass(T)
);
Result :=
TRouter4DRender
.New(
Router4DHistory
.GetHistory(
TPersistentClass(T)
.ClassName
)
);
end;
class function TRouter4D.SideBar: iRouter4DSidebar;
begin
Result := TRouter4DSidebar.New;
end;
class function TRouter4D.Switch: iRouter4DSwitch;
begin
Result := TRouter4DSwitch.New;
end;
end.