using System; using System.ComponentModel; using System.Diagnostics; using System.Threading.Tasks; using ElmSharp; using Tizen.Applications; using Xamarin.Forms.Internals; using EButton = ElmSharp.Button; using EColor = ElmSharp.Color; using ELayout = ElmSharp.Layout; using EProgressBar = ElmSharp.ProgressBar; namespace Xamarin.Forms.Platform.Tizen { public class FormsApplication : CoreUIApplication { Platform _platform; Application _application; bool _isInitialStart; int _pageBusyCount; Native.Dialog _pageBusyDialog; 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 Window MainWindow { get { return _window; } protected set { _window = value; InitializeWindow(); } } public ELayout BaseLayout { get; protected set; } protected override void OnPreCreate() { base.OnPreCreate(); Application.ClearCurrent(); MainWindow = new Window("FormsWindow"); } 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(); } } [EditorBrowsable(EditorBrowsableState.Never)] public static Func RequestingUserConsentFunc { get; set; } = null; public async void LoadApplication(Application application) { if (RequestingUserConsentFunc != null) { await RequestingUserConsentFunc(); } 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); } static void ActionSheetSignalNameHandler(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) { EButton cancel = new EButton(Forms.Context.MainWindow) { Text = arguments.Cancel }; alert.NegativeButton = cancel; cancel.Clicked += (s, evt) => { alert.Dismiss(); }; } alert.BackButtonPressed += (s, evt) => { alert.Dismiss(); }; alert.Show(); } static void AlertSignalNameHandler(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, "
"); alert.Text = message; EButton cancel = new EButton(alert) { Text = arguments.Cancel }; alert.NegativeButton = cancel; cancel.Clicked += (s, evt) => { arguments.SetResult(false); alert.Dismiss(); }; if (arguments.Accept != null) { EButton ok = new EButton(alert) { Text = arguments.Accept }; alert.NeutralButton = ok; ok.Clicked += (s, evt) => { arguments.SetResult(true); alert.Dismiss(); }; } alert.BackButtonPressed += (s, evt) => { arguments.SetResult(false); alert.Dismiss(); }; alert.Show(); } 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 BusySetSignalNameHandler(Page sender, bool enabled) { ShowActivityIndicatorDialog(enabled); } 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, BusySetSignalNameHandler); MessagingCenter.Subscribe(this, Page.AlertSignalName, AlertSignalNameHandler); MessagingCenter.Subscribe(this, Page.ActionSheetSignalName, ActionSheetSignalNameHandler); _platform = new Platform(this); if (_application != null) { _application.Platform = _platform; } _platform.SetPage(page); } void InitializeWindow() { Debug.Assert(MainWindow != null, "Window cannot be null"); MainWindow.Active(); MainWindow.Show(); var conformant = new Conformant(MainWindow); conformant.Show(); // Create the base (default) layout for the application var layout = new ELayout(conformant); layout.SetTheme("layout", "application", "default"); layout.Show(); conformant.SetContent(layout); BaseLayout = layout; MainWindow.AvailableRotations = DisplayRotation.Degree_0 | DisplayRotation.Degree_90 | DisplayRotation.Degree_180 | DisplayRotation.Degree_270; MainWindow.Deleted += (s, e) => { Exit(); }; MainWindow.RotationChanged += (sender, e) => { switch (MainWindow.Rotation) { case 0: Device.Info.CurrentOrientation = Internals.DeviceOrientation.PortraitUp; break; case 90: Device.Info.CurrentOrientation = Internals.DeviceOrientation.LandscapeLeft; break; case 180: Device.Info.CurrentOrientation = Internals.DeviceOrientation.PortraitDown; break; case 270: Device.Info.CurrentOrientation = Internals.DeviceOrientation.LandscapeRight; break; } }; } 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(); } } }