49d78bab002a9177d461148ed7f9aa5a24cf1146
[platform/core/csapi/xsf.git] / src / XSF / Xamarin.Forms.Platform.Tizen / FormsApplication.cs
1 using System;
2 using System.ComponentModel;
3 using System.Diagnostics;
4 using System.Threading.Tasks;
5 using System.Reflection;
6 using ElmSharp;
7 using Tizen.Applications;
8 using Xamarin.Forms.Internals;
9 using ELayout = ElmSharp.Layout;
10 using DeviceOrientation = Xamarin.Forms.Internals.DeviceOrientation;
11 using Xamarin.Forms.Platform.Tizen.Native;
12
13 namespace Xamarin.Forms.Platform.Tizen
14 {
15
16         public class FormsApplication : CoreUIApplication
17         {
18                 ITizenPlatform _platform;
19                 Application _application;
20                 bool _isInitialStart;
21                 Window _window;
22
23                 protected FormsApplication()
24                 {
25                         _isInitialStart = true;
26                 }
27
28                 /// <summary>
29                 /// Gets the main window or <c>null</c> if it's not set.
30                 /// </summary>
31                 /// <value>The main window or <c>null</c>.</value>
32                 public Window MainWindow
33                 {
34                         get
35                         {
36                                 return _window;
37                         }
38                         protected set
39                         {
40                                 _window = value;
41                                 InitializeWindow();
42                         }
43                 }
44
45                 public ELayout BaseLayout
46                 {
47                         get; protected set;
48                 }
49
50                 protected override void OnPreCreate()
51                 {
52                         base.OnPreCreate();
53                         Application.ClearCurrent();
54                         PreloadedWindow window = PreloadedWindow.GetInstance() ?? new PreloadedWindow();
55                         BaseLayout = window.BaseLayout;
56                         MainWindow = window.Window;
57                 }
58
59                 protected override void OnTerminate()
60                 {
61                         base.OnTerminate();
62                         if (_platform != null)
63                         {
64                                 _platform.Dispose();
65                         }
66                 }
67
68                 protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
69                 {
70                         base.OnAppControlReceived(e);
71
72                         if (!_isInitialStart && _application != null)
73                         {
74                                 _application.SendResume();
75                         }
76                         _isInitialStart = false;
77                 }
78
79                 protected override void OnPause()
80                 {
81                         base.OnPause();
82                         if (_application != null)
83                         {
84                                 _application.SendSleep();
85                         }
86                 }
87
88                 protected override void OnResume()
89                 {
90                         base.OnResume();
91                         if (_application != null)
92                         {
93                                 _application.SendResume();
94                         }
95                 }
96
97                 [EditorBrowsable(EditorBrowsableState.Never)]
98                 public static Func<Task> RequestingUserConsentFunc { get; set; } = null;
99
100                 public async void LoadApplication(Application application)
101                 {
102                         if (RequestingUserConsentFunc != null)
103                         {
104                                 await RequestingUserConsentFunc();
105                         }
106
107                         if (null == MainWindow)
108                         {
109                                 throw new InvalidOperationException("MainWindow is not prepared. This method should be called in OnCreated().");
110                         }
111
112                         if (null == application)
113                         {
114                                 throw new ArgumentNullException(nameof(application));
115                         }
116                         _application = application;
117                         Application.Current = application;
118                         application.SendStart();
119                         application.PropertyChanged += new PropertyChangedEventHandler(this.AppOnPropertyChanged);
120                         SetPage(_application.MainPage);
121                 }
122
123                 void AppOnPropertyChanged(object sender, PropertyChangedEventArgs args)
124                 {
125                         if ("MainPage" == args.PropertyName)
126                         {
127                                 SetPage(_application.MainPage);
128                         }
129                 }
130
131                 void SetPage(Page page)
132                 {
133                         if (!Forms.IsInitialized)
134                         {
135                                 throw new InvalidOperationException("Call Forms.Init (UIApplication) before this");
136                         }
137
138 #pragma warning disable CS0618 // Type or member is obsolete
139                         // The Platform property is no longer necessary, but we have to set it because some third-party
140                         // library might still be retrieving it and using it
141                         if (_application != null)
142                         {
143                                 _application.Platform = _platform;
144                         }
145 #pragma warning restore CS0618 // Type or member is obsolete
146
147                         _platform.HasAlpha = MainWindow.Alpha;
148                         _platform.SetPage(page);
149
150                         Device.BeginInvokeOnMainThread(() => Native.NativeFactory.DeleteUnusedNative());
151                 }
152
153                 void InitializeWindow()
154                 {
155                         Debug.Assert(MainWindow != null, "Window cannot be null");
156
157                         MainWindow.Active();
158                         MainWindow.Show();
159
160                         if (BaseLayout == null)
161                         {
162                                 var conformant = new Conformant(MainWindow);
163                                 conformant.Show();
164
165                                 var layout = new ELayout(conformant);
166                                 layout.SetTheme("layout", "application", "default");
167                                 layout.Show();
168
169                                 BaseLayout = layout;
170                                 conformant.SetContent(BaseLayout);
171                         }
172
173                         MainWindow.AvailableRotations = DisplayRotation.Degree_0 | DisplayRotation.Degree_90 | DisplayRotation.Degree_180 | DisplayRotation.Degree_270;
174
175                         MainWindow.Deleted += (s, e) =>
176                         {
177                                 Exit();
178                         };
179
180                         Device.Info.CurrentOrientation = MainWindow.GetDeviceOrientation();
181
182                         MainWindow.RotationChanged += (sender, e) =>
183                         {
184                                 Device.Info.CurrentOrientation = MainWindow.GetDeviceOrientation();
185                         };
186
187                         MainWindow.BackButtonPressed += (sender, e) =>
188                         {
189                                 if (_platform != null)
190                                 {
191                                         if (!_platform.SendBackButtonPressed())
192                                         {
193                                                 Exit();
194                                         }
195                                 }
196                         };
197
198                         _platform = Platform.CreatePlatform(BaseLayout);
199                         BaseLayout.SetContent(_platform.GetRootNativeView());
200                         _platform.RootNativeViewChanged += (s, e) => BaseLayout.SetContent(e.RootNativeView);
201                 }
202
203                 public void Run()
204                 {
205                         Run(System.Environment.GetCommandLineArgs());
206                 }
207
208                 /// <summary>
209                 /// Exits the application's main loop, which initiates the process of its termination
210                 /// </summary>
211                 public override void Exit()
212                 {
213                         if (_platform == null)
214                         {
215                                 Log.Warn("Exit was already called or FormsApplication is not initialized yet.");
216                                 return;
217                         }
218                         try
219                         {
220                                 _platform.Dispose();
221                                 _platform = null;
222                         }
223                         catch (Exception e)
224                         {
225                                 Log.Error("Exception thrown from Dispose: {0}", e.Message);
226                         }
227
228                         base.Exit();
229                 }
230         }
231         static class WindowExtension
232         {
233                 public static DeviceOrientation GetDeviceOrientation(this Window window)
234                 {
235                         DeviceOrientation orientation = DeviceOrientation.Other;
236                         var isPortraitDevice = Forms.NaturalOrientation.IsPortrait();
237                         switch (window.Rotation)
238                         {
239                                 case 0:
240                                 case 180:
241                                         orientation = isPortraitDevice ? DeviceOrientation.Portrait : DeviceOrientation.Landscape;
242                                         break;
243
244                                 case 90:
245                                 case 270:
246                                         orientation = isPortraitDevice ? DeviceOrientation.Landscape : DeviceOrientation.Portrait;
247                                         break;
248                         }
249                         return orientation;
250                 }
251         }
252 }