-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
pianoroll: nudge/snap while dragging notes #5848
Conversation
combobox for switching behavior old behavior (nudge) is default
🤖 Hey, I'm @LmmsBot from github.com/lmms/bot and I made downloads for this pull request, click me to make them magically appear! 🎩
Linux
Windows
🤖{"platform_name_to_artifacts": {"Linux": [{"artifact": {"title": {"title": "(AppImage)", "platform_name": "Linux"}, "link": {"link": "https://12492-15778896-gh.circle-artifacts.com/0/lmms-1.3.0-alpha.1.78%2Bgecea6b8-linux-x86_64.AppImage"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/12492?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}], "Windows": [{"artifact": {"title": {"title": "32-bit", "platform_name": "Windows"}, "link": {"link": "https://12491-15778896-gh.circle-artifacts.com/0/lmms-1.3.0-alpha.1.78%2Bgecea6b8cb-mingw-win32.exe"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/12491?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}, {"artifact": {"title": {"title": "64-bit", "platform_name": "Windows"}, "link": {"link": "https://12494-15778896-gh.circle-artifacts.com/0/lmms-1.3.0-alpha.1.78%2Bgecea6b8cb-mingw-win64.exe"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/12494?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}, {"artifact": {"title": {"title": "32-bit", "platform_name": "Windows"}, "link": {"link": "https://ci.appveyor.com/api/buildjobs/eiybafr1o429xb5u/artifacts/build/lmms-1.3.0-alpha-msvc2017-win32.exe"}}, "build_link": "https://ci.appveyor.com/project/Lukas-W/lmms/builds/37638110"}, {"artifact": {"title": {"title": "64-bit", "platform_name": "Windows"}, "link": {"link": "https://ci.appveyor.com/api/buildjobs/2bt2xo723lomgwqv/artifacts/build/lmms-1.3.0-alpha-msvc2017-win64.exe"}}, "build_link": "https://ci.appveyor.com/project/Lukas-W/lmms/builds/37638110"}]}, "commit_sha": "8c3c5fc8943286d649fb415ebff6f1e352b5a784"} |
Would you consider adding snapping to the end of the note as well? (Choosing whichever is closest to the unquantized position, as with shift drag in the song editor). It would be convenient for reversed samples and such, and shouldn't interfere much with the existing functionality in most situations. I think this is worth adding regardless, but it's a nice-to-have if you're not opposed. |
Didn't think of that. Will do.
[Email stuff trimmed - Spekular]
|
Suggestion: to me it's a bit odd that when snap activated notes are snapping both from the start and the end of the note, and make it seem that the movement it's kind of random (though I see it is as intended). Maybe it would be better if snap has in mind the direction of the movement. If going left, snap with the start of the note. If going right, snap with the end of the note. |
Snapping that depends on the direction of drag seems like a bad idea. What if I just want to move 1/4 note to the right? I'd first have to drag beyond that note and then drag left to finally land there. |
I only tested (very shortly) in pianoroll in the song editor. I'll look at the bb editor case. |
found a bug :-( LMMS.Snap.bug.mp4 |
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.
Just an initial review. As said in Discord, I think the bug that you found is being caused by calling noteUnderMouse
repeatedly to get the note being dragged on the mouseMoveEvent
method. When two notes are in the same position you might end up with the wrong note on the dragNotes
call. m_draggedNote
seems redundant when you have m_currentNote
and I think you could get rid of it and use the latter instead, fixing the bug and also removing an unnecessary variable.
I wrote a few other comments, but before going further with the review I was thinking about suggesting a different approach on the logic that snaps the note to the grid. Why not using the mouse position, quantizing it and then just calculating the offset necessary to get the note from where it is to that quantized mouse position? It sounds to me like it would make the logic simpler (wouldn't require copying the note, quantizing it and moving it around) and it seems like it would work as intended. The only difference in behavior that I can think of is that the position of the mouse in relation to the grid would matter more than the position of the mouse against the initial position of the note. Would have to check in terms of UX if that behavior is annoying or not, but if it is it shouldn't be too complicated to add the offset against the initial position of the note to the math.
I can help you out writing this alternative approach if you like!
It woks good to me! Tested on regular and "no-duration" (beats) notes. |
To avoid problems with translations breaking the conditional, PianoRoll::changeSnapMode now uses the value of the ComboBox model, casted to the GridMode enum instead of the text.
A few code style issues were left, those are fixed in this commit.
Since the last enum value was commented out, there's an unnecessary comma left that was removed.
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.
The snapping code looks unnecessarily long to me, and reasonably it seems that the logic for snap vs nudge should be on the same level, rather than snap being calculated "inside" the nudge logic and overriding it.
Ideally the whole |
Separates Nudge logic and Snap logic more explicitly. Avoids recalculation of mouse conversion to time line ticks. Disables shift resizing for Snap mode. Removes unnecessary range checks. Fixes bug with note key boundary checks (which is present in master).
ke->modifiers() & Qt::AltModifier, | ||
ke->modifiers() & Qt::ShiftModifier, | ||
ke->modifiers() & Qt::ControlModifier |
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.
Since we repeat this function call a few times, can we at least fix this? Just pass the event or modifiers in and test in the function for what we need.
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 not strongly for or against this change, but wouldn't that couple dragNotes more closely to (1) the Qt UI and (2) these specific modifiers? If for example the argument "alt" were renamed to "unquantized" (or inverted and renamed to "quantized") then the dragNotes function is independent of which shortcut is used to perform unquantized actions.
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.
Dragging notes is inherently a UI thing, not a core thing.
I do like the idea of changing the names from ctrl
alt
and shift
, and I would rather just pass in a modifiers
value to the function.
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.
Dragging notes is inherently a UI thing, not a core thing.
Sure, but at the moment this function contains a lot of logic that doesn't rely on the UI. The same quantization strategies are relevant regardless of how the move is input.
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 think the renaming of the arguments and possibly compressing them in a single one seems to be the middle ground: We keep the method decoupled from the Qt event and make the modifiers more generic (allowing us to change them later).
Can I suggest that we do it separately though? As I mentioned on a previous comment, this method needs a bit of an overhaul. Just renaming the arguments would also require some thought because some modifiers are used for multiple actions depending on context. I think both the method refactoring and changing of arguments could be done in a single separate PR, they would both benefit on each other.
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.
Can I suggest that we do it separately though?
Sure. 👍
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 after Ian's latest changes.
Merging tomorrow if there are no objections. There's one conflict but it can be quickly fixed in the web editor before merging. |
m_gridMode was not being initialized on the PianoRoll constructor. For that reason the first note drag without changing the GridMode would result in m_gridMode being used unintialized and neither the Snap nor Nudge mode being used. Here, the result of this was a note being moved unquantized. This fixes it by calling changeSnapMode() after setting up the snapModel on the constructor.
m_gridMode was not being initialized on the PianoRoll constructor. For that reason the first note drag without changing the GridMode would result in m_gridMode being used unintialized and neither the Snap nor Nudge mode being used. Here, the result of this was a note being moved unquantized. This fixes it by calling changeSnapMode() after setting up the snapModel on the constructor.
* pianoroll: nudge/snap while dragging notes combobox for switching behavior old behavior (nudge) is default * snap note start or note end to nearest grid line * fix member variable name * change default width of pianoroll * remove trailing white space * use mouse position instead of m_draggednote * Uses enum instead of text for GridMode selection To avoid problems with translations breaking the conditional, PianoRoll::changeSnapMode now uses the value of the ComboBox model, casted to the GridMode enum instead of the text. * Fixes last code style issues A few code style issues were left, those are fixed in this commit. * Removes forgotten comma on enum Since the last enum value was commented out, there's an unnecessary comma left that was removed. * Rewrites some of the grid logic Separates Nudge logic and Snap logic more explicitly. Avoids recalculation of mouse conversion to time line ticks. Disables shift resizing for Snap mode. Removes unnecessary range checks. Fixes bug with note key boundary checks (which is present in master). * Make noteOffset an int instead of TimePos Co-authored-by: Ian Caio <iancaio_dev@hotmail.com>
m_gridMode was not being initialized on the PianoRoll constructor. For that reason the first note drag without changing the GridMode would result in m_gridMode being used unintialized and neither the Snap nor Nudge mode being used. Here, the result of this was a note being moved unquantized. This fixes it by calling changeSnapMode() after setting up the snapModel on the constructor.
* pianoroll: nudge/snap while dragging notes combobox for switching behavior old behavior (nudge) is default * snap note start or note end to nearest grid line * fix member variable name * change default width of pianoroll * remove trailing white space * use mouse position instead of m_draggednote * Uses enum instead of text for GridMode selection To avoid problems with translations breaking the conditional, PianoRoll::changeSnapMode now uses the value of the ComboBox model, casted to the GridMode enum instead of the text. * Fixes last code style issues A few code style issues were left, those are fixed in this commit. * Removes forgotten comma on enum Since the last enum value was commented out, there's an unnecessary comma left that was removed. * Rewrites some of the grid logic Separates Nudge logic and Snap logic more explicitly. Avoids recalculation of mouse conversion to time line ticks. Disables shift resizing for Snap mode. Removes unnecessary range checks. Fixes bug with note key boundary checks (which is present in master). * Make noteOffset an int instead of TimePos Co-authored-by: Ian Caio <iancaio_dev@hotmail.com>
m_gridMode was not being initialized on the PianoRoll constructor. For that reason the first note drag without changing the GridMode would result in m_gridMode being used unintialized and neither the Snap nor Nudge mode being used. Here, the result of this was a note being moved unquantized. This fixes it by calling changeSnapMode() after setting up the snapModel on the constructor.
* pianoroll: nudge/snap while dragging notes combobox for switching behavior old behavior (nudge) is default * snap note start or note end to nearest grid line * fix member variable name * change default width of pianoroll * remove trailing white space * use mouse position instead of m_draggednote * Uses enum instead of text for GridMode selection To avoid problems with translations breaking the conditional, PianoRoll::changeSnapMode now uses the value of the ComboBox model, casted to the GridMode enum instead of the text. * Fixes last code style issues A few code style issues were left, those are fixed in this commit. * Removes forgotten comma on enum Since the last enum value was commented out, there's an unnecessary comma left that was removed. * Rewrites some of the grid logic Separates Nudge logic and Snap logic more explicitly. Avoids recalculation of mouse conversion to time line ticks. Disables shift resizing for Snap mode. Removes unnecessary range checks. Fixes bug with note key boundary checks (which is present in master). * Make noteOffset an int instead of TimePos Co-authored-by: Ian Caio <iancaio_dev@hotmail.com>
m_gridMode was not being initialized on the PianoRoll constructor. For that reason the first note drag without changing the GridMode would result in m_gridMode being used unintialized and neither the Snap nor Nudge mode being used. Here, the result of this was a note being moved unquantized. This fixes it by calling changeSnapMode() after setting up the snapModel on the constructor.
Adds combobox for switching behavior of the snapping to grid when dragging.
Old behavior (nudge) is default.
Notice that snapping is relative to the dragged note and not the 1st note in the selected range.
It's essentially the same as #4357 but I lost that fork and just started over.