Core - Removed scripting providers

Meta - Updated packages
This commit is contained in:
Robert committed 2024-11-14 14:09:51 +01:00
1 parent 7691af95b9
commit 37f973b093
30 files changed
+35 -1441

No files matched your search

@@ -9,7 +9,6 @@ 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;
@@ -99,8 +98,6 @@ public partial class PluginFeatureViewModel : ActivatableViewModelBase
return MaterialIconKind.Brush;
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerEffectProvider)))
return MaterialIconKind.AutoAwesome;
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(ScriptingProvider)))
return MaterialIconKind.Code;
return MaterialIconKind.Extension;
}
}
@@ -117,8 +114,6 @@ public partial class PluginFeatureViewModel : ActivatableViewModelBase
return "Layer Brush";
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(LayerEffectProvider)))
return "Layer Effect";
if (FeatureInfo.FeatureType.IsAssignableTo(typeof(ScriptingProvider)))
return "Scripting Provider";
return "Miscellaneous feature";
}
}
@@ -31,11 +31,6 @@
<avalonia:MaterialIcon Kind="Settings" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="_View Scripts" Command="{CompiledBinding ViewScripts}">
<MenuItem.Icon>
<avalonia:MaterialIcon Kind="BookEdit" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Adapt Profile" Command="{CompiledBinding AdaptProfile}">
<MenuItem.Icon>
<avalonia:MaterialIcon Kind="Magic" />
@@ -8,7 +8,6 @@ using System.Reactive.Linq;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Screens.Scripting;
using Artemis.UI.Screens.Sidebar;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Routing;
@@ -64,7 +63,6 @@ public partial class MenuBarViewModel : ActivatableViewModelBase
AddFolder = ReactiveCommand.Create(ExecuteAddFolder);
AddLayer = ReactiveCommand.Create(ExecuteAddLayer);
ViewProperties = ReactiveCommand.CreateFromTask(ExecuteViewProperties, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
ViewScripts = ReactiveCommand.CreateFromTask(ExecuteViewScripts, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
AdaptProfile = ReactiveCommand.CreateFromTask(ExecuteAdaptProfile, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
ToggleSuspended = ReactiveCommand.Create(ExecuteToggleSuspended, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
DeleteProfile = ReactiveCommand.CreateFromTask(ExecuteDeleteProfile, this.WhenAnyValue(vm => vm.ProfileConfiguration).Select(c => c != null));
@@ -81,7 +79,6 @@ public partial class MenuBarViewModel : ActivatableViewModelBase
public ReactiveCommand<Unit, Unit> AddLayer { get; }
public ReactiveCommand<Unit, Unit> ToggleSuspended { get; }
public ReactiveCommand<Unit, Unit> ViewProperties { get; }
public ReactiveCommand<Unit, Unit> ViewScripts { get; }
public ReactiveCommand<Unit, Unit> AdaptProfile { get; }
public ReactiveCommand<Unit, Unit> DeleteProfile { get; }
public ReactiveCommand<Unit, Unit> ExportProfile { get; }
@@ -133,16 +130,7 @@ public partial class MenuBarViewModel : ActivatableViewModelBase
await _windowService.ShowDialogAsync<ProfileConfigurationEditViewModel, ProfileConfiguration?>(ProfileConfiguration.Category, ProfileConfiguration);
}
private async Task ExecuteViewScripts()
{
if (ProfileConfiguration?.Profile == null)
return;
await _windowService.ShowDialogAsync<ScriptsDialogViewModel, object?>(ProfileConfiguration.Profile);
await _profileEditorService.SaveProfileAsync();
}
private async Task ExecuteAdaptProfile()
{
if (ProfileConfiguration?.Profile == null)
@@ -1,36 +0,0 @@
<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:dialogs="clr-namespace:Artemis.UI.Screens.Scripting.Dialogs"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:scriptingProviders="clr-namespace:Artemis.Core.ScriptingProviders;assembly=Artemis.Core"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Scripting.Dialogs.ScriptConfigurationCreateView"
x:DataType="dialogs:ScriptConfigurationCreateViewModel">
<Panel>
<StackPanel IsVisible="{CompiledBinding ScriptingProviders.Count}">
<TextBlock Classes="label" Margin="0 5">Script name</TextBlock>
<TextBox Watermark="Name" Text="{CompiledBinding ScriptName}" />
<TextBlock Classes="label" Margin="0 5">Script type</TextBlock>
<ComboBox SelectedItem="{CompiledBinding SelectedScriptingProvider}" ItemsSource="{CompiledBinding ScriptingProviders}" HorizontalAlignment="Stretch">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="scriptingProviders:ScriptingProvider">
<StackPanel Orientation="Horizontal">
<shared:ArtemisIcon Icon="{CompiledBinding Plugin.Info.ResolvedIcon}" Width="16" Height="16" Margin="0 0 5 0" />
<TextBlock Text="{CompiledBinding LanguageName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<TextBlock IsVisible="{CompiledBinding !ScriptingProviders.Count}">
You don't have any scripting providers installed or enabled, therefore you cannot use scripts.
</TextBlock>
</Panel>
</UserControl>
@@ -1,13 +0,0 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Scripting.Dialogs;
public partial class ScriptConfigurationCreateView : ReactiveUserControl<ScriptConfigurationCreateViewModel>
{
public ScriptConfigurationCreateView()
{
InitializeComponent();
}
}
@@ -1,40 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using Artemis.Core.ScriptingProviders;
using Artemis.Core.Services;
using Artemis.UI.Shared;
using FluentAvalonia.UI.Controls;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
namespace Artemis.UI.Screens.Scripting.Dialogs;
public partial class ScriptConfigurationCreateViewModel : ContentDialogViewModelBase
{
[Notify] private string? _scriptName;
[Notify] private ScriptingProvider _selectedScriptingProvider;
public ScriptConfigurationCreateViewModel(IScriptingService scriptingService)
{
ScriptingProviders = new List<ScriptingProvider>(scriptingService.ScriptingProviders);
Submit = ReactiveCommand.Create(ExecuteSubmit, ValidationContext.Valid);
_selectedScriptingProvider = ScriptingProviders.First();
this.ValidationRule(vm => vm.ScriptName, s => !string.IsNullOrWhiteSpace(s), "Script name cannot be empty.");
}
public ScriptConfiguration? ScriptConfiguration { get; private set; }
public List<ScriptingProvider> ScriptingProviders { get; }
public ReactiveCommand<Unit, Unit> Submit { get; }
private void ExecuteSubmit()
{
if (ScriptName == null)
return;
ScriptConfiguration = new ScriptConfiguration(SelectedScriptingProvider, ScriptName, ScriptType.Profile);
ContentDialog?.Hide(ContentDialogResult.Primary);
}
}
@@ -1,10 +0,0 @@
<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:dialogs="clr-namespace:Artemis.UI.Screens.Scripting.Dialogs"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Scripting.Dialogs.ScriptConfigurationEditView"
x:DataType="dialogs:ScriptConfigurationEditViewModel">
<TextBox Watermark="Name" Name="Input" Text="{CompiledBinding ScriptName}" />
</UserControl>
@@ -1,19 +0,0 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using ReactiveUI;
namespace Artemis.UI.Screens.Scripting.Dialogs;
public partial class ScriptConfigurationEditView : ReactiveUserControl<ScriptConfigurationEditViewModel>
{
public ScriptConfigurationEditView()
{
InitializeComponent();
this.WhenActivated(_ =>
{
Input.Focus();
Input.SelectAll();
});
}
}
@@ -1,35 +0,0 @@
using System.Reactive;
using Artemis.Core.ScriptingProviders;
using Artemis.UI.Shared;
using FluentAvalonia.UI.Controls;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
namespace Artemis.UI.Screens.Scripting.Dialogs;
public partial class ScriptConfigurationEditViewModel : ContentDialogViewModelBase
{
[Notify] private string? _scriptName;
public ScriptConfigurationEditViewModel(ScriptConfiguration scriptConfiguration)
{
ScriptConfiguration = scriptConfiguration;
Submit = ReactiveCommand.Create(ExecuteSubmit, ValidationContext.Valid);
ScriptName = ScriptConfiguration.Name;
this.ValidationRule(vm => vm.ScriptName, s => !string.IsNullOrWhiteSpace(s), "Script name cannot be empty.");
}
public ScriptConfiguration ScriptConfiguration { get; }
public ReactiveCommand<Unit, Unit> Submit { get; }
private void ExecuteSubmit()
{
if (ScriptName == null)
return;
ScriptConfiguration.Name = ScriptName;
ContentDialog?.Hide(ContentDialogResult.Primary);
}
}
@@ -1,63 +0,0 @@
using System.Reactive;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.ScriptingProviders;
using Artemis.Core.Services;
using Artemis.UI.Screens.Scripting.Dialogs;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using FluentAvalonia.UI.Controls;
using ReactiveUI;
using ContentDialogButton = Artemis.UI.Shared.Services.Builders.ContentDialogButton;
namespace Artemis.UI.Screens.Scripting;
public class ScriptConfigurationViewModel : ActivatableViewModelBase
{
private readonly IScriptingService _scriptingService;
private readonly IWindowService _windowService;
public ScriptConfigurationViewModel(ScriptConfiguration scriptConfiguration, IScriptingService scriptingService, IWindowService windowService)
{
_scriptingService = scriptingService;
_windowService = windowService;
ScriptConfiguration = scriptConfiguration;
Script = ScriptConfiguration.Script;
EditScriptConfiguration = ReactiveCommand.CreateFromTask<ScriptConfiguration>(ExecuteEditScriptConfiguration);
ToggleSuspended = ReactiveCommand.Create(() => ScriptConfiguration.IsSuspended = !ScriptConfiguration.IsSuspended);
}
public ScriptConfigurationViewModel(Profile profile, ScriptConfiguration scriptConfiguration, IScriptingService scriptingService, IWindowService windowService)
: this(scriptConfiguration, scriptingService, windowService)
{
Profile = profile;
}
public Profile? Profile { get; }
public ScriptConfiguration ScriptConfiguration { get; }
public Script? Script { get; }
public ReactiveCommand<ScriptConfiguration, Unit> EditScriptConfiguration { get; }
public ReactiveCommand<Unit, bool> ToggleSuspended { get; }
private async Task ExecuteEditScriptConfiguration(ScriptConfiguration scriptConfiguration)
{
ContentDialogResult contentDialogResult = await _windowService.CreateContentDialog()
.WithTitle("Edit script")
.WithViewModel(out ScriptConfigurationEditViewModel vm, scriptConfiguration)
.WithCloseButtonText("Cancel")
.HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Submit))
.HavingSecondaryButton(b => b.WithText("Delete"))
.WithDefaultButton(ContentDialogButton.Primary)
.ShowAsync();
// Remove the script if the delete button was pressed
if (contentDialogResult == ContentDialogResult.Secondary)
{
if (Profile != null)
_scriptingService.RemoveScript(scriptConfiguration, Profile);
else
_scriptingService.RemoveScript(scriptConfiguration);
}
}
}
@@ -1,90 +0,0 @@
<windowing:AppWindow 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:scripting="clr-namespace:Artemis.UI.Screens.Scripting"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Scripting.ScriptsDialogView"
x:DataType="scripting:ScriptsDialogViewModel"
Icon="/Assets/Images/Logo/application.ico"
Title="Artemis | Scripts"
Width="1200"
Height="750">
<DockPanel>
<ScrollViewer DockPanel.Dock="Left" VerticalScrollBarVisibility="Auto" Width="300" Margin="10">
<StackPanel>
<ListBox ItemsSource="{CompiledBinding ScriptConfigurations}" SelectedItem="{CompiledBinding SelectedScript}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type scripting:ScriptConfigurationViewModel}">
<Grid ColumnDefinitions="Auto,*,Auto,Auto" RowDefinitions="*,*" Margin="4">
<shared:ArtemisIcon Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="2"
Icon="{CompiledBinding ScriptConfiguration.Script.ScriptingProvider.Plugin.Info.ResolvedIcon, FallbackValue=QuestionMark}"
Width="32 "
Height="32"
Margin="0 0 10 0"
VerticalAlignment="Center" />
<TextBlock Grid.Row="0"
Grid.Column="1"
VerticalAlignment="Center"
Text="{CompiledBinding ScriptConfiguration.Name}"
IsVisible="{CompiledBinding !ScriptConfiguration.HasChanges}"
TextTrimming="CharacterEllipsis" />
<StackPanel Grid.Row="0"
Grid.Column="1"
VerticalAlignment="Center"
Orientation="Horizontal"
IsVisible="{CompiledBinding ScriptConfiguration.HasChanges}">
<TextBlock Text="{CompiledBinding ScriptConfiguration.Name}" FontWeight="Bold"></TextBlock>
<TextBlock Text="*"></TextBlock>
</StackPanel>
<TextBlock Grid.Row="1"
Grid.Column="1"
Text="{CompiledBinding ScriptConfiguration.Script.ScriptingProvider.LanguageName, FallbackValue='Unknown scripting provider'}"
Classes="subtitle"
FontSize="11"
VerticalAlignment="Center" />
<Button Classes="icon-button icon-button-small"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="2"
ToolTip.Tip="Edit script"
HorizontalAlignment="Right"
Command="{CompiledBinding EditScriptConfiguration}"
CommandParameter="{CompiledBinding ScriptConfiguration}"
Margin="0 0 2 0">
<avalonia:MaterialIcon Kind="Cog" />
</Button>
<Button Classes="icon-button icon-button-small"
Command="{CompiledBinding ToggleSuspended}"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="3"
ToolTip.Tip="Suspend/resume script">
<Panel>
<avalonia:MaterialIcon Kind="EyeOff" IsVisible="{CompiledBinding ScriptConfiguration.IsSuspended}" />
<avalonia:MaterialIcon Kind="Eye" IsVisible="{CompiledBinding !ScriptConfiguration.IsSuspended}" />
</Panel>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Add new script"
Margin="10"
HorizontalAlignment="Stretch"
Command="{CompiledBinding AddScriptConfiguration}" />
</StackPanel>
</ScrollViewer>
<Border DockPanel.Dock="Top" Classes="router-container" Margin="0 10 0 0">
<ContentControl Content="{CompiledBinding ScriptEditorViewModel}" />
</Border>
</DockPanel>
</windowing:AppWindow>
@@ -1,34 +0,0 @@
using System.ComponentModel;
using Artemis.UI.Shared;
using Avalonia;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Scripting;
public partial class ScriptsDialogView : ReactiveAppWindow<ScriptsDialogViewModel>
{
private bool _canClose;
public ScriptsDialogView()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
Closing += OnClosing;
}
private async void OnClosing(object? sender, CancelEventArgs e)
{
if (_canClose)
return;
e.Cancel = true;
if (ViewModel == null || await ViewModel.CanClose())
{
_canClose = true;
Close();
}
}
}
@@ -1,142 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.ScriptingProviders;
using Artemis.Core.Services;
using Artemis.UI.DryIoc.Factories;
using Artemis.UI.Screens.Scripting.Dialogs;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Builders;
using DynamicData;
using DynamicData.Binding;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
namespace Artemis.UI.Screens.Scripting;
public partial class ScriptsDialogViewModel : DialogViewModelBase<object?>
{
private readonly Dictionary<ScriptingProvider, IScriptEditorViewModel> _providerViewModels = new();
private readonly IScriptingService _scriptingService;
private readonly IWindowService _windowService;
private ObservableAsPropertyHelper<bool>? _hasScripts;
[Notify] private ReadOnlyObservableCollection<ScriptConfigurationViewModel> _scriptConfigurations;
[Notify] private IScriptEditorViewModel? _scriptEditorViewModel;
[Notify] private ScriptConfigurationViewModel? _selectedScript;
public ScriptsDialogViewModel(IScriptingService scriptingService, IWindowService windowService, IProfileService profileService, IScriptVmFactory scriptVmFactory)
{
_scriptingService = scriptingService;
_windowService = windowService;
ScriptType = ScriptType.Global;
ScriptingProviders = new List<ScriptingProvider>(scriptingService.ScriptingProviders);
AddScriptConfiguration = ReactiveCommand.CreateFromTask(ExecuteAddScriptConfiguration, Observable.Return(ScriptingProviders.Any()));
this.WhenAnyValue(vm => vm.SelectedScript).Subscribe(s => SetupScriptEditor(s?.ScriptConfiguration));
_scriptConfigurations = new ReadOnlyObservableCollection<ScriptConfigurationViewModel>(new ObservableCollection<ScriptConfigurationViewModel>());
// TODO: When not bound to a profile, base the contents of the UI on the ScriptingService
}
public ScriptsDialogViewModel(Profile profile, IScriptingService scriptingService, IWindowService windowService, IProfileService profileService, IScriptVmFactory scriptVmFactory)
: this(scriptingService, windowService, profileService, scriptVmFactory)
{
ScriptType = ScriptType.Profile;
Profile = profile;
this.WhenActivated(d =>
{
_hasScripts = Profile.ScriptConfigurations.ToObservableChangeSet()
.Count()
.Select(c => c > 0)
.ToProperty(this, vm => vm.HasScripts)
.DisposeWith(d);
Profile.ScriptConfigurations.ToObservableChangeSet()
.Transform(c => scriptVmFactory.ScriptConfigurationViewModel(Profile, c))
.Bind(out ReadOnlyObservableCollection<ScriptConfigurationViewModel> scriptConfigurationViewModels)
.Subscribe()
.DisposeWith(d);
ScriptConfigurations = scriptConfigurationViewModels;
SelectedScript = ScriptConfigurations.FirstOrDefault();
Disposable.Create(() => profileService.SaveProfile(Profile, false)).DisposeWith(d);
});
}
public ScriptType ScriptType { get; }
public List<ScriptingProvider> ScriptingProviders { get; }
public Profile? Profile { get; }
public bool HasScripts => _hasScripts?.Value ?? false;
public ReactiveCommand<Unit, Unit> AddScriptConfiguration { get; }
public async Task<bool> CanClose()
{
if (!ScriptConfigurations.Any(s => s.ScriptConfiguration.HasChanges))
return true;
bool result = await _windowService.ShowConfirmContentDialog("Discard changes", "One or more scripts still have pending changes, do you want to discard them?");
if (!result)
return false;
foreach (ScriptConfigurationViewModel scriptConfigurationViewModel in ScriptConfigurations)
scriptConfigurationViewModel.ScriptConfiguration.DiscardPendingChanges();
return true;
}
private void SetupScriptEditor(ScriptConfiguration? scriptConfiguration)
{
if (scriptConfiguration == null)
{
ScriptEditorViewModel = null;
return;
}
// The script is null if the provider is missing
if (scriptConfiguration.Script == null)
{
ScriptEditorViewModel = null;
return;
}
if (!_providerViewModels.TryGetValue(scriptConfiguration.Script.ScriptingProvider, out IScriptEditorViewModel? viewModel))
{
viewModel = scriptConfiguration.Script.ScriptingProvider.CreateScriptEditor(ScriptType);
_providerViewModels.Add(scriptConfiguration.Script.ScriptingProvider, viewModel);
}
ScriptEditorViewModel = viewModel;
ScriptEditorViewModel.ChangeScript(scriptConfiguration.Script);
}
private async Task ExecuteAddScriptConfiguration()
{
await _windowService.CreateContentDialog()
.WithTitle("Add script")
.WithViewModel(out ScriptConfigurationCreateViewModel vm)
.WithCloseButtonText("Cancel")
.HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Submit))
.WithDefaultButton(ContentDialogButton.Primary)
.ShowAsync();
if (vm.ScriptConfiguration == null)
return;
// Add the script to the profile and instantiate it
if (Profile != null)
_scriptingService.AddScript(vm.ScriptConfiguration, Profile);
else
_scriptingService.AddScript(vm.ScriptConfiguration);
// Select the new script
SelectedScript = ScriptConfigurations.LastOrDefault();
}
}