diff options
author | SungHyun Min <shyun.min@samsung.com> | 2017-02-22 19:49:54 +0900 |
---|---|---|
committer | Kangho Hur <kangho.hur@samsung.com> | 2017-10-23 13:34:30 +0900 |
commit | a6a7459ebdac9a907928675b2a80ec33202fba5a (patch) | |
tree | 377572ffcc2a754dd38aa730f75569c0c0509cab /Xamarin.Forms.Platform.Tizen/GestureHandler.cs | |
parent | 884625d1be0e04f16bad7c8b776a1d1066cf31f2 (diff) | |
download | xamarin-forms-a6a7459ebdac9a907928675b2a80ec33202fba5a.tar.gz xamarin-forms-a6a7459ebdac9a907928675b2a80ec33202fba5a.tar.bz2 xamarin-forms-a6a7459ebdac9a907928675b2a80ec33202fba5a.zip |
Refactoring GestureHandler for extension
- Design : http://suprem.sec.samsung.net/confluence/display/SPTDTLC/Refactoring+GestureHandler
Change-Id: I1cbcf830b4b1076c227b0ea641508198c7cb2102
Signed-off-by: SungHyun Min <shyun.min@samsung.com>
Diffstat (limited to 'Xamarin.Forms.Platform.Tizen/GestureHandler.cs')
-rw-r--r-- | Xamarin.Forms.Platform.Tizen/GestureHandler.cs | 293 |
1 files changed, 22 insertions, 271 deletions
diff --git a/Xamarin.Forms.Platform.Tizen/GestureHandler.cs b/Xamarin.Forms.Platform.Tizen/GestureHandler.cs index 209da3e3..0d1bb93d 100644 --- a/Xamarin.Forms.Platform.Tizen/GestureHandler.cs +++ b/Xamarin.Forms.Platform.Tizen/GestureHandler.cs @@ -1,299 +1,50 @@ -using System.Linq; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.Collections.Generic; +using System; +using System.ComponentModel; using ElmSharp; -using EColor = ElmSharp.Color; namespace Xamarin.Forms.Platform.Tizen { - internal class GestureHandler + public abstract class GestureHandler : IGestureController, INotifyPropertyChanged, IRegisterable { - internal readonly IVisualElementRenderer _renderer; - internal GestureLayer _gestureLayer; - View _view => _renderer.Element as View; - IPanGestureController _currentPanGestureController; - int _currentPanGestureId; - IPinchGestureController _currentPinchGestureController; - Point _currentScalePoint; - int _previousPinchRadius; - double _originalPinchScale; - Polygon _hitBox; + public IGestureRecognizer Recognizer { get; private set; } - public GestureHandler(IVisualElementRenderer renderer) - { - _renderer = renderer; - // Whenever a GestureRecognizer is added to the View, it will be connected to GestureLayer - (_view.GestureRecognizers as ObservableCollection<IGestureRecognizer>).CollectionChanged += OnGestureRecognizersChanged; - // handle GestureRecognizers which were already set by the time we got here - if (_view.GestureRecognizers.Count > 0) - { - CreateGestureLayer(); - foreach (var item in _view.GestureRecognizers) - ToggleRecognizer(item, true); - } - } - - public void Clear() - { - // this will clear all callbacks in ElmSharp GestureLayer - _gestureLayer.Unrealize(); - (_view.GestureRecognizers as ObservableCollection<IGestureRecognizer>).CollectionChanged -= OnGestureRecognizersChanged; - if (_hitBox != null) - { - _hitBox.Unrealize(); - _hitBox = null; - } - } - - public void UpdateHitBox() - { - if (_hitBox == null) - return; - // _hitBox has to be used because gestures do not work well with transformations (EvasMap) - // so we create additional object which has the same shape as tranformed target, but does not have EvasMap on it - EvasObject target = _renderer.NativeView; - _hitBox.ClearPoints(); - if (target.IsMapEnabled) - { - var map = target.EvasMap; - Point3D point; - for (var i = 0; i < 4; i++) - { - point = map.GetPointCoordinate(i); - _hitBox.AddPoint(point.X, point.Y); - } - } - else - { - var geometry = target.Geometry; - if (geometry.Width == 0 || geometry.Height == 0) - return; - _hitBox.AddPoint(geometry.Left, geometry.Top); - _hitBox.AddPoint(geometry.Right, geometry.Top); - _hitBox.AddPoint(geometry.Right, geometry.Bottom); - _hitBox.AddPoint(geometry.Left, geometry.Bottom); - } - } - - protected void ToggleRecognizer(IGestureRecognizer recognizer, bool enable) - { - TapGestureRecognizer tapRecognizer; - PanGestureRecognizer panRecognizer; - PinchGestureRecognizer pinchRecognizer; - - if ((tapRecognizer = recognizer as TapGestureRecognizer) != null) - { - ToggleTapRecognizer(tapRecognizer, enable); - } - else if ((panRecognizer = recognizer as PanGestureRecognizer) != null) - { - if (enable) - AddPanRecognizer(panRecognizer); - else - RemovePanRecognizer(panRecognizer); - } - else if ((pinchRecognizer = recognizer as PinchGestureRecognizer) != null) - { - if (enable) - AddPinchRecognizer(pinchRecognizer); - else - RemovePinchRecognizer(pinchRecognizer); - } - else - { - Log.Error("Unknown GestureRecognizer will be ignored: {0}", recognizer); - } - } - - void ToggleTapRecognizer(TapGestureRecognizer recognizer, bool enable) - { - GestureLayer.GestureType type; - switch (recognizer.NumberOfTapsRequired) - { - case 1: - type = GestureLayer.GestureType.Tap; - break; - case 2: - type = GestureLayer.GestureType.DoubleTap; - break; - default: - type = GestureLayer.GestureType.TripleTap; - break; - } - if (enable) - _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.End, (data) => recognizer.SendTapped(_view)); - else - _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.End, null); - } - - void AddPanRecognizer(PanGestureRecognizer recognizer) - { - if (_currentPanGestureController != null) - Log.Warn("More than one PanGestureRecognizer on {0}. Only the last one will work.", _view); - EnsureHitBoxExists(); - _currentPanGestureController = recognizer; - _gestureLayer.SetLineCallback(GestureLayer.GestureState.Start, OnPanStarted); - _gestureLayer.SetLineCallback(GestureLayer.GestureState.Move, OnPanMoved); - _gestureLayer.SetLineCallback(GestureLayer.GestureState.End, OnPanCompleted); - _gestureLayer.SetLineCallback(GestureLayer.GestureState.Abort, OnPanCancelled); - } - - void RemovePanRecognizer(PanGestureRecognizer recognizer) - { - _gestureLayer.SetLineCallback(GestureLayer.GestureState.Start, null); - _gestureLayer.SetLineCallback(GestureLayer.GestureState.Move, null); - _gestureLayer.SetLineCallback(GestureLayer.GestureState.End, null); - _gestureLayer.SetLineCallback(GestureLayer.GestureState.Abort, null); - _currentPanGestureController = null; - } - - void AddPinchRecognizer(PinchGestureRecognizer recognizer) - { - if (_currentPinchGestureController != null) - Log.Warn("More than one PinchGestureRecognizer on {0}. Only the last one will work.", _view); - EnsureHitBoxExists(); - _currentPinchGestureController = recognizer; - _gestureLayer.SetZoomCallback(GestureLayer.GestureState.Start, OnPinchStarted); - _gestureLayer.SetZoomCallback(GestureLayer.GestureState.Move, OnPinchMoved); - _gestureLayer.SetZoomCallback(GestureLayer.GestureState.End, OnPinchCompleted); - _gestureLayer.SetZoomCallback(GestureLayer.GestureState.Abort, OnPinchCancelled); - } - - void RemovePinchRecognizer(PinchGestureRecognizer recognizer) - { - _gestureLayer.SetZoomCallback(GestureLayer.GestureState.Start, null); - _gestureLayer.SetZoomCallback(GestureLayer.GestureState.Move, null); - _gestureLayer.SetZoomCallback(GestureLayer.GestureState.End, null); - _gestureLayer.SetZoomCallback(GestureLayer.GestureState.Abort, null); - _currentPinchGestureController = null; - } - - void CreateGestureLayer() - { - _gestureLayer = new GestureLayer(_renderer.NativeView); - _gestureLayer.Attach(_renderer.NativeView); - } + public abstract GestureLayer.GestureType Type { get; } - void EnsureHitBoxExists() - { - if (_hitBox == null) - { - Box parent = (Platform.GetRenderer(_renderer.Element.RealParent) as LayoutRenderer).Control; - _hitBox = new Polygon(parent) - { - Color = EColor.Transparent - }; - _hitBox.Show(); - UpdateHitBox(); - parent.PackAfter(_hitBox, _renderer.NativeView); - _gestureLayer.Attach(_hitBox); - } - } + public virtual double Timeout { get; } - void AddAndRemoveRecognizers(IEnumerable<IGestureRecognizer> removed, IEnumerable<IGestureRecognizer> added) + protected GestureHandler(IGestureRecognizer recognizer) { - if (_hitBox == null && - added != null && - added.Any(item => (item is IPanGestureController || item is IPinchGestureController))) - { - // at least one of the added recognizers requires _hitBot, which is not ready - _gestureLayer.ClearCallbacks(); - EnsureHitBoxExists(); - // as _gestureLayer was reattached, register all callbacks, not only new ones - removed = null; - added = _view.GestureRecognizers; - } - - if (removed != null) - { - foreach (var item in removed) - ToggleRecognizer(item, false); - } - if (added != null) - { - foreach (var item in added) - ToggleRecognizer(item, true); - } + Recognizer = recognizer; } - void OnGestureRecognizersChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) - { - // Gestures will be registered/unregistered according to changes in the GestureRecognizers list - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - if (_gestureLayer == null) - CreateGestureLayer(); - AddAndRemoveRecognizers(null, e.NewItems.OfType<IGestureRecognizer>()); - break; + public virtual event PropertyChangedEventHandler PropertyChanged; - case NotifyCollectionChangedAction.Replace: - AddAndRemoveRecognizers(e.OldItems.OfType<IGestureRecognizer>(), e.NewItems.OfType<IGestureRecognizer>()); - break; + protected abstract void OnStarted(View sender, object data); - case NotifyCollectionChangedAction.Remove: - AddAndRemoveRecognizers(e.OldItems.OfType<IGestureRecognizer>(), null); - break; + protected abstract void OnMoved(View sender, object data); - case NotifyCollectionChangedAction.Reset: - AddAndRemoveRecognizers(_view.GestureRecognizers, null); - break; - } - } + protected abstract void OnCompleted(View sender, object data); - void OnPanStarted(GestureLayer.LineData data) - { - _currentPanGestureId++; - _currentPanGestureController.SendPanStarted(_view, _currentPanGestureId); - } - - void OnPanMoved(GestureLayer.LineData data) - { - _currentPanGestureController.SendPan(_view, data.X2 - data.X1, data.Y2 - data.Y1, _currentPanGestureId); - } - - void OnPanCompleted(GestureLayer.LineData data) - { - _currentPanGestureController.SendPanCompleted(_view, _currentPanGestureId); - } - - void OnPanCancelled(GestureLayer.LineData data) - { - // don't trust ElmSharp that the gesture has been aborted, report that it is completed - _currentPanGestureController.SendPanCompleted(_view, _currentPanGestureId); - } + protected abstract void OnCanceled(View sender, object data); - void OnPinchStarted(GestureLayer.ZoomData data) + void IGestureController.SendStarted(View sender, object data) { - var geometry = _renderer.NativeView.Geometry; - _currentScalePoint = new Point((data.X - geometry.X) / (double)geometry.Width, (data.Y - geometry.Y) / (double)geometry.Height); - _originalPinchScale = _view.Scale; - _previousPinchRadius = data.Radius; - _currentPinchGestureController.SendPinchStarted(_view, _currentScalePoint); + OnStarted(sender, data); } - void OnPinchMoved(GestureLayer.ZoomData data) + void IGestureController.SendCompleted(View sender, object data) { - if (_previousPinchRadius <= 0) - _previousPinchRadius = 1; - // functionality limitation: _currentScalePoint is not updated - _currentPinchGestureController.SendPinch(_view, - 1 + _originalPinchScale * (data.Radius - _previousPinchRadius) / _previousPinchRadius, - _currentScalePoint - ); - _previousPinchRadius = data.Radius; + OnCompleted(sender, data); } - void OnPinchCompleted(GestureLayer.ZoomData data) + void IGestureController.SendMoved(View sender, object data) { - _currentPinchGestureController.SendPinchEnded(_view); + OnMoved(sender, data); } - void OnPinchCancelled(GestureLayer.ZoomData data) + void IGestureController.SendCanceled(View sender, object data) { - // ElmSharp says the gesture has been aborted really too often, report completion instead - _currentPinchGestureController.SendPinchEnded(_view); + OnCanceled(sender, data); } } -} +}
\ No newline at end of file |