2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.Runtime.InteropServices;
19 using System.Collections.Generic;
24 /// The GestureLayer is used to detect gestures.
27 /// <since_tizen> preview </since_tizen>
28 public class GestureLayer : Widget
30 private readonly Interop.Elementary.GestureEventCallback _gestureCallback;
32 // Important: don't remove items from _handlers list
33 // The list can grow up to (number of GestureType) * (number of GestureState)
34 // but all gestures share the callback and you don't want to desynchronize mapping
35 private readonly List<NativeCallback> _handlers = new List<NativeCallback>();
38 /// Creates and initializes a new instance of the GestureLayer class.
40 /// <param name="parent">The parent is a given container which will be attached by the GestureLayer as a child. It's the <see cref="EvasObject"/> type.</param>
41 /// <since_tizen> preview </since_tizen>
42 public GestureLayer(EvasObject parent) : base(parent)
44 _gestureCallback = new Interop.Elementary.GestureEventCallback(GestureCallbackHandler);
48 /// Enumeration for the supported gesture types.
50 /// <since_tizen> preview </since_tizen>
51 public enum GestureType
54 /// N fingers single taps.
59 /// N fingers single long-taps.
64 /// N fingers double-single taps.
69 /// N fingers triple-single taps.
74 /// Reports momentum in the direction of the move.
79 /// N fingers line gesture.
84 /// N fingers flick gesture.
100 /// Enumeration for the gesture states.
102 /// <since_tizen> preview </since_tizen>
103 public enum GestureState
106 /// Gesture not started.
116 /// Gesture is ongoing.
121 /// Gesture completed.
126 /// Ongoing gesture is aborted.
134 /// Sets or gets the repeat-events setting.
136 /// <since_tizen> preview </since_tizen>
137 public bool HoldEvents
141 return Interop.Elementary.elm_gesture_layer_hold_events_get(Handle);
145 Interop.Elementary.elm_gesture_layer_hold_events_set(Handle, value);
150 /// Sets or gets the gesture layer to continue enable of an object.
152 /// <since_tizen> preview </since_tizen>
153 public bool Continues
157 return Interop.Elementary.elm_gesture_layer_continues_enable_get(Handle);
161 Interop.Elementary.elm_gesture_layer_continues_enable_set(Handle, value);
166 /// Sets or gets the gesture layer finger-size for taps.
168 /// <since_tizen> preview </since_tizen>
169 public int TapFingerSize
173 return Interop.Elementary.elm_gesture_layer_tap_finger_size_get(Handle);
177 Interop.Elementary.elm_gesture_layer_tap_finger_size_set(Handle, value);
182 /// Sets or gets the gesture layer long tap start timeout of an object.
184 /// <since_tizen> preview </since_tizen>
185 public double LongTapTimeout
189 return Interop.Elementary.elm_gesture_layer_long_tap_start_timeout_get(Handle);
193 Interop.Elementary.elm_gesture_layer_long_tap_start_timeout_set(Handle, value);
198 /// Sets or gets the gesture layer double tap timeout of an object.
200 /// <since_tizen> preview </since_tizen>
201 public double DoubleTapTimeout
205 return Interop.Elementary.elm_gesture_layer_double_tap_timeout_get(Handle);
209 Interop.Elementary.elm_gesture_layer_double_tap_timeout_set(Handle, value);
214 /// Sets or gets the gesture layer flick time limit (in ms) of an object.
216 /// <since_tizen> preview </since_tizen>
217 public int FlickTimeLimit
221 return (int)Interop.Elementary.elm_gesture_layer_flick_time_limit_ms_get(Handle);
225 Interop.Elementary.elm_gesture_layer_flick_time_limit_ms_set(Handle, (UInt32)value);
230 /// Sets or gets the gesture layer line minimum length of an object.
232 /// <since_tizen> preview </since_tizen>
233 public int MinimumLineLength
237 return Interop.Elementary.elm_gesture_layer_line_min_length_get(Handle);
241 Interop.Elementary.elm_gesture_layer_line_min_length_set(Handle, value);
246 /// Sets or gets the gesture layer line angular tolerance of an object.
248 /// <since_tizen> preview </since_tizen>
249 public double LineAngularTolerance
253 return Interop.Elementary.elm_gesture_layer_line_angular_tolerance_get(Handle);
257 Interop.Elementary.elm_gesture_layer_line_angular_tolerance_set(Handle, value);
262 /// Sets or gets the gesture layer line distance tolerance of an object.
264 /// <since_tizen> preview </since_tizen>
265 public int LineDistanceTolerance
269 return Interop.Elementary.elm_gesture_layer_line_distance_tolerance_get(Handle);
273 Interop.Elementary.elm_gesture_layer_line_distance_tolerance_set(Handle, value);
278 /// Sets or gets the step-value for the rotate action.
280 /// <since_tizen> preview </since_tizen>
281 public double RotateStep
285 return Interop.Elementary.elm_gesture_layer_rotate_step_get(Handle);
289 Interop.Elementary.elm_gesture_layer_rotate_step_set(Handle, value);
294 /// Sets or gets the gesture layer rotate angular tolerance of an object.
296 /// <since_tizen> preview </since_tizen>
297 public double RotateAngularTolerance
301 return Interop.Elementary.elm_gesture_layer_rotate_angular_tolerance_get(Handle);
305 Interop.Elementary.elm_gesture_layer_rotate_angular_tolerance_set(Handle, value);
310 /// Sets or gets the control step value for the zoom action.
312 /// <since_tizen> preview </since_tizen>
313 public double ZoomStep
317 return Interop.Elementary.elm_gesture_layer_zoom_step_get(Handle);
321 Interop.Elementary.elm_gesture_layer_zoom_step_set(Handle, value);
326 /// Sets or gets the gesture layer zoom distance tolerance of an object.
328 /// <since_tizen> preview </since_tizen>
329 public int ZoomDistanceTolerance
333 return Interop.Elementary.elm_gesture_layer_zoom_distance_tolerance_get(Handle);
337 Interop.Elementary.elm_gesture_layer_zoom_distance_tolerance_set(Handle, value);
342 /// Sets or gets the gesture layer zoom finger factor of an object.
344 /// <since_tizen> preview </since_tizen>
345 public double ZoomFingerFactor
349 return Interop.Elementary.elm_gesture_layer_zoom_finger_factor_get(Handle);
353 Interop.Elementary.elm_gesture_layer_zoom_finger_factor_set(Handle, value);
358 /// Sets or gets the gesture layer zoom wheel factor of an object.
360 /// <since_tizen> preview </since_tizen>
361 public double ZoomWheelFactor
365 return Interop.Elementary.elm_gesture_layer_zoom_wheel_factor_get(Handle);
369 Interop.Elementary.elm_gesture_layer_zoom_wheel_factor_set(Handle, value);
373 #endregion Properties
376 /// Attaches a gesture layer widget to an Evas object (setting the widget's target).
377 /// A gesture layer's target may be any Evas object. This object will be used to listen to mouse and key events.
379 /// <param name="target">The object to attach.</param>
380 /// <since_tizen> preview </since_tizen>
381 public void Attach(EvasObject target)
383 Interop.Elementary.elm_gesture_layer_attach(Handle, target.Handle);
387 /// Sets the gesture state change callback.
388 /// When all callbacks for the gesture are set to null, it means this gesture is disabled.
390 /// <param name="type">The gesture you want to track state of.</param>
391 /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
392 /// <param name="action">The callback itself.</param>
393 /// <since_tizen> preview </since_tizen>
394 public void SetGestureCallback(GestureType type, GestureState state, Action<object> action)
400 // if this (type, state) already exists in _handlers, we will reuse it
401 foreach (var handler in _handlers)
403 if (handler.Type == type && handler.State == state)
412 // if we are changing null -> not-null, or not-null -> null, then inform the EFL
413 if (_handlers[i].Action == null ^ action == null)
414 Interop.Elementary.elm_gesture_layer_cb_set(Handle, type, state, action == null ? null : _gestureCallback, new IntPtr(i));
415 // overwrite previous action
416 _handlers[i].Action = action;
422 // ignore unsetting a handler for event which was not registered yet?
425 // (type, state) was not found, so we are adding a new entry and registering the callback
426 _handlers.Add(new NativeCallback(type, state, action));
427 // callback is always the same, the event is recognised by the index in _handler list (the index is passed as data)
428 Interop.Elementary.elm_gesture_layer_cb_set(Handle, type, state, _gestureCallback, new IntPtr(i));
434 /// Clears the gesture state change callback.
436 /// <since_tizen> preview </since_tizen>
437 public void ClearCallbacks()
442 foreach (var handler in _handlers)
444 if (handler.Action != null)
446 Interop.Elementary.elm_gesture_layer_cb_set(Handle, handler.Type, handler.State, null, new IntPtr(i));
447 handler.Action = null;
454 #region Typed callback setting methods
456 // Following methods have been added for convenience, so the user will not have to convert Info structures himself
458 /// Sets the tap callback.
460 /// <param name="type">The gesture you want to track state of.</param>
461 /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
462 /// <param name="action">The callback itself.</param>
463 /// <since_tizen> preview </since_tizen>
464 public void SetTapCallback(GestureType type, GestureState state, Action<TapData> action)
466 SetCallback(type, state, action);
470 /// Sets the gesture state change callback with momentum gesture type.
472 /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
473 /// <param name="action">The callback itself.</param>
474 /// <since_tizen> preview </since_tizen>
475 public void SetMomentumCallback(GestureState state, Action<MomentumData> action)
477 SetCallback(GestureType.Momentum, state, action);
481 /// Sets the gesture state change callback with line gesture type.
483 /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
484 /// <param name="action">The callback itself.</param>
485 /// <since_tizen> preview </since_tizen>
486 public void SetLineCallback(GestureState state, Action<LineData> action)
488 SetCallback(GestureType.Line, state, action);
492 /// Sets the gesture state change callback with flick gesture type.
494 /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
495 /// <param name="action">The callback itself.</param>
496 /// <since_tizen> preview </since_tizen>
497 public void SetFlickCallback(GestureState state, Action<LineData> action)
499 SetCallback(GestureType.Flick, state, action);
503 /// Sets the gesture state change callback with zoom gesture type.
505 /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
506 /// <param name="action">The callback itself.</param>
507 /// <since_tizen> preview </since_tizen>
508 public void SetZoomCallback(GestureState state, Action<ZoomData> action)
510 SetCallback(GestureType.Zoom, state, action);
514 /// Sets the gesture state change callback with rotate gesture type.
516 /// <param name="state">The event the callback tracks (START, MOVE, END, ABORT).</param>
517 /// <param name="action">The callback itself.</param>
518 /// <since_tizen> preview </since_tizen>
519 public void SetRotateCallback(GestureState state, Action<RotateData> action)
521 SetCallback(GestureType.Rotate, state, action);
524 #endregion Typed callback setting methods
527 /// Calls this function to construct a new gesture-layer object.
529 /// <param name="parent">The gesture layer's parent widget.</param>
530 /// <returns></returns>
531 /// <since_tizen> preview </since_tizen>
532 protected override IntPtr CreateHandle(EvasObject parent)
534 return Interop.Elementary.elm_gesture_layer_add(parent.Handle);
538 /// Clears the gesture state change callback.
540 /// <since_tizen> preview </since_tizen>
541 protected override void OnUnrealize()
547 private void SetCallback<T>(GestureType type, GestureState state, Action<T> action)
550 SetGestureCallback(type, state, null);
552 SetGestureCallback(type, state, new Action<object>((info) => action((T)info)));
555 private int GestureCallbackHandler(IntPtr data, IntPtr event_info)
557 // so EFL called our callback, lets use data to find the right Action to call
558 var handlerIndex = (int)data;
559 // thanks to the fact that we never remove item from _handlers, we don't need a lock here
560 if (handlerIndex < 0 || handlerIndex >= _handlers.Count)
563 var currentHandler = _handlers[handlerIndex];
564 Action<object> action = currentHandler.Action;
568 // the interpretation of the event_info struct pointer depends on the GestureType
569 switch (currentHandler.Type)
571 case GestureType.Tap:
572 case GestureType.LongTap:
573 case GestureType.DoubleTap:
574 case GestureType.TripleTap:
575 action(Marshal.PtrToStructure<TapData>(event_info));
578 case GestureType.Momentum:
579 action(Marshal.PtrToStructure<MomentumData>(event_info));
582 case GestureType.Line:
583 case GestureType.Flick:
584 action(Marshal.PtrToStructure<LineData>(event_info));
587 case GestureType.Zoom:
588 action(Marshal.PtrToStructure<ZoomData>(event_info));
591 case GestureType.Rotate:
592 action(Marshal.PtrToStructure<RotateData>(event_info));
598 #region Info structures
601 /// The struct of TapData.
603 /// <since_tizen> preview </since_tizen>
604 [StructLayout(LayoutKind.Sequential)]
605 public struct TapData
608 /// The X coordinate of the center point.
610 /// <since_tizen> preview </since_tizen>
614 /// The Y coordinate of the center point.
616 /// <since_tizen> preview </since_tizen>
619 #pragma warning disable 3003
622 /// The number of fingers tapped.
624 /// <since_tizen> preview </since_tizen>
625 public UInt32 FingersCount;
630 /// <since_tizen> preview </since_tizen>
631 public UInt32 Timestamp;
633 #pragma warning restore 3003
637 /// The struct of MomentumData.
639 /// <since_tizen> preview </since_tizen>
640 [StructLayout(LayoutKind.Sequential)]
641 public struct MomentumData
644 /// Final-swipe direction starting point on X.
646 /// <since_tizen> preview </since_tizen>
650 /// Final-swipe direction starting point on Y.
652 /// <since_tizen> preview </since_tizen>
656 /// Final-swipe direction ending point on X.
658 /// <since_tizen> preview </since_tizen>
662 /// Final-swipe direction ending point on Y.
664 /// <since_tizen> preview </since_tizen>
667 #pragma warning disable 3003
670 /// Timestamp of start of final X-swipe.
672 /// <since_tizen> preview </since_tizen>
673 public UInt32 HorizontalSwipeTimestamp;
676 /// Timestamp of start of final Y-swipe.
678 /// <since_tizen> preview </since_tizen>
679 public UInt32 VerticalSwipeTimestamp;
684 /// <since_tizen> preview </since_tizen>
685 public Int32 HorizontalMomentum;
690 /// <since_tizen> preview </since_tizen>
691 public Int32 VerticalMomentum;
694 /// Number of fingers.
696 /// <since_tizen> preview </since_tizen>
697 public UInt32 FingersCount;
699 #pragma warning restore 3003
703 /// The struct of LineData.
705 /// <since_tizen> preview </since_tizen>
706 [StructLayout(LayoutKind.Sequential)]
707 public struct LineData
710 /// Final-swipe direction starting point on X.
712 /// <since_tizen> preview </since_tizen>
716 /// Final-swipe direction starting point on Y.
718 /// <since_tizen> preview </since_tizen>
722 /// Final-swipe direction ending point on X.
724 /// <since_tizen> preview </since_tizen>
728 /// Final-swipe direction ending point on Y.
730 /// <since_tizen> preview </since_tizen>
733 #pragma warning disable 3003
736 /// Timestamp of start of final X-swipe.
738 /// <since_tizen> preview </since_tizen>
739 public UInt32 HorizontalSwipeTimestamp;
742 /// Timestamp of start of final Y-swipe.
744 /// <since_tizen> preview </since_tizen>
745 public UInt32 VerticalSwipeTimestamp;
750 /// <since_tizen> preview </since_tizen>
751 public Int32 HorizontalMomentum;
756 /// <since_tizen> preview </since_tizen>
757 public Int32 VerticalMomentum;
760 /// Number of fingers.
762 /// <since_tizen> preview </since_tizen>
763 public UInt32 FingersCount;
765 #pragma warning restore 3003
768 /// Angle (direction) of lines.
770 /// <since_tizen> preview </since_tizen>
775 /// The struct of ZoomData.
777 /// <since_tizen> preview </since_tizen>
778 [StructLayout(LayoutKind.Sequential)]
779 public struct ZoomData
782 /// The X coordinate of zoom center point reported to the user.
784 /// <since_tizen> preview </since_tizen>
788 /// The Y coordinate of zoom center point reported to the user.
790 /// <since_tizen> preview </since_tizen>
794 /// The radius (distance) between fingers reported to user.
796 /// <since_tizen> preview </since_tizen>
800 /// The zoom value. 1.0 means no zoom.
802 /// <since_tizen> preview </since_tizen>
806 /// Zoom momentum: zoom growth per second (NOT YET SUPPORTED).
808 private double Momentum;
812 /// The struct of RotateData.
814 /// <since_tizen> preview </since_tizen>
815 [StructLayout(LayoutKind.Sequential)]
816 public struct RotateData
819 /// The X coordinate of rotation center point reported to the user.
821 /// <since_tizen> preview </since_tizen>
825 /// The Y coordinate of rotation center point reported to the user.
827 /// <since_tizen> preview </since_tizen>
831 /// The radius (distance) between fingers reported to user.
833 /// <since_tizen> preview </since_tizen>
839 /// <since_tizen> preview </since_tizen>
840 public double BaseAngle;
843 /// The rotation value. 0.0 means no rotation.
845 /// <since_tizen> preview </since_tizen>
849 /// Rotation momentum: rotation done per second (NOT YET SUPPORTED).
851 private double Momentum;
854 #endregion Info structures
857 /// Config is a static class, it provides gestureLayer's timeout information.
859 /// <since_tizen> preview </since_tizen>
860 public static class Config
863 /// Sets or gets the duration for occurring long tap event of gesture layer.
865 /// <since_tizen> preview </since_tizen>
866 public static double DefaultLongTapTimeout
870 return Interop.Elementary.elm_config_glayer_long_tap_start_timeout_get();
874 Interop.Elementary.elm_config_glayer_long_tap_start_timeout_set(value);
879 /// Sets or gets the duration for occurring double tap event of gesture layer.
881 /// <since_tizen> preview </since_tizen>
882 public static double DefaultDoubleTapTimeout
886 return Interop.Elementary.elm_config_glayer_double_tap_timeout_get();
890 Interop.Elementary.elm_config_glayer_double_tap_timeout_set(value);
895 private class NativeCallback
897 public readonly GestureType Type;
898 public readonly GestureState State;
899 public Action<object> Action;
901 public NativeCallback(GestureType type, GestureState state, Action<object> action)