-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathFMX.FloatOverlay.pas
More file actions
320 lines (280 loc) · 11.7 KB
/
FMX.FloatOverlay.pas
File metadata and controls
320 lines (280 loc) · 11.7 KB
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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
unit FMX.FloatOverlay;
interface
uses
System.UITypes,
Androidapi.Helpers,
Androidapi.JNI.Widget,
Androidapi.JNI.Util,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNIBridge,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.Webkit;
type
TMyClickListener = class(TJavaLocal, JView_OnClickListener)
public
procedure OnClick(v: JView); cdecl;
end;
type
TFMXFloatOverlay = class(TJavaLocal, JView_OnTouchListener)
private
// Set initial position of the floating object
procedure SetPosition;
// Limit the position of the floating object within the screen bounds
procedure LimitPosition;
public
// Handle touch events on the floating object
function OnTouch(AView: JView; AMotionEvent: JMotionEvent): Boolean; cdecl;
// Create the floating object with specified parameters
procedure CreateFloatObject(AWidth, AHeight, APositionX, APositionY: Integer;
AColor: TAlphaColor; AType: Integer);
procedure CreateFloatWebView(AWidth, AHeight, APositionX, APositionY: Integer;
AColor: TAlphaColor);
// Delete the floating object from the screen
procedure DeleteObject;
// Set text to be displayed on the floating object
procedure SetText(AText: string);
end;
var
// WindowManager for managing the floating object
FWindowManager: JWindowManager;
// Layout parameters for the floating object
FParams: JWindowManager_LayoutParams;
// Layout view of the floating object
FLayoutView: JRelativeLayout;
// TextView for displaying text on the floating object
LTextView: JTextView;
// Touch listener for handling touch events on the floating object
FTouchListener: TFMXFloatOverlay;
// Variables to store position information of the floating object
FPositionX, FPositionY : Integer;
FPositionIniX, FPositionIniY : Single;
FPositionViewX, FPositionViewY : Integer;
FWebView: JWebView;
implementation
// Event handler for button click
procedure TMyClickListener.OnClick(v: JView);
begin
// Remove the floating object when the button is clicked
if (FWindowManager <> nil) then
begin
if (FLayoutView <> nil) then
begin
FWindowManager.removeView(FLayoutView);
FWindowManager := nil;
FLayoutView := nil;
end;
end;
end;
// Set initial position of the floating object
procedure TFMXFloatOverlay.SetPosition;
var
LDisplayMetrics : JDisplayMetrics;
begin
LDisplayMetrics := TJDisplayMetrics.JavaClass.init;
FWindowManager.getDefaultDisplay.getMetrics(LDisplayMetrics);
FPositionX := LDisplayMetrics.widthPixels - FLayoutView.getWidth;
FPositionY := LDisplayMetrics.heightPixels - FLayoutView.getHeight;
end;
// Handle touch events on the floating object
function TFMXFloatOverlay.OnTouch(AView: JView; AMotionEvent: JMotionEvent): Boolean;
var
X, Y: Integer;
begin
// Check if it's an initial touch event
if AMotionEvent.getAction = TJMotionEvent.JavaClass.ACTION_DOWN then
begin
// If initial position is not set, set it
if FPositionX = -1 then
SetPosition;
// Save initial touch coordinates and current coordinates of the floating rectangle
FPositionIniX := AMotionEvent.getRawX();
FPositionIniY := AMotionEvent.getRawY();
FPositionViewX := FParams.X;
FPositionViewY := FParams.Y;
end;
// Check if it's a finger movement event on the screen
if AMotionEvent.getAction = TJMotionEvent.JavaClass.ACTION_MOVE then
begin
// Calculate the difference between current touch coordinates and initial coordinates
X := Trunc(AMotionEvent.getRawX() - FPositionIniX);
Y := Trunc(AMotionEvent.getRawY() - FPositionIniY);
// Update the coordinates of the floating rectangle according to the finger movement
FParams.X := FPositionViewX + X;
FParams.Y := FPositionViewY + Y;
// Limit the coordinates of the floating rectangle to ensure it does not go out of bounds
LimitPosition;
// Update the position of the floating rectangle on the screen
FWindowManager.UpdateViewLayout(FLayoutView, FParams);
end;
end;
// Limit the position of the floating object within the screen bounds
procedure TFMXFloatOverlay.LimitPosition;
begin
// Limit the X coordinate
if FParams.X < 0 then
FParams.X := 0
else if FParams.X > FPositionX then
FParams.X := FPositionX;
// Limit the Y coordinate
if FParams.Y < 0 then
FParams.Y := 0
else if FParams.Y > FPositionY then
FParams.Y := FPositionY;
end;
// Delete the floating object from the screen
procedure TFMXFloatOverlay.DeleteObject;
begin
// Check if the floating object and window manager are initialized
if (FWindowManager <> nil) then
begin
if (FLayoutView <> nil) then
begin
// Remove the floating object from the screen
FWindowManager.removeView(FLayoutView);
// Release the references
FWindowManager := nil;
FLayoutView := nil;
end;
end;
end;
procedure TFMXFloatOverlay.SetText(AText: string);
begin
LTextView.setText(StrToJCharSequence(AText));
end;
// Create the floating object with specified parameters
procedure TFMXFloatOverlay.CreateFloatObject(AWidth, AHeight, APositionX,
APositionY: Integer; AColor: TAlphaColor; AType: Integer);
var
LObject : JObject;
LGradientDrawable: JGradientDrawable;
LButton: JButton;
LButtonParams: JRelativeLayout_LayoutParams;
begin
// Prevent creation of multiple floating objects
if FLayoutView <> nil then
Exit;
// Set initial position
FPositionX := -1;
FPositionY := FPositionX;
// Create touch listener
FTouchListener := TFMXFloatOverlay.Create;
// Create layout
FLayoutView := TJRelativeLayout.JavaClass.init(SharedActivityContext);
FLayoutView.setOnTouchListener(FTouchListener);
// Layout parameters
FParams := TJWindowManager_LayoutParams.JavaClass.init;
FParams.&type := TJWindowManager_LayoutParams.JavaClass.TYPE_APPLICATION_OVERLAY;
FParams.flags := TJWindowManager_LayoutParams.JavaClass.FLAG_NOT_FOCUSABLE;
FParams.format := TJPixelFormat.JavaClass.TRANSLUCENT;
FParams.gravity := TJGravity.JavaClass.LEFT or TJGravity.JavaClass.TOP;
FParams.width := AWidth;
FParams.height := AHeight;
FParams.x := APositionX;
FParams.y := APositionY;
// Create shape
LGradientDrawable := TJGradientDrawable.JavaClass.init;
if AType = 0 then
begin
LGradientDrawable.setShape(TJGradientDrawable.JavaClass.RECTANGLE);
LGradientDrawable.setCornerRadius(100);
end
else
LGradientDrawable.setShape(TJGradientDrawable.JavaClass.OVAL);
LGradientDrawable.setColor(TAndroidHelper.AlphaColorToJColor(AColor));
FLayoutView.setBackground(LGradientDrawable);
// Create TextView
LTextView := TJTextView.JavaClass.init(SharedActivityContext);
LTextView.setText(StrToJCharSequence('Firemonkey'));
LTextView.setTextSize(TJTypedValue.JavaClass.COMPLEX_UNIT_SP, 14); // Text size 14sp
LTextView.setTextColor(TJColor.JavaClass.WHITE); // Text color
LTextView.setGravity(TJGravity.JavaClass.CENTER); // Set text alignment to top and center horizontally
LTextView.setBackgroundColor(TJColor.JavaClass.TRANSPARENT); // Background color of the text view
LTextView.setTextAlignment(TJView.JavaClass.TEXT_ALIGNMENT_CENTER);
LTextView.setWidth(AWidth);
LTextView.setHeight(Round(0.2 * AHeight)); // -80%
FLayoutView.addView(LTextView); // Add to layout
// Create Button
LButton := TJButton.JavaClass.init(SharedActivityContext);
LButton.setText(StrToJCharSequence('Delete'));
LButton.setBackgroundColor(TJColor.JavaClass.BLUE);
LButtonParams := TJRelativeLayout_LayoutParams.JavaClass.init(TJViewGroup_LayoutParams.JavaClass.WRAP_CONTENT, TJViewGroup_LayoutParams.JavaClass.WRAP_CONTENT);
LButtonParams.addRule(TJRelativeLayout.JavaClass.CENTER_HORIZONTAL);
LButtonParams.addRule(TJRelativeLayout.JavaClass.CENTER_VERTICAL);
LButton.setLayoutParams(LButtonParams);
LButton.setOnClickListener(TMyClickListener.Create);
FLayoutView.addView(LButton);
// Get WindowManager service
LObject := SharedActivityContext.getSystemService(TJContext.JavaClass.WINDOW_SERVICE);
FWindowManager := TJWindowManager.Wrap((LObject as ILocalObject).GetObjectID);
// Add the layout view to the WindowManager
FWindowManager.addView(FLayoutView, FParams);
end;
procedure TFMXFloatOverlay.CreateFloatWebView(AWidth, AHeight, APositionX,
APositionY: Integer; AColor: TAlphaColor);
var
LObject : JObject;
LGradientDrawable: JGradientDrawable;
LButton: JButton;
LButtonParams: JRelativeLayout_LayoutParams;
LWebViewParams: JRelativeLayout_LayoutParams;
begin
// Prevent creation of multiple floating objects
if FLayoutView <> nil then
Exit;
// Set initial position
FPositionX := -1;
FPositionY := FPositionX;
// Create touch listener
FTouchListener := TFMXFloatOverlay.Create;
// Create layout
FLayoutView := TJRelativeLayout.JavaClass.init(SharedActivityContext);
FLayoutView.setOnTouchListener(FTouchListener);
// Layout parameters
FParams := TJWindowManager_LayoutParams.JavaClass.init;
FParams.&type := TJWindowManager_LayoutParams.JavaClass.TYPE_APPLICATION_OVERLAY;
FParams.flags := TJWindowManager_LayoutParams.JavaClass.FLAG_NOT_FOCUSABLE;
FParams.format := TJPixelFormat.JavaClass.TRANSLUCENT;
FParams.gravity := TJGravity.JavaClass.LEFT or TJGravity.JavaClass.TOP;
FParams.width := AWidth;
FParams.height := AHeight;
FParams.x := APositionX;
FParams.y := APositionY;
// Create shape
LGradientDrawable := TJGradientDrawable.JavaClass.init;
LGradientDrawable.setShape(TJGradientDrawable.JavaClass.RECTANGLE);
LGradientDrawable.setCornerRadius(20);
LGradientDrawable.setColor(TAndroidHelper.AlphaColorToJColor(AColor));
FLayoutView.setBackground(LGradientDrawable);
// Create Button close
LButton := TJButton.JavaClass.init(SharedActivityContext);
LButton.setText(StrToJCharSequence('X'));
LButton.setTextAlignment(TJView.JavaClass.TEXT_ALIGNMENT_CENTER);
LButton.setTextColor(TJColor.JavaClass.WHITE);
LButton.setTextSize(10);
LButton.setBackgroundColor(TJColor.JavaClass.TRANSPARENT);
LButtonParams := TJRelativeLayout_LayoutParams.JavaClass.init(TJViewGroup_LayoutParams.JavaClass.WRAP_CONTENT, TJViewGroup_LayoutParams.JavaClass.WRAP_CONTENT);
LButtonParams.addRule(TJRelativeLayout.JavaClass.ALIGN_TOP);
LButtonParams.addRule(TJRelativeLayout.JavaClass.ALIGN_PARENT_RIGHT);
LButtonParams.width := 130;
LButtonParams.height := 100;
LButton.setLayoutParams(LButtonParams);
LButton.setOnClickListener(TMyClickListener.Create);
FLayoutView.addView(LButton);
// Create WebView
LWebViewParams := TJRelativeLayout_LayoutParams.JavaClass.init(TJViewGroup_LayoutParams.JavaClass.WRAP_CONTENT, TJViewGroup_LayoutParams.JavaClass.WRAP_CONTENT);
LWebViewParams.height := Round(0.7 * AHeight);
LWebViewParams.width := AWidth;
LWebViewParams.addRule(TJRelativeLayout.JavaClass.CENTER_HORIZONTAL);
LWebViewParams.addRule(TJRelativeLayout.JavaClass.CENTER_VERTICAL);
FWebView := TJWebView.JavaClass.init(SharedActivityContext);
FWebView.getSettings.setJavaScriptEnabled(True); // Enable JavaScript (opcional)
FWebView.loadUrl(StringToJString('https://www.youtube.com/embed/tAGnKpE4NCI')); // Load uma URL
FWebView.setLayoutParams(LWebViewParams);
FLayoutView.addView(FWebView); // Add ao layout
// Get WindowManager service
LObject := SharedActivityContext.getSystemService(TJContext.JavaClass.WINDOW_SERVICE);
FWindowManager := TJWindowManager.Wrap((LObject as ILocalObject).GetObjectID);
// Add the layout view to the WindowManager
FWindowManager.addView(FLayoutView, FParams);
end;
end.