feat: refactor layer storage and index reset rule.
This commit is contained in:
@@ -4,11 +4,12 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d" d:DesignWidth="800"
|
mc:Ignorable="d" d:DesignWidth="800"
|
||||||
xmlns:vm="clr-namespace:Ursa.Demo.ViewModels;assembly=Ursa.Demo"
|
xmlns:vm="clr-namespace:Ursa.Demo.ViewModels;assembly=Ursa.Demo"
|
||||||
|
xmlns:u="https://irihi.tech/ursa"
|
||||||
x:DataType="vm:DrawerDemoViewModel"
|
x:DataType="vm:DrawerDemoViewModel"
|
||||||
x:CompileBindings="True"
|
x:CompileBindings="True"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
x:Class="Ursa.Demo.Pages.DrawerDemo">
|
x:Class="Ursa.Demo.Pages.DrawerDemo">
|
||||||
<StackPanel HorizontalAlignment="Left">
|
<Canvas HorizontalAlignment="Left" Width="500">
|
||||||
<Button Content="Call Drawer" Command="{Binding OpenDrawerCommand}"></Button>
|
<Button Content="Call Drawer" HorizontalAlignment="Stretch" Command="{Binding OpenDrawerCommand}"></Button>
|
||||||
</StackPanel>
|
</Canvas>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -59,8 +59,7 @@
|
|||||||
<Setter Property="ContextFlyout">
|
<Setter Property="ContextFlyout">
|
||||||
<MenuFlyout>
|
<MenuFlyout>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].CloseDialog}"
|
Command="{Binding $parent[u:DialogControlBase].Close}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
|
||||||
Header="{DynamicResource STRING_MENU_DIALOG_CLOSE}">
|
Header="{DynamicResource STRING_MENU_DIALOG_CLOSE}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<PathIcon
|
<PathIcon
|
||||||
@@ -76,7 +75,7 @@
|
|||||||
<Setter Property="ContextFlyout">
|
<Setter Property="ContextFlyout">
|
||||||
<MenuFlyout>
|
<MenuFlyout>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].UpdateLayer}"
|
Command="{Binding $parent[u:DialogControlBase].UpdateLayer}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
||||||
Header="{DynamicResource STRING_MENU_BRING_FORWARD}">
|
Header="{DynamicResource STRING_MENU_BRING_FORWARD}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@@ -87,7 +86,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].UpdateLayer}"
|
Command="{Binding $parent[u:DialogControlBase].UpdateLayer}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.BringToFront}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.BringToFront}"
|
||||||
Header="{DynamicResource STRING_MENU_BRING_TO_FRONT}">
|
Header="{DynamicResource STRING_MENU_BRING_TO_FRONT}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@@ -98,7 +97,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].UpdateLayer}"
|
Command="{Binding $parent[u:DialogControlBase].UpdateLayer}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.SendBackward}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.SendBackward}"
|
||||||
Header="{DynamicResource STRING_MENU_SEND_BACKWARD}">
|
Header="{DynamicResource STRING_MENU_SEND_BACKWARD}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@@ -109,7 +108,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].UpdateLayer}"
|
Command="{Binding $parent[u:DialogControlBase].UpdateLayer}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.SendToBack}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.SendToBack}"
|
||||||
Header="{DynamicResource STRING_MENU_SEND_TO_BACK}">
|
Header="{DynamicResource STRING_MENU_SEND_TO_BACK}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@@ -120,8 +119,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].CloseDialog}"
|
Command="{Binding $parent[u:DialogControlBase].Close}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
|
||||||
Header="{DynamicResource STRING_MENU_DIALOG_CLOSE}">
|
Header="{DynamicResource STRING_MENU_DIALOG_CLOSE}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<PathIcon
|
<PathIcon
|
||||||
@@ -347,8 +345,7 @@
|
|||||||
<Setter Property="ContextFlyout">
|
<Setter Property="ContextFlyout">
|
||||||
<MenuFlyout>
|
<MenuFlyout>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].CloseDialog}"
|
Command="{Binding $parent[u:DialogControlBase].Close}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
|
||||||
Header="{DynamicResource STRING_MENU_DIALOG_CLOSE}">
|
Header="{DynamicResource STRING_MENU_DIALOG_CLOSE}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<PathIcon
|
<PathIcon
|
||||||
@@ -364,7 +361,7 @@
|
|||||||
<Setter Property="ContextFlyout">
|
<Setter Property="ContextFlyout">
|
||||||
<MenuFlyout>
|
<MenuFlyout>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].UpdateLayer}"
|
Command="{Binding $parent[u:DialogControlBase].UpdateLayer}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
||||||
Header="{DynamicResource STRING_MENU_BRING_FORWARD}">
|
Header="{DynamicResource STRING_MENU_BRING_FORWARD}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@@ -375,7 +372,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].UpdateLayer}"
|
Command="{Binding $parent[u:DialogControlBase].UpdateLayer}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.BringToFront}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.BringToFront}"
|
||||||
Header="{DynamicResource STRING_MENU_BRING_TO_FRONT}">
|
Header="{DynamicResource STRING_MENU_BRING_TO_FRONT}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@@ -386,7 +383,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].UpdateLayer}"
|
Command="{Binding $parent[u:DialogControlBase].UpdateLayer}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.SendBackward}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.SendBackward}"
|
||||||
Header="{DynamicResource STRING_MENU_SEND_BACKWARD}">
|
Header="{DynamicResource STRING_MENU_SEND_BACKWARD}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@@ -397,7 +394,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].UpdateLayer}"
|
Command="{Binding $parent[u:DialogControlBase].UpdateLayer}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.SendToBack}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.SendToBack}"
|
||||||
Header="{DynamicResource STRING_MENU_SEND_TO_BACK}">
|
Header="{DynamicResource STRING_MENU_SEND_TO_BACK}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@@ -408,7 +405,7 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding $parent[u:CustomDialogControl].CloseDialog}"
|
Command="{Binding $parent[u:DialogControlBase].Close}"
|
||||||
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
|
||||||
Header="{DynamicResource STRING_MENU_DIALOG_CLOSE}">
|
Header="{DynamicResource STRING_MENU_DIALOG_CLOSE}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public abstract class DialogControlBase: OverlayFeedbackElement
|
|||||||
internal double? HorizontalOffsetRatio { get; set; }
|
internal double? HorizontalOffsetRatio { get; set; }
|
||||||
internal double? VerticalOffsetRatio { get; set; }
|
internal double? VerticalOffsetRatio { get; set; }
|
||||||
internal bool CanClickOnMaskToClose { get; set; }
|
internal bool CanClickOnMaskToClose { get; set; }
|
||||||
|
internal bool CanLightDismiss { get; set; }
|
||||||
|
|
||||||
protected internal Button? _closeButton;
|
protected internal Button? _closeButton;
|
||||||
private Panel? _titleArea;
|
private Panel? _titleArea;
|
||||||
|
|||||||
@@ -26,4 +26,6 @@ public class OverlayDialogOptions
|
|||||||
public DialogButton Buttons { get; set; } = DialogButton.OKCancel;
|
public DialogButton Buttons { get; set; } = DialogButton.OKCancel;
|
||||||
public string? Title { get; set; } = null;
|
public string? Title { get; set; } = null;
|
||||||
public bool IsCloseButtonVisible { get; set; } = true;
|
public bool IsCloseButtonVisible { get; set; } = true;
|
||||||
|
|
||||||
|
public bool CanLightDismiss { get; set; }
|
||||||
}
|
}
|
||||||
@@ -191,6 +191,7 @@ public static class OverlayDialog
|
|||||||
options.VerticalAnchor == VerticalPosition.Center ? null : options.VerticalOffset;
|
options.VerticalAnchor == VerticalPosition.Center ? null : options.VerticalOffset;
|
||||||
control.CanClickOnMaskToClose = options.CanClickOnMaskToClose;
|
control.CanClickOnMaskToClose = options.CanClickOnMaskToClose;
|
||||||
control.IsCloseButtonVisible = options.IsCloseButtonVisible;
|
control.IsCloseButtonVisible = options.IsCloseButtonVisible;
|
||||||
|
control.CanLightDismiss = options.CanLightDismiss;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ConfigureDefaultDialogControl(DefaultDialogControl control, OverlayDialogOptions? options)
|
private static void ConfigureDefaultDialogControl(DefaultDialogControl control, OverlayDialogOptions? options)
|
||||||
@@ -208,6 +209,7 @@ public static class OverlayDialog
|
|||||||
control.Mode = options.Mode;
|
control.Mode = options.Mode;
|
||||||
control.Buttons = options.Buttons;
|
control.Buttons = options.Buttons;
|
||||||
control.Title = options.Title;
|
control.Title = options.Title;
|
||||||
|
control.CanLightDismiss = options.CanLightDismiss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Avalonia.Media;
|
|||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using Avalonia.Utilities;
|
using Avalonia.Utilities;
|
||||||
using Ursa.Controls.OverlayShared;
|
using Ursa.Controls.OverlayShared;
|
||||||
|
using Ursa.Controls.Shapes;
|
||||||
using Ursa.EventArgs;
|
using Ursa.EventArgs;
|
||||||
|
|
||||||
namespace Ursa.Controls;
|
namespace Ursa.Controls;
|
||||||
@@ -21,7 +22,7 @@ public partial class OverlayDialogHost
|
|||||||
public Thickness SnapThickness { get; set; } = new Thickness(0);
|
public Thickness SnapThickness { get; set; } = new Thickness(0);
|
||||||
|
|
||||||
|
|
||||||
private void ResetDialogPosition(DialogControlBase control, Size oldSize, Size newSize)
|
private void ResetDialogPosition(DialogControlBase control, Size newSize)
|
||||||
{
|
{
|
||||||
var width = newSize.Width - control.Bounds.Width;
|
var width = newSize.Width - control.Bounds.Width;
|
||||||
var height = newSize.Height - control.Bounds.Height;
|
var height = newSize.Height - control.Bounds.Height;
|
||||||
@@ -82,8 +83,17 @@ public partial class OverlayDialogHost
|
|||||||
|
|
||||||
internal void AddDialog(DialogControlBase control)
|
internal void AddDialog(DialogControlBase control)
|
||||||
{
|
{
|
||||||
|
PureRectangle? mask = null;
|
||||||
|
if (control.CanLightDismiss)
|
||||||
|
{
|
||||||
|
CreateOverlayMask(false, control.CanLightDismiss);
|
||||||
|
}
|
||||||
|
if (mask is not null)
|
||||||
|
{
|
||||||
|
Children.Add(mask);
|
||||||
|
}
|
||||||
this.Children.Add(control);
|
this.Children.Add(control);
|
||||||
_dialogs.Add(control);
|
_layers.Add(new DialogPair(mask, control));
|
||||||
control.Measure(this.Bounds.Size);
|
control.Measure(this.Bounds.Size);
|
||||||
control.Arrange(new Rect(control.DesiredSize));
|
control.Arrange(new Rect(control.DesiredSize));
|
||||||
SetToPosition(control);
|
SetToPosition(control);
|
||||||
@@ -96,27 +106,19 @@ public partial class OverlayDialogHost
|
|||||||
{
|
{
|
||||||
if (sender is DialogControlBase control)
|
if (sender is DialogControlBase control)
|
||||||
{
|
{
|
||||||
Children.Remove(control);
|
var layer = _layers.FirstOrDefault(a => a.Element == control);
|
||||||
|
if (layer is null) return;
|
||||||
|
_layers.Remove(layer);
|
||||||
|
|
||||||
control.RemoveHandler(OverlayFeedbackElement.ClosedEvent, OnDialogControlClosing);
|
control.RemoveHandler(OverlayFeedbackElement.ClosedEvent, OnDialogControlClosing);
|
||||||
control.RemoveHandler(DialogControlBase.LayerChangedEvent, OnDialogLayerChanged);
|
control.RemoveHandler(DialogControlBase.LayerChangedEvent, OnDialogLayerChanged);
|
||||||
if (_dialogs.Contains(control))
|
|
||||||
|
Children.Remove(control);
|
||||||
|
|
||||||
|
if (layer.Mask is not null)
|
||||||
{
|
{
|
||||||
_dialogs.Remove(control);
|
await _maskDisappearAnimation.RunAsync(layer.Mask);
|
||||||
}
|
Children.Remove(layer.Mask);
|
||||||
else if (_modalDialogs.Contains(control))
|
|
||||||
{
|
|
||||||
if (_masks.Count > 0)
|
|
||||||
{
|
|
||||||
var last = _masks.Last();
|
|
||||||
await _maskDisappearAnimation.RunAsync(last);
|
|
||||||
this.Children.Remove(last);
|
|
||||||
_masks.Remove(last);
|
|
||||||
if (_masks.Count > 0)
|
|
||||||
{
|
|
||||||
_masks.Last().IsVisible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_modalDialogs.Remove(control);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetZIndices();
|
ResetZIndices();
|
||||||
@@ -129,9 +131,8 @@ public partial class OverlayDialogHost
|
|||||||
/// <param name="control"></param>
|
/// <param name="control"></param>
|
||||||
internal void AddModalDialog(DialogControlBase control)
|
internal void AddModalDialog(DialogControlBase control)
|
||||||
{
|
{
|
||||||
var mask = CreateOverlayMask(control.CanClickOnMaskToClose);
|
var mask = CreateOverlayMask(true, control.CanClickOnMaskToClose);
|
||||||
_masks.Add(mask);
|
_layers.Add(new DialogPair(mask, control));
|
||||||
_modalDialogs.Add(control);
|
|
||||||
control.SetAsModal(true);
|
control.SetAsModal(true);
|
||||||
ResetZIndices();
|
ResetZIndices();
|
||||||
this.Children.Add(mask);
|
this.Children.Add(mask);
|
||||||
@@ -148,41 +149,31 @@ public partial class OverlayDialogHost
|
|||||||
// Handle dialog layer change event
|
// Handle dialog layer change event
|
||||||
private void OnDialogLayerChanged(object sender, DialogLayerChangeEventArgs e)
|
private void OnDialogLayerChanged(object sender, DialogLayerChangeEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is not CustomDialogControl control)
|
if (sender is not DialogControlBase control)
|
||||||
return;
|
return;
|
||||||
if (!_dialogs.Contains(control))
|
var layer = _layers.FirstOrDefault(a => a.Element == control);
|
||||||
return;
|
if (layer is null) return;
|
||||||
int index = _dialogs.IndexOf(control);
|
int index = _layers.IndexOf(layer);
|
||||||
_dialogs.Remove(control);
|
_layers.Remove(layer);
|
||||||
int newIndex = index;
|
int newIndex = index;
|
||||||
switch (e.ChangeType)
|
switch (e.ChangeType)
|
||||||
{
|
{
|
||||||
case DialogLayerChangeType.BringForward:
|
case DialogLayerChangeType.BringForward:
|
||||||
newIndex = MathUtilities.Clamp(index + 1, 0, _dialogs.Count);
|
newIndex = MathUtilities.Clamp(index + 1, 0, _layers.Count);
|
||||||
break;
|
break;
|
||||||
case DialogLayerChangeType.SendBackward:
|
case DialogLayerChangeType.SendBackward:
|
||||||
newIndex = MathUtilities.Clamp(index - 1, 0, _dialogs.Count);
|
newIndex = MathUtilities.Clamp(index - 1, 0, _layers.Count);
|
||||||
break;
|
break;
|
||||||
case DialogLayerChangeType.BringToFront:
|
case DialogLayerChangeType.BringToFront:
|
||||||
newIndex = _dialogs.Count;
|
newIndex = _layers.Count;
|
||||||
break;
|
break;
|
||||||
case DialogLayerChangeType.SendToBack:
|
case DialogLayerChangeType.SendToBack:
|
||||||
newIndex = 0;
|
newIndex = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dialogs.Insert(newIndex, control);
|
_layers.Insert(newIndex, layer);
|
||||||
for (int i = 0; i < _dialogs.Count; i++)
|
ResetZIndices();
|
||||||
{
|
|
||||||
_dialogs[i].ZIndex = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < _masks.Count * 2; i += 2)
|
|
||||||
{
|
|
||||||
_masks[i].ZIndex = _dialogs.Count + i;
|
|
||||||
(_modalDialogs[i] as Control)!.ZIndex = _dialogs.Count + i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetToPosition(DialogControlBase? control)
|
private void SetToPosition(DialogControlBase? control)
|
||||||
|
|||||||
@@ -12,15 +12,9 @@ public partial class OverlayDialogHost
|
|||||||
{
|
{
|
||||||
internal async void AddDrawer(DrawerControlBase control)
|
internal async void AddDrawer(DrawerControlBase control)
|
||||||
{
|
{
|
||||||
var mask = CreateOverlayMask(false);
|
var mask = CreateOverlayMask(true, false);
|
||||||
mask.Opacity = 0;
|
mask.Opacity = 0;
|
||||||
_masks.Add(mask);
|
_layers.Add(new DialogPair(mask, control));
|
||||||
_modalDialogs.Add(control);
|
|
||||||
// control.SetAsModal(true);
|
|
||||||
for (int i = 0; i < _masks.Count-1; i++)
|
|
||||||
{
|
|
||||||
_masks[i].Opacity = 0.5;
|
|
||||||
}
|
|
||||||
ResetZIndices();
|
ResetZIndices();
|
||||||
this.Children.Add(mask);
|
this.Children.Add(mask);
|
||||||
this.Children.Add(control);
|
this.Children.Add(control);
|
||||||
@@ -66,23 +60,16 @@ public partial class OverlayDialogHost
|
|||||||
{
|
{
|
||||||
if (sender is DrawerControlBase control)
|
if (sender is DrawerControlBase control)
|
||||||
{
|
{
|
||||||
|
var layer = _layers.FirstOrDefault(a => a.Element == control);
|
||||||
|
if(layer is null) return;
|
||||||
|
_layers.Remove(layer);
|
||||||
|
if (layer.Mask is not null)
|
||||||
|
{
|
||||||
|
layer.Mask.RemoveHandler(PointerPressedEvent, ClickMaskToCloseDialog);
|
||||||
|
}
|
||||||
Children.Remove(control);
|
Children.Remove(control);
|
||||||
control.RemoveHandler(OverlayFeedbackElement.ClosedEvent, OnDialogControlClosing);
|
control.RemoveHandler(OverlayFeedbackElement.ClosedEvent, OnDialogControlClosing);
|
||||||
control.RemoveHandler(DialogControlBase.LayerChangedEvent, OnDialogLayerChanged);
|
control.RemoveHandler(DialogControlBase.LayerChangedEvent, OnDialogLayerChanged);
|
||||||
if (_modalDialogs.Contains(control))
|
|
||||||
{
|
|
||||||
_modalDialogs.Remove(control);
|
|
||||||
if (_masks.Count > 0)
|
|
||||||
{
|
|
||||||
var last = _masks.Last();
|
|
||||||
this.Children.Remove(last);
|
|
||||||
_masks.Remove(last);
|
|
||||||
if (_masks.Count > 0)
|
|
||||||
{
|
|
||||||
_masks.Last().IsVisible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ResetZIndices();
|
ResetZIndices();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Avalonia.Input;
|
|||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Ursa.Controls.OverlayShared;
|
using Ursa.Controls.OverlayShared;
|
||||||
using Avalonia.Layout;
|
using Avalonia.Layout;
|
||||||
|
using Avalonia.Media.Immutable;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using Ursa.Controls.Shapes;
|
using Ursa.Controls.Shapes;
|
||||||
|
|
||||||
@@ -14,18 +15,21 @@ namespace Ursa.Controls;
|
|||||||
|
|
||||||
public partial class OverlayDialogHost: Canvas
|
public partial class OverlayDialogHost: Canvas
|
||||||
{
|
{
|
||||||
private readonly List<OverlayFeedbackElement> _dialogs = new();
|
|
||||||
private readonly List<OverlayFeedbackElement> _modalDialogs = new();
|
|
||||||
private readonly List<PureRectangle> _masks = new();
|
|
||||||
private static readonly Animation _maskAppearAnimation;
|
private static readonly Animation _maskAppearAnimation;
|
||||||
private static readonly Animation _maskDisappearAnimation;
|
private static readonly Animation _maskDisappearAnimation;
|
||||||
|
|
||||||
private readonly List<DialogPair> _layers = new List<DialogPair>();
|
private readonly List<DialogPair> _layers = new List<DialogPair>();
|
||||||
|
|
||||||
private struct DialogPair
|
private class DialogPair
|
||||||
{
|
{
|
||||||
internal PureRectangle Mask;
|
internal PureRectangle? Mask;
|
||||||
internal OverlayFeedbackElement Dialog;
|
internal OverlayFeedbackElement Element;
|
||||||
|
|
||||||
|
public DialogPair(PureRectangle? mask, OverlayFeedbackElement element)
|
||||||
|
{
|
||||||
|
Mask = mask;
|
||||||
|
Element = element;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static OverlayDialogHost()
|
static OverlayDialogHost()
|
||||||
@@ -63,33 +67,38 @@ public partial class OverlayDialogHost: Canvas
|
|||||||
set => SetValue(OverlayMaskBrushProperty, value);
|
set => SetValue(OverlayMaskBrushProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PureRectangle CreateOverlayMask(bool canCloseOnClick)
|
private PureRectangle CreateOverlayMask(bool modal, bool canCloseOnClick)
|
||||||
{
|
{
|
||||||
PureRectangle rec = new()
|
PureRectangle rec = new()
|
||||||
{
|
{
|
||||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
|
||||||
VerticalAlignment = VerticalAlignment.Stretch,
|
|
||||||
Width = this.Bounds.Width,
|
Width = this.Bounds.Width,
|
||||||
Height = this.Bounds.Height,
|
Height = this.Bounds.Height,
|
||||||
[!Shape.FillProperty] = this[!OverlayMaskBrushProperty],
|
|
||||||
IsVisible = true,
|
IsVisible = true,
|
||||||
};
|
};
|
||||||
|
if (modal)
|
||||||
|
{
|
||||||
|
rec[!Shape.FillProperty] = this[!OverlayMaskBrushProperty];
|
||||||
|
}
|
||||||
|
else if(canCloseOnClick)
|
||||||
|
{
|
||||||
|
rec.SetCurrentValue(Shape.FillProperty, Brushes.Transparent);
|
||||||
|
}
|
||||||
if (canCloseOnClick)
|
if (canCloseOnClick)
|
||||||
{
|
{
|
||||||
rec.AddHandler(PointerReleasedEvent, ClickBorderToCloseDialog);
|
rec.AddHandler(PointerReleasedEvent, ClickMaskToCloseDialog);
|
||||||
}
|
}
|
||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClickBorderToCloseDialog(object sender, PointerReleasedEventArgs e)
|
private void ClickMaskToCloseDialog(object sender, PointerReleasedEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is PureRectangle border)
|
if (sender is PureRectangle border)
|
||||||
{
|
{
|
||||||
int i = _masks.IndexOf(border);
|
var layer = _layers.FirstOrDefault(a => a.Mask == border);
|
||||||
if (_modalDialogs[i] is { } element)
|
if (layer is not null)
|
||||||
{
|
{
|
||||||
element.Close();
|
layer.Element.Close();
|
||||||
border.RemoveHandler(PointerReleasedEvent, ClickBorderToCloseDialog);
|
border.RemoveHandler(PointerReleasedEvent, ClickMaskToCloseDialog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,26 +119,16 @@ public partial class OverlayDialogHost: Canvas
|
|||||||
protected sealed override void OnSizeChanged(SizeChangedEventArgs e)
|
protected sealed override void OnSizeChanged(SizeChangedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnSizeChanged(e);
|
base.OnSizeChanged(e);
|
||||||
for (int i = 0; i < _masks.Count; i++)
|
for (int i = 0; i < _layers.Count; i++)
|
||||||
{
|
{
|
||||||
_masks[i].Width = this.Bounds.Width;
|
if (_layers[i].Mask is { } rect)
|
||||||
_masks[i].Height = this.Bounds.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
var oldSize = e.PreviousSize;
|
|
||||||
var newSize = e.NewSize;
|
|
||||||
foreach (var dialog in _dialogs)
|
|
||||||
{
|
|
||||||
if (dialog is DialogControlBase c)
|
|
||||||
{
|
{
|
||||||
ResetDialogPosition(c, oldSize, newSize);
|
rect.Width = this.Bounds.Width;
|
||||||
|
rect.Height = this.Bounds.Height;
|
||||||
}
|
}
|
||||||
}
|
if (_layers[i].Element is DialogControlBase d)
|
||||||
foreach (var modalDialog in _modalDialogs)
|
|
||||||
{
|
|
||||||
if (modalDialog is DialogControlBase c)
|
|
||||||
{
|
{
|
||||||
ResetDialogPosition(c, oldSize, newSize);
|
ResetDialogPosition(d, e.NewSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,31 +136,17 @@ public partial class OverlayDialogHost: Canvas
|
|||||||
private void ResetZIndices()
|
private void ResetZIndices()
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for ( int i = 0; i< _dialogs.Count; i++)
|
|
||||||
{
|
|
||||||
_dialogs[i].ZIndex = index;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
for(int i = 0; i< _masks.Count; i++)
|
|
||||||
{
|
|
||||||
_masks[i].ZIndex = index;
|
|
||||||
index++;
|
|
||||||
(_modalDialogs[i] as Control)!.ZIndex = index;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index2 = 0;
|
|
||||||
for (int i = 0; i < _layers.Count; i++)
|
for (int i = 0; i < _layers.Count; i++)
|
||||||
{
|
{
|
||||||
if(_layers[i].Mask is { } mask)
|
if(_layers[i].Mask is { } mask)
|
||||||
{
|
{
|
||||||
mask.ZIndex = index2;
|
mask.ZIndex = index;
|
||||||
index2++;
|
index++;
|
||||||
}
|
}
|
||||||
if(_layers[i].Dialog is { } dialog)
|
if(_layers[i].Element is { } dialog)
|
||||||
{
|
{
|
||||||
dialog.ZIndex = index2;
|
dialog.ZIndex = index;
|
||||||
index2++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user