Skip to content
This repository has been archived by the owner on Nov 12, 2020. It is now read-only.

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaseFlorell committed Dec 30, 2017
2 parents c172a82 + 4938c89 commit 2abcf0b
Show file tree
Hide file tree
Showing 16 changed files with 927 additions and 53 deletions.
13 changes: 8 additions & 5 deletions example/Xfx.Controls.Example/MainPage.xaml
Expand Up @@ -19,9 +19,9 @@
HeightRequest="150"
HorizontalOptions="Fill"
Aspect="Fill" />
<Label Margin="8">
<Label Margin="10">
<Label.Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse fringilla turpis turpis, id lobortis dolor vestibulum condimentum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse fringilla turpis turpis, id lobortis dolor vestibulum condimentum.
</Label.Text>
</Label>
<Button Text="Go to Main Page" Clicked="Button_OnClicked" Margin="8" />
Expand All @@ -34,13 +34,16 @@
HeightRequest="150"
HorizontalOptions="Fill"
Aspect="Fill" />
<Label Margin="8">
<Label Margin="10">
<Label.Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse fringilla turpis turpis, id lobortis dolor vestibulum condimentum.
Tap this card to navigate to the next page
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse fringilla turpis turpis, id lobortis dolor vestibulum condimentum.
</Label.Text>
</Label>
<Button Text="Go to Main Page" Clicked="Button_OnClicked" Margin="8" />
</StackLayout>
<xfx:XfxCardView.GestureRecognizers>
<TapGestureRecognizer Tapped="Button_OnClicked"/>
</xfx:XfxCardView.GestureRecognizers>
</xfx:XfxCardView>
</StackLayout>
</ScrollView>
Expand Down
177 changes: 177 additions & 0 deletions src/Xfx.Controls.Droid/Forms.Internals/GestureManager.cs
@@ -0,0 +1,177 @@
using System;
using System.ComponentModel;
using System.Linq;
using Android.Support.V4.View;
using Android.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using View = Xamarin.Forms.View;

namespace Xfx.Controls.Droid.Forms.Internals
{
internal class GestureManager : IDisposable
{
IVisualElementRenderer _renderer;
readonly Lazy<GestureDetector> _tapAndPanDetector;
readonly Lazy<ScaleGestureDetector> _scaleDetector;

bool _disposed;
bool _inputTransparent;
bool _isEnabled;

VisualElement Element => _renderer?.Element;

View View => _renderer?.Element as View;

global::Android.Views.View Control => _renderer?.View;

public GestureManager(IVisualElementRenderer renderer)
{
_renderer = renderer;
_renderer.ElementChanged += OnElementChanged;

_tapAndPanDetector = new Lazy<GestureDetector>(InitializeTapAndPanDetector);
_scaleDetector = new Lazy<ScaleGestureDetector>(InitializeScaleDetector);
}

public bool OnTouchEvent(MotionEvent e)
{
if (Control == null)
{
return false;
}

if (!_isEnabled || _inputTransparent)
{
return false;
}

if (!DetectorsValid())
{
return false;
}

var eventConsumed = false;
if (ViewHasPinchGestures())
{
eventConsumed = _scaleDetector.Value.OnTouchEvent(e);
}

eventConsumed = _tapAndPanDetector.Value.OnTouchEvent(e) || eventConsumed;

return eventConsumed;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

bool DetectorsValid()
{
// Make sure we're not testing for gestures on old motion events after our
// detectors have already been disposed

if (_scaleDetector.IsValueCreated && _scaleDetector.Value.Handle == IntPtr.Zero)
{
return false;
}

if (_tapAndPanDetector.IsValueCreated && _tapAndPanDetector.Value.Handle == IntPtr.Zero)
{
return false;
}

return true;
}

GestureDetector InitializeTapAndPanDetector()
{
var context = Control.Context;
var listener = new InnerGestureListener(new TapGestureHandler(() => View),
new PanGestureHandler(() => View, context.FromPixels));

return new GestureDetector(context, listener);
}

ScaleGestureDetector InitializeScaleDetector()
{
var context = Control.Context;
var listener = new InnerScaleListener(new PinchGestureHandler(() => View), context.FromPixels);
var detector = new ScaleGestureDetector(context, listener, Control.Handler);
ScaleGestureDetectorCompat.SetQuickScaleEnabled(detector, true);

return detector;
}

bool ViewHasPinchGestures()
{
return View != null && View.GestureRecognizers.OfType<PinchGestureRecognizer>().Any();
}

void OnElementChanged(object sender, VisualElementChangedEventArgs e)
{
if (e.OldElement != null)
{
e.OldElement.PropertyChanged -= OnElementPropertyChanged;
}

if (e.NewElement != null)
{
e.NewElement.PropertyChanged += OnElementPropertyChanged;
}

UpdateInputTransparent();
UpdateIsEnabled();
}

void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == VisualElement.InputTransparentProperty.PropertyName)
UpdateInputTransparent();
else if (e.PropertyName == VisualElement.IsEnabledProperty.PropertyName)
UpdateIsEnabled();
}

protected void Dispose(bool disposing)
{
if (_disposed)
{
return;
}

_disposed = true;

if (disposing)
{
if (Element != null)
{
Element.PropertyChanged -= OnElementPropertyChanged;
}

_renderer = null;
}
}

void UpdateInputTransparent()
{
if (Element == null)
{
return;
}

_inputTransparent = Element.InputTransparent;
}

void UpdateIsEnabled()
{
if (Element == null)
{
return;
}

_isEnabled = Element.IsEnabled;
}
}
}

0 comments on commit 2abcf0b

Please sign in to comment.