Skip to content

Commit

Permalink
Add an option to show measure number interval at mmrests
Browse files Browse the repository at this point in the history
The MMRestRange is a new class derived from MeasureNumber.

MMRestRange may not be styled like MeasureNumber, so a new set of textstyles were added.
There is 3 possible bracketing around the ranges: parentheses, brackets (the default), or none.
  • Loading branch information
ecstrema committed Nov 25, 2020
1 parent ad4d516 commit 4aa7bb4
Show file tree
Hide file tree
Showing 17 changed files with 448 additions and 119 deletions.
4 changes: 2 additions & 2 deletions libmscore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ add_library (
segmentlist.h select.h sequencer.h shadownote.h shape.h sig.h slur.h slurtie.h spacer.h spanner.h spannermap.h spatium.h
staff.h stafflines.h staffstate.h stafftext.h stafftextbase.h stafftype.h stafftypechange.h stafftypelist.h stem.h
stemslash.h stringdata.h style.h sym.h symbol.h synthesizerstate.h system.h systemdivider.h systemtext.h tempo.h
tempotext.h text.h measurenumber.h textbase.h textedit.h textframe.h textline.h textlinebase.h tie.h tiemap.h timesig.h
tempotext.h text.h mmrestrange.h measurenumber.h textbase.h textedit.h textframe.h textline.h textlinebase.h tie.h tiemap.h timesig.h
tremolo.h tremolobar.h trill.h tuplet.h tupletmap.h types.h undo.h utils.h vibrato.h volta.h xml.h

segmentlist.cpp fingering.cpp accidental.cpp arpeggio.cpp
Expand All @@ -75,7 +75,7 @@ add_library (
score.cpp segment.cpp select.cpp shadownote.cpp slur.cpp tie.cpp slurtie.cpp
spacer.cpp spanner.cpp staff.cpp staffstate.cpp
stafftextbase.cpp stafftext.cpp systemtext.cpp stafftype.cpp stem.cpp style.cpp symbol.cpp
sym.cpp system.cpp stringdata.cpp tempotext.cpp text.cpp measurenumber.cpp textbase.cpp textedit.cpp
sym.cpp system.cpp stringdata.cpp tempotext.cpp text.cpp mmrestrange.cpp measurenumber.cpp textbase.cpp textedit.cpp
textframe.cpp textline.cpp textlinebase.cpp timesig.cpp
tremolobar.cpp tremolo.cpp trill.cpp tuplet.cpp
utils.cpp volta.cpp xmlreader.cpp xmlwriter.cpp mscore.cpp
Expand Down
2 changes: 2 additions & 0 deletions libmscore/layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4018,6 +4018,8 @@ void Score::layoutSystemElements(System* system, LayoutContext& lc)
continue;
Measure* m = toMeasure(mb);
m->layoutMeasureNumber();
m->layoutMMRestRange();

// in continuous view, entire score is one system
// but we only need to process the range
if (lineMode() && (m->tick() < lc.startTick || m->tick() > lc.endTick))
Expand Down
53 changes: 52 additions & 1 deletion libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "system.h"
#include "tempotext.h"
#include "measurenumber.h"
#include "mmrestrange.h"
#include "tie.h"
#include "tiemap.h"
#include "timesig.h"
Expand All @@ -91,6 +92,7 @@ namespace Ms {

class MStaff {
MeasureNumber* _noText { 0 }; ///< Measure number text object
MMRestRange* _mmRangeText { 0 }; ///< Multi measure rest range text object
StaffLines* _lines { 0 };
Spacer* _vspacerUp { 0 };
Spacer* _vspacerDown { 0 };
Expand All @@ -113,6 +115,9 @@ class MStaff {
MeasureNumber* noText() const { return _noText; }
void setNoText(MeasureNumber* t) { _noText = t; }

MMRestRange *mmRangeText() const { return _mmRangeText; }
void setMMRangeText(MMRestRange *r) { _mmRangeText = r; }

StaffLines* lines() const { return _lines; }
void setLines(StaffLines* l) { _lines = l; }

Expand Down Expand Up @@ -433,7 +438,7 @@ AccidentalVal Measure::findAccidental(Segment* s, int staffIdx, int line, bool &

//---------------------------------------------------------
// tick2pos
// return x position for tick relative to System
/// return x position for tick relative to System
//---------------------------------------------------------

qreal Measure::tick2pos(Fraction tck) const
Expand Down Expand Up @@ -538,6 +543,7 @@ void Measure::layoutMeasureNumber()
QString s;
if (smn)
s = QString("%1").arg(no() + 1);

unsigned nn = 1;
bool nas = score()->styleB(Sid::measureNumberAllStaves);

Expand Down Expand Up @@ -580,6 +586,51 @@ void Measure::layoutMeasureNumber()
}
}

void Measure::layoutMMRestRange()
{
if (!isMMRest() || !score()->styleB(Sid::mmRestShowMeasureNumberRange)) {
// Remove existing
for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx) {
MStaff *ms = _mstaves[staffIdx];
MMRestRange *rr = ms->mmRangeText();
if (rr) {
if (rr->generated())
score()->removeElement(rr);
else
score()->undo(new RemoveElement(rr));
}
}

return;
}


QString s;
if (mmRestCount() > 1) {
// middle char is an en dash (not em)
s = QString("%1–%2").arg(no() + 1).arg(no() + mmRestCount());
}
else {
// If the minimum range to create a mmrest is set to 1,
// then simply show the measure number as there is no range
s = QString("%1").arg(no() + 1);
}

for (unsigned staffIdx = 0; staffIdx < _mstaves.size(); ++staffIdx) {
MStaff *ms = _mstaves[staffIdx];
MMRestRange *rr = ms->mmRangeText();
if (!rr) {
rr = new MMRestRange(score());
rr->setTrack(staffIdx * VOICES);
rr->setGenerated(true);
rr->setParent(this);
add(rr);
}
rr->setXmlText(s);
rr->layout();
}
}

//---------------------------------------------------------
// layout2
// called after layout of page
Expand Down
2 changes: 1 addition & 1 deletion libmscore/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ class Measure final : public MeasureBase {
bool showsMeasureNumber();
bool showsMeasureNumberInAutoMode();
void layoutMeasureNumber();
void layoutMMRestRange();

Chord* findChord(Fraction tick, int track);
ChordRest* findChordRest(Fraction tick, int track);
Expand Down Expand Up @@ -278,4 +279,3 @@ class Measure final : public MeasureBase {

} // namespace Ms
#endif

6 changes: 3 additions & 3 deletions libmscore/measurenumber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ static const ElementStyle measureNumberStyle {
// MeasureNumber
//---------------------------------------------------------

MeasureNumber::MeasureNumber(Score* s) : TextBase(s, Tid::MEASURE_NUMBER)
MeasureNumber::MeasureNumber(Score* s, Tid tid, ElementFlags flags)
: TextBase(s, tid, flags)
{
setFlag(ElementFlag::ON_STAFF, true);
initElementStyle(&measureNumberStyle);
Expand Down Expand Up @@ -95,7 +96,7 @@ QVariant MeasureNumber::propertyDefault(Pid id) const
case Pid::PLACEMENT:
return score()->styleV(Sid::measureNumberVPlacement);
case Pid::HPLACEMENT:
return score()->styleV(Sid::measureNumberHPlacement);;
return score()->styleV(Sid::measureNumberHPlacement);
default:
return TextBase::propertyDefault(id);
}
Expand Down Expand Up @@ -197,4 +198,3 @@ void MeasureNumber::layout()
}

} // namespace MS

7 changes: 4 additions & 3 deletions libmscore/measurenumber.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ namespace Ms {

//---------------------------------------------------------
// MeasureNumber
/// The basic element making measure numbers.
/// Reimplemented by MMRestRange
//---------------------------------------------------------

class MeasureNumber final : public TextBase {
class MeasureNumber : public TextBase {

M_PROPERTY (HPlacement, hPlacement, setHPlacement) // Horizontal Placement

public:
MeasureNumber(Score* s = nullptr);
MeasureNumber(Score* = nullptr, Tid tid = Tid::MEASURE_NUMBER, ElementFlags flags = ElementFlag::NOTHING);
MeasureNumber(const MeasureNumber& other);

virtual ElementType type() const override { return ElementType::MEASURE_NUMBER; }
Expand All @@ -47,4 +49,3 @@ class MeasureNumber final : public TextBase {
} // namespace Ms

#endif

127 changes: 127 additions & 0 deletions libmscore/mmrestrange.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2020 MuseScore BVBA and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================

#include "score.h"
#include "mmrestrange.h"
#include "measure.h"
#include "staff.h"

namespace Ms {

//---------------------------------------------------------
// mmRestRangeStyle
//---------------------------------------------------------

static const ElementStyle mmRestRangeStyle {
{ Sid::mmRestRangeBracketType, Pid::MMREST_RANGE_BRACKET_TYPE },
{ Sid::mmRestRangeVPlacement, Pid::PLACEMENT },
{ Sid::mmRestRangeHPlacement, Pid::HPLACEMENT }
};


MMRestRange::MMRestRange(Score* s) : MeasureNumber(s, Tid::MMREST_RANGE)
{
initElementStyle(&mmRestRangeStyle);
}

//---------------------------------------------------------
// MMRestRange
/// Copy constructor
//---------------------------------------------------------

MMRestRange::MMRestRange(const MMRestRange& other) : MeasureNumber(other)
{
initElementStyle(&mmRestRangeStyle);

setBracketType(other.bracketType());
}


QVariant MMRestRange::getProperty(Pid id) const
{
switch (id) {
case Pid::MMREST_RANGE_BRACKET_TYPE:
return int(bracketType());
default:
return MeasureNumber::getProperty(id);
}
}


bool MMRestRange::setProperty(Pid id, const QVariant& val)
{
switch (id) {
case Pid::MMREST_RANGE_BRACKET_TYPE:
setBracketType(MMRestRangeBracketType(val.toInt()));
setLayoutInvalid();
triggerLayout();
return true;
default:
return MeasureNumber::setProperty(id, val);
}
}


QVariant MMRestRange::propertyDefault(Pid id) const
{
switch(id) {
case Pid::SUB_STYLE:
return int(Tid::MMREST_RANGE);
case Pid::PLACEMENT:
return score()->styleV(Sid::mmRestRangeVPlacement);
case Pid::HPLACEMENT:
return score()->styleV(Sid::mmRestRangeHPlacement);
default:
return MeasureNumber::propertyDefault(id);
}
}


bool MMRestRange::readProperties(XmlReader& xml)
{
if (readProperty(xml.name(), xml, Pid::MMREST_RANGE_BRACKET_TYPE))
return true;
else
return MeasureNumber::readProperties(xml);
}

//---------------------------------------------------------
// setXmlText
/// This is reimplemented from TextBase::setXmlText to take care of the brackets
//---------------------------------------------------------

void MMRestRange::setXmlText(const QString& s)
{
switch (bracketType()) {
case MMRestRangeBracketType::BRACKETS:
TextBase::setXmlText("[" + s + "]");
break;
case MMRestRangeBracketType::PARENTHESES:
TextBase::setXmlText("(" + s + ")");
break;
case MMRestRangeBracketType::NONE:
TextBase::setXmlText(s);
break;
default:
Q_UNREACHABLE();
break;
}
}

} // namespace MS
55 changes: 55 additions & 0 deletions libmscore/mmrestrange.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2020 MuseScore BVBA and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================

#ifndef __MMRESTRANGE_H__
#define __MMRESTRANGE_H__

#include "measurenumber.h"
#include "property.h"

namespace Ms {

//---------------------------------------------------------
// MMRestRange
//---------------------------------------------------------

class MMRestRange : public MeasureNumber {

/// Bracketing: [18-24], (18-24) or 18-24
M_PROPERTY (MMRestRangeBracketType, bracketType, setBracketType)

public:
MMRestRange(Score* s = nullptr);
MMRestRange(const MMRestRange& other);

virtual ElementType type() const override { return ElementType::MEASURE_NUMBER; }
virtual MMRestRange* clone() const override { return new MMRestRange(*this); }

virtual QVariant getProperty(Pid id) const override;
virtual bool setProperty(Pid id, const QVariant& val) override;
virtual QVariant propertyDefault(Pid id) const override;

virtual bool readProperties(XmlReader&) override;

virtual void setXmlText(const QString&) override;
};

} // namespace Ms

#endif
1 change: 1 addition & 0 deletions libmscore/property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ static constexpr PropertyMetaData propertyList[] = {
{ Pid::CHANGE_METHOD, true, "changeMethod", P_TYPE::CHANGE_METHOD, DUMMY_QT_TRANSLATE_NOOP("propertyName", "change method") }, // the new, more general version of VELO_CHANGE_METHOD
{ Pid::PLACEMENT, false, "placement", P_TYPE::PLACEMENT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "placement") },
{ Pid::HPLACEMENT, false, "hplacement", P_TYPE::HPLACEMENT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "horizontal placement") },
{ Pid::MMREST_RANGE_BRACKET_TYPE, false, "mmrestRangeBracketType", P_TYPE::INT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "multi-measure rest range bracket type") },
{ Pid::VELOCITY, false, "velocity", P_TYPE::INT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "velocity") },
{ Pid::JUMP_TO, true, "jumpTo", P_TYPE::STRING, DUMMY_QT_TRANSLATE_NOOP("propertyName", "jump to") },
{ Pid::PLAY_UNTIL, true, "playUntil", P_TYPE::STRING, DUMMY_QT_TRANSLATE_NOOP("propertyName", "play until") },
Expand Down
3 changes: 2 additions & 1 deletion libmscore/property.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ enum class Pid {
CHANGE_METHOD,
PLACEMENT, // Goes with P_TYPE::PLACEMENT
HPLACEMENT, // Goes with P_TYPE::HPLACEMENT
MMREST_RANGE_BRACKET_TYPE, // The brackets used arond the measure numbers indicating the range covered by the mmrest
VELOCITY,
JUMP_TO,
PLAY_UNTIL,
Expand Down Expand Up @@ -401,7 +402,7 @@ enum class P_TYPE : char {
FONT,
SUB_STYLE,
ALIGN,
CHANGE_METHOD, // enum class VeloChangeMethod (for single notedynamics)
CHANGE_METHOD, // enum class VeloChangeMethod (for single note dynamics)
CHANGE_SPEED, // enum class Dynamic::Speed
CLEF_TYPE, // enum class ClefType
DYNAMIC_TYPE, // enum class Dynamic::Type
Expand Down
Loading

0 comments on commit 4aa7bb4

Please sign in to comment.