From b8ee9287f013283f749e428d260530c051cc3ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EA=B7=BC/Common=20Platform=20Lab=28SR?= =?UTF-8?q?=29/Staff=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Mon, 19 Jul 2021 16:17:17 +0900 Subject: [PATCH] Add AlertManager on Tizen (#57) * Add AlertManager on Tizen * Add null check and remove whitespace * Remove watch profile code * Change subscriber object --- .../AlertManager/AlertManager.Tizen.cs | 321 +++++++++++++++++- 1 file changed, 315 insertions(+), 6 deletions(-) diff --git a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Tizen.cs b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Tizen.cs index ecaa6da7cd91..402f51f355ad 100644 --- a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Tizen.cs +++ b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Tizen.cs @@ -1,19 +1,328 @@ using System; +using System.Collections.Generic; +using System.Linq; +using ElmSharp; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Handlers; +using Tizen.UIExtensions.ElmSharp; +using EBox = ElmSharp.Box; +using EButton = ElmSharp.Button; +using EColor = ElmSharp.Color; +using EProgressBar = ElmSharp.ProgressBar; +using EWindow = ElmSharp.Window; +using GColor = Microsoft.Maui.Graphics.Color; +using TButton = Tizen.UIExtensions.ElmSharp.Button; +using TColor = Tizen.UIExtensions.Common.Color; namespace Microsoft.Maui.Controls.Platform { internal partial class AlertManager { - internal static void Subscribe(Window window) + readonly List Subscriptions = new List(); + + internal void Subscribe(Window window) + { + IMauiContext mauiContext = window?.MauiContext; + EWindow nativeWindow = mauiContext?.Window; + + if (mauiContext == null || nativeWindow == null) + return; + + if (Subscriptions.Any(s => s.Window == nativeWindow)) + { + return; + } + + Subscriptions.Add(new AlertRequestHelper(nativeWindow, mauiContext)); + } + + internal void Unsubscribe(Window window) + { + IMauiContext mauiContext = window?.MauiContext; + EWindow nativeWindow = mauiContext?.Window; + + var toRemove = Subscriptions.Where(s => s.Window == nativeWindow).ToList(); + + foreach (AlertRequestHelper alertRequestHelper in toRemove) + { + alertRequestHelper.Dispose(); + Subscriptions.Remove(alertRequestHelper); + } + } + } + + internal sealed class AlertRequestHelper : IDisposable + { + int _busyCount; + Dialog _pageBusyDialog; + readonly HashSet _alerts = new HashSet(); + + internal AlertRequestHelper(EWindow window, IMauiContext mauiContext) + { + Window = window; + MauiContext = mauiContext; + + MessagingCenter.Subscribe(Window, Page.BusySetSignalName, OnBusySetRequest); + MessagingCenter.Subscribe(Window, Page.AlertSignalName, OnAlertRequest); + MessagingCenter.Subscribe(Window, Page.ActionSheetSignalName, OnActionSheetRequest); + MessagingCenter.Subscribe(Window, Page.PromptSignalName, OnPromptRequested); + } + + public EWindow Window { get; } + public IMauiContext MauiContext { get; } + + public void Dispose() { - //TODO: Need to implementation - //throw new NotImplementedException(); + MessagingCenter.Unsubscribe(Window, Page.AlertSignalName); + MessagingCenter.Unsubscribe(Window, Page.BusySetSignalName); + MessagingCenter.Unsubscribe(Window, Page.ActionSheetSignalName); + MessagingCenter.Unsubscribe(Window, Page.PromptSignalName); + } + + void OnBusySetRequest(Page sender, bool enabled) + { + // Verify that the page making the request is child of this platform + if (!PageIsInThisContext(sender)) + { + return; + } + _busyCount = Math.Max(0, enabled ? _busyCount + 1 : _busyCount - 1); + + if (null == _pageBusyDialog) + { + _pageBusyDialog = new Dialog(MauiContext.Context.NativeParent) + { + Orientation = PopupOrientation.Center, + BackgroundColor = EColor.Transparent + }; + + _pageBusyDialog.SetTitleBackgroundColor(EColor.Transparent); + _pageBusyDialog.SetContentBackgroundColor(EColor.Transparent); + + var activity = new EProgressBar(_pageBusyDialog) { IsPulseMode = true }.SetLargeStyle(); + activity.PlayPulse(); + activity.Show(); + + _pageBusyDialog.Content = activity; + } + + if (_busyCount > 0) + { + _pageBusyDialog.Show(); + } + else + { + _pageBusyDialog.Dismiss(); + _pageBusyDialog.Unrealize(); + _pageBusyDialog = null; + } + } + + void OnAlertRequest(Page sender, AlertArguments arguments) + { + // Verify that the page making the request is child of this platform + if (!PageIsInThisContext(sender)) + return; + + var alert = Dialog.CreateDialog(MauiContext.Context.NativeParent, (arguments.Accept != null)); + + alert.Title = arguments.Title; + var message = arguments.Message?.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace(Environment.NewLine, "
"); + alert.Message = message; + + var cancel = new EButton(alert) { Text = arguments.Cancel }; + alert.NegativeButton = cancel; + cancel.Clicked += (s, evt) => + { + arguments.SetResult(false); + alert.Dismiss(); + }; + + if (arguments.Accept != null) + { + var 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(); + _alerts.Add(alert); + alert.Dismissed += (s, e) => _alerts.Remove(alert); + } + + void OnActionSheetRequest(Page sender, ActionSheetArguments arguments) + { + // Verify that the page making the request is child of this platform + if (!PageIsInThisContext(sender)) + return; + + var alert = Dialog.CreateDialog(MauiContext.Context.NativeParent); + + alert.Title = arguments.Title; + var box = new EBox(alert); + + if (null != arguments.Destruction) + { + var destruction = new TButton(alert) + { + Text = arguments.Destruction, + AlignmentX = -1 + }; + //TextColor should be set after applying style + destruction.TextColor = TColor.Red; + + destruction.Clicked += (s, evt) => + { + arguments.SetResult(arguments.Destruction); + alert.Dismiss(); + }; + destruction.Show(); + box.PackEnd(destruction); + } + + foreach (string buttonName in arguments.Buttons) + { + var button = new TButton(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) + { + var cancel = new TButton(alert) { Text = arguments.Cancel }; + alert.NegativeButton = cancel; + cancel.Clicked += (s, evt) => + { + alert.Dismiss(); + }; + } + + alert.BackButtonPressed += (s, evt) => + { + alert.Dismiss(); + }; + + alert.Show(); + + _alerts.Add(alert); + alert.Dismissed += (s, e) => _alerts.Remove(alert); + } + + void OnPromptRequested(Page sender, PromptArguments args) + { + // Verify that the page making the request is child of this platform + if (!PageIsInThisContext(sender)) + return; + + var prompt = Dialog.CreateDialog(MauiContext.Context.NativeParent, (args.Accept != null)); + prompt.Title = args.Title; + + var entry = new Entry + { + MinimumWidthRequest = 200, + HorizontalOptions = LayoutOptions.FillAndExpand, + BackgroundColor = GColor.FromRgb(250, 250, 250), + TextColor = GColor.FromRgb(0, 0, 0), + Keyboard = args.Keyboard, + }; + + if (!string.IsNullOrEmpty(args.Placeholder)) + { + entry.Placeholder = args.Placeholder; + } + + if (args.MaxLength > 0) + { + entry.MaxLength = args.MaxLength; + } + + var layout = new VerticalStackLayout + { + Spacing = 10, + }; + layout.Add(new Label + { + LineBreakMode = LineBreakMode.CharacterWrap, + TextColor = Application.AccentColor, + Text = args.Message, + HorizontalOptions = LayoutOptions.FillAndExpand, + HorizontalTextAlignment = TextAlignment.Center, + FontSize = Device.GetNamedSize(NamedSize.Subtitle, typeof(Label)), + }); + layout.Add(entry); + layout.Parent = sender; + var nativeView = layout.ToNative(MauiContext); + + var request = layout.Measure(sender.Width, sender.Height); + (layout.Handler as IRegisterLayoutUpdate)?.RegisterOnLayoutUpdated(); + nativeView.MinimumHeight = request.Request.Height.ToScaledPixel(); + nativeView.MinimumWidth = request.Request.Width.ToScaledPixel(); + + prompt.Content = nativeView; + + var cancel = new EButton(prompt) { Text = args.Cancel }; + prompt.NegativeButton = cancel; + cancel.Clicked += (s, evt) => + { + args.SetResult(null); + prompt.Dismiss(); + }; + + if (args.Accept != null) + { + var ok = new EButton(prompt) { Text = args.Accept }; + prompt.NeutralButton = ok; + ok.Clicked += (s, evt) => + { + args.SetResult(entry.Text); + prompt.Dismiss(); + }; + } + + entry.Completed += (s, e) => + { + args.SetResult(entry.Text); + prompt.Dismiss(); + }; + + prompt.BackButtonPressed += (s, evt) => + { + prompt.Dismiss(); + }; + + prompt.Show(); + + _alerts.Add(prompt); + prompt.Dismissed += (s, e) => _alerts.Remove(prompt); } - internal static void Unsubscribe(Window window) + bool PageIsInThisContext(IPage page) { - //TODO: Need to implementation - //throw new NotImplementedException(); + var context = page.Handler?.MauiContext ?? null; + return context == MauiContext; } } }