diff --git a/samples/ControlCatalog/MainWindow.xaml.cs b/samples/ControlCatalog/MainWindow.xaml.cs index 1d54378f3a..b5e315573d 100644 --- a/samples/ControlCatalog/MainWindow.xaml.cs +++ b/samples/ControlCatalog/MainWindow.xaml.cs @@ -12,7 +12,7 @@ namespace ControlCatalog { public class MainWindow : Window { - private NotificationArea _notificationArea; + private WindowNotificationManager _notificationArea; public MainWindow() { @@ -21,7 +21,7 @@ namespace ControlCatalog //Renderer.DrawFps = true; //Renderer.DrawDirtyRects = Renderer.DrawFps = true; - _notificationArea = new NotificationArea + _notificationArea = new WindowNotificationManager { Position = NotificationPosition.TopRight, MaxItems = 3 diff --git a/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs b/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs index 5ba969345c..962a3227d4 100644 --- a/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs +++ b/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs @@ -1,15 +1,15 @@ using System.Reactive; -using System.Threading.Tasks; using Avalonia.Controls.Notifications; using Avalonia.Diagnostics.ViewModels; -using Avalonia.Threading; using ReactiveUI; namespace ControlCatalog.ViewModels { class MainWindowViewModel : ViewModelBase { - public MainWindowViewModel(INotificationManager notificationManager) + private IManagedNotificationManager _notificationManager; + + public MainWindowViewModel(IManagedNotificationManager notificationManager) { _notificationManager = notificationManager; @@ -20,18 +20,16 @@ namespace ControlCatalog.ViewModels ShowManagedNotificationCommand = ReactiveCommand.Create(() => { - NotificationManager.Show(new NotificationContent { Title = "Welcome", Message = "Avalonia now supports Notifications.", Type = NotificationType.Information }); + NotificationManager.Show(SimpleNotification.Create("Welcome", "Avalonia now supports Notifications.", NotificationType.Information)); }); ShowNativeNotificationCommand = ReactiveCommand.Create(() => { - NotificationManager.Show(new NotificationContent { Title = "Error", Message = "Native Notifications are not quite ready. Coming soon.", Type = NotificationType.Error }); + NotificationManager.Show(SimpleNotification.Create("Error", "Native Notifications are not quite ready. Coming soon.", NotificationType.Error)); }); } - private INotificationManager _notificationManager; - - public INotificationManager NotificationManager + public IManagedNotificationManager NotificationManager { get { return _notificationManager; } set { this.RaiseAndSetIfChanged(ref _notificationManager, value); } diff --git a/samples/ControlCatalog/ViewModels/NotificationViewModel.cs b/samples/ControlCatalog/ViewModels/NotificationViewModel.cs index 9e60700e71..2fba6865c9 100644 --- a/samples/ControlCatalog/ViewModels/NotificationViewModel.cs +++ b/samples/ControlCatalog/ViewModels/NotificationViewModel.cs @@ -1,5 +1,4 @@ using System.Reactive; -using Avalonia; using Avalonia.Controls.Notifications; using ReactiveUI; @@ -11,12 +10,12 @@ namespace ControlCatalog.ViewModels { YesCommand = ReactiveCommand.Create(() => { - manager.Show(new NotificationContent { Title = "Avalonia Notifications", Message = "Start adding notifications to your app today." }); + manager.Show(SimpleNotification.Create("Avalonia Notifications", "Start adding notifications to your app today.")); }); NoCommand = ReactiveCommand.Create(() => { - manager.Show(new NotificationContent { Title = "Avalonia Notifications", Message = "Start adding notifications to your app today. To find out more visit..." }); + manager.Show(SimpleNotification.Create("Avalonia Notifications", "Start adding notifications to your app today. To find out more visit...")); }); } diff --git a/src/Avalonia.Controls/Notifications/INotificationManager.cs b/src/Avalonia.Controls/Notifications/INotificationManager.cs index 45a7c8ff9b..f2af87fb4a 100644 --- a/src/Avalonia.Controls/Notifications/INotificationManager.cs +++ b/src/Avalonia.Controls/Notifications/INotificationManager.cs @@ -2,10 +2,28 @@ namespace Avalonia.Controls.Notifications { + public interface INotification + { + string Title { get; } + + string Message { get; } + + NotificationType Type { get; } + + TimeSpan Expiration { get; } + + Action OnClick { get; } + + Action OnClose { get; } + } + public interface INotificationManager { - void Show(object content, TimeSpan? expirationTime = null, Action onClick = null, Action onClose = null); + void Show(INotification notification); + } - void Show(NotificationContent content, TimeSpan? expirationTime = null, Action onClick = null, Action onClose = null); + public interface IManagedNotificationManager : INotificationManager + { + void Show(object content); } } diff --git a/src/Avalonia.Controls/Notifications/Notification.cs b/src/Avalonia.Controls/Notifications/Notification.cs index d4cee99ba3..54a8e81f86 100644 --- a/src/Avalonia.Controls/Notifications/Notification.cs +++ b/src/Avalonia.Controls/Notifications/Notification.cs @@ -20,7 +20,7 @@ namespace Avalonia.Controls.Notifications public Notification() { this.GetObservable(ContentProperty) - .OfType() + .OfType() .Subscribe(x => { switch (x.Type) diff --git a/src/Avalonia.Controls/Notifications/NotificationContent.cs b/src/Avalonia.Controls/Notifications/NotificationContent.cs deleted file mode 100644 index 637254aff8..0000000000 --- a/src/Avalonia.Controls/Notifications/NotificationContent.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Avalonia.Controls.Notifications -{ - /// - /// Defines content for a control. - /// - /// - /// This notification content type is compatible with native notifications. - /// - public class NotificationContent - { - public string Title { get; set; } - public string Message { get; set; } - public NotificationType Type { get; set; } - } - - public enum NotificationType - { - Information, - Success, - Warning, - Error - } -} diff --git a/src/Avalonia.Controls/Notifications/SimpleNotification.cs b/src/Avalonia.Controls/Notifications/SimpleNotification.cs new file mode 100644 index 0000000000..16e1bb483e --- /dev/null +++ b/src/Avalonia.Controls/Notifications/SimpleNotification.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Avalonia.Controls.Notifications +{ + /// + /// Defines content for a control. + /// + /// + /// This notification content type is compatible with native notifications. + /// + public class SimpleNotification : INotification + { + public static INotification Create ( + string title, + string message, + NotificationType type = NotificationType.Information, + TimeSpan? expiration = null, + Action onClick = null, + Action onClose = null) + { + var result = new SimpleNotification + { + Title = title, + Message = message, + Type = type, + Expiration = expiration.HasValue ? expiration.Value : TimeSpan.FromSeconds(5), + OnClick = onClick, + OnClose = onClose + }; + + return result; + } + + public string Title { get; private set; } + + public string Message { get; private set; } + + public NotificationType Type { get; private set; } + + public TimeSpan Expiration { get; private set; } + + public Action OnClick { get; private set; } + + public Action OnClose { get; private set; } + } + + public enum NotificationType + { + Information, + Success, + Warning, + Error + } +} diff --git a/src/Avalonia.Controls/Notifications/NotificationArea.cs b/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs similarity index 55% rename from src/Avalonia.Controls/Notifications/NotificationArea.cs rename to src/Avalonia.Controls/Notifications/WindowNotificationManager.cs index 01655915e3..676ea230f2 100644 --- a/src/Avalonia.Controls/Notifications/NotificationArea.cs +++ b/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs @@ -8,7 +8,7 @@ using Avalonia.VisualTree; namespace Avalonia.Controls.Notifications { - public class NotificationArea : TemplatedControl, INotificationManager + public class WindowNotificationManager : TemplatedControl, IManagedNotificationManager { private IList _items; @@ -23,7 +23,7 @@ namespace Avalonia.Controls.Notifications } public static readonly AvaloniaProperty PositionProperty = - AvaloniaProperty.RegisterAttached("Position", defaultValue: NotificationPosition.TopLeft, inherits: true); + AvaloniaProperty.RegisterAttached("Position", defaultValue: NotificationPosition.TopLeft, inherits: true); public NotificationPosition Position { @@ -42,7 +42,7 @@ namespace Avalonia.Controls.Notifications } public static readonly AvaloniaProperty MaxItemsProperty = - AvaloniaProperty.RegisterAttached("Position", defaultValue: 5, inherits: true); + AvaloniaProperty.RegisterAttached("Position", defaultValue: 5, inherits: true); public int MaxItems { @@ -50,15 +50,15 @@ namespace Avalonia.Controls.Notifications set { SetValue(MaxItemsProperty, value); } } - static NotificationArea() + static WindowNotificationManager() { - PseudoClass(PositionProperty, x => x == NotificationPosition.TopLeft, ":topleft"); - PseudoClass(PositionProperty, x => x == NotificationPosition.TopRight, ":topright"); - PseudoClass(PositionProperty, x => x == NotificationPosition.BottomLeft, ":bottomleft"); - PseudoClass(PositionProperty, x => x == NotificationPosition.BottomRight, ":bottomright"); + PseudoClass(PositionProperty, x => x == NotificationPosition.TopLeft, ":topleft"); + PseudoClass(PositionProperty, x => x == NotificationPosition.TopRight, ":topright"); + PseudoClass(PositionProperty, x => x == NotificationPosition.BottomLeft, ":bottomleft"); + PseudoClass(PositionProperty, x => x == NotificationPosition.BottomRight, ":bottomright"); - HorizontalAlignmentProperty.OverrideDefaultValue(Layout.HorizontalAlignment.Stretch); - VerticalAlignmentProperty.OverrideDefaultValue(Layout.VerticalAlignment.Stretch); + HorizontalAlignmentProperty.OverrideDefaultValue(Layout.HorizontalAlignment.Stretch); + VerticalAlignmentProperty.OverrideDefaultValue(Layout.VerticalAlignment.Stretch); } protected override void OnTemplateApplied(TemplateAppliedEventArgs e) @@ -69,32 +69,39 @@ namespace Avalonia.Controls.Notifications _items = itemsControl?.Children; } - public void Show(NotificationContent content, TimeSpan? expirationTime, Action onClick, Action onClose) + public void Show(INotification content) { - Show(content as object, expirationTime, onClick, onClose); + Show(content as object); } - public async void Show(object content, TimeSpan? expirationTime, Action onClick, Action onClose) + public async void Show(object content) { - var notification = new Notification + var notification = content as INotification; + + var notificationControl = new Notification { Content = content }; - notification.PointerPressed += (sender, args) => + if (notification != null) + { + notificationControl.NotificationClosed += (sender, args) => notification.OnClose?.Invoke(); + } + + notificationControl.NotificationClosed += OnNotificationClosed; + + notificationControl.PointerPressed += (sender, args) => { - if (onClick != null) + if (notification != null && notification.OnClick != null) { - onClick.Invoke(); + notification.OnClick.Invoke(); (sender as Notification)?.Close(); } }; - notification.NotificationClosed += (sender, args) => onClose?.Invoke(); - notification.NotificationClosed += OnNotificationClosed; lock (_items) { - _items.Add(notification); + _items.Add(notificationControl); if (_items.OfType().Count(i => !i.IsClosing) > MaxItems) { @@ -102,14 +109,14 @@ namespace Avalonia.Controls.Notifications } } - if (expirationTime == TimeSpan.MaxValue) + if (notification != null && notification.Expiration == TimeSpan.MaxValue) { return; } - await Task.Delay(expirationTime ?? TimeSpan.FromSeconds(5)); + await Task.Delay(notification?.Expiration ?? TimeSpan.FromSeconds(5)); - notification.Close(); + notificationControl.Close(); } private void OnNotificationClosed(object sender, RoutedEventArgs routedEventArgs) @@ -118,7 +125,7 @@ namespace Avalonia.Controls.Notifications _items.Remove(notification); } - public void Install(TopLevel host) + public void Install(Window host) { var adornerLayer = host.GetVisualDescendants() .OfType() diff --git a/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj b/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj index 7dedcdef57..49ec1ad764 100644 --- a/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj +++ b/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj @@ -26,4 +26,9 @@ MSBuild:Compile + + + MSBuild:Compile + + diff --git a/src/Avalonia.Themes.Default/DefaultTheme.xaml b/src/Avalonia.Themes.Default/DefaultTheme.xaml index 801fb61a4d..5122bf9c9a 100644 --- a/src/Avalonia.Themes.Default/DefaultTheme.xaml +++ b/src/Avalonia.Themes.Default/DefaultTheme.xaml @@ -46,5 +46,5 @@ - + diff --git a/src/Avalonia.Themes.Default/NotificationArea.xaml b/src/Avalonia.Themes.Default/WindowNotificationManager.xaml similarity index 92% rename from src/Avalonia.Themes.Default/NotificationArea.xaml rename to src/Avalonia.Themes.Default/WindowNotificationManager.xaml index 1c314bbfa2..2eba134b94 100644 --- a/src/Avalonia.Themes.Default/NotificationArea.xaml +++ b/src/Avalonia.Themes.Default/WindowNotificationManager.xaml @@ -1,12 +1,12 @@  - - - - -