mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
UI - Moved exception viewer to its own seperate window
Conditions - Started adding list conditions
This commit is contained in:
1 parent
f21ade955d
commit
cb69760971
36 files changed
+930
-471
No files matched your search
@@ -19,19 +19,9 @@
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 8 8 0" Command="{s:Action Cancel}">
|
||||
<Button.CommandParameter>
|
||||
<system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
False
|
||||
</system:Boolean>
|
||||
</Button.CommandParameter>
|
||||
CANCEL
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 8 0" Command="{s:Action Accept}">
|
||||
<Button.CommandParameter>
|
||||
<system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
True
|
||||
</system:Boolean>
|
||||
</Button.CommandParameter>
|
||||
ACCEPT
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.Dialogs.ProfileExportView"
|
||||
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.Module.ProfileEditor.Dialogs"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Margin="16" Width="500">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" Grid.Row="0">
|
||||
Export current profile
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock Margin="0 10" TextAlignment="Justify" TextWrapping="Wrap" Grid.Row="1">
|
||||
Please note that exporting profiles like this is placeholder functionality. The idea is that this will eventually happen via the workshop.
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock Margin="0 10" TextAlignment="Justify" TextWrapping="Wrap" Grid.Row="2">
|
||||
The workshop will include tools to make profiles convert easily and look good on different layouts.
|
||||
That means right now when someone imports this export unless they have the exact same setup as
|
||||
you, they'll have to select LEDs for each layer in the profile.
|
||||
</TextBlock>
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="3">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 8 8 0" Command="{s:Action Cancel}">
|
||||
CANCEL
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 0 0" Command="{s:Action Accept}">
|
||||
I UNDERSTAND, EXPORT
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Windows;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Services.Storage.Interfaces;
|
||||
using Artemis.UI.Shared.Services.Dialog;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.Dialogs
|
||||
{
|
||||
public class ProfileExportViewModel : DialogViewModelBase
|
||||
{
|
||||
private readonly ISnackbarMessageQueue _mainMessageQueue;
|
||||
|
||||
private readonly IProfileService _profileService;
|
||||
|
||||
public ProfileExportViewModel(ProfileDescriptor profileDescriptor, IProfileService profileService, ISnackbarMessageQueue mainMessageQueue)
|
||||
{
|
||||
ProfileDescriptor = profileDescriptor;
|
||||
|
||||
_profileService = profileService;
|
||||
_mainMessageQueue = mainMessageQueue;
|
||||
}
|
||||
|
||||
public ProfileDescriptor ProfileDescriptor { get; }
|
||||
|
||||
public void Accept()
|
||||
{
|
||||
var encoded = _profileService.ExportProfile(ProfileDescriptor);
|
||||
Clipboard.SetText(encoded);
|
||||
_mainMessageQueue.Enqueue("Profile contents exported to clipboard.");
|
||||
|
||||
Session.Close();
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
Session.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.Dialogs.ProfileImportView"
|
||||
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.Module.ProfileEditor.Dialogs"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Margin="16" Width="800">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" Grid.Row="0">
|
||||
Import profile to current module
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock Margin="0 10" TextAlignment="Justify" TextWrapping="Wrap" Grid.Row="1">
|
||||
Please note that importing profiles like this is placeholder functionality. The idea is that this will eventually happen via the workshop.
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock Margin="0 10" TextAlignment="Justify" TextWrapping="Wrap" Grid.Row="2">
|
||||
The workshop will include tools to make profiles convert easily and look good on different layouts.
|
||||
That means right now when you import this profile unless you have the exact same setup as
|
||||
the person who exported it, you'll have to select LEDs for each layer in the profile.
|
||||
</TextBlock>
|
||||
|
||||
<avalonedit:TextEditor Grid.Row="3" SyntaxHighlighting="JavaScript"
|
||||
FontFamily="pack://application:,,,/Resources/Fonts/#Roboto Mono"
|
||||
FontSize="10pt"
|
||||
Document="{Binding Document}"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
Height="500"
|
||||
Padding="10" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="4">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 8 8 0" Command="{s:Action Cancel}">
|
||||
CANCEL
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 0 0" Command="{s:Action Accept}">
|
||||
I UNDERSTAND, IMPORT
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Windows;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Plugins.Abstract;
|
||||
using Artemis.Core.Services.Storage.Interfaces;
|
||||
using Artemis.UI.Shared.Services.Dialog;
|
||||
using ICSharpCode.AvalonEdit.Document;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.Dialogs
|
||||
{
|
||||
public class ProfileImportViewModel : DialogViewModelBase
|
||||
{
|
||||
private readonly ISnackbarMessageQueue _mainMessageQueue;
|
||||
private readonly IProfileService _profileService;
|
||||
private string _profileJson;
|
||||
|
||||
public ProfileImportViewModel(ProfileModule profileModule, IProfileService profileService, ISnackbarMessageQueue mainMessageQueue)
|
||||
{
|
||||
ProfileModule = profileModule;
|
||||
Document = new TextDocument();
|
||||
|
||||
_profileService = profileService;
|
||||
_mainMessageQueue = mainMessageQueue;
|
||||
}
|
||||
|
||||
public ProfileModule ProfileModule { get; }
|
||||
public TextDocument Document { get; set; }
|
||||
|
||||
public string ProfileJson
|
||||
{
|
||||
get => _profileJson;
|
||||
set => SetAndNotify(ref _profileJson, value);
|
||||
}
|
||||
|
||||
public void Accept()
|
||||
{
|
||||
_profileService.ImportProfile(Document.Text, ProfileModule);
|
||||
_mainMessageQueue.Enqueue("Profile imported.");
|
||||
Session.Close();
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
Session.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -97,6 +97,14 @@
|
||||
<materialDesign:PackIcon Kind="InsertLink" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Add list condition"
|
||||
ToolTip="A condition that evaluates on items in a list"
|
||||
Command="{s:Action AddCondition}"
|
||||
CommandParameter="List">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="FormatListBulleted" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Add group" ToolTip="A group can contain conditions and other groups" Command="{s:Action AddGroup}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="CodeParentheses" />
|
||||
|
||||
+2
@@ -66,6 +66,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
DisplayConditionGroup.AddChild(new DisplayConditionPredicate(DisplayConditionGroup, PredicateType.Static));
|
||||
else if (type == "Dynamic")
|
||||
DisplayConditionGroup.AddChild(new DisplayConditionPredicate(DisplayConditionGroup, PredicateType.Dynamic));
|
||||
else if (type == "List")
|
||||
DisplayConditionGroup.AddChild(new DisplayConditionListPredicate(DisplayConditionGroup));
|
||||
|
||||
Update();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
+139
-3
@@ -4,10 +4,146 @@
|
||||
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.Module.ProfileEditor.DisplayConditions"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance Type=local:DisplayConditionListPredicateViewModel, IsDesignTimeCreatable=False}">
|
||||
<Grid>
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0 3" Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="#E74C4C"
|
||||
Width="25"
|
||||
Height="25"
|
||||
Command="{s:Action Delete}">
|
||||
<materialDesign:PackIcon Kind="Close" Width="18" Height="18" />
|
||||
</Button>
|
||||
|
||||
<!-- Left side, the list this predicate is targeting -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Background="#ab47bc"
|
||||
BorderBrush="#ab47bc"
|
||||
Style="{StaticResource DisplayConditionButton}"
|
||||
ToolTip="{Binding SelectedListProperty.DisplayPropertyPath}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding TargetDataModel.Children}" IsOpen="{Binding TargetDataModelOpen, Mode=OneWayToSource}">
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectListPropertyCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
<Setter Property="IsEnabled" Value="{Binding IsMatchingFilteredTypes}" />
|
||||
<Setter Property="IsSubmenuOpen" Value="{Binding IsVisualizationExpanded, Mode=TwoWay}" />
|
||||
<Setter Property="HeaderTemplate" Value="{StaticResource DataModelSelectionTemplate}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding SelectedListProperty.PropertyDescription.Name}"
|
||||
Visibility="{Binding SelectedListProperty, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock Text="« Select a list »"
|
||||
FontStyle="Italic"
|
||||
Visibility="{Binding SelectedListProperty, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
|
||||
<!-- Operator -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedListOperator}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Any" Command="{s:Action SelectListOperator}" CommandParameter="Any" />
|
||||
<MenuItem Header="All" Command="{s:Action SelectListOperator}" CommandParameter="All" />
|
||||
<MenuItem Header="None" Command="{s:Action SelectListOperator}" CommandParameter="None" />
|
||||
<MenuItem Header="Count (NYI)" Command="{s:Action SelectListOperator}" CommandParameter="Count" IsEnabled="False"/>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
<Button x:Name="AddChildButton"
|
||||
Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="#4CE758"
|
||||
Width="25"
|
||||
Height="25">
|
||||
<Button.Style>
|
||||
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MaterialDesignIconForegroundButton}">
|
||||
<Style.Triggers>
|
||||
<EventTrigger RoutedEvent="Click">
|
||||
<EventTrigger.Actions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
|
||||
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True" />
|
||||
</BooleanAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger.Actions>
|
||||
</EventTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
<materialDesign:PackIcon Kind="Add" Width="18" Height="18" />
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Add static condition"
|
||||
ToolTip="A condition that compares a data model property to a static input"
|
||||
Command="{s:Action AddCondition}"
|
||||
CommandParameter="Static">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="FormTextarea" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Add dynamic condition"
|
||||
ToolTip="A condition that compares two data model properties"
|
||||
Command="{s:Action AddCondition}"
|
||||
CommandParameter="Dynamic">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="InsertLink" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Add group" ToolTip="A group can contain conditions and other groups" Command="{s:Action AddGroup}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="CodeParentheses" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
</UserControl>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DisplayConditionListPredicateView.xaml
|
||||
/// </summary>
|
||||
public partial class DisplayConditionListPredicateView : UserControl
|
||||
{
|
||||
public DisplayConditionListPredicateView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void PropertyButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// DataContext is not set when using left button, I don't know why but there it is
|
||||
if (sender is Button button && button.ContextMenu != null)
|
||||
{
|
||||
button.ContextMenu.DataContext = button.DataContext;
|
||||
button.ContextMenu.IsOpen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+190
-2
@@ -1,18 +1,206 @@
|
||||
using Artemis.Core.Models.Profile.Conditions;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using Artemis.Core.Models.Profile.Conditions;
|
||||
using Artemis.Core.Plugins.Models;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions.Abstract;
|
||||
using Artemis.UI.Shared.DataModelVisualization.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using Artemis.UI.Utilities;
|
||||
using Humanizer;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
{
|
||||
public class DisplayConditionListPredicateViewModel : DisplayConditionViewModel
|
||||
{
|
||||
public DisplayConditionListPredicateViewModel(DisplayConditionListPredicate displayConditionListPredicate, DisplayConditionViewModel parent) : base(displayConditionListPredicate, parent)
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly IDataModelVisualizationService _dataModelVisualizationService;
|
||||
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
|
||||
private bool _isInitialized;
|
||||
private DataModelVisualizationViewModel _selectedListProperty;
|
||||
private DataModelPropertiesViewModel _targetDataModel;
|
||||
private readonly Timer _updateTimer;
|
||||
|
||||
public DisplayConditionListPredicateViewModel(
|
||||
DisplayConditionListPredicate displayConditionListPredicate,
|
||||
DisplayConditionViewModel parent,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelVisualizationService dataModelVisualizationService,
|
||||
IDisplayConditionsVmFactory displayConditionsVmFactory,
|
||||
ISettingsService settingsService) : base(displayConditionListPredicate, parent)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelVisualizationService = dataModelVisualizationService;
|
||||
_displayConditionsVmFactory = displayConditionsVmFactory;
|
||||
_updateTimer = new Timer(500);
|
||||
|
||||
SelectListPropertyCommand = new DelegateCommand(ExecuteSelectListProperty);
|
||||
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
|
||||
// Initialize async, no need to wait for it
|
||||
Task.Run(Initialize);
|
||||
}
|
||||
|
||||
public DelegateCommand SelectListPropertyCommand { get; }
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
|
||||
public DisplayConditionListPredicate DisplayConditionListPredicate => (DisplayConditionListPredicate) Model;
|
||||
|
||||
public bool IsInitialized
|
||||
{
|
||||
get => _isInitialized;
|
||||
set => SetAndNotify(ref _isInitialized, value);
|
||||
}
|
||||
|
||||
public bool TargetDataModelOpen { get; set; }
|
||||
|
||||
public DataModelPropertiesViewModel TargetDataModel
|
||||
{
|
||||
get => _targetDataModel;
|
||||
set => SetAndNotify(ref _targetDataModel, value);
|
||||
}
|
||||
|
||||
public DataModelVisualizationViewModel SelectedListProperty
|
||||
{
|
||||
get => _selectedListProperty;
|
||||
set => SetAndNotify(ref _selectedListProperty, value);
|
||||
}
|
||||
|
||||
public string SelectedListOperator => DisplayConditionListPredicate.ListOperator.Humanize();
|
||||
|
||||
public void SelectListOperator(string type)
|
||||
{
|
||||
var enumValue = Enum.Parse<ListOperator>(type);
|
||||
DisplayConditionListPredicate.ListOperator = enumValue;
|
||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||
}
|
||||
|
||||
public void AddCondition(string type)
|
||||
{
|
||||
if (type == "Static")
|
||||
DisplayConditionListPredicate.AddChild(new DisplayConditionPredicate(DisplayConditionListPredicate, PredicateType.Static));
|
||||
else if (type == "Dynamic")
|
||||
DisplayConditionListPredicate.AddChild(new DisplayConditionPredicate(DisplayConditionListPredicate, PredicateType.Dynamic));
|
||||
|
||||
Update();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddGroup()
|
||||
{
|
||||
DisplayConditionListPredicate.AddChild(new DisplayConditionGroup(DisplayConditionListPredicate));
|
||||
|
||||
Update();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// Get the data models
|
||||
TargetDataModel = _dataModelVisualizationService.GetMainDataModelVisualization();
|
||||
if (!_dataModelVisualizationService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule()))
|
||||
TargetDataModel.Children.Add(_dataModelVisualizationService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
|
||||
|
||||
TargetDataModel.UpdateRequested += TargetDataModelUpdateRequested;
|
||||
|
||||
Update();
|
||||
|
||||
_updateTimer.Start();
|
||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_updateTimer.Stop();
|
||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||
}
|
||||
|
||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (TargetDataModelOpen)
|
||||
TargetDataModel.Update(_dataModelVisualizationService);
|
||||
}
|
||||
|
||||
private void TargetDataModelUpdateRequested(object sender, EventArgs e)
|
||||
{
|
||||
TargetDataModel.ApplyTypeFilter(true, typeof(IEnumerable));
|
||||
}
|
||||
|
||||
public void ApplyList()
|
||||
{
|
||||
DisplayConditionListPredicate.UpdateList(SelectedListProperty.DataModel, SelectedListProperty.PropertyPath);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (TargetDataModel == null)
|
||||
return;
|
||||
|
||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||
|
||||
// Update the selected list property
|
||||
if (DisplayConditionListPredicate.ListDataModel != null && DisplayConditionListPredicate.ListPropertyPath != null)
|
||||
SelectedListProperty = TargetDataModel.GetChildByPath(DisplayConditionListPredicate.ListDataModel.PluginInfo.Guid, DisplayConditionListPredicate.ListPropertyPath);
|
||||
// Ensure filtering is applied to include Enumerables only
|
||||
TargetDataModel.ApplyTypeFilter(true, typeof(IEnumerable));
|
||||
|
||||
// Remove VMs of effects no longer applied on the layer
|
||||
var toRemove = Children.Where(c => !DisplayConditionListPredicate.Children.Contains(c.Model)).ToList();
|
||||
// Using RemoveRange breaks our lovely animations
|
||||
foreach (var displayConditionViewModel in toRemove)
|
||||
{
|
||||
Children.Remove(displayConditionViewModel);
|
||||
displayConditionViewModel.Dispose();
|
||||
}
|
||||
|
||||
foreach (var childModel in Model.Children)
|
||||
{
|
||||
if (Children.Any(c => c.Model == childModel))
|
||||
continue;
|
||||
|
||||
switch (childModel)
|
||||
{
|
||||
case DisplayConditionGroup displayConditionGroup:
|
||||
Children.Add(_displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, this));
|
||||
break;
|
||||
case DisplayConditionListPredicate displayConditionListPredicate:
|
||||
Children.Add(_displayConditionsVmFactory.DisplayConditionListPredicateViewModel(displayConditionListPredicate, this));
|
||||
break;
|
||||
case DisplayConditionPredicate displayConditionPredicate:
|
||||
Children.Add(_displayConditionsVmFactory.DisplayConditionPredicateViewModel(displayConditionPredicate, this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var childViewModel in Children)
|
||||
childViewModel.Update();
|
||||
}
|
||||
|
||||
|
||||
private void ExecuteSelectListProperty(object context)
|
||||
{
|
||||
if (!(context is DataModelVisualizationViewModel dataModelVisualizationViewModel))
|
||||
return;
|
||||
|
||||
SelectedListProperty = dataModelVisualizationViewModel;
|
||||
ApplyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
-41
@@ -21,47 +21,6 @@
|
||||
<ResourceDictionary>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
<DataTemplate x:Key="DataModelSelectionTemplate">
|
||||
<StackPanel>
|
||||
<StackPanel.Resources>
|
||||
<DataTemplate DataType="{x:Type dataModel:DataModelPropertiesViewModel}">
|
||||
<TextBlock Text="{Binding PropertyDescription.Name}" ToolTip="{Binding PropertyDescription.Description}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type dataModel:DataModelPropertyViewModel}">
|
||||
<Grid ToolTip="{Binding PropertyDescription.Description}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Value description -->
|
||||
<TextBlock Grid.Column="0" Text="{Binding PropertyDescription.Name}" ToolTip="{Binding PropertyDescription.Description}" />
|
||||
|
||||
<!-- Value display -->
|
||||
<StackPanel Grid.Column="1" Visibility="{Binding Data.ShowDataModelValues.Value, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay, Source={StaticResource DataContextProxy}}">
|
||||
<TextBlock Text="{Binding DisplayValue, Mode=OneWay}"
|
||||
FontFamily="Consolas"
|
||||
HorizontalAlignment="Right"
|
||||
Visibility="{Binding ShowToString, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
|
||||
Margin="15 0.5 0 0" />
|
||||
<TextBlock Text="null"
|
||||
FontFamily="Consolas"
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="{DynamicResource MaterialDesignCheckBoxDisabled}"
|
||||
Margin="15 0.5 0 0"
|
||||
Visibility="{Binding ShowNull, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
|
||||
<ContentControl s:View.Model="{Binding DisplayViewModel}"
|
||||
FontFamily="Consolas"
|
||||
Margin="15 0.5 0 0"
|
||||
Visibility="{Binding ShowViewModel, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</StackPanel.Resources>
|
||||
<ContentPresenter Content="{Binding}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
+8
-3
@@ -40,9 +40,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
private List<Type> _supportedInputTypes;
|
||||
private readonly Timer _updateTimer;
|
||||
|
||||
public DisplayConditionPredicateViewModel(DisplayConditionPredicate displayConditionPredicate, DisplayConditionViewModel parent, IProfileEditorService profileEditorService,
|
||||
IDataModelVisualizationService dataModelVisualizationService, IDataModelService dataModelService, ISettingsService settingsService, IEventAggregator eventAggregator)
|
||||
: base(displayConditionPredicate, parent)
|
||||
public DisplayConditionPredicateViewModel(
|
||||
DisplayConditionPredicate displayConditionPredicate,
|
||||
DisplayConditionViewModel parent,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelVisualizationService dataModelVisualizationService,
|
||||
IDataModelService dataModelService,
|
||||
ISettingsService settingsService,
|
||||
IEventAggregator eventAggregator) : base(displayConditionPredicate, parent)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelVisualizationService = dataModelVisualizationService;
|
||||
|
||||
+3
-4
@@ -135,9 +135,7 @@
|
||||
VerticalScrollBarVisibility="Hidden"
|
||||
ScrollChanged="TimelineScrollChanged">
|
||||
<Border BorderThickness="0,0,1,0" BorderBrush="{DynamicResource MaterialDesignDivider}">
|
||||
<Grid>
|
||||
<ContentControl s:View.Model="{Binding TreeViewModel}" />
|
||||
</Grid>
|
||||
<ContentControl s:View.Model="{Binding TreeViewModel}" />
|
||||
</Border>
|
||||
</ScrollViewer>
|
||||
<materialDesign:TransitionerSlide>
|
||||
@@ -212,7 +210,8 @@
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- Timeline rails -->
|
||||
<ScrollViewer x:Name="TimelineRailsScrollViewer" Grid.Row="1" Style="{StaticResource SvStyle}" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" ScrollChanged="TimelineScrollChanged">
|
||||
<ScrollViewer x:Name="TimelineRailsScrollViewer" Grid.Row="1" Style="{StaticResource SvStyle}" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
|
||||
ScrollChanged="TimelineScrollChanged">
|
||||
<Grid Background="{DynamicResource MaterialDesignToolBarBackground}">
|
||||
<Canvas Grid.Column="0" Panel.ZIndex="1">
|
||||
<Line Canvas.Left="{Binding TimeCaretPosition}"
|
||||
|
||||
+4
-4
@@ -28,7 +28,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
|
||||
|
||||
public LayerPropertyGroupViewModel LayerPropertyGroupViewModel { get; }
|
||||
|
||||
public async void OpenBrushSettings()
|
||||
public void OpenBrushSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -38,12 +38,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("An exception occured while trying to show the brush's settings window", e);
|
||||
_dialogService.ShowExceptionDialog("An exception occured while trying to show the brush's settings window", e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async void OpenEffectSettings()
|
||||
public void OpenEffectSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -53,7 +53,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("An exception occured while trying to show the effect's settings window", e);
|
||||
_dialogService.ShowExceptionDialog("An exception occured while trying to show the effect's settings window", e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,11 +131,13 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ComboBox Height="26"
|
||||
VerticalAlignment="Top"
|
||||
ItemsSource="{Binding Profiles}"
|
||||
SelectedItem="{Binding SelectedProfile}"
|
||||
SelectedItem="{Binding SelectedProfile}"
|
||||
ItemTemplate="{StaticResource ProfileDescriptorTemplate}">
|
||||
<ComboBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
@@ -144,7 +146,7 @@
|
||||
</ComboBox.ItemsPanel>
|
||||
</ComboBox>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
|
||||
Margin="10 0"
|
||||
Margin="5 0"
|
||||
Grid.Column="1"
|
||||
Width="26"
|
||||
Height="26"
|
||||
@@ -153,6 +155,7 @@
|
||||
<materialDesign:PackIcon Kind="Add" Height="14" Width="14" />
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniDarkButton}"
|
||||
Margin="5 0"
|
||||
Grid.Column="2"
|
||||
Width="26"
|
||||
Height="26"
|
||||
@@ -160,6 +163,24 @@
|
||||
Command="{s:Action DeleteActiveProfile}">
|
||||
<materialDesign:PackIcon Kind="TrashCanOutline" Height="14" Width="14" />
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
|
||||
Margin="5 0"
|
||||
Grid.Column="3"
|
||||
Width="26"
|
||||
Height="26"
|
||||
VerticalAlignment="Top"
|
||||
Command="{s:Action ExportActiveProfile}">
|
||||
<materialDesign:PackIcon Kind="Export" Height="14" Width="14" />
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
|
||||
Margin="5 0 0 0"
|
||||
Grid.Column="4"
|
||||
Width="26"
|
||||
Height="26"
|
||||
VerticalAlignment="Top"
|
||||
Command="{s:Action ImportProfile}">
|
||||
<materialDesign:PackIcon Kind="Import" Height="14" Width="14" />
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<!-- Profile elements -->
|
||||
|
||||
@@ -174,6 +174,22 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
RemoveProfile(SelectedProfile);
|
||||
}
|
||||
|
||||
public async Task ExportActiveProfile()
|
||||
{
|
||||
await DialogService.ShowDialog<ProfileExportViewModel>(new Dictionary<string, object>
|
||||
{
|
||||
{"profileDescriptor", SelectedProfile}
|
||||
});
|
||||
}
|
||||
|
||||
public async Task ImportProfile()
|
||||
{
|
||||
await DialogService.ShowDialog<ProfileImportViewModel>(new Dictionary<string, object>
|
||||
{
|
||||
{"profileModule", Module}
|
||||
});
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
// Expanded status is also undone because undoing works a bit crude, that's annoying
|
||||
@@ -292,7 +308,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
SelectedProfile = lastActiveProfile;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create a default profile if there is none
|
||||
var defaultProfile = _profileService.CreateProfileDescriptor(Module, "Default");
|
||||
Profiles.Add(defaultProfile);
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Artemis.UI.Screens.Settings.Debug
|
||||
_deviceService.IdentifyDevice(Device);
|
||||
}
|
||||
|
||||
public async void OpenPluginDirectory()
|
||||
public void OpenPluginDirectory()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -60,11 +60,11 @@ namespace Artemis.UI.Screens.Settings.Debug
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
public async void OpenImageDirectory()
|
||||
public void OpenImageDirectory()
|
||||
{
|
||||
if (!CanOpenImageDirectory)
|
||||
return;
|
||||
@@ -75,7 +75,7 @@ namespace Artemis.UI.Screens.Settings.Debug
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("Welp, we couldn't open the device's image folder for you", e);
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn't open the device's image folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace Artemis.UI.Screens.Settings
|
||||
_debugService.ShowDebugger();
|
||||
}
|
||||
|
||||
public async Task ShowLogsFolder()
|
||||
public void ShowLogsFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -204,11 +204,11 @@ namespace Artemis.UI.Screens.Settings
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ShowDataFolder()
|
||||
public void ShowDataFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -216,7 +216,7 @@ namespace Artemis.UI.Screens.Settings
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the data folder for you", e);
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn\'t open the data folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ namespace Artemis.UI.Screens.Settings
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
private async Task ApplyAutorun()
|
||||
private void ApplyAutorun()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -254,7 +254,7 @@ namespace Artemis.UI.Screens.Settings
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("An exception occured while trying to apply the auto run setting", e);
|
||||
_dialogService.ShowExceptionDialog("An exception occured while trying to apply the auto run setting", e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
|
||||
_windowManager.ShowWindow(_deviceDebugVmFactory.Create(Device));
|
||||
}
|
||||
|
||||
public async void OpenPluginDirectory()
|
||||
public void OpenPluginDirectory()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -65,7 +65,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
set => Task.Run(() => UpdateEnabled(value));
|
||||
}
|
||||
|
||||
public async Task OpenSettings()
|
||||
public void OpenSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -72,12 +72,12 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("An exception occured while trying to show the plugin's settings window", e);
|
||||
_dialogService.ShowExceptionDialog("An exception occured while trying to show the plugin's settings window", e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ShowLogsFolder()
|
||||
public void ShowLogsFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -85,16 +85,16 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ShowLoadException()
|
||||
public void ShowLoadException()
|
||||
{
|
||||
if (PluginInfo.LoadException == null)
|
||||
return;
|
||||
|
||||
await _dialogService.ShowExceptionDialog("The plugin failed to load: " + PluginInfo.LoadException.Message, PluginInfo.LoadException);
|
||||
_dialogService.ShowExceptionDialog("The plugin failed to load: " + PluginInfo.LoadException.Message, PluginInfo.LoadException);
|
||||
}
|
||||
|
||||
private PackIconKind GetIconKind()
|
||||
@@ -157,7 +157,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_snackbarMessageQueue.Enqueue($"Failed to enable plugin {PluginInfo.Name}\r\n{e.Message}", "VIEW LOGS", async () => await ShowLogsFolder());
|
||||
_snackbarMessageQueue.Enqueue($"Failed to enable plugin {PluginInfo.Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user