Nodes - Added pin value visualization

Nodes - Update values in UI in realtime
Integer node - Fixed loading by removing some trial & error code
This commit is contained in:
Robert committed 2021-08-18 00:03:07 +02:00
1 parent 7d3f5da3c9
commit 32d4ec2812
10 files changed
+181 -66

No files matched your search

@@ -0,0 +1,25 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace Artemis.VisualScripting.Converters
{
internal class CenterTranslateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not double doubleValue)
return value;
return doubleValue / 2 * -1;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not double doubleValue)
return value;
return doubleValue * -1 * 2;
}
}
}
@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@@ -25,11 +26,11 @@ namespace Artemis.VisualScripting.Editor.Controls
#region Dependency Properties
public static readonly DependencyProperty CableProperty = DependencyProperty.Register(
"Cable", typeof(VisualScriptCable), typeof(VisualScriptCablePresenter), new PropertyMetadata(default(VisualScriptCable)));
"Cable", typeof(VisualScriptCable), typeof(VisualScriptCablePresenter), new PropertyMetadata(default(VisualScriptCable), CableChanged));
public VisualScriptCable Cable
{
get => (VisualScriptCable)GetValue(CableProperty);
get => (VisualScriptCable) GetValue(CableProperty);
set => SetValue(CableProperty, value);
}
@@ -38,18 +39,37 @@ namespace Artemis.VisualScripting.Editor.Controls
public double Thickness
{
get => (double)GetValue(ThicknessProperty);
get => (double) GetValue(ThicknessProperty);
set => SetValue(ThicknessProperty, value);
}
public static readonly DependencyProperty ValuePositionProperty = DependencyProperty.Register(
"ValuePosition", typeof(Point), typeof(VisualScriptCablePresenter), new PropertyMetadata(default(Point)));
public Point ValuePosition
{
get => (Point) GetValue(ValuePositionProperty);
set => SetValue(ValuePositionProperty, value);
}
#endregion
#region Methods
public override void OnApplyTemplate()
{
_path = GetTemplateChild(PART_PATH) as Path ?? throw new NullReferenceException($"The Path '{PART_PATH}' is missing.");
_path.MouseDown += OnPathMouseDown;
Unloaded += OnUnloaded;
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
if (Cable?.From != null)
Cable.From.PropertyChanged += OnPinPropertyChanged;
if (Cable?.To != null)
Cable.To.PropertyChanged += OnPinPropertyChanged;
}
private void OnPathMouseDown(object sender, MouseButtonEventArgs args)
@@ -63,6 +83,48 @@ namespace Artemis.VisualScripting.Editor.Controls
Cable.Disconnect();
}
private static void CableChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
if (d is not VisualScriptCablePresenter presenter) return;
presenter.CableChanged(args);
}
private void CableChanged(DependencyPropertyChangedEventArgs args)
{
if (args.OldValue is VisualScriptCable oldCable)
{
oldCable.From.PropertyChanged -= OnPinPropertyChanged;
oldCable.To.PropertyChanged -= OnPinPropertyChanged;
}
if (args.NewValue is VisualScriptCable newCable)
{
newCable.From.PropertyChanged += OnPinPropertyChanged;
newCable.To.PropertyChanged += OnPinPropertyChanged;
}
UpdateValuePosition();
}
private void OnPinPropertyChanged(object sender, PropertyChangedEventArgs e)
{
UpdateValuePosition();
}
private void UpdateValuePosition()
{
if (Cable.From == null || Cable.To == null)
ValuePosition = new Point();
else
{
ValuePosition = new Point(
Cable.From.AbsolutePosition.X + ((Cable.To.AbsolutePosition.X - Cable.From.AbsolutePosition.X) / 2),
Cable.From.AbsolutePosition.Y + ((Cable.To.AbsolutePosition.Y - Cable.From.AbsolutePosition.Y) / 2)
);
}
}
#endregion
}
}
}
@@ -1,33 +1,53 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls">
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls"
xmlns:converters="clr-namespace:Artemis.VisualScripting.Converters">
<converters:CenterTranslateConverter x:Key="CenterTranslateConverter"/>
<ControlTemplate x:Key="TemplateVisualScriptCablePresenter"
TargetType="{x:Type controls:VisualScriptCablePresenter}">
<Path x:Name="PART_Path"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="{TemplateBinding Thickness}"
StrokeStartLineCap="Round"
StrokeEndLineCap="Round">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="{Binding Cable.From.AbsolutePosition, RelativeSource={RelativeSource TemplatedParent}}">
<PathFigure.Segments>
<PathSegmentCollection>
<BezierSegment Point1="{Binding Cable.From.AbsoluteCableTargetPosition, RelativeSource={RelativeSource TemplatedParent}}"
Point2="{Binding Cable.To.AbsoluteCableTargetPosition, RelativeSource={RelativeSource TemplatedParent}}"
Point3="{Binding Cable.To.AbsolutePosition, RelativeSource={RelativeSource TemplatedParent}}" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
<Canvas>
<Path x:Name="PART_Path"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="{TemplateBinding Thickness}"
StrokeStartLineCap="Round"
StrokeEndLineCap="Round">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="{Binding Cable.From.AbsolutePosition, RelativeSource={RelativeSource TemplatedParent}}">
<PathFigure.Segments>
<PathSegmentCollection>
<BezierSegment Point1="{Binding Cable.From.AbsoluteCableTargetPosition, RelativeSource={RelativeSource TemplatedParent}}"
Point2="{Binding Cable.To.AbsoluteCableTargetPosition, RelativeSource={RelativeSource TemplatedParent}}"
Point3="{Binding Cable.To.AbsolutePosition, RelativeSource={RelativeSource TemplatedParent}}" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
<Border Canvas.Left="{Binding ValuePosition.X, RelativeSource={RelativeSource TemplatedParent}}"
Canvas.Top="{Binding ValuePosition.Y, RelativeSource={RelativeSource TemplatedParent}}"
Background="#2A2A2A"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="2"
Padding="6"
CornerRadius="2"
x:Name="PART_ValueDisplay">
<Border.RenderTransform>
<TranslateTransform X="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Border}, Converter={StaticResource CenterTranslateConverter}}"
Y="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Border}, Converter={StaticResource CenterTranslateConverter}}" />
</Border.RenderTransform>
<TextBlock Text="{Binding Cable.From.Pin.PinValue, TargetNullValue=-, RelativeSource={RelativeSource TemplatedParent}}" />
</Border>
</Canvas>
</ControlTemplate>
<Style x:Key="StyleVisualScriptCablePresenter"
@@ -35,8 +55,6 @@
<Setter Property="BorderBrush" Value="#FFFFFFFF" />
<Setter Property="Thickness" Value="4" />
<Setter Property="ToolTip" Value="{Binding Cable.From.Pin.PinValue, TargetNullValue=-, RelativeSource={RelativeSource Self}}" />
<Setter Property="Template" Value="{StaticResource TemplateVisualScriptCablePresenter}" />
<Style.Triggers>
@@ -13,7 +13,7 @@ namespace Artemis.VisualScripting.Nodes.CustomViewModels
public int Input
{
get => (int)(long) _node.Storage;
get => (int) _node.Storage;
set
{
_node.Storage = value;
@@ -26,7 +26,7 @@ namespace Artemis.VisualScripting.Nodes
public override void Evaluate()
{
Output.Value = (int) (Storage as long? ?? 0);
Output.Value = Storage as int? ?? 0;
}
public override void Initialize() => Storage ??= 0;