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