mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Nodes - Added maths node
Nodes - Added visual representation of easing types to easings node
This commit is contained in:
parent
a664cfbcad
commit
28534cb57a
@ -1820,6 +1820,7 @@
|
||||
"Ninject": "3.3.4",
|
||||
"NoStringEvaluating": "2.2.2",
|
||||
"ReactiveUI": "17.1.50",
|
||||
"ReactiveUI.Validation": "2.2.1",
|
||||
"SkiaSharp": "2.88.0-preview.178"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1820,6 +1820,7 @@
|
||||
"Ninject": "3.3.4",
|
||||
"NoStringEvaluating": "2.2.2",
|
||||
"ReactiveUI": "17.1.50",
|
||||
"ReactiveUI.Validation": "2.2.1",
|
||||
"SkiaSharp": "2.88.0-preview.178"
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,13 +3,14 @@ using System.ComponentModel;
|
||||
using System.Reactive.Disposables;
|
||||
using Artemis.Core;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Validation.Helpers;
|
||||
|
||||
namespace Artemis.UI.Shared.VisualScripting;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a custom view model for a node
|
||||
/// </summary>
|
||||
public abstract class CustomNodeViewModel : ActivatableViewModelBase, ICustomNodeViewModel
|
||||
public abstract class CustomNodeViewModel : ReactiveValidationObject, IActivatableViewModel, ICustomNodeViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="CustomNodeViewModel" /> class.
|
||||
@ -38,6 +39,13 @@ public abstract class CustomNodeViewModel : ActivatableViewModelBase, ICustomNod
|
||||
/// </summary>
|
||||
public INodeScript Script { get; }
|
||||
|
||||
#region Implementation of IActivatableViewModel
|
||||
|
||||
/// <inheritdoc />
|
||||
public ViewModelActivator Activator { get; } = new();
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="NodeModified" /> event
|
||||
/// </summary>
|
||||
|
||||
@ -1836,6 +1836,7 @@
|
||||
"Ninject": "3.3.4",
|
||||
"NoStringEvaluating": "2.2.2",
|
||||
"ReactiveUI": "17.1.50",
|
||||
"ReactiveUI.Validation": "2.2.1",
|
||||
"SkiaSharp": "2.88.0-preview.178"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1807,6 +1807,7 @@
|
||||
"Ninject": "3.3.4",
|
||||
"NoStringEvaluating": "2.2.2",
|
||||
"ReactiveUI": "17.1.50",
|
||||
"ReactiveUI.Validation": "2.2.1",
|
||||
"SkiaSharp": "2.88.0-preview.178"
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
<PackageReference Include="Ninject" Version="3.3.4" />
|
||||
<PackageReference Include="NoStringEvaluating" Version="2.2.2" />
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.50" />
|
||||
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.178" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@ -55,13 +55,13 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
|
||||
public ObservableCollection<Module>? Modules
|
||||
{
|
||||
get => _modules;
|
||||
set => RaiseAndSetIfChanged(ref _modules, value);
|
||||
set => this.RaiseAndSetIfChanged(ref _modules, value);
|
||||
}
|
||||
|
||||
public DataModelPath? DataModelPath
|
||||
{
|
||||
get => _dataModelPath;
|
||||
set => RaiseAndSetIfChanged(ref _dataModelPath, value);
|
||||
set => this.RaiseAndSetIfChanged(ref _dataModelPath, value);
|
||||
}
|
||||
|
||||
private void UpdateDataModelPath(DataModelPathEntity? entity)
|
||||
|
||||
@ -54,13 +54,13 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
|
||||
public ObservableCollection<Module>? Modules
|
||||
{
|
||||
get => _modules;
|
||||
set => RaiseAndSetIfChanged(ref _modules, value);
|
||||
set => this.RaiseAndSetIfChanged(ref _modules, value);
|
||||
}
|
||||
|
||||
public DataModelPath? DataModelPath
|
||||
{
|
||||
get => _dataModelPath;
|
||||
set => RaiseAndSetIfChanged(ref _dataModelPath, value);
|
||||
set => this.RaiseAndSetIfChanged(ref _dataModelPath, value);
|
||||
}
|
||||
|
||||
private void UpdateDataModelPath(DataModelPathEntity? entity)
|
||||
|
||||
@ -1,54 +1,35 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Services.NodeEditor;
|
||||
using Artemis.UI.Shared.Services.NodeEditor.Commands;
|
||||
using Artemis.UI.Shared.VisualScripting;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing.CustomViewModels;
|
||||
|
||||
public class EasingTypeNodeCustomViewModel : CustomNodeViewModel
|
||||
{
|
||||
private readonly EasingTypeNode _node;
|
||||
private NodeEasingViewModel _selectedEasingViewModel;
|
||||
private readonly INodeEditorService _nodeEditorService;
|
||||
|
||||
public EasingTypeNodeCustomViewModel(EasingTypeNode node, INodeScript script) : base(node, script)
|
||||
public EasingTypeNodeCustomViewModel(EasingTypeNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script)
|
||||
{
|
||||
_node = node;
|
||||
_nodeEditorService = nodeEditorService;
|
||||
|
||||
NodeModified += (_, _) => this.RaisePropertyChanged(nameof(SelectedEasingViewModel));
|
||||
EasingViewModels = new ObservableCollection<NodeEasingViewModel>(Enum.GetValues(typeof(Easings.Functions)).Cast<Easings.Functions>().Select(e => new NodeEasingViewModel(e)));
|
||||
}
|
||||
|
||||
public ObservableCollection<NodeEasingViewModel> EasingViewModels { get; }
|
||||
|
||||
public NodeEasingViewModel SelectedEasingViewModel
|
||||
public NodeEasingViewModel? SelectedEasingViewModel
|
||||
{
|
||||
get => _selectedEasingViewModel;
|
||||
get => EasingViewModels.FirstOrDefault(e => e.EasingFunction == _node.Storage);
|
||||
set
|
||||
{
|
||||
_selectedEasingViewModel = value;
|
||||
_node.Storage = _selectedEasingViewModel.EasingFunction;
|
||||
if (value != null && _node.Storage != value.EasingFunction)
|
||||
_nodeEditorService.ExecuteCommand(Script, new UpdateStorage<Easings.Functions>(_node, value.EasingFunction));
|
||||
}
|
||||
}
|
||||
|
||||
// public override void OnActivate()
|
||||
// {
|
||||
// _node.PropertyChanged += NodeOnPropertyChanged;
|
||||
// SelectedEasingViewModel = GetNodeEasingViewModel();
|
||||
// }
|
||||
//
|
||||
// public override void OnDeactivate()
|
||||
// {
|
||||
// _node.PropertyChanged -= NodeOnPropertyChanged;
|
||||
// }
|
||||
//
|
||||
// private void NodeOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
// {
|
||||
// if (e.PropertyName == nameof(_node.Storage))
|
||||
// {
|
||||
// _selectedEasingViewModel = GetNodeEasingViewModel();
|
||||
// NotifyOfPropertyChange(nameof(SelectedEasingViewModel));
|
||||
// }
|
||||
// }
|
||||
|
||||
private NodeEasingViewModel GetNodeEasingViewModel()
|
||||
{
|
||||
return EasingViewModels.FirstOrDefault(vm => vm.EasingFunction == _node.Storage);
|
||||
}
|
||||
}
|
||||
@ -15,9 +15,8 @@ public class NodeEasingViewModel : ViewModelBase
|
||||
EasingPoints = new List<Point>();
|
||||
for (int i = 1; i <= 10; i++)
|
||||
{
|
||||
int x = i;
|
||||
double y = Easings.Interpolate(i / 10.0, EasingFunction) * 10;
|
||||
EasingPoints.Add(new Point(x, y));
|
||||
EasingPoints.Add(new Point(i, y));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,8 +2,9 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
||||
xmlns:customViewModels="clr-namespace:Artemis.VisualScripting.Nodes.Easing.CustomViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.VisualScripting.Nodes.Easing.CustomViews.EasingTypeNodeCustomView">
|
||||
<controls:EnumComboBox Classes="condensed" MinWidth="75" Value="{Binding Node.Storage}"/>
|
||||
</UserControl>
|
||||
x:Class="Artemis.VisualScripting.Nodes.Easing.CustomViews.EasingTypeNodeCustomView"
|
||||
x:DataType="customViewModels:EasingTypeNodeCustomViewModel">
|
||||
<ComboBox Classes="condensed" MinWidth="75" Items="{CompiledBinding EasingViewModels}" SelectedItem="{CompiledBinding SelectedEasingViewModel}" />
|
||||
</UserControl>
|
||||
@ -0,0 +1,19 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:customViewModels="clr-namespace:Artemis.VisualScripting.Nodes.Easing.CustomViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.VisualScripting.Nodes.Easing.CustomViews.NodeEasingView"
|
||||
x:DataType="customViewModels:NodeEasingViewModel">
|
||||
<StackPanel Orientation="Horizontal" Spacing="5">
|
||||
<Polyline Stroke="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
StrokeThickness="1"
|
||||
Points="{CompiledBinding EasingPoints}"
|
||||
Stretch="Uniform"
|
||||
Width="15"
|
||||
Height="15"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{CompiledBinding Description}" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -0,0 +1,19 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing.CustomViews
|
||||
{
|
||||
public partial class NodeEasingView : UserControl
|
||||
{
|
||||
public NodeEasingView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,36 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Services.NodeEditor;
|
||||
using Artemis.UI.Shared.Services.NodeEditor.Commands;
|
||||
using Artemis.UI.Shared.VisualScripting;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Validation.Extensions;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Maths.CustomViewModels;
|
||||
|
||||
public class MathExpressionNodeCustomViewModel : CustomNodeViewModel
|
||||
{
|
||||
public MathExpressionNodeCustomViewModel(INode node, INodeScript script) : base(node, script)
|
||||
private readonly MathExpressionNode _node;
|
||||
private readonly INodeEditorService _nodeEditorService;
|
||||
private string? _inputValue;
|
||||
|
||||
public MathExpressionNodeCustomViewModel(MathExpressionNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script)
|
||||
{
|
||||
_node = node;
|
||||
_nodeEditorService = nodeEditorService;
|
||||
|
||||
NodeModified += (_, _) => InputValue = _node.Storage;
|
||||
this.ValidationRule(vm => vm.InputValue, value => _node.IsSyntaxValid(value), value => _node.GetSyntaxErrors(value));
|
||||
}
|
||||
|
||||
public string? InputValue
|
||||
{
|
||||
get => _inputValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _inputValue, value);
|
||||
}
|
||||
|
||||
public void UpdateInputValue()
|
||||
{
|
||||
if (!HasErrors && _node.Storage != InputValue)
|
||||
_nodeEditorService.ExecuteCommand(Script, new UpdateStorage<string>(_node, InputValue));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:customViewModels="clr-namespace:Artemis.VisualScripting.Nodes.Maths.CustomViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.VisualScripting.Nodes.Maths.CustomViews.MathExpressionNodeCustomView"
|
||||
x:DataType="customViewModels:MathExpressionNodeCustomViewModel">
|
||||
<TextBox VerticalAlignment="Top"
|
||||
MinWidth="75"
|
||||
Classes="condensed"
|
||||
Text="{CompiledBinding InputValue}"
|
||||
LostFocus="InputElement_OnLostFocus" />
|
||||
</UserControl>
|
||||
@ -0,0 +1,24 @@
|
||||
using Artemis.VisualScripting.Nodes.Maths.CustomViewModels;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Maths.CustomViews;
|
||||
|
||||
public class MathExpressionNodeCustomView : ReactiveUserControl<MathExpressionNodeCustomViewModel>
|
||||
{
|
||||
public MathExpressionNodeCustomView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
private void InputElement_OnLostFocus(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel?.UpdateInputValue();
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<UserControl x:Class="Artemis.VisualScripting.Nodes.Maths.CustomViews.MathExpressionNodeCustomView"
|
||||
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"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<TextBox VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Stretch"
|
||||
Text="{Binding Node.Storage}" />
|
||||
</UserControl>
|
||||
@ -2,6 +2,7 @@
|
||||
using Artemis.VisualScripting.Nodes.Maths.CustomViewModels;
|
||||
using NoStringEvaluating.Contract;
|
||||
using NoStringEvaluating.Contract.Variables;
|
||||
using NoStringEvaluating.Models.FormulaChecker;
|
||||
using NoStringEvaluating.Models.Values;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Maths;
|
||||
@ -10,14 +11,16 @@ namespace Artemis.VisualScripting.Nodes.Maths;
|
||||
public class MathExpressionNode : Node<string, MathExpressionNodeCustomViewModel>
|
||||
{
|
||||
private readonly INoStringEvaluator _evaluator;
|
||||
private readonly IFormulaChecker _checker;
|
||||
private readonly PinsVariablesContainer _variables;
|
||||
|
||||
#region Constructors
|
||||
|
||||
public MathExpressionNode(INoStringEvaluator evaluator)
|
||||
public MathExpressionNode(INoStringEvaluator evaluator, IFormulaChecker checker)
|
||||
: base("Math Expression", "Outputs the result of a math expression.")
|
||||
{
|
||||
_evaluator = evaluator;
|
||||
_checker = checker;
|
||||
Output = CreateOutputPin<Numeric>();
|
||||
Values = CreateInputPinCollection<Numeric>("Values", 2);
|
||||
Values.PinAdded += (_, _) => SetPinNames();
|
||||
@ -70,6 +73,45 @@ public class MathExpressionNode : Node<string, MathExpressionNodeCustomViewModel
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public bool IsSyntaxValid(string? s)
|
||||
{
|
||||
if (s == null)
|
||||
return true;
|
||||
|
||||
if (!_checker.CheckSyntax(s).Ok)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
_evaluator.CalcNumber(s, _variables);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSyntaxErrors(string? s)
|
||||
{
|
||||
if (s == null)
|
||||
return "";
|
||||
|
||||
CheckFormulaResult? syntaxCheck = _checker.CheckSyntax(s);
|
||||
if (!syntaxCheck.Ok)
|
||||
return string.Join(",", syntaxCheck.Mistakes);
|
||||
|
||||
try
|
||||
{
|
||||
_evaluator.CalcNumber(s, _variables);
|
||||
return "";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PinsVariablesContainer : IVariablesContainer
|
||||
|
||||
@ -68,6 +68,15 @@
|
||||
"Splat": "14.1.45"
|
||||
}
|
||||
},
|
||||
"ReactiveUI.Validation": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.2.1, )",
|
||||
"resolved": "2.2.1",
|
||||
"contentHash": "rhEphZ4ErbGfNtbBQ/tYMsLJYHyLVyqidU+sgZ3kXKbS7QrNoM4j6PPxCwLMKsJUuvVL8JN45xgmB9tSwm7+lg==",
|
||||
"dependencies": {
|
||||
"ReactiveUI": "16.2.6"
|
||||
}
|
||||
},
|
||||
"SkiaSharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.88.0-preview.178, )",
|
||||
@ -538,14 +547,6 @@
|
||||
"Ninject": "3.3.3"
|
||||
}
|
||||
},
|
||||
"ReactiveUI.Validation": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.1",
|
||||
"contentHash": "rhEphZ4ErbGfNtbBQ/tYMsLJYHyLVyqidU+sgZ3kXKbS7QrNoM4j6PPxCwLMKsJUuvVL8JN45xgmB9tSwm7+lg==",
|
||||
"dependencies": {
|
||||
"ReactiveUI": "16.2.6"
|
||||
}
|
||||
},
|
||||
"RGB.NET.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.0-prerelease7",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user