update continuous view

This commit is contained in:
ws 2016-05-18 15:43:47 +02:00
parent 26e443c8f0
commit b448ab9c30
18 changed files with 334 additions and 614 deletions

View file

@ -44,7 +44,7 @@ add_library (
harmony.cpp hook.cpp image.cpp iname.cpp instrchange.cpp
instrtemplate.cpp instrument.cpp interval.cpp
key.cpp keyfinder.cpp keysig.cpp lasso.cpp
layoutbreak.cpp layout.cpp layoutLinear.cpp line.cpp lyrics.cpp measurebase.cpp
layoutbreak.cpp layout.cpp line.cpp lyrics.cpp measurebase.cpp
measure.cpp navigate.cpp note.cpp noteevent.cpp ottava.cpp
page.cpp part.cpp pedal.cpp pitch.cpp pitchspelling.cpp
rendermidi.cpp repeat.cpp repeatlist.cpp rest.cpp

View file

@ -122,7 +122,7 @@ class VBox : public Box {
public:
VBox(Score* score);
virtual ~VBox() {}
virtual VBox* clone() const override { return new VBox(*this); }
virtual VBox* clone() const override { return new VBox(*this); }
virtual Element::Type type() const override { return Element::Type::VBOX; }
virtual void layout() override;

View file

@ -312,8 +312,6 @@ void Clef::layout()
// clefs are right aligned to Segment
// qreal clefKeyRightMargin = score()->styleS(StyleIdx::clefKeyRightMargin).val() * _spatium;
// QPointF off(-r.right() - clefKeyRightMargin, 0);
QPointF off(-r.right(), 0);
for (Element* e : elements)
e->move(off);

View file

@ -76,6 +76,7 @@ class Beam;
class Hook;
class StemSlash;
class Spacer;
class StaffLines;
enum class SymId;
@ -415,6 +416,7 @@ class Element : public QObject, public ScoreElement {
virtual int subtype() const { return -1; } // for select gui
virtual void draw(QPainter*) const {}
void drawAt(QPainter*p, const QPointF& pt) const { p->translate(pt); draw(p); p->translate(-pt);}
virtual void writeProperties(Xml& xml) const;
virtual bool readProperties(XmlReader&);
@ -666,6 +668,7 @@ class Element : public QObject, public ScoreElement {
CONVERT(StemSlash, STEM_SLASH);
CONVERT(SlurSegment, SLUR_SEGMENT);
CONVERT(Spacer, SPACER);
CONVERT(StaffLines, STAFF_LINES);
#undef CONVERT
};
@ -729,6 +732,7 @@ static inline const a* to##a(const Element* e) { Q_ASSERT(e == 0 || e->type() ==
CONVERT(StemSlash, STEM_SLASH);
CONVERT(SlurSegment, SLUR_SEGMENT);
CONVERT(Spacer, SPACER);
CONVERT(StaffLines, STAFF_LINES);
#undef CONVERT
//---------------------------------------------------------

View file

@ -2533,7 +2533,17 @@ void Score::getNextMeasure(LayoutContext& lc)
int mno = lc.adjustMeasureNo(lc.curMeasure);
if (lc.curMeasure->isMeasure() && score()->styleB(StyleIdx::createMultiMeasureRests)) {
bool lineMode = _layoutMode == LayoutMode::LINE;
if (lineMode) {
while (lc.curMeasure && lc.curMeasure->isVBox()) {
lc.curMeasure = lc.nextMeasure;
lc.nextMeasure = lc.curMeasure->next();
}
if (!lc.curMeasure)
return;
}
else if (lc.curMeasure->isMeasure() && score()->styleB(StyleIdx::createMultiMeasureRests)) {
Measure* m = toMeasure(lc.curMeasure);
Measure* nm = m;
Measure* lm = nm;
@ -2930,9 +2940,10 @@ System* Score::collectSystem(LayoutContext& lc)
qreal minMeasureWidth = styleP(StyleIdx::minMeasureWidth);
qreal minWidth = system->leftMargin();
Measure* firstMeasure = 0;
bool firstMeasure = true;
qreal measureSpacing = styleD(StyleIdx::measureSpacing);
qreal systemWidth = pageFormat()->printableWidth() * DPI;
bool lineMode = _layoutMode == LayoutMode::LINE;
while (lc.curMeasure) { // collect measure for system
System* oldSystem = lc.curMeasure->system();
@ -2947,8 +2958,8 @@ System* Score::collectSystem(LayoutContext& lc)
else if (lc.curMeasure->isMeasure()) {
Measure* m = toMeasure(lc.curMeasure);
if (!firstMeasure) {
firstMeasure = m;
if (firstMeasure) {
firstMeasure = false;
addSystemHeader(m, lc.firstSystem);
ww = computeMinWidth(m->first(), true);
}
@ -2980,7 +2991,7 @@ System* Score::collectSystem(LayoutContext& lc)
// check if lc.curMeasure fits, remove if not
// collect at least one measure
if ((system->measures().size() > 1) && (minWidth + ww > systemWidth)) {
if (!lineMode && (system->measures().size() > 1) && (minWidth + ww > systemWidth)) {
system->measures().pop_back();
lc.curMeasure->setSystem(oldSystem);
break;
@ -3023,8 +3034,9 @@ System* Score::collectSystem(LayoutContext& lc)
minWidth += ww;
Element::Type nt = lc.curMeasure ? lc.curMeasure->type() : Element::Type::INVALID;
if (pbreak || nt == Element::Type::VBOX || nt == Element::Type::TBOX || nt == Element::Type::FBOX
|| (minWidth + minMeasureWidth > systemWidth)) {
if (!lineMode
&& (pbreak || nt == Element::Type::VBOX || nt == Element::Type::TBOX || nt == Element::Type::FBOX
|| (minWidth + minMeasureWidth > systemWidth))) {
break; // break system
}
@ -3046,114 +3058,115 @@ System* Score::collectSystem(LayoutContext& lc)
if (lc.curMeasure == 0 && ((minWidth / systemWidth) <= styleD(StyleIdx::lastSystemFillLimit)))
raggedRight = true;
//-------------------------------------------------------
// add cautionary time/key signatures if needed
//-------------------------------------------------------
if (!lineMode) {
//-------------------------------------------------------
// add cautionary time/key signatures if needed
//-------------------------------------------------------
Measure* m = system->lastMeasure();
Measure* nm = m ? m->nextMeasure() : 0;
Segment* s;
if (m && nm) {
m->setHasSystemTrailer(false);
int tick = m->endTick();
bool isFinalMeasureOfSection = m->isFinalMeasureOfSection();
// locate a time sig. in the next measure and, if found,
// check if it has court. sig. turned off
TimeSig* ts;
Segment* tss = nm->findSegment(Segment::Type::TimeSig, tick);
bool showCourtesySig = tss && styleB(StyleIdx::genCourtesyTimesig) && !(isFinalMeasureOfSection && _layoutMode != LayoutMode::FLOAT);
if (showCourtesySig) {
ts = toTimeSig(tss->element(0));
if (ts && !ts->showCourtesySig())
showCourtesySig = false; // this key change has court. sig turned off
}
if (showCourtesySig) {
// if due, create a new courtesy time signature for each staff
m->setHasSystemTrailer(true);
s = m->undoGetSegment(Segment::Type::TimeSigAnnounce, tick);
int nstaves = Score::nstaves();
for (int track = 0; track < nstaves * VOICES; track += VOICES) {
TimeSig* nts = toTimeSig(tss->element(track));
if (!nts)
continue;
ts = toTimeSig(s->element(track));
if (!ts) {
ts = new TimeSig(this);
ts->setTrack(track);
ts->setGenerated(true);
ts->setParent(s);
undoAddElement(ts);
ts->layout();
s->createShape(track / VOICES);
}
ts->setFrom(nts);
}
}
else {
// remove any existing time signatures
Segment* tss = m->findSegment(Segment::Type::TimeSigAnnounce, tick);
if (tss)
undoRemoveElement(tss);
}
// courtesy key signatures
int n = _staves.size();
bool show = m->hasCourtesyKeySig();
Measure* m = system->lastMeasure();
Measure* nm = m ? m->nextMeasure() : 0;
Segment* s;
if (show)
s = m->undoGetSegment(Segment::Type::KeySigAnnounce, tick);
else
s = m->findSegment(Segment::Type::KeySigAnnounce, tick);
Segment* clefSegment = m->findSegment(Segment::Type::Clef, tick);
if (m && nm) {
m->setHasSystemTrailer(false);
int tick = m->endTick();
bool isFinalMeasureOfSection = m->isFinalMeasureOfSection();
for (int staffIdx = 0; staffIdx < n; ++staffIdx) {
int track = staffIdx * VOICES;
Staff* staff = _staves[staffIdx];
// locate a time sig. in the next measure and, if found,
// check if it has court. sig. turned off
TimeSig* ts;
Segment* tss = nm->findSegment(Segment::Type::TimeSig, tick);
bool showCourtesySig = tss && styleB(StyleIdx::genCourtesyTimesig) && !(isFinalMeasureOfSection && _layoutMode != LayoutMode::FLOAT);
if (show) {
if (showCourtesySig) {
ts = toTimeSig(tss->element(0));
if (ts && !ts->showCourtesySig())
showCourtesySig = false; // this key change has court. sig turned off
}
if (showCourtesySig) {
// if due, create a new courtesy time signature for each staff
m->setHasSystemTrailer(true);
KeySig* ks = toKeySig(s->element(track));
KeySigEvent key2 = staff->keySigEvent(tick);
if (!ks) {
ks = new KeySig(this);
ks->setKeySigEvent(key2);
ks->setTrack(track);
ks->setGenerated(true);
ks->setParent(s);
undoAddElement(ks);
s = m->undoGetSegment(Segment::Type::TimeSigAnnounce, tick);
int nstaves = Score::nstaves();
for (int track = 0; track < nstaves * VOICES; track += VOICES) {
TimeSig* nts = toTimeSig(tss->element(track));
if (!nts)
continue;
ts = toTimeSig(s->element(track));
if (!ts) {
ts = new TimeSig(this);
ts->setTrack(track);
ts->setGenerated(true);
ts->setParent(s);
undoAddElement(ts);
ts->layout();
s->createShape(track / VOICES);
}
ts->setFrom(nts);
}
else if (!(ks->keySigEvent() == key2)) {
undo(new ChangeKeySig(ks, key2, ks->showCourtesy()));
}
ks->layout();
s->createShape(track / VOICES);
}
else {
// remove any existent courtesy key signature
if (s && s->element(track))
undoRemoveElement(s->element(track));
// remove any existing time signatures
Segment* tss = m->findSegment(Segment::Type::TimeSigAnnounce, tick);
if (tss)
undoRemoveElement(tss);
}
if (clefSegment) {
Clef* clef = toClef(clefSegment->element(track));
if (clef && (!score()->styleB(StyleIdx::genCourtesyClef)
|| m->repeatEnd() || m->isFinalMeasureOfSection()
|| !clef->showCourtesy())) {
clef->clear(); // make invisible
// courtesy key signatures
int n = _staves.size();
bool show = m->hasCourtesyKeySig();
Segment* s;
if (show)
s = m->undoGetSegment(Segment::Type::KeySigAnnounce, tick);
else
s = m->findSegment(Segment::Type::KeySigAnnounce, tick);
Segment* clefSegment = m->findSegment(Segment::Type::Clef, tick);
for (int staffIdx = 0; staffIdx < n; ++staffIdx) {
int track = staffIdx * VOICES;
Staff* staff = _staves[staffIdx];
if (show) {
m->setHasSystemTrailer(true);
KeySig* ks = toKeySig(s->element(track));
KeySigEvent key2 = staff->keySigEvent(tick);
if (!ks) {
ks = new KeySig(this);
ks->setKeySigEvent(key2);
ks->setTrack(track);
ks->setGenerated(true);
ks->setParent(s);
undoAddElement(ks);
}
else if (!(ks->keySigEvent() == key2)) {
undo(new ChangeKeySig(ks, key2, ks->showCourtesy()));
}
ks->layout();
s->createShape(track / VOICES);
}
else {
// remove any existent courtesy key signature
if (s && s->element(track))
undoRemoveElement(s->element(track));
}
if (clefSegment) {
Clef* clef = toClef(clefSegment->element(track));
if (clef && (!score()->styleB(StyleIdx::genCourtesyClef)
|| m->repeatEnd() || m->isFinalMeasureOfSection()
|| !clef->showCourtesy())) {
clef->clear(); // make invisible
}
}
}
//HACK to layout cautionary elements:
if (m->hasSystemTrailer())
computeMinWidth(m->first(), false);
}
//HACK to layout cautionary elements:
if (m->hasSystemTrailer())
computeMinWidth(m->first(), false);
system->setWidth(systemWidth);
}
system->setWidth(systemWidth);
minWidth = system->leftMargin();
qreal totalWeight = 0.0;
for (MeasureBase* mb : system->measures()) {
@ -3193,10 +3206,14 @@ System* Score::collectSystem(LayoutContext& lc)
qreal stretch = m->userStretch();
if (stretch < 1.0)
stretch = 1.0;
ww = m->width() + rest * m->ticks() * stretch;
for (MStaff* ms : m->mstaves())
ms->lines->layout();
m->stretchMeasure(ww);
if (!lineMode) {
ww = m->width() + rest * m->ticks() * stretch;
m->stretchMeasure(ww);
}
else
ww = m->width();
}
else if (mb->isHBox()) {
mb->setPos(pos);
@ -3208,6 +3225,8 @@ System* Score::collectSystem(LayoutContext& lc)
}
pos.rx() += ww;
}
if (lineMode)
system->setWidth(pos.x());
// layout beams and update the segment shape
for (MeasureBase* mb : system->measures()) {
@ -3240,69 +3259,6 @@ System* Score::collectSystem(LayoutContext& lc)
return system;
}
#if 0
//---------------------------------------------------------
// relayoutPage
//---------------------------------------------------------
static void relayoutPage(Page* page)
{
qreal y = page->tm();
qreal ey = page->height() - page->bm();
Score* score = page->score();
const qreal slb = score->styleP(StyleIdx::staffLowerBorder);
const qreal sub = score->styleP(StyleIdx::staffUpperBorder);
QList<System*>& sl = page->systems();
auto li = sl.begin();
System* s1 = 0;
System* s2 = *li++;
for (;;) {
//
// calculate distance to previous system
//
qreal distance;
if (s1)
distance = s1->minDistance(s2);
else {
// this is the first system on page
VBox* vbox = s2->vbox();
distance = vbox ? vbox->topGap() : sub;
distance = qMax(distance, -s2->minTop());
}
y += distance;
s2->setPos(page->lm(), y);
y += s2->height();
//
// check for page break or if next system will fit on page
//
if (li != sl.end()) {
System* s3 = *li++;
qreal dist = s2->minDistance(s3) + s3->height();
VBox* vbox = s3->vbox();
if (vbox)
dist += vbox->bottomGap();
else
dist += qMax(s3->minBottom(), slb);
s1 = s2; // current system becomes previous
s2 = s3; // next system becomes current
}
else {
VBox* vbox = s2->vbox();
qreal dist = vbox ? vbox->bottomGap() : qMax(s2->minBottom(), slb);
layoutPage(page, ey - (y + dist));
break;
}
}
page->rebuildBspTree();
}
#endif
//---------------------------------------------------------
// collectPage
//---------------------------------------------------------
@ -3474,13 +3430,6 @@ bool Score::collectPage(LayoutContext& lc)
void Score::doLayout()
{
#if 0
static int mops= 0;
++mops;
if (mops == 1)
abort();
#endif
qDebug();
if (_staves.empty() || first() == 0) {
@ -3510,15 +3459,13 @@ void Score::doLayout()
getNextMeasure(lc);
getNextMeasure(lc);
collectSystem(lc);
while (collectPage(lc))
;
if (_layoutMode == LayoutMode::LINE) {
while (lc.curMeasure->isVBox())
getNextMeasure(lc);
layoutLinear(lc);
}
else {
collectSystem(lc);
while (collectPage(lc))
;
Page* page = _pages[0];
System* system = page->system(0);
page->setWidth(system->width());
}
// TODO: remove remaining systems from lc.systemList
@ -3548,6 +3495,7 @@ void Score::doLayoutRange(int stick, int etick)
qDebug(" %d-%d systems %d", stick, etick, _systems.size());
LayoutContext lc;
#if 0
if (_layoutMode == LayoutMode::LINE) {
_systems.swap(lc.systemList);
getNextMeasure(lc);
@ -3555,6 +3503,7 @@ void Score::doLayoutRange(int stick, int etick)
layoutLinear(lc);
return;
}
#endif
lc.rangeLayout = true;
lc.rangeDone = false;

View file

@ -1,158 +0,0 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2016 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#include "accidental.h"
#include "barline.h"
#include "beam.h"
#include "box.h"
#include "chord.h"
#include "clef.h"
#include "element.h"
#include "fingering.h"
#include "glissando.h"
#include "harmony.h"
#include "key.h"
#include "keysig.h"
#include "layoutbreak.h"
#include "layout.h"
#include "lyrics.h"
#include "marker.h"
#include "measure.h"
#include "mscore.h"
#include "notedot.h"
#include "note.h"
#include "ottava.h"
#include "page.h"
#include "part.h"
#include "repeat.h"
#include "score.h"
#include "segment.h"
#include "sig.h"
#include "slur.h"
#include "staff.h"
#include "stem.h"
#include "style.h"
#include "sym.h"
#include "system.h"
#include "text.h"
#include "tie.h"
#include "timesig.h"
#include "tremolo.h"
#include "tuplet.h"
#include "undo.h"
#include "utils.h"
#include "volta.h"
#include "breath.h"
#include "tempotext.h"
#include "systemdivider.h"
namespace Ms {
//---------------------------------------------------------
// layoutLinear
//---------------------------------------------------------
void Score::layoutLinear(LayoutContext& lc)
{
System* system = getNextSystem(lc);
system->setInstrumentNames(true);
qreal xo;
if (lc.curMeasure->isHBox())
xo = point(toHBox(lc.curMeasure)->boxWidth());
else
xo = 0;
system->layoutSystem(xo);
system->setPos(0.0, spatium() * 10.0);
Page* page = getEmptyPage(lc);
page->appendSystem(system);
for (MeasureBase* mb = first(); mb; mb = mb->next()) {
Element::Type t = mb->type();
if (t == Element::Type::VBOX || t == Element::Type::TBOX || t == Element::Type::FBOX)
continue;
if (styleB(StyleIdx::createMultiMeasureRests) && mb->type() == Element::Type::MEASURE) {
Measure* m = static_cast<Measure*>(mb);
if (m->hasMMRest())
mb = m->mmRest();
}
mb->setSystem(system);
system->measures().push_back(mb);
}
if (system->measures().empty())
return;
addSystemHeader(firstMeasureMM(), true);
// also add a system header after a section break
for (Measure* m = firstMeasureMM(); m; m = m->nextMeasureMM()) {
if (m->sectionBreak() && m->nextMeasureMM())
addSystemHeader(m->nextMeasureMM(), true);
}
QPointF pos(0.0, 0.0);
bool isFirstMeasure = true;
qreal minMeasureWidth = point(styleS(StyleIdx::minMeasureWidth));
foreach (MeasureBase* mb, system->measures()) {
qreal w = 0.0;
if (mb->type() == Element::Type::MEASURE) {
Measure* m = static_cast<Measure*>(mb);
Measure* nm = m->nextMeasure();
bool lastMeasureInSystem = nm == 0;
m->createEndBarLines(lastMeasureInSystem);
if (isFirstMeasure) {
pos.rx() += system->leftMargin();
// width with header
qreal w2 = computeMinWidth(m->first(), isFirstMeasure);
// width *completely* excluding header
// minWidth1() includes the initial key / time signatures since they are considered non-generated
Segment* s = m->first();
while (s && s->segmentType() != Segment::Type::ChordRest)
s = s->next();
qreal w1 = s ? computeMinWidth(s, false) : m->minWidth1();
w = (w2 - w1) + w1 * styleD(StyleIdx::linearStretch);
}
else {
m->removeSystemHeader();
w = computeMinWidth(m->first(), false) * styleD(StyleIdx::linearStretch);
}
if (w < minMeasureWidth)
w = minMeasureWidth;
m->stretchMeasure(w);
isFirstMeasure = false;
}
else {
mb->layout();
w = mb->width();
}
mb->setPos(pos);
pos.rx() += w;
}
system->setWidth(pos.x());
page->setWidth(pos.x());
system->layout2();
for (MeasureBase* mb : system->measures()) {
if (!mb->isMeasure())
continue;
Measure* m = toMeasure(mb);
m->layout2();
}
page->setHeight(system->height() + 20 * spatium());
page->rebuildBspTree();
}
} // namespace Ms

View file

@ -232,7 +232,7 @@ static const PropertyData propertyList[] = {
{ P_ID::GLISSANDO_STYLE, false, "glissandoStyle", P_TYPE::GLISSANDO_STYLE},
{ P_ID::LAYOUT_MODE, false, 0, P_TYPE::INT },
// { P_ID::LAYOUT_MODE, false, 0, P_TYPE::INT },
{ P_ID::FRET_STRINGS, false, "strings", P_TYPE::INT },
{ P_ID::FRET_FRETS, false, "frets", P_TYPE::INT },

View file

@ -237,7 +237,7 @@ enum class P_ID : unsigned char {
GLISSANDO_STYLE,
LAYOUT_MODE,
// LAYOUT_MODE,
FRET_STRINGS,
FRET_FRETS,

View file

@ -3936,20 +3936,6 @@ void Score::cropPage(qreal margins)
}
}
//---------------------------------------------------------
// switchToPageMode
// switch to layout mode PAGE
//---------------------------------------------------------
void Score::switchToPageMode()
{
if (layoutMode() != LayoutMode::PAGE) {
startCmd();
ScoreElement::undoChangeProperty(P_ID::LAYOUT_MODE, int(LayoutMode::PAGE));
doLayout();
}
}
//---------------------------------------------------------
// getProperty
//---------------------------------------------------------
@ -3957,8 +3943,8 @@ void Score::switchToPageMode()
QVariant Score::getProperty(P_ID id) const
{
switch (id) {
case P_ID::LAYOUT_MODE:
return QVariant(static_cast<int>(_layoutMode));
// case P_ID::LAYOUT_MODE:
// return QVariant(static_cast<int>(_layoutMode));
default:
qDebug("Score::getProperty: unhandled id");
return QVariant();
@ -3972,14 +3958,14 @@ QVariant Score::getProperty(P_ID id) const
bool Score::setProperty(P_ID id, const QVariant& v)
{
switch (id) {
case P_ID::LAYOUT_MODE:
setLayoutMode(LayoutMode(v.toInt()));
// case P_ID::LAYOUT_MODE:
// setLayoutMode(LayoutMode(v.toInt()));
break;
default:
qDebug("Score::setProperty: unhandled id");
break;
}
score()->setLayoutAll();
setLayoutAll();
return true;
}
@ -3990,8 +3976,8 @@ bool Score::setProperty(P_ID id, const QVariant& v)
QVariant Score::propertyDefault(P_ID id) const
{
switch (id) {
case P_ID::LAYOUT_MODE:
return static_cast<int>(LayoutMode::PAGE);
// case P_ID::LAYOUT_MODE:
// return static_cast<int>(LayoutMode::PAGE);
default:
return QVariant();
}

View file

@ -1074,8 +1074,6 @@ class Score : public QObject, public ScoreElement {
bool checkKeys();
bool checkClefs();
void switchToPageMode();
QFileInfo* fileInfo() { return &info; }
const QFileInfo* fileInfo() const { return &info; }
void setName(const QString& s);

View file

@ -477,8 +477,10 @@ void Score::saveCompressedFile(QFileInfo& info, bool onlySelection)
QImage Score::createThumbnail()
{
LayoutMode layoutMode = _layoutMode;
switchToPageMode();
LayoutMode mode = layoutMode();
setLayoutMode(LayoutMode::PAGE);
doLayout();
Page* page = pages().at(0);
QRectF fr = page->abbox();
qreal mag = 256.0 / qMax(fr.width(), fr.height());
@ -495,8 +497,10 @@ QImage Score::createThumbnail()
p.scale(mag, mag);
print(&p, 0);
p.end();
if (layoutMode != _layoutMode)
endCmd(true); // rollback
if (layoutMode() != mode) {
setLayoutMode(mode);
doLayout();
}
return pm;
}

View file

@ -39,58 +39,41 @@ ContinuousPanel::ContinuousPanel(ScoreView* sv)
_active = true;
_visible = false;
_width = 0.0;
_oldWidth = 0.0;
_newWidth = 0.0;
_measureWidth = 0.0;
_height = 0.0;
_offsetPanel = 0.0;
_x = 0.0;
_y = 0.0;
_widthClef = 0.0;
_widthKeySig = 0.0;
_widthTimeSig = 0.0;
_leftMarginTotal = 0.0;
_panelRightPadding = 5;
_xPosTimeSig = 0.0;
_currentMeasure = nullptr;
_currentMeasureTick = 0;
_currentMeasureNo = 0;
_mmRestCount = 0;
_xPosMeasure = 0;
}
//---------------------------------------------------------
// paintContinousPanel
//---------------------------------------------------------
void ContinuousPanel::paint(const QRect& /*r*/, QPainter& p)
void ContinuousPanel::paint(const QRect&, QPainter& painter)
{
if (!_active) {
_visible = false;
return;
}
qreal _offsetPanel = 0;
qreal _y = 0;
qreal _oldWidth = 0; // The last final panel width
qreal _newWidth = 0; // New panel width
qreal _height = 0;
qreal _leftMarginTotal = 0; // Sum of all elments left margin
qreal _panelRightPadding = 5; // Extra space for the panel after last element
Measure* measure = _score->tick2measure(0);
if (measure == 0){
Measure* measure = _score->firstMeasure();
if (!_active || !measure) {
_visible = false;
return;
}
if (measure->mmRest()) {
measure = measure->mmRest();
_mmRestCount = measure->mmRestCount();
}
System* system = measure->system();
if (system == 0) {
_visible = false;
return;
}
System* system = measure->system();
if (system == 0) {
_visible = false;
return;
}
Segment* s = _score->tick2segment(0);
Segment* s = measure->first();
double _spatium = _score->spatium();
_x = 0;
if (_width <= 0)
_width = s->x();
@ -113,81 +96,55 @@ void ContinuousPanel::paint(const QRect& /*r*/, QPainter& p)
// Check elements at current panel position
//
_offsetPanel = -(_sv->xoffset()) / _sv->mag();
_rect = QRect(_offsetPanel + _width, _y, 1, _height);
//qDebug() << "width=" << _width << "_y="<< _y << "_offsetPanel=" << _offsetPanel << "_sv->xoffset()" << _sv->xoffset() << "_sv->mag()" << _sv->mag() <<"_spatium" << _spatium << "s->canvasPos().x()" << s->canvasPos().x() << "s->x()" << s->x();
Page* page = _score->pages().front();
QList<Element*> elementsCurrent = page->items(_rect);
if (elementsCurrent.empty()) {
_rect = QRect(_offsetPanel + _width, _y, 1, _height);
Page* page = _score->pages().front();
QList<Element*> el = page->items(_rect);
if (el.empty()) {
_visible = false;
return;
}
qStableSort(elementsCurrent.begin(), elementsCurrent.end(), elementLessThan);
qStableSort(el.begin(), el.end(), elementLessThan);
_currentMeasure = nullptr;
for (const Element* e : elementsCurrent) {
const Measure*_currentMeasure = 0;
for (const Element* e : el) {
e->itemDiscovered = 0;
if (!e->visible()) {
if (_score->printing() || !_score->showInvisible())
continue;
}
if (!e->visible() && !_score->showInvisible())
continue;
if (e->type() == Element::Type::MEASURE) {
_currentMeasure = static_cast<const Measure*>(e);
_currentTimeSig = _currentMeasure->timesig();
_currentMeasureTick = _currentMeasure->tick();
_currentMeasureNo = _currentMeasure->no();
// Find number of multi measure rests to display in the panel
if (_currentMeasure->isMMRest())
_mmRestCount = _currentMeasure->mmRestCount();
else if (_currentMeasure->mmRest())
_mmRestCount = _currentMeasure->mmRest()->mmRestCount();
else
_mmRestCount = 0;
_xPosMeasure = e->canvasX();
_measureWidth = e->width();
if (e->isMeasure()) {
_currentMeasure = toMeasure(e);
break;
}
}
if (_currentMeasure == nullptr)
if (!_currentMeasure)
return;
findElementWidths(elementsCurrent);
qreal _xPosMeasure = _currentMeasure->canvasX();
qreal _measureWidth = _currentMeasure->width();
int tick = _currentMeasure->tick();
Fraction _currentTimeSig = _currentMeasure->timesig();
// Don't show panel if staff names are visible
if (_sv->xoffset() / _sv->mag() + _xPosMeasure > 0) {
_visible = false;
return;
}
//qDebug() << "_sv->xoffset()=" <<_sv->xoffset() << " _sv->mag()="<< _sv->mag() <<" s->x=" << s->x() << " width=" << _width << " currentMeasue=" << _currentMeasure->x() << " _xPosMeasure=" << _xPosMeasure;
//---------------------------------------------------------
// findElementWidths
// determines the max width for each element types
//---------------------------------------------------------
draw(p, elementsCurrent);
_visible = true;
}
//---------------------------------------------------------
// findElementWidths
// determines the max width for each element types
//---------------------------------------------------------
void ContinuousPanel::findElementWidths(const QList<Element*>& el) {
// The first pass serves to get the maximum width for each elements
qreal lineWidthName = 0;
_widthClef = 0;
_widthKeySig = 0;
_widthTimeSig = 0;
_xPosTimeSig = 0;
qreal _widthClef = 0;
qreal _widthKeySig = 0;
qreal _widthTimeSig = 0;
qreal _xPosTimeSig = 0;
for (const Element* e : el) {
e->itemDiscovered = 0;
if (!e->visible()) {
if (_score->printing() || !_score->showInvisible())
continue;
}
if (!e->visible() && !_score->showInvisible())
continue;
if (e->type() == Element::Type::STAFF_LINES) {
if (e->isStaffLines()) {
Staff* currentStaff = _score->staff(e->staffIdx());
Segment* parent = _score->tick2segment(_currentMeasureTick);
Segment* parent = _score->tick2segment(tick);
// Find maximum width for the staff name
QList<StaffName>& staffNamesLong = currentStaff->part()->instrument()->longNames();
@ -208,15 +165,17 @@ void ContinuousPanel::findElementWidths(const QList<Element*>& el) {
// Find maximum width for the current Clef
Clef* newClef = new Clef(_score);
ClefType currentClef = currentStaff->clef(_currentMeasureTick);
ClefType currentClef = currentStaff->clef(tick);
newClef->setClefType(currentClef);
newClef->setParent(parent);
newClef->setTrack(e->track());
newClef->layout();
if (newClef->width() > _widthClef)
_widthClef = newClef->width();
// Find maximum width for the current KeySignature
KeySig* newKs = new KeySig(_score);
KeySigEvent currentKeySigEvent = currentStaff->keySigEvent(_currentMeasureTick);
KeySigEvent currentKeySigEvent = currentStaff->keySigEvent(tick);
newKs->setKeySigEvent(currentKeySigEvent);
// The Parent and the Track must be set to have the key signature layout adjusted to different clefs
// This also adds naturals to the key signature (if set in the score style)
@ -224,12 +183,14 @@ void ContinuousPanel::findElementWidths(const QList<Element*>& el) {
newKs->setTrack(e->track());
newKs->setHideNaturals(true);
newKs->layout();
if (newKs->width() > _widthKeySig)
_widthKeySig = newKs->width();
// Find maximum width for the current TimeSignature
TimeSig* newTs = new TimeSig(_score);
// Try to get local time signature, if not, get the current measure one
TimeSig* currentTimeSig = currentStaff->timeSig(_currentMeasureTick);
TimeSig* currentTimeSig = currentStaff->timeSig(tick);
if (currentTimeSig)
newTs->setFrom(currentTimeSig);
else
@ -241,12 +202,6 @@ void ContinuousPanel::findElementWidths(const QList<Element*>& el) {
if ((newName->width() > lineWidthName) && (newName->xmlText() != ""))
lineWidthName = newName->width();
if (newClef->width() > _widthClef)
_widthClef = newClef->width();
if (newKs->width() > _widthKeySig)
_widthKeySig = newKs->width();
if (newTs->width() > _widthTimeSig)
_widthTimeSig = newTs->width();
@ -291,20 +246,22 @@ void ContinuousPanel::findElementWidths(const QList<Element*>& el) {
}
_rect = QRect(0, _y, _width, _height);
}
//---------------------------------------------------------
// draw
//---------------------------------------------------------
//====================
// Don't show panel if staff names are visible
if (_sv->xoffset() / _sv->mag() + _xPosMeasure > 0) {
_visible = false;
return;
}
//qDebug() << "_sv->xoffset()=" <<_sv->xoffset() << " _sv->mag()="<< _sv->mag() <<" s->x=" << s->x() << " width=" << _width << " currentMeasue=" << _currentMeasure->x() << " _xPosMeasure=" << _xPosMeasure;
void ContinuousPanel::draw(QPainter& painter, const QList<Element*>& el) {
painter.save();
painter.setRenderHint(QPainter::Antialiasing, preferences.antialiasedDrawing);
painter.setRenderHint(QPainter::TextAntialiasing, true);
// Draw colored rectangle
painter.setClipping(false);
QPointF pos(_offsetPanel, 0);
painter.translate(pos);
QPen pen;
pen.setWidthF(0.0);
@ -312,6 +269,7 @@ void ContinuousPanel::draw(QPainter& painter, const QList<Element*>& el) {
painter.setPen(pen);
painter.setBrush(preferences.fgColor);
QRectF bg(_rect);
bg.setWidth(_widthClef + _widthKeySig + _widthTimeSig + _leftMarginTotal + _panelRightPadding);
QPixmap* fgPixmap = _sv->fgPixmap();
if (fgPixmap == 0 || fgPixmap->isNull())
@ -329,7 +287,7 @@ void ContinuousPanel::draw(QPainter& painter, const QList<Element*>& el) {
QColor color(MScore::layoutBreakColor);
// Draw measure text number
QString text = _mmRestCount ? QString("#%1-%2").arg(_currentMeasureNo+1).arg(_currentMeasureNo+_mmRestCount) : QString("#%1").arg(_currentMeasureNo+1);
QString text = QString("#%1").arg(_currentMeasure->no()+1);
Text* newElement = new Text(_score);
newElement->setTextStyleType(TextStyleType::DEFAULT);
newElement->setFlag(ElementFlag::MOVABLE, false);
@ -347,41 +305,37 @@ void ContinuousPanel::draw(QPainter& painter, const QList<Element*>& el) {
// This second pass draws the elements spaced evently using the width of the largest element
for (const Element* e : el) {
e->itemDiscovered = 0;
if (!e->visible()) {
if (_score->printing() || !_score->showInvisible())
continue;
}
if (!e->visible() && !_score->showInvisible())
continue;
if (e->type() == Element::Type::STAFF_LINES) {
if (e->isStaffLines()) {
painter.save();
Staff* currentStaff = _score->staff(e->staffIdx());
Segment* parent = _score->tick2segmentMM(_currentMeasureTick);
Segment* parent = _score->tick2segmentMM(tick);
pos = QPointF (_offsetPanel, e->pagePos().y());
painter.translate(pos);
// Draw staff lines
StaffLines* newStaffLines = static_cast<StaffLines*>(e->clone());
newStaffLines->setWidth(bg.width());
newStaffLines->setParent(parent);
newStaffLines->setTrack(e->track());
newStaffLines->layout();
newStaffLines->setColor(color);
newStaffLines->draw(&painter);
delete newStaffLines;
StaffLines newStaffLines(*toStaffLines(e));
newStaffLines.setWidth(bg.width());
newStaffLines.setParent(parent);
newStaffLines.setTrack(e->track());
newStaffLines.layout();
newStaffLines.setColor(color);
newStaffLines.draw(&painter);
// Draw barline
BarLine* newBarLine = new BarLine(_score);
newBarLine->setBarLineType(BarLineType::NORMAL);
newBarLine->setParent(parent);
newBarLine->setTrack(e->track());
newBarLine->setSpan(currentStaff->barLineSpan());
newBarLine->setSpanFrom(currentStaff->barLineFrom());
newBarLine->setSpanTo(currentStaff->barLineTo());
newBarLine->layout();
newBarLine->setColor(color);
newBarLine->draw(&painter);
delete newBarLine;
BarLine barLine(_score);
barLine.setBarLineType(BarLineType::NORMAL);
barLine.setParent(parent);
barLine.setTrack(e->track());
barLine.setSpan(currentStaff->barLineSpan());
barLine.setSpanFrom(currentStaff->barLineFrom());
barLine.setSpanTo(currentStaff->barLineTo());
barLine.layout();
barLine.setColor(color);
barLine.draw(&painter);
// Draw the current staff name
QList<StaffName>& staffNamesLong = currentStaff->part()->instrument()->longNames();
@ -403,69 +357,60 @@ void ContinuousPanel::draw(QPainter& painter, const QList<Element*>& el) {
newName->layout();
if (currentStaff->part()->staff(0) == currentStaff) {
double _spatium = _score->spatium();
pos = QPointF (_score->styleP(StyleIdx::clefLeftMargin) + _widthClef, 0 - _spatium * 2);
pos = QPointF (_score->styleP(StyleIdx::clefLeftMargin) + _widthClef, -_spatium * 2);
painter.translate(pos);
newName->draw(&painter);
painter.translate(-pos);
}
delete newName;
qreal posX = 0.0;
// Draw the current Clef
Clef* newClef = new Clef(_score);
ClefType currentClef = currentStaff->clef(_currentMeasureTick);
newClef->setClefType(currentClef);
newClef->setParent(parent);
newClef->setTrack(e->track());
newClef->setColor(color);
newClef->layout();
pos = QPointF(_score->styleP(StyleIdx::clefLeftMargin), 0);
painter.translate(pos);
newClef->draw(&painter);
pos = QPointF(_widthClef,0);
painter.translate(pos);
delete newClef;
Clef clef(_score);
clef.setClefType(currentStaff->clef(tick));
clef.setParent(parent);
clef.setTrack(e->track());
clef.setColor(color);
clef.layout();
posX += _score->styleP(StyleIdx::clefLeftMargin) + _widthClef;
clef.drawAt(&painter, QPointF(posX, 0.0));
// Draw the current KeySignature
KeySig* newKs = new KeySig(_score);
KeySigEvent currentKeySigEvent = currentStaff->keySigEvent(_currentMeasureTick);
newKs->setKeySigEvent(currentKeySigEvent);
KeySig newKs(_score);
newKs.setKeySigEvent(currentStaff->keySigEvent(tick));
// The Parent and the track must be set to have the key signature layout adjusted to different clefs
// This also adds naturals to the key signature (if set in the score style)
newKs->setParent(parent);
newKs->setTrack(e->track());
newKs->setColor(color);
newKs.setParent(parent);
newKs.setTrack(e->track());
newKs.setColor(color);
newKs.setHideNaturals(true);
newKs.layout();
posX += _score->styleP(StyleIdx::keysigLeftMargin);
newKs.drawAt(&painter, QPointF(posX, 0.0));
newKs->setHideNaturals(true);
pos = QPointF(_score->styleP(StyleIdx::keysigLeftMargin),0);
painter.translate(pos);
newKs->layout();
newKs->draw(&painter);
delete newKs;
pos = QPointF(_widthKeySig + _xPosTimeSig, 0);
painter.translate(pos);
posX += _widthKeySig + _xPosTimeSig;
// Draw the current TimeSignature
TimeSig* newTs = new TimeSig(_score);
TimeSig newTs(_score);
// Try to get local time signature, if not, get the current measure one
TimeSig* currentTimeSig = currentStaff->timeSig(_currentMeasureTick);
TimeSig* currentTimeSig = currentStaff->timeSig(tick);
if (currentTimeSig) {
newTs->setFrom(currentTimeSig);
newTs->setParent(parent);
newTs->setTrack(e->track());
newTs->setColor(color);
newTs->layout();
pos = QPointF(_score->styleP(StyleIdx::timesigLeftMargin),0);
painter.translate(pos);
newTs->draw(&painter);
delete newTs;
newTs.setFrom(currentTimeSig);
newTs.setParent(parent);
newTs.setTrack(e->track());
newTs.setColor(color);
newTs.layout();
posX += _score->styleP(StyleIdx::timesigLeftMargin);
newTs.drawAt(&painter, QPointF(posX, 0.0));
}
pos = QPointF(_offsetPanel + _widthClef + _widthKeySig + _xPosTimeSig + _leftMarginTotal, e->pagePos().y());
painter.translate(-pos);
painter.restore();
}
}
painter.restore();
_visible = true;
}
}

View file

@ -27,30 +27,7 @@ class ContinuousPanel {
QRectF _rect;
bool _active; // Used to active or desactive the panel
bool _visible; // False if beginning of the score is visible
const Measure* _currentMeasure;
int _currentMeasureTick;
int _currentMeasureNo;
int _mmRestCount; // Used for showing mmRest interval in the panel
Fraction _currentTimeSig;
qreal _offsetPanel;
qreal _x;
qreal _y;
qreal _width; // Actual panel width (final or transitional)
qreal _oldWidth; // The last final panel width
qreal _newWidth; // New panel width
qreal _measureWidth;
qreal _height;
qreal _widthClef;
qreal _widthKeySig;
qreal _widthTimeSig;
qreal _leftMarginTotal; // Sum of all elments left margin
qreal _panelRightPadding; // Extra space for the panel after last element
qreal _xPosTimeSig; // X position of the time signature (because it is centered
qreal _xPosMeasure; // Position of the coming measure
protected:
void findElementWidths(const QList<Element*>& el);
void draw(QPainter& painter, const QList<Element*>& el);
public:
ContinuousPanel(ScoreView* sv);

View file

@ -970,5 +970,10 @@
<key>startcenter</key>
<seq>F4</seq>
</SC>
<SC>
<key>viewmode</key>
<seq>Ctrl+Shift+V</seq>
</SC>
</Shortcuts>

View file

@ -1495,7 +1495,10 @@ void MuseScore::printFile()
return;
LayoutMode layoutMode = cs->layoutMode();
cs->switchToPageMode();
if (layoutMode != LayoutMode::PAGE) {
cs->setLayoutMode(LayoutMode::PAGE);
cs->doLayout();
}
QPainter p(&printerDev);
p.setRenderHint(QPainter::Antialiasing, true);
@ -1524,8 +1527,10 @@ void MuseScore::printFile()
}
}
p.end();
if (layoutMode != cs->layoutMode())
cs->endCmd(true); // rollback
if (layoutMode != cs->layoutMode()) {
cs->setLayoutMode(layoutMode);
cs->doLayout();
}
}
//---------------------------------------------------------
@ -1759,6 +1764,10 @@ bool MuseScore::saveAs(Score* cs, bool saveCopy, const QString& path, const QStr
fn += suffix;
LayoutMode layoutMode = cs->layoutMode();
if (layoutMode != LayoutMode::PAGE) {
cs->setLayoutMode(LayoutMode::PAGE);
cs->doLayout();
}
if (ext == "mscx" || ext == "mscz") {
// save as mscore *.msc[xz] file
QFileInfo fi(fn);
@ -1803,17 +1812,14 @@ bool MuseScore::saveAs(Score* cs, bool saveCopy, const QString& path, const QStr
}
else if (ext == "pdf") {
// save as pdf file *.pdf
cs->switchToPageMode();
rv = savePdf(cs, fn);
}
else if (ext == "png") {
// save as png file *.png
cs->switchToPageMode();
rv = savePng(cs, fn);
}
else if (ext == "svg") {
// save as svg file *.svg
cs->switchToPageMode();
rv = saveSvg(cs, fn);
}
#ifdef HAS_AUDIOFILE
@ -1825,12 +1831,10 @@ bool MuseScore::saveAs(Score* cs, bool saveCopy, const QString& path, const QStr
rv = saveMp3(cs, fn);
#endif
else if (ext == "spos") {
cs->switchToPageMode();
// save positions of segments
rv = savePositions(cs, fn, true);
}
else if (ext == "mpos") {
cs->switchToPageMode();
// save positions of measures
rv = savePositions(cs, fn, false);
}
@ -1844,8 +1848,10 @@ bool MuseScore::saveAs(Score* cs, bool saveCopy, const QString& path, const QStr
}
if (!rv && !MScore::noGui)
QMessageBox::critical(this, tr("MuseScore:"), tr("Cannot write into %1").arg(fn));
if (layoutMode != cs->layoutMode())
cs->endCmd(true); // rollback
if (layoutMode != cs->layoutMode()) {
cs->setLayoutMode(layoutMode);
cs->doLayout();
}
return rv;
}
@ -1937,7 +1943,10 @@ bool MuseScore::savePdf(QList<Score*> cs, const QString& saveName)
bool firstPage = true;
for (Score* s : cs) {
LayoutMode layoutMode = s->layoutMode();
s->switchToPageMode();
if (layoutMode != LayoutMode::PAGE) {
s->setLayoutMode(LayoutMode::PAGE);
s->doLayout();
}
s->setPrinting(true);
MScore::pdfPrinting = true;
@ -1956,8 +1965,10 @@ bool MuseScore::savePdf(QList<Score*> cs, const QString& saveName)
s->setPrinting(false);
MScore::pdfPrinting = false;
if (layoutMode != s->layoutMode())
s->endCmd(true); // rollback
if (layoutMode != s->layoutMode()) {
s->setLayoutMode(layoutMode);
s->doLayout();
}
}
p.end();
return true;

View file

@ -577,7 +577,7 @@ MuseScore::MuseScore()
#endif
viewModeCombo->setAccessibleName(tr("View Mode"));
viewModeCombo->setFixedHeight(preferences.iconHeight + 8); // hack
viewModeCombo->addItem(tr("Page View"), int(LayoutMode::PAGE));
viewModeCombo->addItem(tr("Page View"), int(LayoutMode::PAGE));
viewModeCombo->addItem(tr("Continuous View"), int(LayoutMode::LINE));
if (enableExperimental)
viewModeCombo->addItem(tr("Single Page"), int(LayoutMode::SYSTEM));
@ -2136,6 +2136,12 @@ static bool doConvert(Score* cs, QString fn)
bool rv = true;
LayoutMode layoutMode = cs->layoutMode();
cs->setLayoutMode(LayoutMode::PAGE);
if (cs->layoutMode() != layoutMode) {
cs->setLayoutMode(LayoutMode::PAGE);
cs->doLayout();
}
if (!styleFile.isEmpty()) {
QFile f(styleFile);
if (f.open(QIODevice::ReadOnly))
@ -2162,18 +2168,15 @@ static bool doConvert(Score* cs, QString fn)
return true;
}
else if (fn.endsWith(".xml")) {
cs->switchToPageMode();
rv = saveXml(cs, fn);
}
else if (fn.endsWith(".mxl")) {
cs->switchToPageMode();
rv = saveMxl(cs, fn);
}
else if (fn.endsWith(".mid"))
return mscore->saveMidi(cs, fn);
else if (fn.endsWith(".pdf")) {
if (!exportScoreParts) {
cs->switchToPageMode();
rv = mscore->savePdf(fn);
}
else {
@ -2199,7 +2202,6 @@ static bool doConvert(Score* cs, QString fn)
}
}
else if (fn.endsWith(".png")) {
cs->switchToPageMode();
if (!exportScoreParts)
return mscore->savePng(cs, fn);
else {
@ -2232,7 +2234,6 @@ static bool doConvert(Score* cs, QString fn)
}
}
else if (fn.endsWith(".svg")) {
cs->switchToPageMode();
rv = mscore->saveSvg(cs, fn);
}
#ifdef HAS_AUDIOFILE
@ -2244,11 +2245,9 @@ static bool doConvert(Score* cs, QString fn)
return mscore->saveMp3(cs, fn);
#endif
else if (fn.endsWith(".spos")) {
cs->switchToPageMode();
rv = savePositions(cs, fn, true);
}
else if (fn.endsWith(".mpos")) {
cs->switchToPageMode();
rv = savePositions(cs, fn, false);
}
else if (fn.endsWith(".mlog"))
@ -2257,8 +2256,10 @@ static bool doConvert(Score* cs, QString fn)
qDebug("dont know how to convert to %s", qPrintable(outFileName));
return false;
}
if (layoutMode != cs->layoutMode())
cs->endCmd(true); // rollback
if (layoutMode != cs->layoutMode()) {
cs->setLayoutMode(layoutMode);
cs->doLayout();
}
return rv;
}
@ -2344,19 +2345,21 @@ static bool processNonGui(const QStringList& argv)
bool res = false;
if (mscore->loadPlugin(pn)){
Score* cs = mscore->currentScore();
LayoutMode layoutMode = cs->layoutMode();
if (!styleFile.isEmpty()) {
QFile f(styleFile);
if (f.open(QIODevice::ReadOnly))
cs->style()->load(&f);
}
cs->startCmd();
cs->setLayoutAll();
cs->endCmd();
cs->switchToPageMode();
LayoutMode layoutMode = cs->layoutMode();
if (layoutMode != LayoutMode::PAGE) {
cs->setLayoutMode(LayoutMode::PAGE);
cs->doLayout();
}
mscore->pluginTriggered(0);
if (layoutMode != cs->layoutMode())
cs->endCmd(true); // rollback
if (layoutMode != cs->layoutMode()) {
cs->setLayoutMode(layoutMode);
cs->doLayout();
}
res = true;
}
if (!converterMode)
@ -4506,12 +4509,10 @@ void MuseScore::cmd(QAction* a, const QString& cmd)
}
else if (cmd == "viewmode") {
if (cs) {
int mode;
if (cs->layoutMode() == LayoutMode::PAGE)
mode = 1;
switchLayoutMode(LayoutMode::LINE);
else
mode = 0;
switchLayoutMode(mode);
switchLayoutMode(LayoutMode::PAGE);
}
}
else {
@ -4665,20 +4666,23 @@ void MuseScore::switchLayoutMode(int val)
{
if (!cs)
return;
switchLayoutMode(static_cast<LayoutMode>(viewModeCombo->itemData(val).toInt()));
}
cs->startCmd();
void MuseScore::switchLayoutMode(LayoutMode mode)
{
// find a measure to use as reference, if possible
QRectF view = cv->toLogical(QRect(0.0, 0.0, width(), height()));
Measure* m = cs->firstMeasure();
while (m && !view.intersects(m->canvasBoundingRect()))
m = m->nextMeasureMM();
LayoutMode mode = static_cast<LayoutMode>(viewModeCombo->itemData(val).toInt());
cs->ScoreElement::undoChangeProperty(P_ID::LAYOUT_MODE, int(mode));
cv->loopUpdate(getAction("loop")->isChecked());
cs->endCmd();
if (mode != cs->layoutMode()) {
cs->setLayoutMode(mode);
cs->doLayout();
}
// adjustCanvasPosition often tries to preserve Y position
// but this doesn't make sense when switching modes

View file

@ -420,6 +420,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
void updateNewWizard();
void updateViewModeCombo();
void switchLayoutMode(LayoutMode);
private slots:
void cmd(QAction* a, const QString& cmd);

View file

@ -1661,11 +1661,7 @@ void ScoreView::setShadowNote(const QPointF& p)
static void paintElement(void* data, Element* e)
{
QPainter* p = static_cast<QPainter*>(data);
QPointF pos(e->canvasPos());
p->translate(pos);
e->draw(p);
p->translate(-pos);
e->drawAt(static_cast<QPainter*>(data), e->canvasPos());
}
//---------------------------------------------------------