Merge remote-tracking branch 'origin/master' into tizen
[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     /// <since_tizen> preview </since_tizen>
28     public static class RotaryEventManager
29     {
30         static Dictionary<RotaryEventHandler, Interop.Eext.Eext_Rotary_Handler_Cb> s_rotaryEventHandlers = new Dictionary<RotaryEventHandler, Interop.Eext.Eext_Rotary_Handler_Cb>();
31
32         /// <summary>
33         /// Rotated will triggered when rotatable device like Galaxy Gear Bezel is rotated.
34         /// </summary>
35         /// <since_tizen> preview </since_tizen>
36         public static event RotaryEventHandler Rotated
37         {
38             add
39             {
40                 if (s_rotaryEventHandlers.ContainsKey(value)) return;
41
42                 Interop.Eext.Eext_Rotary_Handler_Cb cb = (data, infoPtr) =>
43                 {
44                     var info = Interop.Eext.FromIntPtr(infoPtr);
45                     value.Invoke(new RotaryEventArgs
46                     {
47                         IsClockwise = info.Direction == Interop.Eext.Eext_Rotary_Event_Direction.Clockwise,
48                         Timestamp = info.TimeStamp
49                     });
50                     return true;
51                 };
52                 Interop.Eext.eext_rotary_event_handler_add(cb, IntPtr.Zero);
53                 s_rotaryEventHandlers[value] = cb;
54             }
55
56             remove
57             {
58                 Interop.Eext.Eext_Rotary_Handler_Cb cb;
59                 if (s_rotaryEventHandlers.TryGetValue(value, out cb))
60                 {
61                     Interop.Eext.eext_rotary_event_handler_del(cb);
62                     s_rotaryEventHandlers.Remove(value);
63                 }
64             }
65         }
66     }
67
68
69     /// <summary>
70     /// RotaryEventManager serve extension functions for Rotary event to EvasObject on device like Galaxy Gear.
71     /// </summary>
72     /// <since_tizen> preview </since_tizen>
73     public static class RotaryEventExtensions
74     {
75         static Dictionary<EvasObject, RotaryEventHandler> s_rotaryObjectEventHandlers = new Dictionary<EvasObject, RotaryEventHandler>();
76         static Dictionary<EvasObject, Interop.Eext.Eext_Rotary_Event_Cb> s_rotaryObjectEventMap = new Dictionary<EvasObject, Interop.Eext.Eext_Rotary_Event_Cb>();
77
78         /// <summary>
79         /// Add a handler for Rotary event on specific EvasObject.
80         /// </summary>
81         /// <param name="obj">Target EvasObject</param>
82         /// <param name="handler">Event handler for Rotary event</param>
83         /// <since_tizen> preview </since_tizen>
84         public static void AddRotaryEventHandler(this EvasObject obj, RotaryEventHandler handler)
85         {
86             EnableRotaryEventHandler(obj);
87
88             if (s_rotaryObjectEventHandlers.ContainsKey(obj))
89             {
90                 s_rotaryObjectEventHandlers[obj] += handler;
91             }
92             else
93             {
94                 s_rotaryObjectEventHandlers[obj] = handler;
95             }
96         }
97
98         /// <summary>
99         /// Remove a handler on specific EvasObject for Rotary event.
100         /// </summary>
101         /// <param name="obj">Target EvasObject</param>
102         /// <param name="handler">Event handler for Rotary event</param>
103         /// <since_tizen> preview </since_tizen>
104         public static void RemoveRotaryEventHandler(this EvasObject obj, RotaryEventHandler handler)
105         {
106             if (s_rotaryObjectEventHandlers.ContainsKey(obj))
107             {
108                 s_rotaryObjectEventHandlers[obj] -= handler;
109                 if (s_rotaryObjectEventHandlers[obj] == null)
110                 {
111                     DisableRotaryEventHandler(obj, false);
112                     s_rotaryObjectEventHandlers.Remove(obj);
113                 }
114             }
115         }
116
117         /// <summary>
118         /// Activate this circle widget can take Rotary event.
119         /// </summary>
120         /// <param name="widget">Target circle widget</param>
121         /// <since_tizen> preview </since_tizen>
122         public static void Activate(this IRotaryActionWidget widget)
123         {
124             Interop.Eext.eext_rotary_object_event_activated_set(widget.CircleHandle, true);
125         }
126
127         /// <summary>
128         /// Deactivate this circle widget is blocked from Rotary event.
129         /// </summary>
130         /// <param name="widget">Target circle widget</param>
131         /// <since_tizen> preview </since_tizen>
132         public static void Deactivate(this IRotaryActionWidget widget)
133         {
134             Interop.Eext.eext_rotary_object_event_activated_set(widget.CircleHandle, false);
135         }
136
137         /// <summary>
138         /// Activate this object can take Rotary event.
139         /// </summary>
140         /// <param name="obj">Target object</param>
141         /// <since_tizen> preview </since_tizen>
142         public static void Activate(this EvasObject obj)
143         {
144             Interop.Eext.eext_rotary_object_event_activated_set(obj, true);
145         }
146
147         /// <summary>
148         /// Deactivate this object is blocked from Rotary event.
149         /// </summary>
150         /// <param name="obj">Target object</param>
151         /// <since_tizen> preview </since_tizen>
152         public static void Deactivate(this EvasObject obj)
153         {
154             Interop.Eext.eext_rotary_object_event_activated_set(obj, false);
155         }
156
157         static void EnableRotaryEventHandler(EvasObject obj)
158         {
159             if (!s_rotaryObjectEventMap.ContainsKey(obj))
160             {
161                 Interop.Eext.Eext_Rotary_Event_Cb cb = (d, o, i) =>
162                 {
163                     RotaryEventHandler events;
164                     if (s_rotaryObjectEventHandlers.TryGetValue(obj, out events))
165                     {
166                         var info = Interop.Eext.FromIntPtr(i);
167                         events?.Invoke(new RotaryEventArgs
168                         {
169                             IsClockwise = info.Direction == Interop.Eext.Eext_Rotary_Event_Direction.Clockwise,
170                             Timestamp = info.TimeStamp
171                         });
172                     }
173                     return true;
174                 };
175                 Interop.Eext.eext_rotary_object_event_callback_add(obj, cb, IntPtr.Zero);
176                 s_rotaryObjectEventMap[obj] = cb;
177                 obj.Deleted += (s, e) => DisableRotaryEventHandler(obj, true);
178             }
179         }
180
181         static void DisableRotaryEventHandler(EvasObject obj, bool removeHandler)
182         {
183             Interop.Eext.Eext_Rotary_Event_Cb cb;
184             if (s_rotaryObjectEventMap.TryGetValue(obj, out cb))
185             {
186                 Interop.Eext.eext_rotary_object_event_callback_del(obj, cb);
187                 s_rotaryObjectEventMap.Remove(obj);
188             }
189             if (removeHandler && s_rotaryObjectEventHandlers.ContainsKey(obj))
190             {
191                 s_rotaryObjectEventHandlers.Remove(obj);
192             }
193         }
194     }
195
196     /// <summary>
197     /// Handler for Rotary event
198     /// </summary>
199     /// <param name="args">Rotary event information</param>
200     /// <since_tizen> preview </since_tizen>
201     public delegate void RotaryEventHandler(RotaryEventArgs args);
202
203     /// <summary>
204     /// RotaryEventArgs serve information for triggered rotary event.
205     /// </summary>
206     /// <since_tizen> preview </since_tizen>
207     public class RotaryEventArgs : EventArgs
208     {
209         /// <summary>
210         /// IsClockwise is true when Rotary device rotated clockwise direction or false on counter clockwise.
211         /// </summary>
212         /// <since_tizen> preview </since_tizen>
213         public bool IsClockwise { get; set; }
214
215         /// <summary>
216         /// Timestamp of rotary event
217         /// </summary>
218         /// <since_tizen> preview </since_tizen>
219         public uint Timestamp { get; set; }
220     }
221 }