mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
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:
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; }
|
||||
|
||||
Reference in new issue
Block a user