mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Conditions - Removed old systems
Data bindings - Removed old systems Data bindings - Implemented node system
This commit is contained in:
1 parent
32d4ec2812
commit
5675d1895b
157 files changed
+784
-8802
No files matched your search
-337
@@ -1,337 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract
|
||||
{
|
||||
public abstract class DataModelConditionPredicateViewModel : DataModelConditionViewModel, IDisposable
|
||||
{
|
||||
private readonly IConditionOperatorService _conditionOperatorService;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly List<Module> _modules;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private DataModelStaticViewModel _rightSideInputViewModel;
|
||||
private DataModelDynamicViewModel _rightSideSelectionViewModel;
|
||||
private BaseConditionOperator _selectedOperator;
|
||||
|
||||
private List<Type> _supportedInputTypes;
|
||||
|
||||
protected DataModelConditionPredicateViewModel(
|
||||
DataModelConditionPredicate dataModelConditionPredicate,
|
||||
List<Module> modules,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
ISettingsService settingsService) : base(dataModelConditionPredicate)
|
||||
{
|
||||
_modules = modules;
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_conditionOperatorService = conditionOperatorService;
|
||||
_supportedInputTypes = new List<Type>();
|
||||
|
||||
SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand);
|
||||
Operators = new BindableCollection<BaseConditionOperator>();
|
||||
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
}
|
||||
|
||||
public DataModelConditionPredicate DataModelConditionPredicate => (DataModelConditionPredicate) Model;
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
|
||||
public bool CanSelectOperator => DataModelConditionPredicate.LeftPath is {IsValid: true};
|
||||
|
||||
public BaseConditionOperator SelectedOperator
|
||||
{
|
||||
get => _selectedOperator;
|
||||
set => SetAndNotify(ref _selectedOperator, value);
|
||||
}
|
||||
|
||||
public DataModelDynamicViewModel RightSideSelectionViewModel
|
||||
{
|
||||
get => _rightSideSelectionViewModel;
|
||||
set => SetAndNotify(ref _rightSideSelectionViewModel, value);
|
||||
}
|
||||
|
||||
public DataModelStaticViewModel RightSideInputViewModel
|
||||
{
|
||||
get => _rightSideInputViewModel;
|
||||
set => SetAndNotify(ref _rightSideInputViewModel, value);
|
||||
}
|
||||
|
||||
public DelegateCommand SelectOperatorCommand { get; }
|
||||
public BindableCollection<BaseConditionOperator> Operators { get; }
|
||||
|
||||
protected SolidColorBrush LeftSideColor { get; set; }
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
IsConditionMet = DataModelConditionPredicate.Evaluate();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public virtual void Initialize()
|
||||
{
|
||||
LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_modules);
|
||||
LeftSideSelectionViewModel.PropertySelected += LeftSideOnPropertySelected;
|
||||
if (LeftSideColor != null)
|
||||
LeftSideSelectionViewModel.ButtonBrush = LeftSideColor;
|
||||
|
||||
// Determine which types are currently supported
|
||||
_supportedInputTypes = GetSupportedInputTypes();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
LeftSideSelectionViewModel.FilterTypes = _supportedInputTypes.ToArray();
|
||||
LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionPredicate.LeftPath);
|
||||
|
||||
Type leftSideType = GetLeftSideType();
|
||||
|
||||
// Get the supported operators
|
||||
Operators.Clear();
|
||||
Operators.AddRange(_conditionOperatorService.GetConditionOperatorsForType(leftSideType ?? typeof(object), ConditionParameterSide.Left));
|
||||
if (DataModelConditionPredicate.Operator == null)
|
||||
DataModelConditionPredicate.UpdateOperator(Operators.FirstOrDefault());
|
||||
// The core doesn't care about best matches so if there is a new preferred operator, use that instead
|
||||
else if (!Operators.Contains(DataModelConditionPredicate.Operator))
|
||||
DataModelConditionPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.Description == DataModelConditionPredicate.Operator.Description) ?? Operators.FirstOrDefault());
|
||||
|
||||
NotifyOfPropertyChange(nameof(CanSelectOperator));
|
||||
SelectedOperator = DataModelConditionPredicate.Operator;
|
||||
|
||||
// Without a selected operator or one that supports a right side, leave the right side input empty
|
||||
if (SelectedOperator?.RightSideType == null)
|
||||
{
|
||||
DisposeRightSideStaticViewModel();
|
||||
DisposeRightSideDynamicViewModel();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the right side has the proper VM
|
||||
if (DataModelConditionPredicate.PredicateType == ProfileRightSideType.Dynamic)
|
||||
{
|
||||
DisposeRightSideStaticViewModel();
|
||||
if (RightSideSelectionViewModel == null)
|
||||
CreateRightSideSelectionViewModel();
|
||||
|
||||
RightSideSelectionViewModel.ChangeDataModelPath(DataModelConditionPredicate.RightPath);
|
||||
RightSideSelectionViewModel.FilterTypes = new[] {SelectedOperator.RightSideType};
|
||||
}
|
||||
else
|
||||
{
|
||||
DisposeRightSideDynamicViewModel();
|
||||
if (RightSideInputViewModel == null)
|
||||
CreateRightSideInputViewModel();
|
||||
|
||||
Type preferredType = DataModelConditionPredicate.GetPreferredRightSideType();
|
||||
if (preferredType != null && RightSideInputViewModel.TargetType != preferredType)
|
||||
RightSideInputViewModel.UpdateTargetType(preferredType);
|
||||
|
||||
RightSideInputViewModel.Value = DataModelConditionPredicate.RightStaticValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyLeftSide()
|
||||
{
|
||||
Type newType = LeftSideSelectionViewModel.DataModelPath.GetPropertyType();
|
||||
bool converted = ConvertIfRequired(newType);
|
||||
if (converted)
|
||||
return;
|
||||
|
||||
DataModelConditionPredicate.UpdateLeftSide(LeftSideSelectionViewModel.DataModelPath);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
|
||||
SelectedOperator = DataModelConditionPredicate.Operator;
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideDynamic()
|
||||
{
|
||||
DataModelConditionPredicate.UpdateRightSideDynamic(RightSideSelectionViewModel.DataModelPath);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideStatic(object value)
|
||||
{
|
||||
DataModelConditionPredicate.UpdateRightSideStatic(value);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyOperator()
|
||||
{
|
||||
DataModelConditionPredicate.UpdateOperator(SelectedOperator);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
protected abstract List<Type> GetSupportedInputTypes();
|
||||
protected abstract Type GetLeftSideType();
|
||||
|
||||
protected virtual List<DataModelPropertiesViewModel> GetExtraRightSideDataModelViewModels()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private void ExecuteSelectOperatorCommand(object context)
|
||||
{
|
||||
if (!(context is BaseConditionOperator dataModelConditionOperator))
|
||||
return;
|
||||
|
||||
SelectedOperator = dataModelConditionOperator;
|
||||
ApplyOperator();
|
||||
}
|
||||
|
||||
public override void UpdateModules()
|
||||
{
|
||||
if (LeftSideSelectionViewModel != null)
|
||||
{
|
||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideOnPropertySelected;
|
||||
LeftSideSelectionViewModel.Dispose();
|
||||
LeftSideSelectionViewModel = null;
|
||||
}
|
||||
DisposeRightSideStaticViewModel();
|
||||
DisposeRightSideDynamicViewModel();
|
||||
|
||||
// If the modules changed the paths may no longer be valid if they targeted a module no longer available, in that case clear the path
|
||||
if (DataModelConditionPredicate.LeftPath?.Target != null && !DataModelConditionPredicate.LeftPath.Target.IsExpansion && !_modules.Contains(DataModelConditionPredicate.LeftPath.Target.Module))
|
||||
DataModelConditionPredicate.UpdateLeftSide(null);
|
||||
if (DataModelConditionPredicate.RightPath?.Target != null && !DataModelConditionPredicate.RightPath.Target.IsExpansion && !_modules.Contains(DataModelConditionPredicate.RightPath.Target.Module))
|
||||
DataModelConditionPredicate.UpdateRightSideDynamic(null);
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (LeftSideSelectionViewModel != null)
|
||||
{
|
||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideOnPropertySelected;
|
||||
LeftSideSelectionViewModel.Dispose();
|
||||
LeftSideSelectionViewModel = null;
|
||||
}
|
||||
|
||||
DisposeRightSideStaticViewModel();
|
||||
DisposeRightSideDynamicViewModel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region View model creation
|
||||
|
||||
private void CreateRightSideSelectionViewModel()
|
||||
{
|
||||
RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_modules);
|
||||
RightSideSelectionViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush");
|
||||
RightSideSelectionViewModel.DisplaySwitchButton = true;
|
||||
RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected;
|
||||
RightSideSelectionViewModel.SwitchToStaticRequested += RightSideSelectionViewModelOnSwitchToStaticRequested;
|
||||
|
||||
List<DataModelPropertiesViewModel> extra = GetExtraRightSideDataModelViewModels();
|
||||
if (extra != null)
|
||||
RightSideSelectionViewModel.ExtraDataModelViewModels.AddRange(extra);
|
||||
}
|
||||
|
||||
private void CreateRightSideInputViewModel()
|
||||
{
|
||||
Type preferredType = DataModelConditionPredicate.GetPreferredRightSideType();
|
||||
RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(preferredType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription());
|
||||
RightSideInputViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush");
|
||||
RightSideInputViewModel.DisplaySwitchButton = true;
|
||||
RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered;
|
||||
RightSideInputViewModel.SwitchToDynamicRequested += RightSideInputViewModelOnSwitchToDynamicRequested;
|
||||
}
|
||||
|
||||
private void DisposeRightSideStaticViewModel()
|
||||
{
|
||||
if (RightSideInputViewModel == null)
|
||||
return;
|
||||
RightSideInputViewModel.ValueUpdated -= RightSideOnValueEntered;
|
||||
RightSideInputViewModel.SwitchToDynamicRequested -= RightSideInputViewModelOnSwitchToDynamicRequested;
|
||||
RightSideInputViewModel.Dispose();
|
||||
RightSideInputViewModel = null;
|
||||
}
|
||||
|
||||
private void DisposeRightSideDynamicViewModel()
|
||||
{
|
||||
if (RightSideSelectionViewModel == null)
|
||||
return;
|
||||
RightSideSelectionViewModel.PropertySelected -= RightSideOnPropertySelected;
|
||||
RightSideSelectionViewModel.SwitchToStaticRequested -= RightSideSelectionViewModelOnSwitchToStaticRequested;
|
||||
RightSideSelectionViewModel.Dispose();
|
||||
RightSideSelectionViewModel = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void LeftSideOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
ApplyLeftSide();
|
||||
}
|
||||
|
||||
private void RightSideOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
ApplyRightSideDynamic();
|
||||
}
|
||||
|
||||
private void RightSideOnValueEntered(object sender, DataModelInputStaticEventArgs e)
|
||||
{
|
||||
ApplyRightSideStatic(e.Value);
|
||||
}
|
||||
|
||||
private void RightSideSelectionViewModelOnSwitchToStaticRequested(object sender, EventArgs e)
|
||||
{
|
||||
DataModelConditionPredicate.PredicateType = ProfileRightSideType.Static;
|
||||
|
||||
// Ensure the right static value is never null when the preferred type is a value type
|
||||
Type preferredType = DataModelConditionPredicate.GetPreferredRightSideType();
|
||||
if (DataModelConditionPredicate.RightStaticValue == null && preferredType != null && preferredType.IsValueType)
|
||||
DataModelConditionPredicate.UpdateRightSideStatic(preferredType.GetDefault());
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
private void RightSideInputViewModelOnSwitchToDynamicRequested(object sender, EventArgs e)
|
||||
{
|
||||
DataModelConditionPredicate.PredicateType = ProfileRightSideType.Dynamic;
|
||||
Update();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Stylet;
|
||||
|
||||
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)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DataModelConditionPart Model { get; }
|
||||
|
||||
public DataModelDynamicViewModel LeftSideSelectionViewModel
|
||||
{
|
||||
get => _leftSideSelectionViewModel;
|
||||
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);
|
||||
((DataModelConditionViewModel) Parent).Update();
|
||||
}
|
||||
|
||||
protected bool ConvertIfRequired(Type newType)
|
||||
{
|
||||
if (newType == null)
|
||||
return false;
|
||||
|
||||
if (!(Parent is DataModelConditionGroupViewModel groupViewModel))
|
||||
return false;
|
||||
|
||||
// List
|
||||
if (newType.IsGenericEnumerable())
|
||||
{
|
||||
if (this is DataModelConditionListViewModel)
|
||||
return false;
|
||||
groupViewModel.ConvertToConditionList(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Predicate
|
||||
if (this is DataModelConditionPredicateViewModel)
|
||||
return false;
|
||||
groupViewModel.ConvertToPredicate(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void UpdateModules();
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.Conditions.DataModelConditionEventView"
|
||||
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.ProfileEditor.Conditions"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<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>
|
||||
<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"
|
||||
ToolTip="Delete the event trigger"
|
||||
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 -->
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
s:View.Model="{Binding LeftSideSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
|
||||
<TextBlock Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Margin="5 0 0 0" Text="{Binding TriggerPastParticiple}">
|
||||
|
||||
</TextBlock>
|
||||
|
||||
<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" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,147 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public sealed class DataModelConditionEventViewModel : DataModelConditionViewModel, IDisposable
|
||||
{
|
||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly List<Module> _modules;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private DateTime _lastTrigger;
|
||||
private string _triggerPastParticiple;
|
||||
|
||||
public DataModelConditionEventViewModel(DataModelConditionEvent dataModelConditionEvent,
|
||||
List<Module> modules,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IDataModelConditionsVmFactory dataModelConditionsVmFactory) : base(dataModelConditionEvent)
|
||||
{
|
||||
_modules = modules;
|
||||
_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 string TriggerPastParticiple
|
||||
{
|
||||
get => _triggerPastParticiple;
|
||||
set => SetAndNotify(ref _triggerPastParticiple, value);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_modules);
|
||||
LeftSideSelectionViewModel.PropertySelected += LeftSideSelectionViewModelOnPropertySelected;
|
||||
LeftSideSelectionViewModel.LoadEventChildren = false;
|
||||
|
||||
IReadOnlyCollection<DataModelVisualizationRegistration> editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
List<Type> supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
supportedInputTypes.Add(typeof(DataModelEvent));
|
||||
supportedInputTypes.Add(typeof(DataModelEvent<>));
|
||||
|
||||
LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray();
|
||||
LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(185, 164, 10));
|
||||
LeftSideSelectionViewModel.Placeholder = "Select an event";
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionEvent.EventPath);
|
||||
|
||||
// Remove VMs of effects no longer applied on the layer
|
||||
Items.RemoveRange(Items.Where(c => !DataModelConditionEvent.Children.Contains(c.Model)).ToList());
|
||||
|
||||
if (DataModelConditionEvent.EventPath == null || !DataModelConditionEvent.EventPath.IsValid)
|
||||
return;
|
||||
|
||||
TriggerPastParticiple = DataModelConditionEvent.GetDataModelEvent()?.TriggerPastParticiple;
|
||||
List<DataModelConditionViewModel> viewModels = new();
|
||||
foreach (DataModelConditionPart childModel in Model.Children)
|
||||
{
|
||||
if (Items.Any(c => c.Model == childModel))
|
||||
continue;
|
||||
if (!(childModel is DataModelConditionGroup dataModelConditionGroup))
|
||||
continue;
|
||||
|
||||
DataModelConditionGroupViewModel viewModel = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, ConditionGroupType.Event, _modules);
|
||||
viewModel.IsRootGroup = true;
|
||||
viewModels.Add(viewModel);
|
||||
}
|
||||
|
||||
if (viewModels.Any())
|
||||
Items.AddRange(viewModels);
|
||||
|
||||
foreach (DataModelConditionViewModel childViewModel in Items)
|
||||
childViewModel.Update();
|
||||
}
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
LastTrigger = DataModelConditionEvent.LastTrigger;
|
||||
IsConditionMet = DataModelConditionEvent.Evaluate();
|
||||
}
|
||||
|
||||
public void ApplyEvent()
|
||||
{
|
||||
DataModelConditionEvent.UpdateEvent(LeftSideSelectionViewModel.DataModelPath);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void UpdateModules()
|
||||
{
|
||||
LeftSideSelectionViewModel.Dispose();
|
||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
Initialize();
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void LeftSideSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
ApplyEvent();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
LeftSideSelectionViewModel.Dispose();
|
||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
<UserControl
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:Converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.Conditions"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.Conditions.DataModelConditionGroupView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type local:DataModelConditionGroupViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<Converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<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"
|
||||
ToolTip="Delete the group and all its children"
|
||||
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||
HorizontalAlignment="Left"
|
||||
Visibility="{Binding IsRootGroup, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}"
|
||||
Width="25"
|
||||
Height="25"
|
||||
Foreground="#E74C4C"
|
||||
Command="{s:Action Delete}">
|
||||
<materialDesign:PackIcon Kind="Close" Width="18" Height="18" />
|
||||
</Button>
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
||||
Background="#E74C4C"
|
||||
BorderBrush="#E74C4C"
|
||||
Margin="3 1"
|
||||
Content="{Binding SelectedBooleanOperator}"
|
||||
Visibility="{Binding DisplayBooleanOperator, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
|
||||
IsEnabled="{Binding IsEventGroup, Converter={StaticResource InverseBooleanConverter}}"
|
||||
ToolTipService.ShowOnDisabled="True">
|
||||
<Button.ToolTip>
|
||||
<StackPanel>
|
||||
<TextBlock Visibility="{Binding IsEventGroup, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
|
||||
Change the operator of the group, determining which conditions should match
|
||||
</TextBlock>
|
||||
<TextBlock Visibility="{Binding IsEventGroup, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
The operator of the root group cannot be changed for event-based conditions
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Button.ToolTip>
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="And"
|
||||
Command="{s:Action SelectBooleanOperator}"
|
||||
CommandParameter="And"
|
||||
ToolTip="All the conditions in the group should evaluate to true" />
|
||||
<MenuItem Header="Or"
|
||||
Command="{s:Action SelectBooleanOperator}"
|
||||
CommandParameter="Or"
|
||||
ToolTip="Any of the conditions in the group should evaluate to true" />
|
||||
<MenuItem Header="And not"
|
||||
Command="{s:Action SelectBooleanOperator}"
|
||||
CommandParameter="AndNot"
|
||||
ToolTip="All the conditions in the group should evaluate to false" />
|
||||
<MenuItem Header="Or not"
|
||||
Command="{s:Action SelectBooleanOperator}"
|
||||
CommandParameter="OrNot"
|
||||
ToolTip="Any of the conditions in the group should evaluate to false" />
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
<Button x:Name="AddChildButton"
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
ToolTip="Add another condition to the current group"
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="#4CE758"
|
||||
Width="25"
|
||||
Height="25">
|
||||
<Button.Style>
|
||||
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MaterialDesignIconForegroundButton}">
|
||||
<Style.Triggers>
|
||||
<EventTrigger RoutedEvent="ButtonBase.Click">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
|
||||
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True" />
|
||||
</BooleanAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Add condition" ToolTip="A condition that evaluates the state of a property in the data model" Command="{s:Action AddCondition}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Equal" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Add event condition"
|
||||
ToolTip="An event condition that responds to data model events"
|
||||
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" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Add group" ToolTip="A group for conditions and other groups" Command="{s:Action AddGroup}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="CodeParentheses" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<materialDesign:PackIcon Kind="Add" Width="18" Height="18" />
|
||||
</Button>
|
||||
|
||||
<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}" Margin="0 3 0 0">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,259 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Humanizer;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public class DataModelConditionGroupViewModel : DataModelConditionViewModel
|
||||
{
|
||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||
private readonly List<Module> _modules;
|
||||
private readonly ICoreService _coreService;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private bool _isEventGroup;
|
||||
private bool _isRootGroup;
|
||||
|
||||
public DataModelConditionGroupViewModel(DataModelConditionGroup dataModelConditionGroup,
|
||||
ConditionGroupType groupType,
|
||||
List<Module> modules,
|
||||
ICoreService coreService,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelConditionsVmFactory dataModelConditionsVmFactory)
|
||||
: base(dataModelConditionGroup)
|
||||
{
|
||||
GroupType = groupType;
|
||||
_modules = modules;
|
||||
_coreService = coreService;
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
|
||||
|
||||
Items.CollectionChanged += (_, _) => NotifyOfPropertyChange(nameof(DisplayBooleanOperator));
|
||||
}
|
||||
|
||||
public ConditionGroupType GroupType { get; }
|
||||
public DataModelConditionGroup DataModelConditionGroup => (DataModelConditionGroup) Model;
|
||||
|
||||
public bool IsRootGroup
|
||||
{
|
||||
get => _isRootGroup;
|
||||
set
|
||||
{
|
||||
if (!SetAndNotify(ref _isRootGroup, value)) return;
|
||||
NotifyOfPropertyChange(nameof(CanAddEventCondition));
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanAddEventCondition => IsRootGroup && GroupType == ConditionGroupType.General;
|
||||
|
||||
public bool IsEventGroup
|
||||
{
|
||||
get => _isEventGroup;
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _isEventGroup, value);
|
||||
NotifyOfPropertyChange(nameof(DisplayEvaluationResult));
|
||||
}
|
||||
}
|
||||
|
||||
public bool DisplayBooleanOperator => Items.Count > 1;
|
||||
public bool DisplayEvaluationResult => GroupType == ConditionGroupType.General && !IsEventGroup;
|
||||
public string SelectedBooleanOperator => DataModelConditionGroup.BooleanOperator.Humanize();
|
||||
|
||||
public void SelectBooleanOperator(string type)
|
||||
{
|
||||
BooleanOperator enumValue = Enum.Parse<BooleanOperator>(type);
|
||||
DataModelConditionGroup.BooleanOperator = enumValue;
|
||||
NotifyOfPropertyChange(nameof(SelectedBooleanOperator));
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddCondition()
|
||||
{
|
||||
switch (GroupType)
|
||||
{
|
||||
case ConditionGroupType.General:
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionGeneralPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic));
|
||||
break;
|
||||
case ConditionGroupType.List:
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic));
|
||||
break;
|
||||
case ConditionGroupType.Event:
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionEventPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
Update();
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddEventCondition()
|
||||
{
|
||||
if (!CanAddEventCondition)
|
||||
return;
|
||||
|
||||
// Find a good spot for the event, behind the last existing event
|
||||
int index = 0;
|
||||
DataModelConditionPart existing = DataModelConditionGroup.Children.LastOrDefault(c => c is DataModelConditionEvent);
|
||||
if (existing != null)
|
||||
index = DataModelConditionGroup.Children.IndexOf(existing) + 1;
|
||||
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionEvent(DataModelConditionGroup), index);
|
||||
|
||||
Update();
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddGroup()
|
||||
{
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionGroup(DataModelConditionGroup));
|
||||
|
||||
Update();
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
NotifyOfPropertyChange(nameof(SelectedBooleanOperator));
|
||||
// Remove VMs of effects no longer applied on the layer
|
||||
List<DataModelConditionViewModel> toRemove = Items.Where(c => !DataModelConditionGroup.Children.Contains(c.Model)).ToList();
|
||||
if (toRemove.Any())
|
||||
Items.RemoveRange(toRemove);
|
||||
|
||||
foreach (DataModelConditionPart childModel in Model.Children)
|
||||
{
|
||||
if (Items.Any(c => c.Model == childModel))
|
||||
continue;
|
||||
|
||||
switch (childModel)
|
||||
{
|
||||
case DataModelConditionGroup dataModelConditionGroup:
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, GroupType, _modules));
|
||||
break;
|
||||
case DataModelConditionList dataModelConditionList:
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionListViewModel(dataModelConditionList, _modules));
|
||||
break;
|
||||
case DataModelConditionEvent dataModelConditionEvent:
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionEventViewModel(dataModelConditionEvent, _modules));
|
||||
break;
|
||||
case DataModelConditionGeneralPredicate dataModelConditionGeneralPredicate:
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionGeneralPredicateViewModel(dataModelConditionGeneralPredicate, _modules));
|
||||
break;
|
||||
case DataModelConditionListPredicate dataModelConditionListPredicate:
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionListPredicateViewModel(dataModelConditionListPredicate, _modules));
|
||||
break;
|
||||
case DataModelConditionEventPredicate dataModelConditionEventPredicate:
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionEventPredicateViewModel(dataModelConditionEventPredicate, _modules));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the items are in the same order as on the model
|
||||
((BindableCollection<DataModelConditionViewModel>) Items).Sort(i => Model.Children.IndexOf(i.Model));
|
||||
foreach (DataModelConditionViewModel childViewModel in Items)
|
||||
childViewModel.Update();
|
||||
|
||||
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 override void UpdateModules()
|
||||
{
|
||||
foreach (DataModelConditionViewModel dataModelConditionViewModel in Items)
|
||||
dataModelConditionViewModel.UpdateModules();
|
||||
}
|
||||
|
||||
public void ConvertToConditionList(DataModelConditionViewModel predicateViewModel)
|
||||
{
|
||||
// Store the old index and remove the old predicate
|
||||
int index = DataModelConditionGroup.Children.IndexOf(predicateViewModel.Model);
|
||||
DataModelConditionGroup.RemoveChild(predicateViewModel.Model);
|
||||
|
||||
// Insert a list in the same position
|
||||
DataModelConditionList list = new(DataModelConditionGroup);
|
||||
list.UpdateList(predicateViewModel.LeftSideSelectionViewModel.DataModelPath);
|
||||
DataModelConditionGroup.AddChild(list, index);
|
||||
|
||||
// Update to switch the VMs
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ConvertToPredicate(DataModelConditionViewModel listViewModel)
|
||||
{
|
||||
// Store the old index and remove the old predicate
|
||||
int index = DataModelConditionGroup.Children.IndexOf(listViewModel.Model);
|
||||
DataModelConditionGroup.RemoveChild(listViewModel.Model);
|
||||
|
||||
// Insert a list in the same position
|
||||
DataModelConditionGeneralPredicate predicate = new(DataModelConditionGroup, ProfileRightSideType.Dynamic);
|
||||
predicate.UpdateLeftSide(listViewModel.LeftSideSelectionViewModel.DataModelPath);
|
||||
DataModelConditionGroup.AddChild(predicate, index);
|
||||
|
||||
// Update to switch the VMs
|
||||
Update();
|
||||
}
|
||||
|
||||
private void CoreServiceOnFrameRendered(object sender, FrameRenderedEventArgs e)
|
||||
{
|
||||
if (IsRootGroup)
|
||||
Evaluate();
|
||||
}
|
||||
|
||||
public event EventHandler Updated;
|
||||
|
||||
#region Overrides of Screen
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
base.OnInitialActivate();
|
||||
Update();
|
||||
_coreService.FrameRendered += CoreServiceOnFrameRendered;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnClose()
|
||||
{
|
||||
_coreService.FrameRendered -= CoreServiceOnFrameRendered;
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected virtual void OnUpdated()
|
||||
{
|
||||
Updated?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConditionGroupType
|
||||
{
|
||||
General,
|
||||
List,
|
||||
Event
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.Conditions.DataModelConditionListView"
|
||||
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:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.Conditions"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance Type=local:DataModelConditionListViewModel, IsDesignTimeCreatable=False}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<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"
|
||||
ToolTip="Delete the list predicate and all its children"
|
||||
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 -->
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
s:View.Model="{Binding LeftSideSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
|
||||
<!-- Operator -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedListOperator}"
|
||||
Click="PropertyButton_OnClick"
|
||||
HorizontalAlignment="Left"
|
||||
ToolTip="Change the list operator, determining how the list contents should match">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Any"
|
||||
Command="{s:Action SelectListOperator}"
|
||||
CommandParameter="Any"
|
||||
ToolTip="Any of the list items should evaluate to true" />
|
||||
<MenuItem Header="All"
|
||||
Command="{s:Action SelectListOperator}"
|
||||
CommandParameter="All"
|
||||
ToolTip="All of the list items should evaluate to true" />
|
||||
<MenuItem Header="None"
|
||||
Command="{s:Action SelectListOperator}"
|
||||
CommandParameter="None"
|
||||
ToolTip="None of the list items should evaluate to true" />
|
||||
<MenuItem Header="Count (NYI)"
|
||||
Command="{s:Action SelectListOperator}"
|
||||
CommandParameter="Count"
|
||||
IsEnabled="False"
|
||||
ToolTip="A specific amount of the list items should evaluate to true" />
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
<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" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,26 +0,0 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DataModelConditionListView.xaml
|
||||
/// </summary>
|
||||
public partial class DataModelConditionListView : UserControl
|
||||
{
|
||||
public DataModelConditionListView()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Humanizer;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public sealed class DataModelConditionListViewModel : DataModelConditionViewModel, IDisposable
|
||||
{
|
||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly List<Module> _modules;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
|
||||
public DataModelConditionListViewModel(DataModelConditionList dataModelConditionList,
|
||||
List<Module> modules,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IDataModelConditionsVmFactory dataModelConditionsVmFactory) : base(dataModelConditionList)
|
||||
{
|
||||
_modules = modules;
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
|
||||
}
|
||||
|
||||
public DataModelConditionList DataModelConditionList => (DataModelConditionList) Model;
|
||||
|
||||
public string SelectedListOperator => DataModelConditionList.ListOperator.Humanize();
|
||||
|
||||
public void SelectListOperator(string type)
|
||||
{
|
||||
ListOperator enumValue = Enum.Parse<ListOperator>(type);
|
||||
DataModelConditionList.ListOperator = enumValue;
|
||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddCondition()
|
||||
{
|
||||
DataModelConditionList.AddChild(new DataModelConditionGeneralPredicate(DataModelConditionList, ProfileRightSideType.Dynamic));
|
||||
|
||||
Update();
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddGroup()
|
||||
{
|
||||
DataModelConditionList.AddChild(new DataModelConditionGroup(DataModelConditionList));
|
||||
|
||||
Update();
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
IsConditionMet = DataModelConditionList.Evaluate();
|
||||
foreach (DataModelConditionViewModel dataModelConditionViewModel in Items)
|
||||
dataModelConditionViewModel.Evaluate();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void UpdateModules()
|
||||
{
|
||||
foreach (DataModelConditionViewModel dataModelConditionViewModel in Items)
|
||||
dataModelConditionViewModel.UpdateModules();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_modules);
|
||||
LeftSideSelectionViewModel.PropertySelected += LeftSideSelectionViewModelOnPropertySelected;
|
||||
|
||||
IReadOnlyCollection<DataModelVisualizationRegistration> editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
List<Type> supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
supportedInputTypes.Add(typeof(IEnumerable<>));
|
||||
|
||||
LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray();
|
||||
LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(71, 108, 188));
|
||||
LeftSideSelectionViewModel.Placeholder = "Select a list";
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyList()
|
||||
{
|
||||
Type newType = LeftSideSelectionViewModel.DataModelPath.GetPropertyType();
|
||||
bool converted = ConvertIfRequired(newType);
|
||||
if (converted)
|
||||
return;
|
||||
|
||||
DataModelConditionList.UpdateList(LeftSideSelectionViewModel.DataModelPath);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionList.ListPath);
|
||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||
|
||||
// Remove VMs of effects no longer applied on the layer
|
||||
Items.RemoveRange(Items.Where(c => !DataModelConditionList.Children.Contains(c.Model)).ToList());
|
||||
|
||||
if (DataModelConditionList.ListPath == null || !DataModelConditionList.ListPath.IsValid)
|
||||
return;
|
||||
|
||||
List<DataModelConditionViewModel> viewModels = new();
|
||||
foreach (DataModelConditionPart childModel in Model.Children)
|
||||
{
|
||||
if (Items.Any(c => c.Model == childModel))
|
||||
continue;
|
||||
if (!(childModel is DataModelConditionGroup dataModelConditionGroup))
|
||||
continue;
|
||||
|
||||
DataModelConditionGroupViewModel viewModel = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, ConditionGroupType.List, _modules);
|
||||
viewModel.IsRootGroup = true;
|
||||
viewModels.Add(viewModel);
|
||||
}
|
||||
|
||||
if (viewModels.Any())
|
||||
Items.AddRange(viewModels);
|
||||
|
||||
foreach (DataModelConditionViewModel childViewModel in Items)
|
||||
childViewModel.Update();
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
Initialize();
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
private void LeftSideSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
ApplyList();
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
LeftSideSelectionViewModel.Dispose();
|
||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
<UserControl
|
||||
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:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:DataModelConditions="clr-namespace:Artemis.UI.Screens.ProfileEditor.Conditions"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.Conditions.DataModelConditionEventPredicateView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type DataModelConditions:DataModelConditionEventPredicateViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0 0 0 3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
ToolTip="Delete the predicate"
|
||||
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 -->
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
s:View.Model="{Binding LeftSideSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
|
||||
<!-- Operator -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedOperator.Description}"
|
||||
IsEnabled="{Binding CanSelectOperator}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding Operators}">
|
||||
<ContextMenu.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Kind="{Binding Icon}" VerticalAlignment="Center" Margin="0 0 15 0" />
|
||||
<TextBlock Text="{Binding Description}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ContextMenu.ItemTemplate>
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="Command" Value="{Binding Data.SelectOperatorCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
<!-- Right side, either a selection or an input -->
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
s:View.Model="{Binding RightSideSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
s:View.Model="{Binding RightSideInputViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DataModelConditionEventPredicateView.xaml
|
||||
/// </summary>
|
||||
public partial class DataModelConditionEventPredicateView : UserControl
|
||||
{
|
||||
public DataModelConditionEventPredicateView()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public class DataModelConditionEventPredicateViewModel : DataModelConditionPredicateViewModel
|
||||
{
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
|
||||
public DataModelConditionEventPredicateViewModel(DataModelConditionEventPredicate dataModelConditionEventPredicate,
|
||||
List<Module> modules,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
ISettingsService settingsService)
|
||||
: base(dataModelConditionEventPredicate, modules, profileEditorService, dataModelUIService, conditionOperatorService, settingsService)
|
||||
{
|
||||
_dataModelUIService = dataModelUIService;
|
||||
|
||||
LeftSideColor = new SolidColorBrush(Color.FromRgb(185, 164, 10));
|
||||
}
|
||||
|
||||
public DataModelConditionEventPredicate DataModelConditionEventPredicate => (DataModelConditionEventPredicate) Model;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
DataModelPropertiesViewModel eventDataModel = GetEventDataModel();
|
||||
LeftSideSelectionViewModel.ChangeDataModel(eventDataModel);
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
base.OnInitialActivate();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected override List<Type> GetSupportedInputTypes()
|
||||
{
|
||||
IReadOnlyCollection<DataModelVisualizationRegistration> editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
List<Type> supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
|
||||
return supportedInputTypes;
|
||||
}
|
||||
|
||||
protected override Type GetLeftSideType()
|
||||
{
|
||||
return LeftSideSelectionViewModel.DataModelPath?.GetPropertyType();
|
||||
}
|
||||
|
||||
protected override List<DataModelPropertiesViewModel> GetExtraRightSideDataModelViewModels()
|
||||
{
|
||||
// Only the VM housing the event arguments is expected here which is a DataModelPropertiesViewModel
|
||||
return GetEventDataModel().Children.Cast<DataModelPropertiesViewModel>().ToList();
|
||||
}
|
||||
|
||||
private DataModelPropertiesViewModel GetEventDataModel()
|
||||
{
|
||||
EventPredicateWrapperDataModel wrapper = EventPredicateWrapperDataModel.Create(
|
||||
DataModelConditionEventPredicate.DataModelConditionEvent.EventArgumentType
|
||||
);
|
||||
|
||||
return wrapper.CreateViewModel(_dataModelUIService, new DataModelUpdateConfiguration(false));
|
||||
}
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
<UserControl
|
||||
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:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:conditions="clr-namespace:Artemis.UI.Screens.ProfileEditor.Conditions"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.Conditions.DataModelConditionGeneralPredicateView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type conditions:DataModelConditionGeneralPredicateViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0 0 0 3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
ToolTip="Delete the predicate"
|
||||
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, always a property -->
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
s:View.Model="{Binding LeftSideSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
|
||||
<!-- Operator -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedOperator.Description}"
|
||||
IsEnabled="{Binding CanSelectOperator}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding Operators}">
|
||||
<ContextMenu.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Kind="{Binding Icon}" VerticalAlignment="Center" Margin="0 0 15 0" />
|
||||
<TextBlock Text="{Binding Description}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ContextMenu.ItemTemplate>
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="Command" Value="{Binding Data.SelectOperatorCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
<!-- Right side, either a selection or an input -->
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
s:View.Model="{Binding RightSideSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
s:View.Model="{Binding RightSideInputViewModel}"
|
||||
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>
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DataModelConditionGeneralPredicateView.xaml
|
||||
/// </summary>
|
||||
public partial class DataModelConditionGeneralPredicateView : UserControl
|
||||
{
|
||||
public DataModelConditionGeneralPredicateView()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public class DataModelConditionGeneralPredicateViewModel : DataModelConditionPredicateViewModel
|
||||
{
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
|
||||
public DataModelConditionGeneralPredicateViewModel(DataModelConditionGeneralPredicate dataModelConditionGeneralPredicate,
|
||||
List<Module> modules,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
ISettingsService settingsService)
|
||||
: base(dataModelConditionGeneralPredicate, modules, profileEditorService, dataModelUIService, conditionOperatorService, settingsService)
|
||||
{
|
||||
_dataModelUIService = dataModelUIService;
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected override List<Type> GetSupportedInputTypes()
|
||||
{
|
||||
IReadOnlyCollection<DataModelVisualizationRegistration> editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
List<Type> supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
supportedInputTypes.Add(typeof(IEnumerable<>));
|
||||
|
||||
return supportedInputTypes;
|
||||
}
|
||||
|
||||
protected override Type GetLeftSideType()
|
||||
{
|
||||
return LeftSideSelectionViewModel.DataModelPath?.GetPropertyType();
|
||||
}
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
IsConditionMet = DataModelConditionPredicate.Evaluate();
|
||||
}
|
||||
}
|
||||
}
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
<UserControl
|
||||
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:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:DataModelConditions="clr-namespace:Artemis.UI.Screens.ProfileEditor.Conditions"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.Conditions.DataModelConditionListPredicateView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type DataModelConditions:DataModelConditionListPredicateViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0 0 0 3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
ToolTip="Delete the predicate"
|
||||
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, always a property -->
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
s:View.Model="{Binding LeftSideSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
|
||||
<!-- Operator -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedOperator.Description}"
|
||||
IsEnabled="{Binding CanSelectOperator}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding Operators}">
|
||||
<ContextMenu.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Kind="{Binding Icon}" VerticalAlignment="Center" Margin="0 0 15 0" />
|
||||
<TextBlock Text="{Binding Description}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ContextMenu.ItemTemplate>
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="Command" Value="{Binding Data.SelectOperatorCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
<!-- Right side, either a selection or an input -->
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
s:View.Model="{Binding RightSideSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
s:View.Model="{Binding RightSideInputViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DataModelConditionListPredicateView.xaml
|
||||
/// </summary>
|
||||
public partial class DataModelConditionListPredicateView : UserControl
|
||||
{
|
||||
public DataModelConditionListPredicateView()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public class DataModelConditionListPredicateViewModel : DataModelConditionPredicateViewModel
|
||||
{
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
|
||||
public DataModelConditionListPredicateViewModel(DataModelConditionListPredicate dataModelConditionListPredicate,
|
||||
List<Module> modules,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
ISettingsService settingsService)
|
||||
: base(dataModelConditionListPredicate, modules, profileEditorService, dataModelUIService, conditionOperatorService, settingsService)
|
||||
{
|
||||
_dataModelUIService = dataModelUIService;
|
||||
LeftSideColor = new SolidColorBrush(Color.FromRgb(71, 108, 188));
|
||||
}
|
||||
|
||||
public DataModelConditionListPredicate DataModelConditionListPredicate => (DataModelConditionListPredicate) Model;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
DataModelPropertiesViewModel listDataModel = GetListDataModel();
|
||||
LeftSideSelectionViewModel.ChangeDataModel(listDataModel);
|
||||
|
||||
// If this is a primitive list the user doesn't have much to choose, so preselect the list item for them
|
||||
if (DataModelConditionListPredicate.DataModelConditionList.IsPrimitiveList && DataModelConditionListPredicate.LeftPath == null)
|
||||
{
|
||||
DataModelConditionListPredicate.UpdateLeftSide(listDataModel.Children.FirstOrDefault()?.DataModelPath);
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void UpdateModules()
|
||||
{
|
||||
foreach (DataModelConditionViewModel dataModelConditionViewModel in Items)
|
||||
dataModelConditionViewModel.UpdateModules();
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
base.OnInitialActivate();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected override List<Type> GetSupportedInputTypes()
|
||||
{
|
||||
IReadOnlyCollection<DataModelVisualizationRegistration> editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
List<Type> supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
|
||||
return supportedInputTypes;
|
||||
}
|
||||
|
||||
protected override Type GetLeftSideType()
|
||||
{
|
||||
return DataModelConditionListPredicate.DataModelConditionList.IsPrimitiveList
|
||||
? DataModelConditionListPredicate.DataModelConditionList.ListType
|
||||
: LeftSideSelectionViewModel.DataModelPath?.GetPropertyType();
|
||||
}
|
||||
|
||||
protected override List<DataModelPropertiesViewModel> GetExtraRightSideDataModelViewModels()
|
||||
{
|
||||
if (GetListDataModel()?.Children?.FirstOrDefault() is DataModelPropertiesViewModel listValue)
|
||||
return new List<DataModelPropertiesViewModel> {listValue};
|
||||
return null;
|
||||
}
|
||||
|
||||
private DataModelPropertiesViewModel GetListDataModel()
|
||||
{
|
||||
ListPredicateWrapperDataModel wrapper = ListPredicateWrapperDataModel.Create(
|
||||
DataModelConditionListPredicate.DataModelConditionList.ListType!,
|
||||
DataModelConditionListPredicate.DataModelConditionList.ListPath?.GetPropertyDescription()?.ListItemName
|
||||
);
|
||||
|
||||
return wrapper.CreateViewModel(_dataModelUIService, new DataModelUpdateConfiguration(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-8
@@ -2,14 +2,13 @@
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
{
|
||||
public class DisplayConditionsViewModel : Conductor<DataModelConditionGroupViewModel>, IProfileEditorPanelViewModel
|
||||
public class DisplayConditionsViewModel : Screen, IProfileEditorPanelViewModel
|
||||
{
|
||||
private readonly INodeVmFactory _nodeVmFactory;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
@@ -103,12 +102,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
NotifyOfPropertyChange(nameof(AlwaysFinishTimeline));
|
||||
NotifyOfPropertyChange(nameof(ConditionBehaviourEnabled));
|
||||
|
||||
if (renderProfileElement == null)
|
||||
{
|
||||
ActiveItem = null;
|
||||
return;
|
||||
}
|
||||
|
||||
RenderProfileElement.Timeline.PropertyChanged += TimelineOnPropertyChanged;
|
||||
}
|
||||
|
||||
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding.ConditionalDataBindingModeView"
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:dd="urn:gong-wpf-dragdrop"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Button Grid.Row="0"
|
||||
Style="{StaticResource DataModelConditionButton}"
|
||||
Background="{StaticResource PrimaryHueMidBrush}"
|
||||
BorderBrush="{StaticResource PrimaryHueMidBrush}"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{s:Action AddCondition}"
|
||||
Margin="0 5">
|
||||
ADD CONDITION
|
||||
</Button>
|
||||
|
||||
<ListBox Grid.Row="1"
|
||||
ItemsSource="{Binding Items}"
|
||||
materialDesign:RippleAssist.IsDisabled="True"
|
||||
dd:DragDrop.IsDragSource="True"
|
||||
dd:DragDrop.IsDropTarget="True"
|
||||
dd:DragDrop.UseDefaultDragAdorner="True"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
VirtualizingPanel.ScrollUnit="Pixel"
|
||||
Margin="-10 0 -10 -5">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False"/>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
|
||||
{
|
||||
public sealed class ConditionalDataBindingModeViewModel<TLayerProperty, TProperty> : Conductor<DataBindingConditionViewModel<TLayerProperty, TProperty>>.Collection.AllActive,
|
||||
IDataBindingModeViewModel
|
||||
{
|
||||
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private bool _updating;
|
||||
|
||||
public ConditionalDataBindingModeViewModel(ConditionalDataBinding<TLayerProperty, TProperty> conditionalDataBinding,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataBindingsVmFactory dataBindingsVmFactory)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataBindingsVmFactory = dataBindingsVmFactory;
|
||||
|
||||
ConditionalDataBinding = conditionalDataBinding;
|
||||
}
|
||||
|
||||
public ConditionalDataBinding<TLayerProperty, TProperty> ConditionalDataBinding { get; }
|
||||
|
||||
public void AddCondition()
|
||||
{
|
||||
DataBindingCondition<TLayerProperty, TProperty> condition = ConditionalDataBinding.AddCondition();
|
||||
|
||||
// Find the VM of the new condition
|
||||
DataBindingConditionViewModel<TLayerProperty, TProperty> viewModel = Items.First(c => c.DataBindingCondition == condition);
|
||||
viewModel.ActiveItem.AddCondition();
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void RemoveCondition(DataBindingCondition<TLayerProperty, TProperty> dataBindingCondition)
|
||||
{
|
||||
ConditionalDataBinding.RemoveCondition(dataBindingCondition);
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
Initialize();
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
private void UpdateItems()
|
||||
{
|
||||
_updating = true;
|
||||
|
||||
// Remove old VMs
|
||||
List<DataBindingConditionViewModel<TLayerProperty, TProperty>> toRemove = Items.Where(c => !ConditionalDataBinding.Conditions.Contains(c.DataBindingCondition)).ToList();
|
||||
foreach (DataBindingConditionViewModel<TLayerProperty, TProperty> dataBindingConditionViewModel in toRemove)
|
||||
{
|
||||
Items.Remove(dataBindingConditionViewModel);
|
||||
dataBindingConditionViewModel.Dispose();
|
||||
}
|
||||
|
||||
// Add missing VMs
|
||||
foreach (DataBindingCondition<TLayerProperty, TProperty> condition in ConditionalDataBinding.Conditions)
|
||||
if (Items.All(c => c.DataBindingCondition != condition))
|
||||
Items.Add(_dataBindingsVmFactory.DataBindingConditionViewModel(condition));
|
||||
|
||||
// Fix order
|
||||
((BindableCollection<DataBindingConditionViewModel<TLayerProperty, TProperty>>) Items).Sort(c => c.DataBindingCondition.Order);
|
||||
|
||||
_updating = false;
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
ConditionalDataBinding.ConditionsUpdated += ConditionalDataBindingOnConditionsUpdated;
|
||||
Items.CollectionChanged += ItemsOnCollectionChanged;
|
||||
UpdateItems();
|
||||
}
|
||||
|
||||
private void ItemsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (_updating || e.Action != NotifyCollectionChangedAction.Add)
|
||||
return;
|
||||
|
||||
for (int index = 0; index < Items.Count; index++)
|
||||
{
|
||||
DataBindingConditionViewModel<TLayerProperty, TProperty> conditionViewModel = Items[index];
|
||||
conditionViewModel.DataBindingCondition.Order = index + 1;
|
||||
}
|
||||
|
||||
ConditionalDataBinding.ApplyOrder();
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void ConditionalDataBindingOnConditionsUpdated(object sender, EventArgs e)
|
||||
{
|
||||
UpdateItems();
|
||||
}
|
||||
|
||||
public bool SupportsTestValue => false;
|
||||
|
||||
public void Update()
|
||||
{
|
||||
UpdateItems();
|
||||
}
|
||||
|
||||
public object GetTestValue()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
ConditionalDataBinding.ConditionsUpdated -= ConditionalDataBindingOnConditionsUpdated;
|
||||
|
||||
foreach (DataBindingConditionViewModel<TLayerProperty, TProperty> conditionViewModel in Items)
|
||||
conditionViewModel.Dispose();
|
||||
Items.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding.DataBindingConditionView"
|
||||
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:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Border BorderThickness="0 0 0 1"
|
||||
BorderBrush="{DynamicResource MaterialDesignDivider}"
|
||||
Margin="0 0 0 -4"
|
||||
Padding="0 4"
|
||||
Background="Transparent">
|
||||
<Border.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Add new condition" Command="{s:Action AddCondition}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="CodeNotEqual" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="Duplicate" Command="{s:Action DuplicateCondition}" InputGestureText="Ctrl+D" IsEnabled="False">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ContentDuplicate" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Copy" Command="{s:Action CopyCondition}" InputGestureText="Ctrl+C" IsEnabled="False">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ContentCopy" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Paste" Command="{s:Action PasteCondition}" InputGestureText="Ctrl+V" IsEnabled="False">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ContentPaste" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="Delete" Command="{s:Action RemoveCondition}" InputGestureText="Del">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="TrashCan" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</Border.ContextMenu>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ContentControl Grid.Row="0"
|
||||
s:View.Model="{Binding ActiveItem}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False"
|
||||
Margin="0 -10 0 0"/>
|
||||
|
||||
<ContentControl Grid.Row="1"
|
||||
Margin="26 0 0 0"
|
||||
s:View.Model="{Binding ValueViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
|
||||
{
|
||||
public sealed class DataBindingConditionViewModel<TLayerProperty, TProperty> : Conductor<DataModelConditionGroupViewModel>, IDisposable
|
||||
{
|
||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
|
||||
public DataBindingConditionViewModel(DataBindingCondition<TLayerProperty, TProperty> dataBindingCondition,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelConditionsVmFactory dataModelConditionsVmFactory,
|
||||
IDataModelUIService dataModelUIService)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
DataBindingCondition = dataBindingCondition;
|
||||
}
|
||||
|
||||
public DataBindingCondition<TLayerProperty, TProperty> DataBindingCondition { get; }
|
||||
|
||||
public DataModelStaticViewModel ValueViewModel { get; set; }
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
base.OnInitialActivate();
|
||||
List<Module> modules = new();
|
||||
if (_profileEditorService.SelectedProfileConfiguration?.Module != null)
|
||||
modules.Add(_profileEditorService.SelectedProfileConfiguration.Module);
|
||||
ActiveItem = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(DataBindingCondition.Condition, ConditionGroupType.General, modules);
|
||||
ActiveItem.IsRootGroup = true;
|
||||
|
||||
ActiveItem.Update();
|
||||
ActiveItem.Updated += ActiveItemOnUpdated;
|
||||
|
||||
ValueViewModel = _dataModelUIService.GetStaticInputViewModel(typeof(TProperty), null);
|
||||
ValueViewModel.ValueUpdated += ValueViewModelOnValueUpdated;
|
||||
ValueViewModel.Value = DataBindingCondition.Value;
|
||||
}
|
||||
|
||||
private void ActiveItemOnUpdated(object sender, EventArgs e)
|
||||
{
|
||||
if (!ActiveItem.GetChildren().Any())
|
||||
DataBindingCondition.ConditionalDataBinding.RemoveCondition(DataBindingCondition);
|
||||
}
|
||||
|
||||
private void ValueViewModelOnValueUpdated(object sender, DataModelInputStaticEventArgs e)
|
||||
{
|
||||
DataBindingCondition.Value = (TProperty) Convert.ChangeType(e.Value, typeof(TProperty));
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddCondition()
|
||||
{
|
||||
((ConditionalDataBindingModeViewModel<TLayerProperty, TProperty>) Parent).AddCondition();
|
||||
}
|
||||
|
||||
public void RemoveCondition()
|
||||
{
|
||||
((ConditionalDataBindingModeViewModel<TLayerProperty, TProperty>)Parent).RemoveCondition(DataBindingCondition);
|
||||
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
ValueViewModel?.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+4
-16
@@ -5,6 +5,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls;assembly=Artemis.VisualScripting"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
@@ -36,16 +37,8 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ComboBox Grid.Row="0"
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}"
|
||||
Margin="0 5"
|
||||
materialDesign:HintAssist.Hint="Data binding mode"
|
||||
MinWidth="128"
|
||||
SelectedValue="{Binding SelectedDataBindingMode}"
|
||||
ItemsSource="{Binding DataBindingModes}"
|
||||
SelectedValuePath="Value"
|
||||
DisplayMemberPath="Description" />
|
||||
|
||||
<CheckBox Grid.Row="0" Margin="0 10" IsChecked="{Binding IsDataBindingEnabled}">Enable data binding</CheckBox>
|
||||
|
||||
<TextBox Grid.Row="1"
|
||||
Style="{StaticResource MaterialDesignFilledTextBox}"
|
||||
Margin="0 5"
|
||||
@@ -168,12 +161,7 @@
|
||||
</materialDesign:Card>
|
||||
|
||||
<materialDesign:Card Grid.Column="1" UniformCornerRadius="0" Background="{DynamicResource MaterialDesignToolBarBackground}" Panel.ZIndex="1">
|
||||
<Grid Margin="10 5">
|
||||
<ContentControl s:View.Model="{Binding ActiveItem}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
</Grid>
|
||||
<controls:VisualScriptEditor Script="{Binding Script}" AvailableNodes="{Binding AvailableNodes}"></controls:VisualScriptEditor>
|
||||
</materialDesign:Card>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
+127
-189
@@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Timers;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.Storage.Entities.Profile.DataBindings;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
@@ -13,63 +12,62 @@ using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
{
|
||||
public sealed class DataBindingViewModel<TLayerProperty, TProperty> : Conductor<IDataBindingModeViewModel>, IDataBindingViewModel
|
||||
public sealed class DataBindingViewModel<TLayerProperty, TProperty> : Screen, IDataBindingViewModel
|
||||
{
|
||||
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
||||
private readonly ICoreService _coreService;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private int _easingTime;
|
||||
private bool _isDataBindingEnabled;
|
||||
private bool _isEasingTimeEnabled;
|
||||
private DataBindingModeType _selectedDataBindingMode;
|
||||
private DateTime _lastUpdate;
|
||||
private TimelineEasingViewModel _selectedEasingViewModel;
|
||||
|
||||
private bool _updating;
|
||||
private bool _updatingTestResult;
|
||||
private DateTime _lastUpdate;
|
||||
|
||||
public DataBindingViewModel(DataBindingRegistration<TLayerProperty, TProperty> registration,
|
||||
ICoreService coreService,
|
||||
ISettingsService settingsService,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IDataBindingsVmFactory dataBindingsVmFactory)
|
||||
INodeService nodeService)
|
||||
{
|
||||
Registration = registration;
|
||||
_coreService = coreService;
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataBindingsVmFactory = dataBindingsVmFactory;
|
||||
|
||||
DisplayName = Registration.DisplayName.ToUpper();
|
||||
AlwaysApplyDataBindings = settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", true);
|
||||
DataBindingModes = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(DataBindingModeType)));
|
||||
EasingViewModels = new BindableCollection<TimelineEasingViewModel>();
|
||||
AvailableNodes = nodeService.AvailableNodes;
|
||||
TestInputValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
|
||||
TestResultValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
|
||||
}
|
||||
|
||||
public DataBindingRegistration<TLayerProperty, TProperty> Registration { get; }
|
||||
public NodeScript<TProperty> Script => Registration.DataBinding?.Script;
|
||||
|
||||
public PluginSetting<bool> AlwaysApplyDataBindings { get; }
|
||||
public BindableCollection<ValueDescription> DataBindingModes { get; }
|
||||
public BindableCollection<TimelineEasingViewModel> EasingViewModels { get; }
|
||||
public IEnumerable<NodeData> AvailableNodes { get; }
|
||||
public DataModelDisplayViewModel TestInputValue { get; }
|
||||
public DataModelDisplayViewModel TestResultValue { get; }
|
||||
|
||||
public DataBindingModeType SelectedDataBindingMode
|
||||
{
|
||||
get => _selectedDataBindingMode;
|
||||
set
|
||||
{
|
||||
if (!SetAndNotify(ref _selectedDataBindingMode, value)) return;
|
||||
ApplyDataBindingMode();
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDataBindingEnabled
|
||||
{
|
||||
get => _isDataBindingEnabled;
|
||||
set => SetAndNotify(ref _isDataBindingEnabled, value);
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _isDataBindingEnabled, value);
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
if (value)
|
||||
EnableDataBinding();
|
||||
else
|
||||
DisableDataBinding();
|
||||
}
|
||||
}
|
||||
|
||||
public TimelineEasingViewModel SelectedEasingViewModel
|
||||
@@ -102,162 +100,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
Initialize();
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast<Easings.Functions>().Select(v => new TimelineEasingViewModel(v, false)));
|
||||
|
||||
_lastUpdate = DateTime.Now;
|
||||
_coreService.FrameRendered += OnFrameRendered;
|
||||
CreateDataBindingModeModeViewModel();
|
||||
Update();
|
||||
}
|
||||
|
||||
private void CreateDataBindingModeModeViewModel()
|
||||
{
|
||||
if (Registration.DataBinding?.DataBindingMode == null)
|
||||
{
|
||||
ActiveItem = null;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Registration.DataBinding.DataBindingMode)
|
||||
{
|
||||
case DirectDataBinding<TLayerProperty, TProperty> directDataBinding:
|
||||
ActiveItem = _dataBindingsVmFactory.DirectDataBindingModeViewModel(directDataBinding);
|
||||
break;
|
||||
case ConditionalDataBinding<TLayerProperty, TProperty> conditionalDataBinding:
|
||||
ActiveItem = _dataBindingsVmFactory.ConditionalDataBindingModeViewModel(conditionalDataBinding);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
if (Registration.DataBinding == null)
|
||||
{
|
||||
IsDataBindingEnabled = false;
|
||||
IsEasingTimeEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_updating = true;
|
||||
|
||||
IsDataBindingEnabled = ActiveItem != null;
|
||||
EasingTime = (int) Registration.DataBinding.EasingTime.TotalMilliseconds;
|
||||
SelectedEasingViewModel = EasingViewModels.First(vm => vm.EasingFunction == Registration.DataBinding.EasingFunction);
|
||||
IsEasingTimeEnabled = EasingTime > 0;
|
||||
SelectedDataBindingMode = Registration.DataBinding.DataBindingMode switch
|
||||
{
|
||||
DirectDataBinding<TLayerProperty, TProperty> _ => DataBindingModeType.Direct,
|
||||
ConditionalDataBinding<TLayerProperty, TProperty> _ => DataBindingModeType.Conditional,
|
||||
_ => DataBindingModeType.None
|
||||
};
|
||||
|
||||
ActiveItem?.Update();
|
||||
|
||||
_updating = false;
|
||||
}
|
||||
|
||||
private void ApplyChanges()
|
||||
{
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
if (Registration.DataBinding != null)
|
||||
{
|
||||
Registration.DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime);
|
||||
Registration.DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear;
|
||||
}
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
Update();
|
||||
}
|
||||
|
||||
private void ApplyDataBindingMode()
|
||||
{
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
if (Registration.DataBinding != null && SelectedDataBindingMode == DataBindingModeType.None)
|
||||
RemoveDataBinding();
|
||||
else
|
||||
{
|
||||
if (Registration.DataBinding == null && SelectedDataBindingMode != DataBindingModeType.None)
|
||||
EnableDataBinding();
|
||||
|
||||
Registration.DataBinding!.ChangeDataBindingMode(SelectedDataBindingMode);
|
||||
}
|
||||
|
||||
CreateDataBindingModeModeViewModel();
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void UpdateTestResult()
|
||||
{
|
||||
if (_updating || _updatingTestResult)
|
||||
return;
|
||||
|
||||
_updatingTestResult = true;
|
||||
if (Registration.DataBinding == null || ActiveItem == null)
|
||||
{
|
||||
TestInputValue.UpdateValue(default);
|
||||
TestResultValue.UpdateValue(default);
|
||||
_updatingTestResult = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If always update is disabled, do constantly update the data binding as long as the view model is open
|
||||
// If always update is enabled, this is done for all data bindings in ProfileViewModel
|
||||
if (!AlwaysApplyDataBindings.Value)
|
||||
{
|
||||
Registration.DataBinding.UpdateWithDelta(DateTime.Now - _lastUpdate);
|
||||
_profileEditorService.UpdateProfilePreview();
|
||||
}
|
||||
|
||||
if (ActiveItem.SupportsTestValue)
|
||||
{
|
||||
TProperty currentValue = Registration.Converter.ConvertFromObject(ActiveItem?.GetTestValue() ?? default(TProperty));
|
||||
TestInputValue.UpdateValue(currentValue);
|
||||
TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(currentValue) : default);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(default) : default);
|
||||
}
|
||||
|
||||
_updatingTestResult = false;
|
||||
}
|
||||
|
||||
private void EnableDataBinding()
|
||||
{
|
||||
if (Registration.DataBinding != null)
|
||||
return;
|
||||
|
||||
Registration.LayerProperty.EnableDataBinding(Registration);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void RemoveDataBinding()
|
||||
{
|
||||
if (Registration.DataBinding == null)
|
||||
return;
|
||||
|
||||
ActiveItem = null;
|
||||
Registration.LayerProperty.DisableDataBinding(Registration.DataBinding);
|
||||
Update();
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void CopyDataBinding()
|
||||
{
|
||||
if (Registration.DataBinding != null)
|
||||
@@ -277,10 +119,115 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
|
||||
Registration.DataBinding.EasingTime = dataBindingEntity.EasingTime;
|
||||
Registration.DataBinding.EasingFunction = (Easings.Functions) dataBindingEntity.EasingFunction;
|
||||
Registration.DataBinding.ApplyDataBindingEntity(dataBindingEntity.DataBindingMode);
|
||||
CreateDataBindingModeModeViewModel();
|
||||
|
||||
// TODO - Paste visual script
|
||||
|
||||
Update();
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
Initialize();
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast<Easings.Functions>().Select(v => new TimelineEasingViewModel(v, false)));
|
||||
|
||||
_lastUpdate = DateTime.Now;
|
||||
_coreService.FrameRendered += OnFrameRendered;
|
||||
Update();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
if (Registration.DataBinding == null)
|
||||
{
|
||||
IsDataBindingEnabled = false;
|
||||
IsEasingTimeEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_updating = true;
|
||||
|
||||
EasingTime = (int) Registration.DataBinding.EasingTime.TotalMilliseconds;
|
||||
SelectedEasingViewModel = EasingViewModels.First(vm => vm.EasingFunction == Registration.DataBinding.EasingFunction);
|
||||
IsDataBindingEnabled = true;
|
||||
IsEasingTimeEnabled = EasingTime > 0;
|
||||
|
||||
_updating = false;
|
||||
}
|
||||
|
||||
private void ApplyChanges()
|
||||
{
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
if (Registration.DataBinding != null)
|
||||
{
|
||||
Registration.DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime);
|
||||
Registration.DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear;
|
||||
}
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
Update();
|
||||
}
|
||||
|
||||
private void UpdateTestResult()
|
||||
{
|
||||
if (_updating || _updatingTestResult)
|
||||
return;
|
||||
|
||||
_updatingTestResult = true;
|
||||
|
||||
if (Registration.DataBinding == null)
|
||||
{
|
||||
TestInputValue.UpdateValue(default);
|
||||
TestResultValue.UpdateValue(default);
|
||||
_updatingTestResult = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If always update is disabled, do constantly update the data binding as long as the view model is open
|
||||
// If always update is enabled, this is done for all data bindings in ProfileViewModel
|
||||
if (!AlwaysApplyDataBindings.Value)
|
||||
{
|
||||
Registration.DataBinding.UpdateWithDelta(DateTime.Now - _lastUpdate);
|
||||
_profileEditorService.UpdateProfilePreview();
|
||||
}
|
||||
|
||||
TProperty currentValue = Registration.Converter.ConvertFromObject(Registration.DataBinding.Script.Result ?? default(TProperty));
|
||||
TestInputValue.UpdateValue(currentValue);
|
||||
TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(currentValue) : default);
|
||||
|
||||
_updatingTestResult = false;
|
||||
}
|
||||
|
||||
private void EnableDataBinding()
|
||||
{
|
||||
if (Registration.DataBinding != null)
|
||||
return;
|
||||
|
||||
Registration.LayerProperty.EnableDataBinding(Registration);
|
||||
NotifyOfPropertyChange(nameof(Script));
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void DisableDataBinding()
|
||||
{
|
||||
if (Registration.DataBinding == null)
|
||||
return;
|
||||
|
||||
Registration.LayerProperty.DisableDataBinding(Registration.DataBinding);
|
||||
NotifyOfPropertyChange(nameof(Script));
|
||||
Update();
|
||||
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
@@ -291,20 +238,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
_lastUpdate = DateTime.Now;
|
||||
}
|
||||
|
||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
UpdateTestResult();
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
_coreService.FrameRendered -= OnFrameRendered;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public interface IDataBindingViewModel : IScreen, IDisposable
|
||||
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.DataBindingModifierView"
|
||||
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:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding"
|
||||
xmlns:modifierTypes="clr-namespace:Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<shared:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="0"
|
||||
ToolTip="Delete the modifier"
|
||||
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="#E74C4C"
|
||||
Width="25"
|
||||
Height="25"
|
||||
Command="{s:Action Delete}">
|
||||
<materialDesign:PackIcon Kind="Close" Width="18" Height="18" />
|
||||
</Button>
|
||||
|
||||
<Button Grid.Column="1"
|
||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding ModifierTypeViewModels.Children}">
|
||||
<ContextMenu.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<StackPanel.Resources>
|
||||
<DataTemplate DataType="{x:Type modifierTypes:ModifierTypeCategoryViewModel}">
|
||||
<TextBlock Text="{Binding Category}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type modifierTypes:ModifierTypeViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Kind="{Binding ModifierType.Icon}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0 0 15 0"
|
||||
Visibility="{Binding ModifierType.Icon, Converter={StaticResource NullToVisibilityConverter}}"/>
|
||||
<TextBlock Text="{Binding ModifierType.Name}"
|
||||
VerticalAlignment="Center"
|
||||
ToolTip="{Binding ModifierType.Description}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</StackPanel.Resources>
|
||||
<ContentPresenter Content="{Binding}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ContextMenu.ItemTemplate>
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectModifierTypeCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding SelectedModifierType.Name}"
|
||||
Visibility="{Binding SelectedModifierType, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock FontStyle="Italic"
|
||||
Visibility="{Binding SelectedModifierType, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||
« Select a modifier »
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
</Button>
|
||||
|
||||
<ContentControl Grid.Column="2" s:View.Model="{Binding DynamicSelectionViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
<ContentControl Grid.Column="2" s:View.Model="{Binding StaticInputViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DataBindingModifierView.xaml
|
||||
/// </summary>
|
||||
public partial class DataBindingModifierView : UserControl
|
||||
{
|
||||
public DataBindingModifierView()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-212
@@ -1,212 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
|
||||
{
|
||||
public sealed class DataBindingModifierViewModel<TLayerProperty, TProperty> : PropertyChangedBase, IDisposable
|
||||
{
|
||||
private readonly IDataBindingService _dataBindingService;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private DataModelDynamicViewModel _dynamicSelectionViewModel;
|
||||
private ModifierTypeCategoryViewModel _modifierTypeViewModels;
|
||||
private BaseDataBindingModifierType _selectedModifierType;
|
||||
private DataModelStaticViewModel _staticInputViewModel;
|
||||
|
||||
public DataBindingModifierViewModel(DataBindingModifier<TLayerProperty, TProperty> modifier,
|
||||
IDataBindingService dataBindingService,
|
||||
ISettingsService settingsService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IProfileEditorService profileEditorService)
|
||||
{
|
||||
_dataBindingService = dataBindingService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_profileEditorService = profileEditorService;
|
||||
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
|
||||
Modifier = modifier;
|
||||
SelectModifierTypeCommand = new DelegateCommand(ExecuteSelectModifierTypeCommand);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public DelegateCommand SelectModifierTypeCommand { get; }
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
public DataBindingModifier<TLayerProperty, TProperty> Modifier { get; }
|
||||
|
||||
public ModifierTypeCategoryViewModel ModifierTypeViewModels
|
||||
{
|
||||
get => _modifierTypeViewModels;
|
||||
set => SetAndNotify(ref _modifierTypeViewModels, value);
|
||||
}
|
||||
|
||||
public BaseDataBindingModifierType SelectedModifierType
|
||||
{
|
||||
get => _selectedModifierType;
|
||||
set => SetAndNotify(ref _selectedModifierType, value);
|
||||
}
|
||||
|
||||
public DataModelDynamicViewModel DynamicSelectionViewModel
|
||||
{
|
||||
get => _dynamicSelectionViewModel;
|
||||
private set => SetAndNotify(ref _dynamicSelectionViewModel, value);
|
||||
}
|
||||
|
||||
public DataModelStaticViewModel StaticInputViewModel
|
||||
{
|
||||
get => _staticInputViewModel;
|
||||
private set => SetAndNotify(ref _staticInputViewModel, value);
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
Modifier.DirectDataBinding.RemoveModifier(Modifier);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
Modifier.UpdateParameterDynamic(e.DataModelPath);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void StaticInputViewModelOnValueUpdated(object sender, DataModelInputStaticEventArgs e)
|
||||
{
|
||||
Modifier.UpdateParameterStatic(e.Value);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Type sourceType = Modifier.DirectDataBinding.GetSourceType();
|
||||
if (sourceType == null)
|
||||
throw new ArtemisUIException("Cannot use a data binding modifier VM for a data binding without a source");
|
||||
|
||||
if (Modifier.ModifierType == null || Modifier.ModifierType.ParameterType == null)
|
||||
{
|
||||
DisposeDynamicSelectionViewModel();
|
||||
DisposeStaticInputViewModel();
|
||||
}
|
||||
else if (Modifier.ParameterType == ProfileRightSideType.Dynamic)
|
||||
{
|
||||
DisposeStaticInputViewModel();
|
||||
DynamicSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.SelectedProfileConfiguration.Module);
|
||||
if (DynamicSelectionViewModel != null)
|
||||
{
|
||||
DynamicSelectionViewModel.DisplaySwitchButton = true;
|
||||
DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected;
|
||||
DynamicSelectionViewModel.SwitchToStaticRequested += DynamicSelectionViewModelOnSwitchToStaticRequested;
|
||||
DynamicSelectionViewModel.FilterTypes = new[] {Modifier.ModifierType.ParameterType ?? sourceType};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DisposeDynamicSelectionViewModel();
|
||||
StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(Modifier.ModifierType.ParameterType ?? sourceType, null);
|
||||
if (StaticInputViewModel != null)
|
||||
{
|
||||
StaticInputViewModel.DisplaySwitchButton = true;
|
||||
StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated;
|
||||
StaticInputViewModel.SwitchToDynamicRequested += StaticInputViewModelOnSwitchToDynamicRequested;
|
||||
}
|
||||
}
|
||||
|
||||
// Modifier type
|
||||
ModifierTypeCategoryViewModel root = new(null, null);
|
||||
IEnumerable<IGrouping<string, BaseDataBindingModifierType>> modifierTypes = _dataBindingService.GetCompatibleModifierTypes(sourceType, ModifierTypePart.Value).GroupBy(t => t.Category);
|
||||
foreach (IGrouping<string, BaseDataBindingModifierType> dataBindingModifierTypes in modifierTypes)
|
||||
{
|
||||
IEnumerable<ModifierTypeViewModel> viewModels = dataBindingModifierTypes.Select(t => new ModifierTypeViewModel(t));
|
||||
if (dataBindingModifierTypes.Key == null)
|
||||
root.Children.AddRange(viewModels);
|
||||
else
|
||||
root.Children.Add(new ModifierTypeCategoryViewModel(dataBindingModifierTypes.Key, viewModels));
|
||||
}
|
||||
|
||||
ModifierTypeViewModels = root;
|
||||
SelectedModifierType = Modifier.ModifierType;
|
||||
|
||||
// Parameter
|
||||
if (DynamicSelectionViewModel != null)
|
||||
DynamicSelectionViewModel.ChangeDataModelPath(Modifier.ParameterPath);
|
||||
else if (StaticInputViewModel != null)
|
||||
StaticInputViewModel.Value = Modifier.ParameterStaticValue;
|
||||
}
|
||||
|
||||
private void ExecuteSelectModifierTypeCommand(object context)
|
||||
{
|
||||
if (!(context is ModifierTypeViewModel modifierTypeViewModel))
|
||||
return;
|
||||
|
||||
Modifier.UpdateModifierType(modifierTypeViewModel.ModifierType);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
DisposeDynamicSelectionViewModel();
|
||||
DisposeStaticInputViewModel();
|
||||
}
|
||||
|
||||
private void DisposeStaticInputViewModel()
|
||||
{
|
||||
if (StaticInputViewModel != null)
|
||||
{
|
||||
StaticInputViewModel.Dispose();
|
||||
StaticInputViewModel.ValueUpdated -= StaticInputViewModelOnValueUpdated;
|
||||
StaticInputViewModel.SwitchToDynamicRequested -= StaticInputViewModelOnSwitchToDynamicRequested;
|
||||
StaticInputViewModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeDynamicSelectionViewModel()
|
||||
{
|
||||
if (DynamicSelectionViewModel != null)
|
||||
{
|
||||
DynamicSelectionViewModel.Dispose();
|
||||
DynamicSelectionViewModel.PropertySelected -= ParameterSelectionViewModelOnPropertySelected;
|
||||
DynamicSelectionViewModel.SwitchToStaticRequested -= DynamicSelectionViewModelOnSwitchToStaticRequested;
|
||||
DynamicSelectionViewModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void DynamicSelectionViewModelOnSwitchToStaticRequested(object sender, EventArgs e)
|
||||
{
|
||||
Modifier.ParameterType = ProfileRightSideType.Static;
|
||||
|
||||
// Ensure the right static value is never null when the preferred type is a value type
|
||||
if (SelectedModifierType.ParameterType != null &&
|
||||
SelectedModifierType.ParameterType.IsValueType && Modifier.ParameterStaticValue == null)
|
||||
Modifier.UpdateParameterStatic(SelectedModifierType.ParameterType.GetDefault());
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
private void StaticInputViewModelOnSwitchToDynamicRequested(object sender, EventArgs e)
|
||||
{
|
||||
Modifier.ParameterType = ProfileRightSideType.Dynamic;
|
||||
Update();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.DirectDataBindingModeView"
|
||||
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:s="https://github.com/canton7/Stylet"
|
||||
xmlns:dd="urn:gong-wpf-dragdrop"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Margin="0 5 0 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ContentControl Grid.Row="0"
|
||||
s:View.Model="{Binding TargetSelectionViewModel}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource MaterialDesignFlatMidBgButton}"
|
||||
HorizontalAlignment="Right"
|
||||
FontSize="12"
|
||||
Padding="6 4"
|
||||
Height="22"
|
||||
Command="{s:Action AddModifier}">
|
||||
ADD MODIFIER
|
||||
</Button>
|
||||
|
||||
<ListBox Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
ItemsSource="{Binding ModifierViewModels}"
|
||||
materialDesign:RippleAssist.IsDisabled="True"
|
||||
dd:DragDrop.IsDragSource="True"
|
||||
dd:DragDrop.IsDropTarget="True"
|
||||
dd:DragDrop.UseDefaultDragAdorner="True"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Margin="0 5 0 0">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
-169
@@ -1,169 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
|
||||
{
|
||||
public sealed class DirectDataBindingModeViewModel<TLayerProperty, TProperty> : Screen, IDataBindingModeViewModel
|
||||
{
|
||||
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private bool _canAddModifier;
|
||||
private DataModelDynamicViewModel _targetSelectionViewModel;
|
||||
private bool _updating;
|
||||
|
||||
public DirectDataBindingModeViewModel(DirectDataBinding<TLayerProperty, TProperty> directDataBinding,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IDataBindingsVmFactory dataBindingsVmFactory)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_dataBindingsVmFactory = dataBindingsVmFactory;
|
||||
|
||||
DirectDataBinding = directDataBinding;
|
||||
ModifierViewModels = new BindableCollection<DataBindingModifierViewModel<TLayerProperty, TProperty>>();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
|
||||
public DirectDataBinding<TLayerProperty, TProperty> DirectDataBinding { get; }
|
||||
public BindableCollection<DataBindingModifierViewModel<TLayerProperty, TProperty>> ModifierViewModels { get; }
|
||||
|
||||
public bool CanAddModifier
|
||||
{
|
||||
get => _canAddModifier;
|
||||
set => SetAndNotify(ref _canAddModifier, value);
|
||||
}
|
||||
|
||||
public DataModelDynamicViewModel TargetSelectionViewModel
|
||||
{
|
||||
get => _targetSelectionViewModel;
|
||||
private set => SetAndNotify(ref _targetSelectionViewModel, value);
|
||||
}
|
||||
|
||||
public bool SupportsTestValue => true;
|
||||
|
||||
public void Update()
|
||||
{
|
||||
TargetSelectionViewModel.ChangeDataModelPath(DirectDataBinding.SourcePath);
|
||||
TargetSelectionViewModel.FilterTypes = new[] {DirectDataBinding.DataBinding.GetTargetType()};
|
||||
|
||||
CanAddModifier = DirectDataBinding.SourcePath != null && DirectDataBinding.SourcePath.IsValid;
|
||||
UpdateModifierViewModels();
|
||||
}
|
||||
|
||||
public object GetTestValue()
|
||||
{
|
||||
return DirectDataBinding.SourcePath?.GetValue();
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
|
||||
TargetSelectionViewModel.Dispose();
|
||||
DirectDataBinding.ModifiersUpdated -= DirectDataBindingOnModifiersUpdated;
|
||||
|
||||
foreach (DataBindingModifierViewModel<TLayerProperty, TProperty> dataBindingModifierViewModel in ModifierViewModels)
|
||||
dataBindingModifierViewModel.Dispose();
|
||||
ModifierViewModels.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
DirectDataBinding.ModifiersUpdated += DirectDataBindingOnModifiersUpdated;
|
||||
TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.SelectedProfileConfiguration.Module);
|
||||
TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected;
|
||||
ModifierViewModels.CollectionChanged += ModifierViewModelsOnCollectionChanged;
|
||||
Update();
|
||||
}
|
||||
|
||||
private void ModifierViewModelsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (_updating || e.Action != NotifyCollectionChangedAction.Add)
|
||||
return;
|
||||
|
||||
for (int index = 0; index < ModifierViewModels.Count; index++)
|
||||
{
|
||||
DataBindingModifierViewModel<TLayerProperty, TProperty> dataBindingModifierViewModel = ModifierViewModels[index];
|
||||
dataBindingModifierViewModel.Modifier.Order = index + 1;
|
||||
}
|
||||
|
||||
DirectDataBinding.ApplyOrder();
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
#region Target
|
||||
|
||||
private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
DirectDataBinding.UpdateSource(e.DataModelPath);
|
||||
Update();
|
||||
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Modifiers
|
||||
|
||||
public void AddModifier()
|
||||
{
|
||||
DirectDataBinding.AddModifier(ProfileRightSideType.Dynamic);
|
||||
_profileEditorService.SaveSelectedProfileElement();
|
||||
}
|
||||
|
||||
private void UpdateModifierViewModels()
|
||||
{
|
||||
_updating = true;
|
||||
|
||||
// Remove old VMs
|
||||
List<DataBindingModifierViewModel<TLayerProperty, TProperty>> toRemove = ModifierViewModels.Where(m => !DirectDataBinding.Modifiers.Contains(m.Modifier)).ToList();
|
||||
foreach (DataBindingModifierViewModel<TLayerProperty, TProperty> modifierViewModel in toRemove)
|
||||
{
|
||||
ModifierViewModels.Remove(modifierViewModel);
|
||||
modifierViewModel.Dispose();
|
||||
}
|
||||
|
||||
// Don't create children without a source or with an invalid source
|
||||
if (DirectDataBinding.SourcePath == null || !DirectDataBinding.SourcePath.IsValid)
|
||||
return;
|
||||
|
||||
// Add missing VMs
|
||||
foreach (DataBindingModifier<TLayerProperty, TProperty> modifier in DirectDataBinding.Modifiers)
|
||||
{
|
||||
if (ModifierViewModels.All(m => m.Modifier != modifier))
|
||||
ModifierViewModels.Add(_dataBindingsVmFactory.DataBindingModifierViewModel(modifier));
|
||||
}
|
||||
|
||||
// Fix order
|
||||
ModifierViewModels.Sort(m => m.Modifier.Order);
|
||||
|
||||
_updating = false;
|
||||
}
|
||||
|
||||
private void DirectDataBindingOnModifiersUpdated(object sender, EventArgs e)
|
||||
{
|
||||
UpdateModifierViewModels();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes
|
||||
{
|
||||
public interface IModifierTypeViewModel
|
||||
{
|
||||
}
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes
|
||||
{
|
||||
public class ModifierTypeCategoryViewModel : IModifierTypeViewModel
|
||||
{
|
||||
public ModifierTypeCategoryViewModel(string category, IEnumerable<IModifierTypeViewModel> children)
|
||||
{
|
||||
Category = category;
|
||||
Children = children == null
|
||||
? new BindableCollection<IModifierTypeViewModel>()
|
||||
: new BindableCollection<IModifierTypeViewModel>(children);
|
||||
}
|
||||
|
||||
public string Category { get; set; }
|
||||
public BindableCollection<IModifierTypeViewModel> Children { get; set; }
|
||||
}
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes
|
||||
{
|
||||
public class ModifierTypeViewModel : IModifierTypeViewModel
|
||||
{
|
||||
public ModifierTypeViewModel(BaseDataBindingModifierType modifierType)
|
||||
{
|
||||
ModifierType = modifierType;
|
||||
}
|
||||
|
||||
public BaseDataBindingModifierType ModifierType { get; set; }
|
||||
}
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
using System;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
||||
{
|
||||
public interface IDataBindingModeViewModel : IScreen, IDisposable
|
||||
{
|
||||
bool SupportsTestValue { get; }
|
||||
void Update();
|
||||
object GetTestValue();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user