diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs
index a1f8400e8..81ec38993 100644
--- a/src/Artemis.Core/Models/Profile/Folder.cs
+++ b/src/Artemis.Core/Models/Profile/Folder.cs
@@ -14,6 +14,8 @@ namespace Artemis.Core
///
public sealed class Folder : RenderProfileElement
{
+ private bool _isExpanded;
+
///
/// Creates a new instance of the class and adds itself to the child collection of the provided
///
@@ -46,6 +48,7 @@ namespace Artemis.Core
Profile = profile;
Parent = parent;
Name = folderEntity.Name;
+ IsExpanded = folderEntity.IsExpanded;
Suspended = folderEntity.Suspended;
Order = folderEntity.Order;
@@ -57,6 +60,15 @@ namespace Artemis.Core
///
public bool IsRootFolder => Parent == Profile;
+ ///
+ /// Gets or sets a boolean indicating whether this folder is expanded
+ ///
+ public bool IsExpanded
+ {
+ get => _isExpanded;
+ set => SetAndNotify(ref _isExpanded, value);
+ }
+
///
/// Gets the folder entity this folder uses for persistent storage
///
@@ -72,8 +84,10 @@ namespace Artemis.Core
{
List result = new();
foreach (BaseLayerEffect layerEffect in LayerEffects)
+ {
if (layerEffect.BaseProperties != null)
result.AddRange(layerEffect.BaseProperties.GetAllLayerProperties());
+ }
return result;
}
@@ -151,27 +165,6 @@ namespace Artemis.Core
return $"[Folder] {nameof(Name)}: {Name}, {nameof(Order)}: {Order}";
}
- internal void CalculateRenderProperties()
- {
- if (Disposed)
- throw new ObjectDisposedException("Folder");
-
- SKPath path = new() {FillType = SKPathFillType.Winding};
- foreach (ProfileElement child in Children)
- {
- if (child is RenderProfileElement effectChild && effectChild.Path != null)
- path.AddPath(effectChild.Path);
- }
-
- Path = path;
-
- // Folder render properties are based on child paths and thus require an update
- if (Parent is Folder folder)
- folder.CalculateRenderProperties();
-
- OnRenderPropertiesUpdated();
- }
-
#region Rendering
///
@@ -209,7 +202,7 @@ namespace Artemis.Core
canvas.SaveLayer(layerPaint);
canvas.Translate(Bounds.Left - basePosition.X, Bounds.Top - basePosition.Y);
-
+
// Iterate the children in reverse because the first layer must be rendered last to end up on top
for (int index = Children.Count - 1; index > -1; index--)
Children[index].Render(canvas, new SKPointI(Bounds.Left, Bounds.Top));
@@ -229,57 +222,6 @@ namespace Artemis.Core
#endregion
- ///
- protected override void Dispose(bool disposing)
- {
- Disposed = true;
-
- Disable();
- foreach (ProfileElement profileElement in Children)
- profileElement.Dispose();
-
- base.Dispose(disposing);
- }
-
- internal override void Load()
- {
- ExpandedPropertyGroups.AddRange(FolderEntity.ExpandedPropertyGroups);
- Reset();
-
- // Load child folders
- foreach (FolderEntity childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId))
- ChildrenList.Add(new Folder(Profile, this, childFolder));
- // Load child layers
- foreach (LayerEntity childLayer in Profile.ProfileEntity.Layers.Where(f => f.ParentId == EntityId))
- ChildrenList.Add(new Layer(Profile, this, childLayer));
-
- // Ensure order integrity, should be unnecessary but no one is perfect specially me
- ChildrenList = ChildrenList.OrderBy(c => c.Order).ToList();
- for (int index = 0; index < ChildrenList.Count; index++)
- ChildrenList[index].Order = index + 1;
-
- LoadRenderElement();
- }
-
- internal override void Save()
- {
- if (Disposed)
- throw new ObjectDisposedException("Folder");
-
- FolderEntity.Id = EntityId;
- FolderEntity.ParentId = Parent?.EntityId ?? new Guid();
-
- FolderEntity.Order = Order;
- FolderEntity.Name = Name;
- FolderEntity.Suspended = Suspended;
-
- FolderEntity.ProfileId = Profile.EntityId;
- FolderEntity.ExpandedPropertyGroups.Clear();
- FolderEntity.ExpandedPropertyGroups.AddRange(ExpandedPropertyGroups);
-
- SaveRenderElement();
- }
-
///
public override void Enable()
{
@@ -320,18 +262,87 @@ namespace Artemis.Core
Enabled = false;
}
- #region Events
-
///
/// Occurs when a property affecting the rendering properties of this folder has been updated
///
public event EventHandler? RenderPropertiesUpdated;
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ Disposed = true;
+
+ Disable();
+ foreach (ProfileElement profileElement in Children)
+ profileElement.Dispose();
+
+ base.Dispose(disposing);
+ }
+
+ internal void CalculateRenderProperties()
+ {
+ if (Disposed)
+ throw new ObjectDisposedException("Folder");
+
+ SKPath path = new() {FillType = SKPathFillType.Winding};
+ foreach (ProfileElement child in Children)
+ {
+ if (child is RenderProfileElement effectChild && effectChild.Path != null)
+ path.AddPath(effectChild.Path);
+ }
+
+ Path = path;
+
+ // Folder render properties are based on child paths and thus require an update
+ if (Parent is Folder folder)
+ folder.CalculateRenderProperties();
+
+ OnRenderPropertiesUpdated();
+ }
+
+ internal override void Load()
+ {
+ ExpandedPropertyGroups.AddRange(FolderEntity.ExpandedPropertyGroups);
+ Reset();
+
+ // Load child folders
+ foreach (FolderEntity childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId))
+ ChildrenList.Add(new Folder(Profile, this, childFolder));
+ // Load child layers
+ foreach (LayerEntity childLayer in Profile.ProfileEntity.Layers.Where(f => f.ParentId == EntityId))
+ ChildrenList.Add(new Layer(Profile, this, childLayer));
+
+ // Ensure order integrity, should be unnecessary but no one is perfect specially me
+ ChildrenList = ChildrenList.OrderBy(c => c.Order).ToList();
+ for (int index = 0; index < ChildrenList.Count; index++)
+ ChildrenList[index].Order = index + 1;
+
+ LoadRenderElement();
+ }
+
+ internal override void Save()
+ {
+ if (Disposed)
+ throw new ObjectDisposedException("Folder");
+
+ FolderEntity.Id = EntityId;
+ FolderEntity.ParentId = Parent?.EntityId ?? new Guid();
+
+ FolderEntity.Order = Order;
+ FolderEntity.Name = Name;
+ FolderEntity.IsExpanded = IsExpanded;
+ FolderEntity.Suspended = Suspended;
+
+ FolderEntity.ProfileId = Profile.EntityId;
+ FolderEntity.ExpandedPropertyGroups.Clear();
+ FolderEntity.ExpandedPropertyGroups.AddRange(ExpandedPropertyGroups);
+
+ SaveRenderElement();
+ }
+
private void OnRenderPropertiesUpdated()
{
RenderPropertiesUpdated?.Invoke(this, EventArgs.Empty);
}
-
- #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Profile.cs b/src/Artemis.Core/Models/Profile/Profile.cs
index 75ec5d66b..e2870dec1 100644
--- a/src/Artemis.Core/Models/Profile/Profile.cs
+++ b/src/Artemis.Core/Models/Profile/Profile.cs
@@ -14,6 +14,7 @@ namespace Artemis.Core
{
private readonly object _lock = new();
private bool _isFreshImport;
+ private ProfileElement? _lastSelectedProfileElement;
internal Profile(ProfileConfiguration configuration, ProfileEntity profileEntity) : base(null!)
{
@@ -60,6 +61,15 @@ namespace Artemis.Core
set => SetAndNotify(ref _isFreshImport, value);
}
+ ///
+ /// Gets or sets the last selected profile element of this profile
+ ///
+ public ProfileElement? LastSelectedProfileElement
+ {
+ get => _lastSelectedProfileElement;
+ set => SetAndNotify(ref _lastSelectedProfileElement, value);
+ }
+
///
/// Gets the profile entity this profile uses for persistent storage
///
@@ -187,6 +197,15 @@ namespace Artemis.Core
}
}
+ if (ProfileEntity.LastSelectedProfileElement != Guid.Empty)
+ {
+ LastSelectedProfileElement = GetAllFolders().FirstOrDefault(f => f.EntityId == ProfileEntity.LastSelectedProfileElement);
+ if (LastSelectedProfileElement == null)
+ LastSelectedProfileElement = GetAllLayers().FirstOrDefault(f => f.EntityId == ProfileEntity.LastSelectedProfileElement);
+ }
+ else
+ LastSelectedProfileElement = null;
+
foreach (ScriptConfiguration scriptConfiguration in ScriptConfigurations)
scriptConfiguration.Script?.Dispose();
ScriptConfigurations.Clear();
@@ -201,6 +220,7 @@ namespace Artemis.Core
ProfileEntity.Id = EntityId;
ProfileEntity.Name = Configuration.Name;
ProfileEntity.IsFreshImport = IsFreshImport;
+ ProfileEntity.LastSelectedProfileElement = LastSelectedProfileElement?.EntityId ?? Guid.Empty;
foreach (ProfileElement profileElement in Children)
profileElement.Save();
diff --git a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs
index f4103388e..21e1a3157 100644
--- a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs
+++ b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs
@@ -179,7 +179,8 @@ namespace Artemis.Core
{
if (_disposed)
throw new ObjectDisposedException("ProfileConfiguration");
-
+ if (IsBeingEdited)
+ return true;
if (Category.IsSuspended || IsSuspended || IsMissingModule)
return false;
diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs
index f026abccb..7d7a229f2 100644
--- a/src/Artemis.Core/Services/Storage/ProfileService.cs
+++ b/src/Artemis.Core/Services/Storage/ProfileService.cs
@@ -209,7 +209,7 @@ namespace Artemis.Core.Services
ProcessPendingKeyEvents(profileConfiguration);
// Profiles being edited are updated at their own leisure
- if (profileConfiguration.IsBeingEdited)
+ if (profileConfiguration.IsBeingEdited && RenderForEditor)
continue;
bool shouldBeActive = profileConfiguration.ShouldBeActive(false);
@@ -254,11 +254,9 @@ namespace Artemis.Core.Services
try
{
ProfileConfiguration profileConfiguration = profileCategory.ProfileConfigurations[j];
- if (RenderForEditor)
- {
- if (profileConfiguration.IsBeingEdited)
- profileConfiguration.Profile?.Render(canvas, SKPointI.Empty);
- }
+ // Always render profiles being edited
+ if (profileConfiguration.IsBeingEdited)
+ profileConfiguration.Profile?.Render(canvas, SKPointI.Empty);
else
{
// Ensure all criteria are met before rendering
diff --git a/src/Artemis.Storage/Entities/Profile/FolderEntity.cs b/src/Artemis.Storage/Entities/Profile/FolderEntity.cs
index 035210069..0f6cdde1b 100644
--- a/src/Artemis.Storage/Entities/Profile/FolderEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/FolderEntity.cs
@@ -16,6 +16,7 @@ namespace Artemis.Storage.Entities.Profile
public int Order { get; set; }
public string Name { get; set; }
+ public bool IsExpanded { get; set; }
public bool Suspended { get; set; }
[BsonRef("ProfileEntity")]
diff --git a/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs b/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs
index 0a65c180f..abc390d98 100644
--- a/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs
@@ -18,6 +18,7 @@ namespace Artemis.Storage.Entities.Profile
public string Name { get; set; }
public bool IsFreshImport { get; set; }
+ public Guid LastSelectedProfileElement { get; set; }
public List Folders { get; set; }
public List Layers { get; set; }
diff --git a/src/Artemis.UI.Shared/Controls/DraggableFloat.xaml.cs b/src/Artemis.UI.Shared/Controls/DraggableFloat.xaml.cs
index cbc59f4f8..499afb5d7 100644
--- a/src/Artemis.UI.Shared/Controls/DraggableFloat.xaml.cs
+++ b/src/Artemis.UI.Shared/Controls/DraggableFloat.xaml.cs
@@ -27,12 +27,12 @@ namespace Artemis.UI.Shared
///
/// Gets or sets the minimum value
///
- public static readonly DependencyProperty MinProperty = DependencyProperty.Register(nameof(Min), typeof(float?), typeof(DraggableFloat));
+ public static readonly DependencyProperty MinProperty = DependencyProperty.Register(nameof(Min), typeof(object), typeof(DraggableFloat));
///
/// Gets or sets the maximum value
///
- public static readonly DependencyProperty MaxProperty = DependencyProperty.Register(nameof(Max), typeof(float?), typeof(DraggableFloat));
+ public static readonly DependencyProperty MaxProperty = DependencyProperty.Register(nameof(Max), typeof(object), typeof(DraggableFloat));
///
/// Occurs when the value has changed
@@ -90,18 +90,18 @@ namespace Artemis.UI.Shared
///
/// Gets or sets the minimum value
///
- public float? Min
+ public object? Min
{
- get => (float?) GetValue(MinProperty);
+ get => (object?) GetValue(MinProperty);
set => SetValue(MinProperty, value);
}
///
/// Gets or sets the maximum value
///
- public float? Max
+ public object? Max
{
- get => (float?) GetValue(MaxProperty);
+ get => (object?) GetValue(MaxProperty);
set => SetValue(MaxProperty, value);
}
@@ -207,10 +207,11 @@ namespace Artemis.UI.Shared
stepSize = stepSize * 10;
float value = (float) RoundToNearestOf(startValue + stepSize * (x - startX), stepSize);
- if (Min != null)
- value = Math.Max(value, Min.Value);
- if (Max != null)
- value = Math.Min(value, Max.Value);
+
+ if (Min != null && float.TryParse(Min.ToString(), out float minFloat))
+ value = Math.Max(value, minFloat);
+ if (Max != null && float.TryParse(Max.ToString(), out float maxFloat))
+ value = Math.Min(value, maxFloat);
Value = value;
}
diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
index 0184583d9..059137ac6 100644
--- a/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
+++ b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
@@ -17,9 +17,17 @@ namespace Artemis.UI.Shared.Services
///
ProfileConfiguration? SelectedProfileConfiguration { get; }
+ ///
+ /// Gets the previous selected profile configuration
+ ///
+ ProfileConfiguration? PreviousSelectedProfileConfiguration { get; }
+
///
/// Gets the currently selected profile
- /// if the editor is closed, always equal to .
+ ///
+ /// if the editor is closed, always equal to .
+ ///
+ ///
///
Profile? SelectedProfile { get; }
@@ -53,6 +61,11 @@ namespace Artemis.UI.Shared.Services
///
bool Playing { get; set; }
+ ///
+ /// Gets or sets a boolean indicating whether editing should be suspended
+ ///
+ bool SuspendEditing { get; set; }
+
///
/// Changes the selected profile by its
///
diff --git a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
index ed1a2d68f..c0fa9c665 100644
--- a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
+++ b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
@@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using Artemis.Core;
-using Artemis.Core.Modules;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile;
using Artemis.UI.Shared.Services.Models;
@@ -30,6 +29,7 @@ namespace Artemis.UI.Shared.Services
private TimeSpan _currentTime;
private bool _doTick;
private int _pixelsPerSecond;
+ private bool _suspendEditing;
public ProfileEditorService(IKernel kernel, ILogger logger, IProfileService profileService, ICoreService coreService, IRgbService rgbService, IModuleService moduleService)
{
@@ -76,7 +76,7 @@ namespace Artemis.UI.Shared.Services
private void Tick()
{
- if (SelectedProfile == null || _doTick)
+ if (SelectedProfile == null || _doTick || SuspendEditing)
return;
TickProfileElement(SelectedProfile.GetRootFolder());
@@ -106,6 +106,27 @@ namespace Artemis.UI.Shared.Services
public ReadOnlyCollection RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
public bool Playing { get; set; }
+
+ public bool SuspendEditing
+ {
+ get => _suspendEditing;
+ set
+ {
+ _suspendEditing = value;
+ if (value)
+ {
+ Playing = false;
+ _profileService.RenderForEditor = false;
+ }
+ else
+ {
+ if (SelectedProfileConfiguration != null)
+ _profileService.RenderForEditor = true;
+ }
+ }
+ }
+
+ public ProfileConfiguration? PreviousSelectedProfileConfiguration { get; private set; }
public ProfileConfiguration? SelectedProfileConfiguration { get; private set; }
public Profile? SelectedProfile => SelectedProfileConfiguration?.Profile;
public RenderProfileElement? SelectedProfileElement { get; private set; }
@@ -152,13 +173,18 @@ namespace Artemis.UI.Shared.Services
SelectedProfileConfiguration.IsBeingEdited = false;
// The new profile may need activation
+ PreviousSelectedProfileConfiguration = SelectedProfileConfiguration;
SelectedProfileConfiguration = profileConfiguration;
+ ;
if (SelectedProfileConfiguration != null)
{
SelectedProfileConfiguration.IsBeingEdited = true;
_moduleService.SetActivationOverride(SelectedProfileConfiguration.Module);
_profileService.ActivateProfile(SelectedProfileConfiguration);
_profileService.RenderForEditor = true;
+
+ if (SelectedProfileConfiguration.Profile?.LastSelectedProfileElement is RenderProfileElement renderProfileElement)
+ ChangeSelectedProfileElement(renderProfileElement);
}
else
{
@@ -179,6 +205,7 @@ namespace Artemis.UI.Shared.Services
if (SelectedProfile == null)
return;
+ SelectedProfile.LastSelectedProfileElement = SelectedProfileElement;
_profileService.SaveProfile(SelectedProfile, true);
OnSelectedProfileUpdated(new ProfileConfigurationEventArgs(SelectedProfileConfiguration));
UpdateProfilePreview();
diff --git a/src/Artemis.UI/Events/RequestSelectSidebarItemEvent.cs b/src/Artemis.UI/Events/RequestSelectSidebarItemEvent.cs
index 3241ac8f8..2892cfe61 100644
--- a/src/Artemis.UI/Events/RequestSelectSidebarItemEvent.cs
+++ b/src/Artemis.UI/Events/RequestSelectSidebarItemEvent.cs
@@ -1,4 +1,6 @@
-namespace Artemis.UI.Events
+using Artemis.UI.Screens.Sidebar;
+
+namespace Artemis.UI.Events
{
public class RequestSelectSidebarItemEvent
{
@@ -7,6 +9,12 @@
DisplayName = displayName;
}
+ public RequestSelectSidebarItemEvent(SidebarScreenViewModel viewModel)
+ {
+ ViewModel = viewModel;
+ }
+
public string DisplayName { get; }
+ public SidebarScreenViewModel ViewModel { get; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
index 5aa6a6515..9a1a3610a 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
@@ -559,6 +559,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
private void CoreServiceOnFrameRendering(object sender, FrameRenderingEventArgs e)
{
+ if (!ProfileEditorService.Playing)
+ {
+ Pause();
+ return;
+ }
+
Execute.PostToUIThread(() =>
{
TimeSpan newTime = ProfileEditorService.CurrentTime.Add(TimeSpan.FromSeconds(e.DeltaTime));
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.xaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.xaml
index 735390a5d..5de7e7fee 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.xaml
@@ -110,6 +110,24 @@
IsEnabled="{Binding HasSelectedElement}"
Command="{s:Action OpenLayerPropertyScripts}"/>
+
{
private readonly IDebugService _debugService;
private readonly IMessageService _messageService;
@@ -28,15 +32,12 @@ namespace Artemis.UI.Screens.ProfileEditor
private readonly ISettingsService _settingsService;
private readonly ISidebarVmFactory _sidebarVmFactory;
private readonly IWindowManager _windowManager;
- private PluginSetting _bottomPanelsHeight;
- private PluginSetting _dataModelConditionsHeight;
+ private readonly IEventAggregator _eventAggregator;
private DisplayConditionsViewModel _displayConditionsViewModel;
- private PluginSetting _elementPropertiesWidth;
private LayerPropertiesViewModel _layerPropertiesViewModel;
private ProfileTreeViewModel _profileTreeViewModel;
private ProfileViewModel _profileViewModel;
- private PluginSetting _sidePanelsWidth;
-
+
public ProfileEditorViewModel(ProfileViewModel profileViewModel,
ProfileTreeViewModel profileTreeViewModel,
DisplayConditionsViewModel dataModelConditionsViewModel,
@@ -48,6 +49,7 @@ namespace Artemis.UI.Screens.ProfileEditor
IMessageService messageService,
IDebugService debugService,
IWindowManager windowManager,
+ IEventAggregator eventAggregator,
IScriptVmFactory scriptVmFactory,
ISidebarVmFactory sidebarVmFactory)
{
@@ -57,9 +59,10 @@ namespace Artemis.UI.Screens.ProfileEditor
_messageService = messageService;
_debugService = debugService;
_windowManager = windowManager;
+ _eventAggregator = eventAggregator;
_scriptVmFactory = scriptVmFactory;
_sidebarVmFactory = sidebarVmFactory;
-
+
DisplayName = "Profile Editor";
DialogService = dialogService;
@@ -102,29 +105,14 @@ namespace Artemis.UI.Screens.ProfileEditor
set => SetAndNotify(ref _profileViewModel, value);
}
- public PluginSetting SidePanelsWidth
- {
- get => _sidePanelsWidth;
- set => SetAndNotify(ref _sidePanelsWidth, value);
- }
-
- public PluginSetting DataModelConditionsHeight
- {
- get => _dataModelConditionsHeight;
- set => SetAndNotify(ref _dataModelConditionsHeight, value);
- }
-
- public PluginSetting BottomPanelsHeight
- {
- get => _bottomPanelsHeight;
- set => SetAndNotify(ref _bottomPanelsHeight, value);
- }
-
- public PluginSetting ElementPropertiesWidth
- {
- get => _elementPropertiesWidth;
- set => SetAndNotify(ref _elementPropertiesWidth, value);
- }
+ public PluginSetting SidePanelsWidth => _settingsService.GetSetting("ProfileEditor.SidePanelsWidth", new GridLength(385));
+ public PluginSetting DataModelConditionsHeight => _settingsService.GetSetting("ProfileEditor.DataModelConditionsHeight", new GridLength(345));
+ public PluginSetting BottomPanelsHeight => _settingsService.GetSetting("ProfileEditor.BottomPanelsHeight", new GridLength(265));
+ public PluginSetting ElementPropertiesWidth => _settingsService.GetSetting("ProfileEditor.ElementPropertiesWidth", new GridLength(545));
+ public PluginSetting StopOnFocusLoss => _settingsService.GetSetting("ProfileEditor.StopOnFocusLoss", true);
+ public PluginSetting ShowDataModelValues => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
+ public PluginSetting FocusSelectedLayer => _settingsService.GetSetting("ProfileEditor.FocusSelectedLayer", true);
+ public PluginSetting AlwaysApplyDataBindings => _settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", true);
public void Undo()
{
@@ -180,25 +168,39 @@ namespace Artemis.UI.Screens.ProfileEditor
_messageService.ShowMessage("Redid profile update", "UNDO", Undo);
}
+ #region Overrides of Screen
protected override void OnInitialActivate()
{
+ StopOnFocusLoss.AutoSave = true;
+ ShowDataModelValues.AutoSave = true;
+ FocusSelectedLayer.AutoSave = true;
+ AlwaysApplyDataBindings.AutoSave = true;
+
_profileEditorService.SelectedProfileChanged += ProfileEditorServiceOnSelectedProfileChanged;
_profileEditorService.SelectedProfileElementChanged += ProfileEditorServiceOnSelectedProfileElementChanged;
- LoadWorkspaceSettings();
+ _eventAggregator.Subscribe(this);
base.OnInitialActivate();
}
protected override void OnClose()
{
+ StopOnFocusLoss.AutoSave = false;
+ ShowDataModelValues.AutoSave = false;
+ FocusSelectedLayer.AutoSave = false;
+ AlwaysApplyDataBindings.AutoSave = false;
+
_profileEditorService.SelectedProfileChanged -= ProfileEditorServiceOnSelectedProfileChanged;
_profileEditorService.SelectedProfileElementChanged -= ProfileEditorServiceOnSelectedProfileElementChanged;
+ _eventAggregator.Unsubscribe(this);
SaveWorkspaceSettings();
_profileEditorService.ChangeSelectedProfileConfiguration(null);
base.OnClose();
}
+ #endregion
+
private void ProfileEditorServiceOnSelectedProfileChanged(object sender, ProfileConfigurationEventArgs e)
{
NotifyOfPropertyChange(nameof(ProfileConfiguration));
@@ -208,15 +210,7 @@ namespace Artemis.UI.Screens.ProfileEditor
{
NotifyOfPropertyChange(nameof(HasSelectedElement));
}
-
- private void LoadWorkspaceSettings()
- {
- SidePanelsWidth = _settingsService.GetSetting("ProfileEditor.SidePanelsWidth", new GridLength(385));
- DataModelConditionsHeight = _settingsService.GetSetting("ProfileEditor.DataModelConditionsHeight", new GridLength(345));
- BottomPanelsHeight = _settingsService.GetSetting("ProfileEditor.BottomPanelsHeight", new GridLength(265));
- ElementPropertiesWidth = _settingsService.GetSetting("ProfileEditor.ElementPropertiesWidth", new GridLength(545));
- }
-
+
private void SaveWorkspaceSettings()
{
SidePanelsWidth.Save();
@@ -234,7 +228,7 @@ namespace Artemis.UI.Screens.ProfileEditor
{
await _sidebarVmFactory.SidebarProfileConfigurationViewModel(_profileEditorService.SelectedProfileConfiguration).ViewProperties();
}
-
+
public async Task AdaptProfile()
{
if (_profileEditorService.SelectedProfileConfiguration?.Profile == null)
@@ -322,5 +316,19 @@ namespace Artemis.UI.Screens.ProfileEditor
}
#endregion
+
+ #region Implementation of IHandle
+
+ ///
+ public void Handle(MainWindowFocusChangedEvent message)
+ {
+ if (!StopOnFocusLoss.Value)
+ return;
+
+ _profileEditorService.SuspendEditing = !message.IsFocused;
+ ProfileViewModel.SuspendedEditing = !message.IsFocused;
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml
index c3388512a..843a7e09b 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml
@@ -97,6 +97,11 @@
+
+
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
index 9156b86f1..e9d5bed51 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Artemis.Core;
@@ -24,8 +25,6 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{
_profileEditorService = profileEditorService;
_profileTreeVmFactory = profileTreeVmFactory;
-
- CreateRootFolderViewModel();
}
public TreeItemViewModel SelectedTreeItem
@@ -33,7 +32,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
get => _selectedTreeItem;
set
{
- if (!_updatingTree && SetAndNotify(ref _selectedTreeItem, value) && !_draggingTreeView)
+ if (!_updatingTree && SetAndNotify(ref _selectedTreeItem, value) && !_draggingTreeView)
ApplySelectedTreeItem();
}
}
@@ -54,6 +53,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
protected override void OnInitialActivate()
{
Subscribe();
+ CreateRootFolderViewModel();
base.OnInitialActivate();
}
@@ -83,6 +83,13 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
ActiveItem = _profileTreeVmFactory.FolderViewModel(folder);
_updatingTree = false;
+
+ Execute.PostToUIThread(async () =>
+ {
+ await Task.Delay(1500);
+ SelectedTreeItem = ActiveItem.GetAllChildren().FirstOrDefault(c => c.ProfileElement == _profileEditorService.SelectedProfileElement);
+ });
+
}
#region IDropTarget
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/FolderViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/FolderViewModel.cs
index ba8de22bd..7682a7868 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/FolderViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/FolderViewModel.cs
@@ -1,4 +1,5 @@
-using Artemis.Core;
+using System.ComponentModel;
+using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Services;
@@ -19,5 +20,35 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
}
public override bool SupportsChildren => true;
+
+ public override bool IsExpanded
+ {
+ get => ((Folder) ProfileElement).IsExpanded;
+ set => ((Folder) ProfileElement).IsExpanded = value;
+ }
+
+ private void ProfileElementOnPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(Folder.IsExpanded))
+ NotifyOfPropertyChange(nameof(IsExpanded));
+ }
+
+ #region Overrides of Screen
+
+ ///
+ protected override void OnInitialActivate()
+ {
+ ProfileElement.PropertyChanged += ProfileElementOnPropertyChanged;
+ base.OnInitialActivate();
+ }
+
+ ///
+ protected override void OnClose()
+ {
+ ProfileElement.PropertyChanged -= ProfileElementOnPropertyChanged;
+ base.OnClose();
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs
index ee961a91b..d1cf96079 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs
@@ -33,5 +33,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
public Layer Layer => ProfileElement as Layer;
public bool ShowIcons => Layer?.LayerBrush != null;
public override bool SupportsChildren => false;
+
+ public override bool IsExpanded { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs
index e4309201c..4c1cba42b 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs
@@ -52,6 +52,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
public bool CanPasteElement => _profileEditorService.GetCanPasteProfileElement();
public abstract bool SupportsChildren { get; }
+ public abstract bool IsExpanded { get; set; }
public List GetAllChildren()
{
diff --git a/src/Artemis.UI/Screens/ProfileEditor/SuspendedProfileEditorView.xaml b/src/Artemis.UI/Screens/ProfileEditor/SuspendedProfileEditorView.xaml
new file mode 100644
index 000000000..b35e2712b
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/SuspendedProfileEditorView.xaml
@@ -0,0 +1,23 @@
+
+
+
+
+ Profile editing has been paused
+
+
+ Artemis has resumed regular profile playback. As soon as you focus this window, the editor will open to continue editing
+ ''.
+
+
+ You can disable this behaviour in the editor's option menu.
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/SuspendedProfileEditorViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/SuspendedProfileEditorViewModel.cs
new file mode 100644
index 000000000..ca9525e3e
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/SuspendedProfileEditorViewModel.cs
@@ -0,0 +1,53 @@
+using Artemis.Core;
+using Artemis.UI.Events;
+using Artemis.UI.Shared.Services;
+using Stylet;
+
+namespace Artemis.UI.Screens.ProfileEditor
+{
+ public class SuspendedProfileEditorViewModel : MainScreenViewModel, IHandle
+ {
+ private readonly IEventAggregator _eventAggregator;
+ private readonly IProfileEditorService _profileEditorService;
+ private ProfileConfiguration _previousSelectedProfileConfiguration;
+
+ public SuspendedProfileEditorViewModel(IEventAggregator eventAggregator, IProfileEditorService profileEditorService)
+ {
+ _eventAggregator = eventAggregator;
+ _profileEditorService = profileEditorService;
+ }
+
+ public ProfileConfiguration PreviousSelectedProfileConfiguration
+ {
+ get => _previousSelectedProfileConfiguration;
+ set => SetAndNotify(ref _previousSelectedProfileConfiguration, value);
+ }
+
+ public void Handle(MainWindowFocusChangedEvent message)
+ {
+ if (!message.IsFocused)
+ return;
+
+ RootViewModel rootViewModel = (RootViewModel) Parent;
+ if (PreviousSelectedProfileConfiguration != null)
+ rootViewModel.SidebarViewModel.SelectProfileConfiguration(PreviousSelectedProfileConfiguration);
+ }
+
+ #region Overrides of Screen
+
+ protected override void OnInitialActivate()
+ {
+ PreviousSelectedProfileConfiguration = _profileEditorService.PreviousSelectedProfileConfiguration;
+ _eventAggregator.Subscribe(this);
+ base.OnInitialActivate();
+ }
+
+ protected override void OnClose()
+ {
+ _eventAggregator.Unsubscribe(this);
+ base.OnClose();
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileView.xaml
index 4e9ebdf6f..688d828a2 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileView.xaml
@@ -101,6 +101,7 @@
@@ -129,25 +130,7 @@
-
-
-
-
-
- Focus selected layer
-
-
- Apply all data bindings in editor
-
-
-
-
-
+
_alwaysApplyDataBindings;
private bool _canApplyToLayer;
private bool _canSelectEditTool;
private BindableCollection _devices;
private BindableCollection _highlightedLeds;
- private PluginSetting _focusSelectedLayer;
private DateTime _lastUpdate;
private PanZoomViewModel _panZoomViewModel;
private Layer _previousSelectedLayer;
private int _previousTool;
+ private bool _suspendedEditing;
public ProfileViewModel(IProfileEditorService profileEditorService,
IRgbService rgbService,
@@ -78,19 +77,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
get => _highlightedLeds;
set => SetAndNotify(ref _highlightedLeds, value);
}
-
- public PluginSetting AlwaysApplyDataBindings
- {
- get => _alwaysApplyDataBindings;
- set => SetAndNotify(ref _alwaysApplyDataBindings, value);
- }
-
- public PluginSetting FocusSelectedLayer
- {
- get => _focusSelectedLayer;
- set => SetAndNotify(ref _focusSelectedLayer, value);
- }
-
+
public VisualizationToolViewModel ActiveToolViewModel
{
get => _activeToolViewModel;
@@ -132,9 +119,21 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
set => SetAndNotify(ref _canApplyToLayer, value);
}
+ public bool SuspendedEditing
+ {
+ get => _suspendedEditing;
+ set => SetAndNotify(ref _suspendedEditing, value);
+ }
+
protected override void OnInitialActivate()
{
- PanZoomViewModel = new PanZoomViewModel {LimitToZero = false};
+ PanZoomViewModel = new PanZoomViewModel
+ {
+ LimitToZero = false,
+ PanX = _settingsService.GetSetting("ProfileEditor.PanX", 0d).Value,
+ PanY = _settingsService.GetSetting("ProfileEditor.PanY", 0d).Value,
+ Zoom = _settingsService.GetSetting("ProfileEditor.Zoom", 0d).Value
+ };
Devices = new BindableCollection();
HighlightedLeds = new BindableCollection();
@@ -143,14 +142,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
ActivateToolByIndex(0);
ApplyActiveProfile();
-
- AlwaysApplyDataBindings = _settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", true);
- FocusSelectedLayer = _settingsService.GetSetting("ProfileEditor.FocusSelectedLayer", true);
-
+
_lastUpdate = DateTime.Now;
_coreService.FrameRendered += OnFrameRendered;
- FocusSelectedLayer.SettingChanged += HighlightSelectedLayerOnSettingChanged;
_rgbService.DeviceAdded += RgbServiceOnDevicesModified;
_rgbService.DeviceRemoved += RgbServiceOnDevicesModified;
_profileEditorService.SelectedProfileChanged += OnSelectedProfileChanged;
@@ -163,7 +158,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
protected override void OnClose()
{
_coreService.FrameRendered -= OnFrameRendered;
- FocusSelectedLayer.SettingChanged -= HighlightSelectedLayerOnSettingChanged;
_rgbService.DeviceAdded -= RgbServiceOnDevicesModified;
_rgbService.DeviceRemoved -= RgbServiceOnDevicesModified;
_profileEditorService.SelectedProfileChanged -= OnSelectedProfileChanged;
@@ -172,9 +166,13 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
if (_previousSelectedLayer != null)
_previousSelectedLayer.LayerBrushUpdated -= SelectedLayerOnLayerBrushUpdated;
- AlwaysApplyDataBindings.Save();
- FocusSelectedLayer.Save();
-
+ _settingsService.GetSetting("ProfileEditor.PanX", 0d).Value = PanZoomViewModel.PanX;
+ _settingsService.GetSetting("ProfileEditor.PanX", 0d).Save();
+ _settingsService.GetSetting("ProfileEditor.PanY", 0d).Value = PanZoomViewModel.PanY;
+ _settingsService.GetSetting("ProfileEditor.PanY", 0d).Save();
+ _settingsService.GetSetting("ProfileEditor.Zoom", 0d).Value = PanZoomViewModel.Zoom;
+ _settingsService.GetSetting("ProfileEditor.Zoom", 0d).Save();
+
base.OnClose();
}
@@ -210,7 +208,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
private void UpdateLedsDimStatus()
{
HighlightedLeds.Clear();
- if (FocusSelectedLayer.Value && _profileEditorService.SelectedProfileElement is Layer layer)
+ if (_profileEditorService.SelectedProfileElement is Layer layer)
HighlightedLeds.AddRange(layer.Leds);
}
@@ -308,7 +306,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
TimeSpan delta = DateTime.Now - _lastUpdate;
_lastUpdate = DateTime.Now;
- if (!AlwaysApplyDataBindings.Value || _profileEditorService.SelectedProfile == null)
+ if (!_settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", true).Value || _profileEditorService.SelectedProfile == null)
return;
foreach (IDataBindingRegistration dataBindingRegistration in _profileEditorService.SelectedProfile.GetAllFolders()
diff --git a/src/Artemis.UI/Screens/RootViewModel.cs b/src/Artemis.UI/Screens/RootViewModel.cs
index 8301080b0..902b447f2 100644
--- a/src/Artemis.UI/Screens/RootViewModel.cs
+++ b/src/Artemis.UI/Screens/RootViewModel.cs
@@ -15,6 +15,7 @@ using MaterialDesignExtensions.Controls;
using MaterialDesignThemes.Wpf;
using Ninject;
using Stylet;
+using Stylet.Xaml;
using Constants = Artemis.Core.Constants;
namespace Artemis.UI.Screens
@@ -90,6 +91,8 @@ namespace Artemis.UI.Screens
{
if (!_lostFocus)
return;
+ if (!((MaterialWindow)View).IsActive)
+ return;
_lostFocus = false;
_eventAggregator.Publish(new MainWindowFocusChangedEvent(true));
diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
index 3407d7e07..2e4a4f734 100644
--- a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
+++ b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
@@ -126,7 +126,12 @@ namespace Artemis.UI.Screens.Sidebar
public void Handle(RequestSelectSidebarItemEvent message)
{
- SidebarScreenViewModel requested = SidebarScreens.FirstOrDefault(s => s.DisplayName == message.DisplayName);
+ SidebarScreenViewModel requested = null;
+ if (message.DisplayName != null)
+ requested = SidebarScreens.FirstOrDefault(s => s.DisplayName == message.DisplayName);
+ else
+ requested = message.ViewModel;
+
if (requested != null)
SelectedSidebarScreen = requested;
}