Improved XE5 mobile previews part 2

Last time around I blogged about how to extract the default XE5 mobile styles into *.style files – in a nutshell, you need to create an app that extracts the desired style resource to a file, then open the file in the stylebook editor, delete the ‘Description’ resource, and resave. In that post I went on to suggest using the extracted files in TStyleBook components. There is however a better way – provide a custom FMX.MobilePreview unit instead (NB: for all about the standard mobile previews – introduced in XE5 update 2 – check out either Marco Cantù’s blog post or the documentation).

To do this, create a new unit and, modeling on the standard FMX.MobilePreview.pas, add the following code:

unit FMX.MobilePreview;
{
  Use actual Android style
}
interface

implementation

{$IFDEF MSWINDOWS}

{$IF CompilerVersion <> 26}
  {$MESSAGE Error 'Custom FMX.MobilePreview.pas expects XE5!'}
{$IFEND}

uses
  System.Types, System.SysUtils, FMX.Styles, FMX.Graphics, FMX.Platform;

var
  OldInitProc: TProcedure;

procedure InitializeStyle;
begin
  if Assigned(OldInitProc) then
    OldInitProc();
  //!!!change path to whereever you have put the resaved *.style file
  TStyleManager.SetStyle(TStyleManager.LoadFromFile('C:\Delphi\LibXE5\Android.style'));
end;

initialization
  OldInitProc := InitProc;
  InitProc := @InitializeStyle;

finalization
  TStyleManager.SetStyle(nil);
  TCanvasManager.UnInitialize;
{$ENDIF}
end.

If you save the unit as FMX.MobilePreview.pas, compile and ensure the DCUs are in the global search path, you can have the IDE pick it up rather than the standard FMX.MobilePreview.pas. Alternatively, save it under a different name and just amend your project files to use it rather than FMX.MobilePreview.

That said, if you do this, something still won’t quite be right – namely, the font:

Font not right

This is because in the current FireMonkey code, the default font is a property of the platform rather than the style. As such, the font used here is a regular Windows one rather than Roboto, the default font on Android. Fixing this discrepancy is easy however – back in the custom unit, first add the following class immediately after the uses clause:

type
  TFMXSystemFontService = class(TInterfacedObject, IFMXSystemFontService)
  public
    function GetDefaultFontFamilyName: string;
  end;

function TFMXSystemFontService.GetDefaultFontFamilyName: string;
begin
  Result := 'Roboto';
end;

Secondly, unregister the standard IFMXSystemFontService implementation before registering our own by adding the following lines at the top of the unit’s initialization block:

  TPlatformServices.Current.RemovePlatformService(IFMXSystemFontService);
  TPlatformServices.Current.AddPlatformService(IFMXSystemFontService, TFMXSystemFontService.Create);

In all, the code for unit should now look like this:

unit FMX.MobilePreview;
{
  Use actual Android style
}
interface

implementation

{$IFDEF MSWINDOWS}
{$IF CompilerVersion <> 26}
  {$MESSAGE Error 'Custom FMX.MobilePreview.pas expects XE5!'}
{$IFEND}
uses
  System.Types, System.SysUtils, FMX.Styles, FMX.Graphics, FMX.Platform;

type
  TFMXSystemFontService = class(TInterfacedObject, IFMXSystemFontService)
  public
    function GetDefaultFontFamilyName: string;
  end;

function TFMXSystemFontService.GetDefaultFontFamilyName: string;
begin
  Result := 'Roboto';
end;

var
  OldInitProc: TProcedure;

procedure InitializeStyle;
begin
  if Assigned(OldInitProc) then
    OldInitProc();
  TStyleManager.SetStyle(TStyleManager.LoadFromFile('C:\Users\CCR\Downloads\Android FMX (resaved, and minus description).style'));
end;

initialization
  TPlatformServices.Current.RemovePlatformService(IFMXSystemFontService);
  TPlatformServices.Current.AddPlatformService(IFMXSystemFontService, TFMXSystemFontService.Create);
  OldInitProc := InitProc;
  InitProc := @InitializeStyle;

finalization
  TStyleManager.SetStyle(nil);
  TCanvasManager.UnInitialize;
{$ENDIF}
end.

Run the mobile preview again, and the font is now how it should be:

Font fixed

Advertisements

2 thoughts on “Improved XE5 mobile previews part 2

    • Because I’m personally only interested in Android at the moment. If you’re not, then do what you need to do…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s