2021-04-19 16:06:08 +02:00
|
|
|
|
/*
|
|
|
|
|
* SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
|
* MuseScore-CLA-applies
|
|
|
|
|
*
|
|
|
|
|
* MuseScore
|
|
|
|
|
* Music Composition & Notation
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2021 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 3 as
|
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
|
*
|
|
|
|
|
* 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, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
2012-05-26 14:26:10 +02:00
|
|
|
|
|
|
|
|
|
#ifndef __MEASURE_H__
|
|
|
|
|
#define __MEASURE_H__
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
\file
|
2016-12-28 16:23:10 +01:00
|
|
|
|
Definition of class Measure.
|
2012-05-26 14:26:10 +02:00
|
|
|
|
*/
|
|
|
|
|
|
2021-08-26 13:16:41 +02:00
|
|
|
|
#include "infrastructure/draw/color.h"
|
2012-05-26 14:26:10 +02:00
|
|
|
|
#include "measurebase.h"
|
|
|
|
|
#include "fraction.h"
|
|
|
|
|
#include "segmentlist.h"
|
|
|
|
|
|
2021-09-21 13:39:16 +02:00
|
|
|
|
namespace mu::engraving::rw {
|
|
|
|
|
class MeasureRW;
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
|
namespace Ms {
|
2016-11-19 11:51:21 +01:00
|
|
|
|
class XmlWriter;
|
2012-05-26 14:26:10 +02:00
|
|
|
|
class Beam;
|
|
|
|
|
class Tuplet;
|
|
|
|
|
class Staff;
|
|
|
|
|
class Chord;
|
2018-10-24 10:40:03 +02:00
|
|
|
|
class MeasureNumber;
|
2021-02-04 14:13:07 +01:00
|
|
|
|
class MMRestRange;
|
2012-05-26 14:26:10 +02:00
|
|
|
|
class ChordRest;
|
|
|
|
|
class Score;
|
|
|
|
|
class MuseScoreView;
|
|
|
|
|
class System;
|
|
|
|
|
class Note;
|
|
|
|
|
class Spacer;
|
|
|
|
|
class TieMap;
|
|
|
|
|
class AccidentalState;
|
|
|
|
|
class Spanner;
|
2012-07-21 12:53:18 +02:00
|
|
|
|
class Part;
|
2020-08-28 22:55:29 +02:00
|
|
|
|
class MeasureRepeat;
|
2012-05-26 14:26:10 +02:00
|
|
|
|
|
2013-03-08 12:55:12 +01:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// MeasureNumberMode
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
enum class MeasureNumberMode : char {
|
|
|
|
|
AUTO, // show measure number depending on style
|
|
|
|
|
SHOW, // always show measure number
|
2018-11-27 22:49:18 +01:00
|
|
|
|
HIDE // don’t show measure number
|
2013-03-08 12:55:12 +01:00
|
|
|
|
};
|
|
|
|
|
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// MStaff
|
|
|
|
|
/// Per staff values of measure.
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
class MStaff
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
MStaff() {}
|
|
|
|
|
~MStaff();
|
|
|
|
|
MStaff(const MStaff&);
|
|
|
|
|
|
|
|
|
|
void setScore(Score*);
|
|
|
|
|
void setTrack(int);
|
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
MeasureNumber* noText() const { return m_noText; }
|
|
|
|
|
void setNoText(MeasureNumber* t) { m_noText = t; }
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
|
2021-02-04 14:13:07 +01:00
|
|
|
|
MMRestRange* mmRangeText() const { return m_mmRangeText; }
|
|
|
|
|
void setMMRangeText(MMRestRange* r) { m_mmRangeText = r; }
|
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
StaffLines* lines() const { return m_lines; }
|
|
|
|
|
void setLines(StaffLines* l) { m_lines = l; }
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
Spacer* vspacerUp() const { return m_vspacerUp; }
|
|
|
|
|
void setVspacerUp(Spacer* s) { m_vspacerUp = s; }
|
|
|
|
|
Spacer* vspacerDown() const { return m_vspacerDown; }
|
|
|
|
|
void setVspacerDown(Spacer* s) { m_vspacerDown = s; }
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
bool hasVoices() const { return m_hasVoices; }
|
|
|
|
|
void setHasVoices(bool val) { m_hasVoices = val; }
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
bool visible() const { return m_visible; }
|
|
|
|
|
void setVisible(bool val) { m_visible = val; }
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
bool stemless() const { return m_stemless; }
|
|
|
|
|
void setStemless(bool val) { m_stemless = val; }
|
2020-08-28 18:54:57 +02:00
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2020-08-28 22:55:29 +02:00
|
|
|
|
bool corrupted() const { return m_corrupted; }
|
|
|
|
|
void setCorrupted(bool val) { m_corrupted = val; }
|
2020-08-28 18:54:57 +02:00
|
|
|
|
#endif
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
int measureRepeatCount() const { return m_measureRepeatCount; }
|
|
|
|
|
void setMeasureRepeatCount(int n) { m_measureRepeatCount = n; }
|
|
|
|
|
|
2020-08-28 18:54:57 +02:00
|
|
|
|
private:
|
2020-08-28 22:55:29 +02:00
|
|
|
|
MeasureNumber* m_noText { nullptr }; ///< Measure number text object
|
2021-02-04 14:13:07 +01:00
|
|
|
|
MMRestRange* m_mmRangeText { nullptr }; ///< Multi measure rest range text object
|
2020-08-28 22:55:29 +02:00
|
|
|
|
StaffLines* m_lines { nullptr };
|
|
|
|
|
Spacer* m_vspacerUp { nullptr };
|
|
|
|
|
Spacer* m_vspacerDown { nullptr };
|
2020-08-28 18:54:57 +02:00
|
|
|
|
bool m_hasVoices { false }; ///< indicates that MStaff contains more than one voice,
|
|
|
|
|
///< this changes some layout rules
|
|
|
|
|
bool m_visible { true };
|
|
|
|
|
bool m_stemless { false };
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
#ifndef NDEBUG
|
2020-08-28 18:54:57 +02:00
|
|
|
|
bool m_corrupted { false };
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
#endif
|
2020-08-28 22:55:29 +02:00
|
|
|
|
int m_measureRepeatCount { 0 };
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
};
|
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
2012-07-11 21:29:42 +02:00
|
|
|
|
// @@ Measure
|
2012-07-25 11:49:34 +02:00
|
|
|
|
/// one measure in a system
|
2014-07-06 01:56:30 +02:00
|
|
|
|
//
|
2015-04-24 01:38:32 +02:00
|
|
|
|
// @P firstSegment Segment the first segment of the measure (read-only)
|
|
|
|
|
// @P lastSegment Segment the last segment of the measure (read-only)
|
2012-05-26 14:26:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2017-12-21 14:03:45 +01:00
|
|
|
|
class Measure final : public MeasureBase
|
|
|
|
|
{
|
2020-05-26 15:54:26 +02:00
|
|
|
|
public:
|
2021-09-09 16:44:05 +02:00
|
|
|
|
|
2019-02-21 01:30:35 +01:00
|
|
|
|
~Measure();
|
2012-05-26 14:26:10 +02:00
|
|
|
|
|
2020-03-25 15:06:32 +01:00
|
|
|
|
Measure* clone() const override { return new Measure(*this); }
|
2016-09-09 09:33:11 +02:00
|
|
|
|
void setScore(Score* s) override;
|
|
|
|
|
Measure* cloneMeasure(Score*, const Fraction& tick, TieMap*);
|
2012-05-26 14:26:10 +02:00
|
|
|
|
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
// Score Tree functions
|
2021-09-20 11:46:05 +02:00
|
|
|
|
EngravingObject* scanParent() const override;
|
|
|
|
|
EngravingObject* scanChild(int idx) const override;
|
|
|
|
|
int scanChildCount() const override;
|
Create Score Tree Model
This commit adds virtual functions treeChild, treeParent and
treeChildCount to ScoreElement and implements them in most non-leaf-node
classes. An iterator is also added to ScoreElement class to iterate over
the children of any element.
In this model, Spanners, Beams and Ties are given a single parent, which
is the starting element of the spanner, beam or tie. Also, to ensure
consistency in the model, spanners, beams, and ties appear in the
children list only for their starting element. Children of spanner
elements are SpannerSegments, one for each system the spanner appears
in.
2020-06-19 19:46:59 +02:00
|
|
|
|
|
2021-09-21 13:39:16 +02:00
|
|
|
|
void read(XmlReader& d) override;
|
2020-03-25 15:06:32 +01:00
|
|
|
|
void readAddConnector(ConnectorInfoReader* info, bool pasteMode) override;
|
2021-09-02 15:26:45 +02:00
|
|
|
|
void write(XmlWriter& xml) const override { EngravingItem::write(xml); }
|
2020-09-25 17:52:43 +02:00
|
|
|
|
void write(XmlWriter&, int, bool writeSystemElements, bool forceTimeSig) const override;
|
2016-11-19 11:51:21 +01:00
|
|
|
|
void writeBox(XmlWriter&) const;
|
2013-01-11 18:10:18 +01:00
|
|
|
|
void readBox(XmlReader&);
|
2020-03-25 15:06:32 +01:00
|
|
|
|
bool isEditable() const override { return false; }
|
2021-04-11 12:19:24 +02:00
|
|
|
|
void checkMeasure(int idx, bool useGapRests = true);
|
2012-05-26 14:26:10 +02:00
|
|
|
|
|
2021-09-02 15:26:45 +02:00
|
|
|
|
void add(EngravingItem*) override;
|
|
|
|
|
void remove(EngravingItem*) override;
|
|
|
|
|
void change(EngravingItem* o, EngravingItem* n) override;
|
2016-12-12 14:55:35 +01:00
|
|
|
|
void spatiumChanged(qreal oldValue, qreal newValue) override;
|
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
System* system() const { return toSystem(parent()); }
|
2016-12-12 14:55:35 +01:00
|
|
|
|
bool hasVoices(int staffIdx, Fraction stick, Fraction len) const;
|
2020-11-22 04:23:07 +01:00
|
|
|
|
bool hasVoices(int staffIdx) const;
|
|
|
|
|
void setHasVoices(int staffIdx, bool v);
|
|
|
|
|
|
|
|
|
|
StaffLines* staffLines(int staffIdx);
|
|
|
|
|
Spacer* vspacerDown(int staffIdx) const;
|
|
|
|
|
Spacer* vspacerUp(int staffIdx) const;
|
|
|
|
|
void setStaffVisible(int staffIdx, bool visible);
|
|
|
|
|
void setStaffStemless(int staffIdx, bool stemless);
|
2020-08-28 18:54:57 +02:00
|
|
|
|
#ifndef NDEBUG
|
2020-08-28 22:55:29 +02:00
|
|
|
|
bool corrupted(int staffIdx) const { return m_mstaves[staffIdx]->corrupted(); }
|
|
|
|
|
void setCorrupted(int staffIdx, bool val) { m_mstaves[staffIdx]->setCorrupted(val); }
|
2020-08-28 18:54:57 +02:00
|
|
|
|
#endif
|
2020-08-28 22:55:29 +02:00
|
|
|
|
MeasureNumber* noText(int staffIdx) const { return m_mstaves[staffIdx]->noText(); }
|
|
|
|
|
void setNoText(int staffIdx, MeasureNumber* t) { m_mstaves[staffIdx]->setNoText(t); }
|
2013-03-08 12:55:12 +01:00
|
|
|
|
|
2021-02-04 14:13:07 +01:00
|
|
|
|
void setMMRangeText(int staffIdx, MMRestRange*);
|
|
|
|
|
MMRestRange* mmRangeText(int staffIdx) const;
|
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
|
void createStaves(int);
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
MeasureNumberMode measureNumberMode() const { return m_noMode; }
|
|
|
|
|
void setMeasureNumberMode(MeasureNumberMode v) { m_noMode = v; }
|
2019-01-30 15:13:54 +01:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
Fraction timesig() const { return m_timesig; }
|
|
|
|
|
void setTimesig(const Fraction& f) { m_timesig = f; }
|
2013-05-13 18:49:17 +02:00
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
|
Fraction stretchedLen(Staff*) const;
|
2020-08-28 22:55:29 +02:00
|
|
|
|
bool isIrregular() const { return m_timesig != _len; }
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
int size() const { return m_segments.size(); }
|
2021-02-05 12:44:30 +01:00
|
|
|
|
Ms::Segment* first() const { return m_segments.first(); }
|
2020-08-28 22:55:29 +02:00
|
|
|
|
Segment* first(SegmentType t) const { return m_segments.first(t); }
|
|
|
|
|
Segment* firstEnabled() const { return m_segments.first(ElementFlag::ENABLED); }
|
2021-02-05 12:44:30 +01:00
|
|
|
|
|
|
|
|
|
Ms::Segment* last() const { return m_segments.last(); }
|
|
|
|
|
Segment* lastEnabled() const { return m_segments.last(ElementFlag::ENABLED); }
|
2020-08-28 22:55:29 +02:00
|
|
|
|
SegmentList& segments() { return m_segments; }
|
|
|
|
|
const SegmentList& segments() const { return m_segments; }
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2014-05-17 18:40:05 +02:00
|
|
|
|
qreal userStretch() const;
|
2020-08-28 22:55:29 +02:00
|
|
|
|
void setUserStretch(qreal v) { m_userStretch = v; }
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2016-01-04 14:48:58 +01:00
|
|
|
|
void stretchMeasure(qreal stretch);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction computeTicks();
|
2012-05-26 14:26:10 +02:00
|
|
|
|
void layout2();
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-03-10 07:50:48 +01:00
|
|
|
|
bool showsMeasureNumber();
|
|
|
|
|
bool showsMeasureNumberInAutoMode();
|
2018-12-09 15:11:26 +01:00
|
|
|
|
void layoutMeasureNumber();
|
2021-02-04 14:13:07 +01:00
|
|
|
|
void layoutMMRestRange();
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Chord* findChord(Fraction tick, int track);
|
|
|
|
|
ChordRest* findChordRest(Fraction tick, int track);
|
2021-06-07 19:25:41 +02:00
|
|
|
|
Fraction snap(const Fraction& tick, const mu::PointF p) const;
|
|
|
|
|
Fraction snapNote(const Fraction& tick, const mu::PointF p, int staff) const;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-01-29 10:38:02 +01:00
|
|
|
|
Segment* searchSegment(qreal x, SegmentType st, int strack, int etrack, const Segment* preferredSegment = nullptr,
|
|
|
|
|
qreal spacingFactor = 0.5) const;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
|
void insertStaff(Staff*, int staff);
|
|
|
|
|
void insertMStaff(MStaff* staff, int idx);
|
|
|
|
|
void removeMStaff(MStaff* staff, int idx);
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-03-25 15:06:32 +01:00
|
|
|
|
void moveTicks(const Fraction& diff) override;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
|
void cmdRemoveStaves(int s, int e);
|
|
|
|
|
void cmdAddStaves(int s, int e, bool createRest);
|
|
|
|
|
void removeStaves(int s, int e);
|
|
|
|
|
void insertStaves(int s, int e);
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
qreal tick2pos(Fraction) const;
|
|
|
|
|
Segment* tick2segment(const Fraction& tick, SegmentType st = SegmentType::ChordRest);
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
|
void sortStaves(QList<int>& dst);
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-03-25 15:06:32 +01:00
|
|
|
|
bool acceptDrop(EditData&) const override;
|
2021-09-02 15:26:45 +02:00
|
|
|
|
EngravingItem* drop(EditData&) override;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
int repeatCount() const { return m_repeatCount; }
|
|
|
|
|
void setRepeatCount(int val) { m_repeatCount = val; }
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Segment* findSegmentR(SegmentType st, const Fraction&) const;
|
|
|
|
|
Segment* undoGetSegmentR(SegmentType st, const Fraction& f);
|
|
|
|
|
Segment* getSegmentR(SegmentType st, const Fraction& f);
|
|
|
|
|
Segment* findFirstR(SegmentType st, const Fraction& rtick) const;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
// segment routines with absolute tick values
|
|
|
|
|
Segment* findSegment(SegmentType st, const Fraction& f) const { return findSegmentR(st, f - tick()); }
|
|
|
|
|
Segment* undoGetSegment(SegmentType st, const Fraction& f) { return undoGetSegmentR(st, f - tick()); }
|
|
|
|
|
Segment* getSegment(SegmentType st, const Fraction& f) { return getSegmentR(st, f - tick()); }
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2019-07-06 14:35:18 +02:00
|
|
|
|
void connectTremolo();
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2016-01-04 14:48:58 +01:00
|
|
|
|
qreal createEndBarLines(bool);
|
2016-10-18 15:41:00 +02:00
|
|
|
|
void barLinesSetSpan(Segment*);
|
2021-07-23 00:14:12 +02:00
|
|
|
|
void setEndBarLineType(BarLineType val, int track, bool visible = true, mu::draw::Color color = mu::draw::Color());
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2021-09-02 15:26:45 +02:00
|
|
|
|
void scanElements(void* data, void (* func)(void*, EngravingItem*), bool all=true) override;
|
2012-05-26 14:26:10 +02:00
|
|
|
|
void createVoice(int track);
|
2017-03-24 17:31:25 +01:00
|
|
|
|
void adjustToLen(Fraction, bool appendRestsIfNecessary = true);
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2012-08-08 20:46:29 +02:00
|
|
|
|
AccidentalVal findAccidental(Note*) const;
|
2016-01-21 14:33:32 +01:00
|
|
|
|
AccidentalVal findAccidental(Segment* s, int staffIdx, int line, bool& error) const;
|
2014-08-29 10:35:17 +02:00
|
|
|
|
void exchangeVoice(int voice1, int voice2, int staffIdx);
|
2012-05-26 14:26:10 +02:00
|
|
|
|
void checkMultiVoices(int staffIdx);
|
|
|
|
|
bool hasVoice(int track) const;
|
2019-03-27 22:36:06 +01:00
|
|
|
|
bool isEmpty(int staffIdx) const;
|
2021-02-02 16:12:45 +01:00
|
|
|
|
bool isCutawayClef(int staffIdx) const;
|
2015-08-04 19:53:54 +02:00
|
|
|
|
bool isFullMeasureRest() const;
|
2012-05-26 14:26:10 +02:00
|
|
|
|
bool visible(int staffIdx) const;
|
2019-08-19 15:07:30 +02:00
|
|
|
|
bool stemless(int staffIdx) const;
|
2015-09-19 11:53:40 +02:00
|
|
|
|
bool isFinalMeasureOfSection() const;
|
2016-08-08 17:46:56 +02:00
|
|
|
|
bool isAnacrusis() const;
|
2020-03-26 15:41:36 +01:00
|
|
|
|
bool isFirstInSystem() const;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
bool breakMultiMeasureRest() const { return m_breakMultiMeasureRest; }
|
2020-08-28 18:54:57 +02:00
|
|
|
|
void setBreakMultiMeasureRest(bool val) { m_breakMultiMeasureRest = val; }
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2016-02-06 22:03:43 +01:00
|
|
|
|
bool empty() const;
|
2014-02-17 19:07:03 +01:00
|
|
|
|
bool isOnlyRests(int track) const;
|
2016-05-17 22:14:29 +02:00
|
|
|
|
bool isOnlyDeletedRests(int track) const;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
int playbackCount() const { return m_playbackCount; }
|
|
|
|
|
void setPlaybackCount(int val) { m_playbackCount = val; }
|
2021-06-07 19:25:41 +02:00
|
|
|
|
mu::RectF staffabbox(int staffIdx) const;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-03-25 15:06:32 +01:00
|
|
|
|
QVariant getProperty(Pid propertyId) const override;
|
|
|
|
|
bool setProperty(Pid propertyId, const QVariant&) override;
|
|
|
|
|
QVariant propertyDefault(Pid) const override;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
bool hasMMRest() const { return m_mmRest != 0; }
|
|
|
|
|
bool isMMRest() const { return m_mmRestCount > 0; }
|
|
|
|
|
Measure* mmRest() const { return m_mmRest; }
|
2015-01-19 12:37:17 +01:00
|
|
|
|
const Measure* mmRest1() const;
|
2020-08-28 22:55:29 +02:00
|
|
|
|
void setMMRest(Measure* m) { m_mmRest = m; }
|
2021-02-01 16:44:34 +01:00
|
|
|
|
int mmRestCount() const { return m_mmRestCount; } // number of measures m_mmRest spans
|
2020-08-28 22:55:29 +02:00
|
|
|
|
void setMMRestCount(int n) { m_mmRestCount = n; }
|
2013-10-30 14:21:08 +01:00
|
|
|
|
Measure* mmRestFirst() const;
|
|
|
|
|
Measure* mmRestLast() const;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
int measureRepeatCount(int staffIdx) const { return m_mstaves[staffIdx]->measureRepeatCount(); }
|
|
|
|
|
void setMeasureRepeatCount(int n, int staffIdx) { m_mstaves[staffIdx]->setMeasureRepeatCount(n); }
|
|
|
|
|
bool isMeasureRepeatGroup(int staffIdx) const { return measureRepeatCount(staffIdx); } // alias for convenience
|
|
|
|
|
bool isMeasureRepeatGroupWithNextM(int staffIdx) const;
|
|
|
|
|
bool isMeasureRepeatGroupWithPrevM(int staffIdx) const;
|
|
|
|
|
Measure* firstOfMeasureRepeatGroup(int staffIdx) const; // used to find beginning of group
|
|
|
|
|
MeasureRepeat* measureRepeatElement(int staffIdx) const; // get measure repeat element from anywhere within group
|
|
|
|
|
int measureRepeatNumMeasures(int staffIdx) const;
|
|
|
|
|
bool isOneMeasureRepeat(int staffIdx) const;
|
|
|
|
|
bool nextIsOneMeasureRepeat(int staffidx) const;
|
|
|
|
|
bool prevIsOneMeasureRepeat(int staffIdx) const;
|
|
|
|
|
|
2021-09-02 15:26:45 +02:00
|
|
|
|
EngravingItem* nextElementStaff(int staff);
|
|
|
|
|
EngravingItem* prevElementStaff(int staff);
|
2020-03-25 15:06:32 +01:00
|
|
|
|
QString accessibleInfo() const override;
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2016-10-18 15:41:00 +02:00
|
|
|
|
void addSystemHeader(bool firstSystem);
|
|
|
|
|
void addSystemTrailer(Measure* nm);
|
2016-10-25 17:30:55 +02:00
|
|
|
|
void removeSystemHeader();
|
|
|
|
|
void removeSystemTrailer();
|
2020-05-26 15:54:26 +02:00
|
|
|
|
|
2016-09-21 17:10:19 +02:00
|
|
|
|
const BarLine* endBarLine() const;
|
2016-04-18 09:46:30 +02:00
|
|
|
|
BarLineType endBarLineType() const;
|
2016-05-18 15:43:25 +02:00
|
|
|
|
bool endBarLineVisible() const;
|
2020-03-25 15:06:32 +01:00
|
|
|
|
void triggerLayout() const override;
|
2016-10-18 15:41:00 +02:00
|
|
|
|
qreal basicStretch() const;
|
|
|
|
|
qreal basicWidth() const;
|
2019-04-02 23:22:45 +02:00
|
|
|
|
int layoutWeight(int maxMMRestLength = 0) const;
|
2020-09-25 17:52:43 +02:00
|
|
|
|
void computeMinWidth() override;
|
2016-10-25 17:30:55 +02:00
|
|
|
|
void checkHeader();
|
|
|
|
|
void checkTrailer();
|
2016-10-31 10:55:11 +01:00
|
|
|
|
void setStretchedWidth(qreal);
|
2016-12-12 14:55:35 +01:00
|
|
|
|
void layoutStaffLines();
|
2020-08-28 18:54:57 +02:00
|
|
|
|
|
2021-09-08 08:23:00 +02:00
|
|
|
|
//! puts segments on the positions according to their length
|
|
|
|
|
void layoutSegmentsInPracticeMode(const std::vector<int>& visibleParts);
|
|
|
|
|
|
|
|
|
|
qreal computeFirstSegmentXPosition(Segment* segment);
|
|
|
|
|
|
|
|
|
|
void layoutSegmentsWithDuration(const std::vector<int>& visibleParts);
|
|
|
|
|
|
|
|
|
|
void calculateQuantumCell(const std::vector<int>& visibleParts);
|
|
|
|
|
|
|
|
|
|
Fraction quantumOfSegmentCell() const;
|
|
|
|
|
|
|
|
|
|
void stretchMeasureInPracticeMode(qreal stretch);
|
|
|
|
|
|
2020-08-28 18:54:57 +02:00
|
|
|
|
private:
|
2021-09-09 16:44:05 +02:00
|
|
|
|
|
|
|
|
|
friend class mu::engraving::Factory;
|
2021-09-21 13:39:16 +02:00
|
|
|
|
friend class mu::engraving::rw::MeasureRW;
|
|
|
|
|
|
2021-09-09 16:44:05 +02:00
|
|
|
|
Measure(System* parent = 0);
|
|
|
|
|
Measure(const Measure&);
|
|
|
|
|
|
2020-08-28 18:54:57 +02:00
|
|
|
|
void push_back(Segment* e);
|
|
|
|
|
void push_front(Segment* e);
|
|
|
|
|
|
2021-04-11 12:19:24 +02:00
|
|
|
|
void fillGap(const Fraction& pos, const Fraction& len, int track, const Fraction& stretch, bool useGapRests = true);
|
2020-08-28 18:54:57 +02:00
|
|
|
|
void computeMinWidth(Segment* s, qreal x, bool isSystemHeader);
|
|
|
|
|
|
|
|
|
|
MStaff* mstaff(int staffIndex) const;
|
2020-11-22 04:23:07 +01:00
|
|
|
|
|
2020-08-28 18:54:57 +02:00
|
|
|
|
std::vector<MStaff*> m_mstaves;
|
|
|
|
|
SegmentList m_segments;
|
2021-02-01 16:44:34 +01:00
|
|
|
|
Measure* m_mmRest; // multi measure rest which replaces a measure range
|
2020-08-28 18:54:57 +02:00
|
|
|
|
|
|
|
|
|
qreal m_userStretch;
|
|
|
|
|
|
|
|
|
|
Fraction m_timesig;
|
|
|
|
|
|
2021-02-01 16:44:34 +01:00
|
|
|
|
int m_mmRestCount; // > 0 if this is a multimeasure rest
|
|
|
|
|
// 0 if this is the start of am mmrest (m_mmRest != 0)
|
|
|
|
|
// < 0 if this measure is covered by an mmrest
|
2020-08-28 18:54:57 +02:00
|
|
|
|
|
2021-09-08 08:23:00 +02:00
|
|
|
|
int m_playbackCount = 0; // temp. value used in RepeatList
|
2020-08-28 18:54:57 +02:00
|
|
|
|
// counts how many times this measure was already played
|
|
|
|
|
|
2020-08-28 22:55:29 +02:00
|
|
|
|
int m_repeatCount; ///< end repeat marker and repeat count
|
2020-08-28 18:54:57 +02:00
|
|
|
|
|
|
|
|
|
MeasureNumberMode m_noMode;
|
|
|
|
|
bool m_breakMultiMeasureRest;
|
2021-09-08 08:23:00 +02:00
|
|
|
|
|
|
|
|
|
Fraction m_quantumOfSegmentCell = { 1, 16 };
|
2020-05-26 15:54:26 +02:00
|
|
|
|
};
|
2013-05-13 18:49:17 +02:00
|
|
|
|
} // namespace Ms
|
2012-05-26 14:26:10 +02:00
|
|
|
|
#endif
|