2 using System.Runtime.InteropServices;
3 using System.Collections.Generic;
7 public class GestureLayer : EvasObject
9 private readonly Interop.Elementary.GestureEventCallback _gestureCallback;
11 // Important: don't remove items from _handlers list
12 // The list can grow up to (number of GestureType) * (number of GestureState)
13 // but all gestures share the callback and you don't want to desynchronize mapping
14 private readonly List<NativeCallback> _handlers = new List<NativeCallback>();
16 public GestureLayer(EvasObject parent) : base(parent)
18 _gestureCallback = new Interop.Elementary.GestureEventCallback(GestureCallbackHandler);
21 public enum GestureType
34 public enum GestureState
44 public bool HoldEvents
48 return Interop.Elementary.elm_gesture_layer_hold_events_get(Handle);
52 Interop.Elementary.elm_gesture_layer_hold_events_set(Handle, value);
60 return Interop.Elementary.elm_gesture_layer_continues_enable_get(Handle);
64 Interop.Elementary.elm_gesture_layer_continues_enable_set(Handle, value);
68 public int TapFingerSize
72 return Interop.Elementary.elm_gesture_layer_tap_finger_size_get(Handle);
76 Interop.Elementary.elm_gesture_layer_tap_finger_size_set(Handle, value);
80 public double LongTapTimeout
84 return Interop.Elementary.elm_gesture_layer_long_tap_start_timeout_get(Handle);
88 Interop.Elementary.elm_gesture_layer_long_tap_start_timeout_set(Handle, value);
92 public double DoubleTapTimeout
96 return Interop.Elementary.elm_gesture_layer_double_tap_timeout_get(Handle);
100 Interop.Elementary.elm_gesture_layer_double_tap_timeout_set(Handle, value);
104 public int FlickTimeLimit
108 return (int)Interop.Elementary.elm_gesture_layer_flick_time_limit_ms_get(Handle);
112 Interop.Elementary.elm_gesture_layer_flick_time_limit_ms_set(Handle, (UInt32)value);
116 public int MinimumLineLength
120 return Interop.Elementary.elm_gesture_layer_line_min_length_get(Handle);
124 Interop.Elementary.elm_gesture_layer_line_min_length_set(Handle, value);
128 public double LineAngularTolerance
132 return Interop.Elementary.elm_gesture_layer_line_angular_tolerance_get(Handle);
136 Interop.Elementary.elm_gesture_layer_line_angular_tolerance_set(Handle, value);
140 public int LineDistanceTolerance
144 return Interop.Elementary.elm_gesture_layer_line_distance_tolerance_get(Handle);
148 Interop.Elementary.elm_gesture_layer_line_distance_tolerance_set(Handle, value);
152 public double RotateStep
156 return Interop.Elementary.elm_gesture_layer_rotate_step_get(Handle);
160 Interop.Elementary.elm_gesture_layer_rotate_step_set(Handle, value);
164 public double RotateAngularTolerance
168 return Interop.Elementary.elm_gesture_layer_rotate_angular_tolerance_get(Handle);
172 Interop.Elementary.elm_gesture_layer_rotate_angular_tolerance_set(Handle, value);
176 public double ZoomStep
180 return Interop.Elementary.elm_gesture_layer_zoom_step_get(Handle);
184 Interop.Elementary.elm_gesture_layer_zoom_step_set(Handle, value);
188 public int ZoomDistanceTolerance
192 return Interop.Elementary.elm_gesture_layer_zoom_distance_tolerance_get(Handle);
196 Interop.Elementary.elm_gesture_layer_zoom_distance_tolerance_set(Handle, value);
200 public double ZoomFingerFactor
204 return Interop.Elementary.elm_gesture_layer_zoom_finger_factor_get(Handle);
208 Interop.Elementary.elm_gesture_layer_zoom_finger_factor_set(Handle, value);
212 public double ZoomWheelFactor
216 return Interop.Elementary.elm_gesture_layer_zoom_wheel_factor_get(Handle);
220 Interop.Elementary.elm_gesture_layer_zoom_wheel_factor_set(Handle, value);
223 #endregion Properties
225 public void Attach(EvasObject target)
227 Interop.Elementary.elm_gesture_layer_attach(Handle, target.Handle);
230 public void SetGestureCallback(GestureType type, GestureState state, Action<object> action)
236 // if this (type, state) already exists in _handlers, we will reuse it
237 foreach (var handler in _handlers)
239 if (handler.Type == type && handler.State == state)
248 // if we are changing null -> not-null, or not-null -> null, then inform the EFL
249 if (_handlers[i].Action == null ^ action == null)
250 Interop.Elementary.elm_gesture_layer_cb_set(Handle, type, state, action == null ? null : _gestureCallback, new IntPtr(i));
251 // overwrite previous action
252 _handlers[i].Action = action;
258 // ignore unsetting a handler for event which was not registered yet?
261 // (type, state) was not found, so we are adding a new entry and registering the callback
262 _handlers.Add(new NativeCallback(type, state, action));
263 // callback is always the same, the event is recognised by the index in _handler list (the index is passed as data)
264 Interop.Elementary.elm_gesture_layer_cb_set(Handle, type, state, _gestureCallback, new IntPtr(i));
269 public void ClearCallbacks()
274 foreach (var handler in _handlers)
276 if (handler.Action != null)
278 Interop.Elementary.elm_gesture_layer_cb_set(Handle, handler.Type, handler.State, null, new IntPtr(i));
279 handler.Action = null;
286 #region Typed callback setting methods
287 // Following methods have been added for convenience, so the user will not have to convert Info structures himself
288 public void SetTapCallback(GestureType type, GestureState state, Action<TapData> action)
290 SetCallback(type, state, action);
293 public void SetMomentumCallback(GestureState state, Action<MomentumData> action)
295 SetCallback(GestureType.Momentum, state, action);
298 public void SetLineCallback(GestureState state, Action<LineData> action)
300 SetCallback(GestureType.Line, state, action);
303 public void SetFlickCallback(GestureState state, Action<LineData> action)
305 SetCallback(GestureType.Flick, state, action);
308 public void SetZoomCallback(GestureState state, Action<ZoomData> action)
310 SetCallback(GestureType.Zoom, state, action);
313 public void SetRotateCallback(GestureState state, Action<RotateData> action)
315 SetCallback(GestureType.Rotate, state, action);
317 #endregion Typed callback setting methods
319 protected override IntPtr CreateHandle(EvasObject parent)
321 return Interop.Elementary.elm_gesture_layer_add(parent);
324 protected override void OnUnrealize()
330 private void SetCallback<T>(GestureType type, GestureState state, Action<T> action)
333 SetGestureCallback(type, state, null);
335 SetGestureCallback(type, state, new Action<object>((info) => action((T)info)));
338 private void GestureCallbackHandler(IntPtr data, IntPtr event_info)
340 // so EFL called our callback, lets use data to find the right Action to call
341 var handlerIndex = (int)data;
342 // thanks to the fact that we never remove item from _handlers, we don't need a lock here
343 if (handlerIndex < 0 || handlerIndex >= _handlers.Count)
345 Action<object> action = _handlers[handlerIndex].Action;
348 // the interpretation of the event_info struct pointer depends on the GestureType
349 switch (_handlers[handlerIndex].Type)
351 case GestureType.Tap:
352 case GestureType.LongTap:
353 case GestureType.DoubleTap:
354 case GestureType.TripleTap:
355 action(Marshal.PtrToStructure(event_info, typeof(TapData)));
357 case GestureType.Momentum:
358 action(Marshal.PtrToStructure(event_info, typeof(MomentumData)));
360 case GestureType.Line:
361 case GestureType.Flick:
362 action(Marshal.PtrToStructure(event_info, typeof(LineData)));
364 case GestureType.Zoom:
365 action(Marshal.PtrToStructure(event_info, typeof(ZoomData)));
367 case GestureType.Rotate:
368 action(Marshal.PtrToStructure(event_info, typeof(RotateData)));
373 #region Info structures
375 [StructLayout(LayoutKind.Sequential)]
376 public struct TapData
379 /// The x coordinate of the center point.
384 /// The y coordinate of the center point.
388 #pragma warning disable 3003
390 /// The number of fingers tapped.
392 public UInt32 FingersCount;
397 public UInt32 Timestamp;
398 #pragma warning restore 3003
401 [StructLayout(LayoutKind.Sequential)]
402 public struct MomentumData
405 /// Final-swipe direction starting point on X.
410 /// Final-swipe direction starting point on Y.
415 /// Final-swipe direction ending point on X.
420 /// Final-swipe direction ending point on Y
424 #pragma warning disable 3003
426 /// Timestamp of start of final x-swipe.
428 public UInt32 HorizontalSwipeTimestamp;
431 /// Timestamp of start of final y-swipe.
433 public UInt32 VerticalSwipeTimestamp;
438 public Int32 HorizontalMomentum;
443 public Int32 VerticalMomentum;
446 /// Number of fingers.
448 public UInt32 FingersCount;
449 #pragma warning restore 3003
452 [StructLayout(LayoutKind.Sequential)]
453 public struct LineData
456 /// Final-swipe direction starting point on X.
461 /// Final-swipe direction starting point on Y.
466 /// Final-swipe direction ending point on X.
471 /// Final-swipe direction ending point on Y
475 #pragma warning disable 3003
477 /// Timestamp of start of final x-swipe.
479 public UInt32 HorizontalSwipeTimestamp;
482 /// Timestamp of start of final y-swipe.
484 public UInt32 VerticalSwipeTimestamp;
489 public Int32 HorizontalMomentum;
494 public Int32 VerticalMomentum;
497 /// Number of fingers.
499 public UInt32 FingersCount;
500 #pragma warning restore 3003
503 /// Angle (direction) of lines.
508 [StructLayout(LayoutKind.Sequential)]
509 public struct ZoomData
512 /// The x coordinate of zoom center point reported to user.
517 /// The y coordinate of zoom center point reported to user.
522 /// The radius (distance) between fingers reported to user.
527 /// The zoom value. 1.0 means no zoom.
532 /// Zoom momentum: zoom growth per second (NOT YET SUPPORTED).
534 private double Momentum;
537 [StructLayout(LayoutKind.Sequential)]
538 public struct RotateData
541 /// The x coordinate of rotation center point reported to user.
546 /// The y coordinate of rotation center point reported to user.
551 /// The radius (distance) between fingers reported to user.
558 public double BaseAngle;
561 /// The rotation value. 0.0 means no rotation.
566 /// Rotation momentum: rotation done per second (NOT YET SUPPORTED).
568 private double Momentum;
571 #endregion Info structures
573 public static class Config
575 public static double DefaultLongTapTimeout
578 return Interop.Elementary.elm_config_glayer_long_tap_start_timeout_get();
581 Interop.Elementary.elm_config_glayer_long_tap_start_timeout_set(value);
585 public static double DefaultDoubleTapTimeout
588 return Interop.Elementary.elm_config_glayer_double_tap_timeout_get();
591 Interop.Elementary.elm_config_glayer_double_tap_timeout_set(value);
596 private class NativeCallback
598 public readonly GestureType Type;
599 public readonly GestureState State;
600 public Action<object> Action;
602 public NativeCallback(GestureType type, GestureState state, Action<object> action)