MuseScore/src/engraving/libmscore/stafflines.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

222 lines
6.6 KiB
C++
Raw Normal View History

/*
* 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/>.
*/
2016-12-23 12:05:18 +01:00
#include "stafflines.h"
#include "system.h"
#include "measure.h"
#include "score.h"
#include "stafftype.h"
#include "staff.h"
2021-06-07 19:25:41 +02:00
using namespace mu;
2016-12-23 12:05:18 +01:00
// Anatomy of StaffLines:
//
// step - The possible vertical positions of a note are counted as steps.
// The top staff line is step position zero.
// lines - number of visible staff lines
// lineDistance - The distance between lines, measured in step units. A standard five line
// staff has a line distance of two steps.
// stepDistance - The distance between steps measured in scaled spatium/2 units. A standard five
// line staff has a step distance of 0.5 which results in a line distance of
// one spatium. The spatium unit is scaled by staff size.
// yoffset - vertical offset to align with other staves of different height
// stepOffset - This value changes the staff line step numbering.
//
namespace Ms {
//---------------------------------------------------------
// StaffLines
//---------------------------------------------------------
2020-05-29 18:47:27 +02:00
StaffLines::StaffLines(Score* s)
: Element(s)
2016-12-23 12:05:18 +01:00
{
setSelectable(false);
}
//---------------------------------------------------------
// pagePos
//---------------------------------------------------------
2021-06-07 19:25:41 +02:00
PointF StaffLines::pagePos() const
2016-12-23 12:05:18 +01:00
{
System* system = measure()->system();
2021-06-07 19:25:41 +02:00
return PointF(measure()->x() + system->x(), system->staff(staffIdx())->y() + system->y());
2016-12-23 12:05:18 +01:00
}
//---------------------------------------------------------
// canvasPos
//---------------------------------------------------------
2021-06-07 19:25:41 +02:00
PointF StaffLines::canvasPos() const
2016-12-23 12:05:18 +01:00
{
2021-06-07 19:25:41 +02:00
PointF p(pagePos());
2016-12-23 12:05:18 +01:00
Element* e = parent();
while (e) {
2017-01-18 14:16:33 +01:00
if (e->type() == ElementType::PAGE) {
2016-12-23 12:05:18 +01:00
p += e->pos();
break;
}
e = e->parent();
}
return p;
}
//---------------------------------------------------------
// layout
//---------------------------------------------------------
void StaffLines::layout()
{
layoutForWidth(measure()->width());
}
//---------------------------------------------------------
// layoutForWidth
//---------------------------------------------------------
void StaffLines::layoutForWidth(qreal w)
2016-12-23 12:05:18 +01:00
{
const Staff* s = staff();
2016-12-23 12:05:18 +01:00
qreal _spatium = spatium();
2017-12-15 10:37:37 +01:00
qreal dist = _spatium;
2021-06-07 19:25:41 +02:00
setPos(PointF(0.0, 0.0));
2016-12-23 12:05:18 +01:00
int _lines;
if (s) {
setMag(s->staffMag(measure()->tick()));
setVisible(!s->invisible(measure()->tick()));
setColor(s->color(measure()->tick()));
const StaffType* st = s->staffType(measure()->tick());
2016-12-23 12:05:18 +01:00
dist *= st->lineDistance().val();
_lines = st->lines();
rypos() = st->yoffset().val() * _spatium;
// if (_lines == 1)
// rypos() = 2 * _spatium;
2016-12-23 12:05:18 +01:00
} else {
_lines = 5;
setColor(MScore::defaultColor);
}
lw = score()->styleS(Sid::staffLineWidth).val() * _spatium;
2016-12-23 12:05:18 +01:00
qreal x1 = pos().x();
qreal x2 = x1 + w;
qreal y = pos().y();
2017-12-15 10:37:37 +01:00
bbox().setRect(x1, -lw * .5 + y, w, (_lines - 1) * dist + lw);
2020-05-26 15:54:26 +02:00
if (_lines == 1) {
qreal extraSize = _spatium;
bbox().adjust(0, -extraSize, 0, extraSize);
} else if (_lines == 0) {
bbox().adjust(0, -2 * dist, 0, 2 * dist);
}
2020-05-26 15:54:26 +02:00
2016-12-23 12:05:18 +01:00
lines.clear();
for (int i = 0; i < _lines; ++i) {
lines.push_back(LineF(x1, y, x2, y));
2016-12-23 12:05:18 +01:00
y += dist;
}
}
//---------------------------------------------------------
// layoutPartialWidth
/// Layout staff lines for the specified width only, aligned
/// to the left or right of the measure
//---------------------------------------------------------
void StaffLines::layoutPartialWidth(qreal w, qreal wPartial, bool alignRight)
{
const Staff* s = staff();
qreal _spatium = spatium();
wPartial *= spatium();
qreal dist = _spatium;
2021-06-07 19:25:41 +02:00
setPos(PointF(0.0, 0.0));
int _lines;
if (s) {
setMag(s->staffMag(measure()->tick()));
setColor(s->color(measure()->tick()));
const StaffType* st = s->staffType(measure()->tick());
dist *= st->lineDistance().val();
_lines = st->lines();
rypos() = st->yoffset().val() * _spatium;
} else {
_lines = 5;
setColor(MScore::defaultColor);
}
lw = score()->styleS(Sid::staffLineWidth).val() * _spatium;
qreal x1 = pos().x();
qreal x2 = x1 + w;
qreal y = pos().y();
bbox().setRect(x1, -lw * .5 + y, w, (_lines - 1) * dist + lw);
if (_lines == 1) {
qreal extraSize = _spatium;
bbox().adjust(0, -extraSize, 0, extraSize);
}
lines.clear();
for (int i = 0; i < _lines; ++i) {
if (alignRight) {
lines.push_back(LineF(x2 - wPartial, y, x2, y));
} else {
lines.push_back(LineF(x1, y, x1 + wPartial, y));
}
y += dist;
2016-12-23 12:05:18 +01:00
}
}
//---------------------------------------------------------
// draw
//---------------------------------------------------------
void StaffLines::draw(mu::draw::Painter* painter) const
2016-12-23 12:05:18 +01:00
{
2021-03-09 13:27:51 +01:00
TRACE_OBJ_DRAW;
2021-06-29 23:42:51 +02:00
using namespace mu::draw;
painter->setPen(Pen(curColor(), lw, PenStyle::SolidLine, PenCapStyle::FlatCap));
2016-12-23 12:05:18 +01:00
painter->drawLines(lines);
}
//---------------------------------------------------------
// y1
//---------------------------------------------------------
qreal StaffLines::y1() const
{
System* system = measure()->system();
/* if (system == 0 || staffIdx() >= system->staves()->size())
return 0.0;
*/
return system->staff(staffIdx())->y() + ipos().y();
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void StaffLines::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (all || (measure()->visible(staffIdx()) && score()->staff(staffIdx())->show())) {
func(data, this);
}
}
2016-12-23 12:05:18 +01:00
}