fix #279229 Pianoroll update issues
PRE is now updated when undo/redo command issued. Can now click and drag single note events in PRE.
This commit is contained in:
parent
835c19d7a6
commit
572d18b278
3 changed files with 108 additions and 26 deletions
|
@ -4619,6 +4619,8 @@ void MuseScore::undoRedo(bool undo)
|
|||
endCmd();
|
||||
if (_inspector)
|
||||
_inspector->update();
|
||||
if (pianorollEditor)
|
||||
pianorollEditor->update();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -319,23 +319,78 @@ int PianoLevels::pixelYToVal(int pix) {
|
|||
return (int)(frac * range + filter->minRange());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// pickNoteEvent
|
||||
//---------------------------------------------------------
|
||||
|
||||
bool PianoLevels::pickNoteEvent(int x, int y, bool selectedOnly, Note*& pickedNote, NoteEvent*& pickedNoteEvent)
|
||||
{
|
||||
PianoLevelsFilter* filter = PianoLevelsFilter::FILTER_LIST[_levelsIndex];
|
||||
|
||||
for (int i = 0; i < noteList.size(); ++i) {
|
||||
Note* note = noteList[i];
|
||||
if (selectedOnly && !note->selected())
|
||||
continue;
|
||||
|
||||
if (filter->isPerEvent()) {
|
||||
for (NoteEvent& e : note->playEvents()) {
|
||||
int noteX = tickToPixelX(noteStartTick(note, &e));
|
||||
int noteY = valToPixelY(filter->value(_staff, note, &e));
|
||||
int dx = noteX - x;
|
||||
int dy = noteY - y;
|
||||
|
||||
if (dx * dx + dy * dy < pickRadius * pickRadius) {
|
||||
pickedNote = note;
|
||||
pickedNoteEvent = &e;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int noteX = tickToPixelX(noteStartTick(note, nullptr));
|
||||
int noteY = valToPixelY(filter->value(_staff, note, nullptr));
|
||||
int dx = noteX - x;
|
||||
int dy = noteY - y;
|
||||
|
||||
if (dx * dx + dy * dy < pickRadius * pickRadius) {
|
||||
pickedNote = note;
|
||||
pickedNoteEvent = nullptr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pickedNote = nullptr;
|
||||
pickedNoteEvent = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// mousePressEvent
|
||||
// adjustLevelLerp
|
||||
//---------------------------------------------------------
|
||||
|
||||
void PianoLevels::adjustLevel(Note* note, NoteEvent* noteEvt, int value)
|
||||
{
|
||||
PianoLevelsFilter* filter = PianoLevelsFilter::FILTER_LIST[_levelsIndex];
|
||||
|
||||
filter->setValue(_staff, note, noteEvt, value);
|
||||
|
||||
update();
|
||||
emit noteLevelsChanged();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// adjustLevelLerp
|
||||
// For all points between tick0 and tick1, linearly interploate between value0 and value1 and
|
||||
// use it to set the value of the level.
|
||||
//---------------------------------------------------------
|
||||
|
||||
void PianoLevels::adjustLevel(int tick0, int value0, int tick1, int value1, bool selectedOnly)
|
||||
void PianoLevels::adjustLevelLerp(int tick0, int value0, int tick1, int value1, bool selectedOnly)
|
||||
{
|
||||
if (tick1 < tick0) {
|
||||
int tmp = tick0;
|
||||
tick0 = tick1;
|
||||
tick1 = tmp;
|
||||
|
||||
tmp = value0;
|
||||
value0 = value1;
|
||||
value1 = tmp;
|
||||
std::swap(tick0, tick1);
|
||||
std::swap(value0, value1);
|
||||
}
|
||||
|
||||
PianoLevelsFilter* filter = PianoLevelsFilter::FILTER_LIST[_levelsIndex];
|
||||
|
@ -385,6 +440,13 @@ void PianoLevels::mousePressEvent(QMouseEvent* e)
|
|||
mouseDown = true;
|
||||
mouseDownPos = e->pos();
|
||||
lastMousePos = mouseDownPos;
|
||||
|
||||
if (pickNoteEvent(mouseDownPos.x(), mouseDownPos.y(), true, singleNoteDrag, singleNoteEventDrag)) {
|
||||
dragStyle = DragStyle::OFFSET;
|
||||
}
|
||||
else {
|
||||
dragStyle = DragStyle::LERP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,7 +466,7 @@ void PianoLevels::mouseReleaseEvent(QMouseEvent* e)
|
|||
int tick0 = pixelXToTick(lastMousePos.x() - 4);
|
||||
int tick1 = pixelXToTick(lastMousePos.x() + 4);
|
||||
int val = pixelYToVal(lastMousePos.y());
|
||||
adjustLevel(tick0, val, tick1, val);
|
||||
adjustLevelLerp(tick0, val, tick1, val);
|
||||
}
|
||||
|
||||
mouseDown = false;
|
||||
|
@ -425,31 +487,38 @@ void PianoLevels::mouseMoveEvent(QMouseEvent* e)
|
|||
if (!dragging) {
|
||||
int dx = e->x() - mouseDownPos.x();
|
||||
int dy = e->y() - mouseDownPos.y();
|
||||
if (dx * dx + dy * dy > 4) {
|
||||
if (dx * dx + dy * dy > pickRadius * pickRadius) {
|
||||
//Start dragging
|
||||
dragging = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dragging) {
|
||||
int tick0 = pixelXToTick(lastMousePos.x());
|
||||
int tick1 = pixelXToTick(e->x());
|
||||
|
||||
int val0;
|
||||
int val1;
|
||||
|
||||
if (bnShift) {
|
||||
//If shift is held, set to value at mousedown
|
||||
val0 = pixelYToVal(mouseDownPos.y());
|
||||
val1 = pixelYToVal(mouseDownPos.y());
|
||||
if (dragStyle == DragStyle::OFFSET) {
|
||||
int val = pixelYToVal(lastMousePos.y());
|
||||
adjustLevel(singleNoteDrag, singleNoteEventDrag, val);
|
||||
}
|
||||
else {
|
||||
val0 = pixelYToVal(lastMousePos.y());
|
||||
val1 = pixelYToVal(e->y());
|
||||
int tick0 = pixelXToTick(lastMousePos.x());
|
||||
int tick1 = pixelXToTick(e->x());
|
||||
|
||||
int val0;
|
||||
int val1;
|
||||
|
||||
if (bnShift) {
|
||||
//If shift is held, set to value at mousedown
|
||||
val0 = pixelYToVal(mouseDownPos.y());
|
||||
val1 = pixelYToVal(mouseDownPos.y());
|
||||
}
|
||||
else {
|
||||
val0 = pixelYToVal(lastMousePos.y());
|
||||
val1 = pixelYToVal(e->y());
|
||||
}
|
||||
|
||||
adjustLevelLerp(tick0, val0, tick1, val1);
|
||||
}
|
||||
|
||||
lastMousePos = e->pos();
|
||||
adjustLevel(tick0, val0, tick1, val1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,6 +43,10 @@ class PianoLevels : public QWidget
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum DragStyle {
|
||||
LERP, OFFSET
|
||||
};
|
||||
|
||||
Score* _score;
|
||||
int _xpos;
|
||||
qreal _xZoom;
|
||||
|
@ -54,11 +58,15 @@ class PianoLevels : public QWidget
|
|||
int _levelsIndex;
|
||||
int vMargin;
|
||||
int levelLen;
|
||||
int pickRadius = 4;
|
||||
|
||||
bool mouseDown;
|
||||
QPointF mouseDownPos;
|
||||
QPointF lastMousePos;
|
||||
int dragging;
|
||||
int dragging = false;
|
||||
DragStyle dragStyle = DragStyle::OFFSET;
|
||||
Note* singleNoteDrag = nullptr;
|
||||
NoteEvent* singleNoteEventDrag = nullptr;
|
||||
|
||||
int minBeatGap;
|
||||
|
||||
|
@ -79,7 +87,10 @@ class PianoLevels : public QWidget
|
|||
void addChord(Chord* chord, int voice);
|
||||
void clearNoteData();
|
||||
|
||||
void adjustLevel(int tick0, int value0, int tick1, int value1, bool selectedOnly = true);
|
||||
bool pickNoteEvent(int x, int y, bool selectedOnly,
|
||||
Note*& pickedNote, NoteEvent*& pickedNoteEvent);
|
||||
void adjustLevelLerp(int tick0, int value0, int tick1, int value1, bool selectedOnly = true);
|
||||
void adjustLevel(Note* note, NoteEvent* noteEvt, int value);
|
||||
|
||||
signals:
|
||||
void posChanged(const Pos&);
|
||||
|
|
Loading…
Reference in a new issue