Scripting - Added script creation

This commit is contained in:
Robert committed 2021-06-21 00:44:57 +02:00
1 parent 8c729055ea
commit 4a69baebb7
11 files changed
+366 -49

No files matched your search

@@ -0,0 +1,61 @@
<UserControl x:Class="Artemis.UI.Screens.Scripting.Dialogs.ScriptConfigurationCreateView"
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:local="clr-namespace:Artemis.UI.Screens.Scripting.Dialogs"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:scriptingProviders="clr-namespace:Artemis.Core.ScriptingProviders;assembly=Artemis.Core"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:ScriptConfigurationCreateViewModel}">
<UserControl.Resources>
<shared:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
</UserControl.Resources>
<StackPanel Margin="16">
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}">
Add new script
</TextBlock>
<TextBox materialDesign:HintAssist.Hint="Script name"
Margin="0 8 0 16"
Width="300"
Style="{StaticResource MaterialDesignFilledTextBox}"
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<ComboBox materialDesign:HintAssist.Hint="Scripting provider"
Margin="0 8 0 16"
Width="300"
Style="{StaticResource MaterialDesignFilledComboBox}"
SelectedItem="{Binding SelectedScriptingProvider}">
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem IsEnabled="False"
Visibility="{Binding HasScriptingProviders, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
No scripting providers found
</ComboBoxItem>
<CollectionContainer Collection="{Binding Data.ScriptingProviders, Source={StaticResource DataContextProxy}}" />
</CompositeCollection>
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type scriptingProviders:ScriptingProvider}">
<StackPanel Orientation="Horizontal">
<shared:ArtemisIcon Icon="{Binding Info.ResolvedIcon}" Width="18 " Height="18" Margin="0 0 5 0" VerticalAlignment="Center" />
<TextBlock Text="{Binding Info.Name}" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 8 0 0">
<Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 0 8 0" Command="{s:Action Cancel}">
CANCEL
</Button>
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 0 0 0" Command="{s:Action Accept}">
ACCEPT
</Button>
</StackPanel>
</StackPanel>
</UserControl>
@@ -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<ScriptConfigurationCreateViewModel> validator, IPluginManagementService pluginManagementService) : base(validator)
{
_name = "My script";
ScriptingProviders = new BindableCollection<ScriptingProvider>(pluginManagementService.GetFeaturesOfType<ScriptingProvider>());
HasScriptingProviders = ScriptingProviders.Count > 0;
}
public BindableCollection<ScriptingProvider> 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<ScriptConfigurationCreateViewModel>
{
public ProfileElementScriptConfigurationCreateViewModelValidator()
{
RuleFor(m => m.Name).NotEmpty().WithMessage("Script name may not be empty");
RuleFor(m => m.SelectedScriptingProvider).NotNull().WithMessage("Scripting provider is required");
}
}
}
@@ -0,0 +1,52 @@
using Artemis.Core.ScriptingProviders;
using Artemis.UI.Shared.ScriptingProviders;
using Stylet;
namespace Artemis.UI.Screens.Scripting
{
public class ScriptConfigurationViewModel : Conductor<IScriptEditorViewModel>
{
public ScriptConfigurationViewModel(ScriptConfiguration scriptConfiguration)
{
ScriptConfiguration = scriptConfiguration;
Script = ScriptConfiguration.Script;
}
public Script Script { get; set; }
public ScriptConfiguration ScriptConfiguration { get; }
#region Overrides of Screen
/// <inheritdoc />
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();
}
/// <inheritdoc />
protected override void OnClose()
{
ActiveItem = null;
base.OnClose();
}
#endregion
}
public class UnknownScriptEditorViewModel : ScriptEditorViewModel
{
/// <inheritdoc />
public UnknownScriptEditorViewModel(Script script) : base(script)
{
}
}
}
@@ -0,0 +1,90 @@
<mde:MaterialWindow x:Class="Artemis.UI.Screens.Scripting.ScriptsDialogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:local="clr-namespace:Artemis.UI.Screens.Scripting"
xmlns:mde="https://spiegelp.github.io/MaterialDesignExtensions/winfx/xaml"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
FadeContentIfInactive="False"
Icon="/Resources/Images/Logo/bow.ico"
Title="{Binding DisplayName}"
TitleBarIcon="{svgc:SvgImage Source=/Resources/Images/Logo/bow-white.svg}"
Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
UseLayoutRounding="True"
Height="800" Width="1200"
d:DataContext="{d:DesignInstance {x:Type local:ScriptsDialogViewModel}}">
<mde:MaterialWindow.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Sidebar/ArtemisSidebar.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</mde:MaterialWindow.Resources>
<materialDesign:DialogHost IsTabStop="False" Focusable="False" Identifier="ScriptsDialog" DialogTheme="Inherit">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="240" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Sidebar -->
<Border Grid.Column="0" ClipToBounds="True" Background="{DynamicResource MaterialDesignToolBarBackground}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0"
Margin="0 10 0 0"
ItemContainerStyle="{StaticResource SidebarListBoxItem}"
ItemsSource="{Binding Items}"
SelectedItem="{Binding ActiveItem}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:ScriptConfigurationViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<shared:ArtemisIcon Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="2"
Icon="{Binding ScriptConfiguration.Script.ScriptingProvider.Info.ResolvedIcon, FallbackValue=QuestionMark}"
Width="18 "
Height="18"
Margin="0 0 10 0"
VerticalAlignment="Center" />
<TextBlock Grid.Row="0"
Grid.Column="1"
Text="{Binding ScriptConfiguration.Name}" VerticalAlignment="Center" />
<TextBlock Grid.Row="1"
Grid.Column="1"
Text="{Binding ScriptConfiguration.Script.ScriptingProvider.Info.Name, FallbackValue='Unknown scripting provider'}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
VerticalAlignment="Center" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="1" Style="{StaticResource MaterialDesignOutlinedButton}" Content="ADD NEW SCRIPT" Margin="10 10 10 0" Command="{s:Action AddScriptConfiguration}"
VerticalAlignment="Top" />
</Grid>
</Border>
<!-- Script editor -->
<ContentControl Grid.Column="1" s:View.Model="{Binding ActiveItem.ActiveItem}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
</Grid>
</materialDesign:DialogHost>
</mde:MaterialWindow>
@@ -1,24 +1,75 @@
using Artemis.Core;
using System;
using System.Linq;
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.Services;
using Stylet;
namespace Artemis.UI.Screens.Scripting
{
public class ScriptsDialogViewModel : Conductor<ScriptConfigurationViewModel>.Collection.OneActive
{
public ScriptsDialogViewModel(Profile profile)
private readonly IScriptingService _scriptingService;
private readonly IDialogService _dialogService;
public Profile Profile { get; }
public Layer Layer { get; }
public ILayerProperty LayerProperty { get; }
public ScriptsDialogViewModel(Profile profile, IScriptingService scriptingService, IDialogService dialogService)
{
_scriptingService = scriptingService;
_dialogService = dialogService;
DisplayName = "Artemins | Profile Scripts";
Profile = profile ?? throw new ArgumentNullException(nameof(profile));
Items.AddRange(Profile.ScriptConfigurations.Select(s => new ScriptConfigurationViewModel(s)));
}
public ScriptsDialogViewModel(Layer layer)
public ScriptsDialogViewModel(Layer layer, IDialogService dialogService)
{
_dialogService = dialogService;
DisplayName = "Artemins | Layer Scripts";
Layer = layer ?? throw new ArgumentNullException(nameof(layer));
Items.AddRange(Layer.ScriptConfigurations.Select(s => new ScriptConfigurationViewModel(s)));
}
public ScriptsDialogViewModel(ILayerProperty layerProperty)
public ScriptsDialogViewModel(ILayerProperty layerProperty, IDialogService dialogService)
{
}
}
_dialogService = dialogService;
DisplayName = "Artemins | Layer Property Scripts";
LayerProperty = layerProperty ?? throw new ArgumentNullException(nameof(layerProperty));
public class ScriptConfigurationViewModel : Screen
{
Items.AddRange(LayerProperty.ScriptConfigurations.Select(s => new ScriptConfigurationViewModel(s)));
}
public async Task AddScriptConfiguration()
{
object result = await _dialogService.ShowDialogAt<ScriptConfigurationCreateViewModel>("ScriptsDialog");
if (result is not ScriptConfiguration scriptConfiguration)
return;
if (Profile != null)
{
Profile.ScriptConfigurations.Add(scriptConfiguration);
_scriptingService.CreateScriptInstance(Profile, scriptConfiguration);
}
else if (Layer != null)
{
Layer.ScriptConfigurations.Add(scriptConfiguration);
_scriptingService.CreateScriptInstance(Layer, scriptConfiguration);
}
else if (LayerProperty != null)
{
LayerProperty.ScriptConfigurations.Add(scriptConfiguration);
_scriptingService.CreateScriptInstance(LayerProperty, scriptConfiguration);
}
Items.Add(new ScriptConfigurationViewModel(scriptConfiguration));
}
}
}