mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Profile editor - Continuously update datamodel in cond. target select
Profile editor - Fixed undo/redo sometimes not registering Ctrl+Z/Ctrl+Y Profile editor - Added feedback messaging to undo/redo
This commit is contained in:
parent
c5dbe73000
commit
1f70c65651
@ -24,8 +24,8 @@ namespace Artemis.UI.Shared.Services.Interfaces
|
||||
void ChangeSelectedProfileElement(RenderProfileElement profileElement);
|
||||
void UpdateSelectedProfileElement();
|
||||
void UpdateProfilePreview();
|
||||
void UndoUpdateProfile(ProfileModule module);
|
||||
void RedoUpdateProfile(ProfileModule module);
|
||||
bool UndoUpdateProfile(ProfileModule module);
|
||||
bool RedoUpdateProfile(ProfileModule module);
|
||||
Module GetCurrentModule();
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -132,11 +132,11 @@ namespace Artemis.UI.Shared.Services
|
||||
OnProfilePreviewUpdated();
|
||||
}
|
||||
|
||||
public void UndoUpdateProfile(ProfileModule module)
|
||||
public bool UndoUpdateProfile(ProfileModule module)
|
||||
{
|
||||
var undid = _profileService.UndoUpdateProfile(SelectedProfile, module);
|
||||
if (!undid)
|
||||
return;
|
||||
return false;
|
||||
|
||||
OnSelectedProfileChanged(new ProfileEventArgs(SelectedProfile, SelectedProfile));
|
||||
|
||||
@ -149,13 +149,14 @@ namespace Artemis.UI.Shared.Services
|
||||
}
|
||||
|
||||
UpdateProfilePreview();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RedoUpdateProfile(ProfileModule module)
|
||||
public bool RedoUpdateProfile(ProfileModule module)
|
||||
{
|
||||
var redid = _profileService.RedoUpdateProfile(SelectedProfile, module);
|
||||
if (!redid)
|
||||
return;
|
||||
return false;
|
||||
|
||||
OnSelectedProfileChanged(new ProfileEventArgs(SelectedProfile, SelectedProfile));
|
||||
|
||||
@ -168,6 +169,7 @@ namespace Artemis.UI.Shared.Services
|
||||
}
|
||||
|
||||
UpdateProfilePreview();
|
||||
return true;
|
||||
}
|
||||
|
||||
public PropertyInputRegistration RegisterPropertyInput<T>(PluginInfo pluginInfo) where T : PropertyInputViewModel
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
using Artemis.Core.Models.Profile.Conditions;
|
||||
using System;
|
||||
using Artemis.Core.Models.Profile.Conditions.Abstract;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions.Abstract
|
||||
{
|
||||
public abstract class DisplayConditionViewModel : PropertyChangedBase
|
||||
public abstract class DisplayConditionViewModel : PropertyChangedBase, IDisposable
|
||||
{
|
||||
protected DisplayConditionViewModel(DisplayConditionPart model, DisplayConditionViewModel parent)
|
||||
{
|
||||
@ -17,6 +17,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions.Abstract
|
||||
public DisplayConditionViewModel Parent { get; set; }
|
||||
public BindableCollection<DisplayConditionViewModel> Children { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var child in Children)
|
||||
child.Dispose();
|
||||
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public abstract void Update();
|
||||
|
||||
public virtual void Delete()
|
||||
@ -24,5 +33,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions.Abstract
|
||||
Model.Parent.RemoveChild(Model);
|
||||
Parent.Update();
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,7 +87,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
var toRemove = Children.Where(c => !DisplayConditionGroup.Children.Contains(c.Model)).ToList();
|
||||
// Using RemoveRange breaks our lovely animations
|
||||
foreach (var displayConditionViewModel in toRemove)
|
||||
{
|
||||
Children.Remove(displayConditionViewModel);
|
||||
displayConditionViewModel.Dispose();
|
||||
}
|
||||
|
||||
foreach (var childModel in Model.Children)
|
||||
{
|
||||
|
||||
@ -93,7 +93,7 @@
|
||||
ToolTip="{Binding SelectedLeftSideProperty.DisplayPropertyPath}"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding LeftSideDataModel.Children}">
|
||||
<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}" />
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
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;
|
||||
@ -27,7 +28,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private bool _isInitialized;
|
||||
private DataModelPropertiesViewModel _leftSideDataModel;
|
||||
private List<DisplayConditionOperator> _operators;
|
||||
private BindableCollection<DisplayConditionOperator> _operators;
|
||||
private DataModelPropertiesViewModel _rightSideDataModel;
|
||||
private DataModelInputViewModel _rightSideInputViewModel;
|
||||
private int _rightSideTransitionIndex;
|
||||
@ -37,6 +38,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
private DataModelVisualizationViewModel _selectedRightSideProperty;
|
||||
|
||||
private List<Type> _supportedInputTypes;
|
||||
private readonly Timer _updateTimer;
|
||||
|
||||
public DisplayConditionPredicateViewModel(DisplayConditionPredicate displayConditionPredicate, DisplayConditionViewModel parent, IProfileEditorService profileEditorService,
|
||||
IDataModelVisualizationService dataModelVisualizationService, IDataModelService dataModelService, ISettingsService settingsService, IEventAggregator eventAggregator)
|
||||
@ -46,10 +48,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
_dataModelVisualizationService = dataModelVisualizationService;
|
||||
_dataModelService = dataModelService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_updateTimer = new Timer(500);
|
||||
|
||||
SelectLeftPropertyCommand = new DelegateCommand(ExecuteSelectLeftProperty);
|
||||
SelectRightPropertyCommand = new DelegateCommand(ExecuteSelectRightProperty);
|
||||
SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand);
|
||||
Operators = new BindableCollection<DisplayConditionOperator>();
|
||||
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
|
||||
@ -68,6 +72,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
private set => SetAndNotify(ref _isInitialized, value);
|
||||
}
|
||||
|
||||
public bool LeftSideDataModelOpen { get; set; }
|
||||
|
||||
public DataModelPropertiesViewModel LeftSideDataModel
|
||||
{
|
||||
get => _leftSideDataModel;
|
||||
@ -80,6 +86,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
set => SetAndNotify(ref _rightSideDataModel, value);
|
||||
}
|
||||
|
||||
public bool RightSideDataModelOpen { get; set; }
|
||||
|
||||
public DataModelVisualizationViewModel SelectedLeftSideProperty
|
||||
{
|
||||
get => _selectedLeftSideProperty;
|
||||
@ -114,7 +122,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
set => SetAndNotify(ref _rightSideInputViewModel, value);
|
||||
}
|
||||
|
||||
public List<DisplayConditionOperator> Operators
|
||||
public BindableCollection<DisplayConditionOperator> Operators
|
||||
{
|
||||
get => _operators;
|
||||
set => SetAndNotify(ref _operators, value);
|
||||
@ -172,17 +180,20 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
_supportedInputTypes = editors.Select(e => e.SupportedType).ToList();
|
||||
_supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes));
|
||||
|
||||
|
||||
LeftSideDataModel.UpdateRequested += LeftDataModelUpdateRequested;
|
||||
RightSideDataModel.UpdateRequested += RightDataModelUpdateRequested;
|
||||
|
||||
Update();
|
||||
|
||||
_updateTimer.Start();
|
||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (LeftSideDataModel == null || (DisplayConditionPredicate.PredicateType == PredicateType.Dynamic && RightSideDataModel == null))
|
||||
if (LeftSideDataModel == null || DisplayConditionPredicate.PredicateType == PredicateType.Dynamic && RightSideDataModel == null)
|
||||
return;
|
||||
|
||||
// If static, only allow selecting properties also supported by input
|
||||
@ -194,7 +205,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
var leftSideType = SelectedLeftSideProperty?.PropertyInfo?.PropertyType;
|
||||
|
||||
// Get the supported operators
|
||||
Operators = _dataModelService.GetCompatibleConditionOperators(leftSideType);
|
||||
Operators.Clear();
|
||||
Operators.AddRange(_dataModelService.GetCompatibleConditionOperators(leftSideType));
|
||||
if (DisplayConditionPredicate.Operator == null)
|
||||
DisplayConditionPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
|
||||
SelectedOperator = DisplayConditionPredicate.Operator;
|
||||
@ -265,6 +277,20 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
_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 leftSideType = SelectedLeftSideProperty?.PropertyInfo?.PropertyType;
|
||||
|
||||
@ -1,27 +1,24 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Profile.Conditions;
|
||||
using Artemis.Storage.Entities.Profile.Abstract;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Shared.Events;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
{
|
||||
public class DisplayConditionsViewModel : ProfileEditorPanelViewModel
|
||||
{
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
|
||||
private DisplayConditionGroupViewModel _rootGroup;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private RenderProfileElement _renderProfileElement;
|
||||
private DisplayConditionGroupViewModel _rootGroup;
|
||||
private int _transitionerIndex;
|
||||
|
||||
public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IDisplayConditionsVmFactory displayConditionsVmFactory)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_displayConditionsVmFactory = displayConditionsVmFactory;
|
||||
_displayConditionsVmFactory = displayConditionsVmFactory;
|
||||
}
|
||||
|
||||
public int TransitionerIndex
|
||||
@ -57,31 +54,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
|
||||
public bool ConditionBehaviourEnabled => RenderProfileElement != null;
|
||||
|
||||
private void ProfileEditorServiceOnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
|
||||
{
|
||||
RenderProfileElement = e.RenderProfileElement;
|
||||
NotifyOfPropertyChange(nameof(ConditionBehaviourIndex));
|
||||
NotifyOfPropertyChange(nameof(ConditionBehaviourEnabled));
|
||||
|
||||
if (e.RenderProfileElement == null)
|
||||
{
|
||||
RootGroup = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the layer has a root display condition group
|
||||
if (e.RenderProfileElement.DisplayConditionGroup == null)
|
||||
e.RenderProfileElement.DisplayConditionGroup = new DisplayConditionGroup(null);
|
||||
|
||||
RootGroup = _displayConditionsVmFactory.DisplayConditionGroupViewModel(e.RenderProfileElement.DisplayConditionGroup, null);
|
||||
RootGroup.IsRootGroup = true;
|
||||
RootGroup.Update();
|
||||
|
||||
// Only show the intro to conditions once, and only if the layer has no conditions
|
||||
if (TransitionerIndex != 1)
|
||||
TransitionerIndex = RootGroup.Children.Any() ? 1 : 0;
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
_profileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
|
||||
@ -90,6 +62,36 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
_profileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
|
||||
|
||||
RootGroup?.Dispose();
|
||||
RootGroup = null;
|
||||
}
|
||||
|
||||
private void ProfileEditorServiceOnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
|
||||
{
|
||||
RenderProfileElement = e.RenderProfileElement;
|
||||
NotifyOfPropertyChange(nameof(ConditionBehaviourIndex));
|
||||
NotifyOfPropertyChange(nameof(ConditionBehaviourEnabled));
|
||||
|
||||
if (e.RenderProfileElement == null)
|
||||
{
|
||||
RootGroup?.Dispose();
|
||||
RootGroup = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the layer has a root display condition group
|
||||
if (e.RenderProfileElement.DisplayConditionGroup == null)
|
||||
e.RenderProfileElement.DisplayConditionGroup = new DisplayConditionGroup(null);
|
||||
|
||||
RootGroup?.Dispose();
|
||||
RootGroup = _displayConditionsVmFactory.DisplayConditionGroupViewModel(e.RenderProfileElement.DisplayConditionGroup, null);
|
||||
RootGroup.IsRootGroup = true;
|
||||
RootGroup.Update();
|
||||
|
||||
// Only show the intro to conditions once, and only if the layer has no conditions
|
||||
if (TransitionerIndex != 1)
|
||||
TransitionerIndex = RootGroup.Children.Any() ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,9 @@
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:profileEditor="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor"
|
||||
xmlns:behaviors="clr-namespace:Artemis.UI.Behaviors"
|
||||
mc:Ignorable="d"
|
||||
behaviors:InputBindingBehavior.PropagateInputBindingsToWindow="True"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance Type=profileEditor:ProfileEditorViewModel, IsDesignTimeCreatable=False}">
|
||||
<UserControl.Resources>
|
||||
|
||||
@ -14,6 +14,7 @@ using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.Visualization;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
@ -23,6 +24,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly IProfileService _profileService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
||||
private BindableCollection<Profile> _profiles;
|
||||
private PluginSetting<GridLength> _sidePanelsWidth;
|
||||
private PluginSetting<GridLength> _displayConditionsHeight;
|
||||
@ -38,11 +40,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
IProfileEditorService profileEditorService,
|
||||
IProfileService profileService,
|
||||
IDialogService dialogService,
|
||||
ISettingsService settingsService)
|
||||
ISettingsService settingsService,
|
||||
ISnackbarMessageQueue snackbarMessageQueue)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_profileService = profileService;
|
||||
_settingsService = settingsService;
|
||||
_snackbarMessageQueue = snackbarMessageQueue;
|
||||
|
||||
DisplayName = "Profile editor";
|
||||
Module = module;
|
||||
@ -172,11 +176,17 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
var beforeGroups = LayerPropertiesViewModel.GetAllLayerPropertyGroupViewModels();
|
||||
var expandedPaths = beforeGroups.Where(g => g.IsExpanded).Select(g => g.LayerPropertyGroup.Path).ToList();
|
||||
|
||||
_profileEditorService.UndoUpdateProfile(Module);
|
||||
if (!_profileEditorService.UndoUpdateProfile(Module))
|
||||
{
|
||||
_snackbarMessageQueue.Enqueue("Nothing to undo");
|
||||
return;
|
||||
}
|
||||
|
||||
// Restore the expanded status
|
||||
foreach (var allLayerPropertyGroupViewModel in LayerPropertiesViewModel.GetAllLayerPropertyGroupViewModels())
|
||||
allLayerPropertyGroupViewModel.IsExpanded = expandedPaths.Contains(allLayerPropertyGroupViewModel.LayerPropertyGroup.Path);
|
||||
|
||||
_snackbarMessageQueue.Enqueue("Undid profile update", "REDO", Redo);
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
@ -185,11 +195,17 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
var beforeGroups = LayerPropertiesViewModel.GetAllLayerPropertyGroupViewModels();
|
||||
var expandedPaths = beforeGroups.Where(g => g.IsExpanded).Select(g => g.LayerPropertyGroup.Path).ToList();
|
||||
|
||||
_profileEditorService.RedoUpdateProfile(Module);
|
||||
if (!_profileEditorService.RedoUpdateProfile(Module))
|
||||
{
|
||||
_snackbarMessageQueue.Enqueue("Nothing to redo");
|
||||
return;
|
||||
}
|
||||
|
||||
// Restore the expanded status
|
||||
foreach (var allLayerPropertyGroupViewModel in LayerPropertiesViewModel.GetAllLayerPropertyGroupViewModels())
|
||||
allLayerPropertyGroupViewModel.IsExpanded = expandedPaths.Contains(allLayerPropertyGroupViewModel.LayerPropertyGroup.Path);
|
||||
|
||||
_snackbarMessageQueue.Enqueue("Redid profile update", "UNDO", Undo);
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
|
||||
@ -245,4 +245,5 @@
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=leds/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=snackbar/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=snackbar/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=transitioner/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
Loading…
x
Reference in New Issue
Block a user