void initStaffTypes() { StaffTypePitched* st = new StaffTypePitched(); st->setName("Pitched 5 lines"); st->setBuildin(true); st->setLines(5); st->setLineDistance(Spatium(1.0)); st->setGenClef(true); st->setGenKeysig(true); st->setSlashStyle(false); st->setShowBarlines(true); st->setShowLedgerLines(true); staffTypes.append(st); StaffTypeTablature* stab = new StaffTypeTablature(); stab->setName("Tab"); stab->setBuildin(true); staffTypes.append(stab); StaffTypePercussion* sp = new StaffTypePercussion(); sp->setName("Percussion 5 lines"); sp->setBuildin(true); sp->setLines(5); sp->setLineDistance(Spatium(1.0)); sp->setGenClef(true); sp->setGenKeysig(false); sp->setSlashStyle(false); sp->setShowBarlines(true); sp->setShowLedgerLines(true); staffTypes.append(sp); }
void EditStaffType::updateTabPreview() { // if no preview or current type is not a TAB type, do nothing if(!tabPreview || staffTypes[staffTypeList->currentItem()->data(Qt::UserRole).toInt()]->group() != TAB_STAFF_GROUP) return; // create a new staff type from dlg settings and set it into the preview score StaffTypeTablature* stt = new StaffTypeTablature(); setTabFromDlg(stt); tabPreview->score()->addStaffType(TAB_6COMMON_STAFF_TYPE, stt); tabPreview->score()->doLayout(); #ifdef _USE_NAVIGATOR_PREVIEW_ tabPreview->layoutChanged(); #endif tabPreview->updateAll(); // set preset combo: check stt has the same structure as one of the presets // if none matches, set as custom int idx; int numOfPresets = presetTablatureCombo->count() - 1; // do not count last "Custom" item for(idx=0; idx < numOfPresets; idx++) { int presetIdx = presetTablatureCombo->itemData(idx).toInt(); if(stt->isSameStructure(*StaffType::preset(presetIdx)) ) break; } presetTablatureCombo->blockSignals(true); presetTablatureCombo->setCurrentIndex(idx); presetTablatureCombo->blockSignals(false); }
void Stem::draw(QPainter* painter) const { Staff* st = staff(); bool useTab = st && st->isTabStaff(); if (useTab && st->staffType()->slashStyle()) return; qreal lw = lineWidth(); painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::RoundCap)); painter->drawLine(line); if (!useTab) return; // TODO: adjust bounding rectangle in layout() for dots and for slash StaffTypeTablature* stt = static_cast<StaffTypeTablature*>(st->staffType()); qreal sp = spatium(); // slashed half note stem if (chord() && chord()->durationType().type() == TDuration::V_HALF && stt->minimStyle() == TAB_MINIM_SLASHED) { qreal wdt = sp * STAFFTYPE_TAB_SLASH_WIDTH; qreal sln = sp * STAFFTYPE_TAB_SLASH_SLANTY; qreal thk = sp * STAFFTYPE_TAB_SLASH_THICK; qreal displ = sp * STAFFTYPE_TAB_SLASH_DISPL; QPainterPath path; qreal y = stt->stemsDown() ? _len - STAFFTYPE_TAB_SLASH_2STARTY_DN*sp : -_len + STAFFTYPE_TAB_SLASH_2STARTY_UP*sp; for (int i = 0; i < 2; ++i) { path.moveTo( wdt*0.5-lw, y); // top-right corner path.lineTo( wdt*0.5-lw, y+thk); // bottom-right corner path.lineTo(-wdt*0.5, y+thk+sln);// bottom-left corner path.lineTo(-wdt*0.5, y+sln); // top-left corner path.closeSubpath(); y += displ; } // setbbox(path.boundingRect()); painter->setBrush(QBrush(curColor())); painter->setPen(Qt::NoPen); painter->drawPath(path); } // dots // NOT THE BEST PLACE FOR THIS? // with tablatures, dots are not drawn near 'notes', but near stems int nDots = chord()->dots(); if (nDots > 0) { qreal y = stemLen() - (stt->stemsDown() ? (STAFFTYPE_TAB_DEFAULTSTEMLEN_DN - 0.75) * sp : 0.0 ); symbols[score()->symIdx()][dotSym].draw(painter, magS(), QPointF(STAFFTYPE_TAB_DEFAULTDOTDIST_X * sp, y), nDots); } }
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::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(); if (useTab && st->staffType()->slashStyle()) return; 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 StaffTypeTablature* stt = static_cast<StaffTypeTablature*>(st->staffType()); qreal sp = spatium(); bool _up = up(); // slashed half note stem if (chord()->durationType().type() == TDuration::V_HALF && stt->minimStyle() == TAB_MINIM_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; } // setbbox(path.boundingRect()); 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 y = ( (STAFFTYPE_TAB_DEFAULTSTEMLEN_DN * 0.2) * sp) * (_up ? -1.0 : 1.0); symbols[score()->symIdx()][dotSym].draw(painter, magS(), QPointF(STAFFTYPE_TAB_DEFAULTDOTDIST_X * sp, y), nDots); } }
void Rest::layout() { _space.setLw(0.0); if (parent() && measure() && measure()->multiMeasure()) { _space.setRw(point(score()->styleS(ST_minMMRestWidth))); return; } rxpos() = 0.0; if (staff() && staff()->isTabStaff()) { StaffTypeTablature* tab = (StaffTypeTablature*)staff()->staffType(); // if rests are shown and note values are shown as duration symbols if(tab->showRests() &&tab->genDurations()) { // symbol needed; if not exist, create, if exists, update duration if (!_tabDur) _tabDur = new TabDurationSymbol(score(), tab, durationType().type(), dots()); else _tabDur->setDuration(durationType().type(), dots(), tab); _tabDur->setParent(this); // needed? _tabDur->setTrack(track()); _tabDur->layout(); setbbox(_tabDur->bbox()); setPos(0.0, 0.0); // no rest is drawn: reset any position might be set for it _space.setLw(0.0); _space.setRw(width()); return; } // if no rests or no duration symbols, delete any dur. symbol and chain into standard staff mngmt // this is to ensure horiz space is reserved for rest, even if they are not diplayed // Rest::draw() will skip their drawing, if not needed if(_tabDur) { delete _tabDur; _tabDur = 0; } } switch(durationType().type()) { case TDuration::V_64TH: case TDuration::V_32ND: dotline = -3; break; case TDuration::V_256TH: case TDuration::V_128TH: dotline = -5; break; default: dotline = -1; break; } qreal _spatium = spatium(); int stepOffset = 0; if (staff()) stepOffset = staff()->staffType()->stepOffset(); int line = lrint(userOff().y() / _spatium); // + ((staff()->lines()-1) * 2); qreal lineDist = staff() ? staff()->staffType()->lineDistance().val() : 1.0; int lineOffset = 0; int lines = staff() ? staff()->lines() : 5; if (segment() && measure() && measure()->mstaff(staffIdx())->hasVoices) { // move rests in a multi voice context bool up = (voice() == 0) || (voice() == 2); // TODO: use style values switch(durationType().type()) { case TDuration::V_LONG: lineOffset = up ? -3 : 5; break; case TDuration::V_BREVE: lineOffset = up ? -3 : 5; break; case TDuration::V_MEASURE: if (duration() >= Fraction(2, 1)) // breve symbol lineOffset = up ? -3 : 5; // fall through case TDuration::V_WHOLE: lineOffset = up ? -4 : 6; break; case TDuration::V_HALF: lineOffset = up ? -4 : 4; break; case TDuration::V_QUARTER: lineOffset = up ? -4 : 4; break; case TDuration::V_EIGHT: lineOffset = up ? -4 : 4; break; case TDuration::V_16TH: lineOffset = up ? -6 : 4; break; case TDuration::V_32ND: lineOffset = up ? -6 : 6; break; case TDuration::V_64TH: lineOffset = up ? -8 : 6; break; case TDuration::V_128TH: lineOffset = up ? -8 : 8; break; case TDuration::V_256TH: // not available lineOffset = up ? -10 : 6; break; default: break; } } else { switch(durationType().type()) { case TDuration::V_LONG: case TDuration::V_BREVE: case TDuration::V_MEASURE: case TDuration::V_WHOLE: if (lines == 1) lineOffset = -2; break; case TDuration::V_HALF: case TDuration::V_QUARTER: case TDuration::V_EIGHT: case TDuration::V_16TH: case TDuration::V_32ND: case TDuration::V_64TH: case TDuration::V_128TH: case TDuration::V_256TH: // not available if (lines == 1) lineOffset = -4; break; default: break; } } int yo; _sym = getSymbol(durationType().type(), line + lineOffset/2, lines, &yo); layoutArticulations(); rypos() = (qreal(yo) + qreal(lineOffset + stepOffset) * .5) * lineDist * _spatium; Spatium rs; if (dots()) { rs = Spatium(score()->styleS(ST_dotNoteDistance) + dots() * score()->styleS(ST_dotDotDistance)); } if (dots()) { rs = Spatium(score()->styleS(ST_dotNoteDistance) + dots() * score()->styleS(ST_dotDotDistance)); } setbbox(symbols[score()->symIdx()][_sym].bbox(magS())); _space.setRw(width() + point(rs)); }
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; } }