Merge "[ElmSharp] Add ItemFocused/Unfocused to GenGrid"
[platform/core/csapi/tizenfx.git] / src / Tizen.Applications.Common / Tizen.Applications / CoreApplication.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Globalization;
19 using System.Text;
20 using Tizen.Applications.CoreBackend;
21
22 namespace Tizen.Applications
23 {
24     /// <summary>
25     /// This class represents an application controlled lifecycles by the backend system.
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public class CoreApplication : Application
29     {
30         private readonly ICoreBackend _backend;
31         private bool _disposedValue = false;
32
33         /// <summary>
34         /// Initializes the CoreApplication class.
35         /// </summary>
36         /// <param name="backend">The backend instance implementing ICoreBacked interface.</param>
37         /// <since_tizen> 3 </since_tizen>
38         public CoreApplication(ICoreBackend backend)
39         {
40             _backend = backend;
41         }
42
43         /// <summary>
44         /// Occurs when the application is launched.
45         /// </summary>
46         /// <since_tizen> 3 </since_tizen>
47         public event EventHandler Created;
48
49         /// <summary>
50         /// Occurs when the application is about to shutdown.
51         /// </summary>
52         /// <since_tizen> 3 </since_tizen>
53         public event EventHandler Terminated;
54
55         /// <summary>
56         /// Occurs whenever the application receives the appcontrol message.
57         /// </summary>
58         /// <since_tizen> 3 </since_tizen>
59         public event EventHandler<AppControlReceivedEventArgs> AppControlReceived;
60
61         /// <summary>
62         /// Occurs when the system memory is low.
63         /// </summary>
64         /// <since_tizen> 3 </since_tizen>
65         public event EventHandler<LowMemoryEventArgs> LowMemory;
66
67         /// <summary>
68         /// Occurs when the system battery is low.
69         /// </summary>
70         /// <since_tizen> 3 </since_tizen>
71         public event EventHandler<LowBatteryEventArgs> LowBattery;
72
73         /// <summary>
74         /// Occurs when the system language is chagned.
75         /// </summary>
76         /// <since_tizen> 3 </since_tizen>
77         public event EventHandler<LocaleChangedEventArgs> LocaleChanged;
78
79         /// <summary>
80         /// Occurs when the region format is changed.
81         /// </summary>
82         /// <since_tizen> 3 </since_tizen>
83         public event EventHandler<RegionFormatChangedEventArgs> RegionFormatChanged;
84
85         /// <summary>
86         /// Occurs when the device orientation is changed.
87         /// </summary>
88         /// <since_tizen> 3 </since_tizen>
89         public event EventHandler<DeviceOrientationEventArgs> DeviceOrientationChanged;
90
91         /// <summary>
92         /// The backend instance.
93         /// </summary>
94         /// <since_tizen> 3 </since_tizen>
95         protected ICoreBackend Backend { get { return _backend; } }
96
97         /// <summary>
98         /// Runs the application's main loop.
99         /// </summary>
100         /// <param name="args">Arguments from commandline.</param>
101         /// <since_tizen> 3 </since_tizen>
102         public override void Run(string[] args)
103         {
104             base.Run(args);
105
106             _backend.AddEventHandler(EventType.Created, OnCreate);
107             _backend.AddEventHandler(EventType.Terminated, OnTerminate);
108             _backend.AddEventHandler<AppControlReceivedEventArgs>(EventType.AppControlReceived, OnAppControlReceived);
109             _backend.AddEventHandler<LowMemoryEventArgs>(EventType.LowMemory, OnLowMemory);
110             _backend.AddEventHandler<LowBatteryEventArgs>(EventType.LowBattery, OnLowBattery);
111             _backend.AddEventHandler<LocaleChangedEventArgs>(EventType.LocaleChanged, OnLocaleChanged);
112             _backend.AddEventHandler<RegionFormatChangedEventArgs>(EventType.RegionFormatChanged, OnRegionFormatChanged);
113             _backend.AddEventHandler<DeviceOrientationEventArgs>(EventType.DeviceOrientationChanged, OnDeviceOrientationChanged);
114
115             string[] argsClone = null;
116
117             if (args == null)
118             {
119                 argsClone = new string[1];
120             }
121             else
122             {
123                 argsClone = new string[args.Length + 1];
124                 args.CopyTo(argsClone, 1);
125             }
126             argsClone[0] = string.Empty;
127             _backend.Run(argsClone);
128         }
129
130         /// <summary>
131         /// Exits the main loop of the application.
132         /// </summary>
133         /// <since_tizen> 3 </since_tizen>
134         public override void Exit()
135         {
136             _backend.Exit();
137         }
138
139         /// <summary>
140         /// Overrides this method if want to handle behavior when the application is launched.
141         /// If base.OnCreated() is not called, the event 'Created' will not be emitted.
142         /// </summary>
143         /// <since_tizen> 3 </since_tizen>
144         protected virtual void OnCreate()
145         {
146             Created?.Invoke(this, EventArgs.Empty);
147         }
148
149         /// <summary>
150         /// Overrides this method if want to handle behavior when the application is terminated.
151         /// If base.OnTerminate() is not called, the event 'Terminated' will not be emitted.
152         /// </summary>
153         /// <since_tizen> 3 </since_tizen>
154         protected virtual void OnTerminate()
155         {
156             Terminated?.Invoke(this, EventArgs.Empty);
157         }
158
159         /// <summary>
160         /// Overrides this method if want to handle behavior when the application receives the appcontrol message.
161         /// If base.OnAppControlReceived() is not called, the event 'AppControlReceived' will not be emitted.
162         /// </summary>
163         /// <param name="e"></param>
164         /// <since_tizen> 3 </since_tizen>
165         protected virtual void OnAppControlReceived(AppControlReceivedEventArgs e)
166         {
167             AppControlReceived?.Invoke(this, e);
168         }
169
170         /// <summary>
171         /// Overrides this method if want to handle behavior when the system memory is low.
172         /// If base.OnLowMemory() is not called, the event 'LowMemory' will not be emitted.
173         /// </summary>
174         /// <since_tizen> 3 </since_tizen>
175         protected virtual void OnLowMemory(LowMemoryEventArgs e)
176         {
177             LowMemory?.Invoke(this, e);
178             System.GC.Collect();
179         }
180
181         /// <summary>
182         /// Overrides this method if want to handle behavior when the system battery is low.
183         /// If base.OnLowBattery() is not called, the event 'LowBattery' will not be emitted.
184         /// </summary>
185         /// <since_tizen> 3 </since_tizen>
186         protected virtual void OnLowBattery(LowBatteryEventArgs e)
187         {
188             LowBattery?.Invoke(this, e);
189         }
190
191         /// <summary>
192         /// Overrides this method if want to handle behavior when the system language is changed.
193         /// If base.OnLocaleChanged() is not called, the event 'LocaleChanged' will not be emitted.
194         /// </summary>
195         /// <since_tizen> 3 </since_tizen>
196         protected virtual void OnLocaleChanged(LocaleChangedEventArgs e)
197         {
198             ChangeCurrentCultureInfo(e.Locale);
199             LocaleChanged?.Invoke(this, e);
200         }
201
202         /// <summary>
203         /// Overrides this method if want to handle behavior when the region format is changed.
204         /// If base.OnRegionFormatChanged() is not called, the event 'RegionFormatChanged' will not be emitted.
205         /// </summary>
206         /// <since_tizen> 3 </since_tizen>
207         protected virtual void OnRegionFormatChanged(RegionFormatChangedEventArgs e)
208         {
209             RegionFormatChanged?.Invoke(this, e);
210         }
211
212         /// <summary>
213         /// Overrides this method if want to handle behavior when the device orientation is changed.
214         /// If base.OnRegionFormatChanged() is not called, the event 'RegionFormatChanged' will not be emitted.
215         /// </summary>
216         /// <since_tizen> 3 </since_tizen>
217         protected virtual void OnDeviceOrientationChanged(DeviceOrientationEventArgs e)
218         {
219             DeviceOrientationChanged?.Invoke(this, e);
220         }
221
222         /// <summary>
223         /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
224         /// </summary>
225         /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
226         /// <since_tizen> 3 </since_tizen>
227         protected override void Dispose(bool disposing)
228         {
229             if (!_disposedValue)
230             {
231                 if (disposing)
232                 {
233                     _backend.Dispose();
234                 }
235
236                 _disposedValue = true;
237             }
238             base.Dispose(disposing);
239         }
240
241         private void ChangeCurrentCultureInfo(string locale)
242         {
243             ULocale pLocale = new ULocale(locale);
244             CultureInfo currentCultureInfo = null;
245
246             try
247             {
248                 currentCultureInfo = new CultureInfo(pLocale.Locale.Replace("_", "-"));
249             }
250             catch (CultureNotFoundException)
251             {
252                 currentCultureInfo = GetFallbackCultureInfo(pLocale);
253             }
254
255             CultureInfo.CurrentCulture = currentCultureInfo;
256         }
257
258         private CultureInfo GetCultureInfo(string locale)
259         {
260             CultureInfo cultureInfo = null;
261
262             try
263             {
264                 cultureInfo = new CultureInfo(locale);
265             }
266             catch (CultureNotFoundException)
267             {
268                 return null;
269             }
270
271             return cultureInfo;
272         }
273
274         private CultureInfo GetFallbackCultureInfo(ULocale uLocale)
275         {
276             string locale = string.Empty;
277             CultureInfo fallbackCultureInfo = null;
278
279             if (uLocale.Script != null && uLocale.Country != null)
280             {
281                 locale = uLocale.Language + "-" + uLocale.Script + "-" + uLocale.Country;
282                 fallbackCultureInfo = GetCultureInfo(locale);
283             }
284
285             if (fallbackCultureInfo == null && uLocale.Script != null)
286             {
287                 locale = uLocale.Language + "-" + uLocale.Script;
288                 fallbackCultureInfo = GetCultureInfo(locale);
289             }
290
291             if (fallbackCultureInfo == null && uLocale.Country != null)
292             {
293                 locale = uLocale.Language + "-" + uLocale.Country;
294                 fallbackCultureInfo = GetCultureInfo(locale);
295             }
296
297             if (fallbackCultureInfo == null)
298             {
299                 try
300                 {
301                     fallbackCultureInfo = new CultureInfo(uLocale.Language);
302                 }
303                 catch (CultureNotFoundException)
304                 {
305                     fallbackCultureInfo = new CultureInfo("en");
306                 }
307             }
308
309             return fallbackCultureInfo;
310         }
311     }
312
313     internal class ULocale
314     {
315         private const int ICU_ULOC_FULLNAME_CAPACITY = 157;
316         private const int ICU_ULOC_LANG_CAPACITY = 12;
317         private const int ICU_ULOC_SCRIPT_CAPACITY = 6;
318         private const int ICU_ULOC_COUNTRY_CAPACITY = 4;
319         private const int ICU_ULOC_VARIANT_CAPACITY = ICU_ULOC_FULLNAME_CAPACITY;
320         private const int ICU_U_ZERO_ERROR = 0;
321
322         internal ULocale(string locale)
323         {
324             Locale = Canonicalize(locale);
325             Language = GetLanguage(Locale);
326             Script = GetScript(Locale);
327             Country = GetCountry(Locale);
328             Variant = GetVariant(Locale);
329         }
330
331         internal string Locale { get; private set; }
332         internal string Language { get; private set; }
333         internal string Script { get; private set; }
334         internal string Country { get; private set; }
335         internal string Variant { get; private set; }
336
337         private string Canonicalize(string localeName)
338         {
339             int err = ICU_U_ZERO_ERROR;
340
341             // Get the locale name from ICU
342             StringBuilder sb = new StringBuilder(ICU_ULOC_FULLNAME_CAPACITY);
343             if (Interop.Icu.Canonicalize(localeName, sb, sb.Capacity, out err) <= 0)
344             {
345                 return null;
346             }
347
348             return sb.ToString();
349         }
350
351         private string GetLanguage(string locale)
352         {
353             int err = ICU_U_ZERO_ERROR;
354
355             // Get the language name from ICU
356             StringBuilder sb = new StringBuilder(ICU_ULOC_LANG_CAPACITY);
357             if (Interop.Icu.GetLanguage(locale, sb, sb.Capacity, out err) <= 0)
358             {
359                 return null;
360             }
361
362             return sb.ToString();
363         }
364
365         private string GetScript(string locale)
366         {
367             int err = ICU_U_ZERO_ERROR;
368
369             // Get the script name from ICU
370             StringBuilder sb = new StringBuilder(ICU_ULOC_SCRIPT_CAPACITY);
371             if (Interop.Icu.GetScript(locale, sb, sb.Capacity, out err) <= 0)
372             {
373                 return null;
374             }
375
376             return sb.ToString();
377         }
378
379         private string GetCountry(string locale)
380         {
381             int err = ICU_U_ZERO_ERROR;
382
383             // Get the country name from ICU
384             StringBuilder sb = new StringBuilder(ICU_ULOC_SCRIPT_CAPACITY);
385             if (Interop.Icu.GetCountry(locale, sb, sb.Capacity, out err) <= 0)
386             {
387                 return null;
388             }
389
390             return sb.ToString();
391         }
392
393         private string GetVariant(string locale)
394         {
395             int err = ICU_U_ZERO_ERROR;
396
397             // Get the country name from ICU
398             StringBuilder sb = new StringBuilder(ICU_ULOC_VARIANT_CAPACITY);
399             if (Interop.Icu.GetVariant(locale, sb, sb.Capacity, out err) <= 0)
400             {
401                 return null;
402             }
403
404             return sb.ToString();
405         }
406     }
407 }