mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Nodes - Added easing nodes
Nodes - Update data model node to honor profile editor settings
This commit is contained in:
parent
9d6a61f1e5
commit
64b78cbf9e
@ -19,7 +19,7 @@
|
||||
<DataTemplate x:Key="DataModelDataTemplate">
|
||||
<Control x:Name="TemplateControl" Focusable="False" Template="{StaticResource DataModelSelectionTemplate}" />
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding Data.ShowDataModelValues.Value, Source={StaticResource DataContextProxy}}" Value="True">
|
||||
<DataTrigger Binding="{Binding Data.ShowDataModelValues, Source={StaticResource DataContextProxy}}" Value="True">
|
||||
<Setter TargetName="TemplateControl" Property="Template" Value="{StaticResource DataModelSelectionTemplateWithValues}" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
|
||||
@ -247,7 +247,7 @@ namespace Artemis.UI.Shared
|
||||
object? value = Parent == null || Parent.IsRootViewModel ? DataModel : DataModelPath?.GetValue();
|
||||
if (value is DataModel dataModel)
|
||||
{
|
||||
foreach (var (key, dynamicChild) in dataModel.DynamicChildren)
|
||||
foreach (string key in dataModel.DynamicChildren.Keys.ToList())
|
||||
{
|
||||
string childPath = AppendToPath(key);
|
||||
if (Children.Any(c => c.Path != null && c.Path.Equals(childPath)))
|
||||
|
||||
@ -126,8 +126,8 @@ namespace Artemis.UI.Services
|
||||
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(int), new SKColor(0xFF32CD32));
|
||||
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(double), new SKColor(0xFF1E90FF));
|
||||
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(float), new SKColor(0xFFFF7C00));
|
||||
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(SKColor), new SKColor(0xFF7630C7));
|
||||
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(IList), new SKColor(0xFFC842FF));
|
||||
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(SKColor), new SKColor(0xFFAD3EED));
|
||||
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(IList), new SKColor(0xFFED3E61));
|
||||
|
||||
foreach (Type nodeType in typeof(SumIntegersNode).Assembly.GetTypes().Where(t => typeof(INode).IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract && !t.IsInterface))
|
||||
_nodeService.RegisterNodeType(Constants.CorePlugin, nodeType);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System.ComponentModel;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.CustomViewModels
|
||||
@ -10,11 +11,17 @@ namespace Artemis.VisualScripting.Nodes.CustomViewModels
|
||||
private readonly DataModelNode _node;
|
||||
private BindableCollection<Module> _modules;
|
||||
|
||||
public DataModelNodeCustomViewModel(DataModelNode node) : base(node)
|
||||
public DataModelNodeCustomViewModel(DataModelNode node, ISettingsService settingsService) : base(node)
|
||||
{
|
||||
_node = node;
|
||||
|
||||
ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true);
|
||||
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
|
||||
}
|
||||
|
||||
public PluginSetting<bool> ShowFullPaths { get; }
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
|
||||
public BindableCollection<Module> Modules
|
||||
{
|
||||
get => _modules;
|
||||
@ -41,7 +48,7 @@ namespace Artemis.VisualScripting.Nodes.CustomViewModels
|
||||
_node.UpdateOutputPin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void OnActivate()
|
||||
{
|
||||
if (Modules != null)
|
||||
|
||||
@ -8,5 +8,9 @@
|
||||
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<controls:DataModelPicker DataModelPath="{Binding DataModelPath}" Modules="{Binding Modules}" ButtonBrush="#434343"/>
|
||||
<controls:DataModelPicker DataModelPath="{Binding DataModelPath}"
|
||||
Modules="{Binding Modules}"
|
||||
ShowFullPath="{Binding ShowFullPaths.Value}"
|
||||
ShowDataModelValues="{Binding ShowDataModelValues.Value}"
|
||||
ButtonBrush="#434343"/>
|
||||
</UserControl>
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.Nodes.CustomViewModels;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing.CustomViewModels
|
||||
{
|
||||
public class EasingTypeNodeCustomViewModel : CustomNodeViewModel
|
||||
{
|
||||
private readonly EasingTypeNode _node;
|
||||
private NodeEasingViewModel _selectedEasingViewModel;
|
||||
|
||||
public EasingTypeNodeCustomViewModel(EasingTypeNode node) : base(node)
|
||||
{
|
||||
_node = node;
|
||||
EasingViewModels = new BindableCollection<NodeEasingViewModel>(Enum.GetValues(typeof(Easings.Functions))
|
||||
.Cast<Easings.Functions>()
|
||||
.Select(e => new NodeEasingViewModel(e)));
|
||||
}
|
||||
|
||||
public BindableCollection<NodeEasingViewModel> EasingViewModels { get; }
|
||||
|
||||
public NodeEasingViewModel SelectedEasingViewModel
|
||||
{
|
||||
get => _selectedEasingViewModel;
|
||||
set
|
||||
{
|
||||
_selectedEasingViewModel = value;
|
||||
_node.Storage = _selectedEasingViewModel.EasingFunction;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnActivate()
|
||||
{
|
||||
_node.PropertyChanged += NodeOnPropertyChanged;
|
||||
SelectedEasingViewModel = EasingViewModels.FirstOrDefault(vm => vm.EasingFunction == _node.EasingFunction);
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
_node.PropertyChanged -= NodeOnPropertyChanged;
|
||||
}
|
||||
|
||||
private void NodeOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(Node.Storage))
|
||||
{
|
||||
_selectedEasingViewModel = EasingViewModels.FirstOrDefault(vm => vm.EasingFunction == _node.EasingFunction);
|
||||
NotifyOfPropertyChange(nameof(SelectedEasingViewModel));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Humanizer;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing.CustomViewModels
|
||||
{
|
||||
public class NodeEasingViewModel : PropertyChangedBase
|
||||
{
|
||||
public NodeEasingViewModel(Easings.Functions easingFunction)
|
||||
{
|
||||
EasingFunction = easingFunction;
|
||||
Description = easingFunction.Humanize();
|
||||
|
||||
EasingPoints = new PointCollection();
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
public Easings.Functions EasingFunction { get; }
|
||||
public PointCollection EasingPoints { get; }
|
||||
public string Description { get; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
<UserControl x:Class="Artemis.VisualScripting.Nodes.Easing.CustomViews.EasingTypeNodeCustomView"
|
||||
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.Easing.CustomViews"
|
||||
xmlns:viewModels="clr-namespace:Artemis.VisualScripting.Nodes.Easing.CustomViewModels"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<ComboBox VerticalAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
ItemsSource="{Binding EasingViewModels}"
|
||||
SelectedItem="{Binding SelectedEasingViewModel}">
|
||||
<ComboBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ComboBox.ItemsPanel>
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type viewModels:NodeEasingViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Polyline Stroke="{DynamicResource MaterialDesignBody}"
|
||||
StrokeThickness="1.5"
|
||||
Points="{Binding EasingPoints}"
|
||||
Stretch="Uniform"
|
||||
Width="14"
|
||||
Height="14"
|
||||
Margin="0 0 10 0" />
|
||||
<TextBlock Text="{Binding Description}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
</UserControl>
|
||||
68
src/Artemis.VisualScripting/Nodes/Easing/DoubleEasingNode.cs
Normal file
68
src/Artemis.VisualScripting/Nodes/Easing/DoubleEasingNode.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing
|
||||
{
|
||||
[Node("Double Easing", "Outputs an eased double value")]
|
||||
public class DoubleEasingNode : Node
|
||||
{
|
||||
private DateTime _lastEvaluate = DateTime.MinValue;
|
||||
private float _progress;
|
||||
private double _currentValue;
|
||||
private double _sourceValue;
|
||||
private double _targetValue;
|
||||
|
||||
public DoubleEasingNode() : base("Double Easing", "Outputs an eased double value")
|
||||
{
|
||||
Input = CreateInputPin<double>();
|
||||
EasingTime = CreateInputPin<float>("delay");
|
||||
EasingFunction = CreateInputPin<Easings.Functions>("function");
|
||||
|
||||
Output = CreateOutputPin<double>();
|
||||
}
|
||||
|
||||
public InputPin<double> Input { get; set; }
|
||||
public InputPin<float> EasingTime { get; set; }
|
||||
public InputPin<Easings.Functions> EasingFunction { get; set; }
|
||||
|
||||
public OutputPin<double> Output { get; set; }
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
// If the value changed reset progress
|
||||
if (Math.Abs(_targetValue - Input.Value) > 0.001f)
|
||||
{
|
||||
_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 = eased;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
src/Artemis.VisualScripting/Nodes/Easing/EasingTypeNode.cs
Normal file
22
src/Artemis.VisualScripting/Nodes/Easing/EasingTypeNode.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.Nodes.Easing.CustomViewModels;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing
|
||||
{
|
||||
[Node("Easing Type", "Outputs a selectable easing type.")]
|
||||
public class EasingTypeNode : Node<EasingTypeNodeCustomViewModel>
|
||||
{
|
||||
public EasingTypeNode() : base("Easing Type", "Outputs a selectable easing type.")
|
||||
{
|
||||
Output = CreateOutputPin<Easings.Functions>();
|
||||
}
|
||||
|
||||
public OutputPin<Easings.Functions> Output { get; }
|
||||
public Easings.Functions EasingFunction => Storage as Easings.Functions? ?? Easings.Functions.Linear;
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
Output.Value = EasingFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/Artemis.VisualScripting/Nodes/Easing/FloatEasingNode.cs
Normal file
68
src/Artemis.VisualScripting/Nodes/Easing/FloatEasingNode.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing
|
||||
{
|
||||
[Node("Float Easing", "Outputs an eased float value")]
|
||||
public class FloatEasingNode : Node
|
||||
{
|
||||
private DateTime _lastEvaluate = DateTime.MinValue;
|
||||
private float _progress;
|
||||
private float _currentValue;
|
||||
private float _sourceValue;
|
||||
private float _targetValue;
|
||||
|
||||
public FloatEasingNode() : base("Float Easing", "Outputs an eased float value")
|
||||
{
|
||||
Input = CreateInputPin<float>();
|
||||
EasingTime = CreateInputPin<float>("delay");
|
||||
EasingFunction = CreateInputPin<Easings.Functions>("function");
|
||||
|
||||
Output = CreateOutputPin<float>();
|
||||
}
|
||||
|
||||
public InputPin<float> Input { get; set; }
|
||||
public InputPin<float> EasingTime { get; set; }
|
||||
public InputPin<Easings.Functions> EasingFunction { get; set; }
|
||||
|
||||
public OutputPin<float> Output { get; set; }
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
// If the value changed reset progress
|
||||
if (Math.Abs(_targetValue - Input.Value) > 0.001f)
|
||||
{
|
||||
_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 = (float) eased;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/Artemis.VisualScripting/Nodes/Easing/IntEasingNode.cs
Normal file
68
src/Artemis.VisualScripting/Nodes/Easing/IntEasingNode.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing
|
||||
{
|
||||
[Node("Integer Easing", "Outputs an eased integer value")]
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Easing
|
||||
{
|
||||
[Node("Color Easing", "Outputs an eased color value")]
|
||||
public class SKColorEasingNode : Node
|
||||
{
|
||||
private DateTime _lastEvaluate = DateTime.MinValue;
|
||||
private float _progress;
|
||||
private SKColor _currentValue;
|
||||
private SKColor _sourceValue;
|
||||
private SKColor _targetValue;
|
||||
|
||||
public SKColorEasingNode() : base("Color Easing", "Outputs an eased color value")
|
||||
{
|
||||
Input = CreateInputPin<SKColor>();
|
||||
EasingTime = CreateInputPin<float>("delay");
|
||||
EasingFunction = CreateInputPin<Easings.Functions>("function");
|
||||
|
||||
Output = CreateOutputPin<SKColor>();
|
||||
}
|
||||
|
||||
public InputPin<SKColor> Input { get; set; }
|
||||
public InputPin<float> EasingTime { get; set; }
|
||||
public InputPin<Easings.Functions> EasingFunction { get; set; }
|
||||
|
||||
public OutputPin<SKColor> 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);
|
||||
_currentValue = _sourceValue.Interpolate(_targetValue, (float) Easings.Interpolate(_progress, EasingFunction.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user