Fix Page.DisplayAlert's message format converting
[platform/upstream/xamarin-forms.git] / Xamarin.Forms.Platform.Tizen / FormsApplication.cs
1 using System;
2 using System.ComponentModel;
3 using System.Diagnostics;
4 using Tizen.Applications;
5 using ElmSharp;
6 using EProgressBar = ElmSharp.ProgressBar;
7 using EColor = ElmSharp.Color;
8 using ELabel = ElmSharp.Label;
9
10 namespace Xamarin.Forms.Platform.Tizen
11 {
12         public class FormsApplication : CoreUIApplication
13         {
14                 Platform _platform;
15                 Application _application;
16                 bool _isInitialStart;
17                 int _pageBusyCount;
18                 Native.Dialog _pageBusyDialog;
19                 Native.Window _window;
20
21                 protected FormsApplication()
22                 {
23                         _isInitialStart = true;
24                         _pageBusyCount = 0;
25                 }
26
27                 /// <summary>
28                 /// Gets the main window or <c>null</c> if it's not set.
29                 /// </summary>
30                 /// <value>The main window or <c>null</c>.</value>
31                 public Native.Window MainWindow
32                 {
33                         get
34                         {
35                                 return _window;
36                         }
37
38                         private set
39                         {
40                                 _window = value;
41                         }
42                 }
43
44                 protected override void OnPreCreate()
45                 {
46                         base.OnPreCreate();
47                         Application.ClearCurrent();
48                         CreateWindow();
49                 }
50
51                 protected override void OnTerminate()
52                 {
53                         base.OnTerminate();
54                         MessagingCenter.Unsubscribe<Page, AlertArguments>(this, "Xamarin.SendAlert");
55                         MessagingCenter.Unsubscribe<Page, bool>(this, "Xamarin.BusySet");
56                         MessagingCenter.Unsubscribe<Page, ActionSheetArguments>(this, "Xamarin.ShowActionSheet");
57                         if (_platform != null)
58                         {
59                                 _platform.Dispose();
60                         }
61                 }
62
63                 protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
64                 {
65                         base.OnAppControlReceived(e);
66
67                         if (!_isInitialStart && _application != null)
68                         {
69                                 _application.SendResume();
70                         }
71                         _isInitialStart = false;
72                 }
73
74                 protected override void OnPause()
75                 {
76                         base.OnPause();
77                         if (_application != null)
78                         {
79                                 _application.SendSleepAsync();
80                         }
81                 }
82
83                 protected override void OnResume()
84                 {
85                         base.OnResume();
86                         if (_application != null)
87                         {
88                                 _application.SendResume();
89                         }
90                 }
91
92                 public void LoadApplication(Application application)
93                 {
94                         if (null == MainWindow)
95                         {
96                                 throw new NullReferenceException("MainWindow is not prepared. This method should be called in OnCreated().");
97                         }
98                         if (null == application)
99                         {
100                                 throw new ArgumentNullException("application");
101                         }
102                         _application = application;
103                         Application.Current = application;
104                         application.SendStart();
105                         application.PropertyChanged += new PropertyChangedEventHandler(this.AppOnPropertyChanged);
106                         SetPage(_application.MainPage);
107                 }
108
109                 void AppOnPropertyChanged(object sender, PropertyChangedEventArgs args)
110                 {
111                         if ("MainPage" == args.PropertyName)
112                         {
113                                 SetPage(_application.MainPage);
114                         }
115                 }
116
117                 void ShowActivityIndicatorDialog(bool enabled)
118                 {
119                         if (null == _pageBusyDialog)
120                         {
121                                 _pageBusyDialog = new Native.Dialog(Forms.Context.MainWindow)
122                                 {
123                                         Orientation = PopupOrientation.Top,
124                                 };
125
126                                 var activity = new EProgressBar(_pageBusyDialog)
127                                 {
128                                         Style = "process_large",
129                                         IsPulseMode = true,
130                                 };
131                                 activity.PlayPulse();
132                                 activity.Show();
133
134                                 _pageBusyDialog.Content = activity;
135
136                         }
137                         _pageBusyCount = Math.Max(0, enabled ? _pageBusyCount + 1 : _pageBusyCount - 1);
138                         if (_pageBusyCount > 0)
139                         {
140                                 _pageBusyDialog.Show();
141                         }
142                         else
143                         {
144                                 _pageBusyDialog.Dismiss();
145                                 _pageBusyDialog = null;
146                         }
147                 }
148
149                 void SetPage(Page page)
150                 {
151                         if (!Forms.IsInitialized)
152                         {
153                                 throw new InvalidOperationException("Call Forms.Init (UIApplication) before this");
154                         }
155                         if (_platform != null)
156                         {
157                                 _platform.SetPage(page);
158                                 return;
159                         }
160                         MessagingCenter.Subscribe<Page, bool>(this, Page.BusySetSignalName, delegate (Page sender, bool enabled)
161                                 {
162                                         ShowActivityIndicatorDialog(enabled);
163                                 }, null);
164
165                         MessagingCenter.Subscribe<Page, AlertArguments>(this, Page.AlertSignalName, delegate (Page sender, AlertArguments arguments)
166                                 {
167                                         Native.Dialog alert = new Native.Dialog(Forms.Context.MainWindow);
168                                         alert.Title = arguments.Title;
169                                         var message = arguments.Message.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace(Environment.NewLine, "<br>");
170                                         var label = new ELabel(alert)
171                                         {
172                                                 Text = "<span font_size=30 color=#000000>" + message + "<\\span>",
173                                         };
174                                         label.Show();
175
176                                         var box = new Box(alert);
177                                         box.Show();
178
179                                         bool labelAdded = false;
180                                         box.Resized += (s, e) =>
181                                         {
182                                                 label.LineWrapType = WrapType.Word;
183                                                 //set 2% padding for alert text message width
184                                                 label.LineWrapWidth = (int)Math.Round(box.Geometry.Width * 0.98);
185                                                 if (!labelAdded)
186                                                 {
187                                                         /*Adding label to the box (box.PackEnd(label)) has been placed in box.Resized()
188                                                         event due to get better performance. For some reason (probably EFL bug) when
189                                                         it's placed outside of it, box.Resized() event is called far too many times.*/
190                                                         box.PackEnd(label);
191                                                         labelAdded = true;
192                                                 }
193                                         };
194
195                                         alert.Content = box;
196
197                                         Native.Button cancel = new Native.Button(alert) { Text = arguments.Cancel };
198                                         alert.NegativeButton = cancel;
199                                         cancel.Clicked += (s, evt) =>
200                                         {
201                                                 arguments.SetResult(false);
202                                                 alert.Dismiss();
203                                         };
204
205                                         if (arguments.Accept != null)
206                                         {
207                                                 Native.Button ok = new Native.Button(alert) { Text = arguments.Accept };
208                                                 alert.PositiveButton = ok;
209                                                 ok.Clicked += (s, evt) =>
210                                                 {
211                                                         arguments.SetResult(true);
212                                                         alert.Dismiss();
213                                                 };
214                                         }
215
216                                         alert.BackButtonPressed += (s, evt) =>
217                                         {
218                                                 arguments.SetResult(false);
219                                                 alert.Dismiss();
220                                         };
221
222                                         alert.Show();
223                                 }, null);
224
225                         MessagingCenter.Subscribe<Page, ActionSheetArguments>(this, Page.ActionSheetSignalName, delegate (Page sender, ActionSheetArguments arguments)
226                         {
227                                 Native.Dialog alert = new Native.Dialog(Forms.Context.MainWindow);
228
229                                 alert.Title = arguments.Title;
230                                 Box box = new Box(alert);
231
232                                 if (null != arguments.Destruction)
233                                 {
234                                         Native.Button destruction = new Native.Button(alert)
235                                         {
236                                                 Text = arguments.Destruction,
237                                                 TextColor = EColor.Red,
238                                                 AlignmentX = -1
239                                         };
240                                         destruction.Clicked += (s, evt) =>
241                                         {
242                                                 arguments.SetResult(arguments.Destruction);
243                                                 alert.Dismiss();
244                                         };
245                                         destruction.Show();
246                                         box.PackEnd(destruction);
247                                 }
248
249                                 foreach (string buttonName in arguments.Buttons)
250                                 {
251                                         Native.Button button = new Native.Button(alert)
252                                         {
253                                                 Text = buttonName,
254                                                 AlignmentX = -1
255                                         };
256                                         button.Clicked += (s, evt) =>
257                                         {
258                                                 arguments.SetResult(buttonName);
259                                                 alert.Dismiss();
260                                         };
261                                         button.Show();
262                                         box.PackEnd(button);
263                                 }
264
265                                 box.Show();
266                                 alert.Content = box;
267
268                                 if (null != arguments.Cancel)
269                                 {
270                                         Native.Button cancel = new Native.Button(Forms.Context.MainWindow) { Text = arguments.Cancel };
271                                         alert.NegativeButton = cancel;
272                                         cancel.Clicked += (s, evt) =>
273                                         {
274                                                 alert.Dismiss();
275                                         };
276                                 }
277
278                                 alert.BackButtonPressed += (s, evt) =>
279                                 {
280                                         alert.Dismiss();
281                                 };
282
283                                 alert.Show();
284                         }, null);
285
286                         _platform = new Platform(this);
287                         if (_application != null)
288                         {
289                                 _application.Platform = _platform;
290                         }
291                         _platform.SetPage(page);
292                 }
293
294                 void CreateWindow()
295                 {
296                         Debug.Assert(null == MainWindow);
297
298                         var window = new Native.Window();
299                         window.Closed += (s, e) =>
300                         {
301                                 Exit();
302                         };
303                         window.RotationChanged += (sender, e) =>
304                         {
305                                 switch (_window.CurrentOrientation)
306                                 {
307                                         case Native.DisplayOrientations.None:
308                                                 Device.Info.CurrentOrientation = DeviceOrientation.Other;
309                                                 break;
310
311                                         case Native.DisplayOrientations.Portrait:
312                                                 Device.Info.CurrentOrientation = DeviceOrientation.PortraitUp;
313                                                 break;
314
315                                         case Native.DisplayOrientations.Landscape:
316                                                 Device.Info.CurrentOrientation = DeviceOrientation.LandscapeLeft;
317                                                 break;
318
319                                         case Native.DisplayOrientations.PortraitFlipped:
320                                                 Device.Info.CurrentOrientation = DeviceOrientation.PortraitDown;
321                                                 break;
322
323                                         case Native.DisplayOrientations.LandscapeFlipped:
324                                                 Device.Info.CurrentOrientation = DeviceOrientation.LandscapeRight;
325                                                 break;
326                                 }
327                         };
328
329                         MainWindow = window;
330                 }
331                 public void Run()
332                 {
333                         Run(System.Environment.GetCommandLineArgs());
334                 }
335
336                 /// <summary>
337                 /// Exits the application's main loop, which initiates the process of its termination
338                 /// </summary>
339                 public override void Exit()
340                 {
341                         if (_platform == null)
342                         {
343                                 Log.Warn("Exit was already called or FormsApplication is not initialized yet.");
344                                 return;
345                         }
346                         // before everything is closed, inform the MainPage that it is disappearing
347                         try
348                         {
349                                 (_platform?.Page as IPageController)?.SendDisappearing();
350                                 _platform = null;
351                         }
352                         catch (Exception e)
353                         {
354                                 Log.Error("Exception thrown from SendDisappearing: {0}", e.Message);
355                         }
356
357                         base.Exit();
358                 }
359         }
360 }