-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Beats: allow undoing the last BPM/beats change #12954
Conversation
Yet another coffee and it's done 🎉
|
bd5b8d9
to
495b370
Compare
350ae70
to
01057fb
Compare
Manually everything works as expected, just the tests fail. Need to wrap my head around setting beats and stuff. |
caf0a86
to
39a07c4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. Works good.
There is a usability issue when you have used the shift actions form the waveform, like "adjuste earliere" ten times.
You can do it fast via the GUI buttons, but undoing to the original state = 10 x undo is hard via the menu.
Is there a way to remove intermediate adjustments form the undo stack? I think Gimp has also such a strategy to not undo a brush stroke pixel by pixel.
src/track/track.h
Outdated
@@ -561,6 +566,8 @@ class Track : public QObject { | |||
|
|||
// Storage for the track's beats | |||
mixxx::BeatsPointer m_pBeats; | |||
QList<mixxx::BeatsPointer> m_pBeatsUndoStack; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we may use QStack with push() and pop()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to learn about QStack. So the benefit is to use push() and pop() instead of append() and takeLast()/removeLast(). Dunno if that is worth the extra include, but that's tiny, so I'll use it.
Sure, but I didn't look into it, yet. Maybe such a timeout also helps with the initial useless beats setting. |
This is on any case a feature, not blocking this PR. |
Was rather easy, let's check if the tests also work as desired. The last commit adds an Undo button to the beatgrid edit controls in LateNight. |
d84766f
to
2f1e1ca
Compare
Nope. Maybe the timing is different in the tests? |
795b752
to
507aa04
Compare
src/track/track.cpp
Outdated
// Don't add null beats to the undo stack. Happens when beats are deserialized, | ||
// e.g. when opening the track menu. | ||
// Don't add beats to stack which we're about to undo. | ||
mixxx::Duration time = mixxx::Time::elapsed(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stumbled here for a short moment about "elapsed() since what?".
Maybe we should rename it to mixxx::Time::sinceStart()
or such.
In addition we may want to use a "PerformanceTimer" object instead of implementing it inline.
Using start()
restart()
and elapsed()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm considering this, yes.
Pro argument for the current solution is that we don't create an extra timer object, we simply use the Mixxx time.
A performance timer would be running all the time for each track we touch, even if the user doesn't change the beats (apart from initial load/analyse). A regular one-shot timer (auto-stop) might also work (delta is 800 ms).
Hence I don't really see the necessity to change this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, I have to a strong demand here. We can keep it as it is.
But let's give some insights:
The PerformanceTimer object not "running" in terms of CPU. It is just a thin wrapper around a single member variable that stores the start time. See:
mixxx/src/util/performancetimer.h
Line 37 in 7111b70
std::chrono::time_point<ClockT> m_startTime; |
So basically your current solution wrapped by an API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry, should have looked closer.
I'll try that!
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Manually this works just fine, but I need help with the test (or merge without it). |
* add `beats_undo_adjustment` ControlPushButton * add "Undo last BPM/beats change" to BPM menu, active only if there's something to undo Co-authored-by: Daniel Schürmann <[email protected]>
What is your plan here? Remove form 2.5-beta milestone? |
I need help with the tests, then this is ready. |
I've discovered some issue with the quick actions. (that might also be the reason why the test fails...) |
Jup, that was it, the test passes. Ready to remove the Undo button and the trace output. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, ready for clean up. Thank you.
The manual update is here mixxxdj/manual#654 |
Thank you |
@ronso0 Did you consider using QUndoStack, and if so, why did you prefer to implement your own stack? I used QUndoStack for cue add/remove: #13469 . I have only looked briefly at your implementation, but I think it will be trivial to use the QUndoStack instead of the custom stack for the beat changes, but maybe I am missing something. |
No, I was not aware of QUndoStack. I'll comment in #13469 re the details. |
Allow undoing the last BPM/beats change.
Up to 10 BeatsPointers are stored on each BPM/beats change.
Apparently the beat analyzer set beats twice on initial scan, so the first result is added to the stack 🤷♂️
For changes done in quick succession (<800 ms currently) intermediate states are not stored.
beats_undo_adjustment
ControlPushButtonFixes #12774 (#10138)
TODO
(Tango + LateNight only? in Deere controls are already quite dense)
Nice to have
Do we need 'Redo'?
I'd say no. Might be nice to have for comparison, but beats operations are easy to redo, so 🤷♂️
It would definitely complicate things.