LineSegment* TextLine::createLineSegment() { TextLineSegment* seg = new TextLineSegment(score()); // note-anchored line segments are relative to system not to staff if (anchor() == Spanner::Anchor::NOTE) seg->setFlag(ElementFlag::ON_STAFF, false); return seg; }
void Text::layout() { if (styled() && !_editMode) { SimpleText::layout(); } else { _doc->setDefaultFont(textStyle().font(spatium())); qreal w = -1.0; qreal x = 0.0; qreal y = 0.0; if (parent() && layoutToParentWidth()) { w = parent()->width(); if (parent()->type() == HBOX || parent()->type() == VBOX || parent()->type() == TBOX) { Box* box = static_cast<Box*>(parent()); x += box->leftMargin() * MScore::DPMM; y += box->topMargin() * MScore::DPMM; w = box->width() - ((box->leftMargin() + box->rightMargin()) * MScore::DPMM); } } QTextOption to = _doc->defaultTextOption(); to.setUseDesignMetrics(true); to.setWrapMode(w <= 0.0 ? QTextOption::NoWrap : QTextOption::WrapAtWordBoundaryOrAnywhere); _doc->setDefaultTextOption(to); if (w < 0.0) w = _doc->idealWidth(); _doc->setTextWidth(w); setbbox(QRectF(QPointF(0.0, 0.0), _doc->size())); if (hasFrame()) layoutFrame(); _doc->setModified(false); textStyle().layout(this); // process alignment #if 0 // TODO TEXT_STYLE_TEXTLINE if ((textStyle().align() & ALIGN_VCENTER) && (textStyle() == TEXT_STYLE_TEXTLINE)) { // special case: vertically centered text with TextLine needs to // take into account the line width TextLineSegment* tls = static_cast<TextLineSegment*>(parent()); TextLine* tl = tls->textLine(); if (tl) { qreal textlineLineWidth = point(tl->lineWidth()); rypos() -= textlineLineWidth * .5; } } #endif rxpos() += x; rypos() += y; } if (parent() && parent()->type() == SEGMENT) { Segment* s = static_cast<Segment*>(parent()); rypos() += s ? s->measure()->system()->staff(staffIdx())->y() : 0.0; } adjustReadPos(); }
void ScoreView::elementPropertyAction(const QString& cmd, Element* e) { if (cmd == "a-props") { ArticulationProperties rp(static_cast<Articulation*>(e)); rp.exec(); } else if (cmd == "b-props") { Bend* bend = static_cast<Bend*>(e); BendProperties bp(bend, 0); if (bp.exec()) score()->undo(new ChangeBend(bend, bp.points())); } else if (cmd == "f-props") { BoxProperties vp(static_cast<Box*>(e), 0); vp.exec(); } else if (cmd == "measure-props") { MeasureProperties vp(static_cast<Note*>(e)->chord()->segment()->measure()); vp.exec(); } else if (cmd == "frame-text") { Text* s = new Text(score()); // s->setSubtype(TEXT_FRAME); s->setTextStyleType(TEXT_STYLE_FRAME); s->setParent(e); score()->undoAddElement(s); score()->select(s, SELECT_SINGLE, 0); startEdit(s); score()->setLayoutAll(true); } else if (cmd == "picture") { mscore->addImage(score(), static_cast<HBox*>(e)); } else if (cmd == "frame-text") { Text* t = new Text(score()); t->setTextStyleType(TEXT_STYLE_FRAME); t->setParent(e); score()->undoAddElement(t); score()->select(t, SELECT_SINGLE, 0); startEdit(t); } else if (cmd == "title-text") { Text* t = new Text(score()); t->setTextStyleType(TEXT_STYLE_TITLE); t->setParent(e); score()->undoAddElement(t); score()->select(t, SELECT_SINGLE, 0); startEdit(t); } else if (cmd == "subtitle-text") { Text* t = new Text(score()); t->setTextStyleType(TEXT_STYLE_SUBTITLE); t->setParent(e); score()->undoAddElement(t); score()->select(t, SELECT_SINGLE, 0); startEdit(t); } else if (cmd == "composer-text") { Text* t = new Text(score()); t->setTextStyleType(TEXT_STYLE_COMPOSER); t->setParent(e); score()->undoAddElement(t); score()->select(t, SELECT_SINGLE, 0); startEdit(t); } else if (cmd == "poet-text") { Text* t = new Text(score()); t->setTextStyleType(TEXT_STYLE_POET); t->setParent(e); score()->undoAddElement(t); score()->select(t, SELECT_SINGLE, 0); startEdit(t); } else if (cmd == "insert-hbox") { HBox* s = new HBox(score()); double w = width() - s->leftMargin() * MScore::DPMM - s->rightMargin() * MScore::DPMM; s->setBoxWidth(Spatium(w / s->spatium())); s->setParent(e); score()->undoAddElement(s); score()->select(s, SELECT_SINGLE, 0); startEdit(s); } else if (cmd == "picture") mscore->addImage(score(), e); else if (cmd == "v-props") { VoltaSegment* vs = static_cast<VoltaSegment*>(e); VoltaProperties vp; vp.setText(vs->volta()->text()); vp.setEndings(vs->volta()->endings()); int rv = vp.exec(); if (rv) { QString txt = vp.getText(); QList<int> l = vp.getEndings(); if (txt != vs->volta()->text()) score()->undoChangeVoltaText(vs->volta(), txt); if (l != vs->volta()->endings()) score()->undoChangeVoltaEnding(vs->volta(), l); } } else if (cmd == "l-props") { TextLineSegment* vs = static_cast<TextLineSegment*>(e); TextLine* nTl = vs->textLine()->clone(); LineProperties lp(nTl); if (lp.exec()) { score()->undoChangeElement(vs->textLine(), nTl); // force new text foreach(SpannerSegment* l, nTl->spannerSegments()) static_cast<TextLineSegment*>(l)->clearText(); } else delete nTl; } else if (cmd == "tr-props") { TremoloBar* tb = static_cast<TremoloBar*>(e); TremoloBarProperties bp(tb, 0); if (bp.exec()) score()->undo(new ChangeTremoloBar(tb, bp.points())); } if (cmd == "ts-courtesy") { TimeSig* ts = static_cast<TimeSig*>(e); score()->undo(new ChangeTimesig(static_cast<TimeSig*>(e), !ts->showCourtesySig(), ts->sig(), ts->stretch(), ts->numeratorString(), ts->denominatorString(), ts->timeSigType())); } else if (cmd == "ts-props") { TimeSig* ts = static_cast<TimeSig*>(e); TimeSig r(*ts); TimeSigProperties vp(&r); int rv = vp.exec(); if (rv) { bool stretchChanged = r.stretch() != ts->stretch(); if (r.numeratorString() != ts->numeratorString() || r.denominatorString() != ts->denominatorString() || r.sig() != ts->sig() || stretchChanged || r.timeSigType() != ts->timeSigType()) { score()->undo(new ChangeTimesig(ts, r.showCourtesySig(), r.sig(), r.stretch(), r.numeratorString(), r.denominatorString(), r.timeSigType())); if (stretchChanged) score()->timesigStretchChanged(ts, ts->measure(), ts->staffIdx()); } } } else if (cmd == "smallAcc") score()->undoChangeProperty(e, P_SMALL, !static_cast<Accidental*>(e)->small()); else if (cmd == "smallNote") score()->undoChangeProperty(e, P_SMALL, !static_cast<Note*>(e)->small()); else if (cmd == "clef-courtesy") { bool show = !static_cast<Clef*>(e)->showCourtesy(); score()->undoChangeProperty(e, P_SHOW_COURTESY, show); } else if (cmd == "d-props") { Dynamic* dynamic = static_cast<Dynamic*>(e); Dynamic* nText = new Dynamic(*dynamic); TextProperties tp(nText, 0); int rv = tp.exec(); if (rv) score()->undoChangeElement(dynamic, nText); else delete nText; } else if (cmd == "st-props") { StaffTextProperties rp(static_cast<StaffText*>(e)); rp.exec(); } else if (cmd == "d-dynamics") { Dynamic* dynamic = static_cast<Dynamic*>(e); int oldVelo = dynamic->velocity(); Element::DynamicRange ot = dynamic->dynRange(); DynamicProperties dp(dynamic); int rv = dp.exec(); if (rv) { int newVelo = dynamic->velocity(); Element::DynamicRange nt = dynamic->dynRange(); dynamic->setVelocity(oldVelo); dynamic->setDynRange(ot); if (newVelo != oldVelo) score()->undoChangeProperty(dynamic, P_VELOCITY, newVelo); if (nt != ot) score()->undoChangeProperty(dynamic, P_DYNAMIC_RANGE, nt); } } else if (cmd == "text-props") { Text* ot = static_cast<Text*>(e); Text* nText = static_cast<Text*>(ot->clone()); TextProperties tp(nText); int rv = tp.exec(); if (rv) { QList<Element*> sl = score()->selection().elements(); QList<Element*> selectedElements; foreach(Element* e, sl) { if (e->type() != ot->type()) continue; Text* t = static_cast<Text*>(e); Text* tt = t->clone(); if (nText->styled() != ot->styled() || nText->styled()) { if (nText->styled()) tt->setTextStyleType(nText->textStyleType()); else tt->setUnstyled(); tt->setModified(true); } if (!nText->styled() && (nText->textStyle() != ot->textStyle())) { tt->setTextStyle(nText->textStyle()); tt->styleChanged(); tt->setModified(true); } if (t->selected()) selectedElements.append(tt); score()->undoChangeElement(t, tt); } score()->select(0, SELECT_SINGLE, 0); foreach(Element* e, selectedElements) score()->select(e, SELECT_ADD, 0); } delete nText; }
void Text::layout() { #if 0 QSizeF pageSize(-1.0, 1000000); setPos(0.0, 0.0); if (parent() && _layoutToParentWidth) { pageSize.setWidth(parent()->width()); if (parent()->type() == HBOX || parent()->type() == VBOX || parent()->type() == TBOX) { Box* box = static_cast<Box*>(parent()); rxpos() += box->leftMargin() * DPMM; rypos() += box->topMargin() * DPMM; // pageSize.setHeight(box->height() - (box->topMargin() + box->bottomMargin()) * DPMM); pageSize.setWidth(box->width() - (box->leftMargin() + box->rightMargin()) * DPMM); } } QTextOption to = _doc->defaultTextOption(); to.setUseDesignMetrics(true); to.setWrapMode(pageSize.width() <= 0.0 ? QTextOption::NoWrap : QTextOption::WrapAtWordBoundaryOrAnywhere); _doc->setDefaultTextOption(to); if (pageSize.width() <= 0.0) _doc->setTextWidth(_doc->idealWidth()); else _doc->setPageSize(pageSize); if (hasFrame()) { frame = QRectF(); for (QTextBlock tb = _doc->begin(); tb.isValid(); tb = tb.next()) { QTextLayout* tl = tb.layout(); int n = tl->lineCount(); for (int i = 0; i < n; ++i) // frame |= tl->lineAt(0).naturalTextRect().translated(tl->position()); frame |= tl->lineAt(0).rect().translated(tl->position()); } if (circle()) { if (frame.width() > frame.height()) { frame.setY(frame.y() + (frame.width() - frame.height()) * -.5); frame.setHeight(frame.width()); } else { frame.setX(frame.x() + (frame.height() - frame.width()) * -.5); frame.setWidth(frame.height()); } } qreal w = (paddingWidth() + frameWidth() * .5) * DPMM; frame.adjust(-w, -w, w, w); w = frameWidth() * DPMM; _bbox = frame.adjusted(-w, -w, w, w); } else { _bbox = QRectF(QPointF(0.0, 0.0), _doc->size()); //_doc->documentLayout()->frameBoundingRect(_doc->rootFrame()); } _doc->setModified(false); style().layout(this); // process alignment if ((style().align() & ALIGN_VCENTER) && (subtype() == TEXT_TEXTLINE)) { // special case: vertically centered text with TextLine needs to // take into account the line width TextLineSegment* tls = (TextLineSegment*)parent(); TextLine* tl = (TextLine*)(tls->line()); qreal textlineLineWidth = point(tl->lineWidth()); rypos() -= textlineLineWidth * .5; } if (parent() == 0) return; if (parent()->type() == SEGMENT) { Segment* s = static_cast<Segment*>(parent()); rypos() += s ? s->measure()->system()->staff(staffIdx())->y() : 0.0; } #endif Font f = style().font(spatium()); qreal asc, desc, leading; qreal w = textMetrics(f.family(), _text, f.size(), &asc, &desc, &leading); // printf("text(%s) asc %f desc %f leading %f w %f\n", qPrintable(_text), asc, desc, leading, w); _lineHeight = asc + desc; _lineSpacing = _lineHeight + leading; _baseLine = asc; setbbox(QRectF(0.0, -asc, w, _lineHeight)); #if 0 if (parent() && _layoutToParentWidth) { qreal wi = parent()->width(); qreal ph = parent()->height(); qreal x; qreal y = pos.y(); if (align() & ALIGN_HCENTER) x = (wi - w) * .5; else if (align() & ALIGN_RIGHT) x = wi - w; else x = 0.0; if (align() & ALIGN_VCENTER) y = (ph - asc) * .5; else if (align() & ALIGN_BOTTOM) y = ph - asc; else y = asc; setPos(x, y + asc); } #endif style().layout(this); // process alignment rypos() += asc; if (parent() && _layoutToParentWidth) { qreal wi = parent()->width(); if (align() & ALIGN_HCENTER) rxpos() = (wi - w) * .5; else if (align() & ALIGN_RIGHT) rxpos() = wi - w; } if ((style().align() & ALIGN_VCENTER) && (subtype() == TEXT_TEXTLINE)) { // special case: vertically centered text with TextLine needs to // take into account the line width TextLineSegment* tls = (TextLineSegment*)parent(); TextLine* tl = (TextLine*)(tls->line()); qreal textlineLineWidth = point(tl->lineWidth()); rypos() -= textlineLineWidth * .5; } if (parent() == 0) return; if (parent()->type() == SEGMENT) { Segment* s = static_cast<Segment*>(parent()); rypos() += s ? s->measure()->system()->staff(staffIdx())->y() : 0.0; } }