1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-31 01:42:02 +00:00

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 2021-08-18 00:03:07 +02:00
parent 7d3f5da3c9
commit 32d4ec2812
10 changed files with 181 additions and 66 deletions

View File

@ -26,6 +26,7 @@ namespace Artemis.Core
{ {
_value = value; _value = value;
IsEvaluated = true; IsEvaluated = true;
OnPropertyChanged(nameof(PinValue));
} }
} }
@ -75,6 +76,7 @@ namespace Artemis.Core
_value = value; _value = value;
IsEvaluated = true; IsEvaluated = true;
OnPropertyChanged(nameof(PinValue));
} }
} }

View File

@ -25,6 +25,8 @@ namespace Artemis.Core
{ {
_value = value; _value = value;
IsEvaluated = true; IsEvaluated = true;
OnPropertyChanged(nameof(PinValue));
} }
} }
@ -64,6 +66,7 @@ namespace Artemis.Core
_value = value; _value = value;
IsEvaluated = true; IsEvaluated = true;
OnPropertyChanged(nameof(PinValue));
} }
} }

View File

@ -118,6 +118,8 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
{ {
if (e.ChangedButton != MouseButton.Left) if (e.ChangedButton != MouseButton.Left)
return; return;
if (RenderProfileElement == null)
return;
RenderProfileElement.DisplayCondition ??= new NodeScript<bool>("End Result", ""); RenderProfileElement.DisplayCondition ??= new NodeScript<bool>("End Result", "");

View File

@ -1,26 +1,35 @@
<mde:MaterialWindow x:Class="Artemis.UI.Screens.ProfileEditor.Windows.NodeScriptWindowView" <mde:MaterialWindow x:Class="Artemis.UI.Screens.ProfileEditor.Windows.NodeScriptWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mde="https://spiegelp.github.io/MaterialDesignExtensions/winfx/xaml" xmlns:mde="https://spiegelp.github.io/MaterialDesignExtensions/winfx/xaml"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/" xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls;assembly=Artemis.VisualScripting" xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls;assembly=Artemis.VisualScripting"
xmlns:windows="clr-namespace:Artemis.UI.Screens.ProfileEditor.Windows" xmlns:windows="clr-namespace:Artemis.UI.Screens.ProfileEditor.Windows"
mc:Ignorable="d" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
Title="Node Script | Artemis" mc:Ignorable="d"
TitleBarIcon="{svgc:SvgImage Source=/Resources/Images/Logo/bow-white.svg}" Title="Node Script | Artemis"
Foreground="{DynamicResource MaterialDesignBody}" TitleBarIcon="{svgc:SvgImage Source=/Resources/Images/Logo/bow-white.svg}"
Background="{DynamicResource MaterialDesignPaper}" Foreground="{DynamicResource MaterialDesignBody}"
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto" Background="{DynamicResource MaterialDesignPaper}"
UseLayoutRounding="True" FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
FadeContentIfInactive="False" UseLayoutRounding="True"
Width="1200" FadeContentIfInactive="False"
Height="1000" Width="1200"
d:DesignHeight="800" d:DesignWidth="800" Height="1000"
d:DataContext="{d:DesignInstance windows:NodeScriptWindowViewModel}" d:DesignHeight="800" d:DesignWidth="800"
Icon="/Resources/Images/Logo/bow.ico"> d:DataContext="{d:DesignInstance windows:NodeScriptWindowViewModel}"
<Grid> Icon="/Resources/Images/Logo/bow.ico">
<controls:VisualScriptEditor Script="{Binding NodeScript}" AvailableNodes="{Binding AvailableNodes}" /> <materialDesign:DialogHost IsTabStop="False" Focusable="False" Identifier="NodeScriptDialog" DialogTheme="Inherit">
</Grid> <DockPanel>
</mde:MaterialWindow> <mde:AppBar Type="Dense" Title="Node Script Editor" DockPanel.Dock="Top" Margin="-18 0 0 0">
<mde:AppBar.AppIcon>
<materialDesign:PackIcon Kind="FreehandLine" Width="20" Height="28" />
</mde:AppBar.AppIcon>
</mde:AppBar>
<controls:VisualScriptEditor Script="{Binding NodeScript}" AvailableNodes="{Binding AvailableNodes}" />
</DockPanel>
</materialDesign:DialogHost>
</mde:MaterialWindow>

View File

@ -21,15 +21,9 @@
d:DesignHeight="800" d:DesignWidth="800" d:DataContext="{d:DesignInstance debug:DebugViewModel}" d:DesignHeight="800" d:DesignWidth="800" d:DataContext="{d:DesignInstance debug:DebugViewModel}"
Icon="/Resources/Images/Logo/bow.ico" Icon="/Resources/Images/Logo/bow.ico"
Topmost="{Binding StayOnTopSetting.Value}"> Topmost="{Binding StayOnTopSetting.Value}">
<materialDesign:DialogHost IsTabStop="False" <materialDesign:DialogHost IsTabStop="False" Focusable="False" Identifier="DebuggerDialog" DialogTheme="Inherit">
Focusable="False"
Identifier="DebuggerDialog"
DialogTheme="Inherit">
<DockPanel> <DockPanel>
<mde:AppBar Type="Dense" <mde:AppBar Type="Dense" Title="Debugger" DockPanel.Dock="Top" Margin="-18 0 0 0">
Title="Debugger"
DockPanel.Dock="Top"
Margin="-18 0 0 0">
<mde:AppBar.AppIcon> <mde:AppBar.AppIcon>
<materialDesign:PackIcon Kind="Matrix" Width="20" Height="28" /> <materialDesign:PackIcon Kind="Matrix" Width="20" Height="28" />
</mde:AppBar.AppIcon> </mde:AppBar.AppIcon>

View File

@ -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;
}
}
}

View File

@ -1,4 +1,5 @@
using System; using System;
using System.ComponentModel;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
@ -25,11 +26,11 @@ namespace Artemis.VisualScripting.Editor.Controls
#region Dependency Properties #region Dependency Properties
public static readonly DependencyProperty CableProperty = DependencyProperty.Register( 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 public VisualScriptCable Cable
{ {
get => (VisualScriptCable)GetValue(CableProperty); get => (VisualScriptCable) GetValue(CableProperty);
set => SetValue(CableProperty, value); set => SetValue(CableProperty, value);
} }
@ -38,18 +39,37 @@ namespace Artemis.VisualScripting.Editor.Controls
public double Thickness public double Thickness
{ {
get => (double)GetValue(ThicknessProperty); get => (double) GetValue(ThicknessProperty);
set => SetValue(ThicknessProperty, value); 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 #endregion
#region Methods #region Methods
public override void OnApplyTemplate() public override void OnApplyTemplate()
{ {
_path = GetTemplateChild(PART_PATH) as Path ?? throw new NullReferenceException($"The Path '{PART_PATH}' is missing."); _path = GetTemplateChild(PART_PATH) as Path ?? throw new NullReferenceException($"The Path '{PART_PATH}' is missing.");
_path.MouseDown += OnPathMouseDown; _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) private void OnPathMouseDown(object sender, MouseButtonEventArgs args)
@ -63,6 +83,48 @@ namespace Artemis.VisualScripting.Editor.Controls
Cable.Disconnect(); 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 #endregion
} }
} }

View File

@ -1,33 +1,53 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime" 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" <ControlTemplate x:Key="TemplateVisualScriptCablePresenter"
TargetType="{x:Type controls:VisualScriptCablePresenter}"> TargetType="{x:Type controls:VisualScriptCablePresenter}">
<Path x:Name="PART_Path" <Canvas>
Stroke="{TemplateBinding BorderBrush}" <Path x:Name="PART_Path"
StrokeThickness="{TemplateBinding Thickness}" Stroke="{TemplateBinding BorderBrush}"
StrokeStartLineCap="Round" StrokeThickness="{TemplateBinding Thickness}"
StrokeEndLineCap="Round"> StrokeStartLineCap="Round"
<Path.Data> StrokeEndLineCap="Round">
<PathGeometry> <Path.Data>
<PathGeometry.Figures> <PathGeometry>
<PathFigureCollection> <PathGeometry.Figures>
<PathFigure StartPoint="{Binding Cable.From.AbsolutePosition, RelativeSource={RelativeSource TemplatedParent}}"> <PathFigureCollection>
<PathFigure.Segments> <PathFigure StartPoint="{Binding Cable.From.AbsolutePosition, RelativeSource={RelativeSource TemplatedParent}}">
<PathSegmentCollection> <PathFigure.Segments>
<BezierSegment Point1="{Binding Cable.From.AbsoluteCableTargetPosition, RelativeSource={RelativeSource TemplatedParent}}" <PathSegmentCollection>
Point2="{Binding Cable.To.AbsoluteCableTargetPosition, RelativeSource={RelativeSource TemplatedParent}}" <BezierSegment Point1="{Binding Cable.From.AbsoluteCableTargetPosition, RelativeSource={RelativeSource TemplatedParent}}"
Point3="{Binding Cable.To.AbsolutePosition, RelativeSource={RelativeSource TemplatedParent}}" /> Point2="{Binding Cable.To.AbsoluteCableTargetPosition, RelativeSource={RelativeSource TemplatedParent}}"
</PathSegmentCollection> Point3="{Binding Cable.To.AbsolutePosition, RelativeSource={RelativeSource TemplatedParent}}" />
</PathFigure.Segments> </PathSegmentCollection>
</PathFigure> </PathFigure.Segments>
</PathFigureCollection> </PathFigure>
</PathGeometry.Figures> </PathFigureCollection>
</PathGeometry> </PathGeometry.Figures>
</Path.Data> </PathGeometry>
</Path> </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> </ControlTemplate>
<Style x:Key="StyleVisualScriptCablePresenter" <Style x:Key="StyleVisualScriptCablePresenter"
@ -35,8 +55,6 @@
<Setter Property="BorderBrush" Value="#FFFFFFFF" /> <Setter Property="BorderBrush" Value="#FFFFFFFF" />
<Setter Property="Thickness" Value="4" /> <Setter Property="Thickness" Value="4" />
<Setter Property="ToolTip" Value="{Binding Cable.From.Pin.PinValue, TargetNullValue=-, RelativeSource={RelativeSource Self}}" />
<Setter Property="Template" Value="{StaticResource TemplateVisualScriptCablePresenter}" /> <Setter Property="Template" Value="{StaticResource TemplateVisualScriptCablePresenter}" />
<Style.Triggers> <Style.Triggers>

View File

@ -13,7 +13,7 @@ namespace Artemis.VisualScripting.Nodes.CustomViewModels
public int Input public int Input
{ {
get => (int)(long) _node.Storage; get => (int) _node.Storage;
set set
{ {
_node.Storage = value; _node.Storage = value;

View File

@ -26,7 +26,7 @@ namespace Artemis.VisualScripting.Nodes
public override void Evaluate() public override void Evaluate()
{ {
Output.Value = (int) (Storage as long? ?? 0); Output.Value = Storage as int? ?? 0;
} }
public override void Initialize() => Storage ??= 0; public override void Initialize() => Storage ??= 0;