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