enhance: add TransitionMode prop for GrowlWindow.
This commit is contained in:
1 parent
83fc434e7d
commit
faf2ba4412
8 files changed
+164
-55
No files matched your search
@@ -12694,6 +12694,14 @@
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="hc:Growl.TransitionMode" Value="Bottom2Top">
|
||||
<Setter Property="Margin" Value="10,0,10,10" />
|
||||
</Trigger>
|
||||
<Trigger Property="hc:Growl.TransitionMode" Value="Bottom2TopWithFade">
|
||||
<Setter Property="Margin" Value="10,0,10,10" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style BasedOn="{StaticResource ImageSelectorBaseStyle}" TargetType="hc:ImageSelector" />
|
||||
<Style TargetType="hc:ImageViewer">
|
||||
|
||||
@@ -291,7 +291,7 @@ public class Growl : Control
|
||||
{
|
||||
foreach (var item in panel.Children.OfType<Growl>())
|
||||
{
|
||||
item.Close(false);
|
||||
item.Close(invokeParam: false, isClear: true);
|
||||
}
|
||||
};
|
||||
panel.ContextMenu = new ContextMenu
|
||||
@@ -354,9 +354,9 @@ public class Growl : Control
|
||||
GrowlWindow = new GrowlWindow();
|
||||
GrowlWindow.Show();
|
||||
InitGrowlPanel(GrowlWindow.GrowlPanel);
|
||||
GrowlWindow.Init();
|
||||
}
|
||||
|
||||
GrowlWindow.UpdatePosition(Growl.GetTransitionMode(Application.Current.MainWindow));
|
||||
GrowlWindow.Show(true);
|
||||
|
||||
var ctl = new Growl
|
||||
@@ -408,7 +408,7 @@ public class Growl : Control
|
||||
ConfirmStr = growlInfo.ConfirmStr,
|
||||
CancelStr = growlInfo.CancelStr,
|
||||
Type = growlInfo.Type,
|
||||
_waitTime = Math.Max(growlInfo.WaitTime, MinWaitTime)
|
||||
_waitTime = Math.Max(growlInfo.WaitTime, MinWaitTime),
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(growlInfo.Token))
|
||||
@@ -424,9 +424,11 @@ public class Growl : Control
|
||||
GrowlPanel ??= CreateDefaultPanel();
|
||||
ShowInternal(GrowlPanel, ctl);
|
||||
|
||||
var transitionMode = GetTransitionMode(ctl);
|
||||
var transitionMode = GetTransitionMode(GrowlPanel);
|
||||
GrowlPanel.VerticalAlignment = GetPanelVerticalAlignment(transitionMode);
|
||||
GrowlPanel.HorizontalAlignment = GetPanelHorizontalAlignment(transitionMode);
|
||||
GrowlPanel.SetValue(InverseStackPanel.IsInverseEnabledProperty,
|
||||
transitionMode is TransitionMode.Bottom2Top or TransitionMode.Bottom2TopWithFade);
|
||||
}
|
||||
}
|
||||
#if NET40
|
||||
@@ -446,7 +448,7 @@ public class Growl : Control
|
||||
return null;
|
||||
}
|
||||
|
||||
var panel = new SimpleStackPanel();
|
||||
var panel = new InverseStackPanel();
|
||||
|
||||
InitGrowlPanel(panel);
|
||||
SetIsCreatedAutomatically(panel, true);
|
||||
@@ -830,14 +832,15 @@ public class Growl : Control
|
||||
/// <summary>
|
||||
/// 关闭
|
||||
/// </summary>
|
||||
private void Close(bool invokeParam)
|
||||
private void Close(bool invokeParam, bool isClear = false)
|
||||
{
|
||||
if (ActionBeforeClose?.Invoke(invokeParam) == false)
|
||||
if (!isClear && ActionBeforeClose?.Invoke(invokeParam) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_timerClose?.Stop();
|
||||
Panel.SetZIndex(this, int.MinValue);
|
||||
StartTransition(true, OnStoryboardCompleted);
|
||||
return;
|
||||
|
||||
@@ -942,16 +945,19 @@ public class Growl : Control
|
||||
{
|
||||
var transformLength = GetTransformLength(isClose, transitionMode);
|
||||
var transformAnimation = CreateTransformAnimation(isClose, transitionMode, transformLength);
|
||||
_gridMain.RenderTransform = CreateRenderTransform(isClose, transitionMode, transformLength);
|
||||
|
||||
var storyboard = new Storyboard
|
||||
{
|
||||
Duration = transformAnimation.Duration
|
||||
};
|
||||
Storyboard.SetTarget(transformAnimation, _gridMain);
|
||||
storyboard.Children.Add(transformAnimation);
|
||||
|
||||
if (CreateFadeAnimation(transitionMode) is not { } fadeAnimation)
|
||||
if (transitionMode is not TransitionMode.Fade)
|
||||
{
|
||||
_gridMain.RenderTransform = CreateRenderTransform(isClose, transitionMode, transformLength);
|
||||
Storyboard.SetTarget(transformAnimation, _gridMain);
|
||||
storyboard.Children.Add(transformAnimation);
|
||||
}
|
||||
|
||||
if (CreateFadeAnimation(isClose, transitionMode) is not { } fadeAnimation)
|
||||
{
|
||||
return storyboard;
|
||||
}
|
||||
@@ -970,7 +976,7 @@ public class Growl : Control
|
||||
TransitionMode.Left2Right or TransitionMode.Left2RightWithFade => -ActualWidth,
|
||||
TransitionMode.Bottom2Top or TransitionMode.Bottom2TopWithFade => ActualHeight,
|
||||
TransitionMode.Top2Bottom or TransitionMode.Top2BottomWithFade => -ActualHeight,
|
||||
_ => 0
|
||||
_ => ActualWidth
|
||||
};
|
||||
|
||||
|
||||
@@ -1007,6 +1013,9 @@ public class Growl : Control
|
||||
case Orientation.Vertical:
|
||||
((TranslateTransform) transformGroup.Children[TranslateTransformIndex]).Y = transformLength;
|
||||
break;
|
||||
default:
|
||||
((TranslateTransform) transformGroup.Children[TranslateTransformIndex]).X = transformLength;
|
||||
break;
|
||||
}
|
||||
|
||||
return transformGroup;
|
||||
@@ -1029,23 +1038,29 @@ public class Growl : Control
|
||||
new PropertyPath(
|
||||
$"(UIElement.RenderTransform).(TransformGroup.Children)[{TranslateTransformIndex}].(TranslateTransform.Y)"));
|
||||
break;
|
||||
default:
|
||||
Storyboard.SetTargetProperty(animation,
|
||||
new PropertyPath(
|
||||
$"(UIElement.RenderTransform).(TransformGroup.Children)[{TranslateTransformIndex}].(TranslateTransform.X)"));
|
||||
break;
|
||||
}
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
||||
private static DoubleAnimation CreateFadeAnimation(TransitionMode transitionMode)
|
||||
private static DoubleAnimation CreateFadeAnimation(bool isClose, TransitionMode transitionMode)
|
||||
{
|
||||
if (transitionMode is TransitionMode.Right2Left or
|
||||
TransitionMode.Left2Right or
|
||||
TransitionMode.Bottom2Top or
|
||||
TransitionMode.Top2Bottom)
|
||||
TransitionMode.Top2Bottom or
|
||||
TransitionMode.Custom)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var animation = AnimationHelper.CreateAnimation(1);
|
||||
animation.From = 0;
|
||||
var animation = AnimationHelper.CreateAnimation(isClose ? 0 : 1);
|
||||
animation.From = isClose ? 1 : 0;
|
||||
Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.Opacity)"));
|
||||
|
||||
return animation;
|
||||
@@ -1059,23 +1074,16 @@ public class Growl : Control
|
||||
or TransitionMode.Left2RightWithFade => Orientation.Horizontal,
|
||||
TransitionMode.Bottom2Top or TransitionMode.Bottom2TopWithFade or TransitionMode.Top2Bottom
|
||||
or TransitionMode.Top2BottomWithFade => Orientation.Vertical,
|
||||
_ => null
|
||||
_ => Orientation.Horizontal
|
||||
};
|
||||
}
|
||||
|
||||
private static VerticalAlignment GetPanelVerticalAlignment(TransitionMode transitionMode)
|
||||
internal static VerticalAlignment GetPanelVerticalAlignment(TransitionMode transitionMode)
|
||||
{
|
||||
return transitionMode switch
|
||||
{
|
||||
TransitionMode.Right2Left or TransitionMode.Right2LeftWithFade or TransitionMode.Left2Right
|
||||
or TransitionMode.Left2RightWithFade => VerticalAlignment.Top,
|
||||
TransitionMode.Bottom2Top or TransitionMode.Bottom2TopWithFade => VerticalAlignment.Bottom,
|
||||
TransitionMode.Top2Bottom or TransitionMode.Top2BottomWithFade => VerticalAlignment.Top,
|
||||
_ => VerticalAlignment.Stretch
|
||||
};
|
||||
return VerticalAlignment.Stretch;
|
||||
}
|
||||
|
||||
private static HorizontalAlignment GetPanelHorizontalAlignment(TransitionMode transitionMode)
|
||||
internal static HorizontalAlignment GetPanelHorizontalAlignment(TransitionMode transitionMode)
|
||||
{
|
||||
return transitionMode switch
|
||||
{
|
||||
@@ -1083,7 +1091,7 @@ public class Growl : Control
|
||||
TransitionMode.Left2Right or TransitionMode.Left2RightWithFade => HorizontalAlignment.Left,
|
||||
TransitionMode.Bottom2Top or TransitionMode.Bottom2TopWithFade or TransitionMode.Top2Bottom
|
||||
or TransitionMode.Top2BottomWithFade => HorizontalAlignment.Center,
|
||||
_ => HorizontalAlignment.Stretch
|
||||
_ => HorizontalAlignment.Right
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Tools;
|
||||
using HandyControl.Tools.Interop;
|
||||
|
||||
@@ -15,11 +16,8 @@ public sealed class GrowlWindow : Window
|
||||
WindowStyle = WindowStyle.None;
|
||||
AllowsTransparency = true;
|
||||
|
||||
GrowlPanel = new StackPanel
|
||||
{
|
||||
VerticalAlignment = VerticalAlignment.Top
|
||||
};
|
||||
|
||||
Growl.SetTransitionStoryboard(this, Growl.GetTransitionStoryboard(Application.Current.MainWindow));
|
||||
GrowlPanel = new InverseStackPanel();
|
||||
Content = new ScrollViewer
|
||||
{
|
||||
VerticalScrollBarVisibility = ScrollBarVisibility.Hidden,
|
||||
@@ -28,12 +26,24 @@ public sealed class GrowlWindow : Window
|
||||
};
|
||||
}
|
||||
|
||||
internal void Init()
|
||||
internal void UpdatePosition(TransitionMode transitionMode)
|
||||
{
|
||||
var desktopWorkingArea = SystemParameters.WorkArea;
|
||||
Height = desktopWorkingArea.Height;
|
||||
Left = desktopWorkingArea.Right - Width;
|
||||
Top = 0;
|
||||
|
||||
var panelHorizontalAlignment = Growl.GetPanelHorizontalAlignment(transitionMode);
|
||||
Left = panelHorizontalAlignment switch
|
||||
{
|
||||
HorizontalAlignment.Right => desktopWorkingArea.Right - Width,
|
||||
HorizontalAlignment.Left => desktopWorkingArea.Left,
|
||||
HorizontalAlignment.Center => desktopWorkingArea.Left + (desktopWorkingArea.Width - Width) * 0.5,
|
||||
_ => desktopWorkingArea.Right - Width
|
||||
};
|
||||
|
||||
Growl.SetTransitionMode(this, transitionMode);
|
||||
GrowlPanel.SetValue(InverseStackPanel.IsInverseEnabledProperty,
|
||||
transitionMode is TransitionMode.Bottom2Top or TransitionMode.Bottom2TopWithFade);
|
||||
}
|
||||
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using HandyControl.Data;
|
||||
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
public class InverseStackPanel : SimpleStackPanel
|
||||
{
|
||||
public static readonly DependencyProperty IsInverseEnabledProperty = DependencyProperty.Register(
|
||||
nameof(IsInversed), typeof(bool), typeof(InverseStackPanel),
|
||||
new FrameworkPropertyMetadata(ValueBoxes.TrueBox, FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
public bool IsInversed
|
||||
{
|
||||
get => (bool) GetValue(IsInverseEnabledProperty);
|
||||
set => SetValue(IsInverseEnabledProperty, ValueBoxes.BooleanBox(value));
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size arrangeSize)
|
||||
{
|
||||
if (!IsInversed)
|
||||
{
|
||||
return base.ArrangeOverride(arrangeSize);
|
||||
}
|
||||
|
||||
var rcChild = new Rect(arrangeSize);
|
||||
double previousChildSize;
|
||||
|
||||
if (Orientation == System.Windows.Controls.Orientation.Horizontal)
|
||||
{
|
||||
rcChild.X = arrangeSize.Width;
|
||||
|
||||
foreach (var child in GetVisibleChildren())
|
||||
{
|
||||
previousChildSize = child.DesiredSize.Width;
|
||||
rcChild.X -= previousChildSize;
|
||||
rcChild.Width = previousChildSize;
|
||||
rcChild.Height = Math.Max(arrangeSize.Height, child.DesiredSize.Height);
|
||||
|
||||
child.Arrange(rcChild);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rcChild.Y = arrangeSize.Height;
|
||||
|
||||
foreach (var child in GetVisibleChildren())
|
||||
{
|
||||
previousChildSize = child.DesiredSize.Height;
|
||||
rcChild.Y -= previousChildSize;
|
||||
rcChild.Height = previousChildSize;
|
||||
rcChild.Width = Math.Max(arrangeSize.Width, child.DesiredSize.Width);
|
||||
|
||||
child.Arrange(rcChild);
|
||||
}
|
||||
}
|
||||
|
||||
return arrangeSize;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
@@ -19,18 +20,14 @@ public class SimpleStackPanel : Panel
|
||||
protected override Size MeasureOverride(Size constraint)
|
||||
{
|
||||
var stackDesiredSize = new Size();
|
||||
var children = InternalChildren;
|
||||
var layoutSlotSize = constraint;
|
||||
|
||||
if (Orientation == Orientation.Horizontal)
|
||||
{
|
||||
layoutSlotSize.Width = double.PositiveInfinity;
|
||||
|
||||
for (int i = 0, count = children.Count; i < count; ++i)
|
||||
foreach (var child in GetVisibleChildren())
|
||||
{
|
||||
var child = children[i];
|
||||
if (child == null) continue;
|
||||
|
||||
child.Measure(layoutSlotSize);
|
||||
var childDesiredSize = child.DesiredSize;
|
||||
|
||||
@@ -42,11 +39,8 @@ public class SimpleStackPanel : Panel
|
||||
{
|
||||
layoutSlotSize.Height = double.PositiveInfinity;
|
||||
|
||||
for (int i = 0, count = children.Count; i < count; ++i)
|
||||
foreach (var child in GetVisibleChildren())
|
||||
{
|
||||
var child = children[i];
|
||||
if (child == null) continue;
|
||||
|
||||
child.Measure(layoutSlotSize);
|
||||
var childDesiredSize = child.DesiredSize;
|
||||
|
||||
@@ -60,17 +54,13 @@ public class SimpleStackPanel : Panel
|
||||
|
||||
protected override Size ArrangeOverride(Size arrangeSize)
|
||||
{
|
||||
var children = InternalChildren;
|
||||
var rcChild = new Rect(arrangeSize);
|
||||
var previousChildSize = 0.0;
|
||||
|
||||
if (Orientation == Orientation.Horizontal)
|
||||
{
|
||||
for (int i = 0, count = children.Count; i < count; ++i)
|
||||
foreach (var child in GetVisibleChildren())
|
||||
{
|
||||
var child = children[i];
|
||||
if (child == null) continue;
|
||||
|
||||
rcChild.X += previousChildSize;
|
||||
previousChildSize = child.DesiredSize.Width;
|
||||
rcChild.Width = previousChildSize;
|
||||
@@ -81,11 +71,8 @@ public class SimpleStackPanel : Panel
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0, count = children.Count; i < count; ++i)
|
||||
foreach (var child in GetVisibleChildren())
|
||||
{
|
||||
var child = children[i];
|
||||
if (child == null) continue;
|
||||
|
||||
rcChild.Y += previousChildSize;
|
||||
previousChildSize = child.DesiredSize.Height;
|
||||
rcChild.Height = previousChildSize;
|
||||
@@ -97,4 +84,23 @@ public class SimpleStackPanel : Panel
|
||||
|
||||
return arrangeSize;
|
||||
}
|
||||
|
||||
public virtual IEnumerable<UIElement> GetVisibleChildren()
|
||||
{
|
||||
var children = InternalChildren;
|
||||
|
||||
for (int i = 0, count = children.Count; i < count; ++i)
|
||||
{
|
||||
var child = children[i];
|
||||
if (child == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.Visibility != Visibility.Collapsed)
|
||||
{
|
||||
yield return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\ClipGrid.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\FlexPanel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\ElementGroup.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\InverseStackPanel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\SimpleStackPanel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\UniformSpacingPanel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\ImagePropertyEditor.cs" />
|
||||
|
||||
@@ -60,6 +60,14 @@
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="hc:Growl.TransitionMode" Value="Bottom2Top">
|
||||
<Setter Property="Margin" Value="10,0,10,10"/>
|
||||
</Trigger>
|
||||
<Trigger Property="hc:Growl.TransitionMode" Value="Bottom2TopWithFade">
|
||||
<Setter Property="Margin" Value="10,0,10,10"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -12839,6 +12839,14 @@
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="hc:Growl.TransitionMode" Value="Bottom2Top">
|
||||
<Setter Property="Margin" Value="10,0,10,10" />
|
||||
</Trigger>
|
||||
<Trigger Property="hc:Growl.TransitionMode" Value="Bottom2TopWithFade">
|
||||
<Setter Property="Margin" Value="10,0,10,10" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style BasedOn="{StaticResource ImageSelectorBaseStyle}" TargetType="hc:ImageSelector" />
|
||||
<Style TargetType="hc:ImageViewer">
|
||||
|
||||
Reference in new issue
Block a user