From e2f4fc13b130554df417e0633697f1adb475693c Mon Sep 17 00:00:00 2001 From: Clemens Date: Wed, 12 Jan 2022 23:56:05 +0100 Subject: [PATCH] Fixed panning for UWP/WinUI --- MapControl/Shared/MapImageLayer.cs | 16 +++------ MapControl/Shared/MapTileLayerBase.cs | 17 +++------- MapControl/UWP/MapControl.UWP.csproj | 3 ++ MapControl/WPF/Timer.WPF.cs | 40 ++++++++++++++++++++++ MapControl/WinUI/Map.WinUI.cs | 49 +++++++++++++++++++++++---- MapControl/WinUI/Timer.WinUI.cs | 33 ++++++++++++++++++ 6 files changed, 128 insertions(+), 30 deletions(-) create mode 100644 MapControl/WPF/Timer.WPF.cs create mode 100644 MapControl/WinUI/Timer.WinUI.cs diff --git a/MapControl/Shared/MapImageLayer.cs b/MapControl/Shared/MapImageLayer.cs index 3ae86bf9..c6d7230d 100644 --- a/MapControl/Shared/MapImageLayer.cs +++ b/MapControl/Shared/MapImageLayer.cs @@ -73,16 +73,13 @@ namespace MapControl #if WINUI private readonly DispatcherQueueTimer updateTimer; #else - private readonly DispatcherTimer updateTimer = new DispatcherTimer(); + private readonly DispatcherTimer updateTimer; #endif private bool updateInProgress; public MapImageLayer() { -#if WINUI - updateTimer = DispatcherQueue.CreateTimer(); -#endif - updateTimer.Interval = UpdateInterval; + updateTimer = this.CreateTimer(UpdateInterval); updateTimer.Tick += async (s, e) => await UpdateImageAsync(); } @@ -227,12 +224,7 @@ namespace MapControl base.OnViewportChanged(e); - if (!UpdateWhileViewportChanging) - { - updateTimer.Stop(); // restart - } - - updateTimer.Start(); + updateTimer.Run(!UpdateWhileViewportChanging); } } @@ -242,7 +234,7 @@ namespace MapControl if (updateInProgress) { - updateTimer.Start(); // update image on next timer tick + updateTimer.Run(); // update image on next timer tick } else if (ParentMap != null && ParentMap.RenderSize.Width > 0 && ParentMap.RenderSize.Height > 0) { diff --git a/MapControl/Shared/MapTileLayerBase.cs b/MapControl/Shared/MapTileLayerBase.cs index 71433113..2f42ac8e 100644 --- a/MapControl/Shared/MapTileLayerBase.cs +++ b/MapControl/Shared/MapTileLayerBase.cs @@ -61,7 +61,7 @@ namespace MapControl #if WINUI private readonly DispatcherQueueTimer updateTimer; #else - private readonly DispatcherTimer updateTimer = new DispatcherTimer(); + private readonly DispatcherTimer updateTimer; #endif private MapBase parentMap; @@ -69,10 +69,8 @@ namespace MapControl { RenderTransform = new MatrixTransform(); TileImageLoader = tileImageLoader; -#if WINUI - updateTimer = DispatcherQueue.CreateTimer(); -#endif - updateTimer.Interval = UpdateInterval; + + updateTimer = this.CreateTimer(UpdateInterval); updateTimer.Tick += async (s, e) => await Update(); #if WINUI || UWP @@ -172,7 +170,7 @@ namespace MapControl parentMap.ViewportChanged += OnViewportChanged; } - updateTimer.Start(); + updateTimer.Run(); } } @@ -207,12 +205,7 @@ namespace MapControl { SetRenderTransform(); - if (!UpdateWhileViewportChanging) - { - updateTimer.Stop(); // restart - } - - updateTimer.Start(); + updateTimer.Run(!UpdateWhileViewportChanging); } } } diff --git a/MapControl/UWP/MapControl.UWP.csproj b/MapControl/UWP/MapControl.UWP.csproj index c01b17d1..e386b499 100644 --- a/MapControl/UWP/MapControl.UWP.csproj +++ b/MapControl/UWP/MapControl.UWP.csproj @@ -227,6 +227,9 @@ Vector.WinUI.cs + + Timer.WPF.cs + diff --git a/MapControl/WPF/Timer.WPF.cs b/MapControl/WPF/Timer.WPF.cs new file mode 100644 index 00000000..e3d3f2a6 --- /dev/null +++ b/MapControl/WPF/Timer.WPF.cs @@ -0,0 +1,40 @@ +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2021 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +using System; +#if UWP +using Windows.UI.Xaml; +#else +using System.Windows; +using System.Windows.Threading; +#endif + +namespace MapControl +{ + internal static class Timer + { + public static DispatcherTimer CreateTimer(this DependencyObject obj, TimeSpan interval) + { + var timer = new DispatcherTimer + { + Interval = interval + }; + + return timer; + } + + public static void Run(this DispatcherTimer timer, bool restart = false) + { + if (restart) + { + timer.Stop(); + } + + if (!timer.IsEnabled) + { + timer.Start(); + } + } + } +} diff --git a/MapControl/WinUI/Map.WinUI.cs b/MapControl/WinUI/Map.WinUI.cs index cfefdcb5..ac3cfaed 100644 --- a/MapControl/WinUI/Map.WinUI.cs +++ b/MapControl/WinUI/Map.WinUI.cs @@ -21,6 +21,8 @@ namespace MapControl public static readonly DependencyProperty MouseWheelZoomDeltaProperty = DependencyProperty.Register( nameof(MouseWheelZoomDelta), typeof(double), typeof(Map), new PropertyMetadata(1d)); + private Point? mousePosition; + public Map() { ManipulationMode = ManipulationModes.Scale @@ -28,8 +30,11 @@ namespace MapControl | ManipulationModes.TranslateY | ManipulationModes.TranslateInertia; - ManipulationDelta += OnManipulationDelta; PointerWheelChanged += OnPointerWheelChanged; + PointerPressed += OnPointerPressed; + PointerReleased += OnPointerReleased; + PointerMoved += OnPointerMoved; + ManipulationDelta += OnManipulationDelta; } /// @@ -42,11 +47,6 @@ namespace MapControl set { SetValue(MouseWheelZoomDeltaProperty, value); } } - private void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) - { - TransformMap(e.Position, e.Delta.Translation, e.Delta.Rotation, e.Delta.Scale); - } - private void OnPointerWheelChanged(object sender, PointerRoutedEventArgs e) { var point = e.GetCurrentPoint(this); @@ -54,5 +54,42 @@ namespace MapControl ZoomMap(point.Position, MouseWheelZoomDelta * Math.Round(zoomLevel / MouseWheelZoomDelta)); } + + private void OnPointerPressed(object sender, PointerRoutedEventArgs e) + { + if (CapturePointer(e.Pointer)) + { + mousePosition = e.GetCurrentPoint(this).Position; + } + } + + private void OnPointerReleased(object sender, PointerRoutedEventArgs e) + { + if (mousePosition.HasValue) + { + mousePosition = null; + ReleasePointerCaptures(); + } + } + + private void OnPointerMoved(object sender, PointerRoutedEventArgs e) + { + if (mousePosition.HasValue) + { + Point position = e.GetCurrentPoint(this).Position; + var translation = position - mousePosition.Value; + mousePosition = position; + + TranslateMap(translation); + } + } + + private void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) + { + if (!mousePosition.HasValue) + { + TransformMap(e.Position, e.Delta.Translation, e.Delta.Rotation, e.Delta.Scale); + } + } } } diff --git a/MapControl/WinUI/Timer.WinUI.cs b/MapControl/WinUI/Timer.WinUI.cs new file mode 100644 index 00000000..e4cfbcca --- /dev/null +++ b/MapControl/WinUI/Timer.WinUI.cs @@ -0,0 +1,33 @@ +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2021 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +using Microsoft.UI.Dispatching; +using Microsoft.UI.Xaml; +using System; + +namespace MapControl +{ + internal static class Timer + { + public static DispatcherQueueTimer CreateTimer(this DependencyObject obj, TimeSpan interval) + { + var timer = obj.DispatcherQueue.CreateTimer(); + timer.Interval = interval; + return timer; + } + + public static void Run(this DispatcherQueueTimer timer, bool restart = false) + { + if (restart) + { + timer.Stop(); + } + + if (!timer.IsRunning) + { + timer.Start(); + } + } + } +}