1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Nodes - Vein attempt at script changed events

This commit is contained in:
Robert 2021-10-05 17:10:58 +02:00
parent 245c418b9b
commit 8f990f8f36
19 changed files with 115 additions and 113 deletions

View File

@ -1,4 +1,6 @@
namespace Artemis.Core using System;
namespace Artemis.Core
{ {
/// <summary> /// <summary>
/// Represents a custom view model for a <see cref="INode" /> /// Represents a custom view model for a <see cref="INode" />
@ -19,5 +21,10 @@
/// Called whenever the custom view model is closed /// Called whenever the custom view model is closed
/// </summary> /// </summary>
void OnDeactivate(); void OnDeactivate();
/// <summary>
/// Occurs whenever the node was modified by the view model
/// </summary>
event EventHandler NodeModified;
} }
} }

View File

@ -65,7 +65,7 @@ namespace Artemis.VisualScripting.Editor.Controls
public string SearchInput public string SearchInput
{ {
get => (string)GetValue(SearchInputProperty); get => (string) GetValue(SearchInputProperty);
set => SetValue(SearchInputProperty, value); set => SetValue(SearchInputProperty, value);
} }
@ -109,10 +109,15 @@ namespace Artemis.VisualScripting.Editor.Controls
private bool Filter(object o) private bool Filter(object o)
{ {
if (o is not NodeData nodeData) return false; if (o is not NodeData nodeData) return false;
if (string.IsNullOrWhiteSpace(SearchInput)) return true;
bool searchContains = nodeData.Name.Contains(SearchInput, StringComparison.OrdinalIgnoreCase) || bool searchContains;
if (string.IsNullOrWhiteSpace(SearchInput))
searchContains = true;
else
{
searchContains = nodeData.Name.Contains(SearchInput, StringComparison.OrdinalIgnoreCase) ||
nodeData.Description.Contains(SearchInput, StringComparison.OrdinalIgnoreCase); nodeData.Description.Contains(SearchInput, StringComparison.OrdinalIgnoreCase);
}
if (SourcePin == null || SourcePin.Pin.Type == typeof(object)) if (SourcePin == null || SourcePin.Pin.Type == typeof(object))
return searchContains; return searchContains;

View File

@ -54,6 +54,7 @@ namespace Artemis.VisualScripting.Editor.Controls
public VisualScriptNodePresenter() public VisualScriptNodePresenter()
{ {
Loaded += OnLoaded;
Unloaded += OnUnloaded; Unloaded += OnUnloaded;
} }
@ -170,12 +171,28 @@ namespace Artemis.VisualScripting.Editor.Controls
presenter.GetCustomViewModel(); presenter.GetCustomViewModel();
} }
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (CustomViewModel != null)
CustomViewModel.NodeModified += CustomViewModelOnNodeModified;
}
private void OnUnloaded(object sender, RoutedEventArgs e) private void OnUnloaded(object sender, RoutedEventArgs e)
{ {
CustomViewModel?.OnDeactivate(); if (CustomViewModel != null)
{
CustomViewModel.NodeModified -= CustomViewModelOnNodeModified;
CustomViewModel.OnDeactivate();
}
CustomViewModel = null; CustomViewModel = null;
} }
private void CustomViewModelOnNodeModified(object? sender, EventArgs e)
{
Node.Script.OnScriptUpdated();
}
#endregion #endregion
} }
} }

View File

@ -171,6 +171,12 @@ namespace Artemis.VisualScripting.Editor.Controls
#endregion #endregion
#region Events
public event EventHandler ScriptUpdated;
#endregion
#region Constructors #region Constructors
public VisualScriptPresenter() public VisualScriptPresenter()
@ -236,6 +242,7 @@ namespace Artemis.VisualScripting.Editor.Controls
{ {
if (VisualScript != null) if (VisualScript != null)
{ {
VisualScript.ScriptUpdated -= OnVisualScriptScriptUpdated;
VisualScript.PropertyChanged -= OnVisualScriptPropertyChanged; VisualScript.PropertyChanged -= OnVisualScriptPropertyChanged;
VisualScript.NodeMoved -= OnVisualScriptNodeMoved; VisualScript.NodeMoved -= OnVisualScriptNodeMoved;
VisualScript.NodeCollectionChanged -= OnVisualScriptNodeCollectionChanged; VisualScript.NodeCollectionChanged -= OnVisualScriptNodeCollectionChanged;
@ -245,6 +252,7 @@ namespace Artemis.VisualScripting.Editor.Controls
if (VisualScript != null) if (VisualScript != null)
{ {
VisualScript.ScriptUpdated += OnVisualScriptScriptUpdated;
VisualScript.PropertyChanged += OnVisualScriptPropertyChanged; VisualScript.PropertyChanged += OnVisualScriptPropertyChanged;
VisualScript.NodeMoved += OnVisualScriptNodeMoved; VisualScript.NodeMoved += OnVisualScriptNodeMoved;
VisualScript.NodeCollectionChanged += OnVisualScriptNodeCollectionChanged; VisualScript.NodeCollectionChanged += OnVisualScriptNodeCollectionChanged;
@ -264,6 +272,11 @@ namespace Artemis.VisualScripting.Editor.Controls
CenterAt(new Vector(0, 0)); CenterAt(new Vector(0, 0));
} }
private void OnVisualScriptScriptUpdated(object sender, EventArgs e)
{
ScriptUpdated?.Invoke(this, EventArgs.Empty);
}
private void OnVisualScriptPropertyChanged(object sender, PropertyChangedEventArgs args) private void OnVisualScriptPropertyChanged(object sender, PropertyChangedEventArgs args)
{ {
if (args.PropertyName == nameof(VisualScript.Cables)) if (args.PropertyName == nameof(VisualScript.Cables))
@ -528,7 +541,6 @@ namespace Artemis.VisualScripting.Editor.Controls
if (nodeData == null) return; if (nodeData == null) return;
INode node = nodeData.CreateNode(Script, null); INode node = nodeData.CreateNode(Script, null);
node.Initialize(Script);
node.X = _lastRightClickLocation.X - VisualScript.LocationOffset; node.X = _lastRightClickLocation.X - VisualScript.LocationOffset;
node.Y = _lastRightClickLocation.Y - VisualScript.LocationOffset; node.Y = _lastRightClickLocation.Y - VisualScript.LocationOffset;
@ -554,6 +566,7 @@ namespace Artemis.VisualScripting.Editor.Controls
_creationBoxParent.ContextMenu.IsOpen = false; _creationBoxParent.ContextMenu.IsOpen = false;
Script.AddNode(node); Script.AddNode(node);
VisualScript.OnScriptUpdated();
} }
private void CenterAt(Vector vector) private void CenterAt(Vector vector)

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Threading; using System.Windows.Threading;
@ -66,6 +67,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
public event EventHandler NodeMoved; public event EventHandler NodeMoved;
public event EventHandler NodeCollectionChanged; public event EventHandler NodeCollectionChanged;
public event EventHandler ScriptUpdated;
#endregion #endregion
@ -201,6 +203,8 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
{ {
foreach (VisualScriptNode node in _selectedNodes) foreach (VisualScriptNode node in _selectedNodes)
node.SnapNodeToGrid(); node.SnapNodeToGrid();
OnScriptUpdated();
} }
private void OnNodeDragMoving(object sender, VisualScriptNodeDragMovingEventArgs args) private void OnNodeDragMoving(object sender, VisualScriptNodeDragMovingEventArgs args)
@ -285,5 +289,10 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
} }
#endregion #endregion
public void OnScriptUpdated()
{
ScriptUpdated?.Invoke(this, EventArgs.Empty);
}
} }
} }

View File

@ -280,6 +280,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
{ {
DisconnectAllPins(); DisconnectAllPins();
Script.RemoveNode(this); Script.RemoveNode(this);
Script.OnScriptUpdated();
} }
private bool RemoveCanExecute() => !Node.IsExitNode && !Node.IsDefaultNode; private bool RemoveCanExecute() => !Node.IsExitNode && !Node.IsDefaultNode;

View File

@ -21,6 +21,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
#region Properties & Fields #region Properties & Fields
private bool _isConnectionUpdated = false; private bool _isConnectionUpdated = false;
private bool _disconnectingAll = false;
private VisualScriptPin _isConnectingPin; private VisualScriptPin _isConnectingPin;
private VisualScriptCable _isConnectingCable; private VisualScriptCable _isConnectingCable;
@ -32,6 +33,8 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
internal ObservableCollection<VisualScriptCable> InternalConnections { get; } = new(); internal ObservableCollection<VisualScriptCable> InternalConnections { get; } = new();
private Point _absolutePosition; private Point _absolutePosition;
public Point AbsolutePosition public Point AbsolutePosition
{ {
get => _absolutePosition; get => _absolutePosition;
@ -106,17 +109,22 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
Node?.OnPinConnected(new PinConnectedEventArgs(this, cable)); Node?.OnPinConnected(new PinConnectedEventArgs(this, cable));
if (_isConnectingPin == null)
Node?.Script.OnScriptUpdated();
_isConnectionUpdated = false; _isConnectionUpdated = false;
} }
public void DisconnectAll() public void DisconnectAll()
{ {
_isConnectionUpdated = true; _isConnectionUpdated = true;
_disconnectingAll = true;
List<VisualScriptCable> cables = InternalConnections.ToList(); List<VisualScriptCable> cables = InternalConnections.ToList();
foreach (VisualScriptCable cable in cables) foreach (VisualScriptCable cable in cables)
cable.Disconnect(); cable.Disconnect();
_disconnectingAll = false;
_isConnectionUpdated = false; _isConnectionUpdated = false;
} }
@ -129,6 +137,9 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
Node?.OnPinDisconnected(new PinDisconnectedEventArgs(this, cable)); Node?.OnPinDisconnected(new PinDisconnectedEventArgs(this, cable));
if (!_disconnectingAll && _isConnectingPin == null)
Node?.Script.OnScriptUpdated();
_isConnectionUpdated = false; _isConnectionUpdated = false;
} }

View File

@ -57,6 +57,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
visualScriptPin.DisconnectAll(); visualScriptPin.DisconnectAll();
Pins.Remove(visualScriptPin); Pins.Remove(visualScriptPin);
Node.Script.OnScriptUpdated();
} }
private void OnPinCollectionPinAdded(object sender, SingleValueEventArgs<IPin> args) private void OnPinCollectionPinAdded(object sender, SingleValueEventArgs<IPin> args)
@ -66,6 +67,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
VisualScriptPin visualScriptPin = new(Node, args.Value); VisualScriptPin visualScriptPin = new(Node, args.Value);
_pinMapping.Add(args.Value, visualScriptPin); _pinMapping.Add(args.Value, visualScriptPin);
Pins.Add(visualScriptPin); Pins.Add(visualScriptPin);
Node.Script.OnScriptUpdated();
} }
public void AddPin() => PinCollection.AddPin(); public void AddPin() => PinCollection.AddPin();

View File

@ -9,12 +9,12 @@ namespace Artemis.VisualScripting.Nodes.Color
public BrightenSKColorNode() : base("Brighten Color", "Brightens a color by a specified amount in percent") public BrightenSKColorNode() : base("Brighten Color", "Brightens a color by a specified amount in percent")
{ {
Input = CreateInputPin<SKColor>("Color"); Input = CreateInputPin<SKColor>("Color");
Percentage = CreateInputPin<float>("%"); Percentage = CreateInputPin<Numeric>("%");
Output = CreateOutputPin<SKColor>(); Output = CreateOutputPin<SKColor>();
} }
public InputPin<SKColor> Input { get; } public InputPin<SKColor> Input { get; }
public InputPin<float> Percentage { get; } public InputPin<Numeric> Percentage { get; }
public OutputPin<SKColor> Output { get; set; } public OutputPin<SKColor> Output { get; set; }
public override void Evaluate() public override void Evaluate()

View File

@ -9,12 +9,12 @@ namespace Artemis.VisualScripting.Nodes.Color
public DarkenSKColorNode() : base("Darken Color", "Darkens a color by a specified amount in percent") public DarkenSKColorNode() : base("Darken Color", "Darkens a color by a specified amount in percent")
{ {
Input = CreateInputPin<SKColor>("Color"); Input = CreateInputPin<SKColor>("Color");
Percentage = CreateInputPin<float>("%"); Percentage = CreateInputPin<Numeric>("%");
Output = CreateOutputPin<SKColor>(); Output = CreateOutputPin<SKColor>();
} }
public InputPin<SKColor> Input { get; } public InputPin<SKColor> Input { get; }
public InputPin<float> Percentage { get; } public InputPin<Numeric> Percentage { get; }
public OutputPin<SKColor> Output { get; set; } public OutputPin<SKColor> Output { get; set; }
public override void Evaluate() public override void Evaluate()

View File

@ -10,12 +10,12 @@ namespace Artemis.VisualScripting.Nodes.Color
public DesaturateSKColorNode() : base("Desaturate Color", "Desaturates a color by a specified amount in percent") public DesaturateSKColorNode() : base("Desaturate Color", "Desaturates a color by a specified amount in percent")
{ {
Input = CreateInputPin<SKColor>("Color"); Input = CreateInputPin<SKColor>("Color");
Percentage = CreateInputPin<float>("%"); Percentage = CreateInputPin<Numeric>("%");
Output = CreateOutputPin<SKColor>(); Output = CreateOutputPin<SKColor>();
} }
public InputPin<SKColor> Input { get; } public InputPin<SKColor> Input { get; }
public InputPin<float> Percentage { get; } public InputPin<Numeric> Percentage { get; }
public OutputPin<SKColor> Output { get; set; } public OutputPin<SKColor> Output { get; set; }
public override void Evaluate() public override void Evaluate()

View File

@ -9,12 +9,12 @@ namespace Artemis.VisualScripting.Nodes.Color
public RotateHueSKColorNode() : base("Rotate Color Hue", "Rotates the hue of a color by a specified amount in degrees") public RotateHueSKColorNode() : base("Rotate Color Hue", "Rotates the hue of a color by a specified amount in degrees")
{ {
Input = CreateInputPin<SKColor>("Color"); Input = CreateInputPin<SKColor>("Color");
Amount = CreateInputPin<float>("Amount"); Amount = CreateInputPin<Numeric>("Amount");
Output = CreateOutputPin<SKColor>(); Output = CreateOutputPin<SKColor>();
} }
public InputPin<SKColor> Input { get; } public InputPin<SKColor> Input { get; }
public InputPin<float> Amount { get; } public InputPin<Numeric> Amount { get; }
public OutputPin<SKColor> Output { get; set; } public OutputPin<SKColor> Output { get; set; }
public override void Evaluate() public override void Evaluate()

View File

@ -10,12 +10,12 @@ namespace Artemis.VisualScripting.Nodes.Color
public SaturateSKColorNode() : base("Saturate Color", "Saturates a color by a specified amount in percent") public SaturateSKColorNode() : base("Saturate Color", "Saturates a color by a specified amount in percent")
{ {
Input = CreateInputPin<SKColor>("Color"); Input = CreateInputPin<SKColor>("Color");
Percentage = CreateInputPin<float>("%"); Percentage = CreateInputPin<Numeric>("%");
Output = CreateOutputPin<SKColor>(); Output = CreateOutputPin<SKColor>();
} }
public InputPin<SKColor> Input { get; } public InputPin<SKColor> Input { get; }
public InputPin<float> Percentage { get; } public InputPin<Numeric> Percentage { get; }
public OutputPin<SKColor> Output { get; set; } public OutputPin<SKColor> Output { get; set; }
public override void Evaluate() public override void Evaluate()

View File

@ -1,4 +1,6 @@
using Artemis.Core; using System;
using System.ComponentModel;
using Artemis.Core;
using Stylet; using Stylet;
namespace Artemis.VisualScripting.Nodes.CustomViewModels namespace Artemis.VisualScripting.Nodes.CustomViewModels
@ -17,11 +19,38 @@ namespace Artemis.VisualScripting.Nodes.CustomViewModels
/// <inheritdoc /> /// <inheritdoc />
public virtual void OnActivate() public virtual void OnActivate()
{ {
Node.PropertyChanged += NodeOnPropertyChanged;
} }
/// <inheritdoc /> /// <inheritdoc />
public virtual void OnDeactivate() public virtual void OnDeactivate()
{ {
Node.PropertyChanged -= NodeOnPropertyChanged;
}
#endregion
#region Events
/// <inheritdoc />
public event EventHandler NodeModified;
/// <summary>
/// Invokes the <see cref="NodeModified"/> event
/// </summary>
protected virtual void OnNodeModified()
{
NodeModified?.Invoke(this, EventArgs.Empty);
}
#endregion
#region Event handlers
private void NodeOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Storage")
OnNodeModified();
} }
#endregion #endregion

View File

@ -1,12 +0,0 @@
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.StaticDoubleValueNodeCustomView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.VisualScripting.Nodes.CustomViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<TextBox VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Text="{Binding Node.Storage}" />
</UserControl>

View File

@ -1,12 +0,0 @@
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.StaticIntegerValueNodeCustomView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.VisualScripting.Nodes.CustomViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<TextBox VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Text="{Binding Node.Storage}" />
</UserControl>

View File

@ -1,68 +0,0 @@
using System;
using Artemis.Core;
namespace Artemis.VisualScripting.Nodes.Easing
{
[Node("Integer Easing", "Outputs an eased integer value", "Easing", InputType = typeof(int), OutputType = typeof(int))]
public class IntEasingNode : Node
{
private DateTime _lastEvaluate = DateTime.MinValue;
private float _progress;
private int _currentValue;
private int _sourceValue;
private int _targetValue;
public IntEasingNode() : base("Integer Easing", "Outputs an eased integer value")
{
Input = CreateInputPin<int>();
EasingTime = CreateInputPin<float>("delay");
EasingFunction = CreateInputPin<Easings.Functions>("function");
Output = CreateOutputPin<int>();
}
public InputPin<int> Input { get; set; }
public InputPin<float> EasingTime { get; set; }
public InputPin<Easings.Functions> EasingFunction { get; set; }
public OutputPin<int> Output { get; set; }
public override void Evaluate()
{
DateTime now = DateTime.Now;
// If the value changed reset progress
if (_targetValue != Input.Value)
{
_sourceValue = _currentValue;
_targetValue = Input.Value;
_progress = 0f;
}
// Update until finished
if (_progress < 1f)
{
Update();
Output.Value = _currentValue;
}
// Stop updating past 1 and use the target value
else
{
Output.Value = _targetValue;
}
_lastEvaluate = now;
}
private void Update()
{
TimeSpan delta = DateTime.Now - _lastEvaluate;
// In case of odd delta's, keep progress between 0f and 1f
_progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / EasingTime.Value, 0f, 1f);
double eased = _sourceValue + (_targetValue - _sourceValue) * Easings.Interpolate(_progress, EasingFunction.Value);
_currentValue = (int) Math.Round(eased, MidpointRounding.AwayFromZero);
}
}
}

View File

@ -16,14 +16,14 @@ namespace Artemis.VisualScripting.Nodes.Easing
public SKColorEasingNode() : base("Color Easing", "Outputs an eased color value") public SKColorEasingNode() : base("Color Easing", "Outputs an eased color value")
{ {
Input = CreateInputPin<SKColor>(); Input = CreateInputPin<SKColor>();
EasingTime = CreateInputPin<float>("delay"); EasingTime = CreateInputPin<Numeric>("delay");
EasingFunction = CreateInputPin<Easings.Functions>("function"); EasingFunction = CreateInputPin<Easings.Functions>("function");
Output = CreateOutputPin<SKColor>(); Output = CreateOutputPin<SKColor>();
} }
public InputPin<SKColor> Input { get; set; } public InputPin<SKColor> Input { get; set; }
public InputPin<float> EasingTime { get; set; } public InputPin<Numeric> EasingTime { get; set; }
public InputPin<Easings.Functions> EasingFunction { get; set; } public InputPin<Easings.Functions> EasingFunction { get; set; }
public OutputPin<SKColor> Output { get; set; } public OutputPin<SKColor> Output { get; set; }