| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 | using System;using Syncfusion.XForms.PopupLayout;using Xamarin.Forms;namespace InABox.Mobile{    public interface IPopupManager    {        bool Initialise();            }    public class PopupManagerConfiguration    {        public static double? DefaultHeight => 700;        public static double? DefaultWidth => 350;        public static double? AutoSize => null;                public static RelativePosition? CenterOnScreen => null;                public double? RequestedHeight { get; set; } = DefaultHeight;        public double? RequestedWidth { get; set; } = DefaultWidth;                public AutoSizeMode SizeMode        {            get => (Equals(RequestedHeight,AutoSize) && Equals(RequestedWidth,AutoSize))                ? AutoSizeMode.Both                : Equals(RequestedHeight,AutoSize)                    ? AutoSizeMode.Height                    : Equals(RequestedWidth,AutoSize)                        ? AutoSizeMode.Width                        : AutoSizeMode.None;            set            {                RequestedHeight = value is AutoSizeMode.Both or AutoSizeMode.Height ? AutoSize : DefaultHeight;                RequestedWidth = value is AutoSizeMode.Both or AutoSizeMode.Width ? AutoSize : DefaultWidth;            }        }                public bool ShowHeader { get; set; } = false;        public bool ShowFooter { get; set; } = false;        public int Padding { get; set; } = 10;        public int CornerRadius { get; set; } = 5;        public bool Modal { get; set; } = false;        public RelativePosition? Position { get; set; } = CenterOnScreen;    }        public static class PopupManager    {                private static SfPopupLayout _popup = null;                private static ContentPage FindParentPage(Element view)        {            if (view is ContentPage page)                return page;            return FindParentPage(view.Parent);        }                public static void DisplayError(Element view, string message)        {            MobileLogging.Log("Unable to create Popup Layout!");            var page = FindParentPage(view);            Device.BeginInvokeOnMainThread(() =>            {                 page.DisplayAlert("Error", message, "OK");            });         }        public static bool Initialise()        {            var service = DependencyService.Get<IPopupManager>();            return service?.Initialise() == true;        }        public static void ShowPopup(VisualElement parent, Func<View> view, PopupManagerConfiguration config = null)        {                        if (_popup == null && Initialise())                _popup = new SfPopupLayout();            if (_popup == null)            {                DisplayError(parent, "Unable to create Popup!\nPlease try again or restart the application.");                return;            }            var cfg = config ?? new PopupManagerConfiguration();                        _popup.PopupView.AutoSizeMode = cfg.SizeMode;            if (Equals(cfg.RequestedHeight, PopupManagerConfiguration.AutoSize))                _popup.PopupView.ClearValue(VisualElement.HeightRequestProperty);            else                _popup.PopupView.HeightRequest = cfg.RequestedHeight!.Value;                        if (Equals(cfg.RequestedWidth, PopupManagerConfiguration.AutoSize))                _popup.PopupView.ClearValue(VisualElement.WidthRequestProperty);            else                _popup.PopupView.WidthRequest = cfg.RequestedWidth!.Value;                        _popup.PopupView.ShowHeader = cfg.ShowHeader;            _popup.PopupView.ShowFooter = cfg.ShowFooter;            _popup.PopupView.PopupStyle.CornerRadius = cfg.CornerRadius;            _popup.StaysOpen = cfg.Modal;                        _popup.PopupView.ContentTemplate = new DataTemplate(() =>            {                Grid grid = new Grid() { Padding = cfg.Padding };                grid.Children.Add(view());                return grid;            });                        if (parent is View pView && cfg.Position != PopupManagerConfiguration.CenterOnScreen)            {                var offset = GetOffset(parent, cfg.Position!.Value);                 _popup.ShowRelativeToView(pView, cfg.Position!.Value, offset.X, offset.Y);            }            else                _popup.Show();        }                /// <summary>        /// Calculates the offest of the Menu to position it at the center of the Button        ///  Let's not presume that all the calculations are correct - its only been tested        /// against AlignToLeftOf (for top-right-hand side menu options         /// </summary>        /// <param name="x"></param>        /// <param name="y"></param>        private static Point GetOffset(VisualElement parent, RelativePosition Position)        {            return Position switch            {                // Displays the popup at the top of the given view.                RelativePosition.AlignTop => new Point(parent.Width / 2F, parent.Height / 2F),                // Displays the popup to the left of the given view.</summary>                RelativePosition.AlignToLeftOf => new Point(parent.Width / 2F, parent.Height / 2F),                // Displays the popup to the right of the given view.</summary>                RelativePosition.AlignToRightOf => new Point(0F - (parent.Width / 2F), parent.Height / 2F),                // Displays the popup at the bottom of the given view.</summary>                RelativePosition.AlignBottom => new Point(parent.Width / 2F, 0F - (parent.Height / 2F)),                // Displays the popup at the top left position of the given view.                RelativePosition.AlignTopLeft => new Point(parent.Width / 2F, parent.Height / 2F),                // Displays the popup at the top right position of the given view.                RelativePosition.AlignTopRight => new Point(0F - (parent.Width / 2F), parent.Height / 2F),                // Displays the popup at the bottom left position of the given view.                RelativePosition.AlignBottomLeft => new Point(0F - (parent.Width / 2F), parent.Height / 2F),                // Displays the popup at the bottom right position of the given view.                RelativePosition.AlignBottomRight => new Point(0F - (parent.Width / 2F), 0F - (parent.Height / 2F)),                _ => new Point()            };        }        public static void DismissPopup()        {            if (_popup != null)                _popup.Dismiss();        }    }}
 |