Track tap gestures
This commit is contained in:
parent
0b60b4c800
commit
88a4798acb
|
@ -0,0 +1,169 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
using NativeView = Ooui.Element;
|
||||||
|
|
||||||
|
namespace Ooui.Forms
|
||||||
|
{
|
||||||
|
public class EventTracker
|
||||||
|
{
|
||||||
|
readonly NotifyCollectionChangedEventHandler _collectionChangedHandler;
|
||||||
|
|
||||||
|
readonly Dictionary<IGestureRecognizer, NativeGestureRecognizer> _gestureRecognizers = new Dictionary<IGestureRecognizer, NativeGestureRecognizer> ();
|
||||||
|
|
||||||
|
readonly IVisualElementRenderer _renderer;
|
||||||
|
bool _disposed;
|
||||||
|
NativeView _handler;
|
||||||
|
|
||||||
|
public EventTracker (IVisualElementRenderer renderer)
|
||||||
|
{
|
||||||
|
if (renderer == null)
|
||||||
|
throw new ArgumentNullException (nameof (renderer));
|
||||||
|
|
||||||
|
_collectionChangedHandler = ModelGestureRecognizersOnCollectionChanged;
|
||||||
|
|
||||||
|
_renderer = renderer;
|
||||||
|
_renderer.ElementChanged += OnElementChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObservableCollection<IGestureRecognizer> ElementGestureRecognizers {
|
||||||
|
get {
|
||||||
|
if (_renderer?.Element is View)
|
||||||
|
return ((View)_renderer.Element).GestureRecognizers as ObservableCollection<IGestureRecognizer>;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_disposed = true;
|
||||||
|
|
||||||
|
foreach (var kvp in _gestureRecognizers) {
|
||||||
|
RemoveGestureRecognizer (_handler, kvp.Value);
|
||||||
|
kvp.Value.Dispose ();
|
||||||
|
}
|
||||||
|
|
||||||
|
_gestureRecognizers.Clear ();
|
||||||
|
|
||||||
|
if (ElementGestureRecognizers != null)
|
||||||
|
ElementGestureRecognizers.CollectionChanged -= _collectionChangedHandler;
|
||||||
|
|
||||||
|
_handler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelGestureRecognizersOnCollectionChanged (object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
|
||||||
|
{
|
||||||
|
LoadRecognizers ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnElementChanged (object sender, VisualElementChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.OldElement != null) {
|
||||||
|
// unhook
|
||||||
|
var oldView = e.OldElement as View;
|
||||||
|
if (oldView != null) {
|
||||||
|
var oldRecognizers = (ObservableCollection<IGestureRecognizer>)oldView.GestureRecognizers;
|
||||||
|
oldRecognizers.CollectionChanged -= _collectionChangedHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.NewElement != null) {
|
||||||
|
// hook
|
||||||
|
if (ElementGestureRecognizers != null) {
|
||||||
|
ElementGestureRecognizers.CollectionChanged += _collectionChangedHandler;
|
||||||
|
LoadRecognizers ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadRecognizers ()
|
||||||
|
{
|
||||||
|
if (ElementGestureRecognizers == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var recognizer in ElementGestureRecognizers) {
|
||||||
|
if (_gestureRecognizers.ContainsKey (recognizer))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var nativeRecognizer = GetNativeRecognizer (recognizer);
|
||||||
|
if (nativeRecognizer != null) {
|
||||||
|
AddGestureRecognizer (_handler, nativeRecognizer);
|
||||||
|
|
||||||
|
_gestureRecognizers[recognizer] = nativeRecognizer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var toRemove = _gestureRecognizers.Keys.Where (key => !ElementGestureRecognizers.Contains (key)).ToArray ();
|
||||||
|
foreach (var gestureRecognizer in toRemove) {
|
||||||
|
var uiRecognizer = _gestureRecognizers[gestureRecognizer];
|
||||||
|
_gestureRecognizers.Remove (gestureRecognizer);
|
||||||
|
|
||||||
|
RemoveGestureRecognizer (_handler, uiRecognizer);
|
||||||
|
uiRecognizer.Dispose ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual NativeGestureRecognizer GetNativeRecognizer (IGestureRecognizer recognizer)
|
||||||
|
{
|
||||||
|
if (recognizer == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var weakRecognizer = new WeakReference (recognizer);
|
||||||
|
var weakEventTracker = new WeakReference (this);
|
||||||
|
|
||||||
|
var tapRecognizer = recognizer as TapGestureRecognizer;
|
||||||
|
if (tapRecognizer != null) {
|
||||||
|
var returnAction = new TargetEventHandler ((s, e) => {
|
||||||
|
var tapGestureRecognizer = weakRecognizer.Target as TapGestureRecognizer;
|
||||||
|
var eventTracker = weakEventTracker.Target as EventTracker;
|
||||||
|
var view = eventTracker?._renderer?.Element as View;
|
||||||
|
|
||||||
|
if (tapGestureRecognizer != null && view != null)
|
||||||
|
tapGestureRecognizer.SendTapped (view);
|
||||||
|
});
|
||||||
|
var uiRecognizer = new NativeGestureRecognizer {
|
||||||
|
EventType = "click",
|
||||||
|
Handler = returnAction,
|
||||||
|
};
|
||||||
|
return uiRecognizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddGestureRecognizer (Element element, NativeGestureRecognizer recognizer)
|
||||||
|
{
|
||||||
|
element.AddEventListener (recognizer.EventType, recognizer.Handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RemoveGestureRecognizer (Element element, NativeGestureRecognizer recognizer)
|
||||||
|
{
|
||||||
|
element.RemoveEventListener (recognizer.EventType, recognizer.Handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadEvents (NativeView handler)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException (null);
|
||||||
|
|
||||||
|
_handler = handler;
|
||||||
|
OnElementChanged (this, new VisualElementChangedEventArgs (null, _renderer.Element));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class NativeGestureRecognizer : IDisposable
|
||||||
|
{
|
||||||
|
public string EventType;
|
||||||
|
public TargetEventHandler Handler;
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,6 +57,10 @@ namespace Ooui.Forms
|
||||||
MessagingCenter.Unsubscribe<Page, ActionSheetArguments> (this, Page.ActionSheetSignalName);
|
MessagingCenter.Unsubscribe<Page, ActionSheetArguments> (this, Page.ActionSheetSignalName);
|
||||||
MessagingCenter.Unsubscribe<Page, AlertArguments> (this, Page.AlertSignalName);
|
MessagingCenter.Unsubscribe<Page, AlertArguments> (this, Page.AlertSignalName);
|
||||||
MessagingCenter.Unsubscribe<Page, bool> (this, Page.BusySetSignalName);
|
MessagingCenter.Unsubscribe<Page, bool> (this, Page.BusySetSignalName);
|
||||||
|
|
||||||
|
DisposeModelAndChildrenRenderers (Page);
|
||||||
|
//foreach (var modal in _modals)
|
||||||
|
//DisposeModelAndChildrenRenderers (modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IVisualElementRenderer CreateRenderer (VisualElement element)
|
public static IVisualElementRenderer CreateRenderer (VisualElement element)
|
||||||
|
@ -110,7 +114,29 @@ namespace Ooui.Forms
|
||||||
|
|
||||||
void HandleChildRemoved (object sender, ElementEventArgs e)
|
void HandleChildRemoved (object sender, ElementEventArgs e)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException ();
|
var view = e.Element;
|
||||||
|
DisposeModelAndChildrenRenderers (view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisposeModelAndChildrenRenderers (Xamarin.Forms.Element view)
|
||||||
|
{
|
||||||
|
IVisualElementRenderer renderer;
|
||||||
|
foreach (VisualElement child in view.Descendants ()) {
|
||||||
|
renderer = GetRenderer (child);
|
||||||
|
child.ClearValue (RendererProperty);
|
||||||
|
|
||||||
|
if (renderer != null) {
|
||||||
|
//renderer.NativeView.RemoveFromSuperview ();
|
||||||
|
renderer.Dispose ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer = GetRenderer ((VisualElement)view);
|
||||||
|
if (renderer != null) {
|
||||||
|
//renderer.NativeView.RemoveFromSuperview ();
|
||||||
|
renderer.Dispose ();
|
||||||
|
}
|
||||||
|
view.ClearValue (RendererProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddChild (VisualElement view)
|
void AddChild (VisualElement view)
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace Ooui.Forms
|
||||||
|
|
||||||
VisualElementRendererFlags _flags = VisualElementRendererFlags.AutoPackage | VisualElementRendererFlags.AutoTrack;
|
VisualElementRendererFlags _flags = VisualElementRendererFlags.AutoPackage | VisualElementRendererFlags.AutoTrack;
|
||||||
|
|
||||||
|
EventTracker _events;
|
||||||
VisualElementPackager _packager;
|
VisualElementPackager _packager;
|
||||||
VisualElementTracker _tracker;
|
VisualElementTracker _tracker;
|
||||||
|
|
||||||
|
@ -107,10 +108,10 @@ namespace Ooui.Forms
|
||||||
_packager.Load ();
|
_packager.Load ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (AutoTrack && _events == null) {
|
if (AutoTrack && _events == null) {
|
||||||
// _events = new EventTracker (this);
|
_events = new EventTracker (this);
|
||||||
// _events.LoadEvents (this);
|
_events.LoadEvents (this);
|
||||||
//}
|
}
|
||||||
|
|
||||||
element.PropertyChanged += _propertyChangedHandler;
|
element.PropertyChanged += _propertyChangedHandler;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue