void Clef::layout() { // determine current number of lines and line distance int lines = 5; // assume a resonable default qreal lineDist = 1.0; StaffType* staffType; if (staff() && staff()->staffType()) { staffType = staff()->staffType(); if (!staffType->genClef()) { // if no clef, set empty bbox and do nothing setbbox(QRectF()); return; } // tablatures: if (staffType->group() == TAB_STAFF) { // if current clef type not compatible with tablature, // set tab clef according to score style if (clefTable[clefType()].staffGroup != TAB_STAFF) setClefType( ClefType(score()->styleI(ST_tabClef)) ); } // all staff types: init values from staff type lines = staffType->lines(); lineDist = staffType->lineDistance().val(); } // if nothing changed since last layout, do nothing if (curClefType == clefType() && curLines == lines && curLineDist == lineDist) return; // if something has changed, cache new values and re-layout curClefType = clefType(); curLines = lines; curLineDist = lineDist; layout1(); }
void EditStaff::updateStaffType() { StaffType* staffType = staff->staffType(); lines->setValue(staffType->lines()); lineDistance->setValue(staffType->lineDistance().val()); showClef->setChecked(staffType->genClef()); showTimesig->setChecked(staffType->genTimesig()); showBarlines->setChecked(staffType->showBarlines()); staffGroupName->setText(qApp->translate("Staff type group name", staffType->groupName())); }
void EditStaffType::typeChanged(QListWidgetItem* n, QListWidgetItem* o) { if (n == 0) return; if (o) saveCurrent(o); // retrieve staff type corresponding to new current item in type list int idx = n->data(Qt::UserRole).toInt(); StaffType* st = staffTypes[idx]; // switch to stack page and set props specific to each staff group switch(st->group()) { case STANDARD_STAFF_GROUP: { StaffTypePitched* ps = static_cast<StaffTypePitched*>(st); stack->setCurrentIndex(0); name->setText(st->name()); lines->setValue(st->lines()); lineDistance->setValue(st->lineDistance().val()); genClef->setChecked(st->genClef()); showBarlines->setChecked(st->showBarlines()); genTimesig->setChecked(st->genTimesig()); genKeysigPitched->setChecked(ps->genKeysig()); showLedgerLinesPitched->setChecked(ps->showLedgerLines()); stemlessPitched->setChecked(st->slashStyle()); } break; case TAB_STAFF_GROUP: { StaffTypeTablature* stt = static_cast<StaffTypeTablature*>(st); blockTabPreviewSignals(true); setDlgFromTab(stt); name->setText(stt->name()); // setDlgFromTab() does not copy the name and it shouldn't stack->setCurrentIndex(1); blockTabPreviewSignals(false); } break; case PERCUSSION_STAFF_GROUP: { StaffTypePercussion* ps = static_cast<StaffTypePercussion*>(st); blockPercPreviewSignals(true); setDlgFromPerc(ps); name->setText(ps->name()); // setDlgFromPerc() does not copy the name and it shouldn't stack->setCurrentIndex(2); blockPercPreviewSignals(false); } break; } }
void Stem::layout() { qreal l = _len + _userLen; qreal _up = up() ? -1.0 : 1.0; l *= _up; qreal y1 = 0.0; // vertical displacement to match note attach point Staff* stf = staff(); if (chord()) { int tick = chord()->tick(); StaffType* st = stf->staffType(tick); if (st->isTabStaff() ) { // TAB staves if (st->stemThrough()) { // if stems through staves, gets Y pos. of stem-side note relative to chord other side qreal lineDist = st->lineDistance().val() * spatium(); y1 = (chord()->downString() - chord()->upString()) * _up * lineDist; // if fret marks above lines, raise stem beginning by 1/2 line distance if (!st->onLines()) y1 -= lineDist * 0.5; // shorten stem by 1/2 lineDist to clear the note and a little more to keep 'air' betwen stem and note lineDist *= 0.7 * mag(); y1 += _up * lineDist; } // in other TAB types, no correction } else { // non-TAB // move stem start to note attach point Note* n = up() ? chord()->downNote() : chord()->upNote(); y1 += (up() ? n->stemUpSE().y() : n->stemDownNW().y()); rypos() = n->rypos(); } } qreal lw5 = _lineWidth * .5; line.setLine(0.0, y1, 0.0, l); // compute bounding rectangle QRectF r(line.p1(), line.p2()); setbbox(r.normalized().adjusted(-lw5, -lw5, lw5, lw5)); adjustReadPos(); // does not work if stem is layouted twice }
void Stem::draw(QPainter* painter) const { // hide if second chord of a cross-measure pair if (chord() && chord()->crossMeasure() == CrossMeasure::SECOND) return; Staff* st = staff(); bool useTab = st && st->isTabStaff(); qreal lw = lineWidth(); painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::RoundCap)); painter->drawLine(line); if (!useTab || !chord()) return; // TODO: adjust bounding rectangle in layout() for dots and for slash StaffType* stt = st->staffType(); qreal sp = spatium(); bool _up = up(); // slashed half note stem if (chord()->durationType().type() == TDuration::DurationType::V_HALF && stt->minimStyle() == TablatureMinimStyle::SLASHED) { // position slashes onto stem qreal y = _up ? -(_len+_userLen) + STAFFTYPE_TAB_SLASH_2STARTY_UP*sp : (_len+_userLen) - STAFFTYPE_TAB_SLASH_2STARTY_DN*sp; // if stems through, try to align slashes within or across lines if (stt->stemThrough()) { qreal halfLineDist = stt->lineDistance().val() * sp * 0.5; qreal halfSlashHgt = STAFFTYPE_TAB_SLASH_2TOTHEIGHT * sp * 0.5; y = lrint( (y + halfSlashHgt) / halfLineDist) * halfLineDist - halfSlashHgt; } // draw slashes qreal hlfWdt= sp * STAFFTYPE_TAB_SLASH_WIDTH * 0.5; qreal sln = sp * STAFFTYPE_TAB_SLASH_SLANTY; qreal thk = sp * STAFFTYPE_TAB_SLASH_THICK; qreal displ = sp * STAFFTYPE_TAB_SLASH_DISPL; QPainterPath path; for (int i = 0; i < 2; ++i) { path.moveTo( hlfWdt, y); // top-right corner path.lineTo( hlfWdt, y+thk); // bottom-right corner path.lineTo(-hlfWdt, y+thk+sln); // bottom-left corner path.lineTo(-hlfWdt, y+sln); // top-left corner path.closeSubpath(); y += displ; } painter->setBrush(QBrush(curColor())); painter->setPen(Qt::NoPen); painter->drawPath(path); } // dots // NOT THE BEST PLACE FOR THIS? // with tablatures and stems beside staves, dots are not drawn near 'notes', but near stems int nDots = chord()->dots(); if (nDots > 0 && !stt->stemThrough()) { qreal x = chord()->dotPosX(); qreal y = ( (STAFFTYPE_TAB_DEFAULTSTEMLEN_DN * 0.2) * sp) * (_up ? -1.0 : 1.0); qreal step = score()->styleS(StyleIdx::dotDotDistance).val() * sp; for (int dot = 0; dot < nDots; dot++, x += step) drawSymbol(SymId::augmentationDot, painter, QPointF(x, y)); } }
void Clef::layout() { // determine current number of lines and line distance int lines; qreal lineDist; Segment* clefSeg = segment(); // check clef visibility and type compatibility if (clefSeg && staff()) { StaffType* staffType = staff()->staffType(); bool show = staffType->genClef(); // check staff type allows clef display int tick = clefSeg->tick(); // check clef is compatible with staff type group: if (ClefInfo::staffGroup(clefType()) != staffType->group()) { if (tick > 0 && !generated()) // if clef is not generated, hide it show = false; else // if generated, replace with initial clef type // TODO : instead of initial staff clef (which is assumed to be compatible) // use the last compatible clef previously found in staff _clefTypes = staff()->clefType(0); } // if clef not to show or not compatible with staff group if (!show) { setbbox(QRectF()); qDebug("Clef::layout(): invisible clef at tick %d(%d) staff %d", segment()->tick(), segment()->tick()/1920, staffIdx()); return; } lines = staffType->lines(); // init values from staff type lineDist = staffType->lineDistance().val(); } else { lines = 5; lineDist = 1.0; } qreal _spatium = spatium(); qreal yoff = 0.0; if (clefType() != ClefType::INVALID && clefType() != ClefType::MAX) { symId = ClefInfo::symId(clefType()); yoff = lineDist * (lines - ClefInfo::line(clefType())); } switch (clefType()) { case ClefType::C_19C: // 19th C clef is like a G clef yoff = lineDist * 1.5; break; case ClefType::TAB: // TAB clef // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case ClefType::TAB4: // TAB clef 4 strings // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case ClefType::TAB_SERIF: // TAB clef alternate style // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case ClefType::TAB4_SERIF: // TAB clef alternate style // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case ClefType::PERC: // percussion clefs yoff = lineDist * (lines - 1) * 0.5; break; case ClefType::PERC2: yoff = lineDist * (lines - 1) * 0.5; break; case ClefType::INVALID: case ClefType::MAX: qDebug("Clef::layout: invalid type"); return; default: break; } // clefs are right aligned to Segment QRectF r(symBbox(symId)); // setPos(-r.right(), yoff * _spatium); setPos(0.0, yoff * _spatium); setbbox(r); }
void Clef::layout() { // determine current number of lines and line distance int lines; qreal lineDist; Segment* clefSeg = segment(); qDeleteAll(elements); elements.clear(); // check clef visibility and type compatibility if (clefSeg && staff()) { StaffType* staffType = staff()->staffType(); bool show = staffType->genClef(); // check staff type allows clef display int tick = clefSeg->tick(); // check clef is compatible with staff type group: if (ClefInfo::staffGroup(clefType()) != staffType->group()) { if (tick > 0 && !generated()) // if clef is not generated, hide it show = false; else // if generated, replace with initial clef type // TODO : instead of initial staff clef (which is assumed to be compatible) // use the last compatible clef previously found in staff _clefTypes = staff()->clefType(0); } // if clef not to show or not compatible with staff group if (!show) { setbbox(QRectF()); qDebug("Clef::layout(): invisible clef at tick %d(%d) staff %d", segment()->tick(), segment()->tick()/1920, staffIdx()); return; } lines = staffType->lines(); // init values from staff type lineDist = staffType->lineDistance().val(); } else { lines = 5; lineDist = 1.0; } qreal _spatium = spatium(); qreal yoff = 0.0; Symbol* symbol = new Symbol(score()); switch (clefType()) { case ClefType::G: // G clef on 2nd line symbol->setSym(SymId::gClef); yoff = 3.0 * lineDist; break; case ClefType::G1: // G clef 8va on 2nd line symbol->setSym(SymId::gClef8va); yoff = 3.0 * lineDist; break; case ClefType::G2: // G clef 15ma on 2nd line symbol->setSym(SymId::gClef15ma); yoff = 3.0 * lineDist; break; case ClefType::G3: // G clef 8vb on 2nd line symbol->setSym(SymId::gClef8vb); yoff = 3.0 * lineDist; break; case ClefType::G3_O: // double G clef 8vb on 2nd line symbol->setSym(SymId::gClef8vbOld); yoff = 3.0 * lineDist; break; case ClefType::F: // F clef on penultimate line symbol->setSym(SymId::fClef); yoff = 1.0 * lineDist; break; case ClefType::F8: // F clef 8va bassa on penultimate line symbol->setSym(SymId::fClef8vb); yoff = 1.0 * lineDist; break; case ClefType::F15: // F clef 15ma bassa on penultimate line symbol->setSym(SymId::fClef15mb); yoff = 1.0 * lineDist; break; case ClefType::F_B: // baritone clef symbol->setSym(SymId::fClef); yoff = 2.0 * lineDist; break; case ClefType::F_C: // subbass clef symbol->setSym(SymId::fClef); yoff = 0.0; break; case ClefType::C1: // C clef in 1st line symbol->setSym(SymId::cClef); yoff = 4.0 * lineDist; break; case ClefType::C2: // C clef on 2nd line symbol->setSym(SymId::cClef); yoff = 3.0 * lineDist; break; case ClefType::C3: // C clef in 3rd line symbol->setSym(SymId::cClef); yoff = 2.0 * lineDist; break; case ClefType::C4: // C clef on 4th line symbol->setSym(SymId::cClef); yoff = 1.0 * lineDist; break; case ClefType::C5: // C clef on 5th line symbol->setSym(SymId::cClef); yoff = 0.0; break; case ClefType::TAB: // TAB clef symbol->setSym(SymId::sixStringTabClef); // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case ClefType::TAB2: // TAB clef alternate style symbol->setSym(SymId::sixStringTabClefSerif); // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case ClefType::PERC: // percussion clefs symbol->setSym(SymId::unpitchedPercussionClef1); yoff = lineDist * (lines - 1) * 0.5; break; case ClefType::PERC2: symbol->setSym(SymId::unpitchedPercussionClef2); yoff = lineDist * (lines - 1) * 0.5; break; case ClefType::G4: // G clef in 1st line symbol->setSym(SymId::gClef); yoff = 4.0 * lineDist; break; case ClefType::F_8VA: // F clef 8va on penultimate line symbol->setSym(SymId::fClef8va); yoff = 1.0 * lineDist; break; case ClefType::F_15MA: // F clef 15ma on penultimate line symbol->setSym(SymId::fClef15ma); yoff = 1.0 * lineDist; break; case ClefType::G5: // G clef on 2nd line symbol->setSym(SymId::gClef8vbParens); yoff = 3.0 * lineDist; break; case ClefType::INVALID: case ClefType::MAX: qDebug("Clef::layout: invalid type"); return; } addElement(symbol, .0, yoff * _spatium); QRectF r; for (Element* e : elements) { r |= e->bbox().translated(e->pos()); e->setSelected(selected()); } // clefs are right aligned to Segment QPointF off(-r.right(), 0); for (Element* e : elements) e->move(off); r.translate(off); setbbox(r); setPos(QPointF()); }
void Clef::layout() { setPos(QPoint()); // determine current number of lines and line distance int lines = 5; // assume resonable defaults qreal lineDist = 1.0; Staff* stf = staff(); StaffType* staffType = nullptr; Segment* clefSeg = static_cast<Segment*>(parent()); // check clef visibility and type compatibility if (clefSeg && stf && stf->staffType()) { bool bHide; // check staff type allows clef display staffType = stf->staffType(); bHide = !staffType->genClef(); // check clef is compatible with staff type group int tick = clefSeg->tick(); if (ClefInfo::staffGroup(clefType()) != staffType->group()) { if (tick > 0 && !generated()) // if clef is not generated, hide it bHide = true; else // if generated, replace with initial clef type // TODO : instead of initial staff clef (which is assumed to be compatible) // use the last compatible clef previously found in staff _clefTypes = stf->clefType(0); } // // courtesy clef // bool showClef = true; // only if there is a clef change if (!bHide && tick > 0 ) { Measure* meas = clefSeg->measure(); // courtesy clef: end of last measure measure of system bool courtesy = clefSeg->tick() == meas->endTick() && meas->system() && (meas == meas->system()->lastMeasure() || meas->system()->measures().indexOf(meas) == -1); showClef = // show this clef if: // it is not a courtesy clef !courtesy // or, if courtesy clef: show if score has courtesy clefs on || ( score()->styleB(StyleIdx::genCourtesyClef) // AND measure is not at the end of a repeat or of a section && !( (meas->repeatFlags() & Repeat::END) || meas->isFinalMeasureOfSection() ) // AND this clef has courtesy clef turned on && showCourtesy() ); bHide |= !showClef; } // if clef not to show or not compatible with staff group if (bHide) { qDeleteAll(elements); // set empty bbox and do nothing elements.clear(); setbbox(QRectF()); return; } lines = staffType->lines(); // init values from staff type #if 0 // with fewer than 5 lines, keep clef toward top of staff (ignore line spacing) if (!stf->isPitchedStaff() || lines >= 5) #endif lineDist = staffType->lineDistance().val(); } // if nothing changed since last layout, do nothing //DEBUG if (curClefType == clefType() && curLines == lines && curLineDist == lineDist) // return; // if something has changed, cache new values and re-layout curClefType = clefType(); curLines = lines; curLineDist = lineDist; layout1(); }
void EditStaffType::saveCurrent(QListWidgetItem* o) { bool modif = false; // assume no modifications int idx = o->data(Qt::UserRole).toInt(); StaffType* st = staffTypes[idx]; // if any of the common properties is modified if (name->text() != st->name() || st->lines() != lines->value() || st->lineDistance().val()!= lineDistance->value() || st->genClef() != genClef->isChecked() || st->showBarlines() != showBarlines->isChecked() || st->genTimesig() != genTimesig->isChecked() ) { modif = true; } // or if any of the props specific to each group is modified switch(st->group()) { case STANDARD_STAFF_GROUP: { StaffTypePitched* sp = static_cast<StaffTypePitched*>(st); if (sp->genKeysig() != genKeysigPitched->isChecked() || sp->showLedgerLines() != showLedgerLinesPitched->isChecked() || st->slashStyle() != stemlessPitched->isChecked() ) { modif = true; } } break; case TAB_STAFF_GROUP: { StaffTypeTablature* stt = static_cast<StaffTypeTablature*>(st); TablatureMinimStyle minimStyle = minimNoneRadio->isChecked() ? TAB_MINIM_NONE : (minimShortRadio->isChecked() ? TAB_MINIM_SHORTER : TAB_MINIM_SLASHED); if (stt->durationFontName() != durFontName->currentText() || stt->durationFontSize() != durFontSize->value() || stt->durationFontUserY()!= durY->value() || stt->fretFontName() != fretFontName->currentText() || stt->fretFontSize() != fretFontSize->value() || stt->fretFontUserY() != fretY->value() || stt->linesThrough() != linesThroughRadio->isChecked() || stt->onLines() != onLinesRadio->isChecked() || stt->upsideDown() != upsideDown->isChecked() || stt->useNumbers() != numbersRadio->isChecked() || ( noteValuesNone->isChecked() && (!stt->slashStyle() || stt->genDurations()) ) || ( noteValuesSymb->isChecked() && (!stt->slashStyle() || !stt->genDurations()) ) // if stems, there are more values to take into account || ( noteValuesStems->isChecked()&& ( stt->slashStyle() || stt->genDurations() || stt->stemsDown() != stemBelowRadio->isChecked() || stt->stemThrough() != stemThroughRadio->isChecked() || stt->minimStyle() != minimStyle) ) || stt->showRests() != showRests->isChecked() ) { modif = true; } } break; case PERCUSSION_STAFF_GROUP: { StaffTypePercussion* sp = static_cast<StaffTypePercussion*>(st); if (sp->genKeysig() != genKeysigPercussion->isChecked() || sp->showLedgerLines() != showLedgerLinesPercussion->isChecked() || st->slashStyle() != stemlessPercussion->isChecked() ) { modif = true; } } break; } if (modif) { // save common properties // save-group specific properties if(name->text().isEmpty()) { QString n = createUniqueStaffTypeName(st->group()); name->setText(n); o->setText(n); } switch(st->group()) { case STANDARD_STAFF_GROUP: { StaffTypePitched* stp = static_cast<StaffTypePitched*>(st); stp->setName(name->text()); stp->setLines(lines->value()); stp->setLineDistance(Spatium(lineDistance->value())); stp->setShowBarlines(showBarlines->isChecked()); stp->setGenClef(genClef->isChecked()); stp->setGenTimesig(genTimesig->isChecked()); stp->setGenKeysig(genKeysigPitched->isChecked()); stp->setShowLedgerLines(showLedgerLinesPitched->isChecked()); stp->setSlashStyle(stemlessPitched->isChecked()); } break; case TAB_STAFF_GROUP: { StaffTypeTablature* stt = static_cast<StaffTypeTablature*>(st); setTabFromDlg(stt); } break; case PERCUSSION_STAFF_GROUP: { StaffTypePercussion* stp = static_cast<StaffTypePercussion*>(st); setPercFromDlg(stp); } break; } modified = true; } }
void Clef::layout() { if (curClefType == clefType()) return; qreal smag = _small ? score()->style(ST_smallClefMag).toDouble() : 1.0; qreal _spatium = spatium(); qreal msp = _spatium * smag; qreal yoff = 0.0; qDeleteAll(elements); elements.clear(); curClefType = clefType(); int lines = 5; qreal lineDist = 1.0; #if 0 // TODO: does not work with caching of curClefType if (staff() && staff()->staffType()) { StaffType* staffType = staff()->staffType(); if (staffType->group() == TAB_STAFF) { if (!staffType->genClef()) return; if (clefTable[st].staffGroup != TAB_STAFF) st = ClefType(score()->styleI(ST_tabClef)); } lines = staffType->lines(); lineDist = staffType->lineDistance().val(); } #endif Symbol* symbol = new Symbol(score()); switch (curClefType) { case CLEF_G: symbol->setSym(trebleclefSym); yoff = 3.0; break; case CLEF_G1: { symbol->setSym(trebleclefSym); yoff = 3.0; Symbol* number = new Symbol(score()); number->setMag(smag); number->setSym(clefEightSym); addElement(number, 1.0 * msp, -5.0 * msp + yoff * _spatium); } break; case CLEF_G2: { symbol->setSym(trebleclefSym); yoff = 3.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .6 * msp, -5.0 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, 1.4 * msp, -5.0 * msp + yoff * _spatium); } break; case CLEF_G3: { symbol->setSym(trebleclefSym); yoff = 3.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefEightSym); addElement(number, 1.0 * msp, 4.0 * msp + yoff * _spatium); } break; case CLEF_F: symbol->setSym(bassclefSym); yoff = 1.0; break; case CLEF_F8: { symbol->setSym(bassclefSym); yoff = 1.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefEightSym); addElement(number, .0, 4.5 * msp + yoff * _spatium); } break; case CLEF_F15: { symbol->setSym(bassclefSym); yoff = 1.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .0, 4.5 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, .8 * msp, 4.5 * msp + yoff * _spatium); } break; case CLEF_F_B: // baritone clef symbol->setSym(bassclefSym); yoff = 2.0; break; case CLEF_F_C: // subbass clef symbol->setSym(bassclefSym); yoff = 0.0; break; case CLEF_C1: symbol->setSym(altoclefSym); yoff = 4.0; break; case CLEF_C2: symbol->setSym(altoclefSym); yoff = 3.0; break; case CLEF_C3: symbol->setSym(altoclefSym); yoff = 2.0; break; case CLEF_C4: symbol->setSym(altoclefSym); yoff = 1.0; break; case CLEF_C5: symbol->setSym(altoclefSym); yoff = 0.0; break; case CLEF_TAB: symbol->setSym(tabclefSym); // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case CLEF_TAB2: symbol->setSym(tabclef2Sym); // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case CLEF_PERC: case CLEF_PERC2: symbol->setSym(percussionclefSym); yoff = lineDist * (lines - 1) * 0.5; break; case CLEF_G4: symbol->setSym(trebleclefSym); yoff = 4.0; break; case CLEF_F_8VA: { symbol->setSym(bassclefSym); yoff = 1.0; Symbol* number = new Symbol(score()); number->setMag(smag); number->setSym(clefEightSym); addElement(number, .5 * msp, -1.5 * msp + yoff * _spatium); } break; case CLEF_F_15MA: { symbol->setSym(bassclefSym); yoff = 1.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .0 * msp, -1.5 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, .8 * msp, -1.5 * msp + yoff * _spatium); } break; case CLEF_INVALID: case CLEF_MAX: return; } symbol->setMag(smag * mag()); symbol->layout(); addElement(symbol, .0, yoff * _spatium); setbbox(QRectF()); for (iElement i = elements.begin(); i != elements.end(); ++i) { Element* e = *i; e->setColor(curColor()); addbbox(e->bbox().translated(e->pos())); e->setSelected(selected()); } }
void Clef::layout() { // determine current number of lines and line distance int lines = 5; // assume resonable defaults qreal lineDist = 1.0; Staff* stf = staff(); StaffType* staffType = nullptr; Segment* clefSeg = static_cast<Segment*>(parent()); // check clef visibility and type compatibility if (clefSeg && stf && stf->staffType()) { bool bHide; // check staff type allows clef display staffType = staff()->staffType(); #if 0 // <<<<<<< HEAD if (!staffType->genClef()) { // if no clef, set empty bbox and do nothing qDeleteAll(elements); elements.clear(); setbbox(QRectF()); return; } // tablatures: if (staffType->group() == StaffGroup::TAB) { // if current clef type not compatible with tablature, // set tab clef according to score style if (ClefInfo::staffGroup(clefType()) != StaffGroup::TAB) setClefType( ClefType(score()->styleI(StyleIdx::tabClef)) ); #else bHide = !staffType->genClef(); // check clef is compatible with staff type group int tick = clefSeg->tick(); if (ClefInfo::staffGroup(clefType()) != staffType->group()) { if (tick > 0 && !generated()) // if clef is not generated, hide it bHide = true; else // if generated, replace with initial clef type // TODO : instead of initial staff clef (which is assumed to be compatible) // use the last compatible clef previously found in staff _clefTypes = stf->clefTypeList(0); #endif // >>>>>>> 38c666fa91f5bdaaa6d9ca0645c437c799be8c79 } // // courtesy clef // bool showClef = true; #if 0 // <<<<<<< HEAD Segment* clefSeg = static_cast<Segment*>(parent()); if (clefSeg) { int tick = clefSeg->tick(); // only if there is a clef change if (stf->clef(tick) != stf->clef(tick-1)) { // locate clef at the begining of next measure, if any Clef* clefNext = nullptr; Segment* clefSegNext = nullptr; Measure* meas = static_cast<Measure*>(clefSeg->parent()); Measure* measNext = meas->nextMeasure(); if (measNext) { clefSegNext = measNext->findSegment(SegmentType::Clef, tick); if (clefSegNext) clefNext = static_cast<Clef*>(clefSegNext->element(track())); } // show this clef if: it is not a courtesy clef (no next clef or not at the end of the measure) showClef = !clefNext || (clefSeg->tick() != meas->tick() + meas->ticks()) // if courtesy clef: show if score has courtesy clefs on || ( score()->styleB(StyleIdx::genCourtesyClef) // AND measure is not at the end of a repeat or of a section && !( (meas->repeatFlags() & Repeat::END) || meas->sectionBreak() ) // AND this clef has courtesy clef turned on && showCourtesy() ); if (!showClef) { // if no clef, set empty bbox and do nothing qDeleteAll(elements); elements.clear(); setbbox(QRectF()); return; } #else // only if there is a clef change if (!bHide && tick > 0 && stf->clef(tick) != stf->clef(tick-1)) { // locate clef at the begining of next measure, if any Clef* clefNext = nullptr; Segment* clefSegNext = nullptr; Measure* meas = static_cast<Measure*>(clefSeg->parent()); Measure* measNext = meas->nextMeasure(); if (measNext) { clefSegNext = measNext->findSegment(SegmentType::Clef, tick); if (clefSegNext) clefNext = static_cast<Clef*>(clefSegNext->element(track())); #endif // >>>>>>> 38c666fa91f5bdaaa6d9ca0645c437c799be8c79 } // show this clef if: it is not a courtesy clef (no next clef or not at the end of the measure) showClef = !clefNext || (clefSeg->tick() != meas->tick() + meas->ticks()) // if courtesy clef: show if score has courtesy clefs on || ( score()->styleB(StyleIdx::genCourtesyClef) // AND measure is not at the end of a repeat or of a section && !( (meas->repeatFlags() & Repeat::END) || meas->sectionBreak() ) // AND this clef has courtesy clef turned on && showCourtesy() ); bHide |= !showClef; } // if clef not to show or not compatible with staff group if (bHide) { qDeleteAll(elements); // set empty bbox and do nothing elements.clear(); setbbox(QRectF()); return; } lines = staffType->lines(); // init values from staff type lineDist = staffType->lineDistance().val(); } // if nothing changed since last layout, do nothing //DEBUG if (curClefType == clefType() && curLines == lines && curLineDist == lineDist) // return; // if something has changed, cache new values and re-layout curClefType = clefType(); curLines = lines; curLineDist = lineDist; layout1(); } //--------------------------------------------------------- // layout1 //--------------------------------------------------------- void Clef::layout1() { qreal smag = mag(); qreal _spatium = spatium(); // qreal msp = score()->spatium() * smag; qreal yoff = 0.0; qDeleteAll(elements); elements.clear(); Symbol* symbol = new Symbol(score()); switch (curClefType) { case ClefType::G: // G clef on 2nd line symbol->setSym(SymId::gClef); yoff = 3.0 * curLineDist; break; case ClefType::G1: // G clef 8va on 2nd line symbol->setSym(SymId::gClef8va); yoff = 3.0 * curLineDist; break; case ClefType::G2: // G clef 15ma on 2nd line symbol->setSym(SymId::gClef15ma); yoff = 3.0 * curLineDist; break; case ClefType::G3: // G clef 8vb on 2nd line symbol->setSym(SymId::gClef8vb); yoff = 3.0 * curLineDist; break; case ClefType::F: // F clef on penultimate line symbol->setSym(SymId::fClef); yoff = 1.0 * curLineDist; break; case ClefType::F8: // F clef 8va bassa on penultimate line symbol->setSym(SymId::fClef8vb); yoff = 1.0 * curLineDist; break; case ClefType::F15: // F clef 15ma bassa on penultimate line symbol->setSym(SymId::fClef15mb); yoff = 1.0 * curLineDist; break; case ClefType::F_B: // baritone clef symbol->setSym(SymId::fClef); yoff = 2.0 * curLineDist; break; case ClefType::F_C: // subbass clef symbol->setSym(SymId::fClef); yoff = 0.0; break; case ClefType::C1: // C clef in 1st line symbol->setSym(SymId::cClef); yoff = 4.0 * curLineDist; break; case ClefType::C2: // C clef on 2nd line symbol->setSym(SymId::cClef); yoff = 3.0 * curLineDist; break; case ClefType::C3: // C clef in 3rd line symbol->setSym(SymId::cClef); yoff = 2.0 * curLineDist; break; case ClefType::C4: // C clef on 4th line symbol->setSym(SymId::cClef); yoff = 1.0 * curLineDist; break; case ClefType::C5: // C clef on 5th line symbol->setSym(SymId::cClef); yoff = 0.0; break; case ClefType::TAB: // TAB clef symbol->setSym(SymId::sixStringTabClef); // on tablature, position clef at half the number of spaces * line distance yoff = curLineDist * (curLines - 1) * .5; break; case ClefType::TAB2: // TAB clef alternate style symbol->setSym(SymId::sixStringTabClefSerif); // on tablature, position clef at half the number of spaces * line distance yoff = curLineDist * (curLines - 1) * .5; break; case ClefType::PERC: // percussion clefs case ClefType::PERC2: // no longer supported: fall back to same glyph as PERC symbol->setSym(SymId::unpitchedPercussionClef1); yoff = curLineDist * (curLines - 1) * 0.5; break; case ClefType::G4: // G clef in 1st line symbol->setSym(SymId::gClef); yoff = 4.0 * curLineDist; break; case ClefType::F_8VA: // F clef 8va on penultimate line symbol->setSym(SymId::fClef8va); yoff = 1.0 * curLineDist; break; case ClefType::F_15MA: // F clef 15ma on penultimate line symbol->setSym(SymId::fClef15ma); yoff = 1.0 * curLineDist; break; case ClefType::INVALID: case ClefType::MAX: return; } symbol->setMag(smag); symbol->layout(); addElement(symbol, .0, yoff * _spatium); setbbox(QRectF()); for (auto i = elements.begin(); i != elements.end(); ++i) { Element* e = *i; e->setColor(curColor()); addbbox(e->bbox().translated(e->pos())); e->setSelected(selected()); } } //--------------------------------------------------------- // draw //--------------------------------------------------------- void Clef::draw(QPainter* painter) const { if (staff() && !staff()->staffType()->genClef()) return; QColor color(curColor()); foreach(Element* e, elements) { e->setColor(color); QPointF pt(e->pos()); painter->translate(pt); e->draw(painter); painter->translate(-pt); } }