diff options
Diffstat (limited to 'Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla57515.cs')
-rw-r--r-- | Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla57515.cs | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla57515.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla57515.cs new file mode 100644 index 00000000..b9f3c3ef --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla57515.cs @@ -0,0 +1,147 @@ +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; +using System; +#if UITEST +using Xamarin.UITest; +using Xamarin.Forms.Core.UITests; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ +#if UITEST + [Category(UITestCategories.Gestures)] +#endif + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 57515, "PinchGestureRecognizer not getting called on Android ", PlatformAffected.Android)] + public class Bugzilla57515 : TestContentPage + { + const string ZoomImage = "zoomImg"; + const string ZoomContainer = "zoomContainer"; + + protected override void Init() + { + var layout = new Grid + { + RowDefinitions = new RowDefinitionCollection + { + new RowDefinition { Height = 80 }, + new RowDefinition { Height = GridLength.Star } + } + }; + + var scaleLabel = new Label(); + layout.Children.Add(scaleLabel); + + var pinchToZoomContainer = new PinchToZoomContainer + { + Margin = new Thickness(80), + AutomationId = ZoomContainer, + Content = new Image + { + AutomationId = ZoomImage, + Source = ImageSource.FromFile("oasis.jpg") + } + }; + + Grid.SetRow(pinchToZoomContainer, 1); + layout.Children.Add(pinchToZoomContainer); + + scaleLabel.BindingContext = pinchToZoomContainer; + scaleLabel.SetBinding(Label.TextProperty, new Binding("CurrentScale")); + + Content = layout; + } + + class PinchToZoomContainer : ContentView + { + public static readonly BindableProperty CurrentScaleProperty = + BindableProperty.Create("CurrentScale", typeof(double), typeof(PinchToZoomContainer), 1.0); + + public double CurrentScale + { + get { return (double)GetValue(CurrentScaleProperty); } + set { SetValue(CurrentScaleProperty, value); } + } + + double startScale = 1; + double xOffset = 0; + double yOffset = 0; + + public PinchToZoomContainer() + { + var pinchGesture = new PinchGestureRecognizer(); + pinchGesture.PinchUpdated += OnPinchUpdated; + GestureRecognizers.Add(pinchGesture); + } + + void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e) + { + if (e.Status == GestureStatus.Started) + { + // Store the current scale factor applied to the wrapped user interface element, + // and zero the components for the center point of the translate transform. + startScale = Content.Scale; + Content.AnchorX = 0; + Content.AnchorY = 0; + } + if (e.Status == GestureStatus.Running) + { + // Calculate the scale factor to be applied. + CurrentScale += (e.Scale - 1) * startScale; + CurrentScale = Math.Max(1, CurrentScale); + + // The ScaleOrigin is in relative coordinates to the wrapped user interface element, + // so get the X pixel coordinate. + double renderedX = Content.X + xOffset; + double deltaX = renderedX / Width; + double deltaWidth = Width / (Content.Width * startScale); + double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth; + + // The ScaleOrigin is in relative coordinates to the wrapped user interface element, + // so get the Y pixel coordinate. + double renderedY = Content.Y + yOffset; + double deltaY = renderedY / Height; + double deltaHeight = Height / (Content.Height * startScale); + double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight; + + // Calculate the transformed element pixel coordinates. + double targetX = xOffset - (originX * Content.Width) * (CurrentScale - startScale); + double targetY = yOffset - (originY * Content.Height) * (CurrentScale - startScale); + + // Apply translation based on the change in origin. + Content.TranslationX = targetX.Clamp(-Content.Width * (CurrentScale - 1), 0); + Content.TranslationY = targetY.Clamp(-Content.Height * (CurrentScale - 1), 0); + + // Apply scale factor + Content.Scale = CurrentScale; + } + if (e.Status == GestureStatus.Completed) + { + // Store the translation delta's of the wrapped user interface element. + xOffset = Content.TranslationX; + yOffset = Content.TranslationY; + } + } + } + +#if UITEST + [Test] + public void Bugzilla57515Test() + { + RunningApp.WaitForElement(ZoomContainer); + RunningApp.WaitForElement("1"); + RunningApp.PinchToZoomIn(ZoomContainer); + RunningApp.WaitForNoElement("1"); // The scale should have changed during the zoom + } +#endif + } + + public static class DoubleExtensions + { + public static double Clamp(this double self, double min, double max) + { + return Math.Min(max, Math.Max(self, min)); + } + } +}
\ No newline at end of file |