using System; using System.ComponentModel; using System.Diagnostics; using Tizen.Applications; using ElmSharp; using EProgressBar = ElmSharp.ProgressBar; using EColor = ElmSharp.Color; using ELabel = ElmSharp.Label; namespace Xamarin.Forms.Platform.Tizen { public class FormsApplication : CoreUIApplication { Platform _platform; Application _application; bool _isInitialStart; int _pageBusyCount; Native.Dialog _pageBusyDialog; Native.Window _window; protected FormsApplication() { _isInitialStart = true; _pageBusyCount = 0; } /// /// Gets the main window or null if it's not set. /// /// The main window or null. public Native.Window MainWindow { get { return _window; } private set { _window = value; } } protected override void OnPreCreate() { base.OnPreCreate(); Application.ClearCurrent(); CreateWindow(); } protected override void OnTerminate() { base.OnTerminate(); MessagingCenter.Unsubscribe(this, "Xamarin.SendAlert"); MessagingCenter.Unsubscribe(this, "Xamarin.BusySet"); MessagingCenter.Unsubscribe(this, "Xamarin.ShowActionSheet"); if (_platform != null) { _platform.Dispose(); } } protected override void OnAppControlReceived(AppControlReceivedEventArgs e) { base.OnAppControlReceived(e); if (!_isInitialStart && _application != null) { _application.SendResume(); } _isInitialStart = false; } protected override void OnPause() { base.OnPause(); if (_application != null) { _application.SendSleepAsync(); } } protected override void OnResume() { base.OnResume(); if (_application != null) { _application.SendResume(); } } public void LoadApplication(Application application) { if (null == MainWindow) { throw new NullReferenceException("MainWindow is not prepared. This method should be called in OnCreated()."); } if (null == application) { throw new ArgumentNullException("application"); } _application = application; Application.Current = application; application.SendStart(); application.PropertyChanged += new PropertyChangedEventHandler(this.AppOnPropertyChanged); SetPage(_application.MainPage); } void AppOnPropertyChanged(object sender, PropertyChangedEventArgs args) { if ("MainPage" == args.PropertyName) { SetPage(_application.MainPage); } } void ShowActivityIndicatorDialog(bool enabled) { if (null == _pageBusyDialog) { _pageBusyDialog = new Native.Dialog(Forms.Context.MainWindow) { Orientation = PopupOrientation.Top, }; var activity = new EProgressBar(_pageBusyDialog) { Style = "process_large", IsPulseMode = true, }; activity.PlayPulse(); activity.Show(); _pageBusyDialog.Content = activity; } _pageBusyCount = Math.Max(0, enabled ? _pageBusyCount + 1 : _pageBusyCount - 1); if (_pageBusyCount > 0) { _pageBusyDialog.Show(); } else { _pageBusyDialog.Dismiss(); _pageBusyDialog = null; } } void SetPage(Page page) { if (!Forms.IsInitialized) { throw new InvalidOperationException("Call Forms.Init (UIApplication) before this"); } if (_platform != null) { _platform.SetPage(page); return; } MessagingCenter.Subscribe(this, Page.BusySetSignalName, delegate (Page sender, bool enabled) { ShowActivityIndicatorDialog(enabled); }, null); MessagingCenter.Subscribe(this, Page.AlertSignalName, delegate (Page sender, AlertArguments arguments) { Native.Dialog alert = new Native.Dialog(Forms.Context.MainWindow); alert.Title = arguments.Title; var message = arguments.Message.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace(Environment.NewLine, "
"); var label = new ELabel(alert) { Text = "" + message + "<\\span>", }; label.Show(); var box = new Box(alert); box.Show(); bool labelAdded = false; box.Resized += (s, e) => { label.LineWrapType = WrapType.Word; //set 2% padding for alert text message width label.LineWrapWidth = (int)Math.Round(box.Geometry.Width * 0.98); if (!labelAdded) { /*Adding label to the box (box.PackEnd(label)) has been placed in box.Resized() event due to get better performance. For some reason (probably EFL bug) when it's placed outside of it, box.Resized() event is called far too many times.*/ box.PackEnd(label); labelAdded = true; } }; alert.Content = box; Native.Button cancel = new Native.Button(alert) { Text = arguments.Cancel }; alert.NegativeButton = cancel; cancel.Clicked += (s, evt) => { arguments.SetResult(false); alert.Dismiss(); }; if (arguments.Accept != null) { Native.Button ok = new Native.Button(alert) { Text = arguments.Accept }; alert.PositiveButton = ok; ok.Clicked += (s, evt) => { arguments.SetResult(true); alert.Dismiss(); }; } alert.BackButtonPressed += (s, evt) => { arguments.SetResult(false); alert.Dismiss(); }; alert.Show(); }, null); MessagingCenter.Subscribe(this, Page.ActionSheetSignalName, delegate (Page sender, ActionSheetArguments arguments) { Native.Dialog alert = new Native.Dialog(Forms.Context.MainWindow); alert.Title = arguments.Title; Box box = new Box(alert); if (null != arguments.Destruction) { Native.Button destruction = new Native.Button(alert) { Text = arguments.Destruction, TextColor = EColor.Red, AlignmentX = -1 }; destruction.Clicked += (s, evt) => { arguments.SetResult(arguments.Destruction); alert.Dismiss(); }; destruction.Show(); box.PackEnd(destruction); } foreach (string buttonName in arguments.Buttons) { Native.Button button = new Native.Button(alert) { Text = buttonName, AlignmentX = -1 }; button.Clicked += (s, evt) => { arguments.SetResult(buttonName); alert.Dismiss(); }; button.Show(); box.PackEnd(button); } box.Show(); alert.Content = box; if (null != arguments.Cancel) { Native.Button cancel = new Native.Button(Forms.Context.MainWindow) { Text = arguments.Cancel }; alert.NegativeButton = cancel; cancel.Clicked += (s, evt) => { alert.Dismiss(); }; } alert.BackButtonPressed += (s, evt) => { alert.Dismiss(); }; alert.Show(); }, null); _platform = new Platform(this); if (_application != null) { _application.Platform = _platform; } _platform.SetPage(page); } void CreateWindow() { Debug.Assert(null == MainWindow); var window = new Native.Window(); window.Closed += (s, e) => { Exit(); }; window.RotationChanged += (sender, e) => { switch (_window.CurrentOrientation) { case Native.DisplayOrientations.None: Device.Info.CurrentOrientation = DeviceOrientation.Other; break; case Native.DisplayOrientations.Portrait: Device.Info.CurrentOrientation = DeviceOrientation.PortraitUp; break; case Native.DisplayOrientations.Landscape: Device.Info.CurrentOrientation = DeviceOrientation.LandscapeLeft; break; case Native.DisplayOrientations.PortraitFlipped: Device.Info.CurrentOrientation = DeviceOrientation.PortraitDown; break; case Native.DisplayOrientations.LandscapeFlipped: Device.Info.CurrentOrientation = DeviceOrientation.LandscapeRight; break; } }; MainWindow = window; } public void Run() { Run(System.Environment.GetCommandLineArgs()); } /// /// Exits the application's main loop, which initiates the process of its termination /// public override void Exit() { if (_platform == null) { Log.Warn("Exit was already called or FormsApplication is not initialized yet."); return; } // before everything is closed, inform the MainPage that it is disappearing try { (_platform?.Page as IPageController)?.SendDisappearing(); _platform = null; } catch (Exception e) { Log.Error("Exception thrown from SendDisappearing: {0}", e.Message); } base.Exit(); } } }