Nodes - Added static color node

This commit is contained in:
Robert committed 2022-03-28 23:33:36 +02:00
1 parent 28534cb57a
commit 69b881b044
12 files changed
+203 -67

No files matched your search

@@ -1,11 +1,51 @@
using Artemis.Core;
using Artemis.UI.Shared.Services.NodeEditor;
using Artemis.UI.Shared.Services.NodeEditor.Commands;
using Artemis.UI.Shared.VisualScripting;
using ReactiveUI;
using SkiaSharp;
namespace Artemis.VisualScripting.Nodes.Color.CustomViewModels;
public class StaticSKColorValueNodeCustomViewModel : CustomNodeViewModel
{
public StaticSKColorValueNodeCustomViewModel(StaticSKColorValueNode node, INodeScript script) : base(node, script)
private readonly StaticSKColorValueNode _node;
private readonly INodeEditorService _nodeEditorService;
private bool _applyChanges;
private SKColor? _currentValue;
public StaticSKColorValueNodeCustomViewModel(StaticSKColorValueNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script)
{
_node = node;
_nodeEditorService = nodeEditorService;
_applyChanges = true;
NodeModified += (_, _) => CurrentValue = _node.Storage;
CurrentValue = _node.Storage;
}
public SKColor? CurrentValue
{
get => _currentValue;
set
{
if (_applyChanges && value != _node.Storage)
_nodeEditorService.ExecuteCommand(Script, new UpdateStorage<SKColor>(_node, value ?? SKColor.Empty));
this.RaiseAndSetIfChanged(ref _currentValue, value);
}
}
public void PauseUpdating()
{
_applyChanges = false;
}
public void ResumeUpdating()
{
_applyChanges = true;
SKColor updatedValue = CurrentValue ?? SKColor.Empty;
if (updatedValue != _node.Storage)
_nodeEditorService.ExecuteCommand(Script, new UpdateStorage<SKColor>(_node, updatedValue));
}
}
@@ -0,0 +1,30 @@
<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:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:customViewModels="clr-namespace:Artemis.VisualScripting.Nodes.Color.CustomViewModels"
xmlns:behaviors="clr-namespace:Artemis.UI.Shared.Behaviors;assembly=Artemis.UI.Shared"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.VisualScripting.Nodes.Color.CustomViews.StaticSKColorValueNodeCustomView"
x:DataType="customViewModels:StaticSKColorValueNodeCustomViewModel">
<UserControl.Resources>
<converters:SKColorToStringConverter x:Key="SKColorToStringConverter" />
<converters:SKColorToColor2Converter x:Key="SKColorToColor2Converter" />
</UserControl.Resources>
<Grid Height="24" ColumnDefinitions="*" Width="110">
<TextBox Classes="condensed"
Watermark="#00000000"
Padding="2 2 30 2">
<Interaction.Behaviors>
<behaviors:LostFocusTextBoxBindingBehavior Text="{CompiledBinding CurrentValue, Converter={StaticResource SKColorToStringConverter}}"/>
</Interaction.Behaviors>
</TextBox>
<controls:ColorPickerButton Classes="contained-color-picker-button"
Color="{CompiledBinding CurrentValue, Converter={StaticResource SKColorToColor2Converter}}"
ShowAcceptDismissButtons="False"
FlyoutOpened="ColorPickerButton_OnFlyoutOpened"
FlyoutClosed="ColorPickerButton_OnFlyoutClosed" />
</Grid>
</UserControl>
@@ -0,0 +1,29 @@
using Artemis.VisualScripting.Nodes.Color.CustomViewModels;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using FluentAvalonia.UI.Controls;
namespace Artemis.VisualScripting.Nodes.Color.CustomViews;
public class StaticSKColorValueNodeCustomView : ReactiveUserControl<StaticSKColorValueNodeCustomViewModel>
{
public StaticSKColorValueNodeCustomView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void ColorPickerButton_OnFlyoutOpened(ColorPickerButton sender, EventArgs args)
{
ViewModel?.PauseUpdating();
}
private void ColorPickerButton_OnFlyoutClosed(ColorPickerButton sender, EventArgs args)
{
ViewModel?.ResumeUpdating();
}
}
@@ -1,15 +0,0 @@
<UserControl x:Class="Artemis.VisualScripting.Nodes.Color.CustomViews.StaticSKColorValueNodeCustomView"
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:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<shared:SKColorToColorConverter x:Key="SKColorToColorConverter" />
</UserControl.Resources>
<shared:ColorPicker VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Color="{Binding Node.Storage, Converter={StaticResource SKColorToColorConverter}}" />
</UserControl>
@@ -13,6 +13,7 @@ public class StaticSKColorValueNode : Node<SKColor, StaticSKColorValueNodeCustom
: base("Color", "Outputs a configurable color value.")
{
Output = CreateOutputPin<SKColor>();
Storage = new SKColor(255, 0, 0);
}
#endregion
@@ -1,9 +1,14 @@
using Artemis.Core;
using System.Reactive.Linq;
using Artemis.Core;
using Artemis.Core.Events;
using Artemis.UI.Shared.Services.NodeEditor;
using Artemis.UI.Shared.Services.NodeEditor.Commands;
using Artemis.UI.Shared.VisualScripting;
using Avalonia.Controls.Mixins;
using ReactiveUI;
using ReactiveUI.Validation.Components.Abstractions;
using ReactiveUI.Validation.Extensions;
using ReactiveUI.Validation.Helpers;
namespace Artemis.VisualScripting.Nodes.Maths.CustomViewModels;
@@ -18,8 +23,30 @@ public class MathExpressionNodeCustomViewModel : CustomNodeViewModel
_node = node;
_nodeEditorService = nodeEditorService;
NodeModified += (_, _) => InputValue = _node.Storage;
this.ValidationRule(vm => vm.InputValue, value => _node.IsSyntaxValid(value), value => _node.GetSyntaxErrors(value));
this.WhenActivated(d =>
{
Observable.FromEventPattern<SingleValueEventArgs<IPin>>(x => _node.Values.PinAdded += x, x => _node.Values.PinAdded -= x)
.Subscribe(_ =>
{
string? old = InputValue;
InputValue = null;
InputValue = old;
})
.DisposeWith(d);
Observable.FromEventPattern<SingleValueEventArgs<IPin>>(x => _node.Values.PinRemoved += x, x => _node.Values.PinRemoved -= x)
.Subscribe(_ =>
{
string? old = InputValue;
InputValue = null;
InputValue = old;
})
.DisposeWith(d);
});
NodeModified += (_, _) => InputValue = _node.Storage;
InputValue = _node.Storage;
}
public string? InputValue
@@ -30,7 +57,8 @@ public class MathExpressionNodeCustomViewModel : CustomNodeViewModel
public void UpdateInputValue()
{
if (!HasErrors && _node.Storage != InputValue)
// The value could be invalid but that's ok, we still want to save it
if (_node.Storage != InputValue)
_nodeEditorService.ExecuteCommand(Script, new UpdateStorage<string>(_node, InputValue));
}
}
@@ -43,8 +43,15 @@ public class MathExpressionNode : Node<string, MathExpressionNodeCustomViewModel
public override void Evaluate()
{
if (Storage != null)
Output.Value = new Numeric(_evaluator.CalcNumber(Storage, _variables));
try
{
if (Storage != null)
Output.Value = new Numeric(_evaluator.CalcNumber(Storage, _variables));
}
catch
{
Output.Value = new Numeric(0);
}
}
private void SetPinNames()