mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
193 lines
8.4 KiB
C#
193 lines
8.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Artemis.Core;
|
|
using Artemis.UI.Ninject.Factories;
|
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Abstract;
|
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
|
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree;
|
|
using Artemis.UI.Shared.Services;
|
|
using Humanizer;
|
|
using Ninject;
|
|
using Ninject.Parameters;
|
|
|
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
|
|
{
|
|
public class LayerPropertyGroupViewModel : LayerPropertyBaseViewModel
|
|
{
|
|
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
|
|
private ViewModelType _groupType;
|
|
private TimelinePropertyGroupViewModel _timelinePropertyGroupViewModel;
|
|
private TreePropertyGroupViewModel _treePropertyGroupViewModel;
|
|
|
|
public LayerPropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, PropertyGroupDescriptionAttribute propertyGroupDescription,
|
|
IProfileEditorService profileEditorService, ILayerPropertyVmFactory layerPropertyVmFactory)
|
|
{
|
|
_layerPropertyVmFactory = layerPropertyVmFactory;
|
|
ProfileEditorService = profileEditorService;
|
|
|
|
LayerPropertyGroup = layerPropertyGroup;
|
|
PropertyGroupDescription = propertyGroupDescription;
|
|
|
|
TreePropertyGroupViewModel = _layerPropertyVmFactory.TreePropertyGroupViewModel(this);
|
|
TimelinePropertyGroupViewModel = _layerPropertyVmFactory.TimelinePropertyGroupViewModel(this);
|
|
|
|
// Generate a fallback name if the description does not contain one
|
|
if (PropertyGroupDescription.Name == null)
|
|
{
|
|
var propertyInfo = LayerPropertyGroup.Parent?.GetType().GetProperties().FirstOrDefault(p => ReferenceEquals(p.GetValue(LayerPropertyGroup.Parent), LayerPropertyGroup));
|
|
if (propertyInfo != null)
|
|
PropertyGroupDescription.Name = propertyInfo.Name.Humanize();
|
|
else
|
|
PropertyGroupDescription.Name = "Unknown group";
|
|
}
|
|
|
|
LayerPropertyGroup.VisibilityChanged += LayerPropertyGroupOnVisibilityChanged;
|
|
PopulateChildren();
|
|
DetermineType();
|
|
}
|
|
|
|
public override bool IsVisible => !LayerPropertyGroup.IsHidden;
|
|
public IProfileEditorService ProfileEditorService { get; }
|
|
public LayerPropertyGroup LayerPropertyGroup { get; }
|
|
public PropertyGroupDescriptionAttribute PropertyGroupDescription { get; }
|
|
|
|
public override bool IsExpanded
|
|
{
|
|
get => LayerPropertyGroup.ProfileElement.IsPropertyGroupExpanded(LayerPropertyGroup);
|
|
set
|
|
{
|
|
LayerPropertyGroup.ProfileElement.SetPropertyGroupExpanded(LayerPropertyGroup, value);
|
|
NotifyOfPropertyChange(nameof(IsExpanded));
|
|
}
|
|
}
|
|
|
|
public ViewModelType GroupType
|
|
{
|
|
get => _groupType;
|
|
set => SetAndNotify(ref _groupType, value);
|
|
}
|
|
|
|
public TreePropertyGroupViewModel TreePropertyGroupViewModel
|
|
{
|
|
get => _treePropertyGroupViewModel;
|
|
set => SetAndNotify(ref _treePropertyGroupViewModel, value);
|
|
}
|
|
|
|
public TimelinePropertyGroupViewModel TimelinePropertyGroupViewModel
|
|
{
|
|
get => _timelinePropertyGroupViewModel;
|
|
set => SetAndNotify(ref _timelinePropertyGroupViewModel, value);
|
|
}
|
|
|
|
public override List<BaseLayerPropertyKeyframe> GetKeyframes(bool expandedOnly)
|
|
{
|
|
var result = new List<BaseLayerPropertyKeyframe>();
|
|
if (expandedOnly && !IsExpanded || LayerPropertyGroup.IsHidden)
|
|
return result;
|
|
|
|
foreach (var layerPropertyBaseViewModel in Children)
|
|
result.AddRange(layerPropertyBaseViewModel.GetKeyframes(expandedOnly));
|
|
|
|
return result;
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
foreach (var layerPropertyBaseViewModel in Children)
|
|
layerPropertyBaseViewModel.Dispose();
|
|
|
|
LayerPropertyGroup.VisibilityChanged -= LayerPropertyGroupOnVisibilityChanged;
|
|
TimelinePropertyGroupViewModel.Dispose();
|
|
}
|
|
|
|
public List<LayerPropertyBaseViewModel> GetAllChildren()
|
|
{
|
|
var result = new List<LayerPropertyBaseViewModel>();
|
|
foreach (var layerPropertyBaseViewModel in Children)
|
|
{
|
|
result.Add(layerPropertyBaseViewModel);
|
|
if (layerPropertyBaseViewModel is LayerPropertyGroupViewModel layerPropertyGroupViewModel)
|
|
result.AddRange(layerPropertyGroupViewModel.GetAllChildren());
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public void UpdateOrder(int order)
|
|
{
|
|
LayerPropertyGroup.LayerEffect.Order = order;
|
|
NotifyOfPropertyChange(nameof(IsExpanded));
|
|
}
|
|
|
|
private void DetermineType()
|
|
{
|
|
if (LayerPropertyGroup is LayerGeneralProperties)
|
|
GroupType = ViewModelType.General;
|
|
else if (LayerPropertyGroup is LayerTransformProperties)
|
|
GroupType = ViewModelType.Transform;
|
|
else if (LayerPropertyGroup.Parent == null && LayerPropertyGroup.LayerBrush != null)
|
|
GroupType = ViewModelType.LayerBrushRoot;
|
|
else if (LayerPropertyGroup.Parent == null && LayerPropertyGroup.LayerEffect != null)
|
|
GroupType = ViewModelType.LayerEffectRoot;
|
|
else
|
|
GroupType = ViewModelType.None;
|
|
}
|
|
|
|
private void PopulateChildren()
|
|
{
|
|
// Get all properties and property groups and create VMs for them
|
|
foreach (var propertyInfo in LayerPropertyGroup.GetType().GetProperties())
|
|
{
|
|
var propertyAttribute = (PropertyDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyDescriptionAttribute));
|
|
var groupAttribute = (PropertyGroupDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyGroupDescriptionAttribute));
|
|
var value = propertyInfo.GetValue(LayerPropertyGroup);
|
|
|
|
// Create VMs for properties on the group
|
|
if (propertyAttribute != null && value is BaseLayerProperty baseLayerProperty)
|
|
{
|
|
var viewModel = CreateLayerPropertyViewModel(baseLayerProperty, propertyAttribute);
|
|
if (viewModel != null)
|
|
Children.Add(viewModel);
|
|
}
|
|
// Create VMs for child groups on this group, resulting in a nested structure
|
|
else if (groupAttribute != null && value is LayerPropertyGroup layerPropertyGroup)
|
|
Children.Add(_layerPropertyVmFactory.LayerPropertyGroupViewModel(layerPropertyGroup, groupAttribute));
|
|
}
|
|
}
|
|
|
|
private LayerPropertyBaseViewModel CreateLayerPropertyViewModel(BaseLayerProperty baseLayerProperty, PropertyDescriptionAttribute propertyDescription)
|
|
{
|
|
// Go through the pain of instantiating a generic type VM now via reflection to make things a lot simpler down the line
|
|
var genericType = baseLayerProperty.GetType().Name == typeof(LayerProperty<>).Name
|
|
? baseLayerProperty.GetType().GetGenericArguments()[0]
|
|
: baseLayerProperty.GetType().BaseType.GetGenericArguments()[0];
|
|
|
|
// Only create entries for types supported by a tree input VM
|
|
if (!genericType.IsEnum && ProfileEditorService.RegisteredPropertyEditors.All(r => r.SupportedType != genericType))
|
|
return null;
|
|
var genericViewModel = typeof(LayerPropertyViewModel<>).MakeGenericType(genericType);
|
|
var parameters = new IParameter[]
|
|
{
|
|
new ConstructorArgument("layerProperty", baseLayerProperty),
|
|
new ConstructorArgument("propertyDescription", propertyDescription)
|
|
};
|
|
|
|
return (LayerPropertyBaseViewModel) ProfileEditorService.Kernel.Get(genericViewModel, parameters);
|
|
}
|
|
|
|
private void LayerPropertyGroupOnVisibilityChanged(object sender, EventArgs e)
|
|
{
|
|
NotifyOfPropertyChange(nameof(IsVisible));
|
|
}
|
|
|
|
public enum ViewModelType
|
|
{
|
|
General,
|
|
Transform,
|
|
LayerBrushRoot,
|
|
LayerEffectRoot,
|
|
None
|
|
}
|
|
}
|
|
} |