Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielMazurFL4RE committed Apr 23, 2019
1 parent 610db86 commit 1e866dd
Show file tree
Hide file tree
Showing 45 changed files with 49,082 additions and 9,237 deletions.
2,842 changes: 2,842 additions & 0 deletions HODLER_Multiplatform_Win_And_iOS_Linux/FMX.Ani.pas

Large diffs are not rendered by default.

942 changes: 942 additions & 0 deletions HODLER_Multiplatform_Win_And_iOS_Linux/FMX.Context.GLES.Android.pas

Large diffs are not rendered by default.

6,122 changes: 6,122 additions & 0 deletions HODLER_Multiplatform_Win_And_iOS_Linux/FMX.Platform.Win.pas

Large diffs are not rendered by default.

365 changes: 365 additions & 0 deletions HODLER_Multiplatform_Win_And_iOS_Linux/FMX.VirtualKeyboard.Android.xxx
@@ -0,0 +1,365 @@
{*******************************************************}
{ }
{ Delphi FireMonkey Platform }
{ Copyright(c) 2013-2017 Embarcadero Technologies, Inc. }
{ All rights reserved }
{ }
{*******************************************************}

unit FMX.VirtualKeyboard.Android;

interface

{$SCOPEDENUMS ON}

uses
System.Classes, System.SysUtils, System.UITypes, System.Types,
System.SyncObjs, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Embarcadero, Androidapi.JNI.JavaTypes,
Androidapi.JNIBridge, FMX.Types, FMX.Helpers.Android, FMX.VirtualKeyboard,System.Messaging, FMX.Forms, FMX.Platform.Android, FMX.Platform,Androidapi.JNI.Util;
type
TVirtualKeyboardRect = class;

TGlobalLayoutListener = class(TJavaLocal, JViewTreeObserver_OnGlobalLayoutListener)
private
FVirtualKeyboardRect: TVirtualKeyboardRect;
public
{ JViewTreeObserver_OnGlobalLayoutListener }
procedure onGlobalLayout; cdecl;
public
constructor Create(const AVirtualKeyboardRect: TVirtualKeyboardRect);
end;

TVirtualKeyboardRect = class(TInterfacedObject)
private
FCanFireEvent: Boolean;
FListener: JViewTreeObserver_OnGlobalLayoutListener;
FPendingShow: Boolean;
FVKListener: TVKListener;
FVKVisible: Boolean;
procedure ApplicationEventMessageHandler(const Sender: TObject; const M: TMessage);
procedure InstallListener;
procedure RemoveListener;
procedure VirtualKeyboardHidden;
procedure VirtualKeyboardShown;
protected
procedure GlobalLayoutChange;
property CanFireEvent: Boolean read FCanFireEvent;
property VKListener: TVKListener read FVKListener write FVKListener;
public
constructor Create;
destructor Destroy; override;
end;

{ TGlobalLayoutListener }

constructor TGlobalLayoutListener.Create(const AVirtualKeyboardRect: TVirtualKeyboardRect);
begin
inherited Create;
FVirtualKeyboardRect := AVirtualKeyboardRect;
end;

procedure TGlobalLayoutListener.onGlobalLayout;
begin
FVirtualKeyboardRect.GlobalLayoutChange;
end;

{ TVirtualKeyboardRect }

constructor TVirtualKeyboardRect.Create;
begin
inherited;
TMessageManager.DefaultManager.SubscribeToMessage(TApplicationEventMessage, ApplicationEventMessageHandler);
end;

destructor TVirtualKeyboardRect.Destroy;
begin
if FListener <> nil then
RemoveListener;
TMessageManager.DefaultManager.Unsubscribe(TApplicationEventMessage, ApplicationEventMessageHandler);
inherited;
end;

procedure TVirtualKeyboardRect.ApplicationEventMessageHandler(const Sender: TObject; const M: TMessage);
begin
case TApplicationEventMessage(M).Value.Event of
TApplicationEvent.BecameActive:
begin
if FListener = nil then
InstallListener;
end;
end;
end;

procedure TVirtualKeyboardRect.VirtualKeyboardHidden;
begin
FVKVisible := False;
end;

procedure TVirtualKeyboardRect.VirtualKeyboardShown;
begin
FPendingShow := True;
FVKVisible := True;
end;

procedure TVirtualKeyboardRect.GlobalLayoutChange;
begin
if FPendingShow then
begin
FCanFireEvent := True;
try
FVKListener.onVirtualKeyboardShown;
finally
FCanFireEvent := False;
end;
end
else if FVKVisible and not FCanFireEvent then
TMessageManager.DefaultManager.SendMessage(Self, TVKStateChangeMessage.Create(True, FVKListener.ObtainKeyboardRect), True);
FPendingShow := False;
end;

procedure TVirtualKeyboardRect.InstallListener;
begin
FListener := TGlobalLayoutListener.Create(Self);
MainActivity.getWindow.getDecorView.getViewTreeObserver.addOnGlobalLayoutListener(FListener);
end;

procedure TVirtualKeyboardRect.RemoveListener;
begin
MainActivity.getWindow.getDecorView.getViewTreeObserver.removeGlobalOnLayoutListener(FListener);
end;

var
VirtualKeyboardRect: TVirtualKeyboardRect;

type
TVirtualKeyboardAndroid = class;

TVKListener = class(TJavaLocal, JVKStateChangeListener)
private
[Weak] FKeyboardService: TVirtualKeyboardAndroid;
FEvent: TEvent;
function ObtainKeyboardRect: TRect;
public
constructor Create(const AService: TVirtualKeyboardAndroid);
destructor Destroy; override;
procedure ResetEvent;
procedure WaitEvent;
{ JVKStateChangeListener }
procedure onVirtualKeyboardShown; cdecl;
procedure onVirtualKeyboardHidden; cdecl;
end;

TVirtualKeyboardAndroid = class(TInterfacedObject, IFMXVirtualKeyboardService)
private type
TvkbState = (Hidden, Shown);
private
FState: TvkbState;
FVKListener: TVKListener;
FTransient: Boolean;
function IsAutoShow: Boolean;
procedure SetState(Value: TvkbState);
procedure RegisterListener;
procedure RegisterService;
procedure UnregisterService;
public
constructor Create;
destructor Destroy; override;
{ IFMXVirtualKeyboardService }
function ShowVirtualKeyboard(const AControl: TFmxObject): Boolean;
function HideVirtualKeyboard: Boolean;
function GetVirtualKeyboardState: TVirtualKeyboardStates;
procedure SetTransientState(Value: Boolean);
property VirtualKeyboardState: TVirtualKeyboardStates read GetVirtualKeyboardState;
end;

implementation

uses
System.Messaging, FMX.Forms, FMX.Platform.Android, FMX.Platform;

{ TAndroidVirtualKeyboardService }

function TVirtualKeyboardAndroid.IsAutoShow: Boolean;
begin
Result := VKAutoShowMode in [TVKAutoShowMode.Always, TVKAutoShowMode.DefinedBySystem];
end;

procedure TVirtualKeyboardAndroid.RegisterListener;
begin
if FVKListener = nil then
begin
FVKListener := TVKListener.Create(Self);
MainActivity.getTextEditorProxy.addOnVKStateChangeListener(FVKListener);
end;
end;

procedure TVirtualKeyboardAndroid.RegisterService;
begin
if not TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService) then
TPlatformServices.Current.AddPlatformService(IFMXVirtualKeyboardService, Self);
end;

constructor TVirtualKeyboardAndroid.Create;
begin
inherited;
RegisterService;
end;

destructor TVirtualKeyboardAndroid.Destroy;
begin
UnregisterService;
inherited;
end;

function TVirtualKeyboardAndroid.GetVirtualKeyboardState: TVirtualKeyboardStates;
begin
Result := [];
if IsAutoShow then
Include(Result, TVirtualKeyboardState.AutoShow);
if FTransient then
Include(Result, TVirtualKeyboardState.Transient);
if FState = TvkbState.Shown then
Include(Result, TVirtualKeyboardState.Visible);
end;

function TVirtualKeyboardAndroid.HideVirtualKeyboard: Boolean;
var
TextView: JFMXTextEditorProxy;
begin
Result := False;
try
if not FTransient then
begin
RegisterListener;
TextView := MainActivity.getTextEditorProxy;
FVKListener.ResetEvent;
TextView.setFocusable(false);
TextView.setFocusableInTouchMode(false);
TextView.showSoftInput(false);
TextView.clearFocus;
FVKListener.WaitEvent;
Result := FState = TvkbState.Hidden;
end
except
Application.HandleException(Screen.ActiveForm);
end;
end;

function TVirtualKeyboardAndroid.ShowVirtualKeyboard(const AControl: TFmxObject): Boolean;
var
TextView: JFMXTextEditorProxy;
begin
RegisterListener;
TextView := MainActivity.getTextEditorProxy;
FVKListener.ResetEvent;
TextView.setFocusable(true);
TextView.setFocusableInTouchMode(true);
TextView.requestFocus;
TextView.showSoftInput(true);
FVKListener.WaitEvent;
Result := FState = TvkbState.Shown;
end;

procedure TVirtualKeyboardAndroid.UnregisterService;
begin
TPlatformServices.Current.RemovePlatformService(IFMXVirtualKeyboardService);
end;

procedure TVirtualKeyboardAndroid.SetState(Value: TvkbState);
begin
if FState <> Value then
begin
FState := Value;
TMessageManager.DefaultManager.SendMessage(Self,
TVKStateChangeMessage.Create(FState = TvkbState.Shown, FVKListener.ObtainKeyboardRect), True);
end;
end;

procedure TVirtualKeyboardAndroid.SetTransientState(Value: Boolean);
begin
FTransient := Value;
end;

{ TVKListener }

constructor TVKListener.Create(const AService: TVirtualKeyboardAndroid);
begin
inherited Create;
FKeyboardService := AService;
FEvent := TEvent.Create;
VirtualKeyboardRect.VKListener := Self;
end;

procedure TVKListener.ResetEvent;
begin
FEvent.ResetEvent;
end;

procedure TVKListener.WaitEvent;
begin
FEvent.WaitFor(250);
end;

procedure WaitingForContentChanged(const Listener: TVKListener);
// The only way to get correct keyboard size is waiting little bit to time when system changes ContentView properties
// 1000ms maximum timeout. Usually it takes only one iteration. This procedure called from separated thread and main
// thread not blocked.
const
MaxCounter = 20;
SleepingTime = 50;
var
Counter: Integer;
KeyboardRect: TRect;
begin
Counter := 0;
KeyboardRect := Listener.ObtainKeyboardRect;
while (KeyboardRect = Listener.ObtainKeyboardRect) and (Counter < MaxCounter) do
begin
Sleep(SleepingTime);
Inc(Counter);
end;
end;

procedure TVKListener.onVirtualKeyboardShown;
begin
//WaitingForContentChanged(Self);
if VirtualKeyboardRect.CanFireEvent then
TThread.Synchronize(nil, procedure
begin
FKeyboardService.SetState(TVirtualKeyboardAndroid.TvkbState.Shown);
FEvent.SetEvent;
end);
else
VirtualKeyboardRect.VirtualKeyboardShown;
end;

procedure TVKListener.onVirtualKeyboardHidden;
begin
TThread.Synchronize(nil, procedure
begin
FKeyboardService.SetState(TVirtualKeyboardAndroid.TvkbState.Hidden);
FEvent.SetEvent;
end);
VirtualKeyboardRect.VirtualKeyboardHidden;
end;

destructor TVKListener.Destroy;
begin
FEvent.Free;
inherited;
end;

function TVKListener.ObtainKeyboardRect: TRect;
var
ContentRect, TotalRect: JRect;
begin
ContentRect := TJRect.Create;
TotalRect := TJRect.Create;
MainActivity.getWindow.getDecorView.getWindowVisibleDisplayFrame(ContentRect);
MainActivity.getWindow.getDecorView.getDrawingRect(TotalRect);
Result := TRectF.Create(ConvertPixelToPoint(TPointF.Create(TotalRect.left, TotalRect.top + ContentRect.height)),
ConvertPixelToPoint(TPointF.Create(TotalRect.right, TotalRect.bottom))).Truncate;
end;
initialization
VirtualKeyboardRect := TVirtualKeyboardRect.Create;
end.
Expand Up @@ -4,7 +4,7 @@
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<PropertyGroup>
<DeviceId Condition="'$(Platform)'=='Android'"/>
<DeviceId Condition="'$(Platform)'=='Android'">be1ba857</DeviceId>
<DeviceId Condition="'$(Platform)'=='iOSDevice32'"/>
<DeviceId Condition="'$(Platform)'=='iOSDevice64'"/>
<DeviceId Condition="'$(Platform)'=='iOSSimulator'">iPhone5</DeviceId>
Expand Down Expand Up @@ -3299,6 +3299,15 @@
<RemoteCommand/>
<Overwrite>True</Overwrite>
</DeployFile>
<DeployFile Include="Jet.style" Condition="'$(Config)'=='Release'">
<RemoteDir>HODLER_Wallet_Desktop\</RemoteDir>
<RemoteName>Jet.style</RemoteName>
<DeployClass>ProjectFile</DeployClass>
<Operation>0</Operation>
<LocalCommand/>
<RemoteCommand/>
<Overwrite>True</Overwrite>
</DeployFile>
<DeployFile Include="token_icons\1954.png" Condition="'$(Config)'=='Debug'">
<RemoteDir>HODLER_Wallet_Desktop\</RemoteDir>
<RemoteName>1954.png</RemoteName>
Expand Down

0 comments on commit 1e866dd

Please sign in to comment.