Recent

Author Topic: macOS gestures: NSGestureRecognizer  (Read 305 times)

plashenkov

  • New Member
  • *
  • Posts: 24
macOS gestures: NSGestureRecognizer
« on: September 28, 2020, 02:04:30 pm »
Hey guys!

I'm trying to implement gestures handling on macOS. It's such an important topic...

I've created a component with purpose to provide a convenient way to handle gestures. Here is a simplified code of it (I've removed FreeNotification, etc. stuff for simplicity):

Code: Pascal  [Select][+][-]
  1. unit MagnificationGesture;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch objectivec2}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, Controls, CocoaAll;
  10.  
  11. type
  12.  
  13.   TMagnificationGesture = class;
  14.  
  15.   { TCocoaMagnificationGesture }
  16.  
  17.   TCocoaMagnificationGesture = objcclass(NSMagnificationGestureRecognizer)
  18.   public
  19.     FLCLGesture: TMagnificationGesture;
  20.     procedure HandleGesture; message 'handleGesture';
  21.   end;
  22.  
  23.   { TMagnificationGesture }
  24.  
  25.   TMagnificationGesture = class(TComponent)
  26.   private
  27.     FCocoaGesture: TCocoaMagnificationGesture;
  28.     FControl: TWinControl;
  29.     FOnGesture: TNotifyEvent;
  30.     procedure SetControl(AValue: TWinControl);
  31.   public
  32.     constructor Create(AOwner: TComponent); override;
  33.   published
  34.     property Control: TWinControl read FControl write SetControl;
  35.     property OnGesture: TNotifyEvent read FOnGesture write FOnGesture;
  36.   end;
  37.  
  38. implementation
  39.  
  40. { TCocoaMagnificationGesture }
  41.  
  42. procedure TCocoaMagnificationGesture.HandleGesture;
  43. begin
  44.   if Assigned(FLCLGesture.OnGesture) then
  45.     FLCLGesture.OnGesture(FLCLGesture);
  46. end;
  47.  
  48. { TMagnificationGesture }
  49.  
  50. procedure TMagnificationGesture.SetControl(AValue: TWinControl);
  51. begin
  52.   if FControl = AValue then Exit;
  53.   FControl := AValue;
  54.   NSView(FControl.Handle).addGestureRecognizer(FCocoaGesture);
  55. end;
  56.  
  57. constructor TMagnificationGesture.Create(AOwner: TComponent);
  58. begin
  59.   inherited;
  60.   FCocoaGesture := TCocoaMagnificationGesture
  61.     .alloc
  62.     .initWithTarget_action(FCocoaGesture, objcselector('handleGesture'))
  63.     .autorelease;
  64.   FCocoaGesture.FLCLGesture := Self;
  65. end;
  66.  
  67. end.
  68.  

Using it:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   MagnificationGesture := TMagnificationGesture.Create(Self);
  4.   MagnificationGesture.Control := Panel1;
  5.   MagnificationGesture.OnGesture := @MagnificationGestureGesture;
  6. end;
  7.  
  8. procedure TForm1.MagnificationGestureGesture(Sender: TObject);
  9. begin
  10.   // Just to check if it works
  11.   Caption := Caption + '1';
  12. end;
  13.  

But unfortunately when I do a gesture on a panel the event doesn't fire.

If someone understands how Cocoa works could you give the cue what can be wrong here?
« Last Edit: September 28, 2020, 04:09:05 pm by plashenkov »

plashenkov

  • New Member
  • *
  • Posts: 24
Re: macOS gestures: NSGestureRecognizer
« Reply #1 on: September 28, 2020, 05:02:23 pm »
Ahhh, got it  :D

I initialized NSGestureRecognizer incorrectly.
This is the fix:

Code: Pascal  [Select][+][-]
  1. constructor TMagnificationGesture.Create(AOwner: TComponent);
  2. begin
  3.   inherited;
  4.   FCocoaGesture := TCocoaMagnificationGesture.alloc.init.autorelease;
  5.   FCocoaGesture.setTarget(FCocoaGesture);
  6.   FCocoaGesture.setAction(objcselector('handleGesture'));
  7.   FCocoaGesture.FLCLGesture := Self;
  8. end;
  9.  

plashenkov

  • New Member
  • *
  • Posts: 24
Re: macOS gestures: NSGestureRecognizer
« Reply #2 on: October 03, 2020, 03:02:50 am »
Hi there!
I've published a special package for gestures handling in macOS. Hope it will be useful for someone :) Here it is: https://github.com/plashenkov/macOS-gestures-FPC

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1014
  • Former Delphi 1-7, 10.2 User
Re: macOS gestures: NSGestureRecognizer
« Reply #3 on: October 03, 2020, 04:33:44 am »
Excellent work plashenkov!

I've added this to the Wiki's Mac Portal - see macOS gestures.
o Lazarus v2.1.0 r63871, FPC v3.3.1 r47164, macOS 10.14.6 (with sup update), Xcode 11.3.1
o Lazarus v2.1.0 r61574, FPC v3.3.1 r42318, FreeBSD 12.1 amd64 (VMware Fusion VM)
o FPC 3.0.4, FreeBSD 12.2-STABLE r365646 amd64
o Lazarus v2.1.0 r61574, FPC v3.0.4, Ubuntu 20.04 (Parallels VM)

plashenkov

  • New Member
  • *
  • Posts: 24
Re: macOS gestures: NSGestureRecognizer
« Reply #4 on: October 03, 2020, 04:49:11 am »
Hey trev! Great!
I've just added small fix to the example in README.md. Could you update it in the Wiki?

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1014
  • Former Delphi 1-7, 10.2 User
Re: macOS gestures: NSGestureRecognizer
« Reply #5 on: October 03, 2020, 05:00:53 am »
Updated!
o Lazarus v2.1.0 r63871, FPC v3.3.1 r47164, macOS 10.14.6 (with sup update), Xcode 11.3.1
o Lazarus v2.1.0 r61574, FPC v3.3.1 r42318, FreeBSD 12.1 amd64 (VMware Fusion VM)
o FPC 3.0.4, FreeBSD 12.2-STABLE r365646 amd64
o Lazarus v2.1.0 r61574, FPC v3.0.4, Ubuntu 20.04 (Parallels VM)

plashenkov

  • New Member
  • *
  • Posts: 24
Re: macOS gestures: NSGestureRecognizer
« Reply #6 on: October 03, 2020, 05:01:21 am »
Great, thank you!

 

TinyPortal © 2005-2018