summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Tizen/GestureHandler.cs
diff options
context:
space:
mode:
authorSungHyun Min <shyun.min@samsung.com>2017-02-22 19:49:54 +0900
committerKangho Hur <kangho.hur@samsung.com>2017-10-23 13:34:30 +0900
commita6a7459ebdac9a907928675b2a80ec33202fba5a (patch)
tree377572ffcc2a754dd38aa730f75569c0c0509cab /Xamarin.Forms.Platform.Tizen/GestureHandler.cs
parent884625d1be0e04f16bad7c8b776a1d1066cf31f2 (diff)
downloadxamarin-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.cs293
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