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