mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 03:19:56 +00:00
Profile editor - Fix undo and editor service bugs found by the tests (#913)
* Profile editor - Fix undoing profile editor commands - Undoing a change to an existing keyframe's value restores the value instead of deleting the keyframe - Undoing "remove effect" puts the effect back in its place instead of below the next one - Undoing "toggle keyframes" restores what it was before - Undoing a brush change on a layer that had no brush removes the brush again, using the new Layer.RemoveLayerBrush - Undoing "add element" disables the element again - Undoing an event path change back to no path goes back to an event start node, like a new condition - MoveProfileElement says "Move folder" for folders - UpdateLayerProperty without a time no longer calls itself "Add ... keyframe" * Profile editor - Fix auto-saving, failing commands, suspended editing and smaller editor issues - A failed auto-save no longer stops auto-saving for the rest of the session - A failing command is no longer also reported to ReactiveUI as unhandled, on top of the error dialog - Resuming editing applies the editor's time again right away - Nothing is focused while editing is suspended - A layer created on another layer gets a name that isn't in use next to it - CanUndo and CanRedo start out false, so new subscribers know the state right away - An empty command scope doesn't add an undo step - New subscribers to History get the current history once - Expanding the keyframe selection with an already selected keyframe doesn't add it twice - Snapping can snap to a snap time of zero
This commit is contained in:
1 parent
63186ee06d
commit
295038f338
22 files changed
+140
-133
No files matched your search
@@ -56,7 +56,7 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
ProfileConfiguration = _profileConfigurationSubject.AsObservable();
|
||||
ProfileElement = _profileElementSubject.AsObservable();
|
||||
LayerProperty = _layerPropertySubject.AsObservable();
|
||||
History = Observable.Defer(() => Observable.Return(GetHistory(_profileConfigurationSubject.Value))).Concat(ProfileConfiguration.Select(GetHistory));
|
||||
History = ProfileConfiguration.Select(GetHistory);
|
||||
Time = _timeSubject.AsObservable();
|
||||
Playing = _playingSubject.AsObservable();
|
||||
SuspendedEditing = _suspendedEditingSubject.AsObservable();
|
||||
@@ -101,9 +101,9 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Don't rethrow, that would end the observable that drives auto-saving
|
||||
_windowService.ShowExceptionDialog("Failed to auto-save profile", e);
|
||||
_logger.Error(e, "Failed to auto-save profile");
|
||||
throw;
|
||||
}
|
||||
|
||||
return Unit.Default;
|
||||
@@ -138,8 +138,12 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
|
||||
private void ApplyFocusMode()
|
||||
{
|
||||
// While editing is suspended the profile plays normally, without focus
|
||||
if (_suspendedEditingSubject.Value)
|
||||
{
|
||||
_profileService.FocusProfileElement = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_profileService.FocusProfileElement = _focusModeSubject.Value switch
|
||||
{
|
||||
@@ -235,10 +239,12 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
{
|
||||
if (_profileConfigurationSubject.Value != null)
|
||||
_profileService.UpdateFocusProfile = false;
|
||||
Tick(_timeSubject.Value);
|
||||
}
|
||||
|
||||
_suspendedEditingSubject.OnNext(suspend);
|
||||
// Apply the editor's time again, this only works once editing is no longer suspended
|
||||
if (!suspend)
|
||||
Tick(_timeSubject.Value);
|
||||
ApplyFocusMode();
|
||||
}
|
||||
|
||||
@@ -271,7 +277,10 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
else
|
||||
{
|
||||
if (expand)
|
||||
_selectedKeyframes.Add(keyframe);
|
||||
{
|
||||
if (!_selectedKeyframes.Items.Contains(keyframe))
|
||||
_selectedKeyframes.Add(keyframe);
|
||||
}
|
||||
else
|
||||
_selectedKeyframes.Edit(l =>
|
||||
{
|
||||
@@ -324,9 +333,11 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
if (snapTimes != null)
|
||||
{
|
||||
// Find the closest keyframe
|
||||
TimeSpan closeSnapTime = snapTimes.FirstOrDefault(s => Math.Abs(time.TotalMilliseconds - s.TotalMilliseconds) < tolerance.TotalMilliseconds)!;
|
||||
if (closeSnapTime != TimeSpan.Zero)
|
||||
return closeSnapTime;
|
||||
TimeSpan? closeSnapTime = snapTimes.Where(s => Math.Abs(time.TotalMilliseconds - s.TotalMilliseconds) < tolerance.TotalMilliseconds)
|
||||
.Cast<TimeSpan?>()
|
||||
.FirstOrDefault();
|
||||
if (closeSnapTime != null)
|
||||
return closeSnapTime.Value;
|
||||
}
|
||||
|
||||
return time;
|
||||
@@ -368,7 +379,7 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
{
|
||||
if (target is Layer targetLayer)
|
||||
{
|
||||
Layer layer = new(targetLayer.Parent, targetLayer.GetNewLayerName());
|
||||
Layer layer = new(targetLayer.Parent, targetLayer.Parent.GetNewLayerName());
|
||||
_layerBrushService.ApplyDefaultBrush(layer);
|
||||
|
||||
layer.AddLeds(_deviceService.EnabledDevices.SelectMany(d => d.Leds));
|
||||
@@ -463,6 +474,10 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
ProfileEditorCommandScope scope = _profileEditorHistoryScope;
|
||||
_profileEditorHistoryScope = null;
|
||||
|
||||
// Don't add an undo step that does nothing
|
||||
if (!scope.ProfileEditorCommands.Any())
|
||||
return;
|
||||
|
||||
// Executing the composite command won't do anything the first time (see last ctor variable)
|
||||
// commands were already executed each time they were added to the scope
|
||||
ExecuteCommand(new CompositeCommand(scope.ProfileEditorCommands, scope.Name, true));
|
||||
|
||||
Reference in new issue
Block a user