Profile elements - Simplified class hierarchy

Profile editor - Seperated event types and avoid a lot of type checking
Profile editor - Avoid changing profiles/layers if the new equals the old
Color picker - Fixed binding error
Profile tree - Select first element by default
Profile editor - Adjusted initialization order
This commit is contained in:
Robert committed 2020-07-09 12:23:57 +02:00
1 parent 70aaa645fb
commit 7b27d076b3
25 files changed
+303 -195

No files matched your search

@@ -1,5 +1,4 @@
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.Conditions;
using Artemis.Core.Models.Profile.Conditions;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Events;
using Artemis.UI.Shared.Services.Interfaces;
@@ -23,20 +22,21 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
set => SetAndNotify(ref _rootGroup, value);
}
private void ProfileEditorServiceOnProfileElementSelected(object sender, ProfileElementEventArgs e)
private void ProfileEditorServiceOnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
{
if (e.ProfileElement is Layer layer)
if (e.RenderProfileElement == null)
{
// Ensure the layer has a root display condition group
if (layer.DisplayConditionGroup == null)
layer.DisplayConditionGroup = new DisplayConditionGroup();
RootGroup = _displayConditionsVmFactory.DisplayConditionGroupViewModel(layer.DisplayConditionGroup, null);
RootGroup.IsRootGroup = true;
RootGroup.Update();
}
else
RootGroup = null;
return;
}
// Ensure the layer has a root display condition group
if (e.RenderProfileElement.DisplayConditionGroup == null)
e.RenderProfileElement.DisplayConditionGroup = new DisplayConditionGroup();
RootGroup = _displayConditionsVmFactory.DisplayConditionGroupViewModel(e.RenderProfileElement.DisplayConditionGroup, null);
RootGroup.IsRootGroup = true;
RootGroup.Update();
}
}
}
@@ -56,11 +56,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.LayerEffects
private void HandleSelectedLayerEffectChanged(object sender, PropertyChangedEventArgs e)
{
EffectProfileElement effectElement;
RenderProfileElement renderElement;
if (LayerPropertiesViewModel.SelectedLayer != null)
effectElement = LayerPropertiesViewModel.SelectedLayer;
renderElement = LayerPropertiesViewModel.SelectedLayer;
else if (LayerPropertiesViewModel.SelectedFolder != null)
effectElement = LayerPropertiesViewModel.SelectedFolder;
renderElement = LayerPropertiesViewModel.SelectedFolder;
else
return;
@@ -70,7 +70,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.LayerEffects
Execute.PostToUIThread(async () =>
{
await Task.Delay(500);
_layerService.AddLayerEffect(effectElement, SelectedLayerEffectDescriptor);
_layerService.AddLayerEffect(renderElement, SelectedLayerEffectDescriptor);
_profileEditorService.UpdateSelectedProfileElement();
});
}
@@ -29,7 +29,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
private LayerPropertyGroupViewModel _brushPropertyGroup;
private bool _repeatAfterLastKeyframe;
private int _propertyTreeIndex;
private PropertiesProfileElement _selectedPropertiesElement;
private RenderProfileElement _selectedProfileElement;
private BindableCollection<LayerPropertyGroupViewModel> _layerPropertyGroups;
private TreeViewModel _treeViewModel;
private EffectsViewModel _effectsViewModel;
@@ -86,19 +86,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
public bool PropertyTreeVisible => PropertyTreeIndex == 0;
public PropertiesProfileElement SelectedPropertiesElement
public RenderProfileElement SelectedProfileElement
{
get => _selectedPropertiesElement;
get => _selectedProfileElement;
set
{
if (!SetAndNotify(ref _selectedPropertiesElement, value)) return;
if (!SetAndNotify(ref _selectedProfileElement, value)) return;
NotifyOfPropertyChange(nameof(SelectedLayer));
NotifyOfPropertyChange(nameof(SelectedFolder));
}
}
public Layer SelectedLayer => SelectedPropertiesElement as Layer;
public Folder SelectedFolder => SelectedPropertiesElement as Folder;
public Layer SelectedLayer => SelectedProfileElement as Layer;
public Folder SelectedFolder => SelectedProfileElement as Folder;
public BindableCollection<LayerPropertyGroupViewModel> LayerPropertyGroups
{
@@ -126,8 +126,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
protected override void OnInitialActivate()
{
if (ProfileEditorService.SelectedProfileElement is PropertiesProfileElement propertiesElement)
PopulateProperties(propertiesElement);
PopulateProperties(ProfileEditorService.SelectedProfileElement);
ProfileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
ProfileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged;
@@ -146,12 +145,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
base.OnClose();
}
protected override void OnActivate()
{
PopulateProperties(ProfileEditorService.SelectedProfileElement as PropertiesProfileElement);
base.OnActivate();
}
protected override void OnDeactivate()
{
Pause();
@@ -164,12 +157,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
EffectsViewModel.PopulateDescriptors();
}
private void ProfileEditorServiceOnProfileElementSelected(object sender, ProfileElementEventArgs e)
private void ProfileEditorServiceOnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
{
PopulateProperties(e.ProfileElement as PropertiesProfileElement);
PopulateProperties(e.RenderProfileElement);
}
private void ProfileEditorServiceOnCurrentTimeChanged(object sender, EventArgs e)
{
NotifyOfPropertyChange(nameof(FormattedCurrentTime));
@@ -190,23 +182,27 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
return groups;
}
private void PopulateProperties(PropertiesProfileElement profileElement)
private void PopulateProperties(RenderProfileElement profileElement)
{
if (SelectedPropertiesElement != null && SelectedPropertiesElement is EffectProfileElement effectElement)
effectElement.LayerEffectsUpdated -= SelectedElementOnLayerEffectsUpdated;
// Unsubscribe from old selected element
if (SelectedProfileElement != null)
SelectedProfileElement.LayerEffectsUpdated -= SelectedElementOnLayerEffectsUpdated;
if (SelectedLayer != null)
SelectedLayer.LayerBrushUpdated -= SelectedLayerOnLayerBrushUpdated;
// Clear old properties
foreach (var layerPropertyGroupViewModel in LayerPropertyGroups)
layerPropertyGroupViewModel.Dispose();
LayerPropertyGroups.Clear();
_brushPropertyGroup = null;
SelectedPropertiesElement = profileElement;
if (SelectedPropertiesElement is EffectProfileElement newEffectElement)
newEffectElement.LayerEffectsUpdated += SelectedElementOnLayerEffectsUpdated;
if (profileElement == null)
return;
// Subscribe to new element
SelectedProfileElement = profileElement;
SelectedProfileElement.LayerEffectsUpdated += SelectedElementOnLayerEffectsUpdated;
// Apply layer properties
if (SelectedLayer != null)
{
SelectedLayer.LayerBrushUpdated += SelectedLayerOnLayerBrushUpdated;
@@ -278,21 +274,21 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
private void ApplyEffects()
{
EffectProfileElement effectElement;
RenderProfileElement renderElement;
if (SelectedLayer != null)
effectElement = SelectedLayer;
renderElement = SelectedLayer;
else if (SelectedFolder != null)
effectElement = SelectedFolder;
renderElement = SelectedFolder;
else
return;
// Remove VMs of effects no longer applied on the layer
var toRemove = LayerPropertyGroups.Where(l => l.LayerPropertyGroup.LayerEffect != null && !effectElement.LayerEffects.Contains(l.LayerPropertyGroup.LayerEffect)).ToList();
var toRemove = LayerPropertyGroups.Where(l => l.LayerPropertyGroup.LayerEffect != null && !renderElement.LayerEffects.Contains(l.LayerPropertyGroup.LayerEffect)).ToList();
LayerPropertyGroups.RemoveRange(toRemove);
foreach (var layerPropertyGroupViewModel in toRemove)
layerPropertyGroupViewModel.Dispose();
foreach (var layerEffect in effectElement.LayerEffects)
foreach (var layerEffect in renderElement.LayerEffects)
{
if (LayerPropertyGroups.Any(l => l.LayerPropertyGroup.LayerEffect == layerEffect))
continue;
@@ -28,6 +28,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
private PluginSetting<GridLength> _displayConditionsHeight;
private PluginSetting<GridLength> _bottomPanelsHeight;
private PluginSetting<GridLength> _elementPropertiesWidth;
private ProfileViewModel _profileViewModel;
private ProfileTreeViewModel _profileTreeViewModel;
private LayerPropertiesViewModel _layerPropertiesViewModel;
private DisplayConditionsViewModel _displayConditionsViewModel;
public ProfileEditorViewModel(ProfileModule module,
ICollection<ProfileEditorPanelViewModel> viewModels,
@@ -44,21 +48,44 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
Module = module;
DialogService = dialogService;
DisplayConditionsViewModel = (DisplayConditionsViewModel) viewModels.First(vm => vm is DisplayConditionsViewModel);
LayerPropertiesViewModel = (LayerPropertiesViewModel) viewModels.First(vm => vm is LayerPropertiesViewModel);
ProfileTreeViewModel = (ProfileTreeViewModel) viewModels.First(vm => vm is ProfileTreeViewModel);
ProfileViewModel = (ProfileViewModel) viewModels.First(vm => vm is ProfileViewModel);
Profiles = new BindableCollection<Profile>();
// Run this first to let VMs activate without causing constant UI updates
Items.AddRange(viewModels);
// Populate the panels
ProfileViewModel = (ProfileViewModel) viewModels.First(vm => vm is ProfileViewModel);
ProfileTreeViewModel = (ProfileTreeViewModel) viewModels.First(vm => vm is ProfileTreeViewModel);
DisplayConditionsViewModel = (DisplayConditionsViewModel) viewModels.First(vm => vm is DisplayConditionsViewModel);
LayerPropertiesViewModel = (LayerPropertiesViewModel) viewModels.First(vm => vm is LayerPropertiesViewModel);
}
public ProfileModule Module { get; }
public IDialogService DialogService { get; }
public DisplayConditionsViewModel DisplayConditionsViewModel { get; }
public LayerPropertiesViewModel LayerPropertiesViewModel { get; }
public ProfileTreeViewModel ProfileTreeViewModel { get; }
public ProfileViewModel ProfileViewModel { get; }
public DisplayConditionsViewModel DisplayConditionsViewModel
{
get => _displayConditionsViewModel;
set => SetAndNotify(ref _displayConditionsViewModel, value);
}
public LayerPropertiesViewModel LayerPropertiesViewModel
{
get => _layerPropertiesViewModel;
set => SetAndNotify(ref _layerPropertiesViewModel, value);
}
public ProfileTreeViewModel ProfileTreeViewModel
{
get => _profileTreeViewModel;
set => SetAndNotify(ref _profileTreeViewModel, value);
}
public ProfileViewModel ProfileViewModel
{
get => _profileViewModel;
set => SetAndNotify(ref _profileViewModel, value);
}
public BindableCollection<Profile> Profiles
{
@@ -1,11 +1,13 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using Artemis.Core.Models.Profile;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem;
using Artemis.UI.Shared.Services.Interfaces;
using GongSolutions.Wpf.DragDrop;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
{
@@ -21,10 +23,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
{
_profileEditorService = profileEditorService;
_folderVmFactory = folderVmFactory;
CreateRootFolderViewModel();
_profileEditorService.ProfileSelected += OnProfileSelected;
_profileEditorService.ProfileElementSelected += OnProfileElementSelected;
}
public FolderViewModel RootFolder
@@ -39,8 +37,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
set
{
if (_updatingTree) return;
SetAndNotify(ref _selectedTreeItem, value);
_profileEditorService.ChangeSelectedProfileElement(value?.ProfileElement);
if (!SetAndNotify(ref _selectedTreeItem, value)) return;
if (value != null && value.ProfileElement is RenderProfileElement renderElement)
_profileEditorService.ChangeSelectedProfileElement(renderElement);
else
_profileEditorService.ChangeSelectedProfileElement(null);
}
}
@@ -109,6 +111,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
RootFolder = _folderVmFactory.Create(folder);
_updatingTree = false;
// Auto-select the first layer
if (_profileEditorService.SelectedProfile != null && SelectedTreeItem == null)
{
if (_profileEditorService.SelectedProfile.GetRootFolder().Children.FirstOrDefault() is RenderProfileElement firstElement)
Execute.PostToUIThread(() => _profileEditorService.ChangeSelectedProfileElement(firstElement));
}
}
private static DragDropType GetDragDropType(IDropInfo dropInfo)
@@ -140,8 +149,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
}
}
protected override void OnInitialActivate()
{
_profileEditorService.ProfileSelected += OnProfileSelected;
_profileEditorService.ProfileElementSelected += OnProfileElementSelected;
CreateRootFolderViewModel();
}
protected override void OnClose()
{
_profileEditorService.ProfileSelected -= OnProfileSelected;
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
RootFolder?.Dispose();
RootFolder = null;
base.OnClose();