mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Display conditions - Finished list conditions
This commit is contained in:
parent
75e2fb1689
commit
12456519d5
@ -17,9 +17,6 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
{
|
{
|
||||||
Parent = parent;
|
Parent = parent;
|
||||||
Entity = new DisplayConditionListEntity();
|
Entity = new DisplayConditionListEntity();
|
||||||
|
|
||||||
// There is always a child root group, add it
|
|
||||||
AddChild(new DisplayConditionGroup(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayConditionList(DisplayConditionPart parent, DisplayConditionListEntity entity)
|
public DisplayConditionList(DisplayConditionPart parent, DisplayConditionListEntity entity)
|
||||||
@ -27,16 +24,6 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
Parent = parent;
|
Parent = parent;
|
||||||
Entity = entity;
|
Entity = entity;
|
||||||
ListOperator = (ListOperator) entity.ListOperator;
|
ListOperator = (ListOperator) entity.ListOperator;
|
||||||
|
|
||||||
// There should only be one child and it should be a group
|
|
||||||
var rootGroup = Entity.Children.SingleOrDefault() as DisplayConditionGroupEntity;
|
|
||||||
if (rootGroup == null)
|
|
||||||
{
|
|
||||||
Entity.Children.Clear();
|
|
||||||
AddChild(new DisplayConditionGroup(this));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
AddChild(new DisplayConditionGroup(this, rootGroup));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayConditionListEntity Entity { get; set; }
|
public DisplayConditionListEntity Entity { get; set; }
|
||||||
@ -55,6 +42,8 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
|
|
||||||
public override bool EvaluateObject(object target)
|
public override bool EvaluateObject(object target)
|
||||||
{
|
{
|
||||||
|
if (!Children.Any())
|
||||||
|
return false;
|
||||||
if (!(target is IList list))
|
if (!(target is IList list))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -92,17 +81,28 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
|
|
||||||
internal override void Initialize(IDataModelService dataModelService)
|
internal override void Initialize(IDataModelService dataModelService)
|
||||||
{
|
{
|
||||||
// Target list
|
if (Entity.ListDataModelGuid == null)
|
||||||
if (Entity.ListDataModelGuid != null)
|
return;
|
||||||
{
|
|
||||||
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.ListDataModelGuid.Value);
|
|
||||||
if (dataModel != null && dataModel.ContainsPath(Entity.ListPropertyPath))
|
|
||||||
UpdateList(dataModel, Entity.ListPropertyPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Children
|
// Get the data model and ensure the path is valid
|
||||||
var rootGroup = (DisplayConditionGroup) Children.Single();
|
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.ListDataModelGuid.Value);
|
||||||
rootGroup.Initialize(dataModelService);
|
if (dataModel == null || !dataModel.ContainsPath(Entity.ListPropertyPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Populate properties and create the accessor expression
|
||||||
|
ListDataModel = dataModel;
|
||||||
|
ListPropertyPath = Entity.ListPropertyPath;
|
||||||
|
CreateExpression();
|
||||||
|
|
||||||
|
// There should only be one child and it should be a group
|
||||||
|
if (Entity.Children.SingleOrDefault() is DisplayConditionGroupEntity rootGroup)
|
||||||
|
AddChild(new DisplayConditionGroup(this, rootGroup));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Entity.Children.Clear();
|
||||||
|
AddChild(new DisplayConditionGroup(this));
|
||||||
|
}
|
||||||
|
Children[0].Initialize(dataModelService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateList(DataModel dataModel, string path)
|
public void UpdateList(DataModel dataModel, string path)
|
||||||
@ -120,19 +120,30 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
throw new ArtemisCoreException($"The path '{path}' does not contain a list");
|
throw new ArtemisCoreException($"The path '{path}' does not contain a list");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the old root group that was tied to the old data model
|
||||||
|
while (Children.Any())
|
||||||
|
RemoveChild(Children[0]);
|
||||||
|
|
||||||
ListDataModel = dataModel;
|
ListDataModel = dataModel;
|
||||||
ListPropertyPath = path;
|
ListPropertyPath = path;
|
||||||
|
|
||||||
if (dataModel != null)
|
if (dataModel == null)
|
||||||
{
|
return;
|
||||||
var parameter = Expression.Parameter(typeof(object), "listDataModel");
|
|
||||||
var accessor = path.Split('.').Aggregate<string, Expression>(
|
|
||||||
Expression.Convert(parameter, dataModel.GetType()),
|
|
||||||
(expression, s) => Expression.Convert(Expression.Property(expression, s), typeof(IList)));
|
|
||||||
|
|
||||||
var lambda = Expression.Lambda<Func<object, IList>>(accessor, parameter);
|
// Create a new root group
|
||||||
CompiledListAccessor = lambda.Compile();
|
AddChild(new DisplayConditionGroup(this));
|
||||||
}
|
CreateExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateExpression()
|
||||||
|
{
|
||||||
|
var parameter = Expression.Parameter(typeof(object), "listDataModel");
|
||||||
|
var accessor = ListPropertyPath.Split('.').Aggregate<string, Expression>(
|
||||||
|
Expression.Convert(parameter, ListDataModel.GetType()),
|
||||||
|
(expression, s) => Expression.Convert(Expression.Property(expression, s), typeof(IList)));
|
||||||
|
|
||||||
|
var lambda = Expression.Lambda<Func<object, IList>>(accessor, parameter);
|
||||||
|
CompiledListAccessor = lambda.Compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<object, IList> CompiledListAccessor { get; set; }
|
public Func<object, IList> CompiledListAccessor { get; set; }
|
||||||
|
|||||||
@ -19,6 +19,8 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
Parent = parent;
|
Parent = parent;
|
||||||
PredicateType = predicateType;
|
PredicateType = predicateType;
|
||||||
Entity = new DisplayConditionListPredicateEntity();
|
Entity = new DisplayConditionListPredicateEntity();
|
||||||
|
|
||||||
|
ApplyParentList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayConditionListPredicate(DisplayConditionPart parent, DisplayConditionListPredicateEntity entity)
|
public DisplayConditionListPredicate(DisplayConditionPart parent, DisplayConditionListPredicateEntity entity)
|
||||||
@ -26,6 +28,8 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
Parent = parent;
|
Parent = parent;
|
||||||
Entity = entity;
|
Entity = entity;
|
||||||
PredicateType = (PredicateType) entity.PredicateType;
|
PredicateType = (PredicateType) entity.PredicateType;
|
||||||
|
|
||||||
|
ApplyParentList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayConditionListPredicateEntity Entity { get; set; }
|
public DisplayConditionListPredicateEntity Entity { get; set; }
|
||||||
@ -43,6 +47,20 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
|
|
||||||
public Func<object, bool> CompiledListPredicate { get; private set; }
|
public Func<object, bool> CompiledListPredicate { get; private set; }
|
||||||
|
|
||||||
|
public void ApplyParentList()
|
||||||
|
{
|
||||||
|
var current = Parent;
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
if (current is DisplayConditionList parentList)
|
||||||
|
{
|
||||||
|
UpdateList(parentList.ListDataModel, parentList.ListPropertyPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
current = current.Parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateList(DataModel dataModel, string path)
|
public void UpdateList(DataModel dataModel, string path)
|
||||||
{
|
{
|
||||||
if (dataModel != null && path == null)
|
if (dataModel != null && path == null)
|
||||||
@ -66,9 +84,9 @@ namespace Artemis.Core.Models.Profile.Conditions
|
|||||||
ListDataModel = dataModel;
|
ListDataModel = dataModel;
|
||||||
ListPropertyPath = path;
|
ListPropertyPath = path;
|
||||||
|
|
||||||
if (!ListContainsInnerPath(LeftPropertyPath))
|
if (LeftPropertyPath != null && !ListContainsInnerPath(LeftPropertyPath))
|
||||||
LeftPropertyPath = null;
|
LeftPropertyPath = null;
|
||||||
if (!ListContainsInnerPath(RightPropertyPath))
|
if (RightPropertyPath != null && !ListContainsInnerPath(RightPropertyPath))
|
||||||
RightPropertyPath = null;
|
RightPropertyPath = null;
|
||||||
|
|
||||||
CreateExpression();
|
CreateExpression();
|
||||||
|
|||||||
@ -34,9 +34,9 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
|||||||
set => SetAndNotify(ref _displayValue, value);
|
set => SetAndNotify(ref _displayValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string PropertyPath => Parent?.PropertyPath;
|
public override string PropertyPath => null;
|
||||||
|
|
||||||
public override string DisplayPropertyPath => Parent?.DisplayPropertyPath;
|
public override string DisplayPropertyPath => null;
|
||||||
|
|
||||||
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
|
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -198,6 +198,9 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
|||||||
|
|
||||||
public DataModelVisualizationViewModel GetChildByPath(Guid dataModelGuid, string propertyPath)
|
public DataModelVisualizationViewModel GetChildByPath(Guid dataModelGuid, string propertyPath)
|
||||||
{
|
{
|
||||||
|
if (propertyPath == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
// Ensure children are populated by requesting an update
|
// Ensure children are populated by requesting an update
|
||||||
if (!IsVisualizationExpanded)
|
if (!IsVisualizationExpanded)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -77,9 +77,10 @@ namespace Artemis.UI.Ninject.Factories
|
|||||||
}
|
}
|
||||||
public interface IDisplayConditionsVmFactory : IVmFactory
|
public interface IDisplayConditionsVmFactory : IVmFactory
|
||||||
{
|
{
|
||||||
DisplayConditionGroupViewModel DisplayConditionGroupViewModel(DisplayConditionGroup displayConditionGroup, DisplayConditionViewModel parent);
|
DisplayConditionGroupViewModel DisplayConditionGroupViewModel(DisplayConditionGroup displayConditionGroup, DisplayConditionViewModel parent, bool isListGroup);
|
||||||
DisplayConditionListViewModel DisplayConditionListViewModel(DisplayConditionList displayConditionList, DisplayConditionViewModel parent);
|
DisplayConditionListViewModel DisplayConditionListViewModel(DisplayConditionList displayConditionList, DisplayConditionViewModel parent);
|
||||||
DisplayConditionPredicateViewModel DisplayConditionPredicateViewModel(DisplayConditionPredicate displayConditionPredicate, DisplayConditionViewModel parent);
|
DisplayConditionPredicateViewModel DisplayConditionPredicateViewModel(DisplayConditionPredicate displayConditionPredicate, DisplayConditionViewModel parent);
|
||||||
|
DisplayConditionListPredicateViewModel DisplayConditionListPredicateViewModel(DisplayConditionListPredicate displayConditionListPredicate, DisplayConditionViewModel parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ILayerPropertyVmFactory : IVmFactory
|
public interface ILayerPropertyVmFactory : IVmFactory
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Core.Models.Profile.Conditions.Abstract;
|
using Artemis.Core.Models.Profile.Conditions.Abstract;
|
||||||
using Artemis.UI.Shared.DataModelVisualization.Shared;
|
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract
|
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract
|
||||||
@ -29,11 +28,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract
|
|||||||
|
|
||||||
public abstract void Update();
|
public abstract void Update();
|
||||||
|
|
||||||
public virtual DataModelPropertiesViewModel GetDataModelOverride()
|
|
||||||
{
|
|
||||||
return Parent?.GetDataModelOverride();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Delete()
|
public virtual void Delete()
|
||||||
{
|
{
|
||||||
Model.Parent.RemoveChild(Model);
|
Model.Parent.RemoveChild(Model);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.DisplayConditionGroupView"
|
<UserControl
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@ -6,14 +6,18 @@
|
|||||||
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions"
|
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:s="https://github.com/canton7/Stylet"
|
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"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800"
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
d:DataContext="{d:DesignInstance Type=local:DisplayConditionGroupViewModel, IsDesignTimeCreatable=False}">
|
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=False, Type={x:Type local:DisplayConditionGroupViewModel}}">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
@ -68,23 +72,23 @@
|
|||||||
<Button.Style>
|
<Button.Style>
|
||||||
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MaterialDesignIconForegroundButton}">
|
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MaterialDesignIconForegroundButton}">
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<EventTrigger RoutedEvent="Click">
|
<EventTrigger RoutedEvent="ButtonBase.Click">
|
||||||
<EventTrigger.Actions>
|
<BeginStoryboard>
|
||||||
<BeginStoryboard>
|
<Storyboard>
|
||||||
<Storyboard>
|
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
|
||||||
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
|
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True" />
|
||||||
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True" />
|
</BooleanAnimationUsingKeyFrames>
|
||||||
</BooleanAnimationUsingKeyFrames>
|
</Storyboard>
|
||||||
</Storyboard>
|
</BeginStoryboard>
|
||||||
</BeginStoryboard>
|
|
||||||
</EventTrigger.Actions>
|
|
||||||
</EventTrigger>
|
</EventTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
</Button.Style>
|
</Button.Style>
|
||||||
<materialDesign:PackIcon Kind="Add" Width="18" Height="18" />
|
|
||||||
<Button.ContextMenu>
|
<Button.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
|
<ContextMenu.Resources>
|
||||||
|
<Converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
||||||
|
</ContextMenu.Resources>
|
||||||
<MenuItem Header="Add static condition"
|
<MenuItem Header="Add static condition"
|
||||||
ToolTip="A condition that compares a data model property to a static input"
|
ToolTip="A condition that compares a data model property to a static input"
|
||||||
Command="{s:Action AddCondition}"
|
Command="{s:Action AddCondition}"
|
||||||
@ -104,7 +108,8 @@
|
|||||||
<MenuItem Header="Add list condition"
|
<MenuItem Header="Add list condition"
|
||||||
ToolTip="A condition that evaluates on items in a list"
|
ToolTip="A condition that evaluates on items in a list"
|
||||||
Command="{s:Action AddCondition}"
|
Command="{s:Action AddCondition}"
|
||||||
CommandParameter="List">
|
CommandParameter="List"
|
||||||
|
IsEnabled="{Binding Data.IsListGroup, Converter={StaticResource InverseBooleanConverter}, Source={StaticResource DataContextProxy}}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<materialDesign:PackIcon Kind="FormatListBulleted" />
|
<materialDesign:PackIcon Kind="FormatListBulleted" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
@ -116,6 +121,7 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</Button.ContextMenu>
|
</Button.ContextMenu>
|
||||||
|
<materialDesign:PackIcon Kind="Add" Width="18" Height="18" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Children}">
|
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Children}">
|
||||||
|
|||||||
@ -18,9 +18,10 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
private bool _isInitialized;
|
private bool _isInitialized;
|
||||||
private bool _isRootGroup;
|
private bool _isRootGroup;
|
||||||
|
|
||||||
public DisplayConditionGroupViewModel(DisplayConditionGroup displayConditionGroup, DisplayConditionViewModel parent,
|
public DisplayConditionGroupViewModel(DisplayConditionGroup displayConditionGroup, DisplayConditionViewModel parent, bool isListGroup,
|
||||||
IProfileEditorService profileEditorService, IDisplayConditionsVmFactory displayConditionsVmFactory) : base(displayConditionGroup, parent)
|
IProfileEditorService profileEditorService, IDisplayConditionsVmFactory displayConditionsVmFactory) : base(displayConditionGroup, parent)
|
||||||
{
|
{
|
||||||
|
IsListGroup = isListGroup;
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
_displayConditionsVmFactory = displayConditionsVmFactory;
|
_displayConditionsVmFactory = displayConditionsVmFactory;
|
||||||
|
|
||||||
@ -33,6 +34,8 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsListGroup { get; }
|
||||||
|
|
||||||
public DisplayConditionGroup DisplayConditionGroup => (DisplayConditionGroup) Model;
|
public DisplayConditionGroup DisplayConditionGroup => (DisplayConditionGroup) Model;
|
||||||
|
|
||||||
public bool IsRootGroup
|
public bool IsRootGroup
|
||||||
@ -62,15 +65,27 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
var enumValue = Enum.Parse<BooleanOperator>(type);
|
var enumValue = Enum.Parse<BooleanOperator>(type);
|
||||||
DisplayConditionGroup.BooleanOperator = enumValue;
|
DisplayConditionGroup.BooleanOperator = enumValue;
|
||||||
NotifyOfPropertyChange(nameof(SelectedBooleanOperator));
|
NotifyOfPropertyChange(nameof(SelectedBooleanOperator));
|
||||||
|
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCondition(string type)
|
public void AddCondition(string type)
|
||||||
{
|
{
|
||||||
if (type == "Static")
|
if (type == "Static")
|
||||||
DisplayConditionGroup.AddChild(new DisplayConditionPredicate(DisplayConditionGroup, PredicateType.Static));
|
{
|
||||||
|
if (!IsListGroup)
|
||||||
|
DisplayConditionGroup.AddChild(new DisplayConditionPredicate(DisplayConditionGroup, PredicateType.Static));
|
||||||
|
else
|
||||||
|
DisplayConditionGroup.AddChild(new DisplayConditionListPredicate(DisplayConditionGroup, PredicateType.Static));
|
||||||
|
}
|
||||||
else if (type == "Dynamic")
|
else if (type == "Dynamic")
|
||||||
DisplayConditionGroup.AddChild(new DisplayConditionPredicate(DisplayConditionGroup, PredicateType.Dynamic));
|
{
|
||||||
else if (type == "List")
|
if (!IsListGroup)
|
||||||
|
DisplayConditionGroup.AddChild(new DisplayConditionPredicate(DisplayConditionGroup, PredicateType.Dynamic));
|
||||||
|
else
|
||||||
|
DisplayConditionGroup.AddChild(new DisplayConditionListPredicate(DisplayConditionGroup, PredicateType.Dynamic));
|
||||||
|
}
|
||||||
|
else if (type == "List" && !IsListGroup)
|
||||||
DisplayConditionGroup.AddChild(new DisplayConditionList(DisplayConditionGroup));
|
DisplayConditionGroup.AddChild(new DisplayConditionList(DisplayConditionGroup));
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
@ -106,13 +121,18 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
switch (childModel)
|
switch (childModel)
|
||||||
{
|
{
|
||||||
case DisplayConditionGroup displayConditionGroup:
|
case DisplayConditionGroup displayConditionGroup:
|
||||||
Children.Add(_displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, this));
|
Children.Add(_displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, this, IsListGroup));
|
||||||
break;
|
break;
|
||||||
case DisplayConditionList displayConditionListPredicate:
|
case DisplayConditionList displayConditionListPredicate:
|
||||||
Children.Add(_displayConditionsVmFactory.DisplayConditionListViewModel(displayConditionListPredicate, this));
|
Children.Add(_displayConditionsVmFactory.DisplayConditionListViewModel(displayConditionListPredicate, this));
|
||||||
break;
|
break;
|
||||||
case DisplayConditionPredicate displayConditionPredicate:
|
case DisplayConditionPredicate displayConditionPredicate:
|
||||||
Children.Add(_displayConditionsVmFactory.DisplayConditionPredicateViewModel(displayConditionPredicate, this));
|
if (!IsListGroup)
|
||||||
|
Children.Add(_displayConditionsVmFactory.DisplayConditionPredicateViewModel(displayConditionPredicate, this));
|
||||||
|
break;
|
||||||
|
case DisplayConditionListPredicate displayConditionListPredicate:
|
||||||
|
if (IsListGroup)
|
||||||
|
Children.Add(_displayConditionsVmFactory.DisplayConditionListPredicateViewModel(displayConditionListPredicate, this));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,187 @@
|
|||||||
|
<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:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions"
|
||||||
|
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>
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for DisplayConditionListPredicateView.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class DisplayConditionListPredicateView : UserControl
|
||||||
|
{
|
||||||
|
public DisplayConditionListPredicateView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PropertyButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// DataContext is not set when using left button, I don't know why but there it is
|
||||||
|
if (sender is Button button && button.ContextMenu != null)
|
||||||
|
{
|
||||||
|
button.ContextMenu.DataContext = button.DataContext;
|
||||||
|
button.ContextMenu.IsOpen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,361 @@
|
|||||||
|
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.Models.Profile.Conditions;
|
||||||
|
using Artemis.Core.Plugins.Models;
|
||||||
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.Core.Services.Interfaces;
|
||||||
|
using Artemis.UI.Events;
|
||||||
|
using Artemis.UI.Exceptions;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;
|
||||||
|
using Artemis.UI.Shared.DataModelVisualization;
|
||||||
|
using Artemis.UI.Shared.DataModelVisualization.Shared;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
|
using Artemis.UI.Utilities;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||||
|
{
|
||||||
|
public class DisplayConditionListPredicateViewModel : DisplayConditionViewModel, IHandle<MainWindowKeyEvent>, IHandle<MainWindowMouseEvent>
|
||||||
|
{
|
||||||
|
private readonly IDataModelService _dataModelService;
|
||||||
|
private readonly IDataModelVisualizationService _dataModelVisualizationService;
|
||||||
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
private readonly Timer _updateTimer;
|
||||||
|
private bool _isInitialized;
|
||||||
|
private DataModelVisualizationViewModel _leftSideDataModel;
|
||||||
|
private BindableCollection<DisplayConditionOperator> _operators;
|
||||||
|
private DataModelVisualizationViewModel _rightSideDataModel;
|
||||||
|
private DataModelInputViewModel _rightSideInputViewModel;
|
||||||
|
private int _rightSideTransitionIndex;
|
||||||
|
private object _rightStaticValue;
|
||||||
|
private DataModelVisualizationViewModel _selectedLeftSideProperty;
|
||||||
|
private DisplayConditionOperator _selectedOperator;
|
||||||
|
private DataModelVisualizationViewModel _selectedRightSideProperty;
|
||||||
|
|
||||||
|
private List<Type> _supportedInputTypes;
|
||||||
|
|
||||||
|
public DisplayConditionListPredicateViewModel(
|
||||||
|
DisplayConditionListPredicate displayConditionListPredicate,
|
||||||
|
DisplayConditionViewModel parent,
|
||||||
|
IProfileEditorService profileEditorService,
|
||||||
|
IDataModelVisualizationService dataModelVisualizationService,
|
||||||
|
IDataModelService dataModelService,
|
||||||
|
ISettingsService settingsService,
|
||||||
|
IEventAggregator eventAggregator) : base(displayConditionListPredicate, parent)
|
||||||
|
{
|
||||||
|
_profileEditorService = profileEditorService;
|
||||||
|
_dataModelVisualizationService = dataModelVisualizationService;
|
||||||
|
_dataModelService = dataModelService;
|
||||||
|
_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<DisplayConditionOperator>();
|
||||||
|
|
||||||
|
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||||
|
|
||||||
|
// Initialize async, no need to wait for it
|
||||||
|
Task.Run(Initialize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisplayConditionListPredicate DisplayConditionListPredicate => (DisplayConditionListPredicate) Model;
|
||||||
|
public bool ShowRightSidePropertySelection => DisplayConditionListPredicate.PredicateType == PredicateType.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<DisplayConditionOperator> Operators
|
||||||
|
{
|
||||||
|
get => _operators;
|
||||||
|
set => SetAndNotify(ref _operators, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisplayConditionOperator 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 = _dataModelVisualizationService.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 = DisplayConditionListPredicate.ListDataModel.PluginInfo.Guid;
|
||||||
|
|
||||||
|
// If static, only allow selecting properties also supported by input
|
||||||
|
if (DisplayConditionListPredicate.PredicateType == PredicateType.Static)
|
||||||
|
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
||||||
|
|
||||||
|
// Determine the left side property first
|
||||||
|
SelectedLeftSideProperty = LeftSideDataModel.GetChildByPath(listDataModelGuid, DisplayConditionListPredicate.LeftPropertyPath);
|
||||||
|
var leftSideType = SelectedLeftSideProperty?.PropertyInfo?.PropertyType;
|
||||||
|
|
||||||
|
// Get the supported operators
|
||||||
|
Operators.Clear();
|
||||||
|
Operators.AddRange(_dataModelService.GetCompatibleConditionOperators(leftSideType));
|
||||||
|
if (DisplayConditionListPredicate.Operator == null)
|
||||||
|
DisplayConditionListPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
|
||||||
|
SelectedOperator = DisplayConditionListPredicate.Operator;
|
||||||
|
|
||||||
|
// Determine the right side
|
||||||
|
if (DisplayConditionListPredicate.PredicateType == PredicateType.Dynamic)
|
||||||
|
{
|
||||||
|
SelectedRightSideProperty = RightSideDataModel.GetChildByPath(listDataModelGuid, DisplayConditionListPredicate.RightPropertyPath);
|
||||||
|
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
RightStaticValue = DisplayConditionListPredicate.RightStaticValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyLeftSide()
|
||||||
|
{
|
||||||
|
DisplayConditionListPredicate.UpdateLeftSide(SelectedLeftSideProperty.PropertyPath);
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
|
||||||
|
SelectedOperator = DisplayConditionListPredicate.Operator;
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyRightSideDynamic()
|
||||||
|
{
|
||||||
|
DisplayConditionListPredicate.UpdateRightSideDynamic(SelectedRightSideProperty.PropertyPath);
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyRightSideStatic(object value, bool isSubmitted)
|
||||||
|
{
|
||||||
|
if (isSubmitted)
|
||||||
|
{
|
||||||
|
DisplayConditionListPredicate.UpdateRightSideStatic(value);
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
RightSideTransitionIndex = 0;
|
||||||
|
RightSideInputViewModel = null;
|
||||||
|
RightStaticValue = value;
|
||||||
|
_eventAggregator.Unsubscribe(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyOperator()
|
||||||
|
{
|
||||||
|
DisplayConditionListPredicate.UpdateOperator(SelectedOperator);
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ActivateRightSideInputViewModel()
|
||||||
|
{
|
||||||
|
if (SelectedLeftSideProperty?.PropertyInfo == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RightSideTransitionIndex = 1;
|
||||||
|
RightSideInputViewModel = _dataModelVisualizationService.GetDataModelInputViewModel(
|
||||||
|
SelectedLeftSideProperty.PropertyInfo.PropertyType,
|
||||||
|
SelectedLeftSideProperty.PropertyDescription,
|
||||||
|
DisplayConditionListPredicate.RightStaticValue,
|
||||||
|
ApplyRightSideStatic
|
||||||
|
);
|
||||||
|
_eventAggregator.Subscribe(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
_updateTimer.Stop();
|
||||||
|
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (LeftSideDataModelOpen)
|
||||||
|
LeftSideDataModel.Update(_dataModelVisualizationService);
|
||||||
|
else if (RightSideDataModelOpen)
|
||||||
|
RightSideDataModel.Update(_dataModelVisualizationService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RightDataModelUpdateRequested(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var listDataModelGuid = DisplayConditionListPredicate.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 && DisplayConditionListPredicate.RightPropertyPath != null)
|
||||||
|
SelectedRightSideProperty = RightSideDataModel.GetChildByPath(listDataModelGuid, DisplayConditionListPredicate.RightPropertyPath);
|
||||||
|
|
||||||
|
// With the data model updated, also reapply the filter
|
||||||
|
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LeftDataModelUpdateRequested(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (DisplayConditionListPredicate.PredicateType == PredicateType.Static)
|
||||||
|
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataModelVisualizationViewModel GetListDataModel()
|
||||||
|
{
|
||||||
|
if (DisplayConditionListPredicate.ListDataModel == null || DisplayConditionListPredicate.ListPropertyPath == null)
|
||||||
|
throw new ArtemisUIException("Cannot create a list predicate without first selecting a target list");
|
||||||
|
|
||||||
|
var dataModel = _dataModelVisualizationService.GetMainDataModelVisualization();
|
||||||
|
if (!_dataModelVisualizationService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule()))
|
||||||
|
dataModel.Children.Add(_dataModelVisualizationService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule()));
|
||||||
|
|
||||||
|
var listDataModel = (DataModelListViewModel) dataModel.GetChildByPath(
|
||||||
|
DisplayConditionListPredicate.ListDataModel.PluginInfo.Guid,
|
||||||
|
DisplayConditionListPredicate.ListPropertyPath
|
||||||
|
);
|
||||||
|
|
||||||
|
return listDataModel.GetListTypeViewModel(_dataModelVisualizationService);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 DisplayConditionOperator displayConditionOperator))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SelectedOperator = displayConditionOperator;
|
||||||
|
ApplyOperator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,7 +30,7 @@
|
|||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid Margin="0 3" Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
<Grid Margin="0 3">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
@ -55,11 +55,12 @@
|
|||||||
<!-- Left side, the list this predicate is targeting -->
|
<!-- Left side, the list this predicate is targeting -->
|
||||||
<Button Grid.Row="0"
|
<Button Grid.Row="0"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Background="#ab47bc"
|
Background="#476CBC"
|
||||||
BorderBrush="#ab47bc"
|
BorderBrush="#476CBC"
|
||||||
Style="{StaticResource DisplayConditionButton}"
|
Style="{StaticResource DisplayConditionButton}"
|
||||||
ToolTip="{Binding SelectedListProperty.DisplayPropertyPath}"
|
ToolTip="{Binding SelectedListProperty.DisplayPropertyPath}"
|
||||||
Click="PropertyButton_OnClick">
|
Click="PropertyButton_OnClick"
|
||||||
|
Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||||
<Button.ContextMenu>
|
<Button.ContextMenu>
|
||||||
<ContextMenu ItemsSource="{Binding TargetDataModel.Children}" IsOpen="{Binding TargetDataModelOpen, Mode=OneWayToSource}">
|
<ContextMenu ItemsSource="{Binding TargetDataModel.Children}" IsOpen="{Binding TargetDataModelOpen, Mode=OneWayToSource}">
|
||||||
<ContextMenu.ItemContainerStyle>
|
<ContextMenu.ItemContainerStyle>
|
||||||
@ -92,7 +93,8 @@
|
|||||||
BorderBrush="#7B7B7B"
|
BorderBrush="#7B7B7B"
|
||||||
Content="{Binding SelectedListOperator}"
|
Content="{Binding SelectedListOperator}"
|
||||||
Click="PropertyButton_OnClick"
|
Click="PropertyButton_OnClick"
|
||||||
HorizontalAlignment="Left">
|
HorizontalAlignment="Left"
|
||||||
|
Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||||
<Button.ContextMenu>
|
<Button.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
<MenuItem Header="Any" Command="{s:Action SelectListOperator}" CommandParameter="Any" />
|
<MenuItem Header="Any" Command="{s:Action SelectListOperator}" CommandParameter="Any" />
|
||||||
|
|||||||
@ -73,12 +73,14 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
}
|
}
|
||||||
|
|
||||||
public string SelectedListOperator => DisplayConditionList.ListOperator.Humanize();
|
public string SelectedListOperator => DisplayConditionList.ListOperator.Humanize();
|
||||||
|
|
||||||
public void SelectListOperator(string type)
|
public void SelectListOperator(string type)
|
||||||
{
|
{
|
||||||
var enumValue = Enum.Parse<ListOperator>(type);
|
var enumValue = Enum.Parse<ListOperator>(type);
|
||||||
DisplayConditionList.ListOperator = enumValue;
|
DisplayConditionList.ListOperator = enumValue;
|
||||||
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
NotifyOfPropertyChange(nameof(SelectedListOperator));
|
||||||
|
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCondition(string type)
|
public void AddCondition(string type)
|
||||||
@ -151,14 +153,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override DataModelPropertiesViewModel GetDataModelOverride()
|
|
||||||
{
|
|
||||||
if (SelectedListProperty != null)
|
|
||||||
return SelectedListProperty.GetListTypeViewModel(_dataModelVisualizationService);
|
|
||||||
|
|
||||||
return base.GetDataModelOverride();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
if (TargetDataModel == null)
|
if (TargetDataModel == null)
|
||||||
@ -195,7 +189,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
if (!(childModel is DisplayConditionGroup displayConditionGroup))
|
if (!(childModel is DisplayConditionGroup displayConditionGroup))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var viewModel = _displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, this);
|
var viewModel = _displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, this, true);
|
||||||
viewModel.IsRootGroup = true;
|
viewModel.IsRootGroup = true;
|
||||||
Children.Add(viewModel);
|
Children.Add(viewModel);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -202,9 +202,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
if (LeftSideDataModel == null || DisplayConditionPredicate.PredicateType == PredicateType.Dynamic && RightSideDataModel == null)
|
if (LeftSideDataModel == null || DisplayConditionPredicate.PredicateType == PredicateType.Dynamic && RightSideDataModel == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (GetDataModelOverride() != null)
|
|
||||||
LeftSideDataModel = GetDataModelOverride();
|
|
||||||
|
|
||||||
// If static, only allow selecting properties also supported by input
|
// If static, only allow selecting properties also supported by input
|
||||||
if (DisplayConditionPredicate.PredicateType == PredicateType.Static)
|
if (DisplayConditionPredicate.PredicateType == PredicateType.Static)
|
||||||
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
||||||
@ -224,9 +221,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
if (DisplayConditionPredicate.PredicateType == PredicateType.Dynamic)
|
if (DisplayConditionPredicate.PredicateType == PredicateType.Dynamic)
|
||||||
{
|
{
|
||||||
SelectedRightSideProperty = LeftSideDataModel.GetChildForCondition(DisplayConditionPredicate, DisplayConditionSide.Right);
|
SelectedRightSideProperty = LeftSideDataModel.GetChildForCondition(DisplayConditionPredicate, DisplayConditionSide.Right);
|
||||||
if (GetDataModelOverride() != null)
|
|
||||||
RightSideDataModel = GetDataModelOverride();
|
|
||||||
|
|
||||||
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -98,7 +98,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
e.RenderProfileElement.DisplayConditionGroup = new DisplayConditionGroup(null);
|
e.RenderProfileElement.DisplayConditionGroup = new DisplayConditionGroup(null);
|
||||||
|
|
||||||
RootGroup?.Dispose();
|
RootGroup?.Dispose();
|
||||||
RootGroup = _displayConditionsVmFactory.DisplayConditionGroupViewModel(e.RenderProfileElement.DisplayConditionGroup, null);
|
RootGroup = _displayConditionsVmFactory.DisplayConditionGroupViewModel(e.RenderProfileElement.DisplayConditionGroup, null, false);
|
||||||
RootGroup.IsRootGroup = true;
|
RootGroup.IsRootGroup = true;
|
||||||
RootGroup.Update();
|
RootGroup.Update();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user