How to convert screen coordinates to control coordinates

Arnold

I need code that is able to intercept several taps on a tablet at the same moment. In a previous question concerning how to handle several OnMouseDown's at the same moment (not possible), a link was provided that answered the question on how to handle multi touch clicks in Delphi-Android. However, this code returns (x, y) positions in screen coordinates and I don't know how to translate these to local coordinates of a specific control. The Delphi documentation refers to a ScreenToClient function but that only translates screen coordinates to form coordinates, which is hardly useful in Android (the documentation is about XE2 but the function still exists in XE5 but the function has been removed from FMX.Platform to FMX.Form).

Is there a simple way to convert screen coordinates to TControl coordinates in FMX like in VCL? Of course I can 'de-parent' a control, notate its top-left coordinates and do so for each parent until arrived at the base form, but that's quite tedious.

Edit 1

My current approach is to get the top (x, y) coordinates of the TControl (a TPanel) that is parent to the controls to be tapped (TRectangle's in fact) and add these to check whether a click is inside that rectangle. See sample code below.

procedure TKeyBoard.process_touch (Event: TTouchEvent; status_byte: Int32);
var
  key: TKey;
  p, q: TPointF;
  i: Integer;
  x, y: single;
begin
// Check whether at least one event is present. If so, i points to the last event
   i := Length (Event.Points) - 1;
   if i < 0 then Exit;

// Get (x, y) coordinates from event. It's in screen coordinates
   x := Event.Points [i].Position.X;
   y := Event.Points [i].Position.Y;

// FControl is a reference to the panel holding the keys
// Find its rectangle position and convert to screen coordinates
   p := TPointF.Create (FControl.Position.X, FControl.Position.Y);
   q := TPointF.Create (p.X + FControl.Width, p.Y + FControl.Height);
   p := Application.MainForm.ClientToScreen (p);
   q := Application.MainForm.ClientToScreen (q);

   logd ('control [%.0f %.0f - %.0f, %.0f]', [FControl.Position.X, FControl.Position.Y, FControl.Width, FControl.Height]);
   logd ('to screen [%.0f %.0f - %.0f, %.0f]', [p.X, p.Y, q.X, q.Y]);

// Determine whether a black key has been pressed
   for i := Low (Fkeys) to High (FKeys) do
   begin
      if not cOctave_Major [i mod nOctave] then
      begin
         key := FKeys [i];

         logd ('%d (%.0f, %.0f) - (%.0f, %.0f) (%.0f, %.0f)', [i, x, y,
                  key.Position.X + p.X,             key.Position.Y + p.Y,
                  key.Position.X + P.X + Key.Width, key.Position.Y + p.Y + key.Height]);

         if (x >= key.Position.X + p.X) and (x <= key.Position.X + p.X + Key.Width) and
            (y >= key.Position.Y + p.Y) and (y <= key.Position.Y + p.Y + key.Height)
            then break;
         key := nil;
      end; // if
   end; // for

// if not, check whether a white key has been pressed
   if key = nil then
   begin
      logd ('Major');
      for i := Low (Fkeys) to High (FKeys) do
      begin
         if cOctave_Major [i mod nOctave] then
         begin
            key := FKeys [i];

            logd ('%d (%.0f, %.0f) - (%.0f, %.0f) (%.0f, %.0f)', [i, x, y,
                  key.Position.X + p.X,             key.Position.Y + p.Y,
                  key.Position.X + P.X + Key.Width, key.Position.Y + p.Y + key.Height]);

            if (x >= key.Position.X + p.X) and (x <= key.Position.X + p.X + Key.Width) and
               (y >= key.Position.Y + p.Y) and (y <= key.Position.Y + p.Y + key.Height)
               then break;
            key := nil;
         end; // if
      end; // for
   end; // if


   if key <> nil
      then putShort (status_byte, key.Note, 127);
   if key <> nil
      then logd (' found %s', [key.Text.Text]);
end; // process_touch //

This code is in fact very untidy because it assumes that the Parent control has the Application.MainForm as its parent which need not be the case. Another observation is that the taps might still be slightly wrong in the Y-position. For that reason i'd like to transfer the screen coordinates directly to the control's coordinates.

Edit 2

I tried to use the IsMouseOver check for each key control as suggested by @Sentient but strangely enough that only yields true when a MouseUp event is being processed.

Runner

I am the author of the multi-touch code you are using. When I saw you struggle with coordinates I looked what can be done and updated the code so it now gives you the touched control and the relative coordinates. Also if you are wondering how to get that its simple.

The blog post about it is here:

http://www.cromis.net/blog/2014/02/multi-touch-touched-control-and-relative-coordinates/

The code to solve it look like this:

  if Screen.ActiveForm <> nil then
  begin
    for I := 0 to Length(Event.Points) - 1 do
    begin
      Control := Screen.ActiveForm.ObjectAtPoint(Event.Points[I].Position);

      if Control <> nil then
      begin
        Event.Points[I].Control := Control as TFmxObject;
        Event.Points[I].RelPosition := Control.ScreenToLocal(Event.Points[I].Position);
      end
      else
      begin
        Event.Points[I].Control := Screen.ActiveForm;
        Event.Points[I].RelPosition := Screen.ActiveForm.ScreenToClient(Event.Points[I].Position);
      end;
    end;
  end;

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

QML Screen Coordinates of Component

From Dev

Mac OS X: Convert between NSView coordinates and global screen coordinates

From Dev

How to convert from (x, y) screen coordinates to LatLng (Google Maps)

From Dev

How do you convert screen coordinates to document space in a scaled SVG?

From Dev

How to convert screen coordinates to world coordinates for simple 2D game?

From Dev

How to convert "normal" coordinates to OSM coordinates in OpenLayers

From Dev

ios AVCaptureVideoPreviewLayer convert between camera and screen coordinates

From Dev

Convert screen to WPF coordinates without showing a Window

From Dev

Convert UIKit coordinates to SpriteKit coordinates

From Dev

How to convert workspace coordinates to screen coordinates?

From Dev

How do you convert from AltAz coordinates to equatorial coordinates in Astropy

From Dev

How to convert cartesian coordinates to polar coordinates in JS?

From Dev

How to convert screen coordinates to coordinates on a z transformed element?

From Dev

How to convert the bounds of a box to screen coordinates

From Dev

How to get world coordinates from screen coordinates in Vispy

From Dev

How to project Webcam captured frame coordinates to screen coordinates

From Dev

How do I draw with the screen coordinates on canvas?

From Dev

How to get coordinates of touch screen points in ogl?

From Dev

How to translate window's coordinates into control coordinates

From Dev

Mac OS X: Convert between NSView coordinates and global screen coordinates

From Dev

How to convert "normal" coordinates to OSM coordinates in OpenLayers

From Dev

How to convert workspace coordinates to screen coordinates?

From Dev

How to get object coordinates from screen coordinates?

From Dev

how to convert coordinates

From Dev

How can I correctly convert geographical coordinates to pixels on screen?

From Dev

Transformation the screen coordinates to stage coordinates

From Dev

How to convert a set of coordinates into a Char?

From Dev

How to calculate transformation from screen coordinates to isometric screen coordinates?

From Dev

How to Convert World Coordinates to Camera Image Coordinates?

Related Related

  1. 1

    QML Screen Coordinates of Component

  2. 2

    Mac OS X: Convert between NSView coordinates and global screen coordinates

  3. 3

    How to convert from (x, y) screen coordinates to LatLng (Google Maps)

  4. 4

    How do you convert screen coordinates to document space in a scaled SVG?

  5. 5

    How to convert screen coordinates to world coordinates for simple 2D game?

  6. 6

    How to convert "normal" coordinates to OSM coordinates in OpenLayers

  7. 7

    ios AVCaptureVideoPreviewLayer convert between camera and screen coordinates

  8. 8

    Convert screen to WPF coordinates without showing a Window

  9. 9

    Convert UIKit coordinates to SpriteKit coordinates

  10. 10

    How to convert workspace coordinates to screen coordinates?

  11. 11

    How do you convert from AltAz coordinates to equatorial coordinates in Astropy

  12. 12

    How to convert cartesian coordinates to polar coordinates in JS?

  13. 13

    How to convert screen coordinates to coordinates on a z transformed element?

  14. 14

    How to convert the bounds of a box to screen coordinates

  15. 15

    How to get world coordinates from screen coordinates in Vispy

  16. 16

    How to project Webcam captured frame coordinates to screen coordinates

  17. 17

    How do I draw with the screen coordinates on canvas?

  18. 18

    How to get coordinates of touch screen points in ogl?

  19. 19

    How to translate window's coordinates into control coordinates

  20. 20

    Mac OS X: Convert between NSView coordinates and global screen coordinates

  21. 21

    How to convert "normal" coordinates to OSM coordinates in OpenLayers

  22. 22

    How to convert workspace coordinates to screen coordinates?

  23. 23

    How to get object coordinates from screen coordinates?

  24. 24

    how to convert coordinates

  25. 25

    How can I correctly convert geographical coordinates to pixels on screen?

  26. 26

    Transformation the screen coordinates to stage coordinates

  27. 27

    How to convert a set of coordinates into a Char?

  28. 28

    How to calculate transformation from screen coordinates to isometric screen coordinates?

  29. 29

    How to Convert World Coordinates to Camera Image Coordinates?

HotTag

Archive