This is an old revision of the document!


Interaction

In the following the implementation of mouse and keyboard interaction with default FMX methods will be described.

In case you'll need extended features, have a look at the InputController implementation: Input Polling

Mouse Interaction

Default FMX event handling may be confusing for some of you, by a bit misleading and unexpected behaviour. Especially the way when events getting called and which components receive those events.

At first you should decide which kind of mouse event handling you expect.

In Viewport

In case you want an overall mouse interaction over the complete scene in your viewport, like a rotation of camera around the scene center. This may be the behaviour you like.

The following code snippet shows how to rotate camera around the center, when left mouse button is down. A special scene setup is important. The GorillaCamera1 is attached as child of Dummy1 with an offset (Position.Z = -10). Also the GorillaCamera1.Target is set to Dummy1. This means the camera is always focusing the dummy object.

type
  TForm1 = class(TForm)
    GorillaViewport1: TGorillaViewport;
    Dummy1: TDummy;
    GorillaCamera1: TGorillaCamera;
 
  private
    FIsMoving : Boolean;
    FLastPoint : TPointF;
 
    procedure DoOnViewportMouseUp(ASender : TObject; AButton : TMouseButton;
      AShift : TShiftState; X, Y : Single);
    procedure DoOnViewportMouseDown(ASender : TObject; AButton : TMouseButton;
      AShift : TShiftState; X, Y : Single);
    procedure DoOnViewportMouseMove(ASender : TObject; AShiftState : TShiftState;
      X, Y : Single);
  end;
 
  [...]
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  GorillaViewport1.OnMouseUp   := DoOnViewportMouseUp;
  GorillaViewport1.OnMouseDown := DoOnViewportMouseDown;
  GorillaViewport1.OnMouseMove := DoOnViewportMouseMove;
  [...]
end;
 
procedure TForm1.DoOnViewportMouseUp(ASender : TObject; AButton : TMouseButton;
  AShift : TShiftState; X, Y : Single);
begin
  FIsMoving := false;
end;
 
procedure TForm1.DoOnViewportMouseDown(ASender : TObject; AButton : TMouseButton;
  AShift : TShiftState; X, Y : Single);
begin
  FIsMoving  := true;
  FLastPoint := PointF(X, Y);
end;
 
procedure TForm1.DoOnViewportMouseMove(ASender : TObject; AShiftState : TShiftState;
  X, Y : Single);
var LDiff : TPointF;
begin
  if FIsMoving then
  begin
    if (ssLeft in AShiftState) then
    begin
      LDiff := PointF(X, Y) - FLastPoint;
      Dummy1.RotationAngle.Y := Dummy1.RotationAngle.Y + LDiff.X;
    end;
 
    FLastPoint := PointF(X, Y);
  end;
end;

A mouse event checks all controls on your form to see if the mouse position is within one of these elements. So in case you have, for example a cube in your scene and the mouse hovers over this cube, FMX will call the MouseMove event of the cube, instead of the viewport.

So they above defined events will not be thrown and rotation will not be executed. To make your mouse move events available all over the viewport, you have to set HitTest of each object inside of the viewport to FALSE.

Another solution is to include rotation behaviour in each object related mouse-move event, or to use TGorillaInputController with global mouse hooks (Input Polling).

On components

HitTest Property

Keyboard Interaction