Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Added Notification Type, Type Visibility #13

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions Avalonia.Notification.Samples/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Controls.Notifications;
using Avalonia.Layout;
using Avalonia.Media;

Expand All @@ -25,6 +23,7 @@ public void ButtonBaseErrorOnClick()
.CreateMessage()
.Accent("#F15B19")
.Background("#F15B19")
.HasType(NotificationType.Error)
.HasHeader("Lost connection to server")
.HasMessage("Reconnecting...")
.WithOverlay(new ProgressBar
Expand All @@ -47,6 +46,7 @@ public void ButtonBaseWarningOnClick()
.CreateMessage()
.Accent("#E0A030")
.Background("#333")
.HasType(NotificationType.Warning)
.HasBadge("Warn")
.HasHeader("Error")
.HasMessage("Failed to retrieve data.")
Expand All @@ -61,6 +61,7 @@ public void ButtonBaseInfoOnClick()
.CreateMessage()
.Accent("#1751C3")
.Background("#333")
.HasType(NotificationType.Information)
.HasBadge("Info")
.HasMessage("Update will be installed on next application restart.")
.Dismiss().WithButton("Update now", button => { })
Expand All @@ -76,6 +77,7 @@ public void ButtonBaseInfoDelayOnClick()
.Accent("#1751C3")
.Animates(true)
.Background("#333")
.HasType(NotificationType.Information)
.HasBadge("Info")
.HasMessage(
"Update will be installed on next application restart. This message will be dismissed after 5 seconds.")
Expand All @@ -86,4 +88,4 @@ public void ButtonBaseInfoDelayOnClick()
}
public string Greeting => "Welcome to Avalonia!";
}
}
}
98 changes: 88 additions & 10 deletions Notification.Avalonia/Controls/NotificationMessage.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using System.Collections.ObjectModel;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Reactive;
using Avalonia.Styling;

namespace Avalonia.Notification.Controls;

Expand All @@ -14,8 +13,15 @@ namespace Avalonia.Notification.Controls;
/// </summary>
/// <seealso cref="INotificationMessage" />
/// <seealso cref="Control" />
[PseudoClasses(InformationPseudoClassName, SuccessPseudoClassName, WarningPseudoClassName, ErrorPseudoClassName)]
public class NotificationMessage : TemplatedControl, INotificationMessage, INotificationAnimation
{

private const string InformationPseudoClassName = ":information";
private const string SuccessPseudoClassName = ":success";
private const string WarningPseudoClassName = ":warning";
private const string ErrorPseudoClassName = ":error";

/// <summary>
/// Gets or sets the content of the overlay.
/// </summary>
Expand Down Expand Up @@ -137,6 +143,13 @@ public bool BadgeVisibility
set => SetValue(BadgeVisibilityProperty, value);
}

/// <inheritdoc cref="INotificationMessage.CloseButtonVisibility"/>
public bool CloseButtonVisibility
{
get => GetValue(CloseButtonVisibilityProperty);
set => SetValue(CloseButtonVisibilityProperty, value);
}

/// <summary>
/// Gets or sets the badge accent brush.
/// </summary>
Expand All @@ -161,6 +174,25 @@ public string BadgeText
set => SetValue(BadgeTextProperty, value);
}


/// <inheritdoc cref="INotificationMessage.Type"/>
public NotificationType Type
{
get => GetValue(TypeProperty);
set => SetValue(TypeProperty, value);
}


/// <inheritdoc cref="INotificationMessage.TypeVisibility"/>
/// <remarks>
/// The default value for this property is <see langword="true"/>
/// </remarks>
public bool TypeVisibility
{
get => GetValue(TypeVisibilityProperty);
set => SetValue(TypeVisibilityProperty, value);
}

/// <summary>
/// Gets or sets the header visibility.
/// </summary>
Expand Down Expand Up @@ -335,6 +367,12 @@ private static void AccentBrushPropertyChangedCallback(AvaloniaObject dependency
@this.ButtonAccentBrush ??= dependencyPropertyChangedEventArgs.NewValue as IBrush;
}

/// <summary>
/// The close button visibility property.
/// </summary>
public static readonly StyledProperty<bool> CloseButtonVisibilityProperty =
AvaloniaProperty.Register<NotificationMessage, bool>(nameof(CloseButtonVisibility));

/// <summary>
/// The button accent brush property.
/// </summary>
Expand All @@ -346,7 +384,7 @@ private static void AccentBrushPropertyChangedCallback(AvaloniaObject dependency
/// </summary>
public static readonly StyledProperty<bool> BadgeVisibilityProperty =
AvaloniaProperty.Register<NotificationMessage, bool>("BadgeVisibility");

/// <summary>
/// The badge accent brush property.
/// </summary>
Expand All @@ -373,6 +411,18 @@ private static void BadgeTextPropertyChangedCallback(AvaloniaObject dependencyOb
@this.BadgeVisibility = dependencyPropertyChangedEventArgs.NewValue != null;
}

/// <summary>
/// The <see cref="Type"/> property
/// </summary>
public static readonly StyledProperty<NotificationType> TypeProperty =
AvaloniaProperty.Register<NotificationMessage, NotificationType>(nameof(Type));

/// <summary>
/// The <see cref="TypeVisibility"/> property
/// </summary>
public static readonly StyledProperty<bool> TypeVisibilityProperty =
AvaloniaProperty.Register<NotificationMessage, bool>(nameof(TypeVisibility), true);

/// <summary>
/// The header visibility property.
/// </summary>
Expand Down Expand Up @@ -442,10 +492,14 @@ private static void MessagePropertyChangesCallback(AvaloniaObject dependencyObje
/// </summary>
static NotificationMessage()
{
AccentBrushProperty.Changed.Subscribe(new AnonymousObserver<AvaloniaPropertyChangedEventArgs<IBrush>>(x => AccentBrushPropertyChangedCallback(x.Sender, x)));
BadgeTextProperty.Changed.Subscribe(new AnonymousObserver<AvaloniaPropertyChangedEventArgs<string>>(x => BadgeTextPropertyChangedCallback(x.Sender, x)));
MessageProperty.Changed.Subscribe(new AnonymousObserver<AvaloniaPropertyChangedEventArgs<string>>(x => MessagePropertyChangesCallback(x.Sender, x)));
HeaderProperty.Changed.Subscribe(new AnonymousObserver<AvaloniaPropertyChangedEventArgs<string>>(x => HeaderPropertyChangesCallback(x.Sender, x)));
AccentBrushProperty.Changed.AddClassHandler<NotificationMessage>(AccentBrushPropertyChangedCallback);
BadgeTextProperty.Changed.AddClassHandler<NotificationMessage>(BadgeTextPropertyChangedCallback);
MessageProperty.Changed.AddClassHandler<NotificationMessage>(MessagePropertyChangesCallback);
HeaderProperty.Changed.AddClassHandler<NotificationMessage>(HeaderPropertyChangesCallback);

TypeProperty.Changed.AddClassHandler<NotificationMessage>((s, _) => s.UpdatePseudoClasses());
TypeVisibilityProperty.Changed.AddClassHandler<NotificationMessage>((s, _) => s.UpdatePseudoClasses());

//TODO what is this
// DefaultStyleKeyProperty.OverrideMetadata(typeof(NotificationMessage), new FrameworkPropertyMetadata(typeof(NotificationMessage)));
}
Expand All @@ -460,6 +514,30 @@ public NotificationMessage()
Background = new SolidColorBrush(new Color(100, 0, 0, 0));

this.Foreground = new BrushConverter().ConvertFromString("#DDDDDD") as IBrush;
this.Classes.Add("notificationMessage");

UpdatePseudoClasses();

// This was only used in one style selector which could be rewritten to use the any descendants style selector
//this.Classes.Add("notificationMessage");
}
}

/// <summary>
/// This method updates the pseudo classes of the control when the <see cref="Type"/> or <see cref="TypeVisibility"/> property change
/// </summary>
private void UpdatePseudoClasses()
{
if (!TypeVisibility)
{
this.PseudoClasses.Set(InformationPseudoClassName, false);
this.PseudoClasses.Set(SuccessPseudoClassName, false);
this.PseudoClasses.Set(WarningPseudoClassName, false);
this.PseudoClasses.Set(ErrorPseudoClassName, false);
return;
}

this.PseudoClasses.Set(InformationPseudoClassName, Type == NotificationType.Information);
this.PseudoClasses.Set(SuccessPseudoClassName, Type == NotificationType.Success);
this.PseudoClasses.Set(WarningPseudoClassName, Type == NotificationType.Warning);
this.PseudoClasses.Set(ErrorPseudoClassName, Type == NotificationType.Error);
}
}
31 changes: 30 additions & 1 deletion Notification.Avalonia/INotificationMessage.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using Avalonia.Controls.Notifications;
using Avalonia.Media;

namespace Avalonia.Notification
Expand Down Expand Up @@ -55,6 +56,34 @@ public interface INotificationMessage
/// The badge visibility.
/// </value>
bool BadgeVisibility { get; set; }

/// <summary>
/// Gets or sets the close button visibility.
/// </summary>
/// <value>
/// The close button visibility.
/// </value>
bool CloseButtonVisibility { get; set; }


/// <summary>
/// Gets or sets the type of the notification for use in styles.
/// </summary>
/// <value>
/// The Notification type.
/// </value>
/// <remarks>
/// The default <see cref="NotificationType"/> is <see cref="NotificationType.Information"/>
/// </remarks>
NotificationType Type { get; set; }

/// <summary>
/// Gets or sets the visibility of the notification type display
/// </summary>
/// <value>
/// The visibility of the notification type
/// </value>
bool TypeVisibility { get; set; }

/// <summary>
/// Gets or sets the button accent brush.
Expand Down Expand Up @@ -160,4 +189,4 @@ public interface INotificationMessage
/// </value>
object AdditionalContentOverBadge { get; set; }
}
}
}
37 changes: 35 additions & 2 deletions Notification.Avalonia/NotificationMessageBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Avalonia.Media;
using Avalonia.Controls.Notifications;
using Avalonia.Media;

namespace Avalonia.Notification;

Expand Down Expand Up @@ -33,6 +34,15 @@ public static NotificationMessageBuilder CreateMessage()
return new NotificationMessageBuilder();
}

/// <summary>
/// Sets the close button visibility.
/// </summary>
/// <param name="closeButtonVisibility">The value of the close button visibility</param>
public void SetCloseButtonVisibility(bool closeButtonVisibility)
{
this.Message.CloseButtonVisibility = closeButtonVisibility;
}

/// <summary>
/// Sets the header.
/// </summary>
Expand Down Expand Up @@ -81,6 +91,29 @@ public void SetAccent(IBrush accentBrush)
this.Message.AccentBrush = accentBrush;
}


/// <summary>
/// Sets the type.
/// </summary>
/// <remarks>
/// This also sets the <see cref="INotificationMessage.TypeVisibility"/> to <see langword="true"/> to make for cleaner code
/// </remarks>
/// <param name="type">The <see cref="NotificationType"/> used for the message.</param>
public void SetType(NotificationType type)
{
this.Message.Type = type;
this.Message.TypeVisibility = true;
}

/// <summary>
/// Sets the type visibility
/// </summary>
/// <param name="typeVisibility">The type visibility</param>
public void SetTypeVisibility(bool typeVisibility)
{
this.Message.TypeVisibility = typeVisibility;
}

/*/// <summary>
/// Sets the background.
/// </summary>
Expand Down Expand Up @@ -247,4 +280,4 @@ public DismissNotificationMessage(NotificationMessageBuilder builder)
/// </value>
public NotificationMessageBuilder Builder { get; set; }
}
}
}
50 changes: 48 additions & 2 deletions Notification.Avalonia/NotificationMessageBuilderLinq.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Avalonia.Media;
using Avalonia.Controls.Notifications;
using Avalonia.Media;

// ReSharper disable UnusedMember.Global
// ReSharper disable RedundantEmptySwitchSection
Expand All @@ -10,6 +11,21 @@ namespace Avalonia.Notification;
/// </summary>
public static class NotificationMessageBuilderLinq
{
/// <summary>
/// Sets the close button visibility.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="closeButtonVisibility">The close button visibility</param>
/// <returns>Returns the notification message builder.</returns>
public static NotificationMessageBuilder HasCloseButtonVisibility(
this NotificationMessageBuilder builder,
bool closeButtonVisibility)
{
builder.SetCloseButtonVisibility(closeButtonVisibility);

return builder;
}

/// <summary>
/// Sets the notification message background.
/// </summary>
Expand Down Expand Up @@ -127,6 +143,36 @@ public static NotificationMessageBuilder HasMessage(
return builder;
}

/// <summary>
/// Sets the notification type.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="type">The notification type.</param>
/// <returns>Returns the notification message builder.</returns>
public static NotificationMessageBuilder HasType(
this NotificationMessageBuilder builder,
NotificationType type)
{
builder.SetType(type);

return builder;
}

/// <summary>
/// Sets the message type visibility
/// </summary>
/// <param name="builder">The builder</param>
/// <param name="typeVisibility">The notification type visibility</param>
/// <returns>Returns the notification message builder.</returns>
public static NotificationMessageBuilder HasTypeVisibility(
this NotificationMessageBuilder builder,
bool typeVisibility)
{
builder.SetTypeVisibility(typeVisibility);

return builder;
}

/// <summary>
/// Creates the message.
/// </summary>
Expand Down Expand Up @@ -364,4 +410,4 @@ public static NotificationMessageBuilder Animates(

return builder;
}
}
}
Loading