Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Adaptor.cs
1 /** Copyright (c) 2017 Samsung Electronics Co., Ltd.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 */
16 using System;
17 using System.Runtime.InteropServices;
18
19 namespace Tizen.NUI
20 {
21     /// <summary>
22     /// An Adaptor object is used to initialize and control how Dali runs.
23     ///
24     /// It provides a lifecycle interface that allows the application
25     /// writer to provide their own main loop and other platform related
26     /// features.
27     ///
28     /// The Adaptor class provides a means for initialising the resources required by the Dali::Core.
29     ///
30     /// When dealing with platform events, the application writer MUST ensure that Dali is called in a
31     /// thread-safe manner.
32     ///
33     /// As soon as the Adaptor class is created and started, the application writer can initialise their
34     /// View objects straight away or as required by the main loop they intend to use (there is no
35     /// need to wait for an initialise signal as per the Tizen.NUI.Application class).
36     ///
37     /// </summary>
38     public class Adaptor : global::System.IDisposable
39     {
40         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
41         protected bool swigCMemOwn;
42
43         internal Adaptor(global::System.IntPtr cPtr, bool cMemoryOwn)
44         {
45             swigCMemOwn = cMemoryOwn;
46             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
47         }
48
49         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Adaptor obj)
50         {
51             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
52         }
53
54         //A Flag to check who called Dispose(). (By User or DisposeQueue)
55         private bool isDisposeQueued = false;
56         //A Flat to check if it is already disposed.
57         protected bool disposed = false;
58
59         ~Adaptor()
60         {
61             if (!isDisposeQueued)
62             {
63                 isDisposeQueued = true;
64                 DisposeQueue.Instance.Add(this);
65             }
66         }
67
68         public void Dispose()
69         {
70             //Throw excpetion if Dispose() is called in separate thread.
71             if (!Window.IsInstalled())
72             {
73                 throw new System.InvalidOperationException("This API called from separate thread. This API must be called from MainThread.");
74             }
75
76             if (isDisposeQueued)
77             {
78                 Dispose(DisposeTypes.Implicit);
79             }
80             else
81             {
82                 Dispose(DisposeTypes.Explicit);
83                 System.GC.SuppressFinalize(this);
84             }
85         }
86
87         protected virtual void Dispose(DisposeTypes type)
88         {
89             if (disposed)
90             {
91                 return;
92             }
93
94             if (type == DisposeTypes.Explicit)
95             {
96                 //Called by User
97                 //Release your own managed resources here.
98                 //You should release all of your own disposable objects here.
99
100             }
101
102             //Release your own unmanaged resources here.
103             //You should not access any managed member here except static instance.
104             //because the execution order of Finalizes is non-deterministic.
105
106             if (swigCPtr.Handle != global::System.IntPtr.Zero)
107             {
108                 swigCMemOwn = false;
109                 NDalicManualPINVOKE.delete_Adaptor(swigCPtr);
110                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
111             }
112
113             disposed = true;
114         }
115
116         internal static Adaptor GetAdaptorFromPtr(global::System.IntPtr cPtr)
117         {
118             Adaptor ret = new Adaptor(cPtr, false);
119             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
120             return ret;
121         }
122
123         internal static Adaptor New(Window window)
124         {
125             Adaptor ret = new Adaptor(NDalicManualPINVOKE.Adaptor_New__SWIG_0(Window.getCPtr(window)), false);
126             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
127             return ret;
128         }
129
130         internal static Adaptor New(Window window, SWIGTYPE_p_Configuration__ContextLoss configuration)
131         {
132             Adaptor ret = new Adaptor(NDalicManualPINVOKE.Adaptor_New__SWIG_1(Window.getCPtr(window), SWIGTYPE_p_Configuration__ContextLoss.getCPtr(configuration)), false);
133             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
134             return ret;
135         }
136
137         internal static Adaptor New(Any nativeWindow, SWIGTYPE_p_Dali__RenderSurface surface)
138         {
139             Adaptor ret = new Adaptor(NDalicManualPINVOKE.Adaptor_New__SWIG_2(Any.getCPtr(nativeWindow), SWIGTYPE_p_Dali__RenderSurface.getCPtr(surface)), false);
140             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
141             return ret;
142         }
143
144         internal static Adaptor New(Any nativeWindow, SWIGTYPE_p_Dali__RenderSurface surface, SWIGTYPE_p_Configuration__ContextLoss configuration)
145         {
146             Adaptor ret = new Adaptor(NDalicManualPINVOKE.Adaptor_New__SWIG_3(Any.getCPtr(nativeWindow), SWIGTYPE_p_Dali__RenderSurface.getCPtr(surface), SWIGTYPE_p_Configuration__ContextLoss.getCPtr(configuration)), false);
147             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
148             return ret;
149         }
150
151         /// <summary>
152         /// Starts the Adaptor.
153         /// </summary>
154         internal void Start()
155         {
156             NDalicManualPINVOKE.Adaptor_Start(swigCPtr);
157             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
158         }
159
160         /// <summary>
161         /// Pauses the Adaptor.
162         /// </summary>
163         internal void Pause()
164         {
165             NDalicManualPINVOKE.Adaptor_Pause(swigCPtr);
166             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
167         }
168
169         /// <summary>
170         /// Resumes the Adaptor, if previously paused.
171         /// </summary>
172         /// <remarks>If the adaptor is not paused, this does not do anything.</remarks>
173         internal void Resume()
174         {
175             NDalicManualPINVOKE.Adaptor_Resume(swigCPtr);
176             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
177         }
178
179         /// <summary>
180         /// Stops the Adaptor.
181         /// </summary>
182         internal void Stop()
183         {
184             NDalicManualPINVOKE.Adaptor_Stop(swigCPtr);
185             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
186         }
187
188         internal bool AddIdle(SWIGTYPE_p_Dali__CallbackBase callback)
189         {
190             bool ret = NDalicManualPINVOKE.Adaptor_AddIdle(swigCPtr, SWIGTYPE_p_Dali__CallbackBase.getCPtr(callback));
191             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
192             return ret;
193         }
194
195         internal void RemoveIdle(SWIGTYPE_p_Dali__CallbackBase callback)
196         {
197             NDalicManualPINVOKE.Adaptor_RemoveIdle(swigCPtr, SWIGTYPE_p_Dali__CallbackBase.getCPtr(callback));
198             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
199         }
200
201         internal void ReplaceSurface(Any nativeWindow, SWIGTYPE_p_Dali__RenderSurface surface)
202         {
203             NDalicManualPINVOKE.Adaptor_ReplaceSurface(swigCPtr, Any.getCPtr(nativeWindow), SWIGTYPE_p_Dali__RenderSurface.getCPtr(surface));
204             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
205         }
206
207         internal SWIGTYPE_p_Dali__RenderSurface GetSurface()
208         {
209             SWIGTYPE_p_Dali__RenderSurface ret = new SWIGTYPE_p_Dali__RenderSurface(NDalicManualPINVOKE.Adaptor_GetSurface(swigCPtr), false);
210             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
211             return ret;
212         }
213
214         internal Any GetNativeWindowHandle()
215         {
216             Any ret = new Any(NDalicManualPINVOKE.Adaptor_GetNativeWindowHandle(swigCPtr), true);
217             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
218             return ret;
219         }
220
221         /// <summary>
222         /// Release any locks the surface may hold.
223         /// </summary>
224         /// <remarks>
225         /// For example, after compositing an offscreen surface, use this method to allow rendering to continue.
226         /// </remarks>
227         internal void ReleaseSurfaceLock()
228         {
229             NDalicManualPINVOKE.Adaptor_ReleaseSurfaceLock(swigCPtr);
230             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
231         }
232
233         /// <summary>
234         /// Set the number of frames per render.
235         /// </summary>
236         /// <param name="numberOfVSyncsPerRender">The number of vsyncs between successive renders.. </param>
237         /// <remarks>
238         /// Suggest this is a power of two:
239         /// 1 - render each vsync frame
240         /// 2 - render every other vsync frame
241         /// 4 - render every fourth vsync frame
242         /// 8 - render every eighth vsync frame
243         ///</remarks>
244         internal void SetRenderRefreshRate(uint numberOfVSyncsPerRender)
245         {
246             NDalicManualPINVOKE.Adaptor_SetRenderRefreshRate(swigCPtr, numberOfVSyncsPerRender);
247             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
248         }
249
250         /// <summary>
251         /// Set whether the frame count per render is managed using the hardware VSync or manually timed.
252         /// </summary>
253         /// <param name="useHardware">True if the hardware VSync should be used. </param>
254         internal void SetUseHardwareVSync(bool useHardware)
255         {
256             NDalicManualPINVOKE.Adaptor_SetUseHardwareVSync(swigCPtr, useHardware);
257             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
258         }
259
260         private static readonly Adaptor instance = Adaptor.Get();
261
262         internal static Adaptor Get()
263         {
264             Adaptor ret = new Adaptor(NDalicManualPINVOKE.Adaptor_Get(), false);
265             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
266             return ret;
267         }
268
269         /// <summary>
270         /// Returns a reference to the instance of the adaptor used by the current thread.
271         /// </summary>
272         /// <remarks>The adaptor has been initialised.This is only valid in the main thread.</remarks>
273         public static Adaptor Instance
274         {
275             get
276             {
277                 return instance;
278             }
279         }
280
281         /// <summary>
282         /// Checks whether the adaptor is available.
283         /// </summary>
284         /// <returns>true, if it is available, false otherwise.</returns>
285         internal static bool IsAvailable()
286         {
287             bool ret = NDalicManualPINVOKE.Adaptor_IsAvailable();
288             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
289             return ret;
290         }
291
292         /// <summary>
293         /// Call this method to notify Dali when scene is created and initialized.
294         /// Notify Adaptor that the scene has been created.
295         /// </summary>
296         internal void NotifySceneCreated()
297         {
298             NDalicManualPINVOKE.Adaptor_NotifySceneCreated(swigCPtr);
299             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
300         }
301
302         /// <summary>
303         /// Call this method to notify Dali when the system language changes.
304         ///
305         /// Use this only when NOT using Dali::Application, As Application created using
306         /// Application will automatically receive notification of language change.
307         /// When Dali::Application is not used, the application developer should
308         /// use app-core to receive language change notifications and should update Dali
309         /// by calling this method.
310         /// </summary>
311         internal void NotifyLanguageChanged()
312         {
313             NDalicManualPINVOKE.Adaptor_NotifyLanguageChanged(swigCPtr);
314             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
315         }
316
317         /// <summary>
318         /// Sets minimum distance in pixels that the fingers must move towards/away from each other in order to trigger a pinch gesture.
319         /// </summary>
320         /// <param name="distance">The minimum pinch distance in pixels. </param>
321         internal void SetMinimumPinchDistance(float distance)
322         {
323             NDalicManualPINVOKE.Adaptor_SetMinimumPinchDistance(swigCPtr, distance);
324             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
325         }
326
327         internal void FeedTouchPoint(TouchPoint point, int timeStamp)
328         {
329             NDalicManualPINVOKE.Adaptor_FeedTouchPoint(swigCPtr, TouchPoint.getCPtr(point), timeStamp);
330             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
331         }
332
333         /// <summary>
334         /// Feed a wheel event to the adaptor.
335         /// </summary>
336         /// <param name="wheelEvent">wheel event. </param>
337         public void FeedWheelEvent(Wheel wheelEvent)
338         {
339             NDalicManualPINVOKE.Adaptor_FeedWheelEvent(swigCPtr, Wheel.getCPtr(wheelEvent));
340             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
341         }
342
343         /// <summary>
344         /// Feed a key event to the adaptor.
345         /// </summary>
346         /// <param name="keyEvent">The key event holding the key information. </param>
347         public void FeedKeyEvent(Key keyEvent)
348         {
349             NDalicManualPINVOKE.Adaptor_FeedKeyEvent(swigCPtr, Key.getCPtr(keyEvent));
350             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
351         }
352
353         /// <summary>
354         /// Notify Core that the scene has been created.
355         /// </summary>
356         internal void SceneCreated()
357         {
358             NDalicManualPINVOKE.Adaptor_SceneCreated(swigCPtr);
359             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
360         }
361
362         internal void SetViewMode(ViewMode viewMode)
363         {
364             NDalicManualPINVOKE.Adaptor_SetViewMode(swigCPtr, (int)viewMode);
365             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
366         }
367
368         /// <summary>
369         /// Sets the stereo base (eye separation) for Stereoscopic 3D.
370         /// The stereo base is the distance in millimetres between the eyes. Typical values are
371         /// between 50mm and 70mm. The default value is 65mm.
372         /// </summary>
373         /// <param name="stereoBase">The stereo base (eye separation) for Stereoscopic 3D.</param>
374         internal void SetStereoBase(float stereoBase)
375         {
376             NDalicManualPINVOKE.Adaptor_SetStereoBase(swigCPtr, stereoBase);
377             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
378         }
379
380         /// <summary>
381         /// Event arguments that passed via Resized signal.
382         /// </summary>
383         internal class ResizedEventArgs : EventArgs
384         {
385
386             /// <summary>
387             /// Adaptor - is the adaptor which has size changed.
388             /// </summary>
389             public Adaptor Adaptor
390             {
391                 get;
392                 set;
393             }
394         }
395
396         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
397         private delegate void ResizedCallbackDelegate(IntPtr adaptor);
398         private EventHandler<ResizedEventArgs> _resizedEventHandler;
399         private ResizedCallbackDelegate _resizedCallbackDelegate;
400
401         /// <summary>
402         /// Event for Resized signal which can be used to subscribe/unsubscribe the event handler
403         /// provided by the user. Resized signal is emitted when the size changes.<br>
404         /// </summary>
405         internal event EventHandler<ResizedEventArgs> Resized
406         {
407             add
408             {
409                 if (_resizedEventHandler == null)
410                 {
411                     _resizedCallbackDelegate = (OnResized);
412                     ResizedSignal().Connect(_resizedCallbackDelegate);
413                 }
414                 _resizedEventHandler += value;
415             }
416             remove
417             {
418                 _resizedEventHandler -= value;
419                 if (_resizedEventHandler == null && ResizedSignal().Empty() == false)
420                 {
421                     ResizedSignal().Disconnect(_resizedCallbackDelegate);
422                 }
423             }
424         }
425
426         private void OnResized(IntPtr adaptor)
427         {
428             ResizedEventArgs e = new ResizedEventArgs();
429             if (adaptor != null)
430             {
431                 e.Adaptor = Adaptor.GetAdaptorFromPtr(adaptor);
432             }
433
434             if (_resizedEventHandler != null)
435             {
436                 //here we send all data to user event handlers
437                 _resizedEventHandler(this, e);
438             }
439         }
440
441         internal AdaptorSignalType ResizedSignal()
442         {
443             AdaptorSignalType ret = new AdaptorSignalType(NDalicManualPINVOKE.Adaptor_ResizedSignal(swigCPtr), false);
444             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
445             return ret;
446         }
447
448         /// <summary>
449         /// Event arguments that passed via LanguageChanged signal.
450         /// </summary>
451         internal class LanguageChangedEventArgs : EventArgs
452         {
453
454             /// <summary>
455             /// Adaptor - is the adaptor which has language changed.
456             /// </summary>
457             public Adaptor Adaptor
458             {
459                 get;
460                 set;
461             }
462         }
463
464         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
465         private delegate void LanguageChangedCallbackDelegate(IntPtr adaptor);
466         private EventHandler<LanguageChangedEventArgs> _languageChangedEventHandler;
467         private LanguageChangedCallbackDelegate _languageChangedCallbackDelegate;
468
469         /// <summary>
470         /// Event for LanguageChanged signal which can be used to subscribe/unsubscribe the event handler
471         /// provided by the user. LanguageChanged signal is emitted when the language changes.<br>
472         /// </summary>
473         internal event EventHandler<LanguageChangedEventArgs> LanguageChanged
474         {
475             add
476             {
477                 if (_languageChangedEventHandler == null)
478                 {
479                     _languageChangedCallbackDelegate = (OnLanguageChanged);
480                     LanguageChangedSignal().Connect(_languageChangedCallbackDelegate);
481                 }
482                 _languageChangedEventHandler += value;
483             }
484             remove
485             {
486                 _languageChangedEventHandler -= value;
487                 if (_languageChangedEventHandler == null && LanguageChangedSignal().Empty() == false)
488                 {
489                     LanguageChangedSignal().Disconnect(_languageChangedCallbackDelegate);
490                 }
491             }
492         }
493
494         private void OnLanguageChanged(IntPtr adaptor)
495         {
496             LanguageChangedEventArgs e = new LanguageChangedEventArgs();
497             if (adaptor != null)
498             {
499                 e.Adaptor = Adaptor.GetAdaptorFromPtr(adaptor);
500             }
501
502             if (_languageChangedEventHandler != null)
503             {
504                 //here we send all data to user event handlers
505                 _languageChangedEventHandler(this, e);
506             }
507         }
508
509         internal AdaptorSignalType LanguageChangedSignal()
510         {
511             AdaptorSignalType ret = new AdaptorSignalType(NDalicManualPINVOKE.Adaptor_LanguageChangedSignal(swigCPtr), false);
512             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
513             return ret;
514         }
515
516     }
517
518 }