Skip to content

Commit

Permalink
Merge branch 'Deadpikle-feature/animate'
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksandarDev committed May 3, 2018
2 parents c5f07ca + c31a1a6 commit 7754595
Show file tree
Hide file tree
Showing 13 changed files with 494 additions and 23 deletions.
6 changes: 5 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.3.0] - 2018-05-03
### Added
- Added notification fade-out and fade-in animations.

## [1.2.0] - 2018-04-30
### Added
- Implemented support for setting custom text color with `Foreground` method.
- Implemented support for setting custom text color with `Foreground` method.

## [1.1.0] - 2018-04-03
### Added
Expand Down
2 changes: 1 addition & 1 deletion Enterwell.Clients.Wpf.Notifications.Sample/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
VerticalAlignment="Top"
Background="#1751C3"
Click="ButtonBaseInfoDelayOnClick"
Content="Info message with delayed dismiss (5s)"
Content="Animated info message with delayed dismiss (5s)"
Style="{StaticResource NotificationMessageButtonStyle}" />

</StackPanel>
Expand Down
12 changes: 10 additions & 2 deletions Enterwell.Clients.Wpf.Notifications.Sample/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ public partial class MainWindow
/// </summary>
public MainWindow()
{
InitializeComponent();

this.InitializeComponent();
this.DataContext = this;
}

Expand Down Expand Up @@ -78,6 +77,9 @@ private void ButtonBaseInfoDelayOnClick(object sender, RoutedEventArgs e)
this.Manager
.CreateMessage()
.Accent("#1751C3")
.Animates(true)
.AnimationInDuration(0.75)
.AnimationOutDuration(2)
.Background("#333")
.HasBadge("Info")
.HasMessage("Update will be installed on next application restart. This message will be dismissed after 5 seconds.")
Expand All @@ -87,6 +89,12 @@ private void ButtonBaseInfoDelayOnClick(object sender, RoutedEventArgs e)
.Queue();
}

/// <summary>
/// Gets the notification message manager.
/// </summary>
/// <value>
/// The notification message manager.
/// </value>
public INotificationMessageManager Manager { get; } = new NotificationMessageManager();
}
}
172 changes: 171 additions & 1 deletion Enterwell.Clients.Wpf.Notifications/Controls/NotificationMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Enterwell.Clients.Wpf.Notifications.Controls
{
Expand All @@ -11,7 +12,7 @@ namespace Enterwell.Clients.Wpf.Notifications.Controls
/// </summary>
/// <seealso cref="INotificationMessage" />
/// <seealso cref="Control" />
public class NotificationMessage : Control, INotificationMessage
public class NotificationMessage : Control, INotificationMessage, INotificationAnimation
{
/// <summary>
/// Gets or sets the content of the overlay.
Expand Down Expand Up @@ -145,6 +146,133 @@ public ObservableCollection<object> Buttons
set => SetValue(ButtonsProperty, value);
}

/// <summary>
/// Gets or sets whether the message animates.
/// </summary>
/// <value>
/// Whether or not the message animates.
/// </value>
public bool Animates
{
get => (bool)GetValue(AnimatesProperty);
set => SetValue(AnimatesProperty, value);
}

/// <summary>
/// Gets or sets how long the message animates in (in seconds).
/// </summary>
/// <value>
/// How long the message animates in (in seconds).
/// </value>
public double AnimationInDuration
{
get => (double)GetValue(AnimationInDurationProperty);
set => SetValue(AnimationInDurationProperty, value);
}

/// <summary>
/// Gets or sets how long the message animates out (in seconds).
/// </summary>
/// <value>
/// How long the message animates out (in seconds).
/// </value>
public double AnimationOutDuration
{
get => (double)GetValue(AnimationOutDurationProperty);
set => SetValue(AnimationOutDurationProperty, value);
}

/// <summary>
/// The animatable element used for show/hide animations.
/// </summary>
public UIElement AnimatableElement
{
get => this;
}

/// <summary>
/// The animation in.
/// </summary>
public AnimationTimeline AnimationIn
{
get
{
var animation = (AnimationTimeline)GetValue(AnimationInProperty);
if (animation != null)
{
animation.Duration = TimeSpan.FromSeconds(AnimationInDuration);
return animation;
}
else
{
var doubleAnimation = new DoubleAnimation
{
From = 0,
To = 1,
BeginTime = TimeSpan.FromSeconds(0),
Duration = TimeSpan.FromSeconds(AnimationInDuration),
FillBehavior = FillBehavior.HoldEnd
};
return doubleAnimation;
}
}
set => SetValue(AnimationInProperty, value);
}

/// <summary>
/// The animation out.
/// </summary>
public AnimationTimeline AnimationOut
{
get
{
var animation = (AnimationTimeline)GetValue(AnimationOutProperty);
if (animation != null)
{
animation.Duration = TimeSpan.FromSeconds(AnimationOutDuration);
return animation;
}
else
{
return new DoubleAnimation
{
From = 1,
To = 0,
BeginTime = TimeSpan.FromSeconds(0),
Duration = TimeSpan.FromSeconds(AnimationOutDuration),
FillBehavior = FillBehavior.HoldEnd
};
}
}
set => SetValue(AnimationOutProperty, value);
}

/// <summary>
/// The dependency property on which to animate while animating in.
/// </summary>
public DependencyProperty AnimationInDependencyProperty
{
get
{
var property = (DependencyProperty)GetValue(AnimationInDependencyPropProperty);
return property ?? UIElement.OpacityProperty;
}
set => SetValue(AnimationInDependencyPropProperty, value);
}

/// <summary>
/// The dependency property on which to animate while animating out.
/// </summary>
public DependencyProperty AnimationOutDependencyProperty
{
get
{
var property = (DependencyProperty)GetValue(AnimationOutDependencyPropProperty);
return property ?? UIElement.OpacityProperty;
}
set => SetValue(AnimationOutDependencyPropProperty, value);
}

/// <summary>
/// The overlay content property.
/// </summary>
Expand Down Expand Up @@ -281,6 +409,48 @@ private static void MessagePropertyChangesCallback(DependencyObject dependencyOb
public static readonly DependencyProperty ButtonsProperty =
DependencyProperty.Register("Buttons", typeof(ObservableCollection<object>), typeof(NotificationMessage), new PropertyMetadata(null));

/// <summary>
/// The animates property.
/// </summary>
public static readonly DependencyProperty AnimatesProperty =
DependencyProperty.Register("Animates", typeof(bool), typeof(NotificationMessage), new PropertyMetadata(false));

/// <summary>
/// The animation in duration property (in seconds).
/// </summary>
public static readonly DependencyProperty AnimationInDurationProperty =
DependencyProperty.Register("AnimationInDuration", typeof(double), typeof(NotificationMessage), new PropertyMetadata(0.25));

/// <summary>
/// The animation out duration property (in seconds).
/// </summary>
public static readonly DependencyProperty AnimationOutDurationProperty =
DependencyProperty.Register("AnimationOutDuration", typeof(double), typeof(NotificationMessage), new PropertyMetadata(0.25));

/// <summary>
/// The animation in property.
/// </summary>
public static readonly DependencyProperty AnimationInProperty =
DependencyProperty.Register("AnimationIn", typeof(AnimationTimeline), typeof(NotificationMessage), new PropertyMetadata(null));

/// <summary>
/// The animation out property.
/// </summary>
public static readonly DependencyProperty AnimationOutProperty =
DependencyProperty.Register("AnimationOut", typeof(AnimationTimeline), typeof(NotificationMessage), new PropertyMetadata(null));

/// <summary>
/// The animation in dependency property.
/// </summary>
public static readonly DependencyProperty AnimationInDependencyPropProperty =
DependencyProperty.Register("AnimationInDependencyProperty", typeof(DependencyProperty), typeof(NotificationMessage), new PropertyMetadata(null));

/// <summary>
/// The animation out dependency property.
/// </summary>
public static readonly DependencyProperty AnimationOutDependencyPropProperty =
DependencyProperty.Register("AnimationOutDependencyProperty", typeof(DependencyProperty), typeof(NotificationMessage), new PropertyMetadata(null));


/// <summary>
/// Initializes the <see cref="NotificationMessage" /> class.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace Enterwell.Clients.Wpf.Notifications.Controls
{
Expand Down Expand Up @@ -79,7 +80,30 @@ private void ManagerOnOnMessageDismissed(object sender, NotificationMessageManag
throw new InvalidOperationException(
"Can't use both ItemsSource and Items collection at the same time.");

this.Items?.Remove(args.Message);
if (args.Message is INotificationAnimation)
{
var animatableMessage = args.Message as INotificationAnimation;
var animation = animatableMessage.AnimationOut;
if (animatableMessage.Animates && animatableMessage.AnimatableElement != null
&& animation != null && animatableMessage.AnimationOutDependencyProperty != null)
{
animation.Completed += (s, a) => this.RemoveMessage(args.Message);
animatableMessage.AnimatableElement.BeginAnimation(animatableMessage.AnimationOutDependencyProperty, animation);
}
else
{
this.RemoveMessage(args.Message);
}
}
else
{
this.RemoveMessage(args.Message);
}
}

private void RemoveMessage(INotificationMessage message)
{
this.Items?.Remove(message);
}

/// <summary>
Expand All @@ -95,6 +119,17 @@ private void ManagerOnOnMessageQueued(object sender, NotificationMessageManagerE
"Can't use both ItemsSource and Items collection at the same time.");

this.Items?.Add(args.Message);

if (args.Message is INotificationAnimation)
{
var animatableMessage = args.Message as INotificationAnimation;
var animation = animatableMessage.AnimationIn;
if (animatableMessage.Animates && animatableMessage.AnimatableElement != null
&& animation != null && animatableMessage.AnimationInDependencyProperty != null)
{
animatableMessage.AnimatableElement.BeginAnimation(animatableMessage.AnimationInDependencyProperty, animation);
}
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<Compile Include="Controls\NotificationMessageButton.cs" />
<Compile Include="Controls\NotificationMessageContainer.cs" />
<Compile Include="INotificationMessage.cs" />
<Compile Include="INotificationAnimation.cs" />
<Compile Include="INotificationMessageButton.cs" />
<Compile Include="INotificationMessageFactory.cs" />
<Compile Include="INotificationMessageManager.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<projectUrl>https://github.com/Enterwell/Wpf.Notifications</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
<releaseNotes>Added support for setting custom text color with `Foreground` method.</releaseNotes>
<releaseNotes>Added notification fade-out and fade-in animations.</releaseNotes>
<copyright>Copyright (c) Enterwell d.o.o. 2017-2018</copyright>
<tags>wpf notifications</tags>
</metadata>
Expand Down
54 changes: 54 additions & 0 deletions Enterwell.Clients.Wpf.Notifications/INotificationAnimation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Windows;
using System.Windows.Media.Animation;

namespace Enterwell.Clients.Wpf.Notifications
{
/// <summary>
/// The animation properties for a notification message or some
/// other item.
/// </summary>
interface INotificationAnimation
{
/// <summary>
/// Gets or sets whether the item animates in and out.
/// </summary>
bool Animates { get; set; }

/// <summary>
/// Gets or sets the animation in duration (in seconds).
/// </summary>
double AnimationInDuration { get; set; }

/// <summary>
/// Gets or sets the animation out duration (in seconds).
/// </summary>
double AnimationOutDuration { get; set; }

/// <summary>
/// Gets or sets the animation in.
/// </summary>
AnimationTimeline AnimationIn { get; set; }

/// <summary>
/// Gets or sets the animation out.
/// </summary>
AnimationTimeline AnimationOut { get; set; }

/// <summary>
/// Gets or sets the DependencyProperty for the animation in.
/// </summary>
DependencyProperty AnimationInDependencyProperty { get; set; }

/// <summary>
/// Gets or sets the DependencyProperty for the animation out.
/// </summary>
DependencyProperty AnimationOutDependencyProperty { get; set; }

/// <summary>
/// Gets the animatable UIElement.
/// Typically this is the whole Control object so that the entire
/// item can be animated.
/// </summary>
UIElement AnimatableElement { get; }
}
}
Loading

0 comments on commit 7754595

Please sign in to comment.