Skip to content

Commit

Permalink
Big TimeSigs
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-spa committed Jan 10, 2025
1 parent 7020aab commit f4cfb3b
Show file tree
Hide file tree
Showing 51 changed files with 1,991 additions and 309 deletions.
2 changes: 1 addition & 1 deletion src/engraving/dom/engravingitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ bool EngravingItem::isTopSystemObject() const
if (!systemFlag()) {
return false; // non system object
}
if ((isSpanner() || isSpannerSegment()) && track() != 0) {
if ((isSpanner() || isSpannerSegment() || isTimeSig()) && track() != 0) {
return false;
}
if (!m_links) {
Expand Down
33 changes: 25 additions & 8 deletions src/engraving/dom/segment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1438,6 +1438,8 @@ EngravingItem* Segment::elementAt(track_idx_t track) const

void Segment::scanElements(void* data, void (* func)(void*, EngravingItem*), bool all)
{
all = all || (isType(SegmentType::TimeSig | SegmentType::TimeSigAnnounce)
&& style().styleV(Sid::timeSigPlacement).value<TimeSigPlacement>() != TimeSigPlacement::NORMAL);
for (size_t track = 0; track < score()->nstaves() * VOICES; ++track) {
size_t staffIdx = track / VOICES;
bool thisMeasureVisible = measure()->visible(staffIdx) && score()->staff(staffIdx)->show();
Expand Down Expand Up @@ -2603,25 +2605,19 @@ double Segment::minRight() const
for (const Shape& sh : shapes()) {
distance = std::max(distance, sh.right());
}
if (isClefType()) {
distance += style().styleMM(Sid::clefBarlineDistance);
}
if (trailer()) {
distance += style().styleMM(Sid::systemTrailerRightMargin);
}
return distance;
}

double Segment::minLeft() const
{
double distance = 0.0;
double distance = -DBL_MAX;
for (const Shape& sh : shapes()) {
double l = sh.left();
if (l > distance) {
distance = l;
}
}
return distance;
return distance != -DBL_MAX ? distance : 0.0;
}

void Segment::setSpacing(double val)
Expand All @@ -2634,6 +2630,27 @@ double Segment::spacing() const
return m_spacing;
}

bool Segment::hasTimeSigAboveStaves() const
{
return isType(SegmentType::TimeSig | SegmentType::TimeSigAnnounce)
&& style().styleV(Sid::timeSigPlacement).value<TimeSigPlacement>() == TimeSigPlacement::ABOVE_STAVES;
}

bool Segment::makeSpaceForTimeSigAboveStaves() const
{
bool makeSpace = style().styleB(Sid::timeSigCenterOnBarline)
? style().styleV(Sid::timeSigVSMarginCentered).value<TimeSigVSMargin>() == TimeSigVSMargin::CREATE_SPACE
: style().styleV(Sid::timeSigVSMarginNonCentered).value<TimeSigVSMargin>() == TimeSigVSMargin::CREATE_SPACE;
return hasTimeSigAboveStaves() && makeSpace;
}

bool Segment::hasTimeSigCenteredAcrossStaves() const
{
return isType(SegmentType::TimeSig | SegmentType::TimeSigAnnounce)
&& style().styleV(Sid::timeSigPlacement).value<TimeSigPlacement>() == TimeSigPlacement::ACROSS_STAVES
&& style().styleB(Sid::timeSigCenterAcrossStaveGroup);
}

bool Segment::canWriteSpannerStartEnd(track_idx_t track, const Spanner* spanner) const
{
staff_idx_t staffIdx = track2staff(track);
Expand Down
3 changes: 3 additions & 0 deletions src/engraving/dom/segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ class Segment final : public EngravingItem
bool isKeySigType() const { return m_segmentType == SegmentType::KeySig; }
bool isAmbitusType() const { return m_segmentType == SegmentType::Ambitus; }
bool isTimeSigType() const { return m_segmentType == SegmentType::TimeSig; }
bool hasTimeSigAboveStaves() const;
bool makeSpaceForTimeSigAboveStaves() const;
bool hasTimeSigCenteredAcrossStaves() const;
bool isStartRepeatBarLineType() const { return m_segmentType == SegmentType::StartRepeatBarLine; }
bool isBarLineType() const { return m_segmentType == SegmentType::BarLine; }
bool isBreathType() const { return m_segmentType == SegmentType::Breath; }
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/dom/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ double System::firstNoteRestSegmentX(bool leading) const

// first CR found; back up to previous segment
seg = seg->prevActive();
while (seg && seg->allElementsInvisible()) {
while (seg && (seg->allElementsInvisible() || seg->hasTimeSigAboveStaves())) {
seg = seg->prevActive();
}
if (seg) {
Expand Down
86 changes: 81 additions & 5 deletions src/engraving/dom/timesig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ using namespace mu;
using namespace mu::engraving;

namespace mu::engraving {
static const ElementStyle timesigStyle {
{ Sid::timesigScale, Pid::SCALE },
static const ElementStyle tsStyle {
{ Sid::timeSigNormalScale, Pid::SCALE },
};

//---------------------------------------------------------
Expand All @@ -49,15 +49,16 @@ static const ElementStyle timesigStyle {
//---------------------------------------------------------

TimeSig::TimeSig(Segment* parent)
: EngravingItem(ElementType::TIMESIG, parent, ElementFlag::ON_STAFF | ElementFlag::MOVABLE)
: EngravingItem(ElementType::TIMESIG, parent, ElementFlag::ON_STAFF | ElementFlag::MOVABLE | ElementFlag::PLACE_ABOVE)
{
initElementStyle(&timesigStyle);
initElementStyle(&tsStyle);

m_showCourtesySig = true;
m_stretch.set(1, 1);
m_sig.set(0, 1); // initialize to invalid
m_timeSigType = TimeSigType::NORMAL;
m_largeParentheses = false;
setMinDistance(Spatium(0.5)); // TODO: style
}

void TimeSig::setParent(Segment* parent)
Expand Down Expand Up @@ -272,7 +273,15 @@ PropertyValue TimeSig::propertyDefault(Pid id) const
case Pid::TIMESIG_TYPE:
return int(TimeSigType::NORMAL);
case Pid::SCALE:
return style().styleV(Sid::timesigScale);
{
switch (timeSigPlacement()) {
case TimeSigPlacement::NORMAL: return style().styleV(Sid::timeSigNormalScale).value<ScaleF>();
case TimeSigPlacement::ABOVE_STAVES: return style().styleV(Sid::timeSigAboveScale).value<ScaleF>();
case TimeSigPlacement::ACROSS_STAVES: return style().styleV(Sid::timeSigAcrossScale).value<ScaleF>();
default:
return ScaleF();
}
}
default:
return EngravingItem::propertyDefault(id);
}
Expand Down Expand Up @@ -348,6 +357,73 @@ String TimeSig::accessibleInfo() const
return String(u"%1: %2").arg(EngravingItem::accessibleInfo(), translatedSubtypeUserName());
}

void TimeSig::initElementStyle(const ElementStyle* elementStype)
{
EngravingItem::initElementStyle(elementStype);

setProperty(Pid::SCALE, propertyDefault(Pid::SCALE));
}

void TimeSig::styleChanged()
{
if (isStyled(Pid::SCALE)) {
setProperty(Pid::SCALE, propertyDefault(Pid::SCALE));
}
}

TimeSigPlacement TimeSig::timeSigPlacement() const
{
return style().styleV(Sid::timeSigPlacement).value<TimeSigPlacement>();
}

TimeSigStyle TimeSig::timeSigStyle() const
{
switch (timeSigPlacement()) {
case TimeSigPlacement::NORMAL: return style().styleV(Sid::timeSigNormalStyle).value<TimeSigStyle>();
case TimeSigPlacement::ABOVE_STAVES: return style().styleV(Sid::timeSigAboveStyle).value<TimeSigStyle>();
case TimeSigPlacement::ACROSS_STAVES: return style().styleV(Sid::timeSigAcrossStyle).value<TimeSigStyle>();
default:
return TimeSigStyle::NORMAL;
}
}

double TimeSig::numDist() const
{
switch (timeSigPlacement()) {
case TimeSigPlacement::NORMAL: return style().styleMM(Sid::timeSigNormalNumDist);
case TimeSigPlacement::ABOVE_STAVES: return style().styleMM(Sid::timeSigAboveNumDist);
case TimeSigPlacement::ACROSS_STAVES: return style().styleMM(Sid::timeSigAcrossNumDist);
default:
return 0.0;
}
}

double TimeSig::yPos() const
{
switch (timeSigPlacement()) {
case TimeSigPlacement::NORMAL: return style().styleMM(Sid::timeSigNormalY);
case TimeSigPlacement::ABOVE_STAVES: return style().styleMM(Sid::timeSigAboveY);
case TimeSigPlacement::ACROSS_STAVES: return style().styleMM(Sid::timeSigAcrossY);
default:
return 0.0;
}
}

bool TimeSig::showOnThisStaff() const
{
return timeSigPlacement() == TimeSigPlacement::NORMAL || staffIdx() == 0 || score()->isSystemObjectStaff(staff());
}

bool TimeSig::isAboveStaves() const
{
return timeSigPlacement() == TimeSigPlacement::ABOVE_STAVES;
}

bool TimeSig::isAcrossStaves() const
{
return timeSigPlacement() == TimeSigPlacement::ACROSS_STAVES;
}

//---------------------------------------------------------
// operator==
//---------------------------------------------------------
Expand Down
18 changes: 14 additions & 4 deletions src/engraving/dom/timesig.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,6 @@ class TimeSig final : public EngravingItem
bool largeParentheses() const { return m_largeParentheses; }
void setLargeParentheses(bool v) { m_largeParentheses = v; }

const ScaleF& scale() const { return m_scale; }
void setScale(const ScaleF& s) { m_scale = s; }

void setFrom(const TimeSig*);

PropertyValue getProperty(Pid propertyId) const override;
Expand All @@ -122,6 +119,19 @@ class TimeSig final : public EngravingItem
EngravingItem* prevSegmentElement() override;
String accessibleInfo() const override;

void initElementStyle(const ElementStyle*);
void styleChanged();

bool showOnThisStaff() const;
bool isAboveStaves() const;
bool isAcrossStaves() const;
TimeSigPlacement timeSigPlacement() const;
TimeSigStyle timeSigStyle() const;
double numDist() const;
double yPos() const;
const ScaleF& scale() const { return m_scale; }
void setScale(const ScaleF& s) { m_scale = s; } // TODO: think about what to do with this

struct LayoutData : public EngravingItem::LayoutData {
SymIdList ns;
SymIdList ds;
Expand All @@ -148,7 +158,7 @@ class TimeSig final : public EngravingItem
Fraction m_stretch; // localSig / globalSig
Groups m_groups;

ScaleF m_scale;
ScaleF m_scale = ScaleF(1.0, 1.0);
TimeSigType m_timeSigType = TimeSigType::NORMAL;
bool m_showCourtesySig = false;
bool m_largeParentheses = false;
Expand Down
48 changes: 46 additions & 2 deletions src/engraving/dom/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,7 @@ Segment* skipTuplet(Tuplet* tuplet)
// replace ascii with bravura symbols
//---------------------------------------------------------

SymIdList timeSigSymIdsFromString(const String& string)
SymIdList timeSigSymIdsFromString(const String& string, TimeSigStyle timeSigStyle)
{
static const std::map<Char, SymId> dict = {
{ 43, SymId::timeSigPlusSmall }, // '+'
Expand Down Expand Up @@ -1194,9 +1194,53 @@ SymIdList timeSigSymIdsFromString(const String& string)
{ 59674, SymId::mensuralProlation11 },
};

static const std::map<Char, SymId> dictLarge = {
{ 43, SymId::timeSigPlusSmallLarge }, // '+'
{ 48, SymId::timeSig0Large }, // '0'
{ 49, SymId::timeSig1Large }, // '1'
{ 50, SymId::timeSig2Large }, // '2'
{ 51, SymId::timeSig3Large }, // '3'
{ 52, SymId::timeSig4Large }, // '4'
{ 53, SymId::timeSig5Large }, // '5'
{ 54, SymId::timeSig6Large }, // '6'
{ 55, SymId::timeSig7Large }, // '7'
{ 56, SymId::timeSig8Large }, // '8'
{ 57, SymId::timeSig9Large }, // '9'
{ 67, SymId::timeSigCommonLarge }, // 'C'
{ 40, SymId::timeSigParensLeftSmallLarge }, // '('
{ 41, SymId::timeSigParensRightSmallLarge }, // ')'
{ 162, SymId::timeSigCutCommonLarge }, // '¢'
{ 189, SymId::timeSigFractionHalfLarge },
{ 189, SymId::timeSigFractionQuarterLarge },
};

static const std::map<Char, SymId> dictNarrow = {
{ 43, SymId::timeSigPlusSmallNarrow }, // '+'
{ 48, SymId::timeSig0Narrow }, // '0'
{ 49, SymId::timeSig1Narrow }, // '1'
{ 50, SymId::timeSig2Narrow }, // '2'
{ 51, SymId::timeSig3Narrow }, // '3'
{ 52, SymId::timeSig4Narrow }, // '4'
{ 53, SymId::timeSig5Narrow }, // '5'
{ 54, SymId::timeSig6Narrow }, // '6'
{ 55, SymId::timeSig7Narrow }, // '7'
{ 56, SymId::timeSig8Narrow }, // '8'
{ 57, SymId::timeSig9Narrow }, // '9'
{ 67, SymId::timeSigCommonNarrow }, // 'C'
{ 40, SymId::timeSigParensLeftSmallNarrow }, // '('
{ 41, SymId::timeSigParensRightSmallNarrow }, // ')'
{ 162, SymId::timeSigCutCommonNarrow }, // '¢'
{ 189, SymId::timeSigFractionHalfNarrow },
{ 188, SymId::timeSigFractionQuarterNarrow },
};

SymIdList list;
for (size_t i = 0; i < string.size(); ++i) {
SymId sym = muse::value(dict, string.at(i), SymId::noSym);
SymId sym = muse::value(
timeSigStyle == TimeSigStyle::NARROW ? dictNarrow
: timeSigStyle == TimeSigStyle::LARGE ? dictLarge
: dict,
string.at(i), SymId::noSym);
if (sym != SymId::noSym) {
list.push_back(sym);
}
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/dom/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ int chromaticPitchSteps(const Note* noteL, const Note* noteR, const int nominalD
extern int compareNotesPos(const Note* n1, const Note* n2);

extern Segment* skipTuplet(Tuplet* tuplet);
extern SymIdList timeSigSymIdsFromString(const String&);
extern SymIdList timeSigSymIdsFromString(const String&, TimeSigStyle timeSigStyle = TimeSigStyle::NORMAL);
extern Fraction actualTicks(Fraction duration, Tuplet* tuplet, Fraction timeStretch);

extern double yStaffDifference(const System* system1, const System* system2, staff_idx_t staffIdx1);
Expand Down
Loading

0 comments on commit f4cfb3b

Please sign in to comment.