From 4a69baebb72bdbabb65d06b889c8b7e8a80298a7 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 21 Jun 2021 00:44:57 +0200 Subject: [PATCH] Scripting - Added script creation --- src/Artemis.Core/Services/ScriptingService.cs | 31 ------- .../Services/Storage/ProfileService.cs | 2 +- .../ScriptEditorViewModel.cs | 4 +- .../Ninject/Factories/IVMFactory.cs | 13 ++- .../ProfileEditor/ProfileEditorView.xaml | 11 ++- .../ProfileEditor/ProfileEditorViewModel.cs | 27 +++++- .../ScriptConfigurationCreateView.xaml | 61 +++++++++++++ .../ScriptConfigurationCreateViewModel.cs | 57 ++++++++++++ .../Scripting/ScriptConfigurationViewModel.cs | 52 +++++++++++ .../Screens/Scripting/ScriptsDialogView.xaml | 90 +++++++++++++++++++ .../Scripting/ScriptsDialogViewModel.cs | 67 ++++++++++++-- 11 files changed, 366 insertions(+), 49 deletions(-) create mode 100644 src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateView.xaml create mode 100644 src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateViewModel.cs create mode 100644 src/Artemis.UI/Screens/Scripting/ScriptConfigurationViewModel.cs create mode 100644 src/Artemis.UI/Screens/Scripting/ScriptsDialogView.xaml diff --git a/src/Artemis.Core/Services/ScriptingService.cs b/src/Artemis.Core/Services/ScriptingService.cs index 93f18d856..227ce85d8 100644 --- a/src/Artemis.Core/Services/ScriptingService.cs +++ b/src/Artemis.Core/Services/ScriptingService.cs @@ -179,41 +179,10 @@ namespace Artemis.Core.Services public interface IScriptingService : IArtemisService { - /// - /// Gets a read only collection of all active global scripts - /// ReadOnlyCollection GlobalScripts { get; } - - /// - /// Attempts to create an instance of a global script configured in the provided - /// - /// The script configuration of the script to instantiate - /// An instance of the script if the script provider was found; otherwise GlobalScript? CreateScriptInstance(ScriptConfiguration scriptConfiguration); - - /// - /// Attempts to create an instance of a profile script configured in the provided - /// - /// The profile the script is bound to - /// The script configuration of the script to instantiate - /// An instance of the script if the script provider was found; otherwise ProfileScript? CreateScriptInstance(Profile profile, ScriptConfiguration scriptConfiguration); - - /// - /// Attempts to create an instance of a layer script configured in the provided - /// - /// The layer the script is bound to - /// The script configuration of the script to instantiate - /// An instance of the script if the script provider was found; otherwise LayerScript? CreateScriptInstance(Layer layer, ScriptConfiguration scriptConfiguration); - - /// - /// Attempts to create an instance of a layer property script configured in the provided - /// - /// - /// The layer property the script is bound to - /// The script configuration of the script to instantiate - /// An instance of the script if the script provider was found; otherwise PropertyScript? CreateScriptInstance(ILayerProperty layerProperty, ScriptConfiguration scriptConfiguration); } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs index f7c359390..65cc8c54b 100644 --- a/src/Artemis.Core/Services/Storage/ProfileService.cs +++ b/src/Artemis.Core/Services/Storage/ProfileService.cs @@ -532,7 +532,7 @@ namespace Artemis.Core.Services if (markAsFreshImport) profileEntity.IsFreshImport = true; - if (_profileRepository.Get(profileEntity.Id) != null) + if (_profileRepository.Get(profileEntity.Id) == null) _profileRepository.Add(profileEntity); else throw new ArtemisCoreException($"Cannot import this profile without {nameof(makeUnique)} being true"); diff --git a/src/Artemis.UI.Shared/Plugins/ScriptingProviders/ScriptEditorViewModel.cs b/src/Artemis.UI.Shared/Plugins/ScriptingProviders/ScriptEditorViewModel.cs index 54723b67e..27518f04e 100644 --- a/src/Artemis.UI.Shared/Plugins/ScriptingProviders/ScriptEditorViewModel.cs +++ b/src/Artemis.UI.Shared/Plugins/ScriptingProviders/ScriptEditorViewModel.cs @@ -6,10 +6,10 @@ namespace Artemis.UI.Shared.ScriptingProviders /// /// Represents a Stylet view model containing a script editor /// - public class ScriptEditorViewModelViewModel : Screen, IScriptEditorViewModel + public class ScriptEditorViewModel : Screen, IScriptEditorViewModel { /// - public ScriptEditorViewModelViewModel(Script script) + public ScriptEditorViewModel(Script script) { Script = script; } diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs index fed2f93f1..9f60a7bb9 100644 --- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs +++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs @@ -16,6 +16,7 @@ using Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints; using Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem; using Artemis.UI.Screens.ProfileEditor.Visualization; using Artemis.UI.Screens.ProfileEditor.Visualization.Tools; +using Artemis.UI.Screens.Scripting; using Artemis.UI.Screens.Settings.Device; using Artemis.UI.Screens.Settings.Device.Tabs; using Artemis.UI.Screens.Settings.Tabs.Devices; @@ -108,6 +109,13 @@ namespace Artemis.UI.Ninject.Factories PluginPrerequisiteViewModel PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall); } + public interface IScriptVmFactory : IVmFactory + { + ScriptsDialogViewModel ScriptsDialogViewModel(Profile profile); + ScriptsDialogViewModel ScriptsDialogViewModel(Layer layer); + ScriptsDialogViewModel ScriptsDialogViewModel(ILayerProperty layerProperty); + } + public interface ISidebarVmFactory : IVmFactory { SidebarCategoryViewModel SidebarCategoryViewModel(ProfileCategory profileCategory); @@ -122,7 +130,10 @@ namespace Artemis.UI.Ninject.Factories IDataBindingViewModel DataBindingViewModel(IDataBindingRegistration registration); DirectDataBindingModeViewModel DirectDataBindingModeViewModel(DirectDataBinding directDataBinding); DataBindingModifierViewModel DataBindingModifierViewModel(DataBindingModifier modifier); - ConditionalDataBindingModeViewModel ConditionalDataBindingModeViewModel(ConditionalDataBinding conditionalDataBinding); + + ConditionalDataBindingModeViewModel ConditionalDataBindingModeViewModel( + ConditionalDataBinding conditionalDataBinding); + DataBindingConditionViewModel DataBindingConditionViewModel(DataBindingCondition dataBindingCondition); } diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.xaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.xaml index bef651de6..ad2a6d07b 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.xaml @@ -94,15 +94,18 @@ Command="{s:Action Paste}" InputGestureText="Ctrl+V" /> - + + Icon="{materialDesign:PackIcon Kind=BookEdit}" + Command="{s:Action OpenProfileScripts}"/> + IsEnabled="{Binding HasSelectedElement}" + Command="{s:Action OpenLayerScripts}"/> + IsEnabled="{Binding HasSelectedElement}" + Command="{s:Action OpenLayerPropertyScripts}"/> + + + + + + Add new script + + + + + + + + + No scripting providers found + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateViewModel.cs b/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateViewModel.cs new file mode 100644 index 000000000..5e48e84ae --- /dev/null +++ b/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateViewModel.cs @@ -0,0 +1,57 @@ +using System.Threading.Tasks; +using Artemis.Core.ScriptingProviders; +using Artemis.Core.Services; +using Artemis.UI.Shared.Services; +using FluentValidation; +using Stylet; + +namespace Artemis.UI.Screens.Scripting.Dialogs +{ + public class ScriptConfigurationCreateViewModel : DialogViewModelBase + { + private string _name; + private ScriptingProvider _selectedScriptingProvider; + + public ScriptConfigurationCreateViewModel(IModelValidator validator, IPluginManagementService pluginManagementService) : base(validator) + { + _name = "My script"; + + ScriptingProviders = new BindableCollection(pluginManagementService.GetFeaturesOfType()); + HasScriptingProviders = ScriptingProviders.Count > 0; + } + + public BindableCollection ScriptingProviders { get; } + public bool HasScriptingProviders { get; } + + public string Name + { + get => _name; + set => SetAndNotify(ref _name, value); + } + + public ScriptingProvider SelectedScriptingProvider + { + get => _selectedScriptingProvider; + set => SetAndNotify(ref _selectedScriptingProvider, value); + } + + public async Task Accept() + { + await ValidateAsync(); + + if (HasErrors) + return; + + Session.Close(new ScriptConfiguration(SelectedScriptingProvider, Name)); + } + } + + public class ProfileElementScriptConfigurationCreateViewModelValidator : AbstractValidator + { + public ProfileElementScriptConfigurationCreateViewModelValidator() + { + RuleFor(m => m.Name).NotEmpty().WithMessage("Script name may not be empty"); + RuleFor(m => m.SelectedScriptingProvider).NotNull().WithMessage("Scripting provider is required"); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Scripting/ScriptConfigurationViewModel.cs b/src/Artemis.UI/Screens/Scripting/ScriptConfigurationViewModel.cs new file mode 100644 index 000000000..ab4202142 --- /dev/null +++ b/src/Artemis.UI/Screens/Scripting/ScriptConfigurationViewModel.cs @@ -0,0 +1,52 @@ +using Artemis.Core.ScriptingProviders; +using Artemis.UI.Shared.ScriptingProviders; +using Stylet; + +namespace Artemis.UI.Screens.Scripting +{ + public class ScriptConfigurationViewModel : Conductor + { + public ScriptConfigurationViewModel(ScriptConfiguration scriptConfiguration) + { + ScriptConfiguration = scriptConfiguration; + Script = ScriptConfiguration.Script; + } + + public Script Script { get; set; } + public ScriptConfiguration ScriptConfiguration { get; } + + #region Overrides of Screen + + /// + protected override void OnActivate() + { + ActiveItem = Script switch + { + GlobalScript globalScript => Script.ScriptingProvider.CreateGlobalScriptEditor(globalScript), + LayerScript layerScript => Script.ScriptingProvider.CreateLayerScriptScriptEditor(layerScript), + ProfileScript profileScript => Script.ScriptingProvider.CreateProfileScriptEditor(profileScript), + PropertyScript propertyScript => Script.ScriptingProvider.CreatePropertyScriptEditor(propertyScript), + _ => new UnknownScriptEditorViewModel(null) + }; + + base.OnActivate(); + } + + /// + protected override void OnClose() + { + ActiveItem = null; + base.OnClose(); + } + + #endregion + } + + public class UnknownScriptEditorViewModel : ScriptEditorViewModel + { + /// + public UnknownScriptEditorViewModel(Script script) : base(script) + { + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.xaml b/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.xaml new file mode 100644 index 000000000..14bf6d776 --- /dev/null +++ b/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.xaml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +