This, I hope, should be the last article on multi-touch support for mobile devices. All that was missing in my implementation was support for detecting the control that was touched and getting relative coordinates inside that control along side with screen coordinates that I was already exposing. Today I saw this SO post. Someone was using my code, but was unable to get the local coordinates and control that was being touched. So I took the challenge and threw together some support for this, on all supported devices. Basically, what changed, is the TTouchPoint record. It now looks like this.
TTouchPoint = record ID: Integer; Control: TFmxObject; Position: TPointF; RelPosition: TPointF; History: array of TPointF; end;
I added the control and relative position. If you are interested how I did that its simple.
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;
You get the active form (I suppose there is a theoretical possibility that multi-touch is spreed over more then one form, but I discarded that situation as it seems very unlikely), then you get the object at the touch point coordinates. Finally you get the relative coordinates for that object. If no object is found then the form was touched. I will go no further with this as I spent to much time on it already. If you see some holes in the approach or you have improvements, feel free to tell me so. The code can be downloaded from the downloads section as usual.