Skip to content

Commit de6311a

Browse files
authored
Merge pull request #3162 from MahApps/feature/GH-2825_OverlayFadeIn_OverlayFadeOut_Storyboards
WIP MetroWindow: OverlayFadeIn / OverlayFadeOut
2 parents 22fed03 + 267f01a commit de6311a

File tree

2 files changed

+125
-57
lines changed

2 files changed

+125
-57
lines changed

src/MahApps.Metro/MahApps.Metro.Shared/Controls/MetroWindow.cs

Lines changed: 108 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ public class MetroWindow : Window
108108
public static readonly DependencyProperty OverlayBrushProperty = DependencyProperty.Register("OverlayBrush", typeof(Brush), typeof(MetroWindow), new PropertyMetadata(new SolidColorBrush(Color.FromScRgb(255, 0, 0, 0)))); // BlackColorBrush
109109
public static readonly DependencyProperty OverlayOpacityProperty = DependencyProperty.Register("OverlayOpacity", typeof(double), typeof(MetroWindow), new PropertyMetadata(0.7d));
110110

111+
/// <summary>
112+
/// Identifies the <see cref="OverlayFadeIn"/> dependency property.
113+
/// </summary>
114+
public static readonly DependencyProperty OverlayFadeInProperty = DependencyProperty.Register("OverlayFadeIn", typeof(Storyboard), typeof(MetroWindow), new PropertyMetadata(default(Storyboard)));
115+
/// <summary>
116+
/// Identifies the <see cref="OverlayFadeOut"/> dependency property.
117+
/// </summary>
118+
public static readonly DependencyProperty OverlayFadeOutProperty = DependencyProperty.Register("OverlayFadeOut", typeof(Storyboard), typeof(MetroWindow), new PropertyMetadata(default(Storyboard)));
119+
111120
public static readonly DependencyProperty IconTemplateProperty = DependencyProperty.Register("IconTemplate", typeof(DataTemplate), typeof(MetroWindow), new PropertyMetadata(null));
112121
public static readonly DependencyProperty TitleTemplateProperty = DependencyProperty.Register("TitleTemplate", typeof(DataTemplate), typeof(MetroWindow), new PropertyMetadata(null));
113122

@@ -756,12 +765,54 @@ public double OverlayOpacity
756765
set { SetValue(OverlayOpacityProperty, value); }
757766
}
758767

768+
/// <summary>
769+
/// Gets or sets the overlay fade in storyboard.
770+
/// </summary>
771+
public Storyboard OverlayFadeIn
772+
{
773+
get { return (Storyboard)GetValue(OverlayFadeInProperty); }
774+
set { SetValue(OverlayFadeInProperty, value); }
775+
}
776+
777+
/// <summary>
778+
/// Gets or sets the overlay fade out storyboard.
779+
/// </summary>
780+
public Storyboard OverlayFadeOut
781+
{
782+
get { return (Storyboard)GetValue(OverlayFadeOutProperty); }
783+
set { SetValue(OverlayFadeOutProperty, value); }
784+
}
785+
759786
[Obsolete("This property will be deleted in the next release.")]
760787
public string WindowTitle
761788
{
762789
get { return TitleCaps ? Title.ToUpper() : Title; }
763790
}
764791

792+
private bool CanUseOverlayFadingStoryboard(Storyboard sb, out DoubleAnimation animation)
793+
{
794+
animation = null;
795+
if (null == sb)
796+
{
797+
return false;
798+
}
799+
800+
sb.Dispatcher.VerifyAccess();
801+
802+
animation = sb.Children.OfType<DoubleAnimation>().FirstOrDefault();
803+
if (null == animation)
804+
{
805+
return false;
806+
}
807+
808+
return (sb.Duration.HasTimeSpan && sb.Duration.TimeSpan.Ticks > 0)
809+
|| (sb.AccelerationRatio > 0)
810+
|| (sb.DecelerationRatio > 0)
811+
|| (animation.Duration.HasTimeSpan && animation.Duration.TimeSpan.Ticks > 0)
812+
|| animation.AccelerationRatio > 0
813+
|| animation.DecelerationRatio > 0;
814+
}
815+
765816
/// <summary>
766817
/// Begins to show the MetroWindow's overlay effect.
767818
/// </summary>
@@ -781,32 +832,39 @@ public System.Threading.Tasks.Task ShowOverlayAsync()
781832

782833
Dispatcher.VerifyAccess();
783834

784-
overlayBox.Visibility = Visibility.Visible;
785-
786-
var sb = ((Storyboard)this.Template.Resources["OverlayFastSemiFadeIn"]).Clone();
787-
((DoubleAnimation)sb.Children[0]).To = this.OverlayOpacity;
788-
789-
EventHandler completionHandler = null;
790-
completionHandler = (sender, args) =>
835+
var sb = OverlayFadeIn?.Clone();
836+
overlayStoryboard = sb;
837+
DoubleAnimation animation;
838+
if (CanUseOverlayFadingStoryboard(sb, out animation))
791839
{
792-
sb.Completed -= completionHandler;
840+
this.overlayBox.SetCurrentValue(VisibilityProperty, Visibility.Visible);
793841

794-
if (overlayStoryboard == sb)
795-
{
796-
overlayStoryboard = null;
797-
}
842+
animation.To = this.OverlayOpacity;
798843

799-
tcs.TrySetResult(null);
800-
};
801-
802-
sb.Completed += completionHandler;
844+
EventHandler completionHandler = null;
845+
completionHandler = (sender, args) =>
846+
{
847+
sb.Completed -= completionHandler;
848+
if (overlayStoryboard == sb)
849+
{
850+
overlayStoryboard = null;
851+
}
803852

804-
overlayBox.BeginStoryboard(sb);
853+
tcs.TrySetResult(null);
854+
};
805855

806-
overlayStoryboard = sb;
856+
sb.Completed += completionHandler;
857+
overlayBox.BeginStoryboard(sb);
858+
}
859+
else
860+
{
861+
ShowOverlay();
862+
tcs.TrySetResult(null);
863+
}
807864

808865
return tcs.Task;
809866
}
867+
810868
/// <summary>
811869
/// Begins to hide the MetroWindow's overlay effect.
812870
/// </summary>
@@ -817,55 +875,65 @@ public System.Threading.Tasks.Task HideOverlayAsync()
817875

818876
var tcs = new System.Threading.Tasks.TaskCompletionSource<object>();
819877

820-
if (overlayBox.Visibility == Visibility.Visible && overlayBox.Opacity == 0.0)
878+
if (overlayBox.Visibility == Visibility.Visible && overlayBox.Opacity <= 0.0)
821879
{
822880
//No Task.FromResult in .NET 4.
881+
this.overlayBox.SetCurrentValue(VisibilityProperty, Visibility.Hidden);
823882
tcs.SetResult(null);
824883
return tcs.Task;
825884
}
826885

827886
Dispatcher.VerifyAccess();
828887

829-
var sb = ((Storyboard)this.Template.Resources["OverlayFastSemiFadeOut"]).Clone();
830-
((DoubleAnimation)sb.Children[0]).To = 0d;
831-
832-
EventHandler completionHandler = null;
833-
completionHandler = (sender, args) =>
888+
var sb = OverlayFadeOut?.Clone();
889+
overlayStoryboard = sb;
890+
DoubleAnimation animation;
891+
if (CanUseOverlayFadingStoryboard(sb, out animation))
834892
{
835-
sb.Completed -= completionHandler;
836-
837-
if (overlayStoryboard == sb)
838-
{
839-
overlayBox.Visibility = Visibility.Hidden;
840-
overlayStoryboard = null;
841-
}
893+
animation.To = 0d;
842894

843-
tcs.TrySetResult(null);
844-
};
845-
846-
sb.Completed += completionHandler;
895+
EventHandler completionHandler = null;
896+
completionHandler = (sender, args) =>
897+
{
898+
sb.Completed -= completionHandler;
899+
if (overlayStoryboard == sb)
900+
{
901+
this.overlayBox.SetCurrentValue(VisibilityProperty, Visibility.Hidden);
902+
overlayStoryboard = null;
903+
}
847904

848-
overlayBox.BeginStoryboard(sb);
905+
tcs.TrySetResult(null);
906+
};
849907

850-
overlayStoryboard = sb;
908+
sb.Completed += completionHandler;
909+
overlayBox.BeginStoryboard(sb);
910+
}
911+
else
912+
{
913+
HideOverlay();
914+
tcs.TrySetResult(null);
915+
}
851916

852917
return tcs.Task;
853918
}
919+
854920
public bool IsOverlayVisible()
855921
{
856922
if (overlayBox == null) throw new InvalidOperationException("OverlayBox can not be founded in this MetroWindow's template. Are you calling this before the window has loaded?");
857923

858924
return overlayBox.Visibility == Visibility.Visible && overlayBox.Opacity >= this.OverlayOpacity;
859925
}
926+
860927
public void ShowOverlay()
861928
{
862-
overlayBox.Visibility = Visibility.Visible;
929+
this.overlayBox.SetCurrentValue(VisibilityProperty, Visibility.Visible);
863930
overlayBox.SetCurrentValue(Grid.OpacityProperty, this.OverlayOpacity);
864931
}
932+
865933
public void HideOverlay()
866934
{
867-
overlayBox.SetCurrentValue(Grid.OpacityProperty, 0.0);
868-
overlayBox.Visibility = System.Windows.Visibility.Hidden;
935+
overlayBox.SetCurrentValue(Grid.OpacityProperty, 0d);
936+
this.overlayBox.SetCurrentValue(VisibilityProperty, Visibility.Hidden);
869937
}
870938

871939
/// <summary>

src/MahApps.Metro/MahApps.Metro/Themes/MetroWindow.xaml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -211,23 +211,6 @@
211211
Visibility="Collapsed" />
212212
</Grid>
213213

214-
<ControlTemplate.Resources>
215-
<Storyboard x:Key="OverlayFastSemiFadeIn"
216-
AccelerationRatio=".97"
217-
BeginTime="0:0:0"
218-
SpeedRatio="2.7"
219-
Storyboard.TargetProperty="Opacity">
220-
<DoubleAnimation To=".7" />
221-
</Storyboard>
222-
<Storyboard x:Key="OverlayFastSemiFadeOut"
223-
AccelerationRatio=".97"
224-
BeginTime="0:0:0"
225-
SpeedRatio="2.7"
226-
Storyboard.TargetProperty="Opacity">
227-
<DoubleAnimation To="0.0" />
228-
</Storyboard>
229-
</ControlTemplate.Resources>
230-
231214
<ControlTemplate.Triggers>
232215
<Trigger Property="ShowDialogsOverTitleBar" Value="False">
233216
<Setter TargetName="PART_MetroActiveDialogContainer" Property="Grid.Row" Value="1" />
@@ -553,6 +536,21 @@
553536

554537
</ControlTemplate>
555538

539+
<Storyboard x:Key="OverlayFastSemiFadeIn"
540+
AccelerationRatio=".97"
541+
BeginTime="0:0:0"
542+
SpeedRatio="2.7"
543+
Storyboard.TargetProperty="Opacity">
544+
<DoubleAnimation To=".7" />
545+
</Storyboard>
546+
<Storyboard x:Key="OverlayFastSemiFadeOut"
547+
AccelerationRatio=".97"
548+
BeginTime="0:0:0"
549+
SpeedRatio="2.7"
550+
Storyboard.TargetProperty="Opacity">
551+
<DoubleAnimation To="0.0" />
552+
</Storyboard>
553+
556554
<Style TargetType="{x:Type Controls:MetroWindow}">
557555
<Setter Property="Background" Value="{DynamicResource WhiteBrush}" />
558556
<Setter Property="BorderBrush" Value="Transparent" />
@@ -561,6 +559,8 @@
561559
<Setter Property="NonActiveBorderBrush" Value="{DynamicResource NonActiveBorderColorBrush}" />
562560
<Setter Property="NonActiveWindowTitleBrush" Value="{DynamicResource NonActiveWindowTitleColorBrush}" />
563561
<Setter Property="OverlayBrush" Value="{DynamicResource BlackColorBrush}" />
562+
<Setter Property="OverlayFadeIn" Value="{StaticResource OverlayFastSemiFadeIn}" />
563+
<Setter Property="OverlayFadeOut" Value="{StaticResource OverlayFastSemiFadeOut}" />
564564
<Setter Property="Template" Value="{StaticResource WindowTemplateKey}" />
565565
<Setter Property="TextElement.FontSize" Value="{DynamicResource ContentFontSize}" />
566566
<Setter Property="TitleForeground" Value="{DynamicResource IdealForegroundColorBrush}" />

0 commit comments

Comments
 (0)