1
+ using CoreGraphics ;
2
+ using Foundation ;
3
+ using Microsoft . Maui . Controls . Platform ;
4
+ using OxyPlot . Maui . Skia . Effects ;
5
+ using UIKit ;
6
+
7
+ namespace OxyPlot . Maui . Skia . macOS . Effects ;
8
+
9
+ public class PlatformTouchEffect : PlatformEffect
10
+ {
11
+ private UIView _view ;
12
+ private TouchRecognizer _touchRecognizer ;
13
+ private MyTouchEffect _touchEffect ;
14
+ protected override void OnAttached ( )
15
+ {
16
+ _view = Control ?? Container ;
17
+ _touchEffect = Element . Effects . OfType < MyTouchEffect > ( ) . FirstOrDefault ( ) ;
18
+
19
+ if ( _touchEffect == null || _view == null ) return ;
20
+
21
+ _touchRecognizer = new TouchRecognizer ( Element , _touchEffect ) ;
22
+ _view . AddGestureRecognizer ( _touchRecognizer ) ;
23
+ _view . AddGestureRecognizer ( GetMouseWheelRecognizer ( _view ) ) ;
24
+ }
25
+
26
+ protected override void OnDetached ( )
27
+ {
28
+ if ( _touchRecognizer != null )
29
+ {
30
+ _touchRecognizer . Detach ( ) ;
31
+ _view . RemoveGestureRecognizer ( _touchRecognizer ) ;
32
+ }
33
+ }
34
+
35
+ // https://github.com/dotnet/maui/issues/16130
36
+ private UIPanGestureRecognizer GetMouseWheelRecognizer ( UIView v )
37
+ {
38
+ return new UIPanGestureRecognizer ( ( e ) =>
39
+ {
40
+ if ( e . State == UIGestureRecognizerState . Ended )
41
+ return ;
42
+
43
+ var isZoom = e . NumberOfTouches == 0 ;
44
+ if ( ! isZoom ) return ;
45
+
46
+ var l = e . LocationInView ( v ) ;
47
+ var t = e . TranslationInView ( v ) ;
48
+ var deltaX = t . X / 2 ;
49
+ var deltaY = t . Y / 2 ;
50
+ var delta = deltaY != 0 ? deltaY : deltaX ;
51
+
52
+ var tolerance = 5 ;
53
+ if ( Math . Abs ( delta ) < tolerance ) return ;
54
+
55
+ var pointerX = l . X - t . X ;
56
+ var pointerY = l . Y - t . Y ;
57
+ var locations = new [ ] { new Point ( pointerX , pointerY ) } ;
58
+
59
+ var eventArgs = new TouchActionEventArgs ( 0 , TouchActionType . MouseWheel , locations , false )
60
+ {
61
+ MouseWheelDelta = ( int ) delta
62
+ } ;
63
+
64
+ _touchEffect . OnTouchAction ( Element , eventArgs ) ;
65
+ } )
66
+ {
67
+ AllowedScrollTypesMask = UIScrollTypeMask . Discrete | UIScrollTypeMask . Continuous ,
68
+ MinimumNumberOfTouches = 0 ,
69
+ ShouldRecognizeSimultaneously = ( _ , _ ) => true
70
+ } ;
71
+ }
72
+ }
73
+
74
+ internal class TouchRecognizer : UIGestureRecognizer
75
+ {
76
+ private readonly Microsoft . Maui . Controls . Element _element ;
77
+ private readonly MyTouchEffect _touchEffect ;
78
+ private uint _activeTouchesCount = 0 ;
79
+
80
+ public TouchRecognizer ( Microsoft . Maui . Controls . Element element , MyTouchEffect touchEffect )
81
+ {
82
+ this . _element = element ;
83
+ this . _touchEffect = touchEffect ;
84
+ ShouldRecognizeSimultaneously = ( _ , _ ) => true ;
85
+ }
86
+
87
+ public void Detach ( )
88
+ {
89
+ ShouldRecognizeSimultaneously = null ;
90
+ }
91
+
92
+ public override void TouchesBegan ( NSSet touches , UIEvent evt )
93
+ {
94
+ base . TouchesBegan ( touches , evt ) ;
95
+ _activeTouchesCount += touches . Count . ToUInt32 ( ) ;
96
+ FireEvent ( touches , TouchActionType . Pressed , true ) ;
97
+ }
98
+
99
+ public override void TouchesMoved ( NSSet touches , UIEvent evt )
100
+ {
101
+ base . TouchesMoved ( touches , evt ) ;
102
+
103
+ if ( _activeTouchesCount == touches . Count . ToUInt32 ( ) )
104
+ {
105
+ FireEvent ( touches , TouchActionType . Moved , true ) ;
106
+ }
107
+ }
108
+
109
+ public override void TouchesEnded ( NSSet touches , UIEvent evt )
110
+ {
111
+ base . TouchesEnded ( touches , evt ) ;
112
+ _activeTouchesCount -= touches . Count . ToUInt32 ( ) ;
113
+ FireEvent ( touches , TouchActionType . Released , false ) ;
114
+ }
115
+
116
+ private void FireEvent ( NSSet touches , TouchActionType actionType , bool isInContact )
117
+ {
118
+ UITouch [ ] uiTouches = touches . Cast < UITouch > ( ) . ToArray ( ) ;
119
+ long id = ( ( IntPtr ) uiTouches . First ( ) . Handle ) . ToInt64 ( ) ;
120
+ Point [ ] points = new Point [ uiTouches . Length ] ;
121
+
122
+ for ( int i = 0 ; i < uiTouches . Length ; i ++ )
123
+ {
124
+ CGPoint cgPoint = uiTouches [ i ] . LocationInView ( View ) ;
125
+ points [ i ] = new ( cgPoint . X , cgPoint . Y ) ;
126
+ }
127
+ _touchEffect . OnTouchAction ( _element , new ( id , actionType , points , isInContact ) ) ;
128
+ }
129
+ }
0 commit comments