Beispiel #1
0
void System::setInstrumentNames(bool longName)
      {
      //
      // remark: add/remove instrument names is not undo/redoable
      //         as add/remove of systems is not undoable
      //
      if (isVbox())                 // ignore vbox
            return;
      if (!score()->showInstrumentNames()
              || (score()->styleB(StyleIdx::hideInstrumentNameIfOneInstrument) && score()->parts().size() == 1)) {
            for (int staffIdx = 0; staffIdx < score()->nstaves(); ++staffIdx) {
                  SysStaff* staff = _staves[staffIdx];
                  foreach(InstrumentName* t, staff->instrumentNames)
                        score()->removeElement(t);
                  }
            return;
            }

      // TODO: ml is normally empty here, so we are unable to retrieve tick
      // thus, staff name does not reflect current instrument
      int tick = ml.isEmpty() ? 0 : ml.front()->tick();
      for (int staffIdx = 0; staffIdx < score()->nstaves(); ++staffIdx) {
            SysStaff* staff = _staves[staffIdx];
            Staff* s        = score()->staff(staffIdx);
            if (!s->isTop() || !s->show()) {
                  foreach(InstrumentName* t, staff->instrumentNames)
                        score()->removeElement(t);
                  continue;
                  }

            Part* part = s->part();
            const QList<StaffName>& names = longName? part->longNames(tick) : part->shortNames(tick);

            int idx = 0;
            foreach(const StaffName& sn, names) {
                  InstrumentName* iname = staff->instrumentNames.value(idx);
                  if (iname == 0) {
                        iname = new InstrumentName(score());
                        iname->setGenerated(true);
                        iname->setParent(this);
                        iname->setTrack(staffIdx * VOICES);
                        iname->setInstrumentNameType(longName ? InstrumentNameType::LONG : InstrumentNameType::SHORT);
                        score()->addElement(iname);
                        }
                  iname->setXmlText(sn.name());
                  iname->setLayoutPos(sn.pos());
                  ++idx;
                  }
            for (; idx < staff->instrumentNames.size(); ++idx)
                  score()->removeElement(staff->instrumentNames[idx]);
            }
Beispiel #2
0
void System::layout2()
      {
      if (isVbox())                 // ignore vbox
            return;

      int nstaves    = _staves.size();
      qreal _spatium = spatium();

      qreal y = 0.0;
      int lastStaffIdx  = 0;   // last visible staff
      int firstStaffIdx = -1;
      qreal lastStaffDistanceDown = 0.0;
      for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
            Staff* staff = score()->staff(staffIdx);
            StyleIdx downDistance;
            qreal userDist = 0.0;
            if ((staffIdx + 1) == nstaves) {
                  //
                  // last staff in system
                  //
                  MeasureBase* mb = ml.last();
                  bool nextMeasureIsVBOX = false;
                  if (mb->next()) {
                        Element::Type type = mb->next()->type();
                        if (type == Element::Type::VBOX || type == Element::Type::TBOX || type == Element::Type::FBOX)
                              nextMeasureIsVBOX = true;
                        }
                  downDistance = nextMeasureIsVBOX ? StyleIdx::systemFrameDistance : StyleIdx::minSystemDistance;
                  }
            else if (staff->rstaff() < (staff->part()->staves()->size()-1)) {
                  //
                  // staff is not last staff in a part
                  //
                  downDistance = StyleIdx::akkoladeDistance;
                  userDist = score()->staff(staffIdx + 1)->userDist();
                  }
            else {
                  downDistance = StyleIdx::staffDistance;
                  userDist = score()->staff(staffIdx + 1)->userDist();
                  }

            SysStaff* s    = _staves[staffIdx];
            qreal distDown = score()->styleS(downDistance).val() * _spatium + userDist;
            qreal nominalDistDown = distDown;
            qreal distUp   = 0.0;
            int n = ml.size();
            for (int i = 0; i < n; ++i) {
                  MeasureBase* m = ml.at(i);
                  distDown = qMax(distDown, m->distanceDown(staffIdx));
                  distUp   = qMax(distUp,   m->distanceUp(staffIdx));
                  }
            s->setDistanceDown(distDown);
            s->setDistanceUp(distUp);

            if (!staff->show() || !s->show()) {
                  s->setbbox(QRectF());  // already done in layout() ?
                  continue;
                  }
            qreal sHeight = staff->height();
            qreal dup = staffIdx == 0 ? 0.0 : s->distanceUp();
            if (staff->lines() == 1)
                  dup -= _spatium * staff->mag();
            s->bbox().setRect(_leftMargin, y + dup, width() - _leftMargin, sHeight);
            y += dup + sHeight + s->distanceDown();
            lastStaffIdx = staffIdx;
            lastStaffDistanceDown = distDown - nominalDistDown;
            if (firstStaffIdx == -1)
                  firstStaffIdx = staffIdx;
            }
      if (firstStaffIdx == -1)
            firstStaffIdx = 0;

      qreal systemHeight = staff(lastStaffIdx)->bbox().bottom();
      if (lastStaffIdx < nstaves - 1)
            systemHeight += lastStaffDistanceDown;
      setHeight(systemHeight);

      int n = ml.size();
      for (int i = 0; i < n; ++i) {
            MeasureBase* m = ml.at(i);
            if (m->type() == Element::Type::MEASURE) {
                  // note that the factor 2 * _spatium must be corrected for when exporting
                  // system distance in MusicXML (issue #24733)
                  m->bbox().setRect(0.0, -_spatium, m->width(), systemHeight + 2 * _spatium);
                  }
            else if (m->type() == Element::Type::HBOX) {
                  m->bbox().setRect(0.0, 0.0, m->width(), systemHeight);
                  static_cast<HBox*>(m)->layout2();
                  }
            }

      if (_barLine) {
            _barLine->setTrack(firstStaffIdx * VOICES);
            _barLine->setSpan(lastStaffIdx - firstStaffIdx + 1);
            if (score()->staff(0)->lines() == 1)
                  _barLine->setSpanFrom(BARLINE_SPAN_1LINESTAFF_FROM);

            int spanTo = (score()->staff(lastStaffIdx)->lines() == 1) ?
                              BARLINE_SPAN_1LINESTAFF_TO :
                              (score()->staff(lastStaffIdx)->lines()-1)*2;
            _barLine->setSpanTo(spanTo);
            _barLine->layout();
            }

      //---------------------------------------------------
      //  layout brackets vertical position
      //---------------------------------------------------

      n = _brackets.size();
      for (int i = 0; i < n; ++i) {
            Bracket* b = _brackets.at(i);
            int staffIdx1 = b->firstStaff();
            int staffIdx2 = b->lastStaff();
            qreal sy = 0;                       // assume bracket not visible
            qreal ey = 0;
            // if start staff not visible, try next staff
            while (staffIdx1 <= staffIdx2 && !_staves[staffIdx1]->show())
                  ++staffIdx1;
            // if end staff not visible, try prev staff
            while (staffIdx1 <= staffIdx2 && !_staves[staffIdx2]->show())
                  --staffIdx2;
            // the bracket will be shown IF:
            // it spans at least 2 visible staves (staffIdx1 < staffIdx2) OR
            // it spans just one visible staff (staffIdx1 == staffIdx2) but it is required to do so
            // (the second case happens at least when the bracket is initially dropped)
            bool notHidden = (staffIdx1 < staffIdx2) || (b->span() == 1 && staffIdx1 == staffIdx2);
            if (notHidden) {                    // set vert. pos. and height to visible spanned staves
                  sy = _staves[staffIdx1]->bbox().top();
                  ey = _staves[staffIdx2]->bbox().bottom();
                  }
            b->rypos() = sy;
            b->setHeight(ey - sy);
            b->layout();
            }

      //---------------------------------------------------
      //  layout instrument names
      //---------------------------------------------------

      int staffIdx = 0;
      n = score()->parts().size();

      for (Part* p : score()->parts()) {
            SysStaff* s = staff(staffIdx);
            SysStaff* s2;
            int nstaves = p->nstaves();
            if (s->show()) {
                  for (InstrumentName* t : s->instrumentNames) {
                        //
                        // override Text->layout()
                        //
                        qreal y1, y2;
                        switch (t->layoutPos()) {
                              default:
                              case 0:           // center at part
                                    y1 = s->bbox().top();
                                    s2 = staff(staffIdx);
                                    for (int i = staffIdx + nstaves - 1; i > 0; --i) {
                                          SysStaff* s = staff(i);
                                          if (s->show()) {
                                                s2 = s;
                                                break;
                                                }
                                          }
                                    y2 = s2->bbox().bottom();
                                    break;
                              case 1:           // center at first staff
                                    y1 = s->bbox().top();
                                    y2 = s->bbox().bottom();
                                    break;

                              // TODO:
                              // sort out invisible staves

                              case 2:           // center between first and second staff
                                    y1 = s->bbox().top();
                                    y2 = staff(staffIdx + 1)->bbox().bottom();
                                    break;
                              case 3:           // center at second staff
                                    y1 = staff(staffIdx + 1)->bbox().top();
                                    y2 = staff(staffIdx + 1)->bbox().bottom();
                                    break;
                              case 4:           // center between first and second staff
                                    y1 = staff(staffIdx + 1)->bbox().top();
                                    y2 = staff(staffIdx + 2)->bbox().bottom();
                                    break;
                              case 5:           // center at third staff
                                    y1 = staff(staffIdx + 2)->bbox().top();
                                    y2 = staff(staffIdx + 2)->bbox().bottom();
                                    break;
                              }
                        t->rypos() = y1 + (y2 - y1) * .5 + t->textStyle().offset(t->spatium()).y();
                        }
                  }
            staffIdx += nstaves;
            }
      }
Beispiel #3
0
void System::layout(qreal xo1)
      {
      if (isVbox())                 // ignore vbox
            return;
      static const Spatium instrumentNameOffset(1.0);

      int nstaves  = _staves.size();
      if (nstaves != score()->nstaves())
            qDebug("System::layout: nstaves %d != %d", nstaves, score()->nstaves());

      //---------------------------------------------------
      //  find x position of staves
      //    create brackets
      //---------------------------------------------------

      qreal xoff2 = 0.0;         // x offset for instrument name

      int bracketLevels = 0;
      for (int idx = 0; idx < nstaves; ++idx)
            bracketLevels = qMax(bracketLevels, score()->staff(idx)->bracketLevels());

      qreal bracketWidth[bracketLevels];
      for (int i = 0; i < bracketLevels; ++i)
            bracketWidth[i] = 0.0;

      QList<Bracket*> bl = _brackets;
      _brackets.clear();

      for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
            Staff* s = score()->staff(staffIdx);
            for (int i = 0; i < bracketLevels; ++i) {
                  if (s->bracket(i) == BracketType::NO_BRACKET)
                        continue;
                  int firstStaff = staffIdx;
                  int lastStaff  = staffIdx + s->bracketSpan(i) - 1;
                  if (lastStaff >= nstaves)
                        lastStaff = nstaves - 1;

                  for (; firstStaff <= lastStaff; ++firstStaff) {
                        if (score()->staff(firstStaff)->show())
                              break;
                        }
                  for (; lastStaff >= firstStaff; --lastStaff) {
                        if (score()->staff(lastStaff)->show())
                              break;
                        }
                  int span = lastStaff - firstStaff + 1;
                  //
                  // do not show bracket if it only spans one
                  // system due to some invisible staves
                  //
                  if ((span > 1) || (s->bracketSpan(i) == span)) {
                        //
                        // this bracket is visible
                        //
                        Bracket* b = 0;
                        int track = staffIdx * VOICES;
                        for (int k = 0; k < bl.size(); ++k) {
                              if (bl[k]->track() == track && bl[k]->level() == i) {
                                    b = bl.takeAt(k);
                                    break;
                                    }
                              }
                        if (b == 0) {
                              b = new Bracket(score());
                              b->setGenerated(true);
                              b->setParent(this);
                              b->setTrack(track);
                              b->setLevel(i);
                              b->setBracketType(s->bracket(i));
                              b->setSpan(s->bracketSpan(i));
                              score()->undoAddElement(b);
                              }
                        else
                              _brackets.append(b);
                        b->setFirstStaff(firstStaff);
                        b->setLastStaff(lastStaff);
                        bracketWidth[i] = qMax(bracketWidth[i], b->width());
                        }
                  }
            if (!s->show())
                  continue;
            for (InstrumentName* t : _staves[staffIdx]->instrumentNames) {
                  t->layout();
                  qreal w = t->width() + point(instrumentNameOffset);
                  if (w > xoff2)
                        xoff2 = w;
                  }
            }

      for (Bracket* b : bl)
            score()->undoRemoveElement(b);

      //---------------------------------------------------
      //  layout  SysStaff and StaffLines
      //---------------------------------------------------

      // xoff2 += xo1;
      _leftMargin = xoff2;

      qreal bd = point(score()->styleS(StyleIdx::bracketDistance));
      if ( _brackets.size() > 0) {
            for (int i = 0; i < bracketLevels; ++i)
                  _leftMargin += bracketWidth[i] + bd;
            }


      for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
            SysStaff* s  = _staves[staffIdx];
            Staff* staff = score()->staff(staffIdx);
            if (!staff->show() || !s->show()) {
                  s->setbbox(QRectF());
                  continue;
                  }
            qreal staffMag = staff->mag();
            qreal h;
            if (staff->lines() == 1)
                  h = 2;
            else
                  h = (staff->lines()-1) * staff->lineDistance();
            h = h * staffMag * spatium();
            s->bbox().setRect(_leftMargin + xo1, 0.0, 0.0, h);
            }

      if ((nstaves > 1 && score()->styleB(StyleIdx::startBarlineMultiple)) || (nstaves <= 1 && score()->styleB(StyleIdx::startBarlineSingle))) {
            if (_barLine == 0) {
                  BarLine* bl = new BarLine(score());
                  bl->setParent(this);
                  bl->setTrack(0);
                  bl->setGenerated(true);
                  score()->undoAddElement(bl);
                  }
            }
      else if (_barLine)
            score()->undoRemoveElement(_barLine);
      if (_barLine)
            _barLine->rxpos() = _leftMargin + xo1;

      //---------------------------------------------------
      //  layout brackets
      //---------------------------------------------------

      for (Bracket* b : _brackets) {
            qreal xo = -xo1;
            for (const Bracket* b2 : _brackets) {
                   if (b->level() > b2->level() &&
                      ((b->firstStaff() >= b2->firstStaff() && b->firstStaff() <= b2->lastStaff()) ||
                      (b->lastStaff() >= b2->firstStaff() && b->lastStaff() <= b2->lastStaff())))
                        xo += b2->width() + bd;
                   }
            b->rxpos() = _leftMargin - xo - b->width();
            }

      //---------------------------------------------------
      //  layout instrument names x position
      //---------------------------------------------------

      int idx = 0;
      for (const Part* p : score()->parts()) {
            SysStaff* s = staff(idx);
            if (s->show() && p->show()) {
                  for (InstrumentName* t : s->instrumentNames) {
                        switch (t->textStyle().align() & AlignmentFlags::HMASK) {
                              case int(AlignmentFlags::LEFT):
                                    t->rxpos() = 0;
                                    break;
                              case int(AlignmentFlags::HCENTER):
                                    t->rxpos() = (xoff2 - point(instrumentNameOffset) + xo1) * .5;
                                    break;
                              case int(AlignmentFlags::RIGHT):
                              default:
                                    t->rxpos() = xoff2 - point(instrumentNameOffset) + xo1;
                                    break;
                              }
                        t->rxpos() += t->textStyle().offset(t->spatium()).x();
                        }
                  }
            idx += p->nstaves();
            }
      }