1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Plugin settings - Open settings as an extra window instead of a dialog

Conditions UI - Display condition results while editing
Conditions UI - Added event trigger indicator while editing
This commit is contained in:
Robert 2021-03-09 23:30:06 +01:00
parent 94fac36ffe
commit fa26e6b7da
17 changed files with 205 additions and 30 deletions

View File

@ -12,7 +12,6 @@ namespace Artemis.Core
{
private bool _disposed;
private bool _reinitializing;
private DateTime _lastTrigger;
/// <summary>
/// Creates a new instance of the <see cref="DataModelConditionEvent" /> class
@ -39,6 +38,8 @@ namespace Artemis.Core
/// </summary>
public DataModelPath? EventPath { get; private set; }
public DateTime LastTrigger { get; private set; }
/// <summary>
/// Gets or sets the type of argument the event provides
/// </summary>
@ -55,10 +56,10 @@ namespace Artemis.Core
if (EventPath?.GetValue() is not IDataModelEvent dataModelEvent)
return false;
// Only evaluate to true once every time the event has been triggered since the last evaluation
if (dataModelEvent.LastTrigger <= _lastTrigger)
if (dataModelEvent.LastTrigger <= LastTrigger)
return false;
_lastTrigger = DateTime.Now;
LastTrigger = DateTime.Now;
// If there is a child (root group), it must evaluate to true whenever the event triggered
if (Children.Any())
@ -171,8 +172,8 @@ namespace Artemis.Core
AddChild(new DataModelConditionGroup(this));
}
if (EventPath?.GetValue() is IDataModelEvent dataModelEvent)
_lastTrigger = dataModelEvent.LastTrigger;
if (EventPath?.GetValue() is IDataModelEvent dataModelEvent)
LastTrigger = dataModelEvent.LastTrigger;
}
private Type? GetEventArgumentType()

View File

@ -65,12 +65,6 @@ namespace Artemis.Core
/// </summary>
public LayoutCustomDeviceData LayoutCustomDeviceData { get; private set; } = null!;
public void ReloadFromDisk()
{
Leds.Clear();
LoadLayout();
}
internal void ApplyDevice(ArtemisDevice artemisDevice)
{
Device = artemisDevice;

View File

@ -67,6 +67,11 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract
protected SolidColorBrush LeftSideColor { get; set; }
public override void Evaluate()
{
IsConditionMet = DataModelConditionPredicate.Evaluate();
}
public override void Delete()
{
base.Delete();

View File

@ -8,6 +8,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract
public abstract class DataModelConditionViewModel : Conductor<DataModelConditionViewModel>.Collection.AllActive
{
private DataModelDynamicViewModel _leftSideSelectionViewModel;
private bool _isConditionMet;
protected DataModelConditionViewModel(DataModelConditionPart model)
{
@ -22,8 +23,17 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract
set => SetAndNotify(ref _leftSideSelectionViewModel, value);
}
public bool IsConditionMet
{
get => _isConditionMet;
set => SetAndNotify(ref _isConditionMet, value);
}
public abstract void Update();
public abstract void Evaluate();
public virtual void Delete()
{
Model.Parent.RemoveChild(Model);

View File

@ -13,7 +13,14 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
</ResourceDictionary.MergedDictionaries>
<Storyboard x:Key="EventAnimation" x:Name="StartAnimation">
<DoubleAnimation Duration="0:0:0.5" From="0.5" To="1.5" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" />
<DoubleAnimation Duration="0:0:0.5" From="0.5" To="1.5" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" />
<DoubleAnimation Duration="0:0:0.1" From="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" />
<DoubleAnimation BeginTime="0:0:0.25" Duration="0:0:0.25" From="1" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" />
</Storyboard>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
@ -21,6 +28,7 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
@ -52,7 +60,37 @@
triggered
</TextBlock>
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}" Margin="0 3 0 0">
<Border Grid.Row="0"
Grid.Column="3"
Opacity="0"
Background="#FFB9A40A"
Width="22"
Height="22"
CornerRadius="11"
HorizontalAlignment="Left"
Margin="5 0 0 0"
ToolTip="{Binding LastTrigger, NotifyOnTargetUpdated=True}"
ToolTipService.IsEnabled="False">
<Border.RenderTransform>
<ScaleTransform ScaleX="1" ScaleY="1" CenterX="11" CenterY="11" />
</Border.RenderTransform>
<Border.Triggers>
<!-- Ugly workaround to avoid the event animation showing on load -->
<EventTrigger RoutedEvent="Border.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="0:0:0.01" Duration="0:0:0" From="1" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard Storyboard="{StaticResource EventAnimation}" />
</EventTrigger>
</Border.Triggers>
<materialDesign:PackIcon Kind="LightningBolt" VerticalAlignment="Center" HorizontalAlignment="Center" Width="16" Height="16" />
</Border>
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" ItemsSource="{Binding Items}" Margin="0 3 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />

View File

@ -15,6 +15,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
private readonly IDataModelUIService _dataModelUIService;
private readonly IProfileEditorService _profileEditorService;
private DateTime _lastTrigger;
public DataModelConditionEventViewModel(DataModelConditionEvent dataModelConditionEvent,
IProfileEditorService profileEditorService,
@ -24,10 +25,18 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
_profileEditorService = profileEditorService;
_dataModelUIService = dataModelUIService;
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
_lastTrigger = DataModelConditionEvent.LastTrigger;
}
public DataModelConditionEvent DataModelConditionEvent => (DataModelConditionEvent) Model;
public DateTime LastTrigger
{
get => _lastTrigger;
set => SetAndNotify(ref _lastTrigger, value);
}
public void Initialize()
{
LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
@ -36,7 +45,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
IReadOnlyCollection<DataModelVisualizationRegistration> editors = _dataModelUIService.RegisteredDataModelEditors;
List<Type> supportedInputTypes = new() {typeof(DataModelEvent), typeof(DataModelEvent<>)};
LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray();
LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(185, 164, 10));
LeftSideSelectionViewModel.Placeholder = "Select an event";
@ -74,6 +83,12 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
childViewModel.Update();
}
public override void Evaluate()
{
LastTrigger = DataModelConditionEvent.LastTrigger;
IsConditionMet = DataModelConditionEvent.Evaluate();
}
public void ApplyEvent()
{
DataModelConditionEvent.UpdateEvent(LeftSideSelectionViewModel.DataModelPath);
@ -104,7 +119,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
LeftSideSelectionViewModel.Dispose();
LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected;
}
#endregion
}
}

View File

@ -28,6 +28,7 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
@ -115,9 +116,9 @@
<materialDesign:PackIcon Kind="Equal" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Add event condition"
<MenuItem Header="Add event condition"
ToolTip="An event condition that responds to data model events"
Command="{s:Action AddEventCondition}"
Command="{s:Action AddEventCondition}"
Visibility="{Binding Data.CanAddEventCondition, Source={StaticResource DataContextProxy}, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="LightningBolt" />
@ -133,7 +134,27 @@
<materialDesign:PackIcon Kind="Add" Width="18" Height="18" />
</Button>
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items, IsAsync=True}" Margin="0 3 0 0">
<ToggleButton Grid.Row="0"
Grid.Column="3"
Style="{StaticResource MaterialDesignActionToggleButton}"
Focusable="False"
IsHitTestVisible="False"
IsChecked="{Binding IsConditionMet}"
Visibility="{Binding DisplayEvaluationResult, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
Width="22"
Height="22"
HorizontalAlignment="Left">
<ToggleButton.Content>
<Border Background="#E74C4C" Width="22" Height="22">
<materialDesign:PackIcon Kind="Close" VerticalAlignment="Center" HorizontalAlignment="Center" Width="16" Height="16"/>
</Border>
</ToggleButton.Content>
<materialDesign:ToggleButtonAssist.OnContent>
<materialDesign:PackIcon Kind="Check" Width="16" Height="16"/>
</materialDesign:ToggleButtonAssist.OnContent>
</ToggleButton>
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" ItemsSource="{Binding Items, IsAsync=True}" Margin="0 3 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />

View File

@ -1,12 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.UI.Extensions;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
using Artemis.UI.Screens.ProfileEditor.DisplayConditions;
using Artemis.UI.Shared.Services;
using Humanizer;
using Stylet;
@ -17,9 +15,9 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
{
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
private readonly IProfileEditorService _profileEditorService;
private bool _isEventGroup;
private bool _isInitialized;
private bool _isRootGroup;
private bool _isEventGroup;
public DataModelConditionGroupViewModel(DataModelConditionGroup dataModelConditionGroup,
ConditionGroupType groupType,
@ -31,7 +29,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
_profileEditorService = profileEditorService;
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
Items.CollectionChanged += (sender, args) => NotifyOfPropertyChange(nameof(DisplayBooleanOperator));
Items.CollectionChanged += (_, _) => NotifyOfPropertyChange(nameof(DisplayBooleanOperator));
Execute.PostToUIThread(async () =>
{
@ -58,7 +56,11 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
public bool IsEventGroup
{
get => _isEventGroup;
set => SetAndNotify(ref _isEventGroup, value);
set
{
SetAndNotify(ref _isEventGroup, value);
NotifyOfPropertyChange(nameof(DisplayEvaluationResult));
}
}
public bool IsInitialized
@ -68,6 +70,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
}
public bool DisplayBooleanOperator => Items.Count > 1;
public bool DisplayEvaluationResult => GroupType == ConditionGroupType.General && !IsEventGroup;
public string SelectedBooleanOperator => DataModelConditionGroup.BooleanOperator.Humanize();
public void SelectBooleanOperator(string type)
@ -166,14 +169,19 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
IsEventGroup = Items.Any(i => i is DataModelConditionEventViewModel);
if (IsEventGroup)
{
if (DataModelConditionGroup.BooleanOperator != BooleanOperator.And)
SelectBooleanOperator("And");
}
OnUpdated();
}
public override void Evaluate()
{
IsConditionMet = DataModelConditionGroup.Evaluate();
foreach (DataModelConditionViewModel dataModelConditionViewModel in Items)
dataModelConditionViewModel.Evaluate();
}
public void ConvertToConditionList(DataModelConditionViewModel predicateViewModel)
{
// Store the old index and remove the old predicate

View File

@ -22,6 +22,7 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
@ -79,7 +80,26 @@
</Button.ContextMenu>
</Button>
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}" Margin="0 4 0 0">
<ToggleButton Grid.Row="0"
Grid.Column="3"
Style="{StaticResource MaterialDesignActionToggleButton}"
Focusable="False"
IsHitTestVisible="False"
IsChecked="{Binding IsConditionMet}"
Width="22"
Height="22"
HorizontalAlignment="Left">
<ToggleButton.Content>
<Border Background="#E74C4C" Width="22" Height="22">
<materialDesign:PackIcon Kind="Close" VerticalAlignment="Center" HorizontalAlignment="Center" Width="16" Height="16"/>
</Border>
</ToggleButton.Content>
<materialDesign:ToggleButtonAssist.OnContent>
<materialDesign:PackIcon Kind="Check" Width="16" Height="16"/>
</materialDesign:ToggleButtonAssist.OnContent>
</ToggleButton>
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" ItemsSource="{Binding Items}" Margin="0 4 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms.VisualStyles;
using System.Windows.Media;
using Artemis.Core;
using Artemis.UI.Ninject.Factories;
@ -57,6 +58,13 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
_profileEditorService.UpdateSelectedProfileElement();
}
public override void Evaluate()
{
IsConditionMet = DataModelConditionList.Evaluate();
foreach (DataModelConditionViewModel dataModelConditionViewModel in Items)
dataModelConditionViewModel.Evaluate();
}
public override void Delete()
{
base.Delete();

View File

@ -71,5 +71,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
return wrapper.CreateViewModel(_dataModelUIService, new DataModelUpdateConfiguration(false));
}
public override void Evaluate()
{
throw new NotImplementedException();
}
}
}

View File

@ -27,6 +27,7 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0"
Grid.Column="0"
@ -90,5 +91,24 @@
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsTabStop="False" />
<ToggleButton Grid.Row="0"
Grid.Column="4"
Style="{StaticResource MaterialDesignActionToggleButton}"
Focusable="False"
IsHitTestVisible="False"
IsChecked="{Binding IsConditionMet}"
Width="22"
Height="22"
HorizontalAlignment="Left">
<ToggleButton.Content>
<Border Background="#E74C4C" Width="22" Height="22">
<materialDesign:PackIcon Kind="Close" VerticalAlignment="Center" HorizontalAlignment="Center" Width="16" Height="16"/>
</Border>
</ToggleButton.Content>
<materialDesign:ToggleButtonAssist.OnContent>
<materialDesign:PackIcon Kind="Check" Width="16" Height="16"/>
</materialDesign:ToggleButtonAssist.OnContent>
</ToggleButton>
</Grid>
</UserControl>

View File

@ -42,5 +42,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
{
return LeftSideSelectionViewModel.DataModelPath?.GetPropertyType();
}
public override void Evaluate()
{
IsConditionMet = DataModelConditionPredicate.Evaluate();
}
}
}

View File

@ -81,5 +81,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
return wrapper.CreateViewModel(_dataModelUIService, new DataModelUpdateConfiguration(true));
}
public override void Evaluate()
{
throw new NotImplementedException();
}
}
}

View File

@ -24,9 +24,19 @@
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Margin="0 0 0 -4">
Display conditions
</TextBlock>
<DockPanel Grid.Row="0" Margin="0 -2">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" VerticalAlignment="Center">
Display conditions
</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignSubtitle2TextBlock}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
FontSize="13">
Not applied during editing
</TextBlock>
</DockPanel>
<Separator Grid.Row="1" Grid.Column="0" Style="{StaticResource MaterialDesignDarkSeparator}" Margin="-2 0" />
<Grid Grid.Row="2" Grid.Column="0">

View File

@ -1,6 +1,7 @@
using System;
using System.Linq;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.ProfileEditor.Conditions;
using Artemis.UI.Shared;
@ -12,15 +13,17 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public class DisplayConditionsViewModel : Conductor<DataModelConditionGroupViewModel>, IProfileEditorPanelViewModel
{
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
private readonly ICoreService _coreService;
private readonly IProfileEditorService _profileEditorService;
private RenderProfileElement _renderProfileElement;
private bool _displayStartHint;
private bool _isEventCondition;
public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IDataModelConditionsVmFactory dataModelConditionsVmFactory)
public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IDataModelConditionsVmFactory dataModelConditionsVmFactory, ICoreService coreService)
{
_profileEditorService = profileEditorService;
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
_coreService = coreService;
}
public bool DisplayStartHint
@ -87,12 +90,14 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
protected override void OnInitialActivate()
{
_profileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
_coreService.FrameRendered += CoreServiceOnFrameRendered;
base.OnInitialActivate();
}
protected override void OnClose()
{
_profileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
_coreService.FrameRendered -= CoreServiceOnFrameRendered;
base.OnClose();
}
@ -131,6 +136,11 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
RenderProfileElement.DisplayCondition.ChildRemoved += DisplayConditionOnChildrenModified;
}
private void CoreServiceOnFrameRendered(object? sender, FrameRenderedEventArgs e)
{
ActiveItem?.Evaluate();
}
private void DisplayConditionOnChildrenModified(object sender, EventArgs e)
{
DisplayStartHint = !RenderProfileElement.DisplayCondition.Children.Any();

View File

@ -76,7 +76,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
try
{
PluginConfigurationViewModel viewModel = (PluginConfigurationViewModel) Plugin.Kernel.Get(configurationViewModel.Type);
_windowManager.ShowDialog(new PluginSettingsWindowViewModel(viewModel, Icon));
_windowManager.ShowWindow(new PluginSettingsWindowViewModel(viewModel, Icon));
}
catch (Exception e)
{