From 2c361f9f3c53d3968f92ac3f1b47989f1078a8c2 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sun, 21 Jan 2024 23:40:06 +0800 Subject: [PATCH] feat: WIP dialog window. --- demo/Ursa.Demo/Pages/DialogDemo.axaml | 1 + .../ViewModels/DialogDemoViewModel.cs | 17 ++++-- src/Ursa.Themes.Semi/Controls/Dialog.axaml | 52 +++++++++++++++++++ src/Ursa.Themes.Semi/Controls/_index.axaml | 1 + src/Ursa/Controls/Dialog/DialogBox.cs | 45 +++++++++++++--- src/Ursa/Controls/Dialog/DialogControl.cs | 19 +++++++ src/Ursa/Controls/Dialog/DialogWindow.cs | 30 +++++++++++ src/Ursa/Controls/Dialog/IDialogContext.cs | 3 +- src/Ursa/Controls/Dialog/OverlayDialogHost.cs | 44 +++++++++++++--- 9 files changed, 193 insertions(+), 19 deletions(-) create mode 100644 src/Ursa.Themes.Semi/Controls/Dialog.axaml create mode 100644 src/Ursa/Controls/Dialog/DialogWindow.cs diff --git a/demo/Ursa.Demo/Pages/DialogDemo.axaml b/demo/Ursa.Demo/Pages/DialogDemo.axaml index 4bc5427..24e36eb 100644 --- a/demo/Ursa.Demo/Pages/DialogDemo.axaml +++ b/demo/Ursa.Demo/Pages/DialogDemo.axaml @@ -13,6 +13,7 @@ mc:Ignorable="d"> + diff --git a/demo/Ursa.Demo/ViewModels/DialogDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/DialogDemoViewModel.cs index 7210529..e96ee23 100644 --- a/demo/Ursa.Demo/ViewModels/DialogDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/DialogDemoViewModel.cs @@ -1,10 +1,12 @@ using System; +using System.Threading.Tasks; using System.Windows.Input; using Avalonia.Controls; using Avalonia.Controls.Shapes; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Ursa.Controls; +using Ursa.Demo.Pages; namespace Ursa.Demo.ViewModels; @@ -12,19 +14,26 @@ public class DialogDemoViewModel: ObservableObject { public ICommand ShowLocalOverlayDialogCommand { get; } public ICommand ShowGlobalOverlayDialogCommand { get; } + public ICommand ShowGlobalDialogCommand { get; } public DialogDemoViewModel() { - ShowLocalOverlayDialogCommand = new RelayCommand(ShowLocalOverlayDialog); - ShowGlobalOverlayDialogCommand = new RelayCommand(ShowGlobalOverlayDialog); + ShowLocalOverlayDialogCommand = new AsyncRelayCommand(ShowLocalOverlayDialog); + ShowGlobalOverlayDialogCommand = new AsyncRelayCommand(ShowGlobalOverlayDialog); + ShowGlobalDialogCommand = new AsyncRelayCommand(ShowGlobalDialog); } - private async void ShowGlobalOverlayDialog() + private async Task ShowGlobalDialog() + { + await DialogBox.ShowAsync(new BadgeDemoViewModel()); + } + + private async Task ShowGlobalOverlayDialog() { await DialogBox.ShowOverlayAsync(DateTime.Now, "GlobalHost"); } - private async void ShowLocalOverlayDialog() + private async Task ShowLocalOverlayDialog() { await DialogBox.ShowOverlayAsync(DateTime.Now, "LocalHost"); } diff --git a/src/Ursa.Themes.Semi/Controls/Dialog.axaml b/src/Ursa.Themes.Semi/Controls/Dialog.axaml new file mode 100644 index 0000000..62355cb --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/Dialog.axaml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Full + BorderOnly + + + + + + + + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml index edf9abb..e9ab67e 100644 --- a/src/Ursa.Themes.Semi/Controls/_index.axaml +++ b/src/Ursa.Themes.Semi/Controls/_index.axaml @@ -4,6 +4,7 @@ + diff --git a/src/Ursa/Controls/Dialog/DialogBox.cs b/src/Ursa/Controls/Dialog/DialogBox.cs index 38a3641..980cf57 100644 --- a/src/Ursa/Controls/Dialog/DialogBox.cs +++ b/src/Ursa/Controls/Dialog/DialogBox.cs @@ -1,5 +1,6 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.Shapes; using Avalonia.Media; @@ -7,18 +8,46 @@ namespace Ursa.Controls; public static class DialogBox { - public static async Task ShowAsync() + public static async Task ShowAsync(TViewModel vm) where TView : Control, new() { - return; + var window = new DialogWindow() + { + Content = new TView() + { + DataContext = vm, + }, + DataContext = vm, + }; + var lifetime = Application.Current?.ApplicationLifetime; + if (lifetime is IClassicDesktopStyleApplicationLifetime classLifetime) + { + var main = classLifetime.MainWindow; + if (main is null) + { + window.Show(); + return default(TResult); + } + else + { + var result = await window.ShowDialog(main); + return result; + } + } + else + { + return default(TResult); + } } - - public static async Task ShowAsync(TViewModel vm) - where TView: Control, new() - where TViewModel: new() + + public static async Task ShowAsync(Window owner, TViewModel vm) where + TView: Control, new() { - TView t = new TView(); - t.DataContext = vm; + var window = new DialogWindow(); + window.Content = new TView(); + window.DataContext = vm; + return await window.ShowDialog(owner); } + public static async Task ShowOverlayAsync(TViewModel vm, string hostId) where TView : Control, new() diff --git a/src/Ursa/Controls/Dialog/DialogControl.cs b/src/Ursa/Controls/Dialog/DialogControl.cs index d46adc5..e3cae7a 100644 --- a/src/Ursa/Controls/Dialog/DialogControl.cs +++ b/src/Ursa/Controls/Dialog/DialogControl.cs @@ -1,8 +1,27 @@ using Avalonia.Controls; +using Avalonia.Controls.Metadata; +using Avalonia.Controls.Primitives; +using Avalonia.Interactivity; namespace Ursa.Controls; +[TemplatePart(PART_CloseButton, typeof(Button))] public class DialogControl: ContentControl { + public const string PART_CloseButton = "PART_CloseButton"; + + + private Button? _closeButton; + public event EventHandler OnClose; + + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + } + + public void Show() + { + + } } \ No newline at end of file diff --git a/src/Ursa/Controls/Dialog/DialogWindow.cs b/src/Ursa/Controls/Dialog/DialogWindow.cs new file mode 100644 index 0000000..9ec685e --- /dev/null +++ b/src/Ursa/Controls/Dialog/DialogWindow.cs @@ -0,0 +1,30 @@ +using Avalonia.Controls; +using Avalonia.Controls.Metadata; +using Avalonia.Controls.Primitives; + +namespace Ursa.Controls; + +[TemplatePart(PART_CloseButton, typeof(Button))] +public class DialogWindow: Window +{ + public const string PART_CloseButton = "PART_CloseButton"; + + protected override Type StyleKeyOverride { get; } = typeof(DialogWindow); + + private Button? _closeButton; + + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + _closeButton = e.NameScope.Find