From f6f216f409e970ca0e9d267a617ee21da859f392 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sat, 10 Feb 2024 01:29:06 +0800 Subject: [PATCH] feat: make drawer api similar to dialog. --- demo/Ursa.Demo/Pages/DrawerDemo.axaml | 16 +- .../ViewModels/DrawerDemoViewModel.cs | 76 +++++++--- demo/Ursa.PrismDialogDemo/MainWindow.axaml | 3 +- demo/Ursa.PrismDialogDemo/MainWindow.axaml.cs | 17 ++- src/Ursa.PrismExtension/IUrsaDrawerService.cs | 6 +- src/Ursa.PrismExtension/UrsaDrawerService.cs | 23 ++- src/Ursa/Controls/Drawer/Drawer.cs | 142 ++++++++++++++---- src/Ursa/Controls/Drawer/DrawerControlBase.cs | 5 +- .../Drawer/Options/CustomDrawerOptions.cs | 17 --- ...faultDrawerOptions.cs => DrawerOptions.cs} | 9 +- .../OverlayShared/OverlayDialogHost.Drawer.cs | 22 ++- 11 files changed, 228 insertions(+), 108 deletions(-) delete mode 100644 src/Ursa/Controls/Drawer/Options/CustomDrawerOptions.cs rename src/Ursa/Controls/Drawer/Options/{DefaultDrawerOptions.cs => DrawerOptions.cs} (65%) diff --git a/demo/Ursa.Demo/Pages/DrawerDemo.axaml b/demo/Ursa.Demo/Pages/DrawerDemo.axaml index fca5d36..c613b4e 100644 --- a/demo/Ursa.Demo/Pages/DrawerDemo.axaml +++ b/demo/Ursa.Demo/Pages/DrawerDemo.axaml @@ -23,13 +23,13 @@ OffContent="Local" OnContent="Global" /> @@ -56,13 +56,13 @@ OffContent="Local" OnContent="Global" /> + + diff --git a/demo/Ursa.PrismDialogDemo/MainWindow.axaml.cs b/demo/Ursa.PrismDialogDemo/MainWindow.axaml.cs index ad95fd4..1b51033 100644 --- a/demo/Ursa.PrismDialogDemo/MainWindow.axaml.cs +++ b/demo/Ursa.PrismDialogDemo/MainWindow.axaml.cs @@ -7,15 +7,22 @@ namespace Ursa.PrismDialogDemo; public partial class MainWindow : Window { - private IUrsaOverlayDialogService _ursa; - public MainWindow(IUrsaOverlayDialogService ursa) + private IUrsaOverlayDialogService _dialogService; + private IUrsaDrawerService _drawerService; + public MainWindow(IUrsaOverlayDialogService dialogService, IUrsaDrawerService drawerService) { InitializeComponent(); - _ursa = ursa; + _dialogService = dialogService; + _drawerService = drawerService; } - private void Button_OnClick(object? sender, RoutedEventArgs e) + private void DialogButton_OnClick(object? sender, RoutedEventArgs e) { - _ursa.ShowModal("Default", null, null, null); + _dialogService.ShowModal("Default", null, null, null); + } + + private void DrawerButton_OnClick(object? sender, RoutedEventArgs e) + { + _drawerService.ShowModal("Default", null, null, null); } } \ No newline at end of file diff --git a/src/Ursa.PrismExtension/IUrsaDrawerService.cs b/src/Ursa.PrismExtension/IUrsaDrawerService.cs index 7d97bfc..77f7dc9 100644 --- a/src/Ursa.PrismExtension/IUrsaDrawerService.cs +++ b/src/Ursa.PrismExtension/IUrsaDrawerService.cs @@ -5,6 +5,8 @@ namespace Ursa.PrismExtension; public interface IUrsaDrawerService { - public Task ShowDrawer(string viewName, object? vm, string? hostId = null, DefaultDrawerOptions? options = null); - public Task ShowCustomDrawer(string viewName, object? vm, string? hostId = null, CustomDrawerOptions? options = null); + public void Show(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null); + public void ShowCustom(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null); + public Task ShowModal(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null); + public Task ShowCustomModal(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null); } \ No newline at end of file diff --git a/src/Ursa.PrismExtension/UrsaDrawerService.cs b/src/Ursa.PrismExtension/UrsaDrawerService.cs index 99b9a43..7cd7add 100644 --- a/src/Ursa.PrismExtension/UrsaDrawerService.cs +++ b/src/Ursa.PrismExtension/UrsaDrawerService.cs @@ -7,16 +7,27 @@ namespace Ursa.PrismExtension; public class UrsaDrawerService(IContainerExtension container): IUrsaDrawerService { - public Task ShowDrawer(string viewName, object? vm, string? hostId = null, DefaultDrawerOptions? options = null) + public void Show(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null) { var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); - return Drawer.Show(v, vm, hostId, options); + Drawer.Show(v, vm, hostId, options); } - - public Task ShowCustomDrawer(string viewName, object? vm, string? hostId = null, - CustomDrawerOptions? options = null) + + public void ShowCustom(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null) { var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); - return Drawer.ShowCustom(v, vm, hostId, options); + Drawer.ShowCustom(v, vm, hostId, options); + } + + public Task ShowModal(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + return Drawer.ShowModal(v, vm, hostId, options); + } + + public Task ShowCustomModal(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + return Drawer.ShowCustomModal(v, vm, hostId, options); } } \ No newline at end of file diff --git a/src/Ursa/Controls/Drawer/Drawer.cs b/src/Ursa/Controls/Drawer/Drawer.cs index 70a4374..6013040 100644 --- a/src/Ursa/Controls/Drawer/Drawer.cs +++ b/src/Ursa/Controls/Drawer/Drawer.cs @@ -7,11 +7,11 @@ namespace Ursa.Controls; public static class Drawer { - public static Task Show(TViewModel vm, string? hostId = null, DefaultDrawerOptions? options = null) + public static void Show(TViewModel vm, string? hostId = null, DrawerOptions? options = null) where TView: Control, new() { var host = OverlayDialogManager.GetHost(hostId); - if (host is null) return Task.FromResult(default(DialogResult)); + if (host is null) return; var drawer = new DefaultDrawerControl() { Content = new TView(), @@ -19,14 +19,13 @@ public static class Drawer }; ConfigureDefaultDrawer(drawer, options); host.AddDrawer(drawer); - return drawer.ShowAsync(); } - public static Task Show(Control control, object? vm, string? hostId = null, - DefaultDrawerOptions? options = null) + public static void Show(Control control, object? vm, string? hostId = null, + DrawerOptions? options = null) { var host = OverlayDialogManager.GetHost(hostId); - if (host is null) return Task.FromResult(default(DialogResult)); + if (host is null) return; var drawer = new DefaultDrawerControl() { Content = control, @@ -34,13 +33,12 @@ public static class Drawer }; ConfigureDefaultDrawer(drawer, options); host.AddDrawer(drawer); - return drawer.ShowAsync(); } - public static Task Show(object? vm, string? hostId = null, DefaultDrawerOptions? options = null) + public static void Show(object? vm, string? hostId = null, DrawerOptions? options = null) { var host = OverlayDialogManager.GetHost(hostId); - if (host is null) return Task.FromResult(default(DialogResult)); + if (host is null) return; var view = host.GetDataTemplate(vm)?.Build(vm); if (view is null) view = new ContentControl() { Padding = new Thickness(24) }; view.DataContext = vm; @@ -51,14 +49,60 @@ public static class Drawer }; ConfigureDefaultDrawer(drawer, options); host.AddDrawer(drawer); - return drawer.ShowAsync(); } - public static Task ShowCustom(TViewModel vm, string? hostId = null, CustomDrawerOptions? options = null) + public static Task ShowModal(TViewModel vm, string? hostId = null, DrawerOptions? options = null) where TView: Control, new() { var host = OverlayDialogManager.GetHost(hostId); - if (host is null) return Task.FromResult(default(TResult)); + if (host is null) return Task.FromResult(DialogResult.None); + var drawer = new DefaultDrawerControl() + { + Content = new TView(), + DataContext = vm, + }; + ConfigureDefaultDrawer(drawer, options); + host.AddModalDrawer(drawer); + return drawer.ShowAsync(); + } + + public static Task ShowModal(Control control, object? vm, string? hostId = null, + DrawerOptions? options = null) + { + var host = OverlayDialogManager.GetHost(hostId); + if (host is null) return Task.FromResult(DialogResult.None); + var drawer = new DefaultDrawerControl() + { + Content = control, + DataContext = vm, + }; + ConfigureDefaultDrawer(drawer, options); + host.AddModalDrawer(drawer); + return drawer.ShowAsync(); + } + + public static Task ShowModal(object? vm, string? hostId = null, DrawerOptions? options = null) + { + var host = OverlayDialogManager.GetHost(hostId); + if (host is null) return Task.FromResult(DialogResult.None); + var view = host.GetDataTemplate(vm)?.Build(vm); + if (view is null) view = new ContentControl() { Padding = new Thickness(24) }; + view.DataContext = vm; + var drawer = new DefaultDrawerControl() + { + Content = view, + DataContext = vm, + }; + ConfigureDefaultDrawer(drawer, options); + host.AddModalDrawer(drawer); + return drawer.ShowAsync(); + } + + public static void ShowCustom(TViewModel vm, string? hostId = null, DrawerOptions? options = null) + where TView: Control, new() + { + var host = OverlayDialogManager.GetHost(hostId); + if (host is null) return; var dialog = new CustomDrawerControl() { Content = new TView(), @@ -66,13 +110,12 @@ public static class Drawer }; ConfigureCustomDrawer(dialog, options); host.AddDrawer(dialog); - return dialog.ShowAsync(); } - public static Task ShowCustom(Control control, object? vm, string? hostId = null, CustomDrawerOptions? options = null) + public static void ShowCustom(Control control, object? vm, string? hostId = null, DrawerOptions? options = null) { var host = OverlayDialogManager.GetHost(hostId); - if (host is null) return Task.FromResult(default(TResult)); + if (host is null) return; var dialog = new CustomDrawerControl() { Content = control, @@ -80,13 +123,12 @@ public static class Drawer }; ConfigureCustomDrawer(dialog, options); host.AddDrawer(dialog); - return dialog.ShowAsync(); } - public static Task ShowCustom(object? vm, string? hostId = null, CustomDrawerOptions? options = null) + public static void ShowCustom(object? vm, string? hostId = null, DrawerOptions? options = null) { var host = OverlayDialogManager.GetHost(hostId); - if (host is null) return Task.FromResult(default(TResult)); + if (host is null) return; var view = host.GetDataTemplate(vm)?.Build(vm); if (view is null) view = new ContentControl() { Padding = new Thickness(24) }; view.DataContext = vm; @@ -97,17 +139,59 @@ public static class Drawer }; ConfigureCustomDrawer(dialog, options); host.AddDrawer(dialog); - return dialog.ShowAsync(); } - - private static void ConfigureCustomDrawer(CustomDrawerControl drawer, CustomDrawerOptions? options) + public static Task ShowCustomModal(TViewModel vm, string? hostId = null, DrawerOptions? options = null) + where TView: Control, new() { - options ??= CustomDrawerOptions.Default; + var host = OverlayDialogManager.GetHost(hostId); + if (host is null) return Task.FromResult(default); + var dialog = new CustomDrawerControl() + { + Content = new TView(), + DataContext = vm, + }; + ConfigureCustomDrawer(dialog, options); + host.AddModalDrawer(dialog); + return dialog.ShowAsync(); + } + + public static Task ShowCustomModal(Control control, object? vm, string? hostId = null, DrawerOptions? options = null) + { + var host = OverlayDialogManager.GetHost(hostId); + if (host is null) return Task.FromResult(default); + var dialog = new CustomDrawerControl() + { + Content = control, + DataContext = vm, + }; + ConfigureCustomDrawer(dialog, options); + host.AddModalDrawer(dialog); + return dialog.ShowAsync(); + } + + public static Task ShowCustomModal(object? vm, string? hostId = null, DrawerOptions? options = null) + { + var host = OverlayDialogManager.GetHost(hostId); + if (host is null) return Task.FromResult(default); + var view = host.GetDataTemplate(vm)?.Build(vm); + if (view is null) view = new ContentControl() { Padding = new Thickness(24) }; + view.DataContext = vm; + var dialog = new CustomDrawerControl() + { + Content = view, + DataContext = vm, + }; + ConfigureCustomDrawer(dialog, options); + host.AddModalDrawer(dialog); + return dialog.ShowAsync(); + } + + private static void ConfigureCustomDrawer(CustomDrawerControl drawer, DrawerOptions? options) + { + options ??= DrawerOptions.Default; drawer.Position = options.Position; - drawer.CanClickOnMaskToClose = options.CanClickOnMaskToClose; - drawer.IsCloseButtonVisible = options.IsCloseButtonVisible; - drawer.ShowMask = options.ShowMask; + drawer.IsCloseButtonVisible = options.ShowCloseButton; drawer.CanLightDismiss = options.CanLightDismiss; if (options.Position == Position.Left || options.Position == Position.Right) { @@ -121,16 +205,14 @@ public static class Drawer } } - private static void ConfigureDefaultDrawer(DefaultDrawerControl drawer, DefaultDrawerOptions? options) + private static void ConfigureDefaultDrawer(DefaultDrawerControl drawer, DrawerOptions? options) { - options ??= DefaultDrawerOptions.Default; + options ??= DrawerOptions.Default; drawer.Position = options.Position; - drawer.CanClickOnMaskToClose = options.CanClickOnMaskToClose; drawer.IsCloseButtonVisible = options.IsCloseButtonVisible; + drawer.CanLightDismiss = options.CanLightDismiss; drawer.Buttons = options.Buttons; drawer.Title = options.Title; - drawer.ShowMask = options.ShowMask; - drawer.CanLightDismiss = options.CanLightDismiss; if (options.Position == Position.Left || options.Position == Position.Right) { drawer.MinWidth = options.MinWidth ?? 0.0; diff --git a/src/Ursa/Controls/Drawer/DrawerControlBase.cs b/src/Ursa/Controls/Drawer/DrawerControlBase.cs index c582189..e8c20f7 100644 --- a/src/Ursa/Controls/Drawer/DrawerControlBase.cs +++ b/src/Ursa/Controls/Drawer/DrawerControlBase.cs @@ -15,9 +15,7 @@ namespace Ursa.Controls; [TemplatePart(PART_CloseButton, typeof(Button))] public abstract class DrawerControlBase: OverlayFeedbackElement { -public const string PART_CloseButton = "PART_CloseButton"; - - internal bool CanClickOnMaskToClose { get; set; } + public const string PART_CloseButton = "PART_CloseButton"; protected internal Button? _closeButton; @@ -50,7 +48,6 @@ public const string PART_CloseButton = "PART_CloseButton"; set => SetValue(IsCloseButtonVisibleProperty, value); } - protected internal bool ShowMask { get; set; } protected internal bool CanLightDismiss { get; set; } static DrawerControlBase() diff --git a/src/Ursa/Controls/Drawer/Options/CustomDrawerOptions.cs b/src/Ursa/Controls/Drawer/Options/CustomDrawerOptions.cs deleted file mode 100644 index 9969b18..0000000 --- a/src/Ursa/Controls/Drawer/Options/CustomDrawerOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Ursa.Common; - -namespace Ursa.Controls.Options; - -public class CustomDrawerOptions -{ - internal static CustomDrawerOptions Default => new (); - public Position Position { get; set; } = Position.Right; - public bool CanClickOnMaskToClose { get; set; } = true; - public bool CanLightDismiss { get; set; } = false; - public bool ShowMask { get; set; } = true; - public bool IsCloseButtonVisible { get; set; } = true; - public double? MinWidth { get; set; } = null; - public double? MinHeight { get; set; } = null; - public double? MaxWidth { get; set; } = null; - public double? MaxHeight { get; set; } = null; -} \ No newline at end of file diff --git a/src/Ursa/Controls/Drawer/Options/DefaultDrawerOptions.cs b/src/Ursa/Controls/Drawer/Options/DrawerOptions.cs similarity index 65% rename from src/Ursa/Controls/Drawer/Options/DefaultDrawerOptions.cs rename to src/Ursa/Controls/Drawer/Options/DrawerOptions.cs index 0504240..a0cf4dc 100644 --- a/src/Ursa/Controls/Drawer/Options/DefaultDrawerOptions.cs +++ b/src/Ursa/Controls/Drawer/Options/DrawerOptions.cs @@ -2,13 +2,11 @@ namespace Ursa.Controls.Options; -public class DefaultDrawerOptions +public class DrawerOptions { - internal static DefaultDrawerOptions Default => new (); + internal static DrawerOptions Default => new (); public Position Position { get; set; } = Position.Right; - public bool CanClickOnMaskToClose { get; set; } = true; - public bool CanLightDismiss { get; set; } = false; - public bool ShowMask { get; set; } = true; + public bool CanLightDismiss { get; set; } = true; public bool IsCloseButtonVisible { get; set; } = true; public double? MinWidth { get; set; } = null; public double? MinHeight { get; set; } = null; @@ -16,4 +14,5 @@ public class DefaultDrawerOptions public double? MaxHeight { get; set; } = null; public DialogButton Buttons { get; set; } = DialogButton.OKCancel; public string? Title { get; set; } + public bool ShowCloseButton { get; set; } = true; } \ No newline at end of file diff --git a/src/Ursa/Controls/OverlayShared/OverlayDialogHost.Drawer.cs b/src/Ursa/Controls/OverlayShared/OverlayDialogHost.Drawer.cs index ec7323b..1da3b69 100644 --- a/src/Ursa/Controls/OverlayShared/OverlayDialogHost.Drawer.cs +++ b/src/Ursa/Controls/OverlayShared/OverlayDialogHost.Drawer.cs @@ -15,14 +15,10 @@ public partial class OverlayDialogHost internal async void AddDrawer(DrawerControlBase control) { PureRectangle? mask = null; - if (control.ShowMask == false && control.CanLightDismiss) + if (control.CanLightDismiss) { mask = CreateOverlayMask(false, true); } - else if (control.ShowMask) - { - mask = CreateOverlayMask(control.ShowMask, control.CanClickOnMaskToClose); - } _layers.Add(new DialogPair(mask, control)); ResetZIndices(); if(mask is not null)this.Children.Add(mask); @@ -40,7 +36,21 @@ public partial class OverlayDialogHost { await Task.WhenAll(animation.RunAsync(control), _maskAppearAnimation.RunAsync(mask)); } - + } + + internal async void AddModalDrawer(DrawerControlBase control) + { + PureRectangle? mask = CreateOverlayMask(true, control.CanLightDismiss); + _layers.Add(new DialogPair(mask, control)); + this.Children.Add(mask); + this.Children.Add(control); + ResetZIndices(); + control.Measure(this.Bounds.Size); + control.Arrange(new Rect(control.DesiredSize)); + SetDrawerPosition(control); + control.AddHandler(OverlayFeedbackElement.ClosedEvent, OnDrawerControlClosing); + var animation = CreateAnimation(control.Bounds.Size, control.Position); + await Task.WhenAll(animation.RunAsync(control), _maskAppearAnimation.RunAsync(mask)); } private void SetDrawerPosition(DrawerControlBase control)