Merge remote-tracking branch 'uix-stt-engine/tizen'
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / EvasObjectEvent.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.ComponentModel;
20 using System.Linq;
21
22 namespace ElmSharp
23 {
24     /// <summary>
25     /// IInvalidatable is a interface which can be overrided by its children class.
26     /// Inherits IDisposable
27     /// </summary>
28     public interface IInvalidatable : IDisposable
29     {
30         void MakeInvalidate();
31     }
32
33     /// <summary>
34     /// Enumeration for EvasObjectCallbackType
35     /// </summary>
36     public enum EvasObjectCallbackType
37     {
38         /// <summary>
39         /// Mouse In Event CallbackType.
40         /// </summary>
41         MouseIn,
42
43         /// <summary>
44         /// Mouse Out Event CallbackType
45         /// </summary>
46         MouseOut,
47
48         /// <summary>
49         /// Mouse Button Down Event CallbackType
50         /// </summary>
51         MouseDown,
52
53         /// <summary>
54         /// Mouse Button Up Event CallbackType
55         /// </summary>
56         MouseUp,
57
58         /// <summary>
59         /// Mouse Move Event CallbackType
60         /// </summary>
61         MouseMove,
62
63         /// <summary>
64         /// Mouse Wheel Event CallbackType
65         /// </summary>
66         MouseWheel,
67
68         /// <summary>
69         /// Multi-touch Down Event CallbackType
70         /// </summary>
71         MultiDown,
72
73         /// <summary>
74         /// Multi-touch Up Event CallbackType
75         /// </summary>
76         MultiUp,
77
78         /// <summary>
79         /// Multi-touch Move Event CallbackType
80         /// </summary>
81         MultiMove,
82
83         /// <summary>
84         /// Object Being Freed (Called after Del)
85         /// </summary>
86         Free,
87
88         /// <summary>
89         /// Key Press Event CallbackType
90         /// </summary>
91         KeyDown,
92
93         /// <summary>
94         /// Key Release Event CallbackType
95         /// </summary>
96         KeyUp,
97
98         /// <summary>
99         /// Focus In Event CallbackType
100         /// </summary>
101         FocusIn,
102
103         /// <summary>
104         /// Focus Out Event CallbackType
105         /// </summary>
106         FocusOut,
107
108         /// <summary>
109         /// Show Event CallbackType
110         /// </summary>
111         Show,
112
113         /// <summary>
114         /// Hide Event CallbackType
115         /// </summary>
116         Hide,
117
118         /// <summary>
119         /// Move Event CallbackType
120         /// </summary>
121         Move,
122
123         /// <summary>
124         /// Resize Event CallbackType
125         /// </summary>
126         Resize,
127
128         /// <summary>
129         /// Restack Event CallbackType
130         /// </summary>
131         Restack,
132
133         /// <summary>
134         /// Object Being Deleted (called before Free)
135         /// </summary>
136         Del,
137
138         /// <summary>
139         /// Hold Event CallbackType, Informational purpose event to indicate something
140         /// </summary>
141         Hold,
142
143         /// <summary>
144         /// Size hints changed Event CallbackType
145         /// </summary>
146         ChangedSizeHints,
147
148         /// <summary>
149         /// Image has been preloaded
150         /// </summary>
151         ImagePreloaded,
152
153         /// <summary>
154         /// Canvas got focus as a whole
155         /// </summary>
156         CanvasFocusIn,
157
158         /// <summary>
159         /// Canvas lost focus as a whole
160         /// </summary>
161         CanvasFocusOut,
162
163         /// <summary>
164         /// Called just before rendering is updated on the canvas target
165         /// </summary>
166         RenderFlushPre,
167
168         /// <summary>
169         /// Called just after rendering is updated on the canvas target
170         /// </summary>
171         RenderFlushPost,
172
173         /// <summary>
174         /// Canvas object got focus
175         /// </summary>
176         CanvasObjectFocusIn,
177
178         /// <summary>
179         /// Canvas object lost focus
180         /// </summary>
181         CanvasObjectFocusOut,
182
183         /// <summary>
184         /// Image data has been unloaded (by some mechanism in Evas that throw out original image data)
185         /// </summary>
186         ImageUnloaded,
187
188         /// <summary>
189         /// Called just before rendering starts on the canvas target
190         /// </summary>
191         RenderPre,
192
193         /// <summary>
194         /// Called just after rendering stops on the canvas target
195         /// </summary>
196         RenderPost,
197
198         /// <summary>
199         /// Image size is changed
200         /// </summary>
201         ImageResize,
202
203         /// <summary>
204         /// Devices added, removed or changed on canvas
205         /// </summary>
206         DeviceChanged,
207
208         /// <summary>
209         /// Axis is changed
210         /// </summary>
211         AxisUpdate,
212
213         /// <summary>
214         /// Canvas Viewport size is changed
215         /// </summary>
216         CanvasViewportResize
217     }
218
219     /// <summary>
220     /// Event class for EvasObject
221     /// </summary>
222     /// <typeparam name="TEventArgs">Kinds of EventArgs</typeparam>
223     public class EvasObjectEvent<TEventArgs> : IInvalidatable where TEventArgs : EventArgs
224     {
225         /// <summary>
226         /// SmartEventInfoParser delegate of EvasObjectEvent class
227         /// </summary>
228         /// <param name="data">data</param>
229         /// <param name="obj">obj</param>
230         /// <param name="info">info</param>
231         /// <returns> delegate handle</returns>
232         public delegate TEventArgs SmartEventInfoParser(IntPtr data, IntPtr obj, IntPtr info);
233
234         private bool _disposed = false;
235         private EvasObject _sender;
236         private IntPtr _handle;
237         private readonly EvasObjectCallbackType _type;
238         private readonly SmartEventInfoParser _parser;
239         private readonly List<NativeCallback> _nativeCallbacks = new List<NativeCallback>();
240
241         /// <summary>
242         /// Creates and initializes a new instance of the EvasObjectEvent.
243         /// </summary>
244         /// <param name="sender">EvasObject class belong to</param>
245         /// <param name="type">EvasObjectCallbackType</param>
246         /// <param name="parser">SmartEventInfoParser</param>
247         public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type, SmartEventInfoParser parser) : this(sender, sender.Handle, type, parser)
248         {
249         }
250
251         [EditorBrowsableAttribute(EditorBrowsableState.Never)]
252         public EvasObjectEvent(EvasObject sender, IntPtr handle, EvasObjectCallbackType type, SmartEventInfoParser parser)
253         {
254             _sender = sender;
255             _handle = handle;
256             _type = type;
257             _parser = parser;
258             sender.AddToEventLifeTracker(this);
259         }
260
261         /// <summary>
262         /// Creates and initializes a new instance of the EvasObjectEvent.
263         /// </summary>
264         /// <param name="sender">EvasObject class belong with</param>
265         /// <param name="type">SmartEventInfoParser</param>
266         public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type) : this(sender, type, null)
267         {
268         }
269
270         ~EvasObjectEvent()
271         {
272             Dispose(false);
273         }
274
275         private struct NativeCallback
276         {
277             public Interop.Evas.EventCallback callback;
278             public EventHandler<TEventArgs> eventHandler;
279         }
280
281         /// <summary>
282         /// On Event Handler of EvasObjectEvent
283         /// </summary>
284         public event EventHandler<TEventArgs> On
285         {
286             add
287             {
288                 if (_handle == IntPtr.Zero)
289                 {
290                     return;
291                 }
292                 EventHandler<TEventArgs> handler = value;
293                 var cb = new Interop.Evas.EventCallback((data, evas, obj, info) =>
294                 {
295                     TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(data, obj, info);
296                     handler(_sender, ea);
297                 });
298                 _nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler });
299                 int i = _nativeCallbacks.Count - 1;
300                 Interop.Evas.evas_object_event_callback_add(_handle, (Interop.Evas.ObjectCallbackType)_type, _nativeCallbacks[i].callback, IntPtr.Zero);
301             }
302
303             remove
304             {
305                 if (_handle == IntPtr.Zero)
306                 {
307                     return;
308                 }
309                 EventHandler<TEventArgs> handler = value;
310                 var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
311                 foreach (var cb in callbacks)
312                 {
313                     Interop.Evas.evas_object_event_callback_del(_handle, (Interop.Evas.ObjectCallbackType)_type, cb.callback);
314                 }
315             }
316         }
317
318         protected virtual void Dispose(bool disposing)
319         {
320             if (!_disposed)
321             {
322                 if (disposing)
323                 {
324                     // Place holder to dispose managed state (managed objects).
325                 }
326                 if (_handle != IntPtr.Zero)
327                 {
328                     foreach (var cb in _nativeCallbacks)
329                     {
330                         Interop.Evas.evas_object_event_callback_del(_handle, (Interop.Evas.ObjectCallbackType)_type, cb.callback);
331                     }
332                 }
333                 _nativeCallbacks.Clear();
334                 _disposed = true;
335             }
336         }
337
338         /// <summary>
339         /// Destroy Current Obj
340         /// </summary>
341         public void Dispose()
342         {
343             Dispose(true);
344             GC.SuppressFinalize(this);
345         }
346
347         /// <summary>
348         /// Make current instance invalidate
349         /// </summary>
350         public void MakeInvalidate()
351         {
352             _sender = null;
353             _handle = IntPtr.Zero;
354         }
355     }
356
357     /// <summary>
358     /// Event class for EvasObject
359     /// </summary>
360     public class EvasObjectEvent : IInvalidatable
361     {
362         private EvasObjectEvent<EventArgs> _evasObjectEvent;
363
364         private event EventHandler _handlers;
365
366         private bool _disposed = false;
367
368         /// <summary>
369         /// Creates and initializes a new instance of the EvasObjectEvent.
370         /// </summary>
371         /// <param name="sender">EvasObject class belong to</param>
372         /// <param name="type">EvasObjectCallbackType</param>
373         public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type) : this(sender, sender.Handle, type)
374         {
375         }
376
377         [EditorBrowsableAttribute(EditorBrowsableState.Never)]
378         public EvasObjectEvent(EvasObject sender, IntPtr handle, EvasObjectCallbackType type)
379         {
380             _evasObjectEvent = new EvasObjectEvent<EventArgs>(sender, handle, type, null);
381         }
382
383         ~EvasObjectEvent()
384         {
385             Dispose(false);
386         }
387
388         /// <summary>
389         /// On Event Handler of EvasObjectEvent
390         /// </summary>
391         public event EventHandler On
392         {
393             add
394             {
395                 if (_handlers == null)
396                 {
397                     _evasObjectEvent.On += SendEvent;
398                 }
399                 _handlers += value;
400             }
401
402             remove
403             {
404                 _handlers -= value;
405                 if (_handlers == null)
406                 {
407                     _evasObjectEvent.On -= SendEvent;
408                 }
409             }
410         }
411
412         private void SendEvent(object sender, EventArgs e)
413         {
414             _handlers?.Invoke(sender, e);
415         }
416
417         protected virtual void Dispose(bool disposing)
418         {
419             if (!_disposed)
420             {
421                 if (disposing)
422                 {
423                     _evasObjectEvent.Dispose();
424                 }
425                 _disposed = true;
426             }
427         }
428
429         /// <summary>
430         /// Destroy Current Obj
431         /// </summary>
432         public void Dispose()
433         {
434             Dispose(true);
435             GC.SuppressFinalize(this);
436         }
437
438         /// <summary>
439         /// Make current instance invalidate
440         /// </summary>
441         public void MakeInvalidate()
442         {
443             _evasObjectEvent.MakeInvalidate();
444         }
445     }
446 }