mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Display conditions - Implemented lists in the core, UI needs more work
This commit is contained in:
parent
ae708fa26a
commit
f2f77da953
@ -35,8 +35,19 @@ namespace Artemis.Core.Models.Profile.Conditions.Abstract
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the condition part on the data model
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool Evaluate();
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the condition part on the given target (currently only for lists)
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool EvaluateObject(object target);
|
||||
|
||||
internal abstract void Initialize(IDataModelService dataModelService);
|
||||
internal abstract void ApplyToEntity();
|
||||
internal abstract DisplayConditionPartEntity GetEntity();
|
||||
|
||||
@ -37,9 +37,12 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
|
||||
public override bool Evaluate()
|
||||
{
|
||||
// If there are less than two children, ignore the boolean operator
|
||||
if (Children.Count <= 2)
|
||||
return Children.All(c => c.Evaluate());
|
||||
// Empty groups are always true
|
||||
if (Children.Count == 0)
|
||||
return true;
|
||||
// Groups with only one child ignore the boolean operator
|
||||
if (Children.Count == 1)
|
||||
return Children[0].Evaluate();
|
||||
|
||||
switch (BooleanOperator)
|
||||
{
|
||||
@ -56,6 +59,25 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
}
|
||||
}
|
||||
|
||||
public override bool EvaluateObject(object target)
|
||||
{
|
||||
// Empty groups are always true
|
||||
if (Children.Count == 0)
|
||||
return true;
|
||||
// Groups with only one child ignore the boolean operator
|
||||
if (Children.Count == 1)
|
||||
return Children[0].EvaluateObject(target);
|
||||
|
||||
return BooleanOperator switch
|
||||
{
|
||||
BooleanOperator.And => Children.All(c => c.EvaluateObject(target)),
|
||||
BooleanOperator.Or => Children.Any(c => c.EvaluateObject(target)),
|
||||
BooleanOperator.AndNot => Children.All(c => !c.EvaluateObject(target)),
|
||||
BooleanOperator.OrNot => Children.Any(c => !c.EvaluateObject(target)),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
|
||||
internal override void ApplyToEntity()
|
||||
{
|
||||
DisplayConditionGroupEntity.BooleanOperator = (int) BooleanOperator;
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Artemis.Core.Exceptions;
|
||||
using Artemis.Core.Models.Profile.Conditions.Abstract;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels;
|
||||
@ -44,7 +47,23 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
|
||||
public override bool Evaluate()
|
||||
{
|
||||
return true;
|
||||
return EvaluateObject(CompiledListAccessor(ListDataModel));
|
||||
}
|
||||
|
||||
public override bool EvaluateObject(object target)
|
||||
{
|
||||
if (!(target is IList list))
|
||||
return false;
|
||||
|
||||
var objectList = list.Cast<object>();
|
||||
return ListOperator switch
|
||||
{
|
||||
ListOperator.Any => objectList.Any(o => Children[0].EvaluateObject(o)),
|
||||
ListOperator.All => objectList.All(o => Children[0].EvaluateObject(o)),
|
||||
ListOperator.None => objectList.Any(o => !Children[0].EvaluateObject(o)),
|
||||
ListOperator.Count => false,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
|
||||
internal override void ApplyToEntity()
|
||||
@ -94,11 +113,26 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
{
|
||||
if (!dataModel.ContainsPath(path))
|
||||
throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'");
|
||||
if (dataModel.GetListTypeAtPath(path) == null)
|
||||
throw new ArtemisCoreException($"The path '{path}' does not contain a list");
|
||||
}
|
||||
|
||||
ListDataModel = dataModel;
|
||||
ListPropertyPath = path;
|
||||
|
||||
if (dataModel != null)
|
||||
{
|
||||
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);
|
||||
CompiledListAccessor = lambda.Compile();
|
||||
}
|
||||
}
|
||||
|
||||
public Func<object, IList> CompiledListAccessor { get; set; }
|
||||
}
|
||||
|
||||
public enum ListOperator
|
||||
|
||||
@ -39,10 +39,9 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
public string RightPropertyPath { get; private set; }
|
||||
public object RightStaticValue { get; private set; }
|
||||
|
||||
public Expression<Func<DataModel, DataModel, bool>> DynamicConditionLambda { get; private set; }
|
||||
public Func<DataModel, DataModel, bool> CompiledDynamicConditionLambda { get; private set; }
|
||||
public Expression<Func<DataModel, bool>> StaticConditionLambda { get; private set; }
|
||||
public Func<DataModel, bool> CompiledStaticConditionLambda { get; private set; }
|
||||
public Func<DataModel, DataModel, bool> CompiledDynamicPredicate { get; private set; }
|
||||
public Func<DataModel, bool> CompiledStaticPredicate { get; private set; }
|
||||
public Func<object, bool> CompiledListPredicate { get; private set; }
|
||||
|
||||
public void UpdateLeftSide(DataModel dataModel, string path)
|
||||
{
|
||||
@ -120,10 +119,9 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
|
||||
private void CreateExpression()
|
||||
{
|
||||
DynamicConditionLambda = null;
|
||||
CompiledDynamicConditionLambda = null;
|
||||
StaticConditionLambda = null;
|
||||
CompiledStaticConditionLambda = null;
|
||||
CompiledDynamicPredicate = null;
|
||||
CompiledStaticPredicate = null;
|
||||
CompiledListPredicate = null;
|
||||
|
||||
if (Operator == null)
|
||||
return;
|
||||
@ -137,7 +135,7 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
|
||||
internal override void ApplyToEntity()
|
||||
{
|
||||
DisplayConditionPredicateEntity.PredicateType = (int)PredicateType;
|
||||
DisplayConditionPredicateEntity.PredicateType = (int) PredicateType;
|
||||
DisplayConditionPredicateEntity.LeftDataModelGuid = LeftDataModel?.PluginInfo?.Guid;
|
||||
DisplayConditionPredicateEntity.LeftPropertyPath = LeftPropertyPath;
|
||||
|
||||
@ -151,10 +149,18 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
|
||||
public override bool Evaluate()
|
||||
{
|
||||
if (CompiledDynamicConditionLambda != null)
|
||||
return CompiledDynamicConditionLambda(LeftDataModel, RightDataModel);
|
||||
if (CompiledStaticConditionLambda != null)
|
||||
return CompiledStaticConditionLambda(LeftDataModel);
|
||||
if (CompiledDynamicPredicate != null)
|
||||
return CompiledDynamicPredicate(LeftDataModel, RightDataModel);
|
||||
if (CompiledStaticPredicate != null)
|
||||
return CompiledStaticPredicate(LeftDataModel);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool EvaluateObject(object target)
|
||||
{
|
||||
if (CompiledListPredicate != null)
|
||||
return CompiledListPredicate(target);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -194,7 +200,7 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
// Use the left side type so JSON.NET has a better idea what to do
|
||||
var leftSideType = LeftDataModel.GetTypeAtPath(LeftPropertyPath);
|
||||
object rightSideValue;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
rightSideValue = JsonConvert.DeserializeObject(DisplayConditionPredicateEntity.RightStaticValue, leftSideType);
|
||||
@ -286,26 +292,42 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
if (LeftDataModel == null || RightDataModel == null || Operator == null)
|
||||
return;
|
||||
|
||||
var leftSideParameter = Expression.Parameter(typeof(DataModel), "leftDataModel");
|
||||
var leftSideAccessor = LeftPropertyPath.Split('.').Aggregate<string, Expression>(
|
||||
Expression.Convert(leftSideParameter, LeftDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Property
|
||||
);
|
||||
var rightSideParameter = Expression.Parameter(typeof(DataModel), "rightDataModel");
|
||||
var rightSideAccessor = RightPropertyPath.Split('.').Aggregate<string, Expression>(
|
||||
Expression.Convert(rightSideParameter, LeftDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Property
|
||||
);
|
||||
var isListExpression = LeftDataModel.GetListTypeAtPath(LeftPropertyPath) != null;
|
||||
|
||||
Expression leftSideAccessor;
|
||||
Expression rightSideAccessor;
|
||||
ParameterExpression leftSideParameter;
|
||||
ParameterExpression rightSideParameter = null;
|
||||
if (isListExpression)
|
||||
{
|
||||
// List accessors share the same parameter because a list always contains one item per entry
|
||||
leftSideParameter = Expression.Parameter(typeof(object), "listItem");
|
||||
leftSideAccessor = CreateListAccessor(LeftDataModel, LeftPropertyPath, leftSideParameter);
|
||||
rightSideAccessor = CreateListAccessor(RightDataModel, RightPropertyPath, leftSideParameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
leftSideAccessor = CreateAccessor(LeftDataModel, LeftPropertyPath, "left", out leftSideParameter);
|
||||
rightSideAccessor = CreateAccessor(RightDataModel, RightPropertyPath, "right", out rightSideParameter);
|
||||
}
|
||||
|
||||
// A conversion may be required if the types differ
|
||||
// This can cause issues if the DisplayConditionOperator wasn't accurate in it's supported types but that is not a concern here
|
||||
if (rightSideAccessor.Type != leftSideAccessor.Type)
|
||||
rightSideAccessor = Expression.Convert(rightSideAccessor, leftSideAccessor.Type);
|
||||
|
||||
var dynamicConditionExpression = Operator.CreateExpression(leftSideAccessor, rightSideAccessor);
|
||||
var conditionExpression = Operator.CreateExpression(leftSideAccessor, rightSideAccessor);
|
||||
|
||||
DynamicConditionLambda = Expression.Lambda<Func<DataModel, DataModel, bool>>(dynamicConditionExpression, leftSideParameter, rightSideParameter);
|
||||
CompiledDynamicConditionLambda = DynamicConditionLambda.Compile();
|
||||
if (isListExpression)
|
||||
{
|
||||
var lambda = Expression.Lambda<Func<object, bool>>(conditionExpression, leftSideParameter);
|
||||
CompiledListPredicate = lambda.Compile();
|
||||
}
|
||||
else
|
||||
{
|
||||
var lambda = Expression.Lambda<Func<DataModel, DataModel, bool>>(conditionExpression, leftSideParameter, rightSideParameter);
|
||||
CompiledDynamicPredicate = lambda.Compile();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateStaticExpression()
|
||||
@ -313,11 +335,18 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
if (LeftDataModel == null || Operator == null)
|
||||
return;
|
||||
|
||||
var leftSideParameter = Expression.Parameter(typeof(DataModel), "leftDataModel");
|
||||
var leftSideAccessor = LeftPropertyPath.Split('.').Aggregate<string, Expression>(
|
||||
Expression.Convert(leftSideParameter, LeftDataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Property
|
||||
);
|
||||
var isListExpression = LeftDataModel.GetListTypeAtPath(LeftPropertyPath) != null;
|
||||
|
||||
Expression leftSideAccessor;
|
||||
ParameterExpression leftSideParameter;
|
||||
if (isListExpression)
|
||||
{
|
||||
// List accessors share the same parameter because a list always contains one item per entry
|
||||
leftSideParameter = Expression.Parameter(typeof(object), "listItem");
|
||||
leftSideAccessor = CreateListAccessor(LeftDataModel, LeftPropertyPath, leftSideParameter);
|
||||
}
|
||||
else
|
||||
leftSideAccessor = CreateAccessor(LeftDataModel, LeftPropertyPath, "left", out leftSideParameter);
|
||||
|
||||
// If the left side is a value type but the input is empty, this isn't a valid expression
|
||||
if (leftSideAccessor.Type.IsValueType && RightStaticValue == null)
|
||||
@ -330,8 +359,42 @@ namespace Artemis.Core.Models.Profile.Conditions
|
||||
|
||||
var conditionExpression = Operator.CreateExpression(leftSideAccessor, rightSideConstant);
|
||||
|
||||
StaticConditionLambda = Expression.Lambda<Func<DataModel, bool>>(conditionExpression, leftSideParameter);
|
||||
CompiledStaticConditionLambda = StaticConditionLambda.Compile();
|
||||
if (isListExpression)
|
||||
{
|
||||
var lambda = Expression.Lambda<Func<object, bool>>(conditionExpression, leftSideParameter);
|
||||
CompiledListPredicate = lambda.Compile();
|
||||
}
|
||||
else
|
||||
{
|
||||
var lambda = Expression.Lambda<Func<DataModel, bool>>(conditionExpression, leftSideParameter);
|
||||
CompiledStaticPredicate = lambda.Compile();
|
||||
}
|
||||
}
|
||||
|
||||
private Expression CreateAccessor(DataModel dataModel, string path, string parameterName, out ParameterExpression parameter)
|
||||
{
|
||||
var listType = dataModel.GetListTypeAtPath(path);
|
||||
if (listType != null)
|
||||
throw new ArtemisCoreException($"Cannot create a regular accessor at path {path} because the path contains a list");
|
||||
|
||||
parameter = Expression.Parameter(typeof(object), parameterName + "DataModel");
|
||||
return path.Split('.').Aggregate<string, Expression>(
|
||||
Expression.Convert(parameter, dataModel.GetType()), // Cast to the appropriate type
|
||||
Expression.Property
|
||||
);
|
||||
}
|
||||
|
||||
private Expression CreateListAccessor(DataModel dataModel, string path, ParameterExpression listParameter)
|
||||
{
|
||||
var listType = dataModel.GetListTypeAtPath(path);
|
||||
if (listType == null)
|
||||
throw new ArtemisCoreException($"Cannot create a list accessor at path {path} because the path does not contain a list");
|
||||
|
||||
path = dataModel.GetListInnerPath(path);
|
||||
return path.Split('.').Aggregate<string, Expression>(
|
||||
Expression.Convert(listParameter, listType), // Cast to the appropriate type
|
||||
Expression.Property
|
||||
);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Artemis.Core.Exceptions;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
|
||||
using Artemis.Core.Plugins.Models;
|
||||
|
||||
@ -27,8 +31,14 @@ namespace Artemis.Core.Plugins.Abstract.DataModels
|
||||
var current = GetType();
|
||||
foreach (var part in parts)
|
||||
{
|
||||
var property = current?.GetProperty(part);
|
||||
current = property?.PropertyType;
|
||||
var property = current.GetProperty(part);
|
||||
|
||||
// For lists, look into the list type instead of the list itself
|
||||
if (property != null && typeof(IList).IsAssignableFrom(property.PropertyType))
|
||||
current = property.PropertyType.GetGenericArguments()[0];
|
||||
else
|
||||
current = property?.PropertyType;
|
||||
|
||||
if (property == null)
|
||||
return false;
|
||||
}
|
||||
@ -48,13 +58,63 @@ namespace Artemis.Core.Plugins.Abstract.DataModels
|
||||
foreach (var part in parts)
|
||||
{
|
||||
var property = current.GetProperty(part);
|
||||
current = property.PropertyType;
|
||||
|
||||
// For lists, look into the list type instead of the list itself
|
||||
if (typeof(IList).IsAssignableFrom(property.PropertyType))
|
||||
current = property.PropertyType.GetGenericArguments()[0];
|
||||
else
|
||||
current = property.PropertyType;
|
||||
|
||||
result = property.PropertyType;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Type GetListTypeAtPath(string path)
|
||||
{
|
||||
if (!ContainsPath(path))
|
||||
return null;
|
||||
|
||||
var parts = path.Split('.');
|
||||
var current = GetType();
|
||||
|
||||
foreach (var part in parts)
|
||||
{
|
||||
var property = current.GetProperty(part);
|
||||
|
||||
// For lists, look into the list type instead of the list itself
|
||||
if (typeof(IList).IsAssignableFrom(property.PropertyType))
|
||||
return property.PropertyType.GetGenericArguments()[0];
|
||||
|
||||
current = property.PropertyType;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetListInnerPath(string path)
|
||||
{
|
||||
if (GetListTypeAtPath(path) == null)
|
||||
throw new ArtemisCoreException($"Cannot determine inner list path at {path} because it does not contain a list");
|
||||
|
||||
var parts = path.Split('.');
|
||||
var current = GetType();
|
||||
|
||||
for (var index = 0; index < parts.Length; index++)
|
||||
{
|
||||
var part = parts[index];
|
||||
var property = current.GetProperty(part);
|
||||
|
||||
if (typeof(IList).IsAssignableFrom(property.PropertyType))
|
||||
return string.Join('.', parts.Skip(index + 1).ToList());
|
||||
|
||||
current = property.PropertyType;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a read-only list of all properties in this datamodel that are to be ignored
|
||||
/// </summary>
|
||||
|
||||
@ -34,6 +34,10 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
set => SetAndNotify(ref _displayValue, value);
|
||||
}
|
||||
|
||||
public override string PropertyPath => Parent?.PropertyPath;
|
||||
|
||||
public override string DisplayPropertyPath => Parent?.DisplayPropertyPath;
|
||||
|
||||
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
|
||||
{
|
||||
// Display value gets updated by parent, don't do anything if it is null
|
||||
|
||||
@ -3,7 +3,6 @@ using System.Collections;
|
||||
using System.Reflection;
|
||||
using Artemis.Core.Extensions;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
@ -26,12 +25,6 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
set => SetAndNotify(ref _list, value);
|
||||
}
|
||||
|
||||
public DataModelVisualizationViewModel ListTypePropertyViewModel
|
||||
{
|
||||
get => _listTypePropertyViewModel;
|
||||
set => SetAndNotify(ref _listTypePropertyViewModel, value);
|
||||
}
|
||||
|
||||
public BindableCollection<DataModelVisualizationViewModel> ListChildren { get; set; }
|
||||
|
||||
public string Count
|
||||
@ -40,6 +33,30 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
set => SetAndNotify(ref _count, value);
|
||||
}
|
||||
|
||||
public DataModelPropertiesViewModel GetListTypeViewModel(IDataModelVisualizationService dataModelVisualizationService)
|
||||
{
|
||||
// Create a property VM describing the type of the list
|
||||
var viewModel = CreateListChild(dataModelVisualizationService, List.GetType().GenericTypeArguments[0]);
|
||||
|
||||
// Put an empty value into the list type property view model
|
||||
if (viewModel is DataModelListPropertiesViewModel dataModelListClassViewModel)
|
||||
{
|
||||
dataModelListClassViewModel.DisplayValue = Activator.CreateInstance(dataModelListClassViewModel.ListType);
|
||||
dataModelListClassViewModel.Update(dataModelVisualizationService);
|
||||
return dataModelListClassViewModel;
|
||||
}
|
||||
|
||||
if (viewModel is DataModelListPropertyViewModel dataModelListPropertyViewModel)
|
||||
{
|
||||
dataModelListPropertyViewModel.DisplayValue = Activator.CreateInstance(dataModelListPropertyViewModel.ListType);
|
||||
var wrapper = new DataModelPropertiesViewModel(null,null,null);
|
||||
wrapper.Children.Add(dataModelListPropertyViewModel);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void Update(IDataModelVisualizationService dataModelVisualizationService)
|
||||
{
|
||||
if (Parent != null && !Parent.IsVisualizationExpanded)
|
||||
@ -49,20 +66,6 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
if (List == null)
|
||||
return;
|
||||
|
||||
if (ListTypePropertyViewModel == null)
|
||||
{
|
||||
// Create a property VM describing the type of the list
|
||||
ListTypePropertyViewModel = CreateListChild(dataModelVisualizationService, List.GetType().GenericTypeArguments[0]);
|
||||
|
||||
// Put an empty value into the list type property view model
|
||||
if (ListTypePropertyViewModel is DataModelListPropertiesViewModel dataModelListClassViewModel)
|
||||
dataModelListClassViewModel.DisplayValue = Activator.CreateInstance(dataModelListClassViewModel.ListType);
|
||||
else if (ListTypePropertyViewModel is DataModelListPropertyViewModel dataModelListPropertyViewModel)
|
||||
dataModelListPropertyViewModel.DisplayValue = Activator.CreateInstance(dataModelListPropertyViewModel.ListType);
|
||||
|
||||
ListTypePropertyViewModel.Update(dataModelVisualizationService);
|
||||
}
|
||||
|
||||
var index = 0;
|
||||
foreach (var item in List)
|
||||
{
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Documents;
|
||||
using Artemis.Core.Extensions;
|
||||
using Artemis.Core.Models.Profile.Conditions;
|
||||
using Artemis.Core.Plugins.Abstract;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels;
|
||||
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
|
||||
using Artemis.UI.Shared.Exceptions;
|
||||
@ -26,7 +25,6 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
private DataModelVisualizationViewModel _parent;
|
||||
private DataModelPropertyAttribute _propertyDescription;
|
||||
private PropertyInfo _propertyInfo;
|
||||
private bool _isIgnored;
|
||||
|
||||
internal DataModelVisualizationViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, PropertyInfo propertyInfo)
|
||||
{
|
||||
@ -91,7 +89,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
}
|
||||
}
|
||||
|
||||
public string PropertyPath
|
||||
public virtual string PropertyPath
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -106,7 +104,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayPropertyPath
|
||||
public virtual string DisplayPropertyPath
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -176,7 +174,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
IsMatchingFilteredTypes = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (looseMatch)
|
||||
IsMatchingFilteredTypes = filteredTypes.Any(t => t.IsCastableFrom(PropertyInfo.PropertyType));
|
||||
else
|
||||
@ -213,12 +211,14 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
|
||||
|
||||
if (IsRootViewModel)
|
||||
{
|
||||
var child = Children.FirstOrDefault(c => c.DataModel.PluginInfo.Guid == dataModelGuid);
|
||||
var child = Children.FirstOrDefault(c => c.DataModel != null &&
|
||||
c.DataModel.PluginInfo.Guid == dataModelGuid);
|
||||
return child?.GetChildByPath(dataModelGuid, propertyPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
var child = Children.FirstOrDefault(c => c.DataModel.PluginInfo.Guid == dataModelGuid && c.PropertyInfo?.Name == currentPart);
|
||||
var child = Children.FirstOrDefault(c => c.DataModel != null &&
|
||||
c.DataModel.PluginInfo.Guid == dataModelGuid && c.PropertyInfo?.Name == currentPart);
|
||||
if (child == null)
|
||||
return null;
|
||||
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:dataModel="clr-namespace:Artemis.UI.Shared.DataModelVisualization.Shared;assembly=Artemis.UI.Shared"
|
||||
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">
|
||||
<Style x:Key="DisplayConditionButton" TargetType="{x:Type Button}" BasedOn="{StaticResource MaterialDesignFlatAccentBgButton}">
|
||||
<Setter Property="Margin" Value="3 0" />
|
||||
<Setter Property="Padding" Value="6 4" />
|
||||
@ -90,7 +91,6 @@
|
||||
Margin="15 0.5 0 0"
|
||||
Visibility="{Binding ShowViewModel, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</StackPanel.Resources>
|
||||
|
||||
@ -30,11 +30,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions.Abstract
|
||||
|
||||
public abstract void Update();
|
||||
|
||||
public virtual List<DataModelVisualizationViewModel> GetExtraDataModels()
|
||||
public virtual DataModelPropertiesViewModel GetDataModelOverride()
|
||||
{
|
||||
if (Parent != null)
|
||||
return Parent.GetExtraDataModels();
|
||||
return new List<DataModelVisualizationViewModel>();
|
||||
return Parent?.GetDataModelOverride();
|
||||
}
|
||||
|
||||
public virtual void Delete()
|
||||
|
||||
@ -152,13 +152,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
Update();
|
||||
}
|
||||
|
||||
public override List<DataModelVisualizationViewModel> GetExtraDataModels()
|
||||
public override DataModelPropertiesViewModel GetDataModelOverride()
|
||||
{
|
||||
var list = base.GetExtraDataModels();
|
||||
if (SelectedListProperty != null)
|
||||
list.Add(SelectedListProperty.ListTypePropertyViewModel);
|
||||
return (DataModelPropertiesViewModel) SelectedListProperty.GetListTypeViewModel(_dataModelVisualizationService);
|
||||
|
||||
return list;
|
||||
return base.GetDataModelOverride();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
@ -210,9 +209,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
return;
|
||||
|
||||
SelectedListProperty = dataModelListViewModel;
|
||||
if (SelectedListProperty.ListTypePropertyViewModel == null)
|
||||
SelectedListProperty.Update(_dataModelVisualizationService);
|
||||
|
||||
ApplyList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,6 +202,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
if (LeftSideDataModel == null || DisplayConditionPredicate.PredicateType == PredicateType.Dynamic && RightSideDataModel == null)
|
||||
return;
|
||||
|
||||
if (GetDataModelOverride() != null)
|
||||
LeftSideDataModel = GetDataModelOverride();
|
||||
|
||||
// If static, only allow selecting properties also supported by input
|
||||
if (DisplayConditionPredicate.PredicateType == PredicateType.Static)
|
||||
LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray());
|
||||
@ -221,6 +224,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
if (DisplayConditionPredicate.PredicateType == PredicateType.Dynamic)
|
||||
{
|
||||
SelectedRightSideProperty = LeftSideDataModel.GetChildForCondition(DisplayConditionPredicate, DisplayConditionSide.Right);
|
||||
if (GetDataModelOverride() != null)
|
||||
RightSideDataModel = GetDataModelOverride();
|
||||
|
||||
RightSideDataModel.ApplyTypeFilter(true, leftSideType);
|
||||
}
|
||||
else
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Plugins.Modules.General.DataModel.Windows;
|
||||
|
||||
namespace Artemis.Plugins.Modules.General.DataModel
|
||||
@ -10,6 +11,12 @@ namespace Artemis.Plugins.Modules.General.DataModel
|
||||
{
|
||||
TimeDataModel = new TimeDataModel();
|
||||
TestTimeList = new List<TimeDataModel>();
|
||||
|
||||
var testExpression = new Func<object, object, bool>((leftItem, rightDataModel) =>
|
||||
((TimeDataModel) leftItem).CurrentTime.Month == ((GeneralDataModel) rightDataModel).TimeDataModel.CurrentTime.Day);
|
||||
|
||||
|
||||
var test = TestTimeList.Any(model => testExpression(model, this));
|
||||
}
|
||||
|
||||
public WindowDataModel ActiveWindow { get; set; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user