Skip to content

Commit

Permalink
Merge pull request #4203 from dmitrio95/121431-hairpin-dynamics-layout
Browse files Browse the repository at this point in the history
fix #121431: fit hairpins between adjacent dynamics
  • Loading branch information
anatoly-os committed Nov 25, 2018
2 parents 51ee965 + 5165150 commit 0cab309
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 22 deletions.
28 changes: 27 additions & 1 deletion libmscore/hairpin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,33 @@ Element* HairpinSegment::drop(EditData& data)

void HairpinSegment::layout()
{
qreal _spatium = spatium();
const qreal _spatium = spatium();
const int _track = track();
if (autoplace() && !score()->isPalette()) {
// Try to fit between adjacent dynamics
if (isSingleType() || isBeginType()) {
Segment* start = hairpin()->startSegment();
Dynamic* sd = start ? toDynamic(start->findAnnotation(ElementType::DYNAMIC, _track, _track)) : nullptr;
if (sd) {
const qreal sdRight = sd->bbox().right() + sd->pos().x()
+ sd->segment()->pos().x() + sd->measure()->pos().x();
const qreal dist = sdRight - pos().x() + score()->styleP(Sid::autoplaceHairpinDynamicsDistance);
rxpos() += dist;
rxpos2() -= dist;
}
}
if (isSingleType() || isEndType()) {
Segment* end = hairpin()->endSegment();
Dynamic* ed = end ? toDynamic(end->findAnnotation(ElementType::DYNAMIC, _track, _track)) : nullptr;
if (ed) {
const qreal edLeft = ed->bbox().left() + ed->pos().x()
+ ed->segment()->pos().x() + ed->measure()->pos().x();
const qreal dist = edLeft - pos2().x() - pos().x() - score()->styleP(Sid::autoplaceHairpinDynamicsDistance);
rxpos2() += dist;
}
}
}

HairpinType type = hairpin()->hairpinType();
if (type == HairpinType::DECRESC_LINE || type == HairpinType::CRESC_LINE) {
twoLines = false;
Expand Down
12 changes: 2 additions & 10 deletions libmscore/paste.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,16 +315,8 @@ bool Score::pasteStaff(XmlReader& e, Segment* dst, int dstStaff)
int tick = e.tick();
Measure* m = tick2measure(tick);
Segment* seg = m->undoGetSegment(SegmentType::ChordRest, tick);
if (seg->findAnnotationOrElement(ElementType::HARMONY, e.track(), e.track())) {
QList<Element*> elements;
foreach (Element* el, seg->annotations()) {
if (el->isHarmony() && el->track() == e.track()) {
elements.append(el);
}
}
foreach (Element* el, elements)
undoRemoveElement(el);
}
for (Element* el : seg->findAnnotations(ElementType::HARMONY, e.track(), e.track()))
undoRemoveElement(el);
harmony->setParent(seg);
undoAddElement(harmony);
}
Expand Down
4 changes: 4 additions & 0 deletions libmscore/score.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ class Score : public QObject, public ScoreElement {
///< save a backup file will be created, subsequent
///< saves will not overwrite the backup file.
bool _defaultsRead { false }; ///< defaults were read at MusicXML import, allow export of defaults in convertermode
bool _isPalette { false };

int _pos[3]; ///< 0 - current, 1 - left loop, 2 - right loop

Expand Down Expand Up @@ -905,6 +906,9 @@ class Score : public QObject, public ScoreElement {
void setDefaultsRead(bool b) { _defaultsRead = b; }
Text* getText(Tid subtype);

bool isPalette() const { return _isPalette; }
void setPaletteMode(bool palette) { _isPalette = palette; }

void lassoSelect(const QRectF&);
void lassoSelectEnd();

Expand Down
30 changes: 23 additions & 7 deletions libmscore/segment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,11 +940,11 @@ bool Segment::operator>(const Segment& s) const
}

//---------------------------------------------------------
// findAnnotationOrElement
// hasAnnotationOrElement
/// return true if an annotation of type type or and element is found in the track range
//---------------------------------------------------------

bool Segment::findAnnotationOrElement(ElementType type, int minTrack, int maxTrack)
bool Segment::hasAnnotationOrElement(ElementType type, int minTrack, int maxTrack) const
{
for (const Element* e : _annotations)
if (e->type() == type && e->track() >= minTrack && e->track() <= maxTrack)
Expand All @@ -957,15 +957,31 @@ bool Segment::findAnnotationOrElement(ElementType type, int minTrack, int maxTra

//---------------------------------------------------------
// findAnnotation
/// return true if an annotation of type type
/// Returns the first found annotation of type type
/// or nullptr if nothing was found.
//---------------------------------------------------------

bool Segment::findAnnotation(ElementType type, int minTrack, int maxTrack)
Element* Segment::findAnnotation(ElementType type, int minTrack, int maxTrack)
{
for (const Element* e : _annotations)
for (Element* e : _annotations)
if (e->type() == type && e->track() >= minTrack && e->track() <= maxTrack)
return true;
return false;
return e;
return nullptr;
}

//---------------------------------------------------------
// findAnnotations
/// Returns the list of found annotations
/// or nullptr if nothing was found.
//---------------------------------------------------------

std::vector<Element*> Segment::findAnnotations(ElementType type, int minTrack, int maxTrack)
{
std::vector<Element*> found;
for (Element* e : _annotations)
if (e->type() == type && e->track() >= minTrack && e->track() <= maxTrack)
found.push_back(e);
return found;
}

//---------------------------------------------------------
Expand Down
5 changes: 3 additions & 2 deletions libmscore/segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ class Segment final : public Element {
const std::vector<Element*>& annotations() const { return _annotations; }
void clearAnnotations();
void removeAnnotation(Element* e);
bool findAnnotationOrElement(ElementType type, int minTrack, int maxTrack);
bool findAnnotation(ElementType type, int minTrack, int maxTrack);
bool hasAnnotationOrElement(ElementType type, int minTrack, int maxTrack) const;
Element* findAnnotation(ElementType type, int minTrack, int maxTrack);
std::vector<Element*> findAnnotations(ElementType type, int minTrack, int maxTrack);


qreal dotPosX(int staffIdx) const { return _dotPosX[staffIdx]; }
Expand Down
2 changes: 1 addition & 1 deletion mscore/editfiguredbass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void ScoreView::figuredBassTab(bool bMeas, bool bBack)
int maxTrack = minTrack + (VOICES-1);

while (nextSegm) { // look for a ChordRest in the compatible track range
if(nextSegm->findAnnotationOrElement(ElementType::FIGURED_BASS, minTrack, maxTrack))
if(nextSegm->hasAnnotationOrElement(ElementType::FIGURED_BASS, minTrack, maxTrack))
break;
nextSegm = bBack ? nextSegm->prev1(SegmentType::ChordRest) : nextSegm->next1(SegmentType::ChordRest);
}
Expand Down
2 changes: 1 addition & 1 deletion mscore/editharmony.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ void ScoreView::harmonyBeatsTab(bool noterest, bool back)
if (noterest) {
int minTrack = (track / VOICES ) * VOICES;
int maxTrack = minTrack + (VOICES-1);
if (segment->findAnnotationOrElement(ElementType::HARMONY, minTrack, maxTrack))
if (segment->hasAnnotationOrElement(ElementType::HARMONY, minTrack, maxTrack))
break;
}
}
Expand Down
1 change: 1 addition & 0 deletions mscore/musescore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7154,6 +7154,7 @@ int main(int argc, char* av[])
mscore = new MuseScore();
// create a score for internal use
gscore = new MasterScore();
gscore->setPaletteMode(true);
gscore->setMovements(new Movements());
gscore->setStyle(MScore::baseStyle());

Expand Down

0 comments on commit 0cab309

Please sign in to comment.