Skip to content

Commit efa15e0

Browse files
authored
Add IsAnimatingDirectionaArrows and DirectionalArrowsAnimationDuration dependency properties to BaseConnection (#135)
1 parent 1425d40 commit efa15e0

File tree

9 files changed

+7867
-7777
lines changed

9 files changed

+7867
-7777
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@
44

55
> - Breaking Changes:
66
> - Features:
7-
> - Added OutlineBrush and OutlineThickness dependency properties to BaseConnection to support increasing the selection area without increasing the stroke thickness
87
> - Bugfixes:
98
9+
#### **Version 6.4.0**
10+
11+
> - Features:
12+
> - Added OutlineBrush and OutlineThickness dependency properties to BaseConnection to support increasing the selection area without increasing the stroke thickness
13+
> - Added IsAnimatingDirectionalArrows and DirectionalArrowsAnimationDuration dependency properties to BaseConnection to support controlling the animation from XAML
14+
1015
#### **Version 6.3.0**
1116

1217
> - Features:

Examples/Nodify.Playground/Editor/NodifyEditorView.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@
132132
<Setter Property="TargetOrientation" Value="{Binding Input.Node.Orientation}" />
133133
<Setter Property="DirectionalArrowsCount" Value="{Binding DirectionalArrowsCount, Source={x:Static local:EditorSettings.Instance}}" />
134134
<Setter Property="DirectionalArrowsOffset" Value="{Binding DirectionalArrowsOffset, Source={x:Static local:EditorSettings.Instance}}" />
135+
<Setter Property="IsAnimatingDirectionalArrows" Value="{Binding IsAnimatingConnections, Source={x:Static local:EditorSettings.Instance}}" />
136+
<Setter Property="DirectionalArrowsAnimationDuration" Value="{Binding DirectionalArrowsAnimationDuration, Source={x:Static local:EditorSettings.Instance}}" />
135137
<Setter Property="Text" Value="{Binding ConnectionText, Source={x:Static local:EditorSettings.Instance}}" />
136138
</Style>
137139

Examples/Nodify.Playground/EditorSettings.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ private EditorSettings()
119119
val => Instance.DirectionalArrowsOffset = val,
120120
"Directional arrows offset: ",
121121
"Used to animate the directional arrowheads flowing in the direction of the connection (value is between 0 and 1)."),
122+
new ProxySettingViewModel<bool>(
123+
() => Instance.IsAnimatingConnections,
124+
val => Instance.IsAnimatingConnections = val,
125+
"Animate directional arrows: ",
126+
"Used to animate the directional arrowheads by animating the DirectionalArrowsOffset value"),
127+
new ProxySettingViewModel<double>(
128+
() => Instance.DirectionalArrowsAnimationDuration,
129+
val => Instance.DirectionalArrowsAnimationDuration = val,
130+
"Arrows animation duration: ",
131+
"The duration in seconds of a directional arrowhead flowing from start to end."),
122132
new ProxySettingViewModel<ArrowHeadEnds>(
123133
() => Instance.ArrowHeadEnds,
124134
val => Instance.ArrowHeadEnds = val,
@@ -439,6 +449,20 @@ public double DirectionalArrowsOffset
439449
set => SetProperty(ref _directionalArrowsOffset, value);
440450
}
441451

452+
private bool _isAnimatingConnections;
453+
public bool IsAnimatingConnections
454+
{
455+
get => _isAnimatingConnections;
456+
set => SetProperty(ref _isAnimatingConnections, value);
457+
}
458+
459+
private double _directionalArrowsAnimationDuration = 2.0;
460+
public double DirectionalArrowsAnimationDuration
461+
{
462+
get => _directionalArrowsAnimationDuration;
463+
set => SetProperty(ref _directionalArrowsAnimationDuration, value);
464+
}
465+
442466
private PointEditor _connectionArrowSize = new Size(8, 8);
443467
public PointEditor ConnectionArrowSize
444468
{

Examples/Nodify.Playground/MainWindow.xaml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@
1414
<Window.Resources>
1515
<shared:DebugConverter x:Key="DebugConverter" />
1616
<shared:ToStringConverter x:Key="ToStringConverter" />
17-
18-
<Storyboard RepeatBehavior="Forever"
19-
x:Key="{x:Static local:MainWindow.AnimateDirectionalArrowsStoryboardKey}">
20-
<DoubleAnimation Duration="0:0:2"
21-
From="0"
22-
To="1"
23-
Storyboard.Target="{Binding .,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"
24-
Storyboard.TargetProperty="DirectionalArrowsOffset" />
25-
</Storyboard>
2617
</Window.Resources>
2718

2819
<Window.DataContext>

Examples/Nodify.Playground/MainWindow.xaml.cs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Windows;
33
using System.Windows.Media;
4-
using System.Windows.Media.Animation;
54

65
namespace Nodify.Playground
76
{
@@ -49,22 +48,6 @@ private static void OnRendering(object? sender, EventArgs e)
4948
public partial class MainWindow : Window
5049
{
5150
private readonly Random _rand = new Random();
52-
private bool _connectionAnimationsPlaying;
53-
54-
public static string AnimateDirectionalArrowsStoryboardKey = "AnimateDirectionalArrows";
55-
56-
public static DependencyProperty DirectionalArrowsOffsetProperty = BaseConnection.DirectionalArrowsOffsetProperty.AddOwner(typeof(MainWindow), new FrameworkPropertyMetadata(0d, DirectionalArrowsOffsetChanged));
57-
58-
private static void DirectionalArrowsOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
59-
{
60-
EditorSettings.Instance.DirectionalArrowsOffset = (double)e.NewValue;
61-
}
62-
63-
public double DirectionalArrowsOffset
64-
{
65-
get => (double)GetValue(DirectionalArrowsOffsetProperty);
66-
set => SetValue(DirectionalArrowsOffsetProperty, value);
67-
}
6851

6952
public MainWindow()
7053
{
@@ -95,18 +78,7 @@ private void BringIntoView_Click(object sender, RoutedEventArgs e)
9578

9679
private void AnimateConnections_Click(object sender, RoutedEventArgs e)
9780
{
98-
var storyboard = (Storyboard)FindResource(AnimateDirectionalArrowsStoryboardKey);
99-
100-
if (_connectionAnimationsPlaying)
101-
{
102-
storyboard.Stop();
103-
}
104-
else
105-
{
106-
storyboard.Begin();
107-
}
108-
109-
_connectionAnimationsPlaying = !_connectionAnimationsPlaying;
81+
EditorSettings.Instance.IsAnimatingConnections = !EditorSettings.Instance.IsAnimatingConnections;
11082
}
11183
}
11284
}

Nodify/Connections/BaseConnection.cs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ public abstract class BaseConnection : Shape
122122
public static readonly DependencyProperty DirectionProperty = DependencyProperty.Register(nameof(Direction), typeof(ConnectionDirection), typeof(BaseConnection), new FrameworkPropertyMetadata(default(ConnectionDirection), FrameworkPropertyMetadataOptions.AffectsRender));
123123
public static readonly DependencyProperty DirectionalArrowsCountProperty = DependencyProperty.Register(nameof(DirectionalArrowsCount), typeof(uint), typeof(BaseConnection), new FrameworkPropertyMetadata(BoxValue.UInt0, FrameworkPropertyMetadataOptions.AffectsRender));
124124
public static readonly DependencyProperty DirectionalArrowsOffsetProperty = DependencyProperty.Register(nameof(DirectionalArrowsOffset), typeof(double), typeof(BaseConnection), new FrameworkPropertyMetadata(BoxValue.Double0, FrameworkPropertyMetadataOptions.AffectsRender));
125+
public static readonly DependencyProperty IsAnimatingDirectionalArrowsProperty = DependencyProperty.Register(nameof(IsAnimatingDirectionalArrows), typeof(bool), typeof(BaseConnection), new FrameworkPropertyMetadata(BoxValue.False, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnIsAnimatingDirectionalArrowsChanged)));
126+
public static readonly DependencyProperty DirectionalArrowsAnimationDurationProperty = DependencyProperty.Register(nameof(DirectionalArrowsAnimationDuration), typeof(double), typeof(BaseConnection), new FrameworkPropertyMetadata(BoxValue.Double2, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnDirectionalArrowsAnimationDurationChanged)));
125127
public static readonly DependencyProperty SpacingProperty = DependencyProperty.Register(nameof(Spacing), typeof(double), typeof(BaseConnection), new FrameworkPropertyMetadata(BoxValue.Double0, FrameworkPropertyMetadataOptions.AffectsRender));
126128
public static readonly DependencyProperty ArrowSizeProperty = DependencyProperty.Register(nameof(ArrowSize), typeof(Size), typeof(BaseConnection), new FrameworkPropertyMetadata(BoxValue.ArrowSize, FrameworkPropertyMetadataOptions.AffectsRender));
127129
public static readonly DependencyProperty ArrowEndsProperty = DependencyProperty.Register(nameof(ArrowEnds), typeof(ArrowHeadEnds), typeof(BaseConnection), new FrameworkPropertyMetadata(ArrowHeadEnds.End, FrameworkPropertyMetadataOptions.AffectsRender));
@@ -138,6 +140,28 @@ public abstract class BaseConnection : Shape
138140
public static readonly DependencyProperty FontStyleProperty = TextElement.FontStyleProperty.AddOwner(typeof(BaseConnection));
139141
public static readonly DependencyProperty FontStretchProperty = TextElement.FontStretchProperty.AddOwner(typeof(BaseConnection));
140142

143+
private static void OnIsAnimatingDirectionalArrowsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
144+
{
145+
var con = (BaseConnection)d;
146+
if (e.NewValue is true)
147+
{
148+
con.StartAnimation(con.DirectionalArrowsAnimationDuration);
149+
}
150+
else
151+
{
152+
con.StopAnimation();
153+
}
154+
}
155+
156+
private static void OnDirectionalArrowsAnimationDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
157+
{
158+
var con = (BaseConnection)d;
159+
if (con.IsAnimatingDirectionalArrows)
160+
{
161+
con.StartAnimation((double)e.NewValue);
162+
}
163+
}
164+
141165
private static void OnOutlinePenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
142166
{
143167
((BaseConnection)d)._outlinePen = null;
@@ -242,6 +266,24 @@ public double DirectionalArrowsOffset
242266
set => SetValue(DirectionalArrowsOffsetProperty, value);
243267
}
244268

269+
/// <summary>
270+
/// Gets or sets whether the directional arrows should be flowing through the connection wire.
271+
/// </summary>
272+
public bool IsAnimatingDirectionalArrows
273+
{
274+
get => (bool)GetValue(IsAnimatingDirectionalArrowsProperty);
275+
set => SetValue(IsAnimatingDirectionalArrowsProperty, value);
276+
}
277+
278+
/// <summary>
279+
/// Gets or sets the duration in seconds of a directional arrow flowing from <see cref="Source"/> to <see cref="Target"/>.
280+
/// </summary>
281+
public double DirectionalArrowsAnimationDuration
282+
{
283+
get => (double)GetValue(DirectionalArrowsAnimationDurationProperty);
284+
set => SetValue(DirectionalArrowsAnimationDurationProperty, value);
285+
}
286+
245287
/// <summary>
246288
/// Gets or sets the arrowhead ends.
247289
/// </summary>
@@ -682,10 +724,8 @@ protected virtual Point GetTextPosition(FormattedText text, Point source, Point
682724
/// <param name="duration">The duration for moving an arrowhead from <see cref="Source"/> to <see cref="Target"/>.</param>
683725
public void StartAnimation(double duration = 1.5d)
684726
{
685-
if (DirectionalArrowsCount > 0)
686-
{
687-
this.StartLoopingAnimation(DirectionalArrowsOffsetProperty, DirectionalArrowsOffset + 1d, duration);
688-
}
727+
StopAnimation();
728+
this.StartLoopingAnimation(DirectionalArrowsOffsetProperty, DirectionalArrowsOffset + 1d, duration);
689729
}
690730

691731
/// <summary>Stops the animation started by <see cref="StartAnimation(double)"/></summary>

Nodify/Nodify.csproj

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@
1616
<PackageIcon>icon.png</PackageIcon>
1717
<RepositoryUrl>https://github.com/miroiu/nodify</RepositoryUrl>
1818
<PackageTags>wpf mvvm node-editor controls</PackageTags>
19-
<Version>6.3.0</Version>
19+
<Version>6.4.0</Version>
2020
<PackageReleaseNotes>
2121
> - Features:
22-
> - Added a CuttingLine control that removes intersecting connections
23-
> - Added CuttingLineStyle, CuttingStartedCommand, CuttingCompletedCommand, IsCutting, EnableCuttingLinePreview and CuttingConnectionTypes to NodifyEditor
24-
> - Added EditorGestures.Editor.Cutting and EditorGestures.Editor.CancelAction
25-
> - Bugfixes:
26-
> - Fixed connection styles not inheriting from the BaseConnection style
22+
> - Added OutlineBrush and OutlineThickness dependency properties to BaseConnection to support increasing the selection area without increasing the stroke thickness
23+
> - Added IsAnimatingDirectionalArrows and DirectionalArrowsAnimationDuration dependency properties to BaseConnection to support controlling the animation from XAML
2724
</PackageReleaseNotes>
2825
<AssemblyOriginatorKeyFile>..\build\Nodify.snk</AssemblyOriginatorKeyFile>
2926
<PackageReadmeFile>README.md</PackageReadmeFile>

Nodify/NodifyEditor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ internal void ClearPreviewingSelection()
13221322
/// Inverts the <see cref="ItemContainer"/>s selection in the specified <paramref name="area"/>.
13231323
/// </summary>
13241324
/// <param name="area">The area to look for <see cref="ItemContainer"/>s.</param>
1325-
/// <param name="fit">True to check if the <paramref name="area"/> contains the <see cref="ItemContainer"/>. <br /> False to check if <paramref name="area"/> intersects the <see cref="ItemContainer"/>.</param>
1325+
/// <param name="fit">True to check if the <paramref name="area"/> contains the <see cref="ItemContainer"/>. <br />False to check if <paramref name="area"/> intersects the <see cref="ItemContainer"/>.</param>
13261326
public void InvertSelection(Rect area, bool fit = false)
13271327
{
13281328
ItemCollection items = Items;
@@ -1356,7 +1356,7 @@ public void InvertSelection(Rect area, bool fit = false)
13561356
/// </summary>
13571357
/// <param name="area">The area to look for <see cref="ItemContainer"/>s.</param>
13581358
/// <param name="append">If true, it will add to the existing selection.</param>
1359-
/// <param name="fit">True to check if the <paramref name="area"/> contains the <see cref="ItemContainer"/>. <br /> False to check if <paramref name="area"/> intersects the <see cref="ItemContainer"/>.</param>
1359+
/// <param name="fit">True to check if the <paramref name="area"/> contains the <see cref="ItemContainer"/>. <br />False to check if <paramref name="area"/> intersects the <see cref="ItemContainer"/>.</param>
13601360
public void SelectArea(Rect area, bool append = false, bool fit = false)
13611361
{
13621362
if (!append)
@@ -1385,7 +1385,7 @@ public void SelectArea(Rect area, bool append = false, bool fit = false)
13851385
/// Unselect the <see cref="ItemContainer"/>s in the specified <paramref name="area"/>.
13861386
/// </summary>
13871387
/// <param name="area">The area to look for <see cref="ItemContainer"/>s.</param>
1388-
/// <param name="fit">True to check if the <paramref name="area"/> contains the <see cref="ItemContainer"/>. <br /> False to check if <paramref name="area"/> intersects the <see cref="ItemContainer"/>.</param>
1388+
/// <param name="fit">True to check if the <paramref name="area"/> contains the <see cref="ItemContainer"/>. <br />False to check if <paramref name="area"/> intersects the <see cref="ItemContainer"/>.</param>
13891389
public void UnselectArea(Rect area, bool fit = false)
13901390
{
13911391
IList items = base.SelectedItems;

0 commit comments

Comments
 (0)