diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs index b3e2753..64c2e37 100644 --- a/demo/Ursa.Demo/Models/MenuKeys.cs +++ b/demo/Ursa.Demo/Models/MenuKeys.cs @@ -6,6 +6,7 @@ public static class MenuKeys public const string MenuKeyBadge = "Badge"; public const string MenuKeyBanner = "Banner"; public const string MenuKeyButtonGroup = "ButtonGroup"; + public const string MenuKeyDialog = "Dialog"; public const string MenuKeyDivider = "Divider"; public const string MenuKeyDualBadge = "DualBadge"; public const string MenuKeyImageViewer = "ImageViewer"; diff --git a/demo/Ursa.Demo/Pages/DialogDemo.axaml b/demo/Ursa.Demo/Pages/DialogDemo.axaml new file mode 100644 index 0000000..4bc5427 --- /dev/null +++ b/demo/Ursa.Demo/Pages/DialogDemo.axaml @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/DialogDemo.axaml.cs b/demo/Ursa.Demo/Pages/DialogDemo.axaml.cs new file mode 100644 index 0000000..2453f1a --- /dev/null +++ b/demo/Ursa.Demo/Pages/DialogDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class DialogDemo : UserControl +{ + public DialogDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/DialogDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/DialogDemoViewModel.cs new file mode 100644 index 0000000..7210529 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/DialogDemoViewModel.cs @@ -0,0 +1,31 @@ +using System; +using System.Windows.Input; +using Avalonia.Controls; +using Avalonia.Controls.Shapes; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Ursa.Controls; + +namespace Ursa.Demo.ViewModels; + +public class DialogDemoViewModel: ObservableObject +{ + public ICommand ShowLocalOverlayDialogCommand { get; } + public ICommand ShowGlobalOverlayDialogCommand { get; } + + public DialogDemoViewModel() + { + ShowLocalOverlayDialogCommand = new RelayCommand(ShowLocalOverlayDialog); + ShowGlobalOverlayDialogCommand = new RelayCommand(ShowGlobalOverlayDialog); + } + + private async void ShowGlobalOverlayDialog() + { + await DialogBox.ShowOverlayAsync(DateTime.Now, "GlobalHost"); + } + + private async void ShowLocalOverlayDialog() + { + await DialogBox.ShowOverlayAsync(DateTime.Now, "LocalHost"); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index 85312ef..a4a24ab 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -28,6 +28,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyBadge => new BadgeDemoViewModel(), MenuKeys.MenuKeyBanner => new BannerDemoViewModel(), MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(), + MenuKeys.MenuKeyDialog => new DialogDemoViewModel(), MenuKeys.MenuKeyDivider => new DividerDemoViewModel(), MenuKeys.MenuKeyDualBadge => new DualBadgeDemoViewModel(), MenuKeys.MenuKeyImageViewer => new ImageViewerDemoViewModel(), diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index ea66a5e..0195ee8 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -15,6 +15,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "Badge", Key = MenuKeys.MenuKeyBadge }, new() { MenuHeader = "Banner", Key = MenuKeys.MenuKeyBanner }, new() { MenuHeader = "ButtonGroup", Key = MenuKeys.MenuKeyButtonGroup }, + new() { MenuHeader = "Dialog", Key = MenuKeys.MenuKeyDialog }, new() { MenuHeader = "Divider", Key = MenuKeys.MenuKeyDivider }, new() { MenuHeader = "DualBadge", Key = MenuKeys.MenuKeyDualBadge }, new() { MenuHeader = "IconButton", Key = MenuKeys.MenuKeyIconButton }, diff --git a/demo/Ursa.Demo/Views/MainView.axaml b/demo/Ursa.Demo/Views/MainView.axaml index 710026c..b6f6bb6 100644 --- a/demo/Ursa.Demo/Views/MainView.axaml +++ b/demo/Ursa.Demo/Views/MainView.axaml @@ -80,6 +80,7 @@ + diff --git a/src/Ursa/Controls/Dialog/DialogBox.cs b/src/Ursa/Controls/Dialog/DialogBox.cs index 996ee88..278a065 100644 --- a/src/Ursa/Controls/Dialog/DialogBox.cs +++ b/src/Ursa/Controls/Dialog/DialogBox.cs @@ -1,4 +1,7 @@ +using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.Shapes; +using Avalonia.Media; namespace Ursa.Controls; @@ -15,6 +18,20 @@ public static class DialogBox { TView t = new TView(); t.DataContext = vm; - return; + } + + public static async Task ShowOverlayAsync(TViewModel vm, string hostId) + where TView : Control, new() + where TViewModel: new() + { + var t = new Border() + { + Width = 100, Height = 100, Background = Brushes.Aqua, BorderBrush = Brushes.Yellow, + BorderThickness = new Thickness(1) + }; + t.DataContext = vm; + var host = OverlayDialogManager.GetOverlayDialogHost(hostId); + host?.Children.Add(t); + return null; } } \ No newline at end of file diff --git a/src/Ursa/Controls/Dialog/DialogHost.cs b/src/Ursa/Controls/Dialog/OverlayDialogHost.cs similarity index 54% rename from src/Ursa/Controls/Dialog/DialogHost.cs rename to src/Ursa/Controls/Dialog/OverlayDialogHost.cs index 7166146..cdef578 100644 --- a/src/Ursa/Controls/Dialog/DialogHost.cs +++ b/src/Ursa/Controls/Dialog/OverlayDialogHost.cs @@ -2,18 +2,40 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Input; +using Avalonia.Media; using Avalonia.Utilities; namespace Ursa.Controls; -public class DialogHost: Canvas +public class OverlayDialogHost: Canvas { + public static readonly StyledProperty HostIdProperty = AvaloniaProperty.Register( + nameof(HostId)); + + public string HostId + { + get => GetValue(HostIdProperty); + set => SetValue(HostIdProperty, value); + } + private Point _lastPoint; + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + OverlayDialogManager.RegisterOverlayDialogHost(this, HostId); + } + + protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) + { + OverlayDialogManager.UnregisterOverlayDialogHost(HostId); + base.OnDetachedFromVisualTree(e); + } + protected override void OnPointerMoved(PointerEventArgs e) { base.OnPointerMoved(e); - if (e.Source is DialogControl item) + if (e.Source is Control item) { if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) { @@ -31,7 +53,7 @@ public class DialogHost: Canvas protected override void OnPointerPressed(PointerPressedEventArgs e) { base.OnPointerPressed(e); - if (e.Source is DialogControl item) + if (e.Source is Control item) { _lastPoint = e.GetPosition(item); } diff --git a/src/Ursa/Controls/Dialog/OverlayDialogManager.cs b/src/Ursa/Controls/Dialog/OverlayDialogManager.cs new file mode 100644 index 0000000..1dc1480 --- /dev/null +++ b/src/Ursa/Controls/Dialog/OverlayDialogManager.cs @@ -0,0 +1,23 @@ +using System.Collections.Concurrent; + +namespace Ursa.Controls; + +internal static class OverlayDialogManager +{ + private static ConcurrentDictionary _hosts = new(); + + public static void RegisterOverlayDialogHost(OverlayDialogHost host, string id) + { + _hosts.TryAdd(id, host); + } + + public static void UnregisterOverlayDialogHost(string id) + { + _hosts.TryRemove(id, out _); + } + + public static OverlayDialogHost? GetOverlayDialogHost(string id) + { + return _hosts.TryGetValue(id, out var host) ? host : null; + } +} \ No newline at end of file