Release 4.0.0-preview1-00321
[platform/core/csapi/tizenfx.git] / src / ElmSharp.Wearable / ElmSharp.Wearable / RotaryEventManager.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using System.Text;
21
22 namespace ElmSharp.Wearable
23 {
24     /// <summary>
25     /// RotaryEventManager serve functions for global Rotary event like Galaxy Gear.
26     /// </summary>
27     public static class RotaryEventManager
28     {
29         static Dictionary<RotaryEventHandler, Interop.Eext.Eext_Rotary_Handler_Cb> s_rotaryEventHandlers = new Dictionary<RotaryEventHandler, Interop.Eext.Eext_Rotary_Handler_Cb>();
30
31         /// <summary>
32         /// Rotated will triggered when rotatable device like Galaxy Gear Bezel is rotated.
33         /// </summary>
34         public static event RotaryEventHandler Rotated
35         {
36             add
37             {
38                 if (s_rotaryEventHandlers.ContainsKey(value)) return;
39
40                 Interop.Eext.Eext_Rotary_Handler_Cb cb = (data, infoPtr) =>
41                 {
42                     var info = Interop.Eext.FromIntPtr(infoPtr);
43                     value.Invoke(new RotaryEventArgs
44                     {
45                         IsClockwise = info.Direction == Interop.Eext.Eext_Rotary_Event_Direction.Clockwise,
46                         Timestamp = info.TimeStamp
47                     });
48                     return true;
49                 };
50                 Interop.Eext.eext_rotary_event_handler_add(cb, IntPtr.Zero);
51                 s_rotaryEventHandlers[value] = cb;
52             }
53
54             remove
55             {
56                 Interop.Eext.Eext_Rotary_Handler_Cb cb;
57                 if (s_rotaryEventHandlers.TryGetValue(value, out cb))
58                 {
59                     Interop.Eext.eext_rotary_event_handler_del(cb);
60                     s_rotaryEventHandlers.Remove(value);
61                 }
62             }
63         }
64     }
65
66
67     /// <summary>
68     /// RotaryEventManager serve extension functions for Rotary event to EvasObject on device like Galaxy Gear.
69     /// </summary>
70     public static class EvasObjectExtensions
71     {
72         static Dictionary<EvasObject, RotaryEventHandler> s_rotaryObjectEventHandlers = new Dictionary<EvasObject, RotaryEventHandler>();
73         static Dictionary<EvasObject, Interop.Eext.Eext_Rotary_Event_Cb> s_rotaryObjectEventMap = new Dictionary<EvasObject, Interop.Eext.Eext_Rotary_Event_Cb>();
74
75         /// <summary>
76         /// Add a handler for Rotary event on specific EvasObject.
77         /// </summary>
78         /// <param name="obj">Target EvasObject</param>
79         /// <param name="handler">Event handler for Rotary event</param>
80         public static void AddRotaryEventHandler(this EvasObject obj, RotaryEventHandler handler)
81         {
82             EnableRotaryEventHandler(obj);
83
84             if (s_rotaryObjectEventHandlers.ContainsKey(obj))
85             {
86                 s_rotaryObjectEventHandlers[obj] += handler;
87             }
88             else
89             {
90                 s_rotaryObjectEventHandlers[obj] = handler;
91             }
92         }
93
94         /// <summary>
95         /// Remove a handler on specific EvasObject for Rotary event.
96         /// </summary>
97         /// <param name="obj">Target EvasObject</param>
98         /// <param name="handler">Event handler for Rotary event</param>
99         public static void RemoveRotaryEventHandler(this EvasObject obj, RotaryEventHandler handler)
100         {
101             if (s_rotaryObjectEventHandlers.ContainsKey(obj))
102             {
103                 s_rotaryObjectEventHandlers[obj] -= handler;
104                 if (s_rotaryObjectEventHandlers[obj] == null)
105                 {
106                     DisableRotaryEventHandler(obj, false);
107                     s_rotaryObjectEventHandlers.Remove(obj);
108                 }
109             }
110         }
111
112         /// <summary>
113         /// Activate this object can take Rotary event.
114         /// </summary>
115         /// <param name="obj">Target object</param>
116         public static void Activate(this EvasObject obj)
117         {
118             Interop.Eext.eext_rotary_object_event_activated_set(obj, true);
119         }
120
121         /// <summary>
122         /// Deactivate this object is blocked from Rotary event.
123         /// </summary>
124         /// <param name="obj">Target object</param>
125         public static void Deactivate(this EvasObject obj)
126         {
127             Interop.Eext.eext_rotary_object_event_activated_set(obj, false);
128         }
129
130         static void EnableRotaryEventHandler(EvasObject obj)
131         {
132             if (!s_rotaryObjectEventMap.ContainsKey(obj))
133             {
134                 Interop.Eext.Eext_Rotary_Event_Cb cb = (d, o, i) =>
135                 {
136                     RotaryEventHandler events;
137                     if (s_rotaryObjectEventHandlers.TryGetValue(obj, out events))
138                     {
139                         var info = Interop.Eext.FromIntPtr(i);
140                         events?.Invoke(new RotaryEventArgs
141                         {
142                             IsClockwise = info.Direction == Interop.Eext.Eext_Rotary_Event_Direction.Clockwise,
143                             Timestamp = info.TimeStamp
144                         });
145                     }
146                     return true;
147                 };
148                 Interop.Eext.eext_rotary_object_event_callback_add(obj, cb, IntPtr.Zero);
149                 s_rotaryObjectEventMap[obj] = cb;
150                 obj.Deleted += (s, e) => DisableRotaryEventHandler(obj, true);
151             }
152         }
153
154         static void DisableRotaryEventHandler(EvasObject obj, bool removeHandler)
155         {
156             Interop.Eext.Eext_Rotary_Event_Cb cb;
157             if (s_rotaryObjectEventMap.TryGetValue(obj, out cb))
158             {
159                 Interop.Eext.eext_rotary_object_event_callback_del(obj, cb);
160                 s_rotaryObjectEventMap.Remove(obj);
161             }
162             if (removeHandler && s_rotaryObjectEventHandlers.ContainsKey(obj))
163             {
164                 s_rotaryObjectEventHandlers.Remove(obj);
165             }
166         }
167     }
168
169     /// <summary>
170     /// Handler for Rotary event
171     /// </summary>
172     /// <param name="args">Rotary event information</param>
173     public delegate void RotaryEventHandler(RotaryEventArgs args);
174
175     /// <summary>
176     /// RotaryEventArgs serve information for triggered rotary event.
177     /// </summary>
178     public class RotaryEventArgs : EventArgs
179     {
180         /// <summary>
181         /// IsClockwise is true when Rotary device rotated clockwise direction or false on counter clockwise.
182         /// </summary>
183         public bool IsClockwise { get; set; }
184
185         /// <summary>
186         /// Timestamp of rotary event
187         /// </summary>
188         public uint Timestamp { get; set; }
189     }
190 }