@@ -14,12 +14,13 @@ namespace Ursa.Controls;
|
||||
|
||||
[TemplatePart(PART_CloseButton, typeof(Button))]
|
||||
[TemplatePart(PART_TitleArea, typeof(Panel))]
|
||||
[PseudoClasses(PC_Modal)]
|
||||
[PseudoClasses(PC_Modal, PC_FullScreen)]
|
||||
public abstract class DialogControlBase : OverlayFeedbackElement
|
||||
{
|
||||
public const string PART_CloseButton = "PART_CloseButton";
|
||||
public const string PART_TitleArea = "PART_TitleArea";
|
||||
public const string PC_Modal = ":modal";
|
||||
public const string PC_FullScreen = ":full-screen";
|
||||
|
||||
internal HorizontalPosition HorizontalAnchor { get; set; } = HorizontalPosition.Center;
|
||||
internal VerticalPosition VerticalAnchor { get; set; } = VerticalPosition.Center;
|
||||
@@ -30,7 +31,17 @@ public abstract class DialogControlBase : OverlayFeedbackElement
|
||||
internal double? HorizontalOffsetRatio { get; set; }
|
||||
internal double? VerticalOffsetRatio { get; set; }
|
||||
internal bool CanLightDismiss { get; set; }
|
||||
internal bool CanDragMove { get; set; }
|
||||
|
||||
private bool _isFullScreen;
|
||||
|
||||
public static readonly DirectProperty<DialogControlBase, bool> IsFullScreenProperty = AvaloniaProperty.RegisterDirect<DialogControlBase, bool>(
|
||||
nameof(IsFullScreen), o => o.IsFullScreen, (o, v) => o.IsFullScreen = v);
|
||||
|
||||
public bool IsFullScreen
|
||||
{
|
||||
get => _isFullScreen;
|
||||
set => SetAndRaise(IsFullScreenProperty, ref _isFullScreen, value);
|
||||
}
|
||||
|
||||
protected internal Button? _closeButton;
|
||||
private Panel? _titleArea;
|
||||
@@ -134,6 +145,7 @@ public abstract class DialogControlBase : OverlayFeedbackElement
|
||||
{
|
||||
CanDragMoveProperty.Changed.AddClassHandler<InputElement, bool>(OnCanDragMoveChanged);
|
||||
CanCloseProperty.Changed.AddClassHandler<InputElement, bool>(OnCanCloseChanged);
|
||||
IsFullScreenProperty.AffectsPseudoClass<DialogControlBase>(PC_FullScreen);
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +155,7 @@ public abstract class DialogControlBase : OverlayFeedbackElement
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
_titleArea = e.NameScope.Find<Panel>(PART_TitleArea);
|
||||
if (CanDragMove)
|
||||
if (GetCanDragMove(this))
|
||||
{
|
||||
_titleArea?.RemoveHandler(PointerMovedEvent, OnTitlePointerMove);
|
||||
_titleArea?.RemoveHandler(PointerPressedEvent, OnTitlePointerPressed);
|
||||
|
||||
@@ -17,6 +17,7 @@ public enum VerticalPosition
|
||||
public class OverlayDialogOptions
|
||||
{
|
||||
internal static OverlayDialogOptions Default { get; } = new OverlayDialogOptions();
|
||||
public bool FullScreen { get; set; }
|
||||
public HorizontalPosition HorizontalAnchor { get; set; } = HorizontalPosition.Center;
|
||||
public VerticalPosition VerticalAnchor { get; set; } = VerticalPosition.Center;
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Layout;
|
||||
using Ursa.Common;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
@@ -181,6 +182,12 @@ public static class OverlayDialog
|
||||
private static void ConfigureCustomDialogControl(CustomDialogControl control, OverlayDialogOptions? options)
|
||||
{
|
||||
options ??= OverlayDialogOptions.Default;
|
||||
control.IsFullScreen = options.FullScreen;
|
||||
if (options.FullScreen)
|
||||
{
|
||||
control.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||
control.VerticalAlignment = VerticalAlignment.Stretch;
|
||||
}
|
||||
control.HorizontalAnchor = options.HorizontalAnchor;
|
||||
control.VerticalAnchor = options.VerticalAnchor;
|
||||
control.ActualHorizontalAnchor = options.HorizontalAnchor;
|
||||
@@ -191,12 +198,18 @@ public static class OverlayDialog
|
||||
options.VerticalAnchor == VerticalPosition.Center ? null : options.VerticalOffset;
|
||||
control.IsCloseButtonVisible = options.ShowCloseButton;
|
||||
control.CanLightDismiss = options.CanLightDismiss;
|
||||
control.CanDragMove = options.CanDragMove;
|
||||
DialogControlBase.SetCanDragMove(control, options.CanDragMove);
|
||||
}
|
||||
|
||||
private static void ConfigureDefaultDialogControl(DefaultDialogControl control, OverlayDialogOptions? options)
|
||||
{
|
||||
if (options is null) options = new OverlayDialogOptions();
|
||||
control.IsFullScreen = options.FullScreen;
|
||||
if (options.FullScreen)
|
||||
{
|
||||
control.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||
control.VerticalAlignment = VerticalAlignment.Stretch;
|
||||
}
|
||||
control.HorizontalAnchor = options.HorizontalAnchor;
|
||||
control.VerticalAnchor = options.VerticalAnchor;
|
||||
control.ActualHorizontalAnchor = options.HorizontalAnchor;
|
||||
@@ -209,7 +222,7 @@ public static class OverlayDialog
|
||||
control.Buttons = options.Buttons;
|
||||
control.Title = options.Title;
|
||||
control.CanLightDismiss = options.CanLightDismiss;
|
||||
control.CanDragMove = options.CanDragMove;
|
||||
DialogControlBase.SetCanDragMove(control, options.CanDragMove);
|
||||
}
|
||||
|
||||
internal static T? Recall<T>(string? hostId) where T: Control
|
||||
|
||||
@@ -14,6 +14,14 @@ public partial class OverlayDialogHost
|
||||
|
||||
private static void ResetDialogPosition(DialogControlBase control, Size newSize)
|
||||
{
|
||||
if (control.IsFullScreen)
|
||||
{
|
||||
control.Width = newSize.Width;
|
||||
control.Height = newSize.Height;
|
||||
SetLeft(control, 0);
|
||||
SetTop(control, 0);
|
||||
return;
|
||||
}
|
||||
var width = newSize.Width - control.Bounds.Width;
|
||||
var height = newSize.Height - control.Bounds.Height;
|
||||
var newLeft = width * control.HorizontalOffsetRatio??0;
|
||||
@@ -84,6 +92,11 @@ public partial class OverlayDialogHost
|
||||
}
|
||||
this.Children.Add(control);
|
||||
_layers.Add(new DialogPair(mask, control, false));
|
||||
if (control.IsFullScreen)
|
||||
{
|
||||
control.Width = Bounds.Width;
|
||||
control.Height = Bounds.Height;
|
||||
}
|
||||
control.Measure(this.Bounds.Size);
|
||||
control.Arrange(new Rect(control.DesiredSize));
|
||||
SetToPosition(control);
|
||||
@@ -113,7 +126,10 @@ public partial class OverlayDialogHost
|
||||
{
|
||||
_modalCount--;
|
||||
HasModal = _modalCount > 0;
|
||||
await _maskDisappearAnimation.RunAsync(layer.Mask);
|
||||
if (!IsAnimationDisabled)
|
||||
{
|
||||
await _maskDisappearAnimation.RunAsync(layer.Mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,12 +149,20 @@ public partial class OverlayDialogHost
|
||||
ResetZIndices();
|
||||
this.Children.Add(mask);
|
||||
this.Children.Add(control);
|
||||
if (control.IsFullScreen)
|
||||
{
|
||||
control.Width = Bounds.Width;
|
||||
control.Height = Bounds.Height;
|
||||
}
|
||||
control.Measure(this.Bounds.Size);
|
||||
control.Arrange(new Rect(control.DesiredSize));
|
||||
SetToPosition(control);
|
||||
control.AddHandler(OverlayFeedbackElement.ClosedEvent, OnDialogControlClosing);
|
||||
control.AddHandler(DialogControlBase.LayerChangedEvent, OnDialogLayerChanged);
|
||||
_maskAppearAnimation.RunAsync(mask);
|
||||
if (!IsAnimationDisabled)
|
||||
{
|
||||
_maskAppearAnimation.RunAsync(mask);
|
||||
}
|
||||
_modalCount++;
|
||||
HasModal = _modalCount > 0;
|
||||
control.IsClosed = false;
|
||||
|
||||
@@ -28,13 +28,20 @@ public partial class OverlayDialogHost
|
||||
SetDrawerPosition(control);
|
||||
control.AddHandler(OverlayFeedbackElement.ClosedEvent, OnDrawerControlClosing);
|
||||
var animation = CreateAnimation(control.Bounds.Size, control.Position, true);
|
||||
if (mask is null)
|
||||
if (IsAnimationDisabled)
|
||||
{
|
||||
await animation.RunAsync(control);
|
||||
ResetDrawerPosition(control, this.Bounds.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.WhenAll(animation.RunAsync(control), _maskAppearAnimation.RunAsync(mask));
|
||||
if (mask is null)
|
||||
{
|
||||
await animation.RunAsync(control);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.WhenAll(animation.RunAsync(control), _maskAppearAnimation.RunAsync(mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,9 +55,18 @@ public partial class OverlayDialogHost
|
||||
control.Measure(this.Bounds.Size);
|
||||
control.Arrange(new Rect(control.DesiredSize));
|
||||
SetDrawerPosition(control);
|
||||
_modalCount++;
|
||||
HasModal = _modalCount > 0;
|
||||
control.AddHandler(OverlayFeedbackElement.ClosedEvent, OnDrawerControlClosing);
|
||||
var animation = CreateAnimation(control.Bounds.Size, control.Position);
|
||||
await Task.WhenAll(animation.RunAsync(control), _maskAppearAnimation.RunAsync(mask));
|
||||
if (IsAnimationDisabled)
|
||||
{
|
||||
ResetDrawerPosition(control, this.Bounds.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.WhenAll(animation.RunAsync(control), _maskAppearAnimation.RunAsync(mask));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDrawerPosition(DrawerControlBase control)
|
||||
@@ -145,15 +161,23 @@ public partial class OverlayDialogHost
|
||||
control.RemoveHandler(DialogControlBase.LayerChangedEvent, OnDialogLayerChanged);
|
||||
if (layer.Mask is not null)
|
||||
{
|
||||
_modalCount--;
|
||||
HasModal = _modalCount > 0;
|
||||
layer.Mask.RemoveHandler(PointerPressedEvent, ClickMaskToCloseDialog);
|
||||
var disappearAnimation = CreateAnimation(control.Bounds.Size, control.Position, false);
|
||||
await Task.WhenAll(disappearAnimation.RunAsync(control), _maskDisappearAnimation.RunAsync(layer.Mask));
|
||||
if (!IsAnimationDisabled)
|
||||
{
|
||||
var disappearAnimation = CreateAnimation(control.Bounds.Size, control.Position, false);
|
||||
await Task.WhenAll(disappearAnimation.RunAsync(control), _maskDisappearAnimation.RunAsync(layer.Mask));
|
||||
}
|
||||
Children.Remove(layer.Mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
var disappearAnimation = CreateAnimation(control.Bounds.Size, control.Position, false);
|
||||
await disappearAnimation.RunAsync(control);
|
||||
if (!IsAnimationDisabled)
|
||||
{
|
||||
var disappearAnimation = CreateAnimation(control.Bounds.Size, control.Position, false);
|
||||
await disappearAnimation.RunAsync(control);
|
||||
}
|
||||
}
|
||||
Children.Remove(control);
|
||||
ResetZIndices();
|
||||
|
||||
@@ -15,7 +15,7 @@ public partial class OverlayDialogHost: Canvas
|
||||
private static readonly Animation _maskAppearAnimation;
|
||||
private static readonly Animation _maskDisappearAnimation;
|
||||
|
||||
private readonly List<DialogPair> _layers = new List<DialogPair>();
|
||||
private readonly List<DialogPair> _layers = new List<DialogPair>(10);
|
||||
|
||||
private class DialogPair
|
||||
{
|
||||
@@ -43,6 +43,8 @@ public partial class OverlayDialogHost: Canvas
|
||||
get => _hasModal;
|
||||
private set => SetAndRaise(HasModalProperty, ref _hasModal, value);
|
||||
}
|
||||
|
||||
public bool IsAnimationDisabled { get; set; }
|
||||
|
||||
static OverlayDialogHost()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user