Skip to content

Commit

Permalink
improve double click behavior adding Lines from palette
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcSabatella committed Jun 30, 2015
1 parent 64d3174 commit 6a7fa15
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 72 deletions.
61 changes: 21 additions & 40 deletions libmscore/cmd.cpp
Expand Up @@ -269,47 +269,28 @@ void Score::cmdAddSpanner(Spanner* spanner, const QPointF& pos)

undoAddElement(spanner);
select(spanner, SelectType::SINGLE, 0);
}

if (spanner->type() == Element::Type::TRILL) {
Element* e = segment->element(staffIdx * VOICES);
if (e && e->type() == Element::Type::CHORD) {
Chord* chord = static_cast<Chord*>(e);
Fraction l = chord->duration();
// if (chord->notes().size() > 1) {
// trill do not work for chords
// }
Note* note = chord->upNote();
while (note->tieFor()) {
note = note->tieFor()->endNote();
l += note->chord()->duration();
}
Segment* s = note->chord()->segment();
s = s->next1(Segment::Type::ChordRest);
while (s) {
Element* e = s->element(staffIdx * VOICES);
if (e)
break;
s = s->next1(Segment::Type::ChordRest);
}
if (s) {
for (ScoreElement* e : spanner->linkList())
static_cast<Spanner*>(e)->setTick2(s->tick());
}
Fraction d(1,32);
Fraction e = l / d;
int n = e.numerator() / e.denominator();
QList<NoteEvent*> events;
int pitch = chord->upNote()->ppitch();
Key key = chord->staff()->key(segment->tick());
int pitch2 = diatonicUpDown(key, pitch, 1);
int dpitch = pitch2 - pitch;
for (int i = 0; i < n; i += 2) {
events.append(new NoteEvent(0, i * 1000 / n, 1000/n));
events.append(new NoteEvent(dpitch, (i+1) *1000 / n, 1000/n));
}
undo(new ChangeNoteEvents(chord, events));
}
}
//---------------------------------------------------------
// cmdAddSpanner
// used when applying a spanner to a selection
//---------------------------------------------------------

void Score::cmdAddSpanner(Spanner* spanner, int staffIdx, Segment* startSegment, Segment* endSegment)
{
int track = staffIdx * VOICES;
spanner->setTrack(track);
spanner->setTrack2(track);
spanner->setTick(startSegment->tick());
int tick2;
if (!endSegment)
tick2 = lastSegment()->tick();
else if (endSegment == startSegment)
tick2 = startSegment->measure()->last()->tick();
else
tick2 = endSegment->tick();
spanner->setTick2(tick2);
undoAddElement(spanner);
}

//---------------------------------------------------------
Expand Down
53 changes: 37 additions & 16 deletions libmscore/edit.cpp
Expand Up @@ -1512,24 +1512,45 @@ void Score::cmdAddTie()

void Score::cmdAddOttava(Ottava::Type type)
{
Selection sel = selection();
ChordRest* cr1;
ChordRest* cr2;
getSelectedChordRest2(&cr1, &cr2);
if (!cr1)
return;
if (cr2 == 0)
cr2 = cr1;

Ottava* ottava = new Ottava(this);
ottava->setOttavaType(type);

ottava->setTrack(cr1->track());
ottava->setTrack2(cr1->track());
ottava->setTick(cr1->tick());
ottava->setTick2(cr2->tick() + cr2->actualTicks());
undoAddElement(ottava);
if (!noteEntryMode())
select(ottava, SelectType::SINGLE, 0);
// add on each staff if possible
if (sel.isRange() && sel.staffStart() != sel.staffEnd() - 1) {
for (int staffIdx = sel.staffStart() ; staffIdx < sel.staffEnd(); ++staffIdx) {
ChordRest* cr1 = sel.firstChordRest(staffIdx * VOICES);
ChordRest* cr2 = sel.lastChordRest(staffIdx * VOICES);
if (!cr1)
continue;
if (cr2 == 0)
cr2 = cr1;
Ottava* ottava = new Ottava(this);
ottava->setOttavaType(type);
ottava->setTrack(cr1->track());
ottava->setTrack2(cr1->track());
ottava->setTick(cr1->tick());
ottava->setTick2(cr2->tick() + cr2->actualTicks());
undoAddElement(ottava);
}
}
else {
getSelectedChordRest2(&cr1, &cr2);
if (!cr1)
return;
if (cr2 == 0)
cr2 = cr1;

Ottava* ottava = new Ottava(this);
ottava->setOttavaType(type);

ottava->setTrack(cr1->track());
ottava->setTrack2(cr1->track());
ottava->setTick(cr1->tick());
ottava->setTick2(cr2->tick() + cr2->actualTicks());
undoAddElement(ottava);
if (!noteEntryMode())
select(ottava, SelectType::SINGLE, 0);
}
}

//---------------------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion libmscore/score.h
Expand Up @@ -1012,7 +1012,8 @@ class Score : public QObject {
bool isSpannerStartEnd(int tick, int track) const;
void removeSpanner(Spanner*);
void addSpanner(Spanner*);
void cmdAddSpanner(Spanner* e, const QPointF& pos);
void cmdAddSpanner(Spanner* spanner, const QPointF& pos);
void cmdAddSpanner(Spanner* spanner, int staffIdx, Segment* startSegment, Segment* endSegment);
void checkSpanner(int startTick, int lastTick);
const std::set<Spanner*>unmanagedSpanners() { return _unmanagedSpanner; }
void addUnmanagedSpanner(Spanner*);
Expand Down
3 changes: 3 additions & 0 deletions libmscore/spanner.cpp
Expand Up @@ -18,6 +18,7 @@
#include "segment.h"
#include "measure.h"
#include "undo.h"
#include "staff.h"

namespace Ms {

Expand Down Expand Up @@ -542,6 +543,8 @@ void Spanner::computeEndElement()
if (_ticks != nticks) {
qDebug("%s ticks changed, %d -> %d", name(), _ticks, nticks);
setTicks(nticks);
if (type() == Element::Type::OTTAVA)
staff()->updateOttava();
}
}
break;
Expand Down
52 changes: 42 additions & 10 deletions mscore/palette.cpp
Expand Up @@ -324,6 +324,19 @@ void Palette::mouseDoubleClickEvent(QMouseEvent* ev)
score->startCmd();
}
if (sel.isList()) {
ChordRest* cr1 = sel.firstChordRest();
ChordRest* cr2 = sel.lastChordRest();
bool addSingle = false; // add a single line only
if (cr1 && cr2 == cr1) {
// one chordrest selected, ok to add line
addSingle = true;
}
else if (sel.elements().size() == 2 && cr1 && cr2 && cr1 != cr2) {
// two chordrests selected
// must be on same staff in order to add line, except for slur
if (element->type() == Element::Type::SLUR || cr1->staffIdx() == cr2->staffIdx())
addSingle = true;
}
if (viewer->mscoreState() == STATE_NOTE_ENTRY_DRUM && element->type() == Element::Type::CHORD) {
// use input position rather than selection if possible
Element* e = score->inputState().cr();
Expand All @@ -342,8 +355,22 @@ void Palette::mouseDoubleClickEvent(QMouseEvent* ev)
else
qDebug("nowhere to place drum note");
}
else if (element->type() == Element::Type::SLUR && addSingle) {
viewer->cmdAddSlur();
}
else if (element->isSLine() && element->type() != Element::Type::GLISSANDO && addSingle) {
Segment* startSegment = cr1->segment();
Segment* endSegment = cr2->segment();
if (element->type() == Element::Type::PEDAL && cr2 != cr1)
endSegment = endSegment->nextCR(cr2->track());
// TODO - handle cross-voice selections
int idx = cr1->staffIdx();
Spanner* spanner = static_cast<Spanner*>(element->clone());
spanner->setScore(score);
score->cmdAddSpanner(spanner, idx, startSegment, endSegment);
}
else {
foreach(Element* e, sel.elements())
for (Element* e : sel.elements())
applyDrop(score, viewer, e, element);
}
}
Expand All @@ -356,35 +383,40 @@ void Palette::mouseDoubleClickEvent(QMouseEvent* ev)
QPointF pt(r.x() + r.width() * .5, r.y() + r.height() * .5);
applyDrop(score, viewer, m, element, pt);
}
else if (element->type() == Element::Type::SLUR) {
viewer->cmdAddSlur();
}
else if (element->isSLine() && element->type() != Element::Type::GLISSANDO) {
Segment* startSegment = sel.startSegment();
Segment* endSegment = sel.endSegment();
int endStaff = sel.staffEnd();
for (int i = sel.staffStart(); i < endStaff; ++i) {
Spanner* spanner = static_cast<Spanner*>(element->clone());
spanner->setScore(score);
score->cmdAddSpanner(spanner, i, startSegment, endSegment);
}
}
else {
int track1 = sel.staffStart() * VOICES;
int track2 = sel.staffEnd() * VOICES;
Segment* startSegment = sel.startSegment();
Segment* endSegment = sel.endSegment(); //keep it, it could change during the loop
bool stop = false;
for (Segment* s = startSegment; s && s != endSegment; s = s->next1()) {
for (int track = track1; track < track2; ++track) {
Element* e = s->element(track);
if (e == 0)
continue;
if (e->type() == Element::Type::CHORD) {
Chord* chord = static_cast<Chord*>(e);
foreach(Note* n, chord->notes()) {
for (Note* n : chord->notes())
applyDrop(score, viewer, n, element);
if (element->type() == Element::Type::SLUR || element->type() == Element::Type::HAIRPIN) {
stop = true;
break;
}
}
}
else {
// do not apply articulation to barline in a range selection
if(e->type() != Element::Type::BAR_LINE || element->type() != Element::Type::ARTICULATION)
applyDrop(score, viewer, e, element);
}
if (stop) break;
}
if (stop) break;
}
}
}
Expand Down
22 changes: 17 additions & 5 deletions mscore/scoreview.cpp
Expand Up @@ -4141,7 +4141,7 @@ void ScoreView::startUndoRedo()

//---------------------------------------------------------
// cmdAddSlur
// 'S' typed on keyboard
// command invoked, or icon double clicked
//---------------------------------------------------------

void ScoreView::cmdAddSlur()
Expand All @@ -4154,8 +4154,10 @@ void ScoreView::cmdAddSlur()
is.setSlur(nullptr);
return;
}
bool undoActive = _score->undo()->active();
if (_score->selection().isRange()) {
_score->startCmd();
if (!undoActive)
_score->startCmd();
int startTrack = _score->selection().staffStart() * VOICES;
int endTrack = _score->selection().staffEnd() * VOICES;
for (int track = startTrack; track < endTrack; ++track) {
Expand Down Expand Up @@ -4184,7 +4186,8 @@ void ScoreView::cmdAddSlur()
_score->undoAddElement(slur);
}
}
_score->endCmd();
if (!undoActive)
_score->endCmd();
mscore->endCmd();
}
else {
Expand Down Expand Up @@ -4324,6 +4327,14 @@ void ScoreView::cmdAddSlur(Note* firstNote, Note* lastNote)
void ScoreView::cmdAddHairpin(bool decrescendo)
{
Selection selection = _score->selection();
// special case for two selected chordrests on same staff
bool twoNotesSameStaff = false;
if (selection.isList() && selection.elements().size() == 2) {
ChordRest* cr1 = selection.firstChordRest();
ChordRest* cr2 = selection.lastChordRest();
if (cr1 && cr2 && cr1 != cr2 && cr1->staffIdx() == cr2->staffIdx())
twoNotesSameStaff = true;
}
// add hairpin on each staff if possible
if (selection.isRange() && selection.staffStart() != selection.staffEnd() - 1) {
_score->startCmd();
Expand All @@ -4339,7 +4350,7 @@ void ScoreView::cmdAddHairpin(bool decrescendo)
_score->endCmd();
_score->startCmd();
}
else if (selection.isRange() || selection.isSingle()) {
else if (selection.isRange() || selection.isSingle() || twoNotesSameStaff) {
// for single staff range selection, or single selection,
// find start & end elements elements
ChordRest* cr1;
Expand All @@ -4351,7 +4362,8 @@ void ScoreView::cmdAddHairpin(bool decrescendo)
cr2 = cr1;

_score->startCmd();
Hairpin* pin = _score->addHairpin(decrescendo, cr1->tick(), cr2->tick() + cr2->actualTicks(), cr1->track());
int tick2 = twoNotesSameStaff ? cr2->tick() : cr2->tick() + cr2->actualTicks();
Hairpin* pin = _score->addHairpin(decrescendo, cr1->tick(), tick2, cr1->track());
pin->layout();
_score->endCmd();
_score->startCmd();
Expand Down

0 comments on commit 6a7fa15

Please sign in to comment.