Move/Stretch note hint

Hi,
I’m making a piano roll where the midi notes are not components but are only drawn.
Based on their temporal position I can understand which is the graphic area they cover.
During the mouseDrag however I’m having problems regarding the move/stretch of the notes.

My code is the following:

auto noteArea = getMidiNoteArea(midiNote);

auto x = parent->editViewState.getSnappedX(e.getPosition().getX() - e.getMouseDownPosition().getX(), getWidth(), bpc->startViewX, bpc->endViewX);

noteArea.setX(noteArea.getX() + x - lastPoint.getX());

lastPoint.setX(x);

auto start = parent->editViewState.timeToBeats(parent->editViewState.xToTime(noteArea.getX(), getWidth(), bpc->startViewX, bpc->endViewX, true));

midiNote->setStartAndLength(BeatPosition::fromBeats(start), BeatDuration::fromBeats(midiNote->getLengthBeats().inBeats()), edit.getUndoManager());

@dave96 could you give me some advice on how to do it? I would like to get the same graphic behavior of Waveform.
Thanks.

I don’t quite follow your code, it looks like you’re changing some UI directly during the drag operation?

I think you basically don’t need these lines:

noteArea.setX(noteArea.getX() + x - lastPoint.getX());

lastPoint.setX(x);

You should probably just be setting the start time of the note based on the drag, then when the model i.e. note start updates, repaint your piano roll component and the MIDI note will draw in the new position.


Just a general tip about how we do this in Waveform, when one or more notes are dragged, we create a temporary object that is the state of the drag operation. It contains all the original start times of the notes. When the mouse is moved you can then figure out the drag distance from the original position and apply that to all the notes.

It easiest to think of a drag operation as just being a single change from original to “current mouse position”, rather than a string of tiny drag deltas.

What I tried to do was to set the new start as the mouse position, but doing so, if the drag started at the end of the note, the start jumped to the mouse position. So I thought I should calculate the start as the difference between the mouse down position and the initial position with various small deltas.

How can I prevent, by setting the start to the note position, the note from “jumping” if I start dragging from the end of the note?

You just need to do this on each drag, just find the drag delta, the amount of time this relates to, then add that to the original position of the note when the drag started.