📄 notationstaff.cpp
字号:
if (before) { if ((*it)->event()->isa(Clef::EventType)) { clef = (*it)->event(); } else if ((*it)->event()->isa(::Rosegarden::Key::EventType)) { key = (*it)->event(); } } } double airX, airWidth; el->getLayoutAirspace(airX, airWidth); if (x >= airX && x < airX + airWidth) { return it; } else if (!before) { if (it != notes->begin()) --it; return it; } } return notes->end();}std::stringNotationStaff::getNoteNameAtCanvasCoords(double x, int y, Accidental) const{ Clef clef; ::Rosegarden::Key key; getClefAndKeyAtCanvasCoords(x, y, clef, key); KConfig *config = kapp->config(); config->setGroup(GeneralOptionsConfigGroup); int baseOctave = config->readNumEntry("midipitchoctave", -2); Pitch p(getHeightAtCanvasCoords(x, y), clef, key); //!!! i18n() how? return p.getAsString(key.isSharp(), true, baseOctave);}voidNotationStaff::renderElements(NotationElementList::iterator from, NotationElementList::iterator to){ // NOTATION_DEBUG << "NotationStaff " << this << "::renderElements()" << endl; Profiler profiler("NotationStaff::renderElements"); emit setOperationName(i18n("Rendering staff %1...").arg(getId() + 1)); emit setProgress(0); throwIfCancelled(); // These are only used when rendering keys, and we don't have the // right start data here so we choose not to render keys at all in // this method (see below) so that we can pass bogus clef and key // data to renderSingleElement Clef currentClef; ::Rosegarden::Key currentKey; int elementCount = 0; timeT endTime = (to != getViewElementList()->end() ? (*to)->getViewAbsoluteTime() : getSegment().getEndMarkerTime()); timeT startTime = (from != to ? (*from)->getViewAbsoluteTime() : endTime); for (NotationElementList::iterator it = from, nextIt = from; it != to; it = nextIt) { ++nextIt; if (isDirectlyPrintable(*it)) { // notes are renderable direct to the printer, so don't render // them to the canvas here continue; } if ((*it)->event()->isa(::Rosegarden::Key::EventType)) { // force rendering in positionElements instead NotationElement* el = static_cast<NotationElement*>(*it); el->removeCanvasItem(); continue; } bool selected = isSelected(it); // NOTATION_DEBUG << "Rendering at " << (*it)->getAbsoluteTime() // << " (selected = " << selected << ")" << endl; renderSingleElement(it, currentClef, currentKey, selected); if ((endTime > startTime) && (++elementCount % 200 == 0)) { timeT myTime = (*it)->getViewAbsoluteTime(); emit setProgress((myTime - startTime) * 100 / (endTime - startTime)); throwIfCancelled(); } } // NOTATION_DEBUG << "NotationStaff " << this << "::renderElements: " // << elementCount << " elements rendered" << endl;}voidNotationStaff::renderPrintable(timeT from, timeT to){ if (!m_printPainter) return ; Profiler profiler("NotationStaff::renderElements"); emit setOperationName(i18n("Rendering notes on staff %1...").arg(getId() + 1)); emit setProgress(0); throwIfCancelled(); // These are only used when rendering keys, and we don't do that // here, so we don't care what they are Clef currentClef; ::Rosegarden::Key currentKey; Composition *composition = getSegment().getComposition(); NotationElementList::iterator beginAt = getViewElementList()->findTime(composition->getBarStartForTime(from)); NotationElementList::iterator endAt = getViewElementList()->findTime(composition->getBarEndForTime(to)); int elementCount = 0; for (NotationElementList::iterator it = beginAt, nextIt = beginAt; it != endAt; it = nextIt) { ++nextIt; if (!isDirectlyPrintable(*it)) { continue; } bool selected = isSelected(it); // NOTATION_DEBUG << "Rendering at " << (*it)->getAbsoluteTime() // << " (selected = " << selected << ")" << endl; renderSingleElement(it, currentClef, currentKey, selected); if ((to > from) && (++elementCount % 200 == 0)) { timeT myTime = (*it)->getViewAbsoluteTime(); emit setProgress((myTime - from) * 100 / (to - from)); throwIfCancelled(); } } // NOTATION_DEBUG << "NotationStaff " << this << "::renderElements: " // << elementCount << " elements rendered" << endl;}const NotationProperties &NotationStaff::getProperties() const{ return m_notationView->getProperties();}voidNotationStaff::positionElements(timeT from, timeT to){ // NOTATION_DEBUG << "NotationStaff " << this << "::positionElements()" // << from << " -> " << to << endl; Profiler profiler("NotationStaff::positionElements"); emit setOperationName(i18n("Positioning staff %1...").arg(getId() + 1)); emit setProgress(0); throwIfCancelled(); const NotationProperties &properties(getProperties()); int elementsPositioned = 0; int elementsRendered = 0; // diagnostic Composition *composition = getSegment().getComposition(); timeT nextBarTime = composition->getBarEndForTime(to); NotationElementList::iterator beginAt = getViewElementList()->findTime(composition->getBarStartForTime(from)); NotationElementList::iterator endAt = getViewElementList()->findTime(composition->getBarEndForTime(to)); if (beginAt == getViewElementList()->end()) return ; truncateClefsAndKeysAt(static_cast<int>((*beginAt)->getLayoutX())); Clef currentClef; // used for rendering key sigs bool haveCurrentClef = false; ::Rosegarden::Key currentKey; bool haveCurrentKey = false; for (NotationElementList::iterator it = beginAt, nextIt = beginAt; it != endAt; it = nextIt) { NotationElement * el = static_cast<NotationElement*>(*it); ++nextIt; if (el->event()->isa(Clef::EventType)) { currentClef = Clef(*el->event()); m_clefChanges.push_back(ClefChange(int(el->getLayoutX()), currentClef)); haveCurrentClef = true; } else if (el->event()->isa(::Rosegarden::Key::EventType)) { m_keyChanges.push_back (KeyChange(int(el->getLayoutX()), ::Rosegarden::Key(*el->event()))); if (!haveCurrentClef) { // need this to know how to present the key currentClef = getSegment().getClefAtTime (el->event()->getAbsoluteTime()); haveCurrentClef = true; } if (!haveCurrentKey) { // stores the key _before_ this one currentKey = getSegment().getKeyAtTime (el->event()->getAbsoluteTime() - 1); haveCurrentKey = true; } } else if (isDirectlyPrintable(el)) { // these are rendered by renderPrintable for printing continue; } bool selected = isSelected(it); bool needNewSprite = (selected != el->isSelected()); if (!el->getCanvasItem()) { needNewSprite = true; } else if (el->isNote() && !el->isRecentlyRegenerated()) { // If the note's y-coordinate has changed, we should // redraw it -- its stem direction may have changed, or it // may need leger lines. This will happen e.g. if the // user inserts a new clef; unfortunately this means // inserting clefs is rather slow. needNewSprite = needNewSprite || !elementNotMovedInY(el); if (!needNewSprite) { // If the event is a beamed or tied-forward note, then // we might need a new sprite if the distance from // this note to the next has changed (because the beam // or tie is part of the note's sprite). bool spanning = false; (void)(el->event()->get <Bool> (properties.BEAMED, spanning)); if (!spanning) { (void)(el->event()->get <Bool>(BaseProperties::TIED_FORWARD, spanning)); } if (spanning) { needNewSprite = (el->getViewAbsoluteTime() < nextBarTime || !elementShiftedOnly(it)); } } } else if (el->event()->isa(Indication::EventType) && !el->isRecentlyRegenerated()) { needNewSprite = true; } if (needNewSprite) { renderSingleElement(it, currentClef, currentKey, selected); ++elementsRendered; } if (el->event()->isa(::Rosegarden::Key::EventType)) { // update currentKey after rendering, not before currentKey = ::Rosegarden::Key(*el->event()); } if (!needNewSprite) { LinedStaffCoords coords = getCanvasCoordsForLayoutCoords (el->getLayoutX(), (int)el->getLayoutY()); el->reposition(coords.first, (double)coords.second); } el->setSelected(selected); if ((to > from) && (++elementsPositioned % 300 == 0)) { timeT myTime = el->getViewAbsoluteTime(); emit setProgress((myTime - from) * 100 / (to - from)); throwIfCancelled(); } } // NOTATION_DEBUG << "NotationStaff " << this << "::positionElements " // << from << " -> " << to << ": " // << elementsPositioned << " elements positioned, " // << elementsRendered << " re-rendered" // << endl; // NotePixmapFactory::dumpStats(std::cerr);}voidNotationStaff::truncateClefsAndKeysAt(int x){ for (FastVector<ClefChange>::iterator i = m_clefChanges.begin(); i != m_clefChanges.end(); ++i) { if (i->first >= x) { m_clefChanges.erase(i, m_clefChanges.end()); break; } } for (FastVector<KeyChange>::iterator i = m_keyChanges.begin(); i != m_keyChanges.end(); ++i) { if (i->first >= x) { m_keyChanges.erase(i, m_keyChanges.end()); break; } }}NotationElementList::iteratorNotationStaff::findUnchangedBarStart(timeT from){ NotationElementList *nel = (NotationElementList *)getViewElementList(); // Track back bar-by-bar until we find one whose start position // hasn't changed NotationElementList::iterator beginAt = nel->begin(); do { from = getSegment().getComposition()->getBarStartForTime(from - 1); beginAt = nel->findTime(from); } while (beginAt != nel->begin() && (beginAt == nel->end() || !elementNotMoved(static_cast<NotationElement*>(*beginAt)))); return beginAt;}NotationElementList::iteratorNotationStaff::findUnchangedBarEnd(timeT to){ NotationElementList *nel = (NotationElementList *)getViewElementList(); // Track forward to the end, similarly. Here however it's very // common for all the positions to have changed right up to the // end of the piece; so we save time by assuming that to be the // case if we get more than (arbitrary) 3 changed bars. // We also record the start of the bar following the changed // section, for later use. NotationElementList::iterator endAt = nel->end(); int changedBarCount = 0; NotationElementList::iterator candidate = nel->end(); do { candidate = nel->findTime(getSegment().getBarEndForTime(to)); if (candidate != nel->end()) { to = (*candidate)->getViewAbsoluteTime(); } ++changedBarCount; } while (changedBarCount < 4 && candidate != nel->end() && !elementNotMoved(static_cast<NotationElement*>(*candidate))); if (changedBarCount < 4) return candidate; else return endAt;}boolNotationStaff::elementNotMoved(NotationElement *elt){ if (!elt->getCanvasItem()) return false; LinedStaffCoords coords = getCanvasCoordsForLayoutCoords (elt->getLayoutX(), (int)elt->getLayoutY());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -