From 8d7366642139e5ac2b5882d748217a1fd6b4bff4 Mon Sep 17 00:00:00 2001 From: Alberto Aldegheri Date: Mon, 18 Nov 2024 17:25:24 +0100 Subject: [PATCH] Fix touch gestures not working on MAUI iOS once packaged --- Directory.Build.props | 6 + LiveCharts.Maui.sln | 6 + build/pack.ps1 | 4 +- global.json | 6 + samples/MauiSample/MauiProgram.cs | 1 + samples/MauiSample/MauiSample.csproj | 2 +- .../Platforms/Android/AndroidManifest.xml | 3 +- .../ChartBehaviour.MacCatalyst.cs | 233 +++++++++--------- .../ChartBehaviour._shared.cs | 4 +- .../LiveChartsCore.Behaviours.csproj | 1 - src/LiveChartsCore/LiveChartsCore.csproj | 1 - .../LiveChartsCore.SkiaSharpView.csproj | 1 - .../CartesianChart.xaml | 10 +- .../CartesianChart.xaml.cs | 27 +- .../ChartBehaviour.cs | 119 ++++++--- .../ChartView.cs | 38 +++ .../ChartViewHandler.cs | 81 ++++++ .../LiveChartsCore.SkiaSharpView.Maui.csproj | 5 +- .../LiveChartsCoreMauiAppBuilderExtensions.cs | 39 +++ .../MotionCanvas.xaml.cs | 2 +- .../PieChart.xaml | 10 +- .../PieChart.xaml.cs | 19 +- .../Platforms/Android/PlatformClass1.cs | 6 - .../Platforms/MacCatalyst/PlatformClass1.cs | 6 - .../Platforms/Windows/PlatformClass1.cs | 6 - .../Platforms/iOS/PlatformClass1.cs | 6 - .../PolarChart.xaml | 10 +- .../PolarChart.xaml.cs | 21 +- .../ChartBehaviour.cs | 8 +- 29 files changed, 426 insertions(+), 255 deletions(-) create mode 100644 Directory.Build.props create mode 100644 global.json create mode 100644 src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartView.cs create mode 100644 src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartViewHandler.cs create mode 100644 src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCoreMauiAppBuilderExtensions.cs delete mode 100644 src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/Android/PlatformClass1.cs delete mode 100644 src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/MacCatalyst/PlatformClass1.cs delete mode 100644 src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/Windows/PlatformClass1.cs delete mode 100644 src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/iOS/PlatformClass1.cs diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 000000000..4e093035c --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,6 @@ + + + 8.0.82 + + + diff --git a/LiveCharts.Maui.sln b/LiveCharts.Maui.sln index c2f1f3246..f5a20e98d 100644 --- a/LiveCharts.Maui.sln +++ b/LiveCharts.Maui.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiSample", "samples\MauiS EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ViewModelsSamples", "samples\ViewModelsSamples\ViewModelsSamples.csproj", "{F12F0322-ED2F-48FB-99C2-61B415457443}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiveChartsCore.Behaviours", "src\LiveChartsCore.Behaviours\LiveChartsCore.Behaviours.csproj", "{CCFF5DA6-2C27-48C9-BBB6-CDDDAA835116}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -41,6 +43,10 @@ Global {F12F0322-ED2F-48FB-99C2-61B415457443}.Debug|Any CPU.Build.0 = Debug|Any CPU {F12F0322-ED2F-48FB-99C2-61B415457443}.Release|Any CPU.ActiveCfg = Release|Any CPU {F12F0322-ED2F-48FB-99C2-61B415457443}.Release|Any CPU.Build.0 = Release|Any CPU + {CCFF5DA6-2C27-48C9-BBB6-CDDDAA835116}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CCFF5DA6-2C27-48C9-BBB6-CDDDAA835116}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CCFF5DA6-2C27-48C9-BBB6-CDDDAA835116}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CCFF5DA6-2C27-48C9-BBB6-CDDDAA835116}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build/pack.ps1 b/build/pack.ps1 index 6244da6c2..27aa5eac9 100644 --- a/build/pack.ps1 +++ b/build/pack.ps1 @@ -2,6 +2,7 @@ param([string]$configuration = "Debug", [string]$nupkgOutputPath = "./nupkg") [Project[]]$projects = @( [Project]::new("./src/LiveChartsCore/LiveChartsCore.csproj") + [Project]::new("./src/LiveChartsCore.Behaviours/LiveChartsCore.Behaviours.csproj") [Project]::new("./src/skiasharp/LiveChartsCore.SkiaSharp/LiveChartsCore.SkiaSharpView.csproj") [Project]::new("./src/skiasharp/LiveChartsCore.SkiaSharp.Avalonia/LiveChartsCore.SkiaSharpView.Avalonia.csproj") [Project]::new("./src/skiasharp/LiveChartsCore.SkiaSharp.WinForms/LiveChartsCore.SkiaSharpView.WinForms.csproj") @@ -11,7 +12,6 @@ param([string]$configuration = "Debug", [string]$nupkgOutputPath = "./nupkg") [Project]::new("./src/skiasharp/LiveChartsCore.SkiaSharpView.Eto/LiveChartsCore.SkiaSharpView.Eto.csproj") [Project]::new("./src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCore.SkiaSharpView.Maui.csproj") [Project]::new("./src/skiasharp/LiveChartsCore.SkiaSharpView.Uno.WinUI/LiveChartsCore.SkiaSharpView.Uno.WinUI.csproj") - [Project]::new("./src/LiveChartsCore.Behaviours/LiveChartsCore.Behaviours.csproj") [Project]::new("./src/skiasharp/LiveChartsCore.SkiaSharpView.WinUI/LiveChartsCore.SkiaSharpView.WinUI.csproj") ) @@ -41,6 +41,6 @@ foreach ($p in $projects) { if (Test-Path $($folder + "/bin")) { Remove-Item $($folder + "/bin") -Force -Recurse } - + dotnet pack $p.src -o $nupkgOutputPath -c $configuration -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg } diff --git a/global.json b/global.json new file mode 100644 index 000000000..41336fb9c --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "8.0.401", + "rollForward": "latestFeature" + } +} \ No newline at end of file diff --git a/samples/MauiSample/MauiProgram.cs b/samples/MauiSample/MauiProgram.cs index 2c17f23ef..5e2de79e0 100644 --- a/samples/MauiSample/MauiProgram.cs +++ b/samples/MauiSample/MauiProgram.cs @@ -9,6 +9,7 @@ public static MauiApp CreateMauiApp() var builder = MauiApp.CreateBuilder(); _ = builder .UseSkiaSharp() + .UseLiveCharts() .UseMauiApp() .ConfigureFonts(fonts => { diff --git a/samples/MauiSample/MauiSample.csproj b/samples/MauiSample/MauiSample.csproj index 248d870fc..0227daf45 100644 --- a/samples/MauiSample/MauiSample.csproj +++ b/samples/MauiSample/MauiSample.csproj @@ -12,7 +12,7 @@ The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated; either BOTH runtimes must be indicated or ONLY macatalyst-x64. --> - + Exe MauiSample true diff --git a/samples/MauiSample/Platforms/Android/AndroidManifest.xml b/samples/MauiSample/Platforms/Android/AndroidManifest.xml index 7570ff62d..d635c1f38 100644 --- a/samples/MauiSample/Platforms/Android/AndroidManifest.xml +++ b/samples/MauiSample/Platforms/Android/AndroidManifest.xml @@ -1,6 +1,5 @@  - - \ No newline at end of file + diff --git a/src/LiveChartsCore.Behaviours/ChartBehaviour.MacCatalyst.cs b/src/LiveChartsCore.Behaviours/ChartBehaviour.MacCatalyst.cs index 0c350ce29..018c2883f 100644 --- a/src/LiveChartsCore.Behaviours/ChartBehaviour.MacCatalyst.cs +++ b/src/LiveChartsCore.Behaviours/ChartBehaviour.MacCatalyst.cs @@ -39,132 +39,45 @@ public partial class ChartBehaviour #if MACCATALYST /// - /// Builds a mac catalyst gesture recognizer. + /// Gets the hover gesture recognizer. /// - /// the view. - /// the recognizer. - protected UIHoverGestureRecognizer GetMacCatalystHover(UIView view) - { - return new UIHoverGestureRecognizer((UIHoverGestureRecognizer e) => - { - switch (e.State) - { - case UIGestureRecognizerState.Changed: - var p = e.LocationInView(view); - Moved?.Invoke(view, new(new(p.X, p.Y), e)); - break; - case UIGestureRecognizerState.Cancelled: - case UIGestureRecognizerState.Failed: - case UIGestureRecognizerState.Ended: - Exited?.Invoke(view, new(e)); - break; - case UIGestureRecognizerState.Possible: - case UIGestureRecognizerState.Began: - default: - break; - } - }); - } + protected UIHoverGestureRecognizer MacCatalystHoverGestureRecognizer { get; } + #endif /// - /// Builds a mac catalyst gesture recognizer. + /// Gets the long press gesture recognizer. /// - /// the view. - /// the recognizer. - protected UILongPressGestureRecognizer GetMacCatalystLongPress(UIView view) - { - return new UILongPressGestureRecognizer((UILongPressGestureRecognizer e) => - { - var location = e.LocationInView(view); - var p = new LvcPoint((float)location.X, (float)location.Y); - var isRightClick = (DateTime.Now - _previousPress).TotalMilliseconds < 500; - var isPinch = e.NumberOfTouches > 1; - - switch (e.State) - { - case UIGestureRecognizerState.Began: - Pressed?.Invoke(view, new(p, isRightClick, e)); - _previousPress = DateTime.Now; - break; - case UIGestureRecognizerState.Changed: - Moved?.Invoke(view, new(p, e)); - break; - case UIGestureRecognizerState.Cancelled: - case UIGestureRecognizerState.Ended: - Released?.Invoke(view, new(p, isRightClick, e)); - break; - case UIGestureRecognizerState.Possible: - case UIGestureRecognizerState.Failed: - default: - break; - } - }) - { - MinimumPressDuration = 0, - ShouldRecognizeSimultaneously = (g1, g2) => true - }; - } - - private float _previousScale = 1; + protected UILongPressGestureRecognizer MacCatalystLongPressGestureRecognizer { get; } /// - /// Builds a mac catalyst gesture recognizer. + /// Gets the pinch gesture recognizer. /// - /// the view. - /// the recognizer. - protected UIPinchGestureRecognizer GetMacCatalystPinch(UIView view) - { - return new UIPinchGestureRecognizer((UIPinchGestureRecognizer e) => - { - var p = e.LocationInView(view); - - switch (e.State) - { - case UIGestureRecognizerState.Began: - _previousScale = 1; - break; - case UIGestureRecognizerState.Changed: - var s = (float)e.Scale; - var delta = _previousScale - s; - Pinched?.Invoke(view, new(1 - delta, new(p.X, p.Y), e)); - _previousScale = s; - break; - case UIGestureRecognizerState.Ended: - case UIGestureRecognizerState.Cancelled: - break; - case UIGestureRecognizerState.Possible: - case UIGestureRecognizerState.Failed: - default: - break; - } - }) - { - ShouldRecognizeSimultaneously = (g1, g2) => true - }; - } + protected UIPinchGestureRecognizer MacCatalystPinchGestureRecognizer { get; } - private CGPoint? _last; + /// + /// Gets the pan gesture recognizer. + /// + protected UIPanGestureRecognizer MacCatalystPanGestureRecognizer { get; } /// - /// Builds a mac catalyst gesture recognizer. + /// Initializes a new instance of the class. /// - /// The view. - /// The recognizer. - protected UIPanGestureRecognizer GetMacCatalystOnPan(UIView view) + public ChartBehaviour() { - return new UIPanGestureRecognizer((UIPanGestureRecognizer e) => +#if MACCATALYST + MacCatalystHoverGestureRecognizer = new UIHoverGestureRecognizer(OnHover); +#endif + MacCatalystLongPressGestureRecognizer = new UILongPressGestureRecognizer(OnLongPress) { - var l = e.LocationInView(view); - _last ??= l; - var delta = _last.Value.Y - l.Y; - var isZoom = e.NumberOfTouches == 0; - var tolerance = 5; // just a factor to avoid multiple calls. - - if (e.State == UIGestureRecognizerState.Ended || !isZoom || Math.Abs(delta) < tolerance) return; - Scrolled?.Invoke(view, new(new(l.X, l.Y), delta, e)); - _last = l; - }) + MinimumPressDuration = 0, + ShouldRecognizeSimultaneously = (g1, g2) => true + }; + MacCatalystPinchGestureRecognizer = new UIPinchGestureRecognizer(OnPinch) + { + ShouldRecognizeSimultaneously = (g1, g2) => true + }; + MacCatalystPanGestureRecognizer = new UIPanGestureRecognizer(OnPan) { #if MACCATALYST AllowedScrollTypesMask = UIScrollTypeMask.Discrete | UIScrollTypeMask.Continuous, @@ -173,6 +86,102 @@ protected UIPanGestureRecognizer GetMacCatalystOnPan(UIView view) ShouldRecognizeSimultaneously = (g1, g2) => true }; } + +#if MACCATALYST + + private void OnHover(UIHoverGestureRecognizer e) + { + var view = e.View; + switch (e.State) + { + case UIGestureRecognizerState.Changed: + var p = e.LocationInView(view); + Moved?.Invoke(view, new(new(p.X, p.Y), e)); + break; + case UIGestureRecognizerState.Cancelled: + case UIGestureRecognizerState.Failed: + case UIGestureRecognizerState.Ended: + Exited?.Invoke(view, new(e)); + break; + case UIGestureRecognizerState.Possible: + case UIGestureRecognizerState.Began: + default: + break; + } + } + +#endif + + private void OnLongPress(UILongPressGestureRecognizer e) + { + var view = e.View; + var location = e.LocationInView(view); + var p = new LvcPoint((float)location.X, (float)location.Y); + var isRightClick = (DateTime.Now - _previousPress).TotalMilliseconds < 500; + var isPinch = e.NumberOfTouches > 1; + + switch (e.State) + { + case UIGestureRecognizerState.Began: + Pressed?.Invoke(view, new(p, isRightClick, e)); + _previousPress = DateTime.Now; + break; + case UIGestureRecognizerState.Changed: + Moved?.Invoke(view, new(p, e)); + break; + case UIGestureRecognizerState.Cancelled: + case UIGestureRecognizerState.Ended: + Released?.Invoke(view, new(p, isRightClick, e)); + break; + case UIGestureRecognizerState.Possible: + case UIGestureRecognizerState.Failed: + default: + break; + } + } + + private float _previousScale = 1; + + private void OnPinch(UIPinchGestureRecognizer e) + { + var view = e.View; + var p = e.LocationInView(view); + + switch (e.State) + { + case UIGestureRecognizerState.Began: + _previousScale = 1; + break; + case UIGestureRecognizerState.Changed: + var s = (float)e.Scale; + var delta = _previousScale - s; + Pinched?.Invoke(view, new(1 - delta, new(p.X, p.Y), e)); + _previousScale = s; + break; + case UIGestureRecognizerState.Ended: + case UIGestureRecognizerState.Cancelled: + break; + case UIGestureRecognizerState.Possible: + case UIGestureRecognizerState.Failed: + default: + break; + } + } + + private CGPoint? _last; + private void OnPan(UIPanGestureRecognizer e) + { + var view = e.View; + var l = e.LocationInView(view); + _last ??= l; + var delta = _last.Value.Y - l.Y; + var isZoom = e.NumberOfTouches == 0; + var tolerance = 5; // just a factor to avoid multiple calls. + + if (e.State == UIGestureRecognizerState.Ended || !isZoom || Math.Abs(delta) < tolerance) return; + Scrolled?.Invoke(view, new(new(l.X, l.Y), delta, e)); + _last = l; + } } #endif diff --git a/src/LiveChartsCore.Behaviours/ChartBehaviour._shared.cs b/src/LiveChartsCore.Behaviours/ChartBehaviour._shared.cs index af71c57a6..6cd2e5de3 100644 --- a/src/LiveChartsCore.Behaviours/ChartBehaviour._shared.cs +++ b/src/LiveChartsCore.Behaviours/ChartBehaviour._shared.cs @@ -34,12 +34,12 @@ public abstract partial class ChartBehaviour /// Gets or sets the screen size, only used internally by the Android handler, to implement a /// workaround for https://github.com/dotnet/maui/issues/18547. /// - public LvcSize ScreenSize { get; set; } + public virtual LvcSize ScreenSize { get; } = new(320, 480); /// /// Gets or sets the screen density. /// - public double Density { get; set; } + public virtual double Density { get; } = 1.0; /// /// Called when the pointer/tap is pressed. diff --git a/src/LiveChartsCore.Behaviours/LiveChartsCore.Behaviours.csproj b/src/LiveChartsCore.Behaviours/LiveChartsCore.Behaviours.csproj index b9340a89c..acbadea2f 100644 --- a/src/LiveChartsCore.Behaviours/LiveChartsCore.Behaviours.csproj +++ b/src/LiveChartsCore.Behaviours/LiveChartsCore.Behaviours.csproj @@ -41,7 +41,6 @@ true true true - embedded diff --git a/src/LiveChartsCore/LiveChartsCore.csproj b/src/LiveChartsCore/LiveChartsCore.csproj index 6ad88316e..44ab1e518 100644 --- a/src/LiveChartsCore/LiveChartsCore.csproj +++ b/src/LiveChartsCore/LiveChartsCore.csproj @@ -36,7 +36,6 @@ true true true - embedded diff --git a/src/skiasharp/LiveChartsCore.SkiaSharp/LiveChartsCore.SkiaSharpView.csproj b/src/skiasharp/LiveChartsCore.SkiaSharp/LiveChartsCore.SkiaSharpView.csproj index edef1b70a..c859d4a4e 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharp/LiveChartsCore.SkiaSharpView.csproj +++ b/src/skiasharp/LiveChartsCore.SkiaSharp/LiveChartsCore.SkiaSharpView.csproj @@ -36,7 +36,6 @@ true true true - embedded diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/CartesianChart.xaml b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/CartesianChart.xaml index f1d394f44..9ad594e99 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/CartesianChart.xaml +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/CartesianChart.xaml @@ -1,9 +1,9 @@ - + - + diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/CartesianChart.xaml.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/CartesianChart.xaml.cs index a059bc732..bc9a3133e 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/CartesianChart.xaml.cs +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/CartesianChart.xaml.cs @@ -48,7 +48,7 @@ namespace LiveChartsCore.SkiaSharpView.Maui; /// [XamlCompilation(XamlCompilationOptions.Compile)] -public partial class CartesianChart : ContentView, ICartesianChartView +public partial class CartesianChart : ChartView, ICartesianChartView { #region fields @@ -102,20 +102,9 @@ public CartesianChart() _core.Measuring += OnCoreMeasuring; _core.UpdateStarted += OnCoreUpdateStarted; _core.UpdateFinished += OnCoreUpdateFinished; - - var chartBehaviour = new ChartBehaviour(); - - chartBehaviour.Pressed += OnPressed; - chartBehaviour.Moved += OnMoved; - chartBehaviour.Released += OnReleased; - chartBehaviour.Scrolled += OnScrolled; - chartBehaviour.Pinched += OnPinched; - chartBehaviour.Exited += OnExited; - - chartBehaviour.On(this); } - #region bindable properties + #region bindable properties /// /// The sync context property. @@ -750,7 +739,7 @@ protected override void OnParentSet() _core?.Load(); } - private void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) + internal override void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) { // not implemented yet? // https://github.com/dotnet/maui/issues/16202 @@ -762,7 +751,7 @@ private void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) _core?.InvokePointerDown(args.Location, args.IsSecondaryPress); } - private void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) + internal override void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) { var location = args.Location; @@ -772,7 +761,7 @@ private void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) _core?.InvokePointerMove(location); } - private void OnReleased(object? sender, Behaviours.Events.PressedEventArgs args) + internal override void OnReleased(object? sender, Behaviours.Events.PressedEventArgs args) { var cArgs = new PointerCommandArgs(this, new(args.Location.X, args.Location.Y), args); if (ReleasedCommand?.CanExecute(cArgs) == true) ReleasedCommand.Execute(cArgs); @@ -780,14 +769,14 @@ private void OnReleased(object? sender, Behaviours.Events.PressedEventArgs args) _core?.InvokePointerUp(args.Location, args.IsSecondaryPress); } - private void OnScrolled(object? sender, Behaviours.Events.ScrollEventArgs args) + internal override void OnScrolled(object? sender, Behaviours.Events.ScrollEventArgs args) { if (_core is null) throw new Exception("core not found"); var c = (CartesianChart)_core; c.Zoom(args.Location, args.ScrollDelta > 0 ? ZoomDirection.ZoomIn : ZoomDirection.ZoomOut); } - private void OnPinched(object? sender, Behaviours.Events.PinchEventArgs args) + internal override void OnPinched(object? sender, Behaviours.Events.PinchEventArgs args) { if (_core is null) return; @@ -798,7 +787,7 @@ private void OnPinched(object? sender, Behaviours.Events.PinchEventArgs args) c.Zoom(pivot, ZoomDirection.DefinedByScaleFactor, args.Scale, true); } - private void OnExited(object? sender, Behaviours.Events.EventArgs args) + internal override void OnExited(object? sender, Behaviours.Events.EventArgs args) { _core?.InvokePointerLeft(); } diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartBehaviour.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartBehaviour.cs index ab34ab782..e7b3dbbe3 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartBehaviour.cs +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartBehaviour.cs @@ -1,5 +1,4 @@ - -// The MIT License(MIT) +// The MIT License(MIT) // // Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors // @@ -21,6 +20,17 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +#if IOS || MACCATALYST +using PlatformView = Microsoft.Maui.Platform.ContentView; +#elif ANDROID +using PlatformView = Microsoft.Maui.Platform.ContentViewGroup; +#elif WINDOWS +using PlatformView = Microsoft.Maui.Platform.ContentPanel; +#else +using PlatformView = System.Object; +#endif + +using LiveChartsCore.Drawing; using Microsoft.Maui.Devices; namespace LiveChartsCore.SkiaSharpView.Maui; @@ -28,60 +38,93 @@ namespace LiveChartsCore.SkiaSharpView.Maui; /// /// The chart behaviour for MAUI. /// -public class ChartBehaviour : Behaviours.ChartBehaviour +public partial class ChartBehaviour : Behaviours.ChartBehaviour { - /// - /// Attaches the native events on the specified element. - /// - /// The element. - public void On(Microsoft.Maui.Controls.VisualElement element) + private static double s_density; + private static LvcSize s_screenSize; + + static ChartBehaviour() { - element.HandlerChanged += (sender, e) => + var deviceDisplay = DeviceDisplay.Current; + deviceDisplay.MainDisplayInfoChanged += (_, args) => { - ScreenSize = new( - (float)DeviceDisplay.MainDisplayInfo.Width, - (float)DeviceDisplay.MainDisplayInfo.Height); - Density = DeviceDisplay.MainDisplayInfo.Density; + var displayInfo = args.DisplayInfo; + UpdateScreenInfo(displayInfo); + }; -#if ANDROID + UpdateScreenInfo(deviceDisplay.MainDisplayInfo); + return; + + void UpdateScreenInfo(DisplayInfo displayInfo) + { + s_density = displayInfo.Density; + s_screenSize = new LvcSize((float)displayInfo.Width, (float)displayInfo.Height); + } + } - var contentViewGroup = (Microsoft.Maui.Platform.ContentViewGroup?)element.Handler?.PlatformView - ?? throw new System.Exception("Unable to cast to ContentViewGroup"); + /// + public override LvcSize ScreenSize => s_screenSize; - contentViewGroup.Touch += OnAndroidTouched; - contentViewGroup.Hover += OnAndroidHover; + /// + public override double Density => s_density; + /// + /// Attaches the native events on the specified platform view. + /// + /// The platform view. + public void On(PlatformView platformView) + { +#if ANDROID + platformView.Touch += OnAndroidTouched; + platformView.Hover += OnAndroidHover; #endif #if MACCATALYST || IOS - - var contentView = (Microsoft.Maui.Platform.ContentView?)element.Handler?.PlatformView - ?? throw new System.Exception("Unable to cast to ContentView"); - - contentView.UserInteractionEnabled = true; - + platformView.UserInteractionEnabled = true; #if MACCATALYST - contentView.AddGestureRecognizer(GetMacCatalystHover(contentView)); + platformView.AddGestureRecognizer(MacCatalystHoverGestureRecognizer); #endif - contentView.AddGestureRecognizer(GetMacCatalystLongPress(contentView)); - contentView.AddGestureRecognizer(GetMacCatalystPinch(contentView)); - contentView.AddGestureRecognizer(GetMacCatalystOnPan(contentView)); - + platformView.AddGestureRecognizer(MacCatalystLongPressGestureRecognizer); + platformView.AddGestureRecognizer(MacCatalystPinchGestureRecognizer); + platformView.AddGestureRecognizer(MacCatalystPanGestureRecognizer); #endif #if WINDOWS + platformView.PointerPressed += OnWindowsPointerPressed; + platformView.PointerMoved += OnWindowsPointerMoved; + platformView.PointerReleased += OnWindowsPointerReleased; + platformView.PointerWheelChanged += OnWindowsPointerWheelChanged; + platformView.PointerExited += OnWindowsPointerExited; +#endif + } - var contentPanel = (Microsoft.UI.Xaml.UIElement?)element.Handler?.PlatformView - ?? throw new System.Exception("Unable to cast to ContentPanel"); - - contentPanel.PointerPressed += OnWindowsPointerPressed; - contentPanel.PointerMoved += OnWindowsPointerMoved; - contentPanel.PointerReleased += OnWindowsPointerReleased; - contentPanel.PointerWheelChanged += OnWindowsPointerWheelChanged; - contentPanel.PointerExited += OnWindowsPointerExited; + /// + /// Detaches the native events on the specified platform view. + /// + /// The platform view. + public void Off(PlatformView platformView) + { +#if ANDROID + platformView.Touch -= OnAndroidTouched; + platformView.Hover -= OnAndroidHover; +#endif +#if MACCATALYST || IOS + platformView.UserInteractionEnabled = false; +#if MACCATALYST + platformView.RemoveGestureRecognizer(MacCatalystHoverGestureRecognizer); +#endif + platformView.RemoveGestureRecognizer(MacCatalystLongPressGestureRecognizer); + platformView.RemoveGestureRecognizer(MacCatalystPinchGestureRecognizer); + platformView.RemoveGestureRecognizer(MacCatalystPanGestureRecognizer); #endif - }; +#if WINDOWS + platformView.PointerPressed -= OnWindowsPointerPressed; + platformView.PointerMoved -= OnWindowsPointerMoved; + platformView.PointerReleased -= OnWindowsPointerReleased; + platformView.PointerWheelChanged -= OnWindowsPointerWheelChanged; + platformView.PointerExited -= OnWindowsPointerExited; +#endif } } diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartView.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartView.cs new file mode 100644 index 000000000..a22535b0d --- /dev/null +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartView.cs @@ -0,0 +1,38 @@ +// The MIT License(MIT) +// +// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using Microsoft.Maui.Controls; + +namespace LiveChartsCore.SkiaSharpView.Maui; + +/// +/// Base class for views that display a chart. +/// +public abstract class ChartView : ContentView +{ + internal virtual void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) { } + internal virtual void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) { } + internal virtual void OnReleased(object? sender, Behaviours.Events.PressedEventArgs args) { } + internal virtual void OnScrolled(object? sender, Behaviours.Events.ScrollEventArgs args) { } + internal virtual void OnPinched(object? sender, Behaviours.Events.PinchEventArgs args) { } + internal virtual void OnExited(object? sender, Behaviours.Events.EventArgs args) { } +} diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartViewHandler.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartViewHandler.cs new file mode 100644 index 000000000..ca8293e85 --- /dev/null +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/ChartViewHandler.cs @@ -0,0 +1,81 @@ +// The MIT License(MIT) +// +// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#if IOS || MACCATALYST +using PlatformView = Microsoft.Maui.Platform.ContentView; +#elif ANDROID +using PlatformView = Microsoft.Maui.Platform.ContentViewGroup; +#elif WINDOWS +using PlatformView = Microsoft.Maui.Platform.ContentPanel; +#else +using PlatformView = System.Object; +#endif + +using LiveChartsCore.Behaviours.Events; +using Microsoft.Maui.Handlers; + +namespace LiveChartsCore.SkiaSharpView.Maui; + +/// +/// A specific to the control. +/// +public class ChartViewHandler : ContentViewHandler +{ + private readonly ChartBehaviour _chartBehaviour; + + private ChartView? ChartView => VirtualView as ChartView; + + /// + /// Initializes a new instance of the class. + /// + public ChartViewHandler() + { + _chartBehaviour = new ChartBehaviour(); + _chartBehaviour.Pressed += OnPressed; + _chartBehaviour.Moved += OnMoved; + _chartBehaviour.Released += OnReleased; + _chartBehaviour.Scrolled += OnScrolled; + _chartBehaviour.Pinched += OnPinched; + _chartBehaviour.Exited += OnExited; + } + + /// + protected override void ConnectHandler(PlatformView platformView) + { + base.ConnectHandler(platformView); + _chartBehaviour.On(platformView); + } + + /// + protected override void DisconnectHandler(PlatformView platformView) + { + _chartBehaviour.Off(platformView); + base.DisconnectHandler(platformView); + } + + private void OnPressed(object? sender, PressedEventArgs args) => ChartView?.OnPressed(sender, args); + private void OnMoved(object? sender, ScreenEventArgs args) => ChartView?.OnMoved(sender, args); + private void OnReleased(object? sender, PressedEventArgs args) => ChartView?.OnReleased(sender, args); + private void OnScrolled(object? sender, ScrollEventArgs args) => ChartView?.OnScrolled(sender, args); + private void OnPinched(object? sender, PinchEventArgs args) => ChartView?.OnPinched(sender, args); + private void OnExited(object? sender, EventArgs args) => ChartView?.OnExited(sender, args); +} diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCore.SkiaSharpView.Maui.csproj b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCore.SkiaSharpView.Maui.csproj index 55efc62d7..462647b3d 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCore.SkiaSharpView.Maui.csproj +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCore.SkiaSharpView.Maui.csproj @@ -39,11 +39,10 @@ true true true - embedded - + - + diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCoreMauiAppBuilderExtensions.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCoreMauiAppBuilderExtensions.cs new file mode 100644 index 000000000..438836092 --- /dev/null +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/LiveChartsCoreMauiAppBuilderExtensions.cs @@ -0,0 +1,39 @@ +// The MIT License(MIT) +// +// Copyright(c) 2021 Alberto Rodriguez Orozco & LiveCharts Contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using LiveChartsCore.SkiaSharpView.Maui; + +namespace Microsoft.Maui.Hosting; + +/// +/// LiveCharts extensions for the class. +/// +public static class LiveChartsCoreMauiAppBuilderExtensions +{ + /// + /// Adds LiveCharts components to the MAUI app. + /// + /// + /// + public static MauiAppBuilder UseLiveCharts(this MauiAppBuilder mauiAppBuilder) => + mauiAppBuilder.ConfigureMauiHandlers(handlers => handlers.AddHandler()); +} diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/MotionCanvas.xaml.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/MotionCanvas.xaml.cs index dc142bbb1..e0de8c4a2 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/MotionCanvas.xaml.cs +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/MotionCanvas.xaml.cs @@ -37,7 +37,7 @@ namespace LiveChartsCore.SkiaSharpView.Maui; /// -/// Defines the motion cavnas class for Maui. +/// Defines the motion canvas class for MAUI. /// [XamlCompilation(XamlCompilationOptions.Compile)] public partial class MotionCanvas : ContentView diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PieChart.xaml b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PieChart.xaml index a366d8f8d..3f0f56185 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PieChart.xaml +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PieChart.xaml @@ -1,9 +1,9 @@ - + - + diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PieChart.xaml.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PieChart.xaml.cs index 6bbb8a55f..f073b0726 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PieChart.xaml.cs +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PieChart.xaml.cs @@ -45,7 +45,7 @@ namespace LiveChartsCore.SkiaSharpView.Maui; /// [XamlCompilation(XamlCompilationOptions.Compile)] -public partial class PieChart : ContentView, IPieChartView +public partial class PieChart : ChartView, IPieChartView { #region fields @@ -85,15 +85,6 @@ public PieChart() _core.Measuring += OnCoreMeasuring; _core.UpdateStarted += OnCoreUpdateStarted; _core.UpdateFinished += OnCoreUpdateFinished; - - var chartBehaviour = new ChartBehaviour(); - - chartBehaviour.Pressed += OnPressed; - chartBehaviour.Moved += OnMoved; - chartBehaviour.Released += OnReleased; - chartBehaviour.Exited += OnExited; - - chartBehaviour.On(this); } #region bindable properties @@ -648,7 +639,7 @@ protected override void OnParentSet() _core?.Load(); } - private void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) + internal override void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) { // not implemented yet? // https://github.com/dotnet/maui/issues/16202 @@ -660,7 +651,7 @@ private void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) _core?.InvokePointerDown(args.Location, args.IsSecondaryPress); } - private void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) + internal override void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) { var location = args.Location; @@ -670,12 +661,12 @@ private void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) _core?.InvokePointerMove(location); } - private void OnReleased(object? sender, Behaviours.Events.PressedEventArgs args) + internal override void OnReleased(object? sender, Behaviours.Events.PressedEventArgs args) { _core?.InvokePointerUp(args.Location, args.IsSecondaryPress); } - private void OnExited(object? sender, Behaviours.Events.EventArgs args) + internal override void OnExited(object? sender, Behaviours.Events.EventArgs args) { _core?.InvokePointerLeft(); } diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/Android/PlatformClass1.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/Android/PlatformClass1.cs deleted file mode 100644 index 69e58236c..000000000 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/Android/PlatformClass1.cs +++ /dev/null @@ -1,6 +0,0 @@ -//namespace LiveChartsCore.SkiaSharpView.Maui; - -//// All the code in this file is only included on Android. -//public class PlatformClass1 -//{ -//} diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/MacCatalyst/PlatformClass1.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/MacCatalyst/PlatformClass1.cs deleted file mode 100644 index 3360d5cb5..000000000 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/MacCatalyst/PlatformClass1.cs +++ /dev/null @@ -1,6 +0,0 @@ -//namespace LiveChartsCore.SkiaSharpView.Maui; - -//// All the code in this file is only included on Mac Catalyst. -//public class PlatformClass1 -//{ -//} diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/Windows/PlatformClass1.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/Windows/PlatformClass1.cs deleted file mode 100644 index d942c56c9..000000000 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/Windows/PlatformClass1.cs +++ /dev/null @@ -1,6 +0,0 @@ -//namespace LiveChartsCore.SkiaSharpView.Maui; - -//// All the code in this file is only included on Windows. -//public class PlatformClass1 -//{ -//} diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/iOS/PlatformClass1.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/iOS/PlatformClass1.cs deleted file mode 100644 index 199a2c29d..000000000 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/Platforms/iOS/PlatformClass1.cs +++ /dev/null @@ -1,6 +0,0 @@ -//namespace LiveChartsCore.SkiaSharpView.Maui; - -//// All the code in this file is only included on iOS. -//public class PlatformClass1 -//{ -//} diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PolarChart.xaml b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PolarChart.xaml index c80199267..ceb126a95 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PolarChart.xaml +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PolarChart.xaml @@ -1,9 +1,9 @@ - + - + diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PolarChart.xaml.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PolarChart.xaml.cs index 3ce963909..413754960 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PolarChart.xaml.cs +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Maui/PolarChart.xaml.cs @@ -45,7 +45,7 @@ namespace LiveChartsCore.SkiaSharpView.Maui; /// [XamlCompilation(XamlCompilationOptions.Compile)] -public partial class PolarChart : ContentView, IPolarChartView +public partial class PolarChart : ChartView, IPolarChartView { #region fields @@ -96,18 +96,9 @@ public PolarChart() _core.Measuring += OnCoreMeasuring; _core.UpdateStarted += OnCoreUpdateStarted; _core.UpdateFinished += OnCoreUpdateFinished; - - var chartBehaviour = new ChartBehaviour(); - - chartBehaviour.Pressed += OnPressed; - chartBehaviour.Moved += OnMoved; - chartBehaviour.Released += OnReleased; - chartBehaviour.Exited += OnExited; - - chartBehaviour.On(this); } - #region bindable properties + #region bindable properties /// /// The sync context property. @@ -732,7 +723,7 @@ private void OnDeepCollectionPropertyChanged(object? sender, PropertyChangedEven _core?.Update(); } - private void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) + internal override void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) { // not implemented yet? // https://github.com/dotnet/maui/issues/16202 @@ -744,7 +735,7 @@ private void OnPressed(object? sender, Behaviours.Events.PressedEventArgs args) _core?.InvokePointerDown(args.Location, args.IsSecondaryPress); } - private void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) + internal override void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) { var location = args.Location; @@ -754,12 +745,12 @@ private void OnMoved(object? sender, Behaviours.Events.ScreenEventArgs args) _core?.InvokePointerMove(location); } - private void OnReleased(object? sender, Behaviours.Events.PressedEventArgs args) + internal override void OnReleased(object? sender, Behaviours.Events.PressedEventArgs args) { _core?.InvokePointerUp(args.Location, args.IsSecondaryPress); } - private void OnExited(object? sender, Behaviours.Events.EventArgs args) + internal override void OnExited(object? sender, Behaviours.Events.EventArgs args) { _core?.InvokePointerLeft(); } diff --git a/src/skiasharp/LiveChartsCore.SkiaSharpView.Uno.WinUI/ChartBehaviour.cs b/src/skiasharp/LiveChartsCore.SkiaSharpView.Uno.WinUI/ChartBehaviour.cs index 49b273d94..e5bbd99a8 100644 --- a/src/skiasharp/LiveChartsCore.SkiaSharpView.Uno.WinUI/ChartBehaviour.cs +++ b/src/skiasharp/LiveChartsCore.SkiaSharpView.Uno.WinUI/ChartBehaviour.cs @@ -55,11 +55,11 @@ public void On(FrameworkElement element) element.UserInteractionEnabled = true; #if MACCATALYST - element.AddGestureRecognizer(GetMacCatalystHover(element)); + element.AddGestureRecognizer(MacCatalystHoverGestureRecognizer); #endif - element.AddGestureRecognizer(GetMacCatalystLongPress(element)); - element.AddGestureRecognizer(GetMacCatalystPinch(element)); - element.AddGestureRecognizer(GetMacCatalystOnPan(element)); + element.AddGestureRecognizer(MacCatalystLongPressGestureRecognizer); + element.AddGestureRecognizer(MacCatalystPinchGestureRecognizer); + element.AddGestureRecognizer(MacCatsalystPanGestureRecognizer); #elif WINDOWS