mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Conditions - Big refactor to prepare for conditional databindings
Conditions - Improved list-condition functionality
This commit is contained in:
1 parent
a646ff95ed
commit
8aba0a55ec
55 files changed
+1382
-1608
No files matched your search
+23
@@ -0,0 +1,23 @@
|
||||
using Artemis.Core;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract
|
||||
{
|
||||
public abstract class DataModelConditionViewModel : Conductor<DataModelConditionViewModel>.Collection.AllActive
|
||||
{
|
||||
protected DataModelConditionViewModel(DataModelConditionPart model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DataModelConditionPart Model { get; }
|
||||
|
||||
public abstract void Update();
|
||||
|
||||
public virtual void Delete()
|
||||
{
|
||||
Model.Parent.RemoveChild(Model);
|
||||
((DataModelConditionViewModel) Parent).Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -3,19 +3,19 @@
|
||||
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.DisplayConditions"
|
||||
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"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.DisplayConditionGroupView"
|
||||
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:DisplayConditionGroupViewModel}}">
|
||||
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type local:DataModelConditionGroupViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
</ResourceDictionary>
|
||||
@@ -46,7 +46,7 @@
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
ToolTip="Change the operator of the group"
|
||||
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
|
||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
||||
Background="#E74C4C"
|
||||
BorderBrush="#E74C4C"
|
||||
Margin="3 1"
|
||||
+24
-21
@@ -3,29 +3,30 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Screens.ProfileEditor.DisplayConditions;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Humanizer;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public class DisplayConditionGroupViewModel : DisplayConditionViewModel
|
||||
public class DataModelConditionGroupViewModel : DataModelConditionViewModel
|
||||
{
|
||||
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
|
||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private bool _isInitialized;
|
||||
private bool _isRootGroup;
|
||||
|
||||
public DisplayConditionGroupViewModel(DataModelConditionGroup dataModelConditionGroup,
|
||||
public DataModelConditionGroupViewModel(DataModelConditionGroup dataModelConditionGroup,
|
||||
bool isListGroup,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDisplayConditionsVmFactory displayConditionsVmFactory)
|
||||
IDataModelConditionsVmFactory dataModelConditionsVmFactory)
|
||||
: base(dataModelConditionGroup)
|
||||
{
|
||||
IsListGroup = isListGroup;
|
||||
_profileEditorService = profileEditorService;
|
||||
_displayConditionsVmFactory = displayConditionsVmFactory;
|
||||
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
|
||||
|
||||
Items.CollectionChanged += (sender, args) => NotifyOfPropertyChange(nameof(DisplayBooleanOperator));
|
||||
|
||||
@@ -71,15 +72,17 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
if (!IsListGroup)
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionPredicate(DataModelConditionGroup, ProfileRightSideType.Static));
|
||||
else
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ProfileRightSideType.Static));
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ListRightSideType.Static));
|
||||
}
|
||||
else if (type == "Dynamic")
|
||||
{
|
||||
if (!IsListGroup)
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic));
|
||||
else
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic));
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ListRightSideType.Dynamic));
|
||||
}
|
||||
else if (type == "DynamicExternal" && IsListGroup)
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ListRightSideType.DynamicExternal));
|
||||
else if (type == "List" && !IsListGroup)
|
||||
DataModelConditionGroup.AddChild(new DataModelConditionList(DataModelConditionGroup));
|
||||
|
||||
@@ -102,8 +105,8 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
// Remove VMs of effects no longer applied on the layer
|
||||
var toRemove = Items.Where(c => !DataModelConditionGroup.Children.Contains(c.Model)).ToList();
|
||||
// Using RemoveRange breaks our lovely animations
|
||||
foreach (var displayConditionViewModel in toRemove)
|
||||
Items.Remove(displayConditionViewModel);
|
||||
foreach (var DataModelConditionViewModel in toRemove)
|
||||
Items.Remove(DataModelConditionViewModel);
|
||||
|
||||
foreach (var childModel in Model.Children)
|
||||
{
|
||||
@@ -112,19 +115,19 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
|
||||
switch (childModel)
|
||||
{
|
||||
case DataModelConditionGroup displayConditionGroup:
|
||||
Items.Add(_displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, IsListGroup));
|
||||
case DataModelConditionGroup DataModelConditionGroup:
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionGroupViewModel(DataModelConditionGroup, IsListGroup));
|
||||
break;
|
||||
case DataModelConditionList displayConditionListPredicate:
|
||||
Items.Add(_displayConditionsVmFactory.DisplayConditionListViewModel(displayConditionListPredicate));
|
||||
case DataModelConditionList DataModelConditionListPredicate:
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionListViewModel(DataModelConditionListPredicate));
|
||||
break;
|
||||
case DataModelConditionPredicate displayConditionPredicate:
|
||||
case DataModelConditionPredicate DataModelConditionPredicate:
|
||||
if (!IsListGroup)
|
||||
Items.Add(_displayConditionsVmFactory.DisplayConditionPredicateViewModel(displayConditionPredicate));
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionPredicateViewModel(DataModelConditionPredicate));
|
||||
break;
|
||||
case DataModelConditionListPredicate displayConditionListPredicate:
|
||||
case DataModelConditionListPredicate DataModelConditionListPredicate:
|
||||
if (IsListGroup)
|
||||
Items.Add(_displayConditionsVmFactory.DisplayConditionListPredicateViewModel(displayConditionListPredicate));
|
||||
Items.Add(_dataModelConditionsVmFactory.DataModelConditionListPredicateViewModel(DataModelConditionListPredicate));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -132,8 +135,8 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
foreach (var childViewModel in Items)
|
||||
childViewModel.Update();
|
||||
|
||||
if (IsRootGroup)
|
||||
((DisplayConditionsViewModel) Parent).DisplayStartHint = !Items.Any();
|
||||
if (IsRootGroup && Parent is DisplayConditionsViewModel displayConditionsViewModel)
|
||||
displayConditionsViewModel.DisplayStartHint = !Items.Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
<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:converters="clr-namespace:Artemis.UI.Converters"
|
||||
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>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
<DataTemplate x:Key="DataModelDataTemplate">
|
||||
<Control x:Name="TemplateControl" Focusable="False" Template="{StaticResource DataModelSelectionTemplate}" />
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding Data.ShowDataModelValues.Value, Source={StaticResource DataContextProxy}}" Value="True">
|
||||
<Setter TargetName="TemplateControl" Property="Template" Value="{StaticResource DataModelSelectionTemplateWithValues}" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="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, may be null for primitive lists -->
|
||||
<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}"
|
||||
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>
|
||||
+4
-4
@@ -1,14 +1,14 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DisplayConditionListPredicateView.xaml
|
||||
/// Interaction logic for DataModelConditionListPredicateView.xaml
|
||||
/// </summary>
|
||||
public partial class DisplayConditionListPredicateView : UserControl
|
||||
public partial class DataModelConditionListPredicateView : UserControl
|
||||
{
|
||||
public DisplayConditionListPredicateView()
|
||||
public DataModelConditionListPredicateView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
+285
@@ -0,0 +1,285 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public class DataModelConditionListPredicateViewModel : DataModelConditionViewModel, IDisposable
|
||||
{
|
||||
private readonly IConditionOperatorService _conditionOperatorService;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private bool _isPrimitiveList;
|
||||
private DataModelDynamicViewModel _leftSideSelectionViewModel;
|
||||
private BindableCollection<ConditionOperator> _operators;
|
||||
private DataModelStaticViewModel _rightSideInputViewModel;
|
||||
private DataModelDynamicViewModel _rightSideSelectionViewModel;
|
||||
private ConditionOperator _selectedOperator;
|
||||
|
||||
private List<Type> _supportedInputTypes;
|
||||
|
||||
public DataModelConditionListPredicateViewModel(
|
||||
DataModelConditionListPredicate dataModelConditionListPredicate,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
IEventAggregator eventAggregator) : base(dataModelConditionListPredicate)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_conditionOperatorService = conditionOperatorService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_supportedInputTypes = new List<Type>();
|
||||
|
||||
SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand);
|
||||
Operators = new BindableCollection<ConditionOperator>();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public DataModelConditionListPredicate DataModelConditionListPredicate => (DataModelConditionListPredicate) Model;
|
||||
|
||||
public BindableCollection<ConditionOperator> Operators
|
||||
{
|
||||
get => _operators;
|
||||
set => SetAndNotify(ref _operators, value);
|
||||
}
|
||||
|
||||
public DataModelDynamicViewModel LeftSideSelectionViewModel
|
||||
{
|
||||
get => _leftSideSelectionViewModel;
|
||||
set => SetAndNotify(ref _leftSideSelectionViewModel, value);
|
||||
}
|
||||
|
||||
public DataModelDynamicViewModel RightSideSelectionViewModel
|
||||
{
|
||||
get => _rightSideSelectionViewModel;
|
||||
set => SetAndNotify(ref _rightSideSelectionViewModel, value);
|
||||
}
|
||||
|
||||
public DataModelStaticViewModel RightSideInputViewModel
|
||||
{
|
||||
get => _rightSideInputViewModel;
|
||||
set => SetAndNotify(ref _rightSideInputViewModel, value);
|
||||
}
|
||||
|
||||
public ConditionOperator SelectedOperator
|
||||
{
|
||||
get => _selectedOperator;
|
||||
set => SetAndNotify(ref _selectedOperator, value);
|
||||
}
|
||||
|
||||
public DelegateCommand SelectOperatorCommand { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_isPrimitiveList)
|
||||
{
|
||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideOnPropertySelected;
|
||||
LeftSideSelectionViewModel.Dispose();
|
||||
}
|
||||
|
||||
DisposeRightSideDynamic();
|
||||
DisposeRightSideStatic();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
var listDataModel = GetListDataModel();
|
||||
if (listDataModel.Children.Count == 1 && listDataModel.Children.First() is DataModelListPropertyViewModel)
|
||||
_isPrimitiveList = true;
|
||||
else
|
||||
_isPrimitiveList = false;
|
||||
|
||||
// Get the data models
|
||||
if (!_isPrimitiveList)
|
||||
{
|
||||
LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
|
||||
LeftSideSelectionViewModel.ChangeDataModel((DataModelPropertiesViewModel) listDataModel);
|
||||
LeftSideSelectionViewModel.PropertySelected += LeftSideOnPropertySelected;
|
||||
}
|
||||
|
||||
// Determine which types are currently supported
|
||||
var editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
var listDataModelGuid = DataModelConditionListPredicate.ListDataModel.PluginInfo.Guid;
|
||||
if (!_isPrimitiveList)
|
||||
{
|
||||
LeftSideSelectionViewModel.FilterTypes = _supportedInputTypes.ToArray();
|
||||
LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(71, 108, 188));
|
||||
LeftSideSelectionViewModel.SelectedPropertyViewModel = LeftSideSelectionViewModel.DataModelViewModel.GetChildByPath(
|
||||
listDataModelGuid, DataModelConditionListPredicate.LeftPropertyPath
|
||||
);
|
||||
}
|
||||
|
||||
var leftSideType = _isPrimitiveList
|
||||
? DataModelConditionListPredicate.ListType
|
||||
: LeftSideSelectionViewModel.SelectedPropertyViewModel?.PropertyInfo?.PropertyType;
|
||||
|
||||
// Get the supported operators
|
||||
Operators.Clear();
|
||||
Operators.AddRange(_conditionOperatorService.GetConditionOperatorsForType(leftSideType));
|
||||
if (DataModelConditionListPredicate.Operator == null)
|
||||
DataModelConditionListPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
|
||||
SelectedOperator = DataModelConditionListPredicate.Operator;
|
||||
|
||||
// Ensure the right side has the proper VM
|
||||
if (DataModelConditionListPredicate.PredicateType == ListRightSideType.Dynamic || DataModelConditionListPredicate.PredicateType == ListRightSideType.DynamicExternal)
|
||||
{
|
||||
DisposeRightSideStatic();
|
||||
if (RightSideSelectionViewModel == null)
|
||||
{
|
||||
RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
|
||||
RightSideSelectionViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush");
|
||||
RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected;
|
||||
}
|
||||
|
||||
RightSideSelectionViewModel.FilterTypes = new[] {leftSideType};
|
||||
if (DataModelConditionListPredicate.PredicateType == ListRightSideType.Dynamic)
|
||||
{
|
||||
RightSideSelectionViewModel.SelectedPropertyViewModel = RightSideSelectionViewModel.DataModelViewModel.GetChildByPath(
|
||||
listDataModelGuid, DataModelConditionListPredicate.RightPropertyPath
|
||||
);
|
||||
}
|
||||
else
|
||||
RightSideSelectionViewModel.PopulateSelectedPropertyViewModel(DataModelConditionListPredicate.RightDataModel, DataModelConditionListPredicate.RightPropertyPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisposeRightSideDynamic();
|
||||
if (RightSideInputViewModel == null)
|
||||
{
|
||||
RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(leftSideType);
|
||||
RightSideInputViewModel.Value = DataModelConditionListPredicate.RightStaticValue;
|
||||
RightSideInputViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush");
|
||||
RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered;
|
||||
}
|
||||
|
||||
if (RightSideInputViewModel.TargetType != leftSideType)
|
||||
RightSideInputViewModel.UpdateTargetType(leftSideType);
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyLeftSide()
|
||||
{
|
||||
DataModelConditionListPredicate.UpdateLeftSide(LeftSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
SelectedOperator = DataModelConditionListPredicate.Operator;
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideDynamic()
|
||||
{
|
||||
if (DataModelConditionListPredicate.ListContainsInnerPath(RightSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath))
|
||||
DataModelConditionListPredicate.UpdateRightSideDynamic(RightSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath);
|
||||
else
|
||||
DataModelConditionListPredicate.UpdateRightSideDynamic(
|
||||
RightSideSelectionViewModel.SelectedPropertyViewModel.DataModel,
|
||||
RightSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath
|
||||
);
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideStatic(object value)
|
||||
{
|
||||
DataModelConditionListPredicate.UpdateRightSideStatic(value);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyOperator()
|
||||
{
|
||||
DataModelConditionListPredicate.UpdateOperator(SelectedOperator);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
private DataModelVisualizationViewModel GetListDataModel()
|
||||
{
|
||||
if (DataModelConditionListPredicate.ListDataModel == null || DataModelConditionListPredicate.ListPropertyPath == null)
|
||||
throw new ArtemisUIException("Cannot create a list predicate without first selecting a target list");
|
||||
|
||||
var dataModel = _dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule(), true);
|
||||
var listDataModel = (DataModelListViewModel) dataModel.GetChildByPath(
|
||||
DataModelConditionListPredicate.ListDataModel.PluginInfo.Guid,
|
||||
DataModelConditionListPredicate.ListPropertyPath
|
||||
);
|
||||
|
||||
return listDataModel.GetListTypeViewModel(_dataModelUIService);
|
||||
}
|
||||
|
||||
private void ExecuteSelectOperatorCommand(object context)
|
||||
{
|
||||
if (!(context is ConditionOperator dataModelConditionOperator))
|
||||
return;
|
||||
|
||||
SelectedOperator = dataModelConditionOperator;
|
||||
ApplyOperator();
|
||||
}
|
||||
|
||||
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 DisposeRightSideStatic()
|
||||
{
|
||||
if (RightSideInputViewModel != null)
|
||||
{
|
||||
RightSideInputViewModel.ValueUpdated -= RightSideOnValueEntered;
|
||||
RightSideInputViewModel.Dispose();
|
||||
RightSideInputViewModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeRightSideDynamic()
|
||||
{
|
||||
if (RightSideSelectionViewModel != null)
|
||||
{
|
||||
RightSideSelectionViewModel.PropertySelected -= RightSideOnPropertySelected;
|
||||
RightSideSelectionViewModel.Dispose();
|
||||
RightSideSelectionViewModel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<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 Margin="0 3">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<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 TargetSelectionViewModel}"
|
||||
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">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Any" Command="{s:Action SelectListOperator}" CommandParameter="Any" />
|
||||
<MenuItem Header="All" Command="{s:Action SelectListOperator}" CommandParameter="All" />
|
||||
<MenuItem Header="None" Command="{s:Action SelectListOperator}" CommandParameter="None" />
|
||||
<MenuItem Header="Count (NYI)" Command="{s:Action SelectListOperator}" CommandParameter="Count" IsEnabled="False" />
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}" Margin="0 4 0 0">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<materialDesign:TransitioningContent>
|
||||
<materialDesign:TransitioningContent.OpeningEffects>
|
||||
<materialDesign:TransitionEffect Kind="FadeIn" />
|
||||
<materialDesign:TransitionEffect Kind="SlideInFromLeft" />
|
||||
</materialDesign:TransitioningContent.OpeningEffects>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
</materialDesign:TransitioningContent>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
+4
-4
@@ -1,14 +1,14 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DisplayConditionListView.xaml
|
||||
/// Interaction logic for DataModelConditionListView.xaml
|
||||
/// </summary>
|
||||
public partial class DisplayConditionListView : UserControl
|
||||
public partial class DataModelConditionListView : UserControl
|
||||
{
|
||||
public DisplayConditionListView()
|
||||
public DataModelConditionListView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Humanizer;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public class DataModelConditionListViewModel : DataModelConditionViewModel, IDisposable
|
||||
{
|
||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private DataModelDynamicViewModel _targetSelectionViewModel;
|
||||
|
||||
public DataModelConditionListViewModel(
|
||||
DataModelConditionList dataModelConditionList,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IDataModelConditionsVmFactory dataModelConditionsVmFactory) : base(dataModelConditionList)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public DataModelDynamicViewModel TargetSelectionViewModel
|
||||
{
|
||||
get => _targetSelectionViewModel;
|
||||
set => SetAndNotify(ref _targetSelectionViewModel, value);
|
||||
}
|
||||
|
||||
public DataModelConditionList DataModelConditionList => (DataModelConditionList) Model;
|
||||
|
||||
public string SelectedListOperator => DataModelConditionList.ListOperator.Humanize();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
TargetSelectionViewModel.Dispose();
|
||||
TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
|
||||
}
|
||||
|
||||
public void SelectListOperator(string type)
|
||||
{
|
||||
var enumValue = Enum.Parse<ListOperator>(type);
|
||||
DataModelConditionList.ListOperator = enumValue;
|
||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddCondition(string type)
|
||||
{
|
||||
if (type == "Static")
|
||||
DataModelConditionList.AddChild(new DataModelConditionPredicate(DataModelConditionList, ProfileRightSideType.Static));
|
||||
else if (type == "Dynamic")
|
||||
DataModelConditionList.AddChild(new DataModelConditionPredicate(DataModelConditionList, ProfileRightSideType.Dynamic));
|
||||
|
||||
Update();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddGroup()
|
||||
{
|
||||
DataModelConditionList.AddChild(new DataModelConditionGroup(DataModelConditionList));
|
||||
|
||||
Update();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
|
||||
TargetSelectionViewModel.FilterTypes = new[] {typeof(IList)};
|
||||
TargetSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(71, 108, 188));
|
||||
TargetSelectionViewModel.Placeholder = "Select a list";
|
||||
TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected;
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyList()
|
||||
{
|
||||
DataModelConditionList.UpdateList(
|
||||
TargetSelectionViewModel.SelectedPropertyViewModel.DataModel,
|
||||
TargetSelectionViewModel.SelectedPropertyViewModel.PropertyPath
|
||||
);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
TargetSelectionViewModel.PopulateSelectedPropertyViewModel(DataModelConditionList.ListDataModel, DataModelConditionList.ListPropertyPath);
|
||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||
|
||||
// Remove VMs of effects no longer applied on the layer
|
||||
var toRemove = Items.Where(c => !DataModelConditionList.Children.Contains(c.Model)).ToList();
|
||||
// Using RemoveRange breaks our lovely animations
|
||||
foreach (var conditionViewModel in toRemove)
|
||||
Items.Remove(conditionViewModel);
|
||||
|
||||
foreach (var childModel in Model.Children)
|
||||
{
|
||||
if (Items.Any(c => c.Model == childModel))
|
||||
continue;
|
||||
if (!(childModel is DataModelConditionGroup dataModelConditionGroup))
|
||||
continue;
|
||||
|
||||
var viewModel = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, true);
|
||||
viewModel.IsRootGroup = true;
|
||||
Items.Add(viewModel);
|
||||
}
|
||||
|
||||
foreach (var childViewModel in Items)
|
||||
childViewModel.Update();
|
||||
}
|
||||
|
||||
private void TargetSelectionViewModelOnPropertySelected(object? sender, DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
ApplyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<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.DataModelConditionPredicateView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type conditions:DataModelConditionPredicateViewModel}}">
|
||||
<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 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}"
|
||||
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>
|
||||
+4
-4
@@ -1,14 +1,14 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DisplayConditionPredicateView.xaml
|
||||
/// Interaction logic for DataModelConditionPredicateView.xaml
|
||||
/// </summary>
|
||||
public partial class DisplayConditionPredicateView : UserControl
|
||||
public partial class DataModelConditionPredicateView : UserControl
|
||||
{
|
||||
public DisplayConditionPredicateView()
|
||||
public DataModelConditionPredicateView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Input;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
||||
{
|
||||
public class DataModelConditionPredicateViewModel : DataModelConditionViewModel, IDisposable
|
||||
{
|
||||
private readonly IConditionOperatorService _conditionOperatorService;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private DataModelDynamicViewModel _leftSideSelectionViewModel;
|
||||
private BindableCollection<ConditionOperator> _operators;
|
||||
private DataModelStaticViewModel _rightSideInputViewModel;
|
||||
private DataModelDynamicViewModel _rightSideSelectionViewModel;
|
||||
private ConditionOperator _selectedOperator;
|
||||
|
||||
private List<Type> _supportedInputTypes;
|
||||
|
||||
public DataModelConditionPredicateViewModel(
|
||||
DataModelConditionPredicate dataModelConditionPredicate,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
ISettingsService settingsService) : base(dataModelConditionPredicate)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_conditionOperatorService = conditionOperatorService;
|
||||
_supportedInputTypes = new List<Type>();
|
||||
|
||||
SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand);
|
||||
Operators = new BindableCollection<ConditionOperator>();
|
||||
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public DataModelConditionPredicate DataModelConditionPredicate => (DataModelConditionPredicate) Model;
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
|
||||
|
||||
public BindableCollection<ConditionOperator> Operators
|
||||
{
|
||||
get => _operators;
|
||||
set => SetAndNotify(ref _operators, value);
|
||||
}
|
||||
|
||||
public DataModelDynamicViewModel LeftSideSelectionViewModel
|
||||
{
|
||||
get => _leftSideSelectionViewModel;
|
||||
set => SetAndNotify(ref _leftSideSelectionViewModel, value);
|
||||
}
|
||||
|
||||
public ConditionOperator 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 void Dispose()
|
||||
{
|
||||
if (LeftSideSelectionViewModel != null)
|
||||
{
|
||||
LeftSideSelectionViewModel.PropertySelected -= LeftSideOnPropertySelected;
|
||||
LeftSideSelectionViewModel.Dispose();
|
||||
LeftSideSelectionViewModel = null;
|
||||
}
|
||||
|
||||
DisposeRightSideStatic();
|
||||
DisposeRightSideDynamic();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
|
||||
LeftSideSelectionViewModel.PropertySelected += LeftSideOnPropertySelected;
|
||||
// Determine which types are currently supported
|
||||
var editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
LeftSideSelectionViewModel.FilterTypes = _supportedInputTypes.ToArray();
|
||||
LeftSideSelectionViewModel.PopulateSelectedPropertyViewModel(
|
||||
DataModelConditionPredicate.LeftDataModel,
|
||||
DataModelConditionPredicate.LeftPropertyPath
|
||||
);
|
||||
var leftSideType = LeftSideSelectionViewModel.SelectedPropertyViewModel?.PropertyInfo?.PropertyType;
|
||||
|
||||
// Get the supported operators
|
||||
Operators.Clear();
|
||||
Operators.AddRange(_conditionOperatorService.GetConditionOperatorsForType(leftSideType));
|
||||
if (DataModelConditionPredicate.Operator == null)
|
||||
DataModelConditionPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
|
||||
SelectedOperator = DataModelConditionPredicate.Operator;
|
||||
|
||||
// Ensure the right side has the proper VM
|
||||
var targetType = LeftSideSelectionViewModel?.SelectedPropertyViewModel?.PropertyInfo?.PropertyType;
|
||||
if (DataModelConditionPredicate.PredicateType == ProfileRightSideType.Dynamic)
|
||||
{
|
||||
DisposeRightSideStatic();
|
||||
if (RightSideSelectionViewModel == null)
|
||||
{
|
||||
RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
|
||||
RightSideSelectionViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush");
|
||||
RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected;
|
||||
}
|
||||
|
||||
RightSideSelectionViewModel.PopulateSelectedPropertyViewModel(
|
||||
DataModelConditionPredicate.RightDataModel,
|
||||
DataModelConditionPredicate.RightPropertyPath
|
||||
);
|
||||
RightSideSelectionViewModel.FilterTypes = new[] {targetType};
|
||||
}
|
||||
else
|
||||
{
|
||||
DisposeRightSideDynamic();
|
||||
if (RightSideInputViewModel == null)
|
||||
{
|
||||
RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(targetType);
|
||||
RightSideInputViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush");
|
||||
RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered;
|
||||
}
|
||||
|
||||
if (RightSideInputViewModel.TargetType != targetType)
|
||||
RightSideInputViewModel.UpdateTargetType(targetType);
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyLeftSide()
|
||||
{
|
||||
DataModelConditionPredicate.UpdateLeftSide(
|
||||
LeftSideSelectionViewModel.SelectedPropertyViewModel.DataModel,
|
||||
LeftSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath
|
||||
);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
SelectedOperator = DataModelConditionPredicate.Operator;
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideDynamic()
|
||||
{
|
||||
DataModelConditionPredicate.UpdateRightSide(
|
||||
RightSideSelectionViewModel.SelectedPropertyViewModel.DataModel,
|
||||
RightSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath
|
||||
);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideStatic(object value)
|
||||
{
|
||||
DataModelConditionPredicate.UpdateRightSide(value);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyOperator()
|
||||
{
|
||||
DataModelConditionPredicate.UpdateOperator(SelectedOperator);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
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 ExecuteSelectOperatorCommand(object context)
|
||||
{
|
||||
if (!(context is ConditionOperator DataModelConditionOperator))
|
||||
return;
|
||||
|
||||
SelectedOperator = DataModelConditionOperator;
|
||||
ApplyOperator();
|
||||
}
|
||||
|
||||
private void DisposeRightSideStatic()
|
||||
{
|
||||
if (RightSideInputViewModel != null)
|
||||
{
|
||||
RightSideInputViewModel.ValueUpdated -= RightSideOnValueEntered;
|
||||
RightSideInputViewModel.Dispose();
|
||||
RightSideInputViewModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeRightSideDynamic()
|
||||
{
|
||||
if (RightSideSelectionViewModel != null)
|
||||
{
|
||||
RightSideSelectionViewModel.PropertySelected -= RightSideOnPropertySelected;
|
||||
RightSideSelectionViewModel.Dispose();
|
||||
RightSideSelectionViewModel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
using Artemis.Core;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract
|
||||
{
|
||||
public abstract class DisplayConditionViewModel : Conductor<DisplayConditionViewModel>.Collection.AllActive
|
||||
{
|
||||
protected DisplayConditionViewModel(DataModelConditionPart model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DataModelConditionPart Model { get; }
|
||||
|
||||
public abstract void Update();
|
||||
|
||||
public virtual void Delete()
|
||||
{
|
||||
Model.Parent.RemoveChild(Model);
|
||||
((DisplayConditionViewModel) Parent).Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
-186
@@ -1,186 +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:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:displayConditions="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.DisplayConditionListPredicateView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type displayConditions:DisplayConditionListPredicateViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
<DataTemplate x:Key="DataModelDataTemplate">
|
||||
<Control x:Name="TemplateControl" Focusable="False" Template="{StaticResource DataModelSelectionTemplate}" />
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding Data.ShowDataModelValues.Value, Source={StaticResource DataContextProxy}}" Value="True">
|
||||
<Setter TargetName="TemplateControl" Property="Template" Value="{StaticResource DataModelSelectionTemplateWithValues}" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0 3" Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<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 -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Background="#476CBC"
|
||||
BorderBrush="#476CBC"
|
||||
Style="{StaticResource DisplayConditionButton}"
|
||||
ToolTip="{Binding SelectedLeftSideProperty.DisplayPropertyPath}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding LeftSideDataModel.Children}" IsOpen="{Binding LeftSideDataModelOpen, Mode=OneWayToSource}">
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectLeftPropertyCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
<Setter Property="IsEnabled" Value="{Binding IsMatchingFilteredTypes}" />
|
||||
<Setter Property="IsSubmenuOpen" Value="{Binding IsVisualizationExpanded, Mode=TwoWay}" />
|
||||
<Setter Property="HeaderTemplate" Value="{StaticResource DataModelDataTemplate}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding SelectedLeftSideProperty.PropertyDescription.Name}"
|
||||
Visibility="{Binding SelectedLeftSideProperty, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock Text="« Select a property »"
|
||||
FontStyle="Italic"
|
||||
Visibility="{Binding SelectedLeftSideProperty, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
|
||||
<!-- Operator -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedOperator.Description}"
|
||||
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>
|
||||
|
||||
<Grid Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
Visibility="{Binding SelectedOperator.SupportsRightSide, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<!-- Right side property if type is dynamic -->
|
||||
<Button Background="{DynamicResource PrimaryHueMidBrush}"
|
||||
BorderBrush="{DynamicResource PrimaryHueMidBrush}"
|
||||
Style="{StaticResource DisplayConditionButton}"
|
||||
ToolTip="{Binding SelectedRightSideProperty.DisplayPropertyPath}"
|
||||
Click="PropertyButton_OnClick"
|
||||
Visibility="{Binding ShowRightSidePropertySelection, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding RightSideDataModel.Children}">
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectRightPropertyCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
<Setter Property="IsEnabled" Value="{Binding IsMatchingFilteredTypes}" />
|
||||
<Setter Property="IsSubmenuOpen" Value="{Binding IsVisualizationExpanded, Mode=TwoWay}" />
|
||||
<Setter Property="HeaderTemplate" Value="{StaticResource DataModelDataTemplate}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding SelectedRightSideProperty.PropertyDescription.Name}"
|
||||
Visibility="{Binding SelectedRightSideProperty, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock Text="« Select a property »"
|
||||
FontStyle="Italic"
|
||||
Visibility="{Binding SelectedRightSideProperty, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
|
||||
<!-- Right side property if type is static -->
|
||||
<materialDesign:Transitioner SelectedIndex="{Binding RightSideTransitionIndex}"
|
||||
DefaultTransitionOrigin="0.5, 0.5"
|
||||
Margin="3 -4"
|
||||
Visibility="{Binding ShowRightSidePropertySelection, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
|
||||
<Button Style="{StaticResource DisplayConditionButton}"
|
||||
Background="{DynamicResource PrimaryHueMidBrush}"
|
||||
BorderBrush="{DynamicResource PrimaryHueMidBrush}"
|
||||
Margin="0 4"
|
||||
Command="{s:Action ActivateRightSideInputViewModel}"
|
||||
HorizontalAlignment="Left">
|
||||
<Grid>
|
||||
<StackPanel Visibility="{Binding RightStaticValue, Converter={StaticResource NullToVisibilityConverter}}" Orientation="Horizontal">
|
||||
<TextBlock FontWeight="Light"
|
||||
Text="{Binding SelectedLeftSideProperty.PropertyDescription.Prefix}"
|
||||
Visibility="{Binding SelectedLeftSideProperty.PropertyDescription.Prefix, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock Text="{Binding RightStaticValue}" />
|
||||
<TextBlock FontWeight="Light"
|
||||
Text="{Binding SelectedLeftSideProperty.PropertyDescription.Affix}"
|
||||
Visibility="{Binding SelectedLeftSideProperty.PropertyDescription.Affix, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Text="« Enter a value »"
|
||||
FontStyle="Italic"
|
||||
Visibility="{Binding RightStaticValue, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
<Border BorderBrush="{DynamicResource PrimaryHueMidBrush}"
|
||||
Background="{DynamicResource MaterialDesignPaper}"
|
||||
CornerRadius="3"
|
||||
Padding="3"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="140">
|
||||
<ContentControl s:View.Model="{Binding RightSideInputViewModel}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
|
||||
</Border>
|
||||
</materialDesign:Transitioner>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
-353
@@ -1,353 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Events;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Utilities;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
{
|
||||
public class DisplayConditionListPredicateViewModel : DisplayConditionViewModel, IHandle<MainWindowKeyEvent>, IHandle<MainWindowMouseEvent>, IDisposable
|
||||
{
|
||||
private readonly IConditionOperatorService _conditionOperatorService;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly Timer _updateTimer;
|
||||
private bool _isInitialized;
|
||||
private DataModelVisualizationViewModel _leftSideDataModel;
|
||||
private BindableCollection<ConditionOperator> _operators;
|
||||
private DataModelVisualizationViewModel _rightSideDataModel;
|
||||
private DataModelInputViewModel _rightSideInputViewModel;
|
||||
private int _rightSideTransitionIndex;
|
||||
private object _rightStaticValue;
|
||||
private DataModelVisualizationViewModel _selectedLeftSideProperty;
|
||||
private ConditionOperator _selectedOperator;
|
||||
private DataModelVisualizationViewModel _selectedRightSideProperty;
|
||||
|
||||
private List<Type> _supportedInputTypes;
|
||||
|
||||
public DisplayConditionListPredicateViewModel(
|
||||
DataModelConditionListPredicate dataModelConditionListPredicate,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
ISettingsService settingsService,
|
||||
IEventAggregator eventAggregator) : base(dataModelConditionListPredicate)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_conditionOperatorService = conditionOperatorService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_updateTimer = new Timer(500);
|
||||
_supportedInputTypes = new List<Type>();
|
||||
|
||||
SelectLeftPropertyCommand = new DelegateCommand(ExecuteSelectLeftProperty);
|
||||
SelectRightPropertyCommand = new DelegateCommand(ExecuteSelectRightProperty);
|
||||
SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand);
|
||||
Operators = new BindableCollection<ConditionOperator>();
|
||||
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
|
||||
// Initialize async, no need to wait for it
|
||||
Task.Run(Initialize);
|
||||
}
|
||||
|
||||
public DataModelConditionListPredicate DataModelConditionListPredicate => (DataModelConditionListPredicate) Model;
|
||||
public bool ShowRightSidePropertySelection => DataModelConditionListPredicate.PredicateType == ProfileRightSideType.Dynamic;
|
||||
public bool CanActivateRightSideInputViewModel => SelectedLeftSideProperty?.PropertyInfo != null;
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
|
||||
public bool IsInitialized
|
||||
{
|
||||
get => _isInitialized;
|
||||
private set => SetAndNotify(ref _isInitialized, value);
|
||||
}
|
||||
|
||||
public bool LeftSideDataModelOpen { get; set; }
|
||||
|
||||
public DataModelVisualizationViewModel LeftSideDataModel
|
||||
{
|
||||
get => _leftSideDataModel;
|
||||
set => SetAndNotify(ref _leftSideDataModel, value);
|
||||
}
|
||||
|
||||
public DataModelVisualizationViewModel RightSideDataModel
|
||||
{
|
||||
get => _rightSideDataModel;
|
||||
set => SetAndNotify(ref _rightSideDataModel, value);
|
||||
}
|
||||
|
||||
public bool RightSideDataModelOpen { get; set; }
|
||||
|
||||
public DataModelVisualizationViewModel SelectedLeftSideProperty
|
||||
{
|
||||
get => _selectedLeftSideProperty;
|
||||
set
|
||||
{
|
||||
if (!SetAndNotify(ref _selectedLeftSideProperty, value)) return;
|
||||
NotifyOfPropertyChange(nameof(CanActivateRightSideInputViewModel));
|
||||
}
|
||||
}
|
||||
|
||||
public DataModelVisualizationViewModel SelectedRightSideProperty
|
||||
{
|
||||
get => _selectedRightSideProperty;
|
||||
set => SetAndNotify(ref _selectedRightSideProperty, value);
|
||||
}
|
||||
|
||||
public object RightStaticValue
|
||||
{
|
||||
get => _rightStaticValue;
|
||||
set => SetAndNotify(ref _rightStaticValue, value);
|
||||
}
|
||||
|
||||
public int RightSideTransitionIndex
|
||||
{
|
||||
get => _rightSideTransitionIndex;
|
||||
set => SetAndNotify(ref _rightSideTransitionIndex, value);
|
||||
}
|
||||
|
||||
public DataModelInputViewModel RightSideInputViewModel
|
||||
{
|
||||
get => _rightSideInputViewModel;
|
||||
set => SetAndNotify(ref _rightSideInputViewModel, value);
|
||||
}
|
||||
|
||||
public BindableCollection<ConditionOperator> Operators
|
||||
{
|
||||
get => _operators;
|
||||
set => SetAndNotify(ref _operators, value);
|
||||
}
|
||||
|
||||
public ConditionOperator SelectedOperator
|
||||
{
|
||||
get => _selectedOperator;
|
||||
set => SetAndNotify(ref _selectedOperator, value);
|
||||
}
|
||||
|
||||
public DelegateCommand SelectLeftPropertyCommand { get; }
|
||||
public DelegateCommand SelectRightPropertyCommand { get; }
|
||||
public DelegateCommand SelectOperatorCommand { get; }
|
||||
|
||||
public void Handle(MainWindowKeyEvent message)
|
||||
{
|
||||
if (RightSideInputViewModel == null)
|
||||
return;
|
||||
|
||||
if (!message.KeyDown && message.EventArgs.Key == Key.Escape)
|
||||
RightSideInputViewModel.Cancel();
|
||||
if (!message.KeyDown && message.EventArgs.Key == Key.Enter)
|
||||
RightSideInputViewModel.Submit();
|
||||
}
|
||||
|
||||
public void Handle(MainWindowMouseEvent message)
|
||||
{
|
||||
if (RightSideInputViewModel == null)
|
||||
return;
|
||||
|
||||
if (message.Sender is FrameworkElement frameworkElement && !frameworkElement.IsDescendantOf(RightSideInputViewModel.View))
|
||||
RightSideInputViewModel.Submit();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// Get the data models
|
||||
LeftSideDataModel = GetListDataModel();
|
||||
RightSideDataModel = GetListDataModel();
|
||||
LeftSideDataModel.UpdateRequested += LeftDataModelUpdateRequested;
|
||||
RightSideDataModel.UpdateRequested += RightDataModelUpdateRequested;
|
||||
|
||||
// Determine which types are currently supported
|
||||
var editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
|
||||
Update();
|
||||
|
||||
_updateTimer.Start();
|
||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
// Not yet initialized if these are null
|
||||
if (LeftSideDataModel == null || RightSideDataModel == null)
|
||||
return;
|
||||
|
||||
var listDataModelGuid = DataModelConditionListPredicate.ListDataModel.PluginInfo.Guid;
|
||||
|
||||
// If static, only allow selecting properties also supported by input
|
||||
if (DataModelConditionListPredicate.PredicateType == ProfileRightSideType.Static)
|
||||
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
||||
|
||||
// Determine the left side property first
|
||||
SelectedLeftSideProperty = LeftSideDataModel.GetChildByPath(listDataModelGuid, DataModelConditionListPredicate.LeftPropertyPath);
|
||||
var leftSideType = SelectedLeftSideProperty?.PropertyInfo?.PropertyType;
|
||||
|
||||
// Get the supported operators
|
||||
Operators.Clear();
|
||||
Operators.AddRange(_conditionOperatorService.GetConditionOperatorsForType(leftSideType));
|
||||
if (DataModelConditionListPredicate.Operator == null)
|
||||
DataModelConditionListPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
|
||||
SelectedOperator = DataModelConditionListPredicate.Operator;
|
||||
|
||||
// Determine the right side
|
||||
if (DataModelConditionListPredicate.PredicateType == ProfileRightSideType.Dynamic)
|
||||
{
|
||||
SelectedRightSideProperty = RightSideDataModel.GetChildByPath(listDataModelGuid, DataModelConditionListPredicate.RightPropertyPath);
|
||||
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
||||
}
|
||||
else
|
||||
RightStaticValue = DataModelConditionListPredicate.RightStaticValue;
|
||||
}
|
||||
|
||||
public void ApplyLeftSide()
|
||||
{
|
||||
DataModelConditionListPredicate.UpdateLeftSide(SelectedLeftSideProperty.PropertyPath);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
SelectedOperator = DataModelConditionListPredicate.Operator;
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideDynamic()
|
||||
{
|
||||
DataModelConditionListPredicate.UpdateRightSideDynamic(SelectedRightSideProperty.PropertyPath);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideStatic(object value, bool isSubmitted)
|
||||
{
|
||||
if (isSubmitted)
|
||||
{
|
||||
DataModelConditionListPredicate.UpdateRightSideStatic(value);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
RightSideTransitionIndex = 0;
|
||||
RightSideInputViewModel = null;
|
||||
RightStaticValue = value;
|
||||
_eventAggregator.Unsubscribe(this);
|
||||
}
|
||||
|
||||
public void ApplyOperator()
|
||||
{
|
||||
DataModelConditionListPredicate.UpdateOperator(SelectedOperator);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ActivateRightSideInputViewModel()
|
||||
{
|
||||
if (SelectedLeftSideProperty?.PropertyInfo == null)
|
||||
return;
|
||||
|
||||
RightSideTransitionIndex = 1;
|
||||
RightSideInputViewModel = _dataModelUIService.GetDataModelInputViewModel(
|
||||
SelectedLeftSideProperty.PropertyInfo.PropertyType,
|
||||
SelectedLeftSideProperty.PropertyDescription,
|
||||
DataModelConditionListPredicate.RightStaticValue,
|
||||
ApplyRightSideStatic
|
||||
);
|
||||
_eventAggregator.Subscribe(this);
|
||||
}
|
||||
|
||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (LeftSideDataModelOpen)
|
||||
LeftSideDataModel.Update(_dataModelUIService);
|
||||
else if (RightSideDataModelOpen)
|
||||
RightSideDataModel.Update(_dataModelUIService);
|
||||
}
|
||||
|
||||
private void RightDataModelUpdateRequested(object sender, EventArgs e)
|
||||
{
|
||||
var listDataModelGuid = DataModelConditionListPredicate.ListDataModel.PluginInfo.Guid;
|
||||
var leftSideType = SelectedLeftSideProperty?.PropertyInfo?.PropertyType;
|
||||
|
||||
// If the right side property is missing it may be available now that the data model has been updated
|
||||
if (SelectedRightSideProperty == null && DataModelConditionListPredicate.RightPropertyPath != null)
|
||||
SelectedRightSideProperty = RightSideDataModel.GetChildByPath(listDataModelGuid, DataModelConditionListPredicate.RightPropertyPath);
|
||||
|
||||
// With the data model updated, also reapply the filter
|
||||
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
||||
}
|
||||
|
||||
private void LeftDataModelUpdateRequested(object sender, EventArgs e)
|
||||
{
|
||||
if (DataModelConditionListPredicate.PredicateType == ProfileRightSideType.Static)
|
||||
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
||||
}
|
||||
|
||||
private DataModelVisualizationViewModel GetListDataModel()
|
||||
{
|
||||
if (DataModelConditionListPredicate.ListDataModel == null || DataModelConditionListPredicate.ListPropertyPath == null)
|
||||
throw new ArtemisUIException("Cannot create a list predicate without first selecting a target list");
|
||||
|
||||
var dataModel = _dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule(), true);
|
||||
var listDataModel = (DataModelListViewModel) dataModel.GetChildByPath(
|
||||
DataModelConditionListPredicate.ListDataModel.PluginInfo.Guid,
|
||||
DataModelConditionListPredicate.ListPropertyPath
|
||||
);
|
||||
|
||||
return listDataModel.GetListTypeViewModel(_dataModelUIService);
|
||||
}
|
||||
|
||||
private void ExecuteSelectLeftProperty(object context)
|
||||
{
|
||||
if (!(context is DataModelVisualizationViewModel dataModelVisualizationViewModel))
|
||||
return;
|
||||
|
||||
SelectedLeftSideProperty = dataModelVisualizationViewModel;
|
||||
ApplyLeftSide();
|
||||
}
|
||||
|
||||
private void ExecuteSelectRightProperty(object context)
|
||||
{
|
||||
if (!(context is DataModelVisualizationViewModel dataModelVisualizationViewModel))
|
||||
return;
|
||||
|
||||
SelectedRightSideProperty = dataModelVisualizationViewModel;
|
||||
ApplyRightSideDynamic();
|
||||
}
|
||||
|
||||
private void ExecuteSelectOperatorCommand(object context)
|
||||
{
|
||||
if (!(context is ConditionOperator displayConditionOperator))
|
||||
return;
|
||||
|
||||
SelectedOperator = displayConditionOperator;
|
||||
ApplyOperator();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_updateTimer.Dispose();
|
||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.DisplayConditionListView"
|
||||
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.DisplayConditions"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance Type=local:DisplayConditionListViewModel, IsDesignTimeCreatable=False}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
<DataTemplate x:Key="DataModelDataTemplate">
|
||||
<Control x:Name="TemplateControl" Focusable="False" Template="{StaticResource DataModelSelectionTemplate}" />
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding Data.ShowDataModelValues.Value, Source={StaticResource DataContextProxy}}" Value="True">
|
||||
<Setter TargetName="TemplateControl" Property="Template" Value="{StaticResource DataModelSelectionTemplateWithValues}" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0 3">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<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 -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Background="#476CBC"
|
||||
BorderBrush="#476CBC"
|
||||
Style="{StaticResource DisplayConditionButton}"
|
||||
ToolTip="{Binding SelectedListProperty.DisplayPropertyPath}"
|
||||
Click="PropertyButton_OnClick"
|
||||
Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding TargetDataModel.Children}" IsOpen="{Binding TargetDataModelOpen, Mode=OneWayToSource}">
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectListPropertyCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
<Setter Property="IsEnabled" Value="{Binding IsMatchingFilteredTypes}" />
|
||||
<Setter Property="IsSubmenuOpen" Value="{Binding IsVisualizationExpanded, Mode=TwoWay}" />
|
||||
<Setter Property="HeaderTemplate" Value="{StaticResource DataModelDataTemplate}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding SelectedListProperty.PropertyDescription.Name}"
|
||||
Visibility="{Binding SelectedListProperty, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock Text="« Select a list »"
|
||||
FontStyle="Italic"
|
||||
Visibility="{Binding SelectedListProperty, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
|
||||
<!-- Operator -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedListOperator}"
|
||||
Click="PropertyButton_OnClick"
|
||||
HorizontalAlignment="Left"
|
||||
Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Any" Command="{s:Action SelectListOperator}" CommandParameter="Any" />
|
||||
<MenuItem Header="All" Command="{s:Action SelectListOperator}" CommandParameter="All" />
|
||||
<MenuItem Header="None" Command="{s:Action SelectListOperator}" CommandParameter="None" />
|
||||
<MenuItem Header="Count (NYI)" Command="{s:Action SelectListOperator}" CommandParameter="Count" IsEnabled="False" />
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}" Margin="0 4 0 0">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<materialDesign:TransitioningContent>
|
||||
<materialDesign:TransitioningContent.OpeningEffects>
|
||||
<materialDesign:TransitionEffect Kind="FadeIn" />
|
||||
<materialDesign:TransitionEffect Kind="SlideInFromLeft" />
|
||||
</materialDesign:TransitioningContent.OpeningEffects>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
</materialDesign:TransitioningContent>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
-203
@@ -1,203 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Utilities;
|
||||
using Humanizer;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
{
|
||||
public class DisplayConditionListViewModel : DisplayConditionViewModel, IDisposable
|
||||
{
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly Timer _updateTimer;
|
||||
private bool _isInitialized;
|
||||
private DataModelListViewModel _selectedListProperty;
|
||||
private DataModelPropertiesViewModel _targetDataModel;
|
||||
|
||||
public DisplayConditionListViewModel(
|
||||
DataModelConditionList dataModelConditionList,
|
||||
DisplayConditionViewModel parent,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IDisplayConditionsVmFactory displayConditionsVmFactory,
|
||||
ISettingsService settingsService) : base(dataModelConditionList)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_displayConditionsVmFactory = displayConditionsVmFactory;
|
||||
_updateTimer = new Timer(500);
|
||||
|
||||
SelectListPropertyCommand = new DelegateCommand(ExecuteSelectListProperty);
|
||||
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
|
||||
// Initialize async, no need to wait for it
|
||||
Task.Run(Initialize);
|
||||
}
|
||||
|
||||
public DelegateCommand SelectListPropertyCommand { get; }
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
|
||||
public DataModelConditionList DataModelConditionList => (DataModelConditionList) Model;
|
||||
|
||||
public bool IsInitialized
|
||||
{
|
||||
get => _isInitialized;
|
||||
set => SetAndNotify(ref _isInitialized, value);
|
||||
}
|
||||
|
||||
public bool TargetDataModelOpen { get; set; }
|
||||
|
||||
public DataModelPropertiesViewModel TargetDataModel
|
||||
{
|
||||
get => _targetDataModel;
|
||||
set => SetAndNotify(ref _targetDataModel, value);
|
||||
}
|
||||
|
||||
public DataModelListViewModel SelectedListProperty
|
||||
{
|
||||
get => _selectedListProperty;
|
||||
set => SetAndNotify(ref _selectedListProperty, value);
|
||||
}
|
||||
|
||||
public string SelectedListOperator => DataModelConditionList.ListOperator.Humanize();
|
||||
|
||||
public void SelectListOperator(string type)
|
||||
{
|
||||
var enumValue = Enum.Parse<ListOperator>(type);
|
||||
DataModelConditionList.ListOperator = enumValue;
|
||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddCondition(string type)
|
||||
{
|
||||
if (type == "Static")
|
||||
DataModelConditionList.AddChild(new DataModelConditionPredicate(DataModelConditionList, ProfileRightSideType.Static));
|
||||
else if (type == "Dynamic")
|
||||
DataModelConditionList.AddChild(new DataModelConditionPredicate(DataModelConditionList, ProfileRightSideType.Dynamic));
|
||||
|
||||
Update();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void AddGroup()
|
||||
{
|
||||
DataModelConditionList.AddChild(new DataModelConditionGroup(DataModelConditionList));
|
||||
|
||||
Update();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// Get the data models
|
||||
TargetDataModel = _dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule(), true);
|
||||
TargetDataModel.UpdateRequested += TargetDataModelUpdateRequested;
|
||||
|
||||
Update();
|
||||
|
||||
_updateTimer.Start();
|
||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
public void ApplyList()
|
||||
{
|
||||
DataModelConditionList.UpdateList(SelectedListProperty.DataModel, SelectedListProperty.PropertyPath);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (TargetDataModel == null)
|
||||
return;
|
||||
|
||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||
|
||||
// Update the selected list property
|
||||
if (DataModelConditionList.ListDataModel != null && DataModelConditionList.ListPropertyPath != null)
|
||||
{
|
||||
var child = TargetDataModel.GetChildByPath(
|
||||
DataModelConditionList.ListDataModel.PluginInfo.Guid,
|
||||
DataModelConditionList.ListPropertyPath
|
||||
);
|
||||
SelectedListProperty = child as DataModelListViewModel;
|
||||
}
|
||||
|
||||
// Ensure filtering is applied to include Enumerables only
|
||||
TargetDataModel.ApplyTypeFilter(true, typeof(IList));
|
||||
|
||||
// Remove VMs of effects no longer applied on the layer
|
||||
var toRemove = Items.Where(c => !DataModelConditionList.Children.Contains(c.Model)).ToList();
|
||||
// Using RemoveRange breaks our lovely animations
|
||||
foreach (var displayConditionViewModel in toRemove)
|
||||
Items.Remove(displayConditionViewModel);
|
||||
|
||||
foreach (var childModel in Model.Children)
|
||||
{
|
||||
if (Items.Any(c => c.Model == childModel))
|
||||
continue;
|
||||
if (!(childModel is DataModelConditionGroup displayConditionGroup))
|
||||
continue;
|
||||
|
||||
var viewModel = _displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, true);
|
||||
viewModel.IsRootGroup = true;
|
||||
Items.Add(viewModel);
|
||||
}
|
||||
|
||||
foreach (var childViewModel in Items)
|
||||
childViewModel.Update();
|
||||
}
|
||||
|
||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (TargetDataModelOpen)
|
||||
{
|
||||
TargetDataModel?.Update(_dataModelUIService);
|
||||
SelectedListProperty?.Update(_dataModelUIService);
|
||||
}
|
||||
}
|
||||
|
||||
private void TargetDataModelUpdateRequested(object sender, EventArgs e)
|
||||
{
|
||||
TargetDataModel.ApplyTypeFilter(true, typeof(IList));
|
||||
}
|
||||
|
||||
|
||||
private void ExecuteSelectListProperty(object context)
|
||||
{
|
||||
if (!(context is DataModelListViewModel dataModelListViewModel))
|
||||
return;
|
||||
|
||||
SelectedListProperty = dataModelListViewModel;
|
||||
ApplyList();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_updateTimer.Dispose();
|
||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
-186
@@ -1,186 +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:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:displayConditions="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.DisplayConditionPredicateView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type displayConditions:DisplayConditionPredicateViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
<DataTemplate x:Key="DataModelDataTemplate">
|
||||
<Control x:Name="TemplateControl" Focusable="False" Template="{StaticResource DataModelSelectionTemplate}" />
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding Data.ShowDataModelValues.Value, Source={StaticResource DataContextProxy}}" Value="True">
|
||||
<Setter TargetName="TemplateControl" Property="Template" Value="{StaticResource DataModelSelectionTemplateWithValues}" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0 3" Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<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 -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Background="#ab47bc"
|
||||
BorderBrush="#ab47bc"
|
||||
Style="{StaticResource DisplayConditionButton}"
|
||||
ToolTip="{Binding SelectedLeftSideProperty.DisplayPropertyPath}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding LeftSideDataModel.Children}" IsOpen="{Binding LeftSideDataModelOpen, Mode=OneWayToSource}">
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectLeftPropertyCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
<Setter Property="IsEnabled" Value="{Binding IsMatchingFilteredTypes}" />
|
||||
<Setter Property="IsSubmenuOpen" Value="{Binding IsVisualizationExpanded, Mode=TwoWay}" />
|
||||
<Setter Property="HeaderTemplate" Value="{StaticResource DataModelDataTemplate}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding SelectedLeftSideProperty.PropertyDescription.Name}"
|
||||
Visibility="{Binding SelectedLeftSideProperty, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock Text="« Select a property »"
|
||||
FontStyle="Italic"
|
||||
Visibility="{Binding SelectedLeftSideProperty, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
|
||||
<!-- Operator -->
|
||||
<Button Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Content="{Binding SelectedOperator.Description}"
|
||||
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>
|
||||
|
||||
<Grid Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
Visibility="{Binding SelectedOperator.SupportsRightSide, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<!-- Right side property if type is dynamic -->
|
||||
<Button Background="{DynamicResource PrimaryHueMidBrush}"
|
||||
BorderBrush="{DynamicResource PrimaryHueMidBrush}"
|
||||
Style="{StaticResource DisplayConditionButton}"
|
||||
ToolTip="{Binding SelectedRightSideProperty.DisplayPropertyPath}"
|
||||
Click="PropertyButton_OnClick"
|
||||
Visibility="{Binding ShowRightSidePropertySelection, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding RightSideDataModel.Children}">
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectRightPropertyCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
<Setter Property="IsEnabled" Value="{Binding IsMatchingFilteredTypes}" />
|
||||
<Setter Property="IsSubmenuOpen" Value="{Binding IsVisualizationExpanded, Mode=TwoWay}" />
|
||||
<Setter Property="HeaderTemplate" Value="{StaticResource DataModelDataTemplate}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding SelectedRightSideProperty.PropertyDescription.Name}"
|
||||
Visibility="{Binding SelectedRightSideProperty, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock Text="« Select a property »"
|
||||
FontStyle="Italic"
|
||||
Visibility="{Binding SelectedRightSideProperty, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
|
||||
<!-- Right side property if type is static -->
|
||||
<materialDesign:Transitioner SelectedIndex="{Binding RightSideTransitionIndex}"
|
||||
DefaultTransitionOrigin="0.5, 0.5"
|
||||
Margin="3 -4"
|
||||
Visibility="{Binding ShowRightSidePropertySelection, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
|
||||
<Button Style="{StaticResource DisplayConditionButton}"
|
||||
Background="{DynamicResource PrimaryHueMidBrush}"
|
||||
BorderBrush="{DynamicResource PrimaryHueMidBrush}"
|
||||
Margin="0 4"
|
||||
Command="{s:Action ActivateRightSideInputViewModel}"
|
||||
HorizontalAlignment="Left">
|
||||
<Grid>
|
||||
<StackPanel Visibility="{Binding RightStaticValue, Converter={StaticResource NullToVisibilityConverter}}" Orientation="Horizontal">
|
||||
<TextBlock FontWeight="Light"
|
||||
Text="{Binding SelectedLeftSideProperty.PropertyDescription.Prefix}"
|
||||
Visibility="{Binding SelectedLeftSideProperty.PropertyDescription.Prefix, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock Text="{Binding RightStaticValue}" />
|
||||
<TextBlock FontWeight="Light"
|
||||
Text="{Binding SelectedLeftSideProperty.PropertyDescription.Affix}"
|
||||
Visibility="{Binding SelectedLeftSideProperty.PropertyDescription.Affix, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Text="« Enter a value »"
|
||||
FontStyle="Italic"
|
||||
Visibility="{Binding RightStaticValue, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
<Border BorderBrush="{DynamicResource PrimaryHueMidBrush}"
|
||||
Background="{DynamicResource MaterialDesignPaper}"
|
||||
CornerRadius="3"
|
||||
Padding="3"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="140">
|
||||
<ContentControl s:View.Model="{Binding RightSideInputViewModel}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
|
||||
</Border>
|
||||
</materialDesign:Transitioner>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
-332
@@ -1,332 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Events;
|
||||
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Utilities;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
{
|
||||
public class DisplayConditionPredicateViewModel : DisplayConditionViewModel, IHandle<MainWindowKeyEvent>, IHandle<MainWindowMouseEvent>, IDisposable
|
||||
{
|
||||
private readonly IConditionOperatorService _conditionOperatorService;
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly Timer _updateTimer;
|
||||
private bool _isInitialized;
|
||||
private DataModelPropertiesViewModel _leftSideDataModel;
|
||||
private BindableCollection<ConditionOperator> _operators;
|
||||
private DataModelPropertiesViewModel _rightSideDataModel;
|
||||
private DataModelInputViewModel _rightSideInputViewModel;
|
||||
private int _rightSideTransitionIndex;
|
||||
private object _rightStaticValue;
|
||||
private DataModelVisualizationViewModel _selectedLeftSideProperty;
|
||||
private ConditionOperator _selectedOperator;
|
||||
private DataModelVisualizationViewModel _selectedRightSideProperty;
|
||||
|
||||
private List<Type> _supportedInputTypes;
|
||||
|
||||
public DisplayConditionPredicateViewModel(
|
||||
DataModelConditionPredicate dataModelConditionPredicate,
|
||||
IProfileEditorService profileEditorService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
ISettingsService settingsService,
|
||||
IEventAggregator eventAggregator) : base(dataModelConditionPredicate)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_conditionOperatorService = conditionOperatorService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_updateTimer = new Timer(500);
|
||||
_supportedInputTypes = new List<Type>();
|
||||
|
||||
SelectLeftPropertyCommand = new DelegateCommand(ExecuteSelectLeftProperty);
|
||||
SelectRightPropertyCommand = new DelegateCommand(ExecuteSelectRightProperty);
|
||||
SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand);
|
||||
Operators = new BindableCollection<ConditionOperator>();
|
||||
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public DataModelConditionPredicate DataModelConditionPredicate => (DataModelConditionPredicate) Model;
|
||||
public bool ShowRightSidePropertySelection => DataModelConditionPredicate.PredicateType == ProfileRightSideType.Dynamic;
|
||||
public bool CanActivateRightSideInputViewModel => SelectedLeftSideProperty?.PropertyInfo != null;
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
|
||||
public bool IsInitialized
|
||||
{
|
||||
get => _isInitialized;
|
||||
private set => SetAndNotify(ref _isInitialized, value);
|
||||
}
|
||||
|
||||
public bool LeftSideDataModelOpen { get; set; }
|
||||
|
||||
public DataModelPropertiesViewModel LeftSideDataModel
|
||||
{
|
||||
get => _leftSideDataModel;
|
||||
set => SetAndNotify(ref _leftSideDataModel, value);
|
||||
}
|
||||
|
||||
public DataModelPropertiesViewModel RightSideDataModel
|
||||
{
|
||||
get => _rightSideDataModel;
|
||||
set => SetAndNotify(ref _rightSideDataModel, value);
|
||||
}
|
||||
|
||||
public bool RightSideDataModelOpen { get; set; }
|
||||
|
||||
public DataModelVisualizationViewModel SelectedLeftSideProperty
|
||||
{
|
||||
get => _selectedLeftSideProperty;
|
||||
set
|
||||
{
|
||||
if (!SetAndNotify(ref _selectedLeftSideProperty, value)) return;
|
||||
NotifyOfPropertyChange(nameof(CanActivateRightSideInputViewModel));
|
||||
}
|
||||
}
|
||||
|
||||
public DataModelVisualizationViewModel SelectedRightSideProperty
|
||||
{
|
||||
get => _selectedRightSideProperty;
|
||||
set => SetAndNotify(ref _selectedRightSideProperty, value);
|
||||
}
|
||||
|
||||
public object RightStaticValue
|
||||
{
|
||||
get => _rightStaticValue;
|
||||
set => SetAndNotify(ref _rightStaticValue, value);
|
||||
}
|
||||
|
||||
public int RightSideTransitionIndex
|
||||
{
|
||||
get => _rightSideTransitionIndex;
|
||||
set => SetAndNotify(ref _rightSideTransitionIndex, value);
|
||||
}
|
||||
|
||||
public DataModelInputViewModel RightSideInputViewModel
|
||||
{
|
||||
get => _rightSideInputViewModel;
|
||||
set => SetAndNotify(ref _rightSideInputViewModel, value);
|
||||
}
|
||||
|
||||
public BindableCollection<ConditionOperator> Operators
|
||||
{
|
||||
get => _operators;
|
||||
set => SetAndNotify(ref _operators, value);
|
||||
}
|
||||
|
||||
public ConditionOperator SelectedOperator
|
||||
{
|
||||
get => _selectedOperator;
|
||||
set => SetAndNotify(ref _selectedOperator, value);
|
||||
}
|
||||
|
||||
public DelegateCommand SelectLeftPropertyCommand { get; }
|
||||
public DelegateCommand SelectRightPropertyCommand { get; }
|
||||
public DelegateCommand SelectOperatorCommand { get; }
|
||||
|
||||
public void Handle(MainWindowKeyEvent message)
|
||||
{
|
||||
if (RightSideInputViewModel == null)
|
||||
return;
|
||||
|
||||
if (!message.KeyDown && message.EventArgs.Key == Key.Escape)
|
||||
RightSideInputViewModel.Cancel();
|
||||
if (!message.KeyDown && message.EventArgs.Key == Key.Enter)
|
||||
RightSideInputViewModel.Submit();
|
||||
}
|
||||
|
||||
public void Handle(MainWindowMouseEvent message)
|
||||
{
|
||||
if (RightSideInputViewModel == null)
|
||||
return;
|
||||
|
||||
if (message.Sender is FrameworkElement frameworkElement && !frameworkElement.IsDescendantOf(RightSideInputViewModel.View))
|
||||
RightSideInputViewModel.Submit();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// Get the data models
|
||||
LeftSideDataModel = _dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule(), true);
|
||||
RightSideDataModel = _dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule(), true);
|
||||
|
||||
// Determine which types are currently supported
|
||||
var editors = _dataModelUIService.RegisteredDataModelEditors;
|
||||
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
|
||||
LeftSideDataModel.UpdateRequested += LeftDataModelUpdateRequested;
|
||||
RightSideDataModel.UpdateRequested += RightDataModelUpdateRequested;
|
||||
|
||||
Update();
|
||||
|
||||
_updateTimer.Start();
|
||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (LeftSideDataModel == null || DataModelConditionPredicate.PredicateType == ProfileRightSideType.Dynamic && RightSideDataModel == null)
|
||||
return;
|
||||
|
||||
// If static, only allow selecting properties also supported by input
|
||||
if (DataModelConditionPredicate.PredicateType == ProfileRightSideType.Static)
|
||||
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
||||
|
||||
// Determine the left side property first
|
||||
SelectedLeftSideProperty = LeftSideDataModel.GetChildForCondition(DataModelConditionPredicate, DisplayConditionSide.Left);
|
||||
var leftSideType = SelectedLeftSideProperty?.PropertyInfo?.PropertyType;
|
||||
|
||||
// Get the supported operators
|
||||
Operators.Clear();
|
||||
Operators.AddRange(_conditionOperatorService.GetConditionOperatorsForType(leftSideType));
|
||||
if (DataModelConditionPredicate.Operator == null)
|
||||
DataModelConditionPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
|
||||
SelectedOperator = DataModelConditionPredicate.Operator;
|
||||
|
||||
// Determine the right side
|
||||
if (DataModelConditionPredicate.PredicateType == ProfileRightSideType.Dynamic)
|
||||
{
|
||||
SelectedRightSideProperty = LeftSideDataModel.GetChildForCondition(DataModelConditionPredicate, DisplayConditionSide.Right);
|
||||
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
||||
}
|
||||
else
|
||||
RightStaticValue = DataModelConditionPredicate.RightStaticValue;
|
||||
}
|
||||
|
||||
public void ApplyLeftSide()
|
||||
{
|
||||
DataModelConditionPredicate.UpdateLeftSide(SelectedLeftSideProperty.DataModel, SelectedLeftSideProperty.PropertyPath);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
SelectedOperator = DataModelConditionPredicate.Operator;
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideDynamic()
|
||||
{
|
||||
DataModelConditionPredicate.UpdateRightSide(SelectedRightSideProperty.DataModel, SelectedRightSideProperty.PropertyPath);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ApplyRightSideStatic(object value, bool isSubmitted)
|
||||
{
|
||||
if (isSubmitted)
|
||||
{
|
||||
DataModelConditionPredicate.UpdateRightSide(value);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
RightSideTransitionIndex = 0;
|
||||
RightSideInputViewModel = null;
|
||||
RightStaticValue = value;
|
||||
_eventAggregator.Unsubscribe(this);
|
||||
}
|
||||
|
||||
public void ApplyOperator()
|
||||
{
|
||||
DataModelConditionPredicate.UpdateOperator(SelectedOperator);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void ActivateRightSideInputViewModel()
|
||||
{
|
||||
if (SelectedLeftSideProperty?.PropertyInfo == null)
|
||||
return;
|
||||
|
||||
RightSideTransitionIndex = 1;
|
||||
RightSideInputViewModel = _dataModelUIService.GetDataModelInputViewModel(
|
||||
SelectedLeftSideProperty.PropertyInfo.PropertyType,
|
||||
SelectedLeftSideProperty.PropertyDescription,
|
||||
DataModelConditionPredicate.RightStaticValue,
|
||||
ApplyRightSideStatic
|
||||
);
|
||||
_eventAggregator.Subscribe(this);
|
||||
}
|
||||
|
||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (LeftSideDataModelOpen)
|
||||
LeftSideDataModel.Update(_dataModelUIService);
|
||||
else if (RightSideDataModelOpen)
|
||||
RightSideDataModel.Update(_dataModelUIService);
|
||||
}
|
||||
|
||||
private void RightDataModelUpdateRequested(object sender, EventArgs e)
|
||||
{
|
||||
var leftSideType = SelectedLeftSideProperty?.PropertyInfo?.PropertyType;
|
||||
if (DataModelConditionPredicate.PredicateType == ProfileRightSideType.Dynamic)
|
||||
SelectedRightSideProperty = LeftSideDataModel.GetChildForCondition(DataModelConditionPredicate, DisplayConditionSide.Right);
|
||||
|
||||
// With the data model updated, also reapply the filter
|
||||
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
||||
}
|
||||
|
||||
private void LeftDataModelUpdateRequested(object sender, EventArgs e)
|
||||
{
|
||||
if (DataModelConditionPredicate.PredicateType == ProfileRightSideType.Static)
|
||||
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
||||
}
|
||||
|
||||
private void ExecuteSelectLeftProperty(object context)
|
||||
{
|
||||
if (!(context is DataModelVisualizationViewModel dataModelVisualizationViewModel))
|
||||
return;
|
||||
|
||||
SelectedLeftSideProperty = dataModelVisualizationViewModel;
|
||||
ApplyLeftSide();
|
||||
}
|
||||
|
||||
private void ExecuteSelectRightProperty(object context)
|
||||
{
|
||||
if (!(context is DataModelVisualizationViewModel dataModelVisualizationViewModel))
|
||||
return;
|
||||
|
||||
SelectedRightSideProperty = dataModelVisualizationViewModel;
|
||||
ApplyRightSideDynamic();
|
||||
}
|
||||
|
||||
private void ExecuteSelectOperatorCommand(object context)
|
||||
{
|
||||
if (!(context is ConditionOperator displayConditionOperator))
|
||||
return;
|
||||
|
||||
SelectedOperator = displayConditionOperator;
|
||||
ApplyOperator();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_updateTimer.Dispose();
|
||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-7
@@ -1,23 +1,24 @@
|
||||
using System.Linq;
|
||||
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<DisplayConditionGroupViewModel>, IProfileEditorPanelViewModel
|
||||
public class DisplayConditionsViewModel : Conductor<DataModelConditionGroupViewModel>, IProfileEditorPanelViewModel
|
||||
{
|
||||
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
|
||||
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private RenderProfileElement _renderProfileElement;
|
||||
private bool _displayStartHint;
|
||||
|
||||
public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IDisplayConditionsVmFactory displayConditionsVmFactory)
|
||||
public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IDataModelConditionsVmFactory dataModelConditionsVmFactory)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_displayConditionsVmFactory = displayConditionsVmFactory;
|
||||
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
|
||||
}
|
||||
|
||||
public bool DisplayStartHint
|
||||
@@ -82,10 +83,10 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||
}
|
||||
|
||||
// Ensure the layer has a root display condition group
|
||||
if (e.RenderProfileElement.DataModelConditionGroup == null)
|
||||
e.RenderProfileElement.DataModelConditionGroup = new DataModelConditionGroup(null);
|
||||
if (e.RenderProfileElement.DisplayCondition == null)
|
||||
e.RenderProfileElement.DisplayCondition = new DataModelConditionGroup(null);
|
||||
|
||||
ActiveItem = _displayConditionsVmFactory.DisplayConditionGroupViewModel(e.RenderProfileElement.DataModelConditionGroup, false);
|
||||
ActiveItem = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(e.RenderProfileElement.DisplayCondition, false);
|
||||
ActiveItem.IsRootGroup = true;
|
||||
ActiveItem.Update();
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
@@ -51,7 +51,7 @@
|
||||
</Button>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
|
||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
||||
Background="#7B7B7B"
|
||||
BorderBrush="#7B7B7B"
|
||||
Click="PropertyButton_OnClick">
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<!-- Conditions resize -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<!-- Display conditions -->
|
||||
<RowDefinition Height="{Binding DisplayConditionsHeight.Value, Mode=TwoWay}" MinHeight="100" />
|
||||
<RowDefinition Height="{Binding DataModelConditionsHeight.Value, Mode=TwoWay}" MinHeight="100" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Profile selection -->
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
||||
private PluginSetting<GridLength> _bottomPanelsHeight;
|
||||
private PluginSetting<GridLength> _displayConditionsHeight;
|
||||
private PluginSetting<GridLength> _dataModelConditionsHeight;
|
||||
private DisplayConditionsViewModel _displayConditionsViewModel;
|
||||
private PluginSetting<GridLength> _elementPropertiesWidth;
|
||||
private LayerPropertiesViewModel _layerPropertiesViewModel;
|
||||
@@ -38,7 +38,7 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
public ProfileEditorViewModel(ProfileModule module,
|
||||
ProfileViewModel profileViewModel,
|
||||
ProfileTreeViewModel profileTreeViewModel,
|
||||
DisplayConditionsViewModel displayConditionsViewModel,
|
||||
DisplayConditionsViewModel dataModelConditionsViewModel,
|
||||
LayerPropertiesViewModel layerPropertiesViewModel,
|
||||
IProfileEditorService profileEditorService,
|
||||
IProfileService profileService,
|
||||
@@ -62,12 +62,12 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
// Populate the panels
|
||||
ProfileViewModel = profileViewModel;
|
||||
ProfileTreeViewModel = profileTreeViewModel;
|
||||
DisplayConditionsViewModel = displayConditionsViewModel;
|
||||
DisplayConditionsViewModel = dataModelConditionsViewModel;
|
||||
LayerPropertiesViewModel = layerPropertiesViewModel;
|
||||
|
||||
Items.Add(ProfileViewModel);
|
||||
Items.Add(ProfileTreeViewModel);
|
||||
Items.Add(DisplayConditionsViewModel);
|
||||
Items.Add(dataModelConditionsViewModel);
|
||||
Items.Add(LayerPropertiesViewModel);
|
||||
}
|
||||
|
||||
@@ -110,10 +110,10 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
set => SetAndNotify(ref _sidePanelsWidth, value);
|
||||
}
|
||||
|
||||
public PluginSetting<GridLength> DisplayConditionsHeight
|
||||
public PluginSetting<GridLength> DataModelConditionsHeight
|
||||
{
|
||||
get => _displayConditionsHeight;
|
||||
set => SetAndNotify(ref _displayConditionsHeight, value);
|
||||
get => _dataModelConditionsHeight;
|
||||
set => SetAndNotify(ref _dataModelConditionsHeight, value);
|
||||
}
|
||||
|
||||
public PluginSetting<GridLength> BottomPanelsHeight
|
||||
@@ -303,7 +303,7 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
private void LoadWorkspaceSettings()
|
||||
{
|
||||
SidePanelsWidth = _settingsService.GetSetting("ProfileEditor.SidePanelsWidth", new GridLength(385));
|
||||
DisplayConditionsHeight = _settingsService.GetSetting("ProfileEditor.DisplayConditionsHeight", new GridLength(345));
|
||||
DataModelConditionsHeight = _settingsService.GetSetting("ProfileEditor.DataModelConditionsHeight", new GridLength(345));
|
||||
BottomPanelsHeight = _settingsService.GetSetting("ProfileEditor.BottomPanelsHeight", new GridLength(265));
|
||||
ElementPropertiesWidth = _settingsService.GetSetting("ProfileEditor.ElementPropertiesWidth", new GridLength(545));
|
||||
}
|
||||
@@ -311,7 +311,7 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
private void SaveWorkspaceSettings()
|
||||
{
|
||||
SidePanelsWidth.Save();
|
||||
DisplayConditionsHeight.Save();
|
||||
DataModelConditionsHeight.Save();
|
||||
BottomPanelsHeight.Save();
|
||||
ElementPropertiesWidth.Save();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user