зеркало из https://github.com/DeGsoft/maui-linux.git
147 строки
4.3 KiB
C#
147 строки
4.3 KiB
C#
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));
|
|
}
|
|
}
|
|
} |