[NUI] NUI ThemeManager works with TizenThemeManager
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Application / NUIApplication.cs
1 /*
2  * Copyright (c) 2019 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.Diagnostics.CodeAnalysis;
21 using System.Threading;
22 using System.Reflection;
23 using Tizen.Applications;
24 using Tizen.Applications.CoreBackend;
25 using Tizen.NUI.Binding;
26 using Tizen.NUI.Xaml;
27 using Tizen.Applications.ThemeManager;
28 using System.Collections.Generic;
29
30 namespace Tizen.NUI
31 {
32
33     /// <summary>
34     /// Represents an application that have a UI screen. The NUIApplication class has a default stage.
35     /// </summary>
36     /// <since_tizen> 3 </since_tizen>
37     public class NUIApplication : CoreApplication
38     {
39         /// <summary>
40         /// The instance of ResourceManager.
41         /// </summary>
42         private static System.Resources.ResourceManager resourceManager = null;
43         private Size2D _windowSize2D = null;
44         private Position2D _windowPosition2D = null;
45         private TransitionOptions transitionOptions;
46         private string appId = null;
47         internal static NUIApplication me;
48
49         private static bool isPreLoad = false;
50         private readonly ThemeLoader themeLoader = new ThemeLoader();
51
52         /// <summary>
53         /// The default constructor.
54         /// </summary>
55         /// <since_tizen> 3 </since_tizen>
56         public NUIApplication() : base(new NUICoreBackend())
57         {
58             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
59             me = this;
60             themeLoader.ThemeChanged += TizenThemeChanged;
61         }
62
63         /// <summary>
64         /// The constructor with window size and position.
65         /// </summary>
66         /// <param name="windowSize">The window size.</param>
67         /// <param name="windowPosition">The window position.</param>
68         /// <since_tizen> 5 </since_tizen>
69         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
70         [EditorBrowsable(EditorBrowsableState.Never)]
71         public NUIApplication(Size2D windowSize, Position2D windowPosition) : base(new NUICoreBackend("", WindowMode.Opaque, windowSize, windowPosition))
72         {
73             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
74             themeLoader.ThemeChanged += TizenThemeChanged;
75             _windowSize2D = windowSize;
76             _windowPosition2D = windowPosition;
77             me = this;
78         }
79
80         /// <summary>
81         /// The constructor with a stylesheet.
82         /// </summary>
83         /// <param name="styleSheet">The styleSheet url.</param>
84         /// <since_tizen> 3 </since_tizen>
85         public NUIApplication(string styleSheet) : base(new NUICoreBackend(styleSheet))
86         {
87             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
88             me = this;
89             themeLoader.ThemeChanged += TizenThemeChanged;
90         }
91
92         /// <summary>
93         /// The constructor with a stylesheet, window size, and position.
94         /// </summary>
95         /// <param name="styleSheet">The styleSheet URL.</param>
96         /// <param name="windowSize">The window size.</param>
97         /// <param name="windowPosition">The window position.</param>
98         /// <since_tizen> 5 </since_tizen>
99         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
100         [EditorBrowsable(EditorBrowsableState.Never)]
101         public NUIApplication(string styleSheet, Size2D windowSize, Position2D windowPosition) : base(new NUICoreBackend(styleSheet, WindowMode.Opaque, windowSize, windowPosition))
102         {
103             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
104             themeLoader.ThemeChanged += TizenThemeChanged;
105             _windowSize2D = windowSize;
106             _windowPosition2D = windowPosition;
107             me = this;
108         }
109
110         /// <summary>
111         /// The constructor with a stylesheet and window mode.
112         /// </summary>
113         /// <param name="styleSheet">The styleSheet url.</param>
114         /// <param name="windowMode">The windowMode.</param>
115         /// <since_tizen> 3 </since_tizen>
116         public NUIApplication(string styleSheet, WindowMode windowMode) : base(new NUICoreBackend(styleSheet, windowMode))
117         {
118             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
119             me = this;
120             themeLoader.ThemeChanged += TizenThemeChanged;
121         }
122
123         /// <summary>
124         /// The constructor with a stylesheet, window mode, window size, and position.
125         /// </summary>
126         /// <param name="styleSheet">The styleSheet URL.</param>
127         /// <param name="windowMode">The windowMode.</param>
128         /// <param name="windowSize">The window size.</param>
129         /// <param name="windowPosition">The window position.</param>
130         /// <since_tizen> 5 </since_tizen>
131         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
132         [EditorBrowsable(EditorBrowsableState.Never)]
133         public NUIApplication(string styleSheet, WindowMode windowMode, Size2D windowSize, Position2D windowPosition) : base(new NUICoreBackend(styleSheet, windowMode, windowSize, windowPosition))
134         {
135             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
136             themeLoader.ThemeChanged += TizenThemeChanged;
137             _windowSize2D = windowSize;
138             _windowPosition2D = windowPosition;
139             me = this;
140         }
141
142         /// <summary>
143         /// Internal inhouse constructor with Graphics Backend Type
144         /// </summary>
145         /// <param name="backend"></param>
146         /// <param name="windowMode"></param>
147         /// <param name="windowSize"></param>
148         /// <param name="windowPosition"></param>
149         /// <param name="styleSheet"></param>
150         /// InhouseAPI, this could be opend in NextTizen
151         [Obsolete("Please do not use! This will be deprecated!")]
152         [EditorBrowsable(EditorBrowsableState.Never)]
153         public NUIApplication(Graphics.BackendType backend, WindowMode windowMode = WindowMode.Opaque, Size2D windowSize = null, Position2D windowPosition = null, string styleSheet = "") : base(new NUICoreBackend(styleSheet, windowMode, windowSize, windowPosition))
154         {
155             //windowMode and styleSheet will be added later. currenlty it's not working as expected.
156             Graphics.Backend = backend;
157             Tizen.Log.Error("NUI", "Plaese DO NOT set graphical backend type with this constructor! This will give no effect!");
158
159             if (windowSize != null) { _windowSize2D = windowSize; }
160             if (windowPosition != null) { _windowPosition2D = windowPosition; }
161             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
162             me = this;
163             themeLoader.ThemeChanged += TizenThemeChanged;
164         }
165
166         /// <summary>
167         /// Occurs whenever the application is resumed.
168         /// </summary>
169         /// <since_tizen> 4 </since_tizen>
170         public event EventHandler Resumed;
171
172         /// <summary>
173         /// Occurs whenever the application is paused.
174         /// </summary>
175         /// <since_tizen> 4 </since_tizen>
176         public event EventHandler Paused;
177
178         /// <summary>
179         /// Enumeration for deciding whether a NUI application window is opaque or transparent.
180         /// </summary>
181         /// <since_tizen> 3 </since_tizen>
182         public enum WindowMode
183         {
184             /// <summary>
185             /// Opaque
186             /// </summary>
187             /// <since_tizen> 3 </since_tizen>
188             Opaque = 0,
189             /// <summary>
190             /// Transparent
191             /// </summary>
192             /// <since_tizen> 3 </since_tizen>
193             Transparent = 1
194         }
195
196         /// <summary>
197         /// ResourceManager to handle multilingual.
198         /// </summary>
199         /// <since_tizen> 4 </since_tizen>
200         public static System.Resources.ResourceManager MultilingualResourceManager
201         {
202             get
203             {
204                 return resourceManager;
205             }
206             set
207             {
208                 resourceManager = value;
209             }
210         }
211
212         /// <summary>
213         /// Gets the window instance.
214         /// </summary>
215         /// <since_tizen> 3 </since_tizen>
216         [Obsolete("Please do not use! This will be deprecated!")]
217         [EditorBrowsable(EditorBrowsableState.Never)]
218         public Window Window
219         {
220             get
221             {
222                 return GetDefaultWindow();
223             }
224         }
225
226         /// <summary>
227         /// Gets the Application Id.
228         /// </summary>
229         /// <since_tizen> 6 </since_tizen>
230         [EditorBrowsable(EditorBrowsableState.Never)]
231         public string AppId
232         {
233             get
234             {
235                 return appId;
236             }
237         }
238
239         /// <summary>
240         /// Gets the default window.
241         /// </summary>
242         /// <returns>The default Window.</returns>
243         /// <since_tizen> 6 </since_tizen>
244         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
245         [EditorBrowsable(EditorBrowsableState.Never)]
246         public static Window GetDefaultWindow()
247         {
248             return Window.Instance;
249         }
250
251         internal Application ApplicationHandle
252         {
253             get
254             {
255                 return ((NUICoreBackend)this.Backend).ApplicationHandle;
256             }
257         }
258
259         /// <summary>
260         /// Register the assembly to XAML.
261         /// </summary>
262         /// <since_tizen> 5 </since_tizen>
263         public static void RegisterAssembly(Assembly assembly)
264         {
265             XamlParser.s_assemblies.Add(assembly);
266         }
267
268         /// <summary>
269         /// Runs the NUIApplication.
270         /// </summary>
271         /// <param name="args">Arguments from commandline.</param>
272         /// <since_tizen> 4 </since_tizen>
273         public override void Run(string[] args)
274         {
275             Backend.AddEventHandler(EventType.PreCreated, OnPreCreate);
276             Backend.AddEventHandler(EventType.Resumed, OnResume);
277             Backend.AddEventHandler(EventType.Paused, OnPause);
278             base.Run(args);
279         }
280
281         /// <summary>
282         /// Exits the NUIApplication.
283         /// </summary>
284         /// <since_tizen> 4 </since_tizen>
285         public override void Exit()
286         {
287             base.Exit();
288         }
289
290         /// <summary>
291         /// Ensures that the function passed in is called from the main loop when it is idle.
292         /// </summary>
293         /// <param name="func">The function to call</param>
294         /// <returns>true if added successfully, false otherwise</returns>
295         /// <since_tizen> 4 </since_tizen>
296         public bool AddIdle(System.Delegate func)
297         {
298             return ((NUICoreBackend)this.Backend).AddIdle(func);
299         }
300
301         /// <summary>
302         /// Sets the number of frames per render.
303         /// </summary>
304         /// <param name="numberOfVSyncsPerRender">The number of vsyncs between successive renders.</param>
305         /// <remarks>
306         /// Suggest this is a power of two:
307         /// 1 - render each vsync frame.
308         /// 2 - render every other vsync frame.
309         /// 4 - render every fourth vsync frame.
310         /// 8 - render every eighth vsync frame. <br />
311         /// For example, if an application runs on 60 FPS and SetRenderRefreshRate(2) is called, the frames per second will be changed to 30.
312         ///</remarks>
313         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
314         [EditorBrowsable(EditorBrowsableState.Never)]
315         public static void SetRenderRefreshRate(uint numberOfVSyncsPerRender)
316         {
317             Adaptor.Instance.SetRenderRefreshRate(numberOfVSyncsPerRender);
318         }
319
320         /// <summary>
321         /// Overrides this method if you want to handle behavior.
322         /// </summary>
323         /// <since_tizen> 3 </since_tizen>
324         protected override void OnLocaleChanged(LocaleChangedEventArgs e)
325         {
326             base.OnLocaleChanged(e);
327         }
328
329         /// <summary>
330         /// Overrides this method if you want to handle behavior.
331         /// </summary>
332         /// <since_tizen> 3 </since_tizen>
333         protected override void OnLowBattery(LowBatteryEventArgs e)
334         {
335             base.OnLowBattery(e);
336         }
337
338         /// <summary>
339         /// Overrides this method if you want to handle behavior.
340         /// </summary>
341         /// <since_tizen> 3 </since_tizen>
342         protected override void OnLowMemory(LowMemoryEventArgs e)
343         {
344             base.OnLowMemory(e);
345         }
346
347         /// <summary>
348         /// Overrides this method if you want to handle behavior.
349         /// </summary>
350         /// <since_tizen> 3 </since_tizen>
351         protected override void OnRegionFormatChanged(RegionFormatChangedEventArgs e)
352         {
353             base.OnRegionFormatChanged(e);
354         }
355
356         /// <summary>
357         /// Overrides this method if you want to handle behavior.
358         /// </summary>
359         /// <since_tizen> 3 </since_tizen>
360         protected override void OnTerminate()
361         {
362             base.OnTerminate();
363         }
364
365         /// <summary>
366         /// Overrides this method if you want to handle behavior.
367         /// </summary>
368         /// <since_tizen> 3 </since_tizen>
369         protected virtual void OnPause()
370         {
371             Paused?.Invoke(this, EventArgs.Empty);
372         }
373
374         /// <summary>
375         /// Overrides this method if you want to handle behavior.
376         /// </summary>
377         /// <since_tizen> 3 </since_tizen>
378         protected virtual void OnResume()
379         {
380             Resumed?.Invoke(this, EventArgs.Empty);
381         }
382
383         /// <summary>
384         /// Overrides this method if you want to handle behavior.
385         /// </summary>
386         /// <since_tizen> 3 </since_tizen>
387         protected virtual void OnPreCreate()
388         {
389         }
390
391         /// <summary>
392         /// Overrides this method if you want to handle behavior.
393         /// </summary>
394         /// <since_tizen> 3 </since_tizen>
395         protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
396         {
397             if (e != null)
398             {
399                 Log.Info("NUI", "OnAppControlReceived() is called! ApplicationId=" + e.ReceivedAppControl.ApplicationId);
400                 Log.Info("NUI", "CallerApplicationId=" + e.ReceivedAppControl.CallerApplicationId + "   IsReplyRequest=" + e.ReceivedAppControl.IsReplyRequest);
401             }
402             base.OnAppControlReceived(e);
403         }
404
405         /// <summary>
406         /// Overrides this method if you want to handle behavior.
407         /// </summary>
408         /// <since_tizen> 3 </since_tizen>
409         protected override void OnCreate()
410         {
411             base.OnCreate();
412             appId = Tizen.Applications.Application.Current.ApplicationInfo.ApplicationId;
413         }
414
415         /// <summary>
416         /// This is used to improve application launch performance.
417         /// </summary>
418         [EditorBrowsable(EditorBrowsableState.Never)]
419         static public void PreLoad()
420         {
421             Interop.Application.PreInitialize();
422             isPreLoad = true;
423         }
424
425         /// <summary>
426         /// This is used to improve application launch performance.
427         /// </summary>
428         [EditorBrowsable(EditorBrowsableState.Never)]
429         public void SendLaunchRequest(AppControl appControl)
430         {
431             transitionOptions.SendLaunchRequest(appControl);
432         }
433
434         /// <summary>
435         /// This is used to improve application launch performance.
436         /// </summary>
437         [EditorBrowsable(EditorBrowsableState.Never)]
438         public TransitionOptions TransitionOptions
439         {
440             get
441             {
442                 return transitionOptions;
443             }
444             set
445             {
446                 transitionOptions = value;
447             }
448         }
449         private void TizenThemeChanged(object sender, ThemeEventArgs e)
450         {
451             string prefix = "/theme/";
452
453             Dictionary<string, string> changedResources = new Dictionary<string, string>();
454             foreach (string key in ThemeManager.DefaultTheme.Resources.Keys)
455             {
456                 // NOTE Need improve this code by checking HasKey
457                 string newValue = null;
458                 try
459                 {
460                     newValue = e.Theme.GetString(prefix + key);
461                 }
462                 catch { }
463                 if (newValue != null)
464                 {
465                     changedResources[key] = newValue;
466                 }
467             }
468             ThemeManager.UpdateCurrentThemeResources(changedResources);
469         }
470
471         /// <summary>
472         /// Check if it is loaded as dotnet-loader-nui.
473         /// </summary>
474         static internal bool IsPreLoad
475         {
476             get
477             {
478                 return isPreLoad;
479             }
480         }
481     }
482
483     /// <summary>
484     /// Graphics Backend Type.
485     /// </summary>
486     [SuppressMessage("Microsoft.Design", "CA1052:StaticHolderTypesShouldBeStaticOrNotInheritable")]
487     [EditorBrowsable(EditorBrowsableState.Never)]
488     [Obsolete("Please do not use! This will be deprecated!")]
489     public class Graphics
490     {
491         /// <summary>
492         /// Graphics Backend Type.
493         /// </summary>
494         public enum BackendType
495         {
496             /// <summary>
497             /// The GLES backend.
498             /// </summary>
499             Gles,
500             /// <summary>
501             /// The Vulkan backend.
502             /// </summary>
503             Vulkan
504         }
505
506         /// <summary>
507         /// The backend used by the NUIApplication.
508         /// </summary>
509         [EditorBrowsable(EditorBrowsableState.Never)]
510         internal static BackendType Backend = BackendType.Gles;
511
512         internal const string GlesCSharpBinder = NDalicPINVOKE.Lib;
513         internal const string VulkanCSharpBinder = "libdali-csharp-binder-vk.so";
514     }
515
516 }