From dc172535189ef941860802e9ac537b805cabee03 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 1 Aug 2022 22:26:11 +0200 Subject: [PATCH] Visual scripting - Added pin disconnect with MMB Visual scripting - Added min and max node --- .../NodeEditor/Commands/DisconnectPins.cs | 43 +++++++++++++++++++ .../Ninject/Factories/IVMFactory.cs | 4 +- .../Screens/VisualScripting/NodeViewModel.cs | 4 +- .../Pins/InputPinCollectionViewModel.cs | 4 +- .../VisualScripting/Pins/InputPinView.axaml | 2 +- .../Pins/InputPinView.axaml.cs | 8 ++++ .../VisualScripting/Pins/InputPinViewModel.cs | 4 +- .../Pins/OutputPinCollectionViewModel.cs | 4 +- .../VisualScripting/Pins/OutputPinView.axaml | 2 +- .../Pins/OutputPinView.axaml.cs | 8 ++++ .../Pins/OutputPinViewModel.cs | 4 +- .../VisualScripting/Pins/PinViewModel.cs | 8 +++- .../Artemis.VisualScripting.csproj | 20 ++++----- .../Nodes/Mathematics/MaxNode.cs | 35 +++++++++++++++ .../Nodes/Mathematics/MinNode.cs | 35 +++++++++++++++ 15 files changed, 164 insertions(+), 21 deletions(-) create mode 100644 src/Artemis.UI.Shared/Services/NodeEditor/Commands/DisconnectPins.cs create mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs create mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs diff --git a/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DisconnectPins.cs b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DisconnectPins.cs new file mode 100644 index 000000000..685350335 --- /dev/null +++ b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DisconnectPins.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using Artemis.Core; + +namespace Artemis.UI.Shared.Services.NodeEditor.Commands; + +/// +/// Represents a node editor command that can be used to connect two pins. +/// +public class DisconnectPins : INodeEditorCommand +{ + private readonly IPin _pin; + private readonly List _originalConnections; + + /// + /// Creates a new instance of the class. + /// + /// The pin to disconnect. + public DisconnectPins(IPin pin) + { + _pin = pin; + _originalConnections = new List(_pin.ConnectedTo); + } + + #region Implementation of INodeEditorCommand + + /// + public string DisplayName => "Disconnect pins"; + + /// + public void Execute() + { + _pin.DisconnectAll(); + } + + /// + public void Undo() + { + foreach (IPin pin in _originalConnections) + _pin.ConnectTo(pin); + } + + #endregion +} \ No newline at end of file diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs index 989a1211f..be0109ed5 100644 --- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs +++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs @@ -106,8 +106,8 @@ public interface INodeVmFactory : IVmFactory NodeViewModel NodeViewModel(NodeScriptViewModel nodeScriptViewModel, INode node); CableViewModel CableViewModel(NodeScriptViewModel nodeScriptViewModel, IPin from, IPin to); DragCableViewModel DragCableViewModel(PinViewModel pinViewModel); - InputPinViewModel InputPinViewModel(IPin inputPin); - OutputPinViewModel OutputPinViewModel(IPin outputPin); + InputPinViewModel InputPinViewModel(IPin inputPin, NodeScriptViewModel nodeScriptViewModel); + OutputPinViewModel OutputPinViewModel(IPin outputPin, NodeScriptViewModel nodeScriptViewModel); InputPinCollectionViewModel InputPinCollectionViewModel(IPinCollection inputPinCollection, NodeScriptViewModel nodeScriptViewModel); OutputPinCollectionViewModel OutputPinCollectionViewModel(IPinCollection outputPinCollection, NodeScriptViewModel nodeScriptViewModel); } diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs index 79dca9758..c56b54bd7 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs @@ -47,12 +47,12 @@ public class NodeViewModel : ActivatableViewModelBase // Create observable collections split up by direction nodePins.Connect() .Filter(n => n.Direction == PinDirection.Input) - .Transform(p => (PinViewModel) nodeVmFactory.InputPinViewModel(p)) + .Transform(p => (PinViewModel) nodeVmFactory.InputPinViewModel(p, nodeScriptViewModel)) .Bind(out ReadOnlyObservableCollection inputPins) .Subscribe(); nodePins.Connect() .Filter(n => n.Direction == PinDirection.Output) - .Transform(p => (PinViewModel) nodeVmFactory.OutputPinViewModel(p)) + .Transform(p => (PinViewModel) nodeVmFactory.OutputPinViewModel(p, nodeScriptViewModel)) .Bind(out ReadOnlyObservableCollection outputPins) .Subscribe(); InputPinViewModels = inputPins; diff --git a/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinCollectionViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinCollectionViewModel.cs index 83a66fe5c..d6cfec82f 100644 --- a/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinCollectionViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinCollectionViewModel.cs @@ -6,19 +6,21 @@ namespace Artemis.UI.Screens.VisualScripting.Pins; public class InputPinCollectionViewModel : PinCollectionViewModel { + private readonly NodeScriptViewModel _nodeScriptViewModel; private readonly INodeVmFactory _nodeVmFactory; public IPinCollection InputPinCollection { get; } public InputPinCollectionViewModel(IPinCollection inputPinCollection, NodeScriptViewModel nodeScriptViewModel, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService) : base(inputPinCollection, nodeScriptViewModel, nodeEditorService) { + _nodeScriptViewModel = nodeScriptViewModel; _nodeVmFactory = nodeVmFactory; InputPinCollection = inputPinCollection; } protected override PinViewModel CreatePinViewModel(IPin pin) { - PinViewModel vm = _nodeVmFactory.InputPinViewModel(pin); + PinViewModel vm = _nodeVmFactory.InputPinViewModel(pin, _nodeScriptViewModel); vm.RemovePin = RemovePin; return vm; } diff --git a/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinView.axaml b/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinView.axaml index b995c00a1..330a18642 100644 --- a/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinView.axaml +++ b/src/Artemis.UI/Screens/VisualScripting/Pins/InputPinView.axaml @@ -14,7 +14,7 @@ - + - + nodeEditorService.ExecuteCommand(nodeScriptViewModel.NodeScript, new DisconnectPins(Pin))); + SourceList connectedPins = new(); this.WhenActivated(d => { @@ -78,6 +82,8 @@ public abstract class PinViewModel : ActivatableViewModelBase set => RaiseAndSetIfChanged(ref _removePin, value); } + public ReactiveCommand DisconnectPin { get; } + public bool IsCompatibleWith(PinViewModel pinViewModel) { if (pinViewModel.Pin.Direction == Pin.Direction || pinViewModel.Pin.Node == Pin.Node) diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index 8d46adae9..3a40c56b3 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -8,19 +8,19 @@ - - - - - - - - + + + + + + + + - - + + diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs new file mode 100644 index 000000000..001cca53f --- /dev/null +++ b/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs @@ -0,0 +1,35 @@ +using Artemis.Core; + +namespace Artemis.VisualScripting.Nodes.Mathematics; + +[Node("Max", "Outputs the largest of the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] +public class MaxNumericsNode : Node +{ + #region Constructors + + public MaxNumericsNode() + : base("Max", "Outputs the largest of the connected numeric values.") + { + Values = CreateInputPinCollection("Values", 2); + Max = CreateOutputPin("Max"); + } + + #endregion + + #region Methods + + public override void Evaluate() + { + Max.Value = Values.Values.Max(); + } + + #endregion + + #region Properties & Fields + + public InputPinCollection Values { get; } + + public OutputPin Max { get; } + + #endregion +} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs new file mode 100644 index 000000000..a10ff8c3a --- /dev/null +++ b/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs @@ -0,0 +1,35 @@ +using Artemis.Core; + +namespace Artemis.VisualScripting.Nodes.Mathematics; + +[Node("Min", "Outputs the smallest of the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] +public class MinNumericsNode : Node +{ + #region Constructors + + public MinNumericsNode() + : base("Min", "Outputs the smallest of the connected numeric values.") + { + Values = CreateInputPinCollection("Values", 2); + Min = CreateOutputPin("Min"); + } + + #endregion + + #region Methods + + public override void Evaluate() + { + Min.Value = Values.Values.Min(); + } + + #endregion + + #region Properties & Fields + + public InputPinCollection Values { get; } + + public OutputPin Min { get; } + + #endregion +} \ No newline at end of file