Nodes - Added gradient nodes

Nodes - Added color gradient pin type
Data bindings - Changed color gradient data bindings to now take a color gradient
This commit is contained in:
Robert committed 2022-09-23 21:41:08 +02:00
1 parent 32a444fbeb
commit 9c117d2773
48 files changed
+830 -344

No files matched your search

@@ -25,12 +25,12 @@
</Grid.ContextFlyout>
<!-- Icon column -->
<shared:ArtemisIcon Grid.Column="0"
Icon="{CompiledBinding FeatureInfo.ResolvedIcon}"
Fill="False"
Width="20"
Height="20"
IsVisible="{CompiledBinding LoadException, Converter={x:Static ObjectConverters.IsNull}}" />
<avalonia:MaterialIcon Grid.Column="0"
ToolTip.Tip="{CompiledBinding FeatureType}"
Kind="{CompiledBinding FeatureIcon}"
Width="20"
Height="20"
IsVisible="{CompiledBinding LoadException, Converter={x:Static ObjectConverters.IsNull}}" />
<Button Grid.Column="0"
Classes="AppBarButton icon-button"
@@ -5,11 +5,17 @@ using System.Reactive;
using System.Reactive.Disposables;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.DeviceProviders;
using Artemis.Core.LayerBrushes;
using Artemis.Core.LayerEffects;
using Artemis.Core.Modules;
using Artemis.Core.ScriptingProviders;
using Artemis.Core.Services;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Builders;
using Avalonia.Threading;
using Material.Icons;
using ReactiveUI;
namespace Artemis.UI.Screens.Plugins;
@@ -90,6 +96,42 @@ public class PluginFeatureViewModel : ActivatableViewModelBase
public bool CanRemovePrerequisites => FeatureInfo.PlatformPrerequisites.Any(p => p.UninstallActions.Any());
public bool IsPopupEnabled => CanInstallPrerequisites || CanRemovePrerequisites;
public MaterialIconKind FeatureIcon
{
get
{
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(DeviceProvider)))
return MaterialIconKind.Devices;
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(Module)))
return MaterialIconKind.VectorRectangle;
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerBrushProvider)))
return MaterialIconKind.Brush;
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerEffectProvider)))
return MaterialIconKind.AutoAwesome;
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(ScriptingProvider)))
return MaterialIconKind.Code;
return MaterialIconKind.Extension;
}
}
public string FeatureType
{
get
{
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(DeviceProvider)))
return "Device Provider";
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(Module)))
return "Module";
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerBrushProvider)))
return "Layer Brush";
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerEffectProvider)))
return "Layer Effect";
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(ScriptingProvider)))
return "Scripting Provider";
return "Miscellaneous feature";
}
}
private void ExecuteShowLogsFolder()
{
try
@@ -29,7 +29,22 @@ public class PlaybackViewModel : ActivatableViewModelBase
{
_profileEditorService = profileEditorService;
_settingsService = settingsService;
_repeatTimeline = true;
if (_settingsService.GetSetting("ProfileEditor.RepeatTimeline", true).Value)
{
_repeating = true;
_repeatTimeline = true;
}
else if (_settingsService.GetSetting("ProfileEditor.RepeatSegment", false).Value)
{
_repeating = true;
_repeatSegment = true;
}
else
{
_repeating = false;
_repeatTimeline = true;
}
this.WhenActivated(d =>
{
@@ -42,7 +57,12 @@ public class PlaybackViewModel : ActivatableViewModelBase
_lastUpdate = DateTime.MinValue;
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(60.0 / 1000), DispatcherPriority.Render, Update);
updateTimer.Start();
Disposable.Create(() => updateTimer.Stop()).DisposeWith(d);
Disposable.Create(() =>
{
updateTimer.Stop();
_settingsService.GetSetting("ProfileEditor.RepeatTimeline", true).Value = _repeating && _repeatTimeline;
_settingsService.GetSetting("ProfileEditor.RepeatSegment", false).Value = _repeating && _repeatSegment;
}).DisposeWith(d);
});
PlayFromStart = ReactiveCommand.Create(ExecutePlayFromStart, this.WhenAnyValue(vm => vm.KeyBindingsEnabled));
@@ -21,7 +21,7 @@
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<shared:ArtemisIcon Icon="{CompiledBinding Info.ResolvedIcon}" Width="16" Height="16" Margin="0 0 5 0" />
<shared:ArtemisIcon Icon="{CompiledBinding Plugin.Info.ResolvedIcon}" Width="16" Height="16" Margin="0 0 5 0" />
<TextBlock Text="{CompiledBinding LanguageName}" />
</StackPanel>
</DataTemplate>
@@ -23,7 +23,7 @@
<shared:ArtemisIcon Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="2"
Icon="{CompiledBinding ScriptConfiguration.Script.ScriptingProvider.Info.ResolvedIcon, FallbackValue=QuestionMark}"
Icon="{CompiledBinding ScriptConfiguration.Script.ScriptingProvider.Plugin.Info.ResolvedIcon, FallbackValue=QuestionMark}"
Width="32 "
Height="32"
Margin="0 0 10 0"
@@ -10,7 +10,7 @@ public class ProfileModuleViewModel : ViewModelBase
{
Module = module;
Name = module.Info.Name;
Icon = module.Info.ResolvedIcon ?? MaterialIconKind.QuestionMark.ToString();
Icon = module.Plugin.Info.ResolvedIcon ?? MaterialIconKind.QuestionMark.ToString();
Description = module.Info.Description;
}
@@ -55,10 +55,10 @@
<DataTemplate DataType="skiaSharp:SKColor">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock x:Name="HexDisplay"
Text="{CompiledBinding Converter={StaticResource SKColorToStringConverter}}"
Text="{CompiledBinding Converter={StaticResource SKColorToStringConverter}, Mode=OneWay}"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
FontFamily="Consolas"/>
HorizontalAlignment="Stretch"
FontFamily="Consolas" />
<Border Margin="5 0 0 0"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
@@ -69,22 +69,25 @@
BorderBrush="{DynamicResource ColorPickerButtonOutline}"
CornerRadius="4"
ClipToBounds="True">
<Border CornerRadius="4">
<Border.Background>
<SolidColorBrush Color="{Binding Converter={StaticResource SKColorToColorConverter}}" />
</Border.Background>
</Border>
<Border CornerRadius="4">
<Border.Background>
<SolidColorBrush Color="{Binding Converter={StaticResource SKColorToColorConverter}, Mode=OneWay}" />
</Border.Background>
</Border>
</Border>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="core:ColorGradient">
<TextBlock Text="Color gradient" FontFamily="Consolas" />
</DataTemplate>
<DataTemplate DataType="core:Numeric">
<TextBlock Text="{Binding}" FontFamily="Consolas"/>
<TextBlock Text="{Binding Mode=OneWay}" FontFamily="Consolas" />
</DataTemplate>
<DataTemplate DataType="collections:IList">
<TextBlock Text="{Binding Count, StringFormat='List - {0} item(s)'}" FontFamily="Consolas"/>
<TextBlock Text="{Binding Count, StringFormat='List - {0} item(s)', Mode=OneWay}" FontFamily="Consolas" />
</DataTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="Consolas"/>
<TextBlock Text="{Binding Mode=OneWay}" FontFamily="Consolas" />
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
@@ -51,7 +51,7 @@
<avalonia:MaterialIcon Kind="AlertCircle"></avalonia:MaterialIcon>
</Button>
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="10 0 0 0" Text="{CompiledBinding Node.Name}" ToolTip.Tip="{CompiledBinding Node.Description}"/>
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="10 0 0 0" Text="{CompiledBinding Node.Name}" ToolTip.Tip="{CompiledBinding Node.Description}" />
<Button Grid.Column="2" VerticalAlignment="Center" Classes="icon-button icon-button-small" Margin="5" Command="{CompiledBinding DeleteNode}">
<avalonia:MaterialIcon Kind="Close"></avalonia:MaterialIcon>
@@ -60,21 +60,36 @@
</Border>
</Border>
<Grid Grid.Row="1" ColumnDefinitions="Auto,*,Auto" Margin="4">
<StackPanel Grid.Column="0" IsVisible="{CompiledBinding HasInputPins}">
<Grid Grid.Row="1" RowDefinitions="Auto,Auto,Auto" ColumnDefinitions="Auto,*,Auto" Margin="4">
<ContentControl Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="5"
Content="{CompiledBinding CustomNodeViewModel}"
IsVisible="{CompiledBinding DisplayCustomViewModelAbove}" />
<StackPanel Grid.Row="1" Grid.Column="0" IsVisible="{CompiledBinding HasInputPins}">
<ItemsControl Items="{CompiledBinding InputPinViewModels}" Margin="4 0" />
<ItemsControl Items="{CompiledBinding InputPinCollectionViewModels}" />
</StackPanel>
<ContentControl Grid.Column="1"
Name="CustomViewModelContainer"
<ContentControl Grid.Row="1"
Grid.Column="1"
Content="{CompiledBinding CustomNodeViewModel}"
IsVisible="{CompiledBinding CustomNodeViewModel, Converter={x:Static ObjectConverters.IsNotNull}}" />
VerticalAlignment="{CompiledBinding CustomViewModelVerticalAlignment}"
IsVisible="{CompiledBinding DisplayCustomViewModelBetween}" />
<StackPanel Grid.Column="2" IsVisible="{CompiledBinding HasOutputPins}">
<StackPanel Grid.Row="1" Grid.Column="2" IsVisible="{CompiledBinding HasOutputPins}">
<ItemsControl Items="{CompiledBinding OutputPinViewModels}" Margin="4 0" />
<ItemsControl Items="{CompiledBinding OutputPinCollectionViewModels}" />
</StackPanel>
<ContentControl Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="5"
Content="{CompiledBinding CustomNodeViewModel}"
IsVisible="{CompiledBinding DisplayCustomViewModelBelow}" />
</Grid>
</Grid>
</Border>
@@ -13,6 +13,7 @@ using Artemis.UI.Shared.Services.NodeEditor;
using Artemis.UI.Shared.Services.NodeEditor.Commands;
using Avalonia;
using Avalonia.Controls.Mixins;
using Avalonia.Layout;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
@@ -34,6 +35,10 @@ public class NodeViewModel : ActivatableViewModelBase
private ObservableAsPropertyHelper<bool>? _isStaticNode;
private double _startX;
private double _startY;
private bool _displayCustomViewModelAbove;
private bool _displayCustomViewModelBetween;
private bool _displayCustomViewModelBelow;
private VerticalAlignment _customViewModelVerticalAlignment;
public NodeViewModel(NodeScriptViewModel nodeScriptViewModel, INode node, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService, IWindowService windowService)
{
@@ -132,15 +137,32 @@ public class NodeViewModel : ActivatableViewModelBase
}
});
if (Node is Node coreNode)
CustomNodeViewModel = coreNode.GetCustomViewModel(nodeScriptViewModel.NodeScript);
// Set up the custom node VM if needed
if (Node is ICustomViewModelNode customViewModelNode)
{
CustomNodeViewModel = customViewModelNode.GetCustomViewModel(nodeScriptViewModel.NodeScript);
if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.AbovePins)
DisplayCustomViewModelAbove = true;
else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BelowPins)
DisplayCustomViewModelBelow = true;
else
{
DisplayCustomViewModelBetween = true;
if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop)
CustomViewModelVerticalAlignment = VerticalAlignment.Top;
else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop)
CustomViewModelVerticalAlignment = VerticalAlignment.Center;
else
CustomViewModelVerticalAlignment = VerticalAlignment.Bottom;
}
}
});
}
public bool IsStaticNode => _isStaticNode?.Value ?? true;
public bool HasInputPins => _hasInputPins?.Value ?? false;
public bool HasOutputPins => _hasOutputPins?.Value ?? false;
public NodeScriptViewModel NodeScriptViewModel { get; }
public INode Node { get; }
public ReadOnlyObservableCollection<PinViewModel> InputPinViewModels { get; }
@@ -149,16 +171,40 @@ public class NodeViewModel : ActivatableViewModelBase
public ReadOnlyObservableCollection<PinCollectionViewModel> OutputPinCollectionViewModels { get; }
public ReadOnlyObservableCollection<PinViewModel> PinViewModels { get; }
public bool IsSelected
{
get => _isSelected;
set => RaiseAndSetIfChanged(ref _isSelected, value);
}
public ICustomNodeViewModel? CustomNodeViewModel
{
get => _customNodeViewModel;
set => RaiseAndSetIfChanged(ref _customNodeViewModel, value);
}
public bool IsSelected
public bool DisplayCustomViewModelAbove
{
get => _isSelected;
set => RaiseAndSetIfChanged(ref _isSelected, value);
get => _displayCustomViewModelAbove;
set => RaiseAndSetIfChanged(ref _displayCustomViewModelAbove, value);
}
public bool DisplayCustomViewModelBetween
{
get => _displayCustomViewModelBetween;
set => RaiseAndSetIfChanged(ref _displayCustomViewModelBetween, value);
}
public bool DisplayCustomViewModelBelow
{
get => _displayCustomViewModelBelow;
set => RaiseAndSetIfChanged(ref _displayCustomViewModelBelow, value);
}
public VerticalAlignment CustomViewModelVerticalAlignment
{
get => _customViewModelVerticalAlignment;
set => RaiseAndSetIfChanged(ref _customViewModelVerticalAlignment, value);
}
public ReactiveCommand<Unit, Unit> ShowBrokenState { get; }