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();
- }
- }
- }
|