spierepf
spierepf

Reputation: 2924

I'm looking for an example of Drag-and-Drop for Delphi Firemonkey

I did find one at the end of:

https://forums.embarcadero.com/thread.jspa?messageID=447850

unit Unit1;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Platform;

type
TForm1 = class(TForm)
Panel1: TPanel;
procedure DragDrop(const Data: TDragObject; const Point: TPointF);override;
procedure DragOver(const Data: TDragObject; const Point: TPointF; var Accept: Boolean);override;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.DragDrop(const Data: TDragObject; const Point: TPointF);
var P: TPointF;
begin
P:= Platform.ScreenToClient(Form1,Point);
TPanel(Data.Source).Position.X:=P.X - TPanel(Data.Source).Width/2;
TPanel(Data.Source).Position.Y:=P.Y - TPanel(Data.Source).Height/2;

end;

procedure TForm1.DragOver(const Data: TDragObject; const Point: TPointF; var Accept: Boolean);
begin
Accept:=true;
end;

end.

but it doesn't want to compile. The Platform identifier is undeclared which is not surprising, since it doesn't appear anywhere else in the code.

Also, TPointF and TForm1 are incompatible types. This also doesn't surprise me.

The trouble is, I don't know how to fix either of these problems.

I don't know what the type of Platform should be. When I guessed TPlatform I noticed that it is merely an enum with not ScreenToClient method.

The second problem has me completely baffled. How can the compiler know the parameter types of a method on an instance whose class it can't identify because the instance is undeclared?

edit:

Sorry, I should have been clearer about my requirements. I am trying to build a mobile app that will show users images of products, and allow the user to drag images one at a time into a 'comparison' area. Then the user clicks a compare button and we go to a new screen that compares the products whose images the user has dragged and dropped.

So really, what I'm looking for is a screen with two components on it. One of the components is draggable, and the other is the target. I need to be able to recognize that the drag-and-drop has occurred and the identity of the draggee...

Upvotes: 2

Views: 7950

Answers (2)

Ken White
Ken White

Reputation: 125669

Here's an example of drag/drop, produced with XE5 in a Firemonkey desktop (HD) application (as you did not specify which platform you're trying to use):

Drop a TPanel on the form, enlarge the width to about half the form's width, and drop a TLabel on the panel at the left edge. Set the TLabel.AutoSize property to True.

Click on Panel1 on the form, and then switch to the Events tab in the Object Inspector, and add the following two events for the OnDragOver and OnDragDrop events:

procedure TForm1.Panel1DragDrop(Sender: TObject; const Data: TDragObject;
  const Point: TPointF);
begin
  Label1.Text := Data.Files[0];
end;

procedure TForm1.Panel1DragOver(Sender: TObject; const Data: TDragObject;
  const Point: TPointF; var Accept: Boolean);
begin
  Accept := Length(Data.Files) > 0;
end;

Run the application, and then drag any file from Windows Explorer over the panel and drop it.

Upvotes: 2

RRUZ
RRUZ

Reputation: 136391

Starting with Delphi XE4, FMX now uses Platform services for implement this kind of methods. In this case the ScreenToClient function is defined in the IFMXWindowService interface, so you can get an instance to the implementation of this service using the FWinService field of the Form. To compile your code just replace the Platform variable by the FWinService field like so

P:= FWinService.ScreenToClient(Self ,Point);

Upvotes: 4

Related Questions