summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla57515.cs
diff options
context:
space:
mode:
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.cs147
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