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 GestureLayer class.
40 /// <param name="parent">The parent is a given container which will be attached by GestureLayer as a child. It's <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 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 move
79 /// N fingers line gesture
84 /// N fingers flick gesture
100 /// Enumeration for 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 continues 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 min 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 step-value for 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 control step value for 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 /// Attach 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 /// Set 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 /// clear 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 /// Set 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 /// Set 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 /// Set 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 /// Set 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 /// Set 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 /// Set 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 /// Call 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);
538 /// clear 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 void 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)
562 Action<object> action = _handlers[handlerIndex].Action;
565 // the interpretation of the event_info struct pointer depends on the GestureType
566 switch (_handlers[handlerIndex].Type)
568 case GestureType.Tap:
569 case GestureType.LongTap:
570 case GestureType.DoubleTap:
571 case GestureType.TripleTap:
572 action(Marshal.PtrToStructure<TapData>(event_info));
575 case GestureType.Momentum:
576 action(Marshal.PtrToStructure<MomentumData>(event_info));
579 case GestureType.Line:
580 case GestureType.Flick:
581 action(Marshal.PtrToStructure<LineData>(event_info));
584 case GestureType.Zoom:
585 action(Marshal.PtrToStructure<ZoomData>(event_info));
588 case GestureType.Rotate:
589 action(Marshal.PtrToStructure<RotateData>(event_info));
594 #region Info structures
597 /// The struct of TapData
599 /// <since_tizen> preview </since_tizen>
600 [StructLayout(LayoutKind.Sequential)]
601 public struct TapData
604 /// The x coordinate of the center point.
606 /// <since_tizen> preview </since_tizen>
610 /// The y coordinate of the center point.
612 /// <since_tizen> preview </since_tizen>
615 #pragma warning disable 3003
618 /// The number of fingers tapped.
620 /// <since_tizen> preview </since_tizen>
621 public UInt32 FingersCount;
626 /// <since_tizen> preview </since_tizen>
627 public UInt32 Timestamp;
629 #pragma warning restore 3003
633 /// The struct of MomentumData
635 /// <since_tizen> preview </since_tizen>
636 [StructLayout(LayoutKind.Sequential)]
637 public struct MomentumData
640 /// Final-swipe direction starting point on X.
642 /// <since_tizen> preview </since_tizen>
646 /// Final-swipe direction starting point on Y.
648 /// <since_tizen> preview </since_tizen>
652 /// Final-swipe direction ending point on X.
654 /// <since_tizen> preview </since_tizen>
658 /// Final-swipe direction ending point on Y
660 /// <since_tizen> preview </since_tizen>
663 #pragma warning disable 3003
666 /// Timestamp of start of final x-swipe.
668 /// <since_tizen> preview </since_tizen>
669 public UInt32 HorizontalSwipeTimestamp;
672 /// Timestamp of start of final y-swipe.
674 /// <since_tizen> preview </since_tizen>
675 public UInt32 VerticalSwipeTimestamp;
680 /// <since_tizen> preview </since_tizen>
681 public Int32 HorizontalMomentum;
686 /// <since_tizen> preview </since_tizen>
687 public Int32 VerticalMomentum;
690 /// Number of fingers.
692 /// <since_tizen> preview </since_tizen>
693 public UInt32 FingersCount;
695 #pragma warning restore 3003
699 /// The struct of LineData
701 /// <since_tizen> preview </since_tizen>
702 [StructLayout(LayoutKind.Sequential)]
703 public struct LineData
706 /// Final-swipe direction starting point on X.
708 /// <since_tizen> preview </since_tizen>
712 /// Final-swipe direction starting point on Y.
714 /// <since_tizen> preview </since_tizen>
718 /// Final-swipe direction ending point on X.
720 /// <since_tizen> preview </since_tizen>
724 /// Final-swipe direction ending point on Y
726 /// <since_tizen> preview </since_tizen>
729 #pragma warning disable 3003
732 /// Timestamp of start of final x-swipe.
734 /// <since_tizen> preview </since_tizen>
735 public UInt32 HorizontalSwipeTimestamp;
738 /// Timestamp of start of final y-swipe.
740 /// <since_tizen> preview </since_tizen>
741 public UInt32 VerticalSwipeTimestamp;
746 /// <since_tizen> preview </since_tizen>
747 public Int32 HorizontalMomentum;
752 /// <since_tizen> preview </since_tizen>
753 public Int32 VerticalMomentum;
756 /// Number of fingers.
758 /// <since_tizen> preview </since_tizen>
759 public UInt32 FingersCount;
761 #pragma warning restore 3003
764 /// Angle (direction) of lines.
766 /// <since_tizen> preview </since_tizen>
771 /// The struct of ZoomData
773 /// <since_tizen> preview </since_tizen>
774 [StructLayout(LayoutKind.Sequential)]
775 public struct ZoomData
778 /// The x coordinate of zoom center point reported to user.
780 /// <since_tizen> preview </since_tizen>
784 /// The y coordinate of zoom center point reported to user.
786 /// <since_tizen> preview </since_tizen>
790 /// The radius (distance) between fingers reported to user.
792 /// <since_tizen> preview </since_tizen>
796 /// The zoom value. 1.0 means no zoom.
798 /// <since_tizen> preview </since_tizen>
802 /// Zoom momentum: zoom growth per second (NOT YET SUPPORTED).
804 private double Momentum;
808 /// The struct of RotateData
810 /// <since_tizen> preview </since_tizen>
811 [StructLayout(LayoutKind.Sequential)]
812 public struct RotateData
815 /// The x coordinate of rotation center point reported to user.
817 /// <since_tizen> preview </since_tizen>
821 /// The y coordinate of rotation center point reported to user.
823 /// <since_tizen> preview </since_tizen>
827 /// The radius (distance) between fingers reported to user.
829 /// <since_tizen> preview </since_tizen>
835 /// <since_tizen> preview </since_tizen>
836 public double BaseAngle;
839 /// The rotation value. 0.0 means no rotation.
841 /// <since_tizen> preview </since_tizen>
845 /// Rotation momentum: rotation done per second (NOT YET SUPPORTED).
847 private double Momentum;
850 #endregion Info structures
853 /// Config is a static class, it provides gestureLayer's timeout information.
855 /// <since_tizen> preview </since_tizen>
856 public static class Config
859 /// Sets or gets the duration for occurring long tap event of gesture layer.
861 /// <since_tizen> preview </since_tizen>
862 public static double DefaultLongTapTimeout
866 return Interop.Elementary.elm_config_glayer_long_tap_start_timeout_get();
870 Interop.Elementary.elm_config_glayer_long_tap_start_timeout_set(value);
875 /// Sets or gets the duration for occurring double tap event of gesture layer.
877 /// <since_tizen> preview </since_tizen>
878 public static double DefaultDoubleTapTimeout
882 return Interop.Elementary.elm_config_glayer_double_tap_timeout_get();
886 Interop.Elementary.elm_config_glayer_double_tap_timeout_set(value);
891 private class NativeCallback
893 public readonly GestureType Type;
894 public readonly GestureState State;
895 public Action<object> Action;
897 public NativeCallback(GestureType type, GestureState state, Action<object> action)