-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathse.utils.client.pas
232 lines (209 loc) · 7.16 KB
/
se.utils.client.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
{******************************************************************************}
{ }
{ SE Network Development Framework }
{ }
{ Copyright (c) 2018 looper(2031056602@qq.com) }
{ }
{ Source: https://github.com/looper/se-framework }
{ Homepage: http://www.asphyre.cn }
{ }
{******************************************************************************}
unit se.utils.client;
interface
uses
System.UITypes, System.SysUtils, System.Types, System.Classes, System.IOUtils,
FMX.Types, FMX.Forms;
type
TClientUtils = class
private class var
FMainForm: TForm;
FAppFile, FAppPath, FAppHome, FAppDocuments, FAppName: string;
FStatusBarHeight, FScreenScale: Single;
FPhysicalScreenSize, FRawScreenSize: TSize;
FCosTable256: array[0..255] of Double;
private
class constructor Create;
class destructor Destroy;
public
class property AppFile: string read FAppFile;
class property AppPath: string read FAppPath;
class property AppHome: string read FAppHome;
class property AppDocuments: string read FAppDocuments;
class property AppName: string read FAppName;
public
//设置主窗口
class procedure SetMainForm(const AForm: TForm); static;
//状态栏高度
class property StatusBarHeight: Single read FStatusBarHeight;
//物理屏幕大小<移动设备不包含状态栏高度>
class property PhysicalScreenSize: TSize read FPhysicalScreenSize;
//原始屏幕大小<移动设备包含状态栏及导航栏高度>
class property RawScreenSize: TSize read FRawScreenSize;
//屏幕比例
class property ScreenScale: Single read FScreenScale;
public
class function Cos256(const AIndex: Integer): Double;
class function Sin256(const AIndex: Integer): Double;
public
//组件持久化相关
class function ComponentToStr(const AComponent: TComponent): string;
class function StrToComponent(const AString: string): TComponent;
end;
implementation
uses FMX.Platform, FMX.BehaviorManager
{$IFDEF ANDROID}
, Androidapi.JNIBridge, Androidapi.Helpers, Androidapi.JNI.OS, Androidapi.JNI.JavaTypes
{$ENDIF}
;
function GetStatusBarHeight: Single;
{$IFDEF ANDROID}
var
resourceID: Integer;
ScreenService: IFMXScreenService;
sScale: Single;
sAbis: string;
arrAbis: TJavaObjectArray<JString>;
I: Integer;
needCheckStatusBarHeight: Boolean;
{$ENDIF}
begin
Result := 0;
{$IFDEF ANDROID}
if TOSVersion.Major >= 5 then
begin
sAbis := '';
arrAbis := TJBuild.JavaClass.SUPPORTED_ABIS;
for I := 0 to arrAbis.Length - 1 do
sAbis := sAbis + ',' + JStringToString(arrAbis.Items[I]);
sAbis := sAbis.trim([',']);
end
else
sAbis := JStringToString(TJBuild.JavaClass.CPU_ABI) + ',' + JStringToString(TJBuild.JavaClass.CPU_ABI2);
needCheckStatusBarHeight := (sAbis.Contains('x86') or JStringToString(TJBuild.JavaClass.FINGERPRINT).Contains('intel')
or sAbis.Contains('arm64-v8a')) and (TOSVersion.Major >= 4);
if (TOSVersion.Major >= 5) or (needCheckStatusBarHeight) then
begin
sScale := 1;
if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then
sScale := ScreenService.GetScreenScale;
resourceID := TAndroidHelper.Activity.getResources.getIdentifier(StringToJString('status_bar_height'),
StringToJString('dimen'), StringToJString('android'));
if resourceID > 0 then
Result:= Trunc(TAndroidHelper.Activity.getResources.getDimensionPixelSize(resourceID)
/ sScale);
end;
{$ENDIF}
end;
function GetScreenScale: Single;
var
ScreenService: IFMXScreenService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, ScreenService) then
Result:= ScreenService.GetScreenScale
else
Result:= 1.0;
end;
{ TClientUtils }
class constructor TClientUtils.Create;
var
I: Integer;
begin
FAppFile:= ParamStr(0);
FAppName:= ChangeFileExt(ExtractFileName(FAppFile), '');
FAppPath:= IncludeTrailingPathDelimiter(ExtractFilePath(FAppFile));
{$IF defined(IOS) or defined(ANDROID)}
FAppHome:= IncludeTrailingPathDelimiter(TPath.GetHomePath);
{$ELSE}
FAppHome:= IncludeTrailingPathDelimiter(TPath.Combine(TPath.GetHomePath, FAppName));
{$ENDIF}
{$IF defined(IOS) or defined(ANDROID)}
FAppDocuments:= IncludeTrailingPathDelimiter(TPath.GetDocumentsPath);
{$ELSE}
FAppDocuments:= IncludeTrailingPathDelimiter(TPath.Combine(TPath.GetDocumentsPath, FAppName));
{$ENDIF}
FStatusBarHeight:= 0;
FScreenScale:= 1.0;
FPhysicalScreenSize.Create(0, 0);
FRawScreenSize.Create(0, 0);
FMainForm:= nil;
//
for I:= 0 to 255 do
FCosTable256[I]:= Cos((I/256)*2*PI);
end;
class destructor TClientUtils.Destroy;
begin
FMainForm:= nil;
end;
class procedure TClientUtils.SetMainForm(const AForm: TForm);
var
LDeviceBehavior: IDeviceBehavior;
LDisplayMetrics: TDeviceDisplayMetrics;
begin
if AForm = nil then Exit;
FMainForm:= AForm;
//
FStatusBarHeight:= GetStatusBarHeight;
FScreenScale:= GetScreenScale;
FPhysicalScreenSize.cx:= FMainForm.ClientWidth;
FPhysicalScreenSize.cy:= FMainForm.ClientHeight;
FRawScreenSize.cx:= FMainForm.Width;
FRawScreenSize.cy:= FMainForm.Height;
//
if TBehaviorServices.Current.SupportsBehaviorService(IDeviceBehavior,
LDeviceBehavior, FMainForm) then
begin
LDisplayMetrics:= LDeviceBehavior.GetDisplayMetrics(FMainForm);
FPhysicalScreenSize:= LDisplayMetrics.PhysicalScreenSize;
FPhysicalScreenSize.cy:= Trunc(FPhysicalScreenSize.cy - FStatusBarHeight*FScreenScale);
FRawScreenSize:= LDisplayMetrics.RawScreenSize;
end;
end;
class function TClientUtils.Cos256(const AIndex: Integer): Double;
begin
Result:= FCosTable256[AIndex and 255];
end;
class function TClientUtils.Sin256(const AIndex: Integer): Double;
begin
Result:= FCosTable256[(AIndex+192) and 255];
end;
class function TClientUtils.ComponentToStr(const AComponent: TComponent): string;
var
LMemStream: TMemoryStream;
LStrStream: TStringStream;
begin
LMemStream:= TMemoryStream.Create;
try
LStrStream:= TStringStream.Create;
try
LMemStream.WriteComponent(AComponent);
LMemStream.Seek(0, soFromBeginning);
System.Classes.ObjectBinaryToText(LMemStream, LStrStream);
LStrStream.Seek(0, soFromBeginning);
Result:= LStrStream.DataString;
finally
FreeAndNil(LStrStream);
end;
finally
FreeAndNil(LMemStream);
end;
end;
class function TClientUtils.StrToComponent(const AString: string): TComponent;
var
LStrStream: TStringStream;
LMemStream: TMemoryStream;
begin
LStrStream := TStringStream.Create(AString);
try
LMemStream := TMemoryStream.Create;
try
System.Classes.ObjectTextToBinary(LStrStream,LMemStream);
LMemStream.Seek(0,soFromBeginning);
Result := LMemStream.ReadComponent(nil);
finally
FreeAndNil(LMemStream);
end;
finally
FreeAndNil(LStrStream);
end;
end;
end.