Use file-scoped namespace
This commit is contained in:
parent
ea176051c2
commit
45cbe53703
@ -5,3 +5,7 @@
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.cs]
|
||||
|
||||
# Namespace preferences
|
||||
csharp_style_namespace_declarations = file_scoped:warning
|
||||
|
||||
@ -1,25 +1,24 @@
|
||||
using Mopups.Pages;
|
||||
|
||||
namespace Mopups.Interfaces
|
||||
namespace Mopups.Interfaces;
|
||||
|
||||
public interface IPopupNavigation
|
||||
{
|
||||
public interface IPopupNavigation
|
||||
{
|
||||
event EventHandler<PopupPage> Pushing;
|
||||
event EventHandler<PopupPage> Pushing;
|
||||
|
||||
event EventHandler<PopupPage> Pushed;
|
||||
event EventHandler<PopupPage> Pushed;
|
||||
|
||||
event EventHandler<PopupPage> Popping;
|
||||
event EventHandler<PopupPage> Popping;
|
||||
|
||||
event EventHandler<PopupPage> Popped;
|
||||
event EventHandler<PopupPage> Popped;
|
||||
|
||||
IReadOnlyList<PopupPage> PopupStack { get; }
|
||||
IReadOnlyList<PopupPage> PopupStack { get; }
|
||||
|
||||
Task PushAsync(PopupPage page);
|
||||
Task PushAsync(PopupPage page);
|
||||
|
||||
Task PopAsync();
|
||||
Task PopAsync();
|
||||
|
||||
Task PopAllAsync();
|
||||
Task PopAllAsync();
|
||||
|
||||
Task RemovePageAsync(PopupPage page);
|
||||
}
|
||||
Task RemovePageAsync(PopupPage page);
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
using Mopups.Pages;
|
||||
|
||||
namespace Mopups.Interfaces
|
||||
{
|
||||
public interface IPopupPlatform
|
||||
{
|
||||
Task AddAsync(PopupPage page);
|
||||
namespace Mopups.Interfaces;
|
||||
|
||||
Task RemoveAsync(PopupPage page);
|
||||
}
|
||||
public interface IPopupPlatform
|
||||
{
|
||||
Task AddAsync(PopupPage page);
|
||||
|
||||
Task RemoveAsync(PopupPage page);
|
||||
}
|
||||
|
||||
@ -1,78 +1,77 @@
|
||||
using AsyncAwaitBestPractices;
|
||||
using Mopups.Services;
|
||||
|
||||
namespace Mopups.Pages
|
||||
namespace Mopups.Pages;
|
||||
|
||||
public partial class PopupPage : ContentPage
|
||||
{
|
||||
public partial class PopupPage : ContentPage
|
||||
|
||||
public event EventHandler? BackgroundClicked;
|
||||
|
||||
public static readonly BindableProperty CloseWhenBackgroundIsClickedProperty = BindableProperty.Create(nameof(CloseWhenBackgroundIsClicked), typeof(bool), typeof(PopupPage), true);
|
||||
|
||||
public bool CloseWhenBackgroundIsClicked
|
||||
{
|
||||
get { return (bool)GetValue(CloseWhenBackgroundIsClickedProperty); }
|
||||
set { SetValue(CloseWhenBackgroundIsClickedProperty, value); }
|
||||
}
|
||||
|
||||
public event EventHandler? BackgroundClicked;
|
||||
public static readonly BindableProperty BackgroundInputTransparentProperty = BindableProperty.Create(nameof(BackgroundInputTransparent), typeof(bool), typeof(PopupPage), false);
|
||||
|
||||
public static readonly BindableProperty CloseWhenBackgroundIsClickedProperty = BindableProperty.Create(nameof(CloseWhenBackgroundIsClicked), typeof(bool), typeof(PopupPage), true);
|
||||
public bool BackgroundInputTransparent
|
||||
{
|
||||
get { return (bool)GetValue(BackgroundInputTransparentProperty); }
|
||||
set { SetValue(BackgroundInputTransparentProperty, value); }
|
||||
}
|
||||
|
||||
public bool CloseWhenBackgroundIsClicked
|
||||
public static readonly BindableProperty HasKeyboardOffsetProperty = BindableProperty.Create(nameof(HasKeyboardOffset), typeof(bool), typeof(PopupPage), true);
|
||||
|
||||
public bool HasKeyboardOffset
|
||||
{
|
||||
get { return (bool)GetValue(HasKeyboardOffsetProperty); }
|
||||
set { SetValue(HasKeyboardOffsetProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty KeyboardOffsetProperty = BindableProperty.Create(nameof(KeyboardOffset), typeof(double), typeof(PopupPage), 0d, BindingMode.OneWayToSource);
|
||||
|
||||
public double KeyboardOffset
|
||||
{
|
||||
get { return (double)GetValue(KeyboardOffsetProperty); }
|
||||
private set { SetValue(KeyboardOffsetProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public PopupPage()
|
||||
{
|
||||
BackgroundColor = Color.FromArgb("#80000000");
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected override void LayoutChildren(double x, double y, double width, double height)
|
||||
{
|
||||
height -= KeyboardOffset;
|
||||
base.LayoutChildren(x, y, width, height);
|
||||
}
|
||||
|
||||
|
||||
protected virtual bool OnBackgroundClicked()
|
||||
{
|
||||
return CloseWhenBackgroundIsClicked;
|
||||
}
|
||||
|
||||
|
||||
internal void SendBackgroundClick()
|
||||
{
|
||||
BackgroundClicked?.Invoke(this, EventArgs.Empty);
|
||||
if (OnBackgroundClicked())
|
||||
{
|
||||
get { return (bool)GetValue(CloseWhenBackgroundIsClickedProperty); }
|
||||
set { SetValue(CloseWhenBackgroundIsClickedProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty BackgroundInputTransparentProperty = BindableProperty.Create(nameof(BackgroundInputTransparent), typeof(bool), typeof(PopupPage), false);
|
||||
|
||||
public bool BackgroundInputTransparent
|
||||
{
|
||||
get { return (bool)GetValue(BackgroundInputTransparentProperty); }
|
||||
set { SetValue(BackgroundInputTransparentProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty HasKeyboardOffsetProperty = BindableProperty.Create(nameof(HasKeyboardOffset), typeof(bool), typeof(PopupPage), true);
|
||||
|
||||
public bool HasKeyboardOffset
|
||||
{
|
||||
get { return (bool)GetValue(HasKeyboardOffsetProperty); }
|
||||
set { SetValue(HasKeyboardOffsetProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty KeyboardOffsetProperty = BindableProperty.Create(nameof(KeyboardOffset), typeof(double), typeof(PopupPage), 0d, BindingMode.OneWayToSource);
|
||||
|
||||
public double KeyboardOffset
|
||||
{
|
||||
get { return (double)GetValue(KeyboardOffsetProperty); }
|
||||
private set { SetValue(KeyboardOffsetProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public PopupPage()
|
||||
{
|
||||
BackgroundColor = Color.FromArgb("#80000000");
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected override void LayoutChildren(double x, double y, double width, double height)
|
||||
{
|
||||
height -= KeyboardOffset;
|
||||
base.LayoutChildren(x, y, width, height);
|
||||
}
|
||||
|
||||
|
||||
protected virtual bool OnBackgroundClicked()
|
||||
{
|
||||
return CloseWhenBackgroundIsClicked;
|
||||
}
|
||||
|
||||
|
||||
internal void SendBackgroundClick()
|
||||
{
|
||||
BackgroundClicked?.Invoke(this, EventArgs.Empty);
|
||||
if (OnBackgroundClicked())
|
||||
{
|
||||
MopupService.Instance.RemovePageAsync(this).SafeFireAndForget();
|
||||
}
|
||||
MopupService.Instance.RemovePageAsync(this).SafeFireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
using Android.Views;
|
||||
|
||||
namespace Mopups.Droid.Gestures
|
||||
namespace Mopups.Droid.Gestures;
|
||||
|
||||
internal class MopupGestureDetectorListener : GestureDetector.SimpleOnGestureListener
|
||||
{
|
||||
internal class MopupGestureDetectorListener : GestureDetector.SimpleOnGestureListener
|
||||
public event EventHandler<MotionEvent>? Clicked;
|
||||
|
||||
public override bool OnSingleTapUp(MotionEvent? e)
|
||||
{
|
||||
public event EventHandler<MotionEvent>? Clicked;
|
||||
if (e != null) Clicked?.Invoke(this, e);
|
||||
|
||||
public override bool OnSingleTapUp(MotionEvent? e)
|
||||
{
|
||||
if (e != null) Clicked?.Invoke(this, e);
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,18 @@
|
||||
|
||||
using Mopups.Pages;
|
||||
|
||||
using Mopups.Pages;
|
||||
namespace Mopups.Droid.Extension;
|
||||
|
||||
namespace Mopups.Droid.Extension
|
||||
internal static class PlatformExtension
|
||||
{
|
||||
internal static class PlatformExtension
|
||||
public static IViewHandler GetOrCreateHandler(this VisualElement bindable)
|
||||
{
|
||||
public static IViewHandler GetOrCreateHandler(this VisualElement bindable)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
return bindable.Handler ??= new PopupPageHandler();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
return bindable.Handler ??= new PopupPageHandler();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,85 +8,84 @@ using Mopups.Interfaces;
|
||||
using Mopups.Pages;
|
||||
using Mopups.Services;
|
||||
|
||||
namespace Mopups.Droid.Implementation
|
||||
namespace Mopups.Droid.Implementation;
|
||||
|
||||
public class AndroidMopups : IPopupPlatform
|
||||
{
|
||||
public class AndroidMopups : IPopupPlatform
|
||||
|
||||
private static FrameLayout? DecoreView => Platform.CurrentActivity.Window.DecorView as FrameLayout;
|
||||
|
||||
|
||||
public static bool SendBackPressed(Action? backPressedHandler = null)
|
||||
{
|
||||
var popupNavigationInstance = MopupService.Instance;
|
||||
|
||||
private static FrameLayout? DecoreView => Platform.CurrentActivity.Window.DecorView as FrameLayout;
|
||||
|
||||
|
||||
public static bool SendBackPressed(Action? backPressedHandler = null)
|
||||
if (popupNavigationInstance.PopupStack.Count > 0)
|
||||
{
|
||||
var popupNavigationInstance = MopupService.Instance;
|
||||
var lastPage = popupNavigationInstance.PopupStack[popupNavigationInstance.PopupStack.Count - 1];
|
||||
|
||||
if (popupNavigationInstance.PopupStack.Count > 0)
|
||||
var isPreventClose = lastPage.SendBackButtonPressed();
|
||||
|
||||
if (!isPreventClose)
|
||||
{
|
||||
var lastPage = popupNavigationInstance.PopupStack[popupNavigationInstance.PopupStack.Count - 1];
|
||||
|
||||
var isPreventClose = lastPage.SendBackButtonPressed();
|
||||
|
||||
if (!isPreventClose)
|
||||
{
|
||||
popupNavigationInstance.PopAsync().SafeFireAndForget();
|
||||
}
|
||||
|
||||
return true;
|
||||
popupNavigationInstance.PopAsync().SafeFireAndForget();
|
||||
}
|
||||
|
||||
backPressedHandler?.Invoke();
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Task AddAsync(PopupPage page)
|
||||
{
|
||||
try
|
||||
{
|
||||
var decoreView = DecoreView;
|
||||
|
||||
page.Parent = MauiApplication.Current.Application.Windows[0].Content as Element;
|
||||
var AndroidNativeView = page.GetOrCreateHandler().NativeView as Android.Views.View;
|
||||
decoreView?.AddView(AndroidNativeView);
|
||||
return PostAsync(AndroidNativeView);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public Task RemoveAsync(PopupPage page)
|
||||
{
|
||||
var renderer = page.GetOrCreateHandler();
|
||||
if (renderer != null)
|
||||
{
|
||||
|
||||
DecoreView?.RemoveView(renderer.NativeView as Android.Views.View);
|
||||
renderer.DisconnectHandler(); //?? no clue if works
|
||||
page.Parent = null;
|
||||
|
||||
return PostAsync(DecoreView);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Task<bool> PostAsync(Android.Views.View nativeView)
|
||||
{
|
||||
if (nativeView == null)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
||||
nativeView.Post(() => tcs.SetResult(true));
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
|
||||
backPressedHandler?.Invoke();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Task AddAsync(PopupPage page)
|
||||
{
|
||||
try
|
||||
{
|
||||
var decoreView = DecoreView;
|
||||
|
||||
page.Parent = MauiApplication.Current.Application.Windows[0].Content as Element;
|
||||
var AndroidNativeView = page.GetOrCreateHandler().NativeView as Android.Views.View;
|
||||
decoreView?.AddView(AndroidNativeView);
|
||||
return PostAsync(AndroidNativeView);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public Task RemoveAsync(PopupPage page)
|
||||
{
|
||||
var renderer = page.GetOrCreateHandler();
|
||||
if (renderer != null)
|
||||
{
|
||||
|
||||
DecoreView?.RemoveView(renderer.NativeView as Android.Views.View);
|
||||
renderer.DisconnectHandler(); //?? no clue if works
|
||||
page.Parent = null;
|
||||
|
||||
return PostAsync(DecoreView);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Task<bool> PostAsync(Android.Views.View nativeView)
|
||||
{
|
||||
if (nativeView == null)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
||||
nativeView.Post(() => tcs.SetResult(true));
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -5,224 +5,221 @@ using Microsoft.Maui.Handlers;
|
||||
using Microsoft.Maui.Platform;
|
||||
using Mopups.Droid.Gestures;
|
||||
|
||||
namespace Mopups.Pages
|
||||
namespace Mopups.Pages;
|
||||
|
||||
public class PopupPageHandler : ContentViewHandler
|
||||
{
|
||||
public class PopupPageHandler : ContentViewHandler
|
||||
private readonly MopupGestureDetectorListener _gestureDetectorListener;
|
||||
private readonly GestureDetector _gestureDetector;
|
||||
private DateTime _downTime;
|
||||
private Microsoft.Maui.Graphics.Point _downPosition;
|
||||
private bool _disposed;
|
||||
|
||||
public PopupPageHandler()
|
||||
{
|
||||
private readonly MopupGestureDetectorListener _gestureDetectorListener;
|
||||
private readonly GestureDetector _gestureDetector;
|
||||
private DateTime _downTime;
|
||||
private Microsoft.Maui.Graphics.Point _downPosition;
|
||||
private bool _disposed;
|
||||
|
||||
public PopupPageHandler()
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
//--HACK--
|
||||
this.SetMauiContext(new MauiContext(MauiApplication.Current.Services, MauiApplication.Current.ApplicationContext));
|
||||
//
|
||||
_gestureDetectorListener = new MopupGestureDetectorListener();
|
||||
|
||||
_gestureDetectorListener.Clicked += OnBackgroundClick;
|
||||
|
||||
_gestureDetector = new GestureDetector(MauiApplication.Current.ApplicationContext, _gestureDetectorListener);
|
||||
ForceHandlerPauseWaitForVirtualView();
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
//--HACK--
|
||||
void ForceHandlerPauseWaitForVirtualView()
|
||||
this.SetMauiContext(new MauiContext(MauiApplication.Current.Services, MauiApplication.Current.ApplicationContext));
|
||||
//
|
||||
_gestureDetectorListener = new MopupGestureDetectorListener();
|
||||
|
||||
_gestureDetectorListener.Clicked += OnBackgroundClick;
|
||||
|
||||
_gestureDetector = new GestureDetector(MauiApplication.Current.ApplicationContext, _gestureDetectorListener);
|
||||
ForceHandlerPauseWaitForVirtualView();
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
//--HACK--
|
||||
void ForceHandlerPauseWaitForVirtualView()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
Task.Run(async () =>
|
||||
while (this.VirtualView == null)
|
||||
{
|
||||
while (this.VirtualView == null)
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
this.NativeView.LayoutChange += PopupPage_LayoutChange;
|
||||
this.NativeView.Touch += NativeView_Touch;
|
||||
this.NativeView.Touch += NativeView_Touch1;
|
||||
});
|
||||
}
|
||||
await Task.Delay(100);
|
||||
}
|
||||
this.NativeView.LayoutChange += PopupPage_LayoutChange;
|
||||
this.NativeView.Touch += NativeView_Touch;
|
||||
this.NativeView.Touch += NativeView_Touch1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void NativeView_Touch1(object? sender, Android.Views.View.TouchEventArgs e)
|
||||
private void NativeView_Touch1(object? sender, Android.Views.View.TouchEventArgs e)
|
||||
{
|
||||
OnTouchEvent(sender, e.Event);
|
||||
}
|
||||
|
||||
|
||||
private bool OnTouchEvent(object? sender, MotionEvent e)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
OnTouchEvent(sender, e.Event);
|
||||
}
|
||||
|
||||
|
||||
private bool OnTouchEvent(object? sender, MotionEvent e)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var baseValue = (sender as Android.Views.View).OnTouchEvent(e);
|
||||
|
||||
_gestureDetector.OnTouchEvent(e);
|
||||
|
||||
if ((sender as PopupPage)?.BackgroundInputTransparent == true)
|
||||
{
|
||||
OnBackgroundClick(sender, e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnBackgroundClick(object? sender, MotionEvent e)
|
||||
var baseValue = (sender as Android.Views.View).OnTouchEvent(e);
|
||||
|
||||
_gestureDetector.OnTouchEvent(e);
|
||||
|
||||
if ((sender as PopupPage)?.BackgroundInputTransparent == true)
|
||||
{
|
||||
|
||||
var isInRegion = IsInRegion(e.RawX, e.RawY, (sender as Android.Views.View)!);
|
||||
|
||||
if (!isInRegion)
|
||||
(sender as PopupPage).SendBackgroundClick();
|
||||
OnBackgroundClick(sender, e);
|
||||
}
|
||||
|
||||
// Fix for "CloseWhenBackgroundIsClicked not works on Android with Xamarin.Forms 2.4.0.280" #173
|
||||
private bool IsInRegion(float x, float y, Android.Views.View v)
|
||||
{
|
||||
var mCoordBuffer = new int[2];
|
||||
return false;
|
||||
}
|
||||
|
||||
v.GetLocationOnScreen(mCoordBuffer);
|
||||
return mCoordBuffer[0] + v.Width > x && // right edge
|
||||
mCoordBuffer[1] + v.Height > y && // bottom edge
|
||||
mCoordBuffer[0] < x && // left edge
|
||||
mCoordBuffer[1] < y; // top edge
|
||||
}
|
||||
private void OnBackgroundClick(object? sender, MotionEvent e)
|
||||
{
|
||||
|
||||
private void NativeView_Touch(object? sender, Android.Views.View.TouchEventArgs e)
|
||||
var isInRegion = IsInRegion(e.RawX, e.RawY, (sender as Android.Views.View)!);
|
||||
|
||||
if (!isInRegion)
|
||||
(sender as PopupPage).SendBackgroundClick();
|
||||
}
|
||||
|
||||
// Fix for "CloseWhenBackgroundIsClicked not works on Android with Xamarin.Forms 2.4.0.280" #173
|
||||
private bool IsInRegion(float x, float y, Android.Views.View v)
|
||||
{
|
||||
var mCoordBuffer = new int[2];
|
||||
|
||||
v.GetLocationOnScreen(mCoordBuffer);
|
||||
return mCoordBuffer[0] + v.Width > x && // right edge
|
||||
mCoordBuffer[1] + v.Height > y && // bottom edge
|
||||
mCoordBuffer[0] < x && // left edge
|
||||
mCoordBuffer[1] < y; // top edge
|
||||
}
|
||||
|
||||
private void NativeView_Touch(object? sender, Android.Views.View.TouchEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
|
||||
DispatchTouchEvent(e.Event);
|
||||
|
||||
void DispatchTouchEvent(MotionEvent e)
|
||||
{
|
||||
|
||||
DispatchTouchEvent(e.Event);
|
||||
|
||||
void DispatchTouchEvent(MotionEvent e)
|
||||
if (e.Action == MotionEventActions.Down)
|
||||
{
|
||||
_downTime = DateTime.UtcNow;
|
||||
_downPosition = new Point(e.RawX, e.RawY);
|
||||
}
|
||||
if (e.Action != MotionEventActions.Up)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Action == MotionEventActions.Down)
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
Android.Views.View? currentFocus1 = Platform.CurrentActivity.CurrentFocus;
|
||||
|
||||
if (currentFocus1 is Android.Widget.EditText)
|
||||
{
|
||||
Android.Views.View? currentFocus2 = Platform.CurrentActivity.CurrentFocus;
|
||||
if (currentFocus1 == currentFocus2 && _downPosition.Distance(new(e.RawX, e.RawY)) <= Context.ToPixels(20.0) && !(DateTime.UtcNow - _downTime > TimeSpan.FromMilliseconds(200.0)))
|
||||
{
|
||||
_downTime = DateTime.UtcNow;
|
||||
_downPosition = new Point(e.RawX, e.RawY);
|
||||
}
|
||||
if (e.Action != MotionEventActions.Up)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
Android.Views.View? currentFocus1 = Platform.CurrentActivity.CurrentFocus;
|
||||
|
||||
if (currentFocus1 is Android.Widget.EditText)
|
||||
{
|
||||
Android.Views.View? currentFocus2 = Platform.CurrentActivity.CurrentFocus;
|
||||
if (currentFocus1 == currentFocus2 && _downPosition.Distance(new(e.RawX, e.RawY)) <= Context.ToPixels(20.0) && !(DateTime.UtcNow - _downTime > TimeSpan.FromMilliseconds(200.0)))
|
||||
int[] location = new int[2];
|
||||
currentFocus1.GetLocationOnScreen(location);
|
||||
float num1 = e.RawX + currentFocus1.Left - location[0];
|
||||
float num2 = e.RawY + currentFocus1.Top - location[1];
|
||||
if (!new Rectangle(currentFocus1.Left, currentFocus1.Top, currentFocus1.Width, currentFocus1.Height).Contains(num1, num2))
|
||||
{
|
||||
int[] location = new int[2];
|
||||
currentFocus1.GetLocationOnScreen(location);
|
||||
float num1 = e.RawX + currentFocus1.Left - location[0];
|
||||
float num2 = e.RawY + currentFocus1.Top - location[1];
|
||||
if (!new Rectangle(currentFocus1.Left, currentFocus1.Top, currentFocus1.Width, currentFocus1.Height).Contains(num1, num2))
|
||||
{
|
||||
Context.HideKeyboard(currentFocus1);
|
||||
currentFocus1.ClearFocus();
|
||||
}
|
||||
Context.HideKeyboard(currentFocus1);
|
||||
currentFocus1.ClearFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopupPage_LayoutChange(object? sender, Android.Views.View.LayoutChangeEventArgs e)
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = Microsoft.Maui.Essentials.Platform.CurrentActivity;
|
||||
|
||||
Microsoft.Maui.Thickness systemPadding;
|
||||
var keyboardOffset = 0d;
|
||||
|
||||
var decoreView = activity.Window.DecorView;
|
||||
var decoreHeight = decoreView.Height;
|
||||
var decoreWidth = decoreView.Width;
|
||||
|
||||
using var visibleRect = new Android.Graphics.Rect();
|
||||
|
||||
decoreView.GetWindowVisibleDisplayFrame(visibleRect);
|
||||
|
||||
using var screenSize = new Android.Graphics.Point();
|
||||
|
||||
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
|
||||
{
|
||||
|
||||
var windowInsets = activity.WindowManager.DefaultDisplay.Cutout;
|
||||
|
||||
|
||||
var bottomPadding = windowInsets.SafeInsetBottom;
|
||||
|
||||
if (screenSize.Y - visibleRect.Bottom > bottomPadding)
|
||||
{
|
||||
keyboardOffset = Context.FromPixels(screenSize.Y - visibleRect.Bottom);
|
||||
}
|
||||
|
||||
systemPadding = new Microsoft.Maui.Thickness
|
||||
{
|
||||
Left = Context.FromPixels(windowInsets.SafeInsetLeft),
|
||||
Top = Context.FromPixels(windowInsets.SafeInsetTop),
|
||||
Right = Context.FromPixels(windowInsets.SafeInsetRight),
|
||||
Bottom = Context.FromPixels(bottomPadding)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
var keyboardHeight = 0d;
|
||||
|
||||
if (visibleRect.Bottom < screenSize.Y)
|
||||
{
|
||||
keyboardHeight = screenSize.Y - visibleRect.Bottom;
|
||||
keyboardOffset = Context.FromPixels(decoreHeight - visibleRect.Bottom);
|
||||
}
|
||||
|
||||
systemPadding = new Microsoft.Maui.Thickness
|
||||
{
|
||||
Left = Context.FromPixels(visibleRect.Left),
|
||||
Top = Context.FromPixels(visibleRect.Top),
|
||||
Right = Context.FromPixels(decoreWidth - visibleRect.Right),
|
||||
Bottom = Context.FromPixels(decoreHeight - visibleRect.Bottom - keyboardHeight)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//CurrentElement.SetValue(PopupPage.SystemPaddingProperty, systemPadding);
|
||||
//CurrentElement.SetValue(PopupPage.KeyboardOffsetProperty, keyboardOffset);
|
||||
this.NativeView.Layout((int)Context.FromPixels(e.Left), (int)Context.FromPixels(e.Top), (int)Context.FromPixels(e.Right), (int)Context.FromPixels(e.Bottom));
|
||||
this.NativeView.ForceLayout();
|
||||
|
||||
//base.OnLayout(changed, l, t, r, b);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopupPage_LayoutChange(object? sender, Android.Views.View.LayoutChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = Microsoft.Maui.Essentials.Platform.CurrentActivity;
|
||||
|
||||
Microsoft.Maui.Thickness systemPadding;
|
||||
var keyboardOffset = 0d;
|
||||
|
||||
var decoreView = activity.Window.DecorView;
|
||||
var decoreHeight = decoreView.Height;
|
||||
var decoreWidth = decoreView.Width;
|
||||
|
||||
using var visibleRect = new Android.Graphics.Rect();
|
||||
|
||||
decoreView.GetWindowVisibleDisplayFrame(visibleRect);
|
||||
|
||||
using var screenSize = new Android.Graphics.Point();
|
||||
|
||||
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
|
||||
{
|
||||
|
||||
var windowInsets = activity.WindowManager.DefaultDisplay.Cutout;
|
||||
|
||||
|
||||
var bottomPadding = windowInsets.SafeInsetBottom;
|
||||
|
||||
if (screenSize.Y - visibleRect.Bottom > bottomPadding)
|
||||
{
|
||||
keyboardOffset = Context.FromPixels(screenSize.Y - visibleRect.Bottom);
|
||||
}
|
||||
|
||||
systemPadding = new Microsoft.Maui.Thickness
|
||||
{
|
||||
Left = Context.FromPixels(windowInsets.SafeInsetLeft),
|
||||
Top = Context.FromPixels(windowInsets.SafeInsetTop),
|
||||
Right = Context.FromPixels(windowInsets.SafeInsetRight),
|
||||
Bottom = Context.FromPixels(bottomPadding)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
var keyboardHeight = 0d;
|
||||
|
||||
if (visibleRect.Bottom < screenSize.Y)
|
||||
{
|
||||
keyboardHeight = screenSize.Y - visibleRect.Bottom;
|
||||
keyboardOffset = Context.FromPixels(decoreHeight - visibleRect.Bottom);
|
||||
}
|
||||
|
||||
systemPadding = new Microsoft.Maui.Thickness
|
||||
{
|
||||
Left = Context.FromPixels(visibleRect.Left),
|
||||
Top = Context.FromPixels(visibleRect.Top),
|
||||
Right = Context.FromPixels(decoreWidth - visibleRect.Right),
|
||||
Bottom = Context.FromPixels(decoreHeight - visibleRect.Bottom - keyboardHeight)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//CurrentElement.SetValue(PopupPage.SystemPaddingProperty, systemPadding);
|
||||
//CurrentElement.SetValue(PopupPage.KeyboardOffsetProperty, keyboardOffset);
|
||||
this.NativeView.Layout((int)Context.FromPixels(e.Left), (int)Context.FromPixels(e.Top), (int)Context.FromPixels(e.Right), (int)Context.FromPixels(e.Bottom));
|
||||
this.NativeView.ForceLayout();
|
||||
|
||||
//base.OnLayout(changed, l, t, r, b);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,51 +1,50 @@
|
||||
using Mopups.Interfaces;
|
||||
|
||||
namespace Mopups.Services
|
||||
namespace Mopups.Services;
|
||||
|
||||
public static class MopupService
|
||||
{
|
||||
public static class MopupService
|
||||
static IPopupNavigation? _customNavigation;
|
||||
static readonly Lazy<IPopupNavigation> implementation = new(() => CreatePopupNavigation(), System.Threading.LazyThreadSafetyMode.PublicationOnly);
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the plugin is supported on the current platform.
|
||||
/// </summary>
|
||||
public static bool IsSupported => implementation.Value != null;
|
||||
|
||||
/// <summary>
|
||||
/// Current plugin implementation to use
|
||||
/// </summary>
|
||||
public static IPopupNavigation Instance
|
||||
{
|
||||
static IPopupNavigation? _customNavigation;
|
||||
static readonly Lazy<IPopupNavigation> implementation = new(() => CreatePopupNavigation(), System.Threading.LazyThreadSafetyMode.PublicationOnly);
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the plugin is supported on the current platform.
|
||||
/// </summary>
|
||||
public static bool IsSupported => implementation.Value != null;
|
||||
|
||||
/// <summary>
|
||||
/// Current plugin implementation to use
|
||||
/// </summary>
|
||||
public static IPopupNavigation Instance
|
||||
get
|
||||
{
|
||||
get
|
||||
IPopupNavigation lazyEvalPopupNavigation = _customNavigation ?? implementation.Value;
|
||||
if (lazyEvalPopupNavigation == null)
|
||||
{
|
||||
IPopupNavigation lazyEvalPopupNavigation = _customNavigation ?? implementation.Value;
|
||||
if (lazyEvalPopupNavigation == null)
|
||||
{
|
||||
throw NotImplementedInReferenceAssembly();
|
||||
}
|
||||
return lazyEvalPopupNavigation;
|
||||
throw NotImplementedInReferenceAssembly();
|
||||
}
|
||||
return lazyEvalPopupNavigation;
|
||||
}
|
||||
|
||||
public static void SetInstance(IPopupNavigation instance)
|
||||
{
|
||||
_customNavigation = instance;
|
||||
}
|
||||
|
||||
public static void RestoreDefaultInstance()
|
||||
{
|
||||
_customNavigation = null;
|
||||
}
|
||||
|
||||
static IPopupNavigation CreatePopupNavigation()
|
||||
{
|
||||
return new PopupNavigation();
|
||||
}
|
||||
|
||||
internal static Exception NotImplementedInReferenceAssembly() =>
|
||||
new NotImplementedException("This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation.");
|
||||
}
|
||||
|
||||
public static void SetInstance(IPopupNavigation instance)
|
||||
{
|
||||
_customNavigation = instance;
|
||||
}
|
||||
|
||||
public static void RestoreDefaultInstance()
|
||||
{
|
||||
_customNavigation = null;
|
||||
}
|
||||
|
||||
static IPopupNavigation CreatePopupNavigation()
|
||||
{
|
||||
return new PopupNavigation();
|
||||
}
|
||||
|
||||
internal static Exception NotImplementedInReferenceAssembly() =>
|
||||
new NotImplementedException("This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,116 +1,112 @@
|
||||
|
||||
using AsyncAwaitBestPractices;
|
||||
|
||||
|
||||
using AsyncAwaitBestPractices;
|
||||
using Mopups.Interfaces;
|
||||
using Mopups.Pages;
|
||||
|
||||
namespace Mopups.Services
|
||||
namespace Mopups.Services;
|
||||
|
||||
public class PopupNavigation : IPopupNavigation
|
||||
{
|
||||
public class PopupNavigation : IPopupNavigation
|
||||
private readonly object _locker = new();
|
||||
|
||||
public IReadOnlyList<PopupPage> PopupStack => _popupStack;
|
||||
private readonly List<PopupPage> _popupStack = new();
|
||||
|
||||
public event EventHandler<PopupPage> Pushing;
|
||||
|
||||
public event EventHandler<PopupPage> Pushed;
|
||||
|
||||
public event EventHandler<PopupPage> Popping;
|
||||
|
||||
public event EventHandler<PopupPage> Popped;
|
||||
|
||||
|
||||
private static readonly Lazy<IPopupPlatform> lazyImplementation = new(() => GeneratePopupPlatform(), System.Threading.LazyThreadSafetyMode.PublicationOnly);
|
||||
|
||||
private readonly IPopupPlatform PopupPlatform = lazyImplementation.Value;
|
||||
|
||||
private static IPopupPlatform GeneratePopupPlatform()
|
||||
{
|
||||
private readonly object _locker = new();
|
||||
|
||||
public IReadOnlyList<PopupPage> PopupStack => _popupStack;
|
||||
private readonly List<PopupPage> _popupStack = new();
|
||||
|
||||
public event EventHandler<PopupPage> Pushing;
|
||||
|
||||
public event EventHandler<PopupPage> Pushed;
|
||||
|
||||
public event EventHandler<PopupPage> Popping;
|
||||
|
||||
public event EventHandler<PopupPage> Popped;
|
||||
return PullPlatformImplementation();
|
||||
|
||||
|
||||
private static readonly Lazy<IPopupPlatform> lazyImplementation = new(() => GeneratePopupPlatform(), System.Threading.LazyThreadSafetyMode.PublicationOnly);
|
||||
|
||||
private readonly IPopupPlatform PopupPlatform = lazyImplementation.Value;
|
||||
|
||||
private static IPopupPlatform GeneratePopupPlatform()
|
||||
static IPopupPlatform PullPlatformImplementation()
|
||||
{
|
||||
return PullPlatformImplementation();
|
||||
|
||||
|
||||
static IPopupPlatform PullPlatformImplementation()
|
||||
{
|
||||
#if ANDROID
|
||||
return new Mopups.Droid.Implementation.AndroidMopups();
|
||||
return new Mopups.Droid.Implementation.AndroidMopups();
|
||||
#endif
|
||||
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInitialized(object? sender, EventArgs e)
|
||||
private void OnInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
if (_popupStack.Count > 0)
|
||||
{
|
||||
if (_popupStack.Count > 0)
|
||||
PopAllAsync().SafeFireAndForget();
|
||||
}
|
||||
}
|
||||
|
||||
public Task PushAsync(PopupPage page)
|
||||
{
|
||||
Pushing?.Invoke(this, page);
|
||||
_popupStack.Add(page);
|
||||
|
||||
return MainThread.IsMainThread
|
||||
? PushPage()
|
||||
: MainThread.InvokeOnMainThreadAsync(PushPage);
|
||||
|
||||
async Task PushPage()
|
||||
{
|
||||
await PopupPlatform.AddAsync(page);
|
||||
Pushed?.Invoke(this, page);
|
||||
};
|
||||
}
|
||||
|
||||
public async Task PopAllAsync()
|
||||
{
|
||||
while (MopupService.Instance.PopupStack.Count > 0)
|
||||
{
|
||||
await PopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public Task PopAsync()
|
||||
{
|
||||
return _popupStack.Count <= 0
|
||||
? throw new InvalidOperationException("PopupStack is empty")
|
||||
: RemovePageAsync(PopupStack[PopupStack.Count - 1]);
|
||||
}
|
||||
|
||||
public Task RemovePageAsync(PopupPage page)
|
||||
{
|
||||
|
||||
if (page == null)
|
||||
throw new InvalidOperationException("Page can not be null");
|
||||
|
||||
if (!_popupStack.Contains(page))
|
||||
throw new InvalidOperationException("The page has not been pushed yet or has been removed already");
|
||||
|
||||
return (MainThread.IsMainThread
|
||||
? RemovePage()
|
||||
: MainThread.InvokeOnMainThreadAsync(RemovePage));
|
||||
|
||||
|
||||
async Task RemovePage()
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
PopAllAsync().SafeFireAndForget();
|
||||
}
|
||||
}
|
||||
|
||||
public Task PushAsync(PopupPage page)
|
||||
{
|
||||
Pushing?.Invoke(this, page);
|
||||
_popupStack.Add(page);
|
||||
|
||||
return MainThread.IsMainThread
|
||||
? PushPage()
|
||||
: MainThread.InvokeOnMainThreadAsync(PushPage);
|
||||
|
||||
async Task PushPage()
|
||||
{
|
||||
await PopupPlatform.AddAsync(page);
|
||||
Pushed?.Invoke(this, page);
|
||||
};
|
||||
}
|
||||
|
||||
public async Task PopAllAsync()
|
||||
{
|
||||
while (MopupService.Instance.PopupStack.Count > 0)
|
||||
{
|
||||
await PopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public Task PopAsync()
|
||||
{
|
||||
return _popupStack.Count <= 0
|
||||
? throw new InvalidOperationException("PopupStack is empty")
|
||||
: RemovePageAsync(PopupStack[PopupStack.Count - 1]);
|
||||
}
|
||||
|
||||
public Task RemovePageAsync(PopupPage page)
|
||||
{
|
||||
|
||||
if (page == null)
|
||||
throw new InvalidOperationException("Page can not be null");
|
||||
|
||||
if (!_popupStack.Contains(page))
|
||||
throw new InvalidOperationException("The page has not been pushed yet or has been removed already");
|
||||
|
||||
return (MainThread.IsMainThread
|
||||
? RemovePage()
|
||||
: MainThread.InvokeOnMainThreadAsync(RemovePage));
|
||||
|
||||
|
||||
async Task RemovePage()
|
||||
{
|
||||
lock (_locker)
|
||||
if (!_popupStack.Contains(page))
|
||||
{
|
||||
if (!_popupStack.Contains(page))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Popping?.Invoke(this, page);
|
||||
await PopupPlatform.RemoveAsync(page);
|
||||
|
||||
_popupStack.Remove(page);
|
||||
Popped?.Invoke(this, page);
|
||||
}
|
||||
|
||||
Popping?.Invoke(this, page);
|
||||
await PopupPlatform.RemoveAsync(page);
|
||||
|
||||
_popupStack.Remove(page);
|
||||
Popped?.Invoke(this, page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
|
||||
//using Demo.Pages;
|
||||
|
||||
//using Demo.Pages;
|
||||
using SampleMaui.CSharpMarkup;
|
||||
|
||||
using Application = Microsoft.Maui.Controls.Application;
|
||||
|
||||
[assembly: XamlCompilation(XamlCompilationOptions.Skip)]
|
||||
namespace SampleMaui
|
||||
namespace SampleMaui;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public partial class App : Application
|
||||
public App()
|
||||
{
|
||||
public App()
|
||||
{
|
||||
MainPage = new MainPage();
|
||||
}
|
||||
MainPage = new MainPage();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,110 +1,100 @@
|
||||
|
||||
using Mopups.Pages;
|
||||
using Mopups.Pages;
|
||||
using Mopups.Services;
|
||||
using ScrollView = Microsoft.Maui.Controls.ScrollView;
|
||||
|
||||
namespace SampleMaui.CSharpMarkup;
|
||||
|
||||
namespace SampleMaui.CSharpMarkup
|
||||
public partial class LoginPage : PopupPage
|
||||
{
|
||||
public partial class LoginPage : PopupPage
|
||||
public Frame FrameContainer { get; set; }
|
||||
public Image DotNetBotImage { get; set; }
|
||||
|
||||
public Entry UsernameEntry { get; set; }
|
||||
public Entry PasswordEntry { get; set; }
|
||||
|
||||
public Button LoginButton { get; set; }
|
||||
protected void BuildContent()
|
||||
{
|
||||
public Frame FrameContainer { get; set; }
|
||||
public Image DotNetBotImage { get; set; }
|
||||
|
||||
public Entry UsernameEntry { get; set; }
|
||||
public Entry PasswordEntry { get; set; }
|
||||
|
||||
public Microsoft.Maui.Controls.Button LoginButton { get; set; }
|
||||
protected void BuildContent()
|
||||
try
|
||||
{
|
||||
try
|
||||
this.Content = new ScrollView
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
this.Content = new ScrollView
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
BackgroundColor = Color.FromRgb(200.00, 0.00, 0.00),
|
||||
Content = GenerateLoginView()
|
||||
|
||||
};
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private Frame GenerateLoginView()
|
||||
{
|
||||
FrameContainer = new Frame
|
||||
{
|
||||
Margin = new Microsoft.Maui.Thickness(1),
|
||||
Padding = new Microsoft.Maui.Thickness(0),
|
||||
BackgroundColor = Microsoft.Maui.Graphics.Colors.Gray,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
Content = GenerateFrameContainerContent()
|
||||
BackgroundColor = Color.FromRgb(200.00, 0.00, 0.00),
|
||||
Content = GenerateLoginView()
|
||||
|
||||
};
|
||||
return FrameContainer;
|
||||
}
|
||||
private StackLayout GenerateFrameContainerContent()
|
||||
catch (Exception)
|
||||
{
|
||||
var frameContainerContent = new StackLayout
|
||||
{
|
||||
Margin = new Microsoft.Maui.Thickness(1),
|
||||
Padding = new Microsoft.Maui.Thickness(1, 1),
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
|
||||
};
|
||||
/*
|
||||
DotNetBotImage = new Image
|
||||
{
|
||||
|
||||
Margin = new Microsoft.Maui.Thickness(1),
|
||||
BackgroundColor = Microsoft.Maui.Graphics.Colors.White,
|
||||
Scale = 10,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
Source = ImageSource.FromFile("fluent_balloon.svg")
|
||||
};
|
||||
*/
|
||||
UsernameEntry = new Entry
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
Placeholder = "Username",
|
||||
PlaceholderColor = Microsoft.Maui.Graphics.Color.FromHex("#FF9CDAF1"),
|
||||
TextColor = Microsoft.Maui.Graphics.Color.FromHex("#FF7DBBE6")
|
||||
};
|
||||
|
||||
PasswordEntry = new Entry
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
IsPassword = true,
|
||||
Placeholder = "Password",
|
||||
PlaceholderColor = Microsoft.Maui.Graphics.Color.FromHex("#FF9CDAF1"),
|
||||
TextColor = Microsoft.Maui.Graphics.Color.FromHex("#FF7DBBE6")
|
||||
};
|
||||
|
||||
LoginButton = new Button
|
||||
{
|
||||
Command = new Command(() => MopupService.Instance.PopAllAsync())
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
//frameContainerContent.Add(DotNetBotImage);
|
||||
frameContainerContent.Add(UsernameEntry);
|
||||
frameContainerContent.Add(PasswordEntry);
|
||||
frameContainerContent.Add(LoginButton);
|
||||
|
||||
return frameContainerContent;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private Frame GenerateLoginView()
|
||||
{
|
||||
FrameContainer = new Frame
|
||||
{
|
||||
Margin = new Microsoft.Maui.Thickness(1),
|
||||
Padding = new Microsoft.Maui.Thickness(0),
|
||||
BackgroundColor = Microsoft.Maui.Graphics.Colors.Gray,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
Content = GenerateFrameContainerContent()
|
||||
};
|
||||
return FrameContainer;
|
||||
}
|
||||
|
||||
private StackLayout GenerateFrameContainerContent()
|
||||
{
|
||||
var frameContainerContent = new StackLayout
|
||||
{
|
||||
Margin = new Microsoft.Maui.Thickness(1),
|
||||
Padding = new Microsoft.Maui.Thickness(1, 1),
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
|
||||
};
|
||||
/*
|
||||
DotNetBotImage = new Image
|
||||
{
|
||||
|
||||
Margin = new Microsoft.Maui.Thickness(1),
|
||||
BackgroundColor = Microsoft.Maui.Graphics.Colors.White,
|
||||
Scale = 10,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
Source = ImageSource.FromFile("fluent_balloon.svg")
|
||||
};
|
||||
*/
|
||||
UsernameEntry = new Entry
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
Placeholder = "Username",
|
||||
PlaceholderColor = Color.FromHex("#FF9CDAF1"),
|
||||
TextColor = Color.FromHex("#FF7DBBE6")
|
||||
};
|
||||
|
||||
PasswordEntry = new Entry
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
IsPassword = true,
|
||||
Placeholder = "Password",
|
||||
PlaceholderColor = Color.FromHex("#FF9CDAF1"),
|
||||
TextColor = Color.FromHex("#FF7DBBE6")
|
||||
};
|
||||
|
||||
LoginButton = new Button
|
||||
{
|
||||
Command = new Command(() => MopupService.Instance.PopAllAsync())
|
||||
};
|
||||
|
||||
//frameContainerContent.Add(DotNetBotImage);
|
||||
frameContainerContent.Add(UsernameEntry);
|
||||
frameContainerContent.Add(PasswordEntry);
|
||||
frameContainerContent.Add(LoginButton);
|
||||
|
||||
return frameContainerContent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,16 @@
|
||||
|
||||
using Mopups.Pages;
|
||||
using Mopups.Pages;
|
||||
|
||||
namespace SampleMaui.CSharpMarkup
|
||||
namespace SampleMaui.CSharpMarkup;
|
||||
|
||||
public partial class LoginPage : PopupPage
|
||||
{
|
||||
public partial class LoginPage : PopupPage
|
||||
public LoginPage()
|
||||
{
|
||||
public LoginPage()
|
||||
{
|
||||
BuildContent();
|
||||
BuildContent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override bool OnBackgroundClicked()
|
||||
{
|
||||
return base.OnBackgroundClicked();
|
||||
}
|
||||
protected override bool OnBackgroundClicked()
|
||||
{
|
||||
return base.OnBackgroundClicked();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,65 +1,60 @@
|
||||
|
||||
using AsyncAwaitBestPractices.MVVM;
|
||||
using AsyncAwaitBestPractices.MVVM;
|
||||
using Mopups.Pages;
|
||||
using Mopups.Services;
|
||||
using Button = Microsoft.Maui.Controls.Button;
|
||||
using ScrollView = Microsoft.Maui.Controls.ScrollView;
|
||||
|
||||
namespace SampleMaui.CSharpMarkup
|
||||
namespace SampleMaui.CSharpMarkup;
|
||||
|
||||
public partial class MainPage : ContentPage
|
||||
{
|
||||
public partial class MainPage : ContentPage
|
||||
protected void BuildContent()
|
||||
{
|
||||
protected void BuildContent()
|
||||
BackgroundColor = Color.FromRgb(255, 255, 255);
|
||||
Title = "Popup Demo";
|
||||
Content = new ScrollView
|
||||
{
|
||||
BackgroundColor = Color.FromRgb(255, 255, 255);
|
||||
Title = "Popup Demo";
|
||||
Content = new ScrollView
|
||||
{
|
||||
VerticalOptions = LayoutOptions.FillAndExpand,
|
||||
Content = GenerateMainPageStackLayout()
|
||||
};
|
||||
}
|
||||
VerticalOptions = LayoutOptions.FillAndExpand,
|
||||
Content = GenerateMainPageStackLayout()
|
||||
};
|
||||
}
|
||||
|
||||
private StackLayout GenerateMainPageStackLayout()
|
||||
private StackLayout GenerateMainPageStackLayout()
|
||||
{
|
||||
var mainStackLayout = new StackLayout
|
||||
{
|
||||
var mainStackLayout = new StackLayout
|
||||
{
|
||||
Spacing = 20,
|
||||
Margin = new Microsoft.Maui.Thickness(10, 15)
|
||||
};
|
||||
mainStackLayout.Add(GeneratePopupButton("Open Popup", GenerateSimpleCommandForPopup<LoginPage>()));
|
||||
return mainStackLayout;
|
||||
}
|
||||
Spacing = 20,
|
||||
Margin = new Microsoft.Maui.Thickness(10, 15)
|
||||
};
|
||||
mainStackLayout.Add(GeneratePopupButton("Open Popup", GenerateSimpleCommandForPopup<LoginPage>()));
|
||||
return mainStackLayout;
|
||||
}
|
||||
|
||||
private static Button GeneratePopupButton(string buttonText, AsyncCommand buttonCommand)
|
||||
private static Button GeneratePopupButton(string buttonText, AsyncCommand buttonCommand)
|
||||
{
|
||||
return new Button
|
||||
{
|
||||
return new Button
|
||||
{
|
||||
Text = buttonText,
|
||||
BackgroundColor = Color.FromHex("#FF7DBBE6"),
|
||||
TextColor = Color.FromRgb(255, 255, 255),
|
||||
Command = buttonCommand,
|
||||
};
|
||||
}
|
||||
Text = buttonText,
|
||||
BackgroundColor = Color.FromHex("#FF7DBBE6"),
|
||||
TextColor = Color.FromRgb(255, 255, 255),
|
||||
Command = buttonCommand,
|
||||
};
|
||||
}
|
||||
|
||||
private static AsyncCommand GenerateSimpleCommandForPopup<TPopupPage>() where TPopupPage : PopupPage, new()
|
||||
private static AsyncCommand GenerateSimpleCommandForPopup<TPopupPage>() where TPopupPage : PopupPage, new()
|
||||
{
|
||||
return new AsyncCommand(async () =>
|
||||
{
|
||||
return new AsyncCommand(async () =>
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var page = new TPopupPage();
|
||||
await MopupService.Instance.PushAsync(page);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var page = new TPopupPage();
|
||||
await MopupService.Instance.PushAsync(page);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,23 +1,22 @@
|
||||
using Mopups.Services;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SampleMaui.CSharpMarkup
|
||||
namespace SampleMaui.CSharpMarkup;
|
||||
|
||||
public partial class MainPage : ContentPage
|
||||
{
|
||||
public partial class MainPage : ContentPage
|
||||
public MainPage()
|
||||
{
|
||||
public MainPage()
|
||||
{
|
||||
BuildContent();
|
||||
BuildContent();
|
||||
|
||||
MopupService.Instance.Pushing += (sender, e) => Debug.WriteLine($"[Popup] Pushing: {e.GetType().Name}");
|
||||
MopupService.Instance.Pushed += (sender, e) => Debug.WriteLine($"[Popup] Pushed: {e.GetType().Name}");
|
||||
MopupService.Instance.Popping += (sender, e) => Debug.WriteLine($"[Popup] Popping: {e.GetType().Name}");
|
||||
MopupService.Instance.Popped += (sender, e) => Debug.WriteLine($"[Popup] Popped: {e.GetType().Name}");
|
||||
}
|
||||
MopupService.Instance.Pushing += (sender, e) => Debug.WriteLine($"[Popup] Pushing: {e.GetType().Name}");
|
||||
MopupService.Instance.Pushed += (sender, e) => Debug.WriteLine($"[Popup] Pushed: {e.GetType().Name}");
|
||||
MopupService.Instance.Popping += (sender, e) => Debug.WriteLine($"[Popup] Popping: {e.GetType().Name}");
|
||||
MopupService.Instance.Popped += (sender, e) => Debug.WriteLine($"[Popup] Popped: {e.GetType().Name}");
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,22 +1,21 @@
|
||||
using Mopups.Hosting;
|
||||
|
||||
namespace SampleMaui
|
||||
{
|
||||
public static class MauiProgram
|
||||
{
|
||||
public static MauiApp CreateMauiApp()
|
||||
{
|
||||
var builder = MauiApp.CreateBuilder();
|
||||
builder
|
||||
.UseMauiApp<App>()
|
||||
.ConfigureFonts(fonts =>
|
||||
{
|
||||
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
||||
})
|
||||
.ConfigureMopups();
|
||||
namespace SampleMaui;
|
||||
|
||||
//Work out how to register this as a singleton
|
||||
return builder.Build();
|
||||
}
|
||||
public static class MauiProgram
|
||||
{
|
||||
public static MauiApp CreateMauiApp()
|
||||
{
|
||||
var builder = MauiApp.CreateBuilder();
|
||||
builder
|
||||
.UseMauiApp<App>()
|
||||
.ConfigureFonts(fonts =>
|
||||
{
|
||||
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
||||
})
|
||||
.ConfigureMopups();
|
||||
|
||||
//Work out how to register this as a singleton
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
|
||||
namespace SampleMaui
|
||||
namespace SampleMaui;
|
||||
|
||||
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
|
||||
public class MainActivity : MauiAppCompatActivity
|
||||
{
|
||||
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
|
||||
public class MainActivity : MauiAppCompatActivity
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
using Android.App;
|
||||
using Android.Runtime;
|
||||
|
||||
namespace SampleMaui
|
||||
{
|
||||
[Application]
|
||||
public class MainApplication : MauiApplication
|
||||
{
|
||||
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
|
||||
: base(handle, ownership)
|
||||
{
|
||||
Microsoft.Maui.Essentials.Platform.Init(Current);
|
||||
}
|
||||
namespace SampleMaui;
|
||||
|
||||
protected override MauiApp CreateMauiApp()
|
||||
{
|
||||
return MauiProgram.CreateMauiApp();
|
||||
}
|
||||
[Application]
|
||||
public class MainApplication : MauiApplication
|
||||
{
|
||||
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
|
||||
: base(handle, ownership)
|
||||
{
|
||||
Microsoft.Maui.Essentials.Platform.Init(Current);
|
||||
}
|
||||
|
||||
protected override MauiApp CreateMauiApp()
|
||||
{
|
||||
return MauiProgram.CreateMauiApp();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user