[NUI] Support Device orientation and window orientation event.
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Application / NUICoreBackend.cs
1 /*
2  * Copyright (c) 2018 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
18 using System;
19 using System.ComponentModel;
20 using System.Collections.Generic;
21 using Tizen.Applications.CoreBackend;
22 using Tizen.Applications;
23
24 namespace Tizen.NUI
25 {
26     class NUICoreBackend : ICoreTaskBackend
27     {
28         /// <summary>
29         /// The Application instance to connect event.
30         /// </summary>
31         protected Application application;
32         private string stylesheet = "";
33         private NUIApplication.WindowMode windowMode = NUIApplication.WindowMode.Opaque;
34         private Rectangle windowRectangle = null;
35         private WindowType defaultWindowType = WindowType.Normal;
36         private ICoreTask coreTask;
37
38         /// <summary>
39         /// The Dictionary to contain each type of event callback.
40         /// </summary>
41         protected IDictionary<EventType, object> Handlers = new Dictionary<EventType, object>();
42         protected IDictionary<EventType, object> TaskHandlers = new Dictionary<EventType, object>();
43
44         /// <summary>
45         /// The default Constructor.
46         /// </summary>
47         public NUICoreBackend()
48         {
49         }
50
51         /// <summary>
52         /// The constructor with stylesheet.
53         /// </summary>
54         public NUICoreBackend(string stylesheet)
55         {
56             this.stylesheet = stylesheet;
57         }
58
59         /// <summary>
60         /// The constructor with stylesheet and window mode.
61         /// </summary>
62         public NUICoreBackend(string stylesheet, NUIApplication.WindowMode windowMode)
63         {
64             this.stylesheet = stylesheet;
65             this.windowMode = windowMode;
66         }
67
68         /// <summary>
69         /// The constructor with stylesheet, window mode, window size and window position.
70         /// </summary>
71         public NUICoreBackend(string stylesheet, NUIApplication.WindowMode windowMode, Size2D windowSize, Position2D windowPosition)
72         {
73             this.stylesheet = stylesheet;
74             this.windowMode = windowMode;
75             if (windowSize != null && windowPosition != null)
76             {
77                 this.windowRectangle = new Rectangle(windowPosition.X, windowPosition.Y, windowSize.Width, windowSize.Height);
78             }
79         }
80
81         /// <summary>
82         /// The constructor with stylesheet, window mode, window size, window position and default window type.
83         /// This will be hidden as inhouse API. Because it is only for internal IME window.
84         /// </summary>
85         [EditorBrowsable(EditorBrowsableState.Never)]
86         public NUICoreBackend(string stylesheet, NUIApplication.WindowMode windowMode, WindowType type)
87         {
88             this.stylesheet = stylesheet;
89             this.windowMode = windowMode;
90             this.defaultWindowType = type;
91         }
92
93         /// <summary>
94         /// Adds NUIApplication event to Application.
95         /// Puts each type of event callback in Dictionary.
96         /// </summary>
97         /// <param name="evType">The type of event.</param>
98         /// <param name="handler">The event callback.</param>
99         public void AddEventHandler(EventType evType, Action handler)
100         {
101             Handlers.Add(evType, handler);
102         }
103
104         /// <summary>
105         /// Adds NUIApplication event to Application.
106         /// Puts each type of event callback in Dictionary.
107         /// </summary>
108         /// <typeparam name="TEventArgs">The argument type for the event.</typeparam>
109         /// <param name="evType">The type of event.</param>
110         /// <param name="handler">The event callback.</param>
111         public void AddEventHandler<TEventArgs>(EventType evType, Action<TEventArgs> handler) where TEventArgs : EventArgs
112         {
113             Handlers.Add(evType, handler);
114         }
115
116         /// <summary>
117         /// The Dispose function.
118         /// </summary>
119         public void Dispose()
120         {
121             if (application != null)
122             {
123                 application.Dispose();
124             }
125             if (windowRectangle != null)
126             {
127                 windowRectangle.Dispose();
128             }
129         }
130
131         /// <summary>
132         /// The Exit application.
133         /// </summary>
134         public void Exit()
135         {
136             if (application != null)
137             {
138                 application.Quit();
139             }
140         }
141
142         /// <summary>
143         /// Ensures that the function passed in is called from the main loop when it is idle.
144         /// </summary>
145         /// <param name="func">The function to call</param>
146         /// <returns>true if added successfully, false otherwise</returns>
147         public bool AddIdle(System.Delegate func)
148         {
149             return application.AddIdle(func);
150         }
151
152         /// <summary>
153         /// The Run application.
154         /// </summary>
155         /// <param name="args">The arguments from commandline.</param>
156         public void Run(string[] args)
157         {
158             Tizen.Tracer.Begin("[NUI] NUICorebackend Run()");
159
160             Tizen.Tracer.Begin("[NUI] NUICorebackend Run(): TizenSynchronizationContext.Initialize() called");
161             TizenSynchronizationContext.Initialize();
162             Tizen.Tracer.End();
163
164             Tizen.Tracer.Begin("[NUI] NUICorebackend Run(): args of main set, window type set");
165             if (Tizen.Applications.Application.Current?.ApplicationInfo != null)
166             {
167                 args[0] = Tizen.Applications.Application.Current.ApplicationInfo.ExecutablePath;
168             }
169             if (string.IsNullOrEmpty(args[0]))
170             {
171                 args[0] = this.GetType().Assembly.FullName.Replace(" ", "");
172             }
173
174             if (defaultWindowType != WindowType.Normal)
175             {
176                 application = Application.NewApplication(stylesheet, windowMode, defaultWindowType);
177             }
178             else
179             {
180                 if (windowRectangle != null)
181                 {
182                     if (coreTask != null)
183                     {
184                         application = Application.NewApplication(args, stylesheet, windowMode, windowRectangle, true);
185                     }
186                     else
187                     {
188                         application = Application.NewApplication(args, stylesheet, windowMode, windowRectangle);
189                     }
190                 }
191                 else
192                 {
193                     if (coreTask != null)
194                     {
195                         // The Rectangle(0, 0, 0, 0) means that want to use the full screen size window at 0,0.
196                         using (Rectangle rec = new Rectangle(0, 0, 0, 0))
197                         {
198                             application = Application.NewApplication(args, stylesheet, windowMode, rec, true);
199                         }
200                     }
201                     else
202                     {
203                         application = Application.NewApplication(args, stylesheet, windowMode);
204                     }
205                 }
206             }
207             Tizen.Tracer.End();
208
209             Tizen.Tracer.Begin("[NUI] NUICorebackend Run(): add application related events");
210             application.BatteryLow += OnBatteryLow;
211             application.LanguageChanged += OnLanguageChanged;
212             application.MemoryLow += OnMemoryLow;
213             application.RegionChanged += OnRegionChanged;
214             application.DeviceOrientationChanged += OnDeviceOrientationChanged;
215
216             application.Initialized += OnInitialized;
217             application.Resumed += OnResumed;
218             application.Terminating += OnTerminated;
219             application.Paused += OnPaused;
220             application.AppControl += OnAppControl;
221             Tizen.Tracer.End();
222
223             Tizen.Tracer.End();
224
225             if (coreTask != null)
226             {
227                 application.TaskBatteryLow += OnTaskBatteryLow;
228                 application.TaskLanguageChanged += OnTaskLanguageChanged;
229                 application.TaskMemoryLow += OnTaskMemoryLow;
230                 application.TaskRegionChanged += OnTaskRegionChanged;
231                 application.TaskDeviceOrientationChanged += OnTaskDeviceOrientationChanged;
232
233                 application.TaskInitialized += OnTaskInitialized;
234                 application.TaskTerminating += OnTaskTerminated;
235                 application.TaskAppControl += OnTaskAppControl;
236                 // Note: UIEvent, DeviceOrientationChanged are not implemented.
237             }
238
239             application.MainLoop();
240             application.Dispose();
241         }
242
243         /// <summary>
244         /// Sets the core task.
245         /// </summary>
246         /// <param name="task">The core task interface.</param>
247         /// <since_tizen> 10 </since_tizen>
248         public void SetCoreTask(ICoreTask task)
249         {
250             coreTask = task;
251         }
252
253         /// <summary>
254         /// The Region changed event callback function.
255         /// </summary>
256         /// <param name="source">The application instance.</param>
257         /// <param name="e">The event argument for RegionChanged.</param>
258         private void OnRegionChanged(object source, NUIApplicationRegionChangedEventArgs e)
259         {
260             Log.Info("NUI", "NUICorebackend OnRegionChanged Called");
261             var handler = Handlers[EventType.RegionFormatChanged] as Action<RegionFormatChangedEventArgs>;
262             handler?.Invoke(new RegionFormatChangedEventArgs((source as Application)?.GetRegion()));
263         }
264
265         /// <summary>
266         /// The Memory Low event callback function.
267         /// </summary>
268         /// <param name="source">The application instance.</param>
269         /// <param name="e">The event argument for MemoryLow.</param>
270         private void OnMemoryLow(object source, NUIApplicationMemoryLowEventArgs e)
271         {
272             Log.Info("NUI", "NUICorebackend OnMemoryLow Called");
273             var handler = Handlers[EventType.LowMemory] as Action<LowMemoryEventArgs>;
274
275             switch (e.MemoryStatus)
276             {
277                 case Application.MemoryStatus.Normal:
278                     {
279                         handler?.Invoke(new LowMemoryEventArgs(LowMemoryStatus.None));
280                         break;
281                     }
282                 case Application.MemoryStatus.Low:
283                     {
284                         handler?.Invoke(new LowMemoryEventArgs(LowMemoryStatus.SoftWarning));
285                         break;
286                     }
287                 case Application.MemoryStatus.CriticallyLow:
288                     {
289                         handler?.Invoke(new LowMemoryEventArgs(LowMemoryStatus.HardWarning));
290                         break;
291                     }
292             }
293         }
294
295         /// <summary>
296         /// The Language changed event callback function.
297         /// </summary>
298         /// <param name="source">The application instance.</param>
299         /// <param name="e">The event argument for LanguageChanged.</param>
300         private void OnLanguageChanged(object source, NUIApplicationLanguageChangedEventArgs e)
301         {
302             Log.Info("NUI", "NUICorebackend OnLanguageChanged Called");
303             var handler = Handlers[EventType.LocaleChanged] as Action<LocaleChangedEventArgs>;
304             handler?.Invoke(new LocaleChangedEventArgs((source as Application)?.GetLanguage()));
305         }
306
307         /// <summary>
308         /// The Battery Low event callback function.
309         /// </summary>
310         /// <param name="source">The application instance.</param>
311         /// <param name="e">The event argument for BatteryLow.</param>
312         private void OnBatteryLow(object source, NUIApplicationBatteryLowEventArgs e)
313         {
314             Log.Info("NUI", "NUICorebackend OnBatteryLow Called");
315             var handler = Handlers[EventType.LowBattery] as Action<LowBatteryEventArgs>;
316             switch (e.BatteryStatus)
317             {
318                 case Application.BatteryStatus.Normal:
319                     {
320                         handler?.Invoke(new LowBatteryEventArgs(LowBatteryStatus.None));
321                         break;
322                     }
323                 case Application.BatteryStatus.CriticallyLow:
324                     {
325                         handler?.Invoke(new LowBatteryEventArgs(LowBatteryStatus.CriticalLow));
326                         break;
327                     }
328                 case Application.BatteryStatus.PowerOff:
329                     {
330                         handler?.Invoke(new LowBatteryEventArgs(LowBatteryStatus.PowerOff));
331                         break;
332                     }
333             }
334         }
335
336         /// <summary>
337         /// The Device Orientation changed event callback function.
338         /// </summary>
339         /// <param name="source">The application instance.</param>
340         /// <param name="e">The event argument for DeviceOrientationChanged.</param>
341         private void OnDeviceOrientationChanged(object source, NUIApplicationDeviceOrientationChangedEventArgs e)
342         {
343             Log.Info("NUI", "NUICorebackend OnDeviceOrientationChanged Called");
344             var handler = Handlers[EventType.DeviceOrientationChanged] as Action<DeviceOrientationEventArgs>;
345
346             switch (e.DeviceOrientationStatus)
347             {
348                 case Application.DeviceOrientationStatus.Orientation_0:
349                     {
350                         handler?.Invoke(new DeviceOrientationEventArgs(DeviceOrientation.Orientation_0));
351                         break;
352                     }
353                 case Application.DeviceOrientationStatus.Orientation_90:
354                     {
355                         handler?.Invoke(new DeviceOrientationEventArgs(DeviceOrientation.Orientation_90));
356                         break;
357                     }
358                 case Application.DeviceOrientationStatus.Orientation_180:
359                     {
360                         handler?.Invoke(new DeviceOrientationEventArgs(DeviceOrientation.Orientation_180));
361                         break;
362                     }
363                 case Application.DeviceOrientationStatus.Orientation_270:
364                     {
365                         handler?.Invoke(new DeviceOrientationEventArgs(DeviceOrientation.Orientation_270));
366                         break;
367                     }
368             }
369         }
370
371         /// <summary>
372         /// The Initialized event callback function.
373         /// </summary>
374         /// <param name="source">The application instance.</param>
375         /// <param name="e">The event argument for Initialized.</param>
376         private void OnInitialized(object source, NUIApplicationInitEventArgs e)
377         {
378             Tizen.Tracer.Begin("[NUI] OnInitialized()");
379
380             Log.Info("NUI", "NUICorebackend OnPreCreated Called");
381
382             Tizen.Tracer.Begin("[NUI] OnInitialized(): OnPreCreated event handler");
383             var preCreateHandler = Handlers[EventType.PreCreated] as Action;
384             preCreateHandler?.Invoke();
385             Tizen.Tracer.End();
386
387             Log.Info("NUI", "NUICorebackend OnCreate Called");
388
389             Tizen.Tracer.Begin("[NUI] OnInitialized(): OnCreated event handler");
390             var createHandler = Handlers[EventType.Created] as Action;
391             createHandler?.Invoke();
392             Tizen.Tracer.End();
393
394             Tizen.Tracer.End();
395         }
396
397         /// <summary>
398         /// The Terminated event callback function.
399         /// </summary>
400         /// <param name="source">The application instance.</param>
401         /// <param name="e">The event argument for Terminated.</param>
402         private void OnTerminated(object source, NUIApplicationTerminatingEventArgs e)
403         {
404             Log.Info("NUI", "NUICorebackend OnTerminated Called");
405             var handler = Handlers[EventType.Terminated] as Action;
406             handler?.Invoke();
407         }
408
409         /// <summary>
410         /// The Resumed event callback function.
411         /// </summary>
412         /// <param name="source">The application instance.</param>
413         /// <param name="e">The event argument for Resumed.</param>
414         private void OnResumed(object source, NUIApplicationResumedEventArgs e)
415         {
416             Tizen.Tracer.Begin("[NUI] OnResumed()");
417
418             Log.Info("NUI", "NUICorebackend OnResumed Called");
419
420             Tizen.Tracer.Begin("[NUI] OnResumed(): OnResumed event handler");
421             var handler = Handlers[EventType.Resumed] as Action;
422             handler?.Invoke();
423             Tizen.Tracer.End();
424
425             Tizen.Tracer.End();
426         }
427
428         /// <summary>
429         /// The App control event callback function.
430         /// </summary>
431         /// <param name="source">The application instance.</param>
432         /// <param name="e">The event argument for AppControl.</param>
433         private void OnAppControl(object source, NUIApplicationAppControlEventArgs e)
434         {
435             Log.Info("NUI", "NUICorebackend OnAppControl Called");
436             var handler = Handlers[EventType.AppControlReceived] as Action<AppControlReceivedEventArgs>;
437             using SafeAppControlHandle handle = new SafeAppControlHandle(e.VoidP, false);
438             handler?.Invoke(new AppControlReceivedEventArgs(new ReceivedAppControl(handle)));
439         }
440
441         /// <summary>
442         /// The Paused event callback function.
443         /// </summary>
444         /// <param name="source">The application instance.</param>
445         /// <param name="e">The event argument for Paused.</param>
446         private void OnPaused(object source, NUIApplicationPausedEventArgs e)
447         {
448             Log.Info("NUI", "NUICorebackend OnPaused Called");
449             var handler = Handlers[EventType.Paused] as Action;
450             handler?.Invoke();
451         }
452
453         /// <summary>
454         /// The Region changed event callback function. The callback is emitted on the main thread.
455         /// </summary>
456         /// <param name="source">The application instance.</param>
457         /// <param name="e">The event argument for RegionChanged.</param>
458         private void OnTaskRegionChanged(object source, NUIApplicationRegionChangedEventArgs e)
459         {
460             Log.Info("NUI", "NUICorebackend OnTaskRegionChanged Called");
461             coreTask.OnRegionFormatChanged(new RegionFormatChangedEventArgs((source as Application)?.GetRegion()));
462         }
463
464         /// <summary>
465         /// The Memory Low event callback function. The callback is emitted on the main thread.
466         /// </summary>
467         /// <param name="source">The application instance.</param>
468         /// <param name="e">The event argument for MemoryLow.</param>
469         private void OnTaskMemoryLow(object source, NUIApplicationMemoryLowEventArgs e)
470         {
471             Log.Info("NUI", "NUICorebackend OnTaskMemoryLow Called");
472             switch (e.MemoryStatus)
473             {
474                 case Application.MemoryStatus.Normal:
475                     {
476                         coreTask.OnLowMemory(new LowMemoryEventArgs(LowMemoryStatus.None));
477                         break;
478                     }
479                 case Application.MemoryStatus.Low:
480                     {
481                         coreTask.OnLowMemory(new LowMemoryEventArgs(LowMemoryStatus.SoftWarning));
482                         break;
483                     }
484                 case Application.MemoryStatus.CriticallyLow:
485                     {
486                         coreTask.OnLowMemory(new LowMemoryEventArgs(LowMemoryStatus.HardWarning));
487                         break;
488                     }
489             }
490         }
491
492         /// <summary>
493         /// The Language changed event callback function. The callback is emitted on the main thread.
494         /// </summary>
495         /// <param name="source">The application instance.</param>
496         /// <param name="e">The event argument for LanguageChanged.</param>
497         private void OnTaskLanguageChanged(object source, NUIApplicationLanguageChangedEventArgs e)
498         {
499             Log.Info("NUI", "NUICorebackend OnTaskLanguageChanged Called");
500             coreTask.OnLocaleChanged(new LocaleChangedEventArgs((source as Application)?.GetLanguage()));
501         }
502
503         /// <summary>
504         /// The Battery Low event callback function. The callback is emitted on the main thread.
505         /// </summary>
506         /// <param name="source">The application instance.</param>
507         /// <param name="e">The event argument for BatteryLow.</param>
508         private void OnTaskBatteryLow(object source, NUIApplicationBatteryLowEventArgs e)
509         {
510             Log.Info("NUI", "NUICorebackend OnTaskBatteryLow Called");
511             switch (e.BatteryStatus)
512             {
513                 case Application.BatteryStatus.Normal:
514                     {
515                         coreTask?.OnLowBattery(new LowBatteryEventArgs(LowBatteryStatus.None));
516                         break;
517                     }
518                 case Application.BatteryStatus.CriticallyLow:
519                     {
520                         coreTask?.OnLowBattery(new LowBatteryEventArgs(LowBatteryStatus.CriticalLow));
521                         break;
522                     }
523                 case Application.BatteryStatus.PowerOff:
524                     {
525                         coreTask?.OnLowBattery(new LowBatteryEventArgs(LowBatteryStatus.PowerOff));
526                         break;
527                     }
528             }
529         }
530
531         /// <summary>
532         /// The Orientation Changed event callback function. The callback is emitted on the main thread.
533         /// </summary>
534         /// <param name="source">The application instance.</param>
535         /// <param name="e">The event argument for changing device orientation.</param>
536         private void OnTaskDeviceOrientationChanged(object source, NUIApplicationDeviceOrientationChangedEventArgs e)
537         {
538             Log.Info("NUI", "NUICorebackend OnTaskBatteryLow Called");
539             switch (e.DeviceOrientationStatus)
540             {
541                 case Application.DeviceOrientationStatus.Orientation_0:
542                     {
543                         coreTask?.OnDeviceOrientationChanged(new DeviceOrientationEventArgs(DeviceOrientation.Orientation_0));
544                         break;
545                     }
546                 case Application.DeviceOrientationStatus.Orientation_90:
547                     {
548                         coreTask?.OnDeviceOrientationChanged(new DeviceOrientationEventArgs(DeviceOrientation.Orientation_90));
549                         break;
550                     }
551                 case Application.DeviceOrientationStatus.Orientation_180:
552                     {
553                         coreTask?.OnDeviceOrientationChanged(new DeviceOrientationEventArgs(DeviceOrientation.Orientation_180));
554                         break;
555                     }
556                 case Application.DeviceOrientationStatus.Orientation_270:
557                     {
558                         coreTask?.OnDeviceOrientationChanged(new DeviceOrientationEventArgs(DeviceOrientation.Orientation_270));
559                         break;
560                     }
561             }
562         }
563
564         /// <summary>
565         /// The Initialized event callback function. The callback is emitted on the main thread.
566         /// </summary>
567         /// <param name="source">The application instance.</param>
568         /// <param name="e">The event argument for Initialized.</param>
569         private void OnTaskInitialized(object source, NUIApplicationInitEventArgs e)
570         {
571             Log.Info("NUI", "NUICorebackend OnTaskInitialized Called");
572             coreTask.OnCreate();
573         }
574
575         /// <summary>
576         /// The Terminated event callback function. The callback is emitted on the main thread.
577         /// </summary>
578         /// <param name="source">The application instance.</param>
579         /// <param name="e">The event argument for Terminated.</param>
580         private void OnTaskTerminated(object source, NUIApplicationTerminatingEventArgs e)
581         {
582             Log.Info("NUI", "NUICorebackend OnTaskTerminated Called");
583             coreTask.OnTerminate();
584         }
585
586         /// <summary>
587         /// The App control event callback function. The callback is emitted on the main thread.
588         /// </summary>
589         /// <param name="source">The application instance.</param>
590         /// <param name="e">The event argument for AppControl.</param>
591         private void OnTaskAppControl(object source, NUIApplicationAppControlEventArgs e)
592         {
593             Log.Info("NUI", "NUICorebackend OnTaskAppControl Called");
594             using SafeAppControlHandle handle = new SafeAppControlHandle(e.VoidP, false);
595             coreTask.OnAppControlReceived(new AppControlReceivedEventArgs(new ReceivedAppControl(handle)));
596         }
597
598         internal Application ApplicationHandle
599         {
600             get
601             {
602                 return application;
603             }
604         }
605     }
606 }