Skip to content

Commit

Permalink
fix #121431: fit hairpins between adjacent dynamics
Browse files Browse the repository at this point in the history
Adjusts horizontal dimensions of hairpins to fit between adjacent
dynamics, if any exist. No vertical aligning included, as it is
already available in the form of begin/end text for hairpins.
Still for some common cases the logic added by this commit is
good enough.

Dimensions calculation code is taken (with some adjustments) from
8bdd1af

Also includes:
 - Rename/update Segment::findAnnotation[orElement]
 - Add Score::isPalette() to make it easier to distinguish between
   palette and normal scores on layout stage.
  • Loading branch information
dmitrio95 committed Nov 23, 2018
1 parent 100d297 commit 5165150
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 @@ -7106,6 +7106,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 5165150

Please sign in to comment.