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;
23 public class GestureLayer : EvasObject
25 private readonly Interop.Elementary.GestureEventCallback _gestureCallback;
27 // Important: don't remove items from _handlers list
28 // The list can grow up to (number of GestureType) * (number of GestureState)
29 // but all gestures share the callback and you don't want to desynchronize mapping
30 private readonly List<NativeCallback> _handlers = new List<NativeCallback>();
32 public GestureLayer(EvasObject parent) : base(parent)
34 _gestureCallback = new Interop.Elementary.GestureEventCallback(GestureCallbackHandler);
37 public enum GestureType
50 public enum GestureState
60 public bool HoldEvents
64 return Interop.Elementary.elm_gesture_layer_hold_events_get(Handle);
68 Interop.Elementary.elm_gesture_layer_hold_events_set(Handle, value);
76 return Interop.Elementary.elm_gesture_layer_continues_enable_get(Handle);
80 Interop.Elementary.elm_gesture_layer_continues_enable_set(Handle, value);
84 public int TapFingerSize
88 return Interop.Elementary.elm_gesture_layer_tap_finger_size_get(Handle);
92 Interop.Elementary.elm_gesture_layer_tap_finger_size_set(Handle, value);
96 public double LongTapTimeout
100 return Interop.Elementary.elm_gesture_layer_long_tap_start_timeout_get(Handle);
104 Interop.Elementary.elm_gesture_layer_long_tap_start_timeout_set(Handle, value);
108 public double DoubleTapTimeout
112 return Interop.Elementary.elm_gesture_layer_double_tap_timeout_get(Handle);
116 Interop.Elementary.elm_gesture_layer_double_tap_timeout_set(Handle, value);
120 public int FlickTimeLimit
124 return (int)Interop.Elementary.elm_gesture_layer_flick_time_limit_ms_get(Handle);
128 Interop.Elementary.elm_gesture_layer_flick_time_limit_ms_set(Handle, (UInt32)value);
132 public int MinimumLineLength
136 return Interop.Elementary.elm_gesture_layer_line_min_length_get(Handle);
140 Interop.Elementary.elm_gesture_layer_line_min_length_set(Handle, value);
144 public double LineAngularTolerance
148 return Interop.Elementary.elm_gesture_layer_line_angular_tolerance_get(Handle);
152 Interop.Elementary.elm_gesture_layer_line_angular_tolerance_set(Handle, value);
156 public int LineDistanceTolerance
160 return Interop.Elementary.elm_gesture_layer_line_distance_tolerance_get(Handle);
164 Interop.Elementary.elm_gesture_layer_line_distance_tolerance_set(Handle, value);
168 public double RotateStep
172 return Interop.Elementary.elm_gesture_layer_rotate_step_get(Handle);
176 Interop.Elementary.elm_gesture_layer_rotate_step_set(Handle, value);
180 public double RotateAngularTolerance
184 return Interop.Elementary.elm_gesture_layer_rotate_angular_tolerance_get(Handle);
188 Interop.Elementary.elm_gesture_layer_rotate_angular_tolerance_set(Handle, value);
192 public double ZoomStep
196 return Interop.Elementary.elm_gesture_layer_zoom_step_get(Handle);
200 Interop.Elementary.elm_gesture_layer_zoom_step_set(Handle, value);
204 public int ZoomDistanceTolerance
208 return Interop.Elementary.elm_gesture_layer_zoom_distance_tolerance_get(Handle);
212 Interop.Elementary.elm_gesture_layer_zoom_distance_tolerance_set(Handle, value);
216 public double ZoomFingerFactor
220 return Interop.Elementary.elm_gesture_layer_zoom_finger_factor_get(Handle);
224 Interop.Elementary.elm_gesture_layer_zoom_finger_factor_set(Handle, value);
228 public double ZoomWheelFactor
232 return Interop.Elementary.elm_gesture_layer_zoom_wheel_factor_get(Handle);
236 Interop.Elementary.elm_gesture_layer_zoom_wheel_factor_set(Handle, value);
239 #endregion Properties
241 public void Attach(EvasObject target)
243 Interop.Elementary.elm_gesture_layer_attach(Handle, target.Handle);
246 public void SetGestureCallback(GestureType type, GestureState state, Action<object> action)
252 // if this (type, state) already exists in _handlers, we will reuse it
253 foreach (var handler in _handlers)
255 if (handler.Type == type && handler.State == state)
264 // if we are changing null -> not-null, or not-null -> null, then inform the EFL
265 if (_handlers[i].Action == null ^ action == null)
266 Interop.Elementary.elm_gesture_layer_cb_set(Handle, type, state, action == null ? null : _gestureCallback, new IntPtr(i));
267 // overwrite previous action
268 _handlers[i].Action = action;
274 // ignore unsetting a handler for event which was not registered yet?
277 // (type, state) was not found, so we are adding a new entry and registering the callback
278 _handlers.Add(new NativeCallback(type, state, action));
279 // callback is always the same, the event is recognised by the index in _handler list (the index is passed as data)
280 Interop.Elementary.elm_gesture_layer_cb_set(Handle, type, state, _gestureCallback, new IntPtr(i));
285 public void ClearCallbacks()
290 foreach (var handler in _handlers)
292 if (handler.Action != null)
294 Interop.Elementary.elm_gesture_layer_cb_set(Handle, handler.Type, handler.State, null, new IntPtr(i));
295 handler.Action = null;
302 #region Typed callback setting methods
303 // Following methods have been added for convenience, so the user will not have to convert Info structures himself
304 public void SetTapCallback(GestureType type, GestureState state, Action<TapData> action)
306 SetCallback(type, state, action);
309 public void SetMomentumCallback(GestureState state, Action<MomentumData> action)
311 SetCallback(GestureType.Momentum, state, action);
314 public void SetLineCallback(GestureState state, Action<LineData> action)
316 SetCallback(GestureType.Line, state, action);
319 public void SetFlickCallback(GestureState state, Action<LineData> action)
321 SetCallback(GestureType.Flick, state, action);
324 public void SetZoomCallback(GestureState state, Action<ZoomData> action)
326 SetCallback(GestureType.Zoom, state, action);
329 public void SetRotateCallback(GestureState state, Action<RotateData> action)
331 SetCallback(GestureType.Rotate, state, action);
333 #endregion Typed callback setting methods
335 protected override IntPtr CreateHandle(EvasObject parent)
337 return Interop.Elementary.elm_gesture_layer_add(parent);
340 protected override void OnUnrealize()
346 private void SetCallback<T>(GestureType type, GestureState state, Action<T> action)
349 SetGestureCallback(type, state, null);
351 SetGestureCallback(type, state, new Action<object>((info) => action((T)info)));
354 private void GestureCallbackHandler(IntPtr data, IntPtr event_info)
356 // so EFL called our callback, lets use data to find the right Action to call
357 var handlerIndex = (int)data;
358 // thanks to the fact that we never remove item from _handlers, we don't need a lock here
359 if (handlerIndex < 0 || handlerIndex >= _handlers.Count)
361 Action<object> action = _handlers[handlerIndex].Action;
364 // the interpretation of the event_info struct pointer depends on the GestureType
365 switch (_handlers[handlerIndex].Type)
367 case GestureType.Tap:
368 case GestureType.LongTap:
369 case GestureType.DoubleTap:
370 case GestureType.TripleTap:
371 action(Marshal.PtrToStructure(event_info, typeof(TapData)));
373 case GestureType.Momentum:
374 action(Marshal.PtrToStructure(event_info, typeof(MomentumData)));
376 case GestureType.Line:
377 case GestureType.Flick:
378 action(Marshal.PtrToStructure(event_info, typeof(LineData)));
380 case GestureType.Zoom:
381 action(Marshal.PtrToStructure(event_info, typeof(ZoomData)));
383 case GestureType.Rotate:
384 action(Marshal.PtrToStructure(event_info, typeof(RotateData)));
389 #region Info structures
391 [StructLayout(LayoutKind.Sequential)]
392 public struct TapData
395 /// The x coordinate of the center point.
400 /// The y coordinate of the center point.
404 #pragma warning disable 3003
406 /// The number of fingers tapped.
408 public UInt32 FingersCount;
413 public UInt32 Timestamp;
414 #pragma warning restore 3003
417 [StructLayout(LayoutKind.Sequential)]
418 public struct MomentumData
421 /// Final-swipe direction starting point on X.
426 /// Final-swipe direction starting point on Y.
431 /// Final-swipe direction ending point on X.
436 /// Final-swipe direction ending point on Y
440 #pragma warning disable 3003
442 /// Timestamp of start of final x-swipe.
444 public UInt32 HorizontalSwipeTimestamp;
447 /// Timestamp of start of final y-swipe.
449 public UInt32 VerticalSwipeTimestamp;
454 public Int32 HorizontalMomentum;
459 public Int32 VerticalMomentum;
462 /// Number of fingers.
464 public UInt32 FingersCount;
465 #pragma warning restore 3003
468 [StructLayout(LayoutKind.Sequential)]
469 public struct LineData
472 /// Final-swipe direction starting point on X.
477 /// Final-swipe direction starting point on Y.
482 /// Final-swipe direction ending point on X.
487 /// Final-swipe direction ending point on Y
491 #pragma warning disable 3003
493 /// Timestamp of start of final x-swipe.
495 public UInt32 HorizontalSwipeTimestamp;
498 /// Timestamp of start of final y-swipe.
500 public UInt32 VerticalSwipeTimestamp;
505 public Int32 HorizontalMomentum;
510 public Int32 VerticalMomentum;
513 /// Number of fingers.
515 public UInt32 FingersCount;
516 #pragma warning restore 3003
519 /// Angle (direction) of lines.
524 [StructLayout(LayoutKind.Sequential)]
525 public struct ZoomData
528 /// The x coordinate of zoom center point reported to user.
533 /// The y coordinate of zoom center point reported to user.
538 /// The radius (distance) between fingers reported to user.
543 /// The zoom value. 1.0 means no zoom.
548 /// Zoom momentum: zoom growth per second (NOT YET SUPPORTED).
550 private double Momentum;
553 [StructLayout(LayoutKind.Sequential)]
554 public struct RotateData
557 /// The x coordinate of rotation center point reported to user.
562 /// The y coordinate of rotation center point reported to user.
567 /// The radius (distance) between fingers reported to user.
574 public double BaseAngle;
577 /// The rotation value. 0.0 means no rotation.
582 /// Rotation momentum: rotation done per second (NOT YET SUPPORTED).
584 private double Momentum;
587 #endregion Info structures
589 public static class Config
591 public static double DefaultLongTapTimeout
594 return Interop.Elementary.elm_config_glayer_long_tap_start_timeout_get();
597 Interop.Elementary.elm_config_glayer_long_tap_start_timeout_set(value);
601 public static double DefaultDoubleTapTimeout
604 return Interop.Elementary.elm_config_glayer_double_tap_timeout_get();
607 Interop.Elementary.elm_config_glayer_double_tap_timeout_set(value);
612 private class NativeCallback
614 public readonly GestureType Type;
615 public readonly GestureState State;
616 public Action<object> Action;
618 public NativeCallback(GestureType type, GestureState state, Action<object> action)