Skip to content

Commit

Permalink
Add OutlineBrush and OutlineThickness to BaseConnection
Browse files Browse the repository at this point in the history
Fixes #131
  • Loading branch information
miroiu committed Aug 16, 2024
1 parent 55766f8 commit 55e2a30
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

> - Breaking Changes:
> - Features:
> - Added OutlineBrush and OutlineThickness dependency properties to BaseConnection to support increasing the selection area without increasing the stroke thickness
> - Bugfixes:
#### **Version 6.3.0**
Expand Down
65 changes: 48 additions & 17 deletions Examples/Nodify.Playground/Editor/NodifyEditorView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,45 +43,76 @@
Transform="{Binding ViewportTransform, ElementName=Editor}"
Drawing="{StaticResource LargeGridGeometry}" />

<SolidColorBrush x:Key="SquareConnectorColor" Color="MediumSlateBlue" />
<SolidColorBrush x:Key="TriangleConnectorColor" Color="MediumVioletRed" />

<UIElement x:Key="ConnectionAnimationPlaceholder" Opacity="1" />
<SolidColorBrush x:Key="SquareConnectorColor"
Color="MediumSlateBlue" />
<SolidColorBrush x:Key="TriangleConnectorColor"
Color="MediumVioletRed" />
<SolidColorBrush x:Key="SquareConnectorOutline"
Color="MediumSlateBlue"
Opacity="0.15" />
<SolidColorBrush x:Key="TriangleConnectorOutline"
Color="MediumVioletRed"
Opacity="0.15" />

<UIElement x:Key="ConnectionAnimationPlaceholder"
Opacity="1" />

<Storyboard x:Key="HighlightConnection">
<DoubleAnimation Storyboard.TargetProperty="StrokeThickness"
Duration="0:0:0.3" From="3" To="6" />
<DoubleAnimation Storyboard.Target="{StaticResource ConnectionAnimationPlaceholder}"
Storyboard.TargetProperty="(UIElement.Opacity)"
Duration="0:0:0.3" From="1" To="0.3" />
Storyboard.TargetProperty="(UIElement.Opacity)"
Duration="0:0:0.3"
From="1"
To="0.3" />
</Storyboard>

<Style x:Key="ConnectionStyle" TargetType="{x:Type nodify:BaseConnection}"
BasedOn="{StaticResource {x:Type nodify:BaseConnection}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Input.Shape}"
<DataTrigger Binding="{Binding Input.Shape}"
Value="{x:Static local:ConnectorShape.Square}">
<Setter Property="Stroke" Value="{StaticResource SquareConnectorColor}"/>
<Setter Property="Fill" Value="{StaticResource SquareConnectorColor}"/>
<Setter Property="Stroke"
Value="{StaticResource SquareConnectorColor}" />
<Setter Property="Fill"
Value="{StaticResource SquareConnectorColor}" />
<Setter Property="OutlineBrush"
Value="{StaticResource SquareConnectorOutline}" />
</DataTrigger>
<DataTrigger Binding="{Binding Input.Shape}"
<DataTrigger Binding="{Binding Input.Shape}"
Value="{x:Static local:ConnectorShape.Triangle}">
<Setter Property="Stroke" Value="{StaticResource TriangleConnectorColor}"/>
<Setter Property="Fill" Value="{StaticResource TriangleConnectorColor}"/>
<Setter Property="Stroke"
Value="{StaticResource TriangleConnectorColor}" />
<Setter Property="Fill"
Value="{StaticResource TriangleConnectorColor}" />
<Setter Property="OutlineBrush"
Value="{StaticResource TriangleConnectorOutline}" />
</DataTrigger>
<Trigger Property="IsMouseDirectlyOver" Value="True">
<Trigger Property="IsMouseDirectlyOver"
Value="True">
<Trigger.EnterActions>
<BeginStoryboard Name="HighlightConnection" Storyboard="{StaticResource HighlightConnection}" />
<BeginStoryboard Name="HighlightConnection"
Storyboard="{StaticResource HighlightConnection}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="HighlightConnection" />
</Trigger.ExitActions>
<Setter Property="Opacity" Value="1" />
<Setter Property="Opacity"
Value="1" />
</Trigger>
<Trigger Property="IsMouseDirectlyOver"
Value="False">
<Setter Property="OutlineBrush"
Value="Transparent" />
</Trigger>
</Style.Triggers>
<Setter Property="Opacity" Value="{Binding Source={StaticResource ConnectionAnimationPlaceholder}, Path=Opacity}" />
<Setter Property="Stroke" Value="{DynamicResource Connection.StrokeBrush}"/>
<Setter Property="Fill" Value="{DynamicResource Connection.StrokeBrush}"/>
<Setter Property="OutlineBrush">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource Connection.StrokeColor}"
Opacity="0.15" />
</Setter.Value>
</Setter>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="ToolTip" Value="Double click to split"/>
<Setter Property="Source" Value="{Binding Output.Anchor}" />
Expand Down
18 changes: 17 additions & 1 deletion Examples/Nodify.Shapes/Canvas/CanvasView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,21 @@
<SolidColorBrush Color="White"
Opacity="0.7" />
</nodify:StepConnection.Stroke>
<nodify:StepConnection.Style>
<Style TargetType="{x:Type nodify:StepConnection}">
<Setter Property="OutlineBrush"
Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="OutlineBrush">
<Setter.Value>
<SolidColorBrush Color="White" Opacity="0.15" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</nodify:StepConnection.Style>
</nodify:StepConnection>
</DataTemplate>
</nodify:NodifyEditor.ConnectionTemplate>
Expand Down Expand Up @@ -358,7 +373,8 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type shared:Resizer}">
<Grid Margin="-3 -6 -6 -3" Background="Transparent">
<Grid Margin="-3 -6 -6 -3"
Background="Transparent">
<Rectangle Height="12"
Width="3"
Fill="#d2d4d7"
Expand Down
37 changes: 37 additions & 0 deletions Nodify/Connections/BaseConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ public abstract class BaseConnection : Shape
public static readonly DependencyProperty ArrowShapeProperty = DependencyProperty.Register(nameof(ArrowShape), typeof(ArrowHeadShape), typeof(BaseConnection), new FrameworkPropertyMetadata(ArrowHeadShape.Arrowhead, FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty SplitCommandProperty = DependencyProperty.Register(nameof(SplitCommand), typeof(ICommand), typeof(BaseConnection));
public static readonly DependencyProperty DisconnectCommandProperty = Connector.DisconnectCommandProperty.AddOwner(typeof(BaseConnection));
public static readonly DependencyProperty OutlineThicknessProperty = DependencyProperty.Register(nameof(OutlineThickness), typeof(double), typeof(BaseConnection), new FrameworkPropertyMetadata(BoxValue.Double5, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlinePenChanged)));
public static readonly DependencyProperty OutlineBrushProperty = DependencyProperty.Register(nameof(OutlineBrush), typeof(Brush), typeof(BaseConnection), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnOutlinePenChanged)));
public static readonly DependencyProperty ForegroundProperty = TextBlock.ForegroundProperty.AddOwner(typeof(BaseConnection));
public static readonly DependencyProperty TextProperty = TextBlock.TextProperty.AddOwner(typeof(BaseConnection), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty FontSizeProperty = TextElement.FontSizeProperty.AddOwner(typeof(BaseConnection));
Expand All @@ -136,6 +138,11 @@ public abstract class BaseConnection : Shape
public static readonly DependencyProperty FontStyleProperty = TextElement.FontStyleProperty.AddOwner(typeof(BaseConnection));
public static readonly DependencyProperty FontStretchProperty = TextElement.FontStretchProperty.AddOwner(typeof(BaseConnection));

private static void OnOutlinePenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((BaseConnection)d)._outlinePen = null;
}

/// <summary>
/// Gets or sets the start point of this connection.
/// </summary>
Expand Down Expand Up @@ -291,6 +298,24 @@ public ICommand? DisconnectCommand
set => SetValue(DisconnectCommandProperty, value);
}

/// <summary>
/// The thickness of the outline.
/// </summary>
public double OutlineThickness
{
get => (double)GetValue(OutlineThicknessProperty);
set => SetValue(OutlineThicknessProperty, value);
}

/// <summary>
/// The brush used to render the outline.
/// </summary>
public Brush? OutlineBrush
{
get => (Brush?)GetValue(OutlineBrushProperty);
set => SetValue(OutlineBrushProperty, value);
}

/// <summary>
/// The brush used to render the <see cref="Text"/>.
/// </summary>
Expand Down Expand Up @@ -373,6 +398,8 @@ public event ConnectionEventHandler Split
/// </summary>
protected static readonly Vector ZeroVector = new Vector(0d, 0d);

private Pen? _outlinePen;

private readonly StreamGeometry _geometry = new StreamGeometry
{
FillRule = FillRule.EvenOdd
Expand Down Expand Up @@ -734,8 +761,18 @@ protected override void OnMouseUp(MouseButtonEventArgs e)
}
}

private Pen GetOutlinePen()
{
return _outlinePen ??= new Pen(OutlineBrush, StrokeThickness + OutlineThickness * 2d);
}

protected override void OnRender(DrawingContext drawingContext)
{
if (OutlineBrush != null)
{
drawingContext.DrawGeometry(OutlineBrush, GetOutlinePen(), DefiningGeometry);
}

base.OnRender(drawingContext);

if (!string.IsNullOrEmpty(Text))
Expand Down
1 change: 1 addition & 0 deletions Nodify/Helpers/BoxValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public static class BoxValue
public static readonly object Double0 = 0d;
public static readonly object Double1 = 1d;
public static readonly object Double2 = 2d;
public static readonly object Double5 = 5d;
public static readonly object Double45 = 45d;
public static readonly object Double1000 = 1000d;
public static readonly object Int0 = 0;
Expand Down

0 comments on commit 55e2a30

Please sign in to comment.