void QtSegmentControl::mousePressEvent(QMouseEvent *event) { int index = segmentAt(event->pos()); if (segmentEnabled(index)) { d->wasPressed = d->focusIndex = d->pressedIndex = segmentAt(event->pos()); d->postUpdate(d->pressedIndex); } }
QRectF SLine::bbox() const { if (spannerSegments().isEmpty()) return QRectF(); else return segmentAt(0)->bbox(); }
void RadialMap::Widget::mouseMoveEvent( QMouseEvent *e ) { //set m_focus to what we hover over, update UI if it's a new segment Segment const * const oldFocus = m_focus; QPoint p = e->pos(); m_focus = segmentAt( p ); //NOTE p is passed by non-const reference if( m_focus && m_focus->file() != m_tree ) { if( m_focus != oldFocus ) //if not same as last time { setCursor( KCursor::handCursor() ); m_tip->updateTip( m_focus->file(), m_tree ); emit mouseHover( m_focus->file()->fullPath() ); //repaint required to update labels now before transparency is generated repaint( false ); } m_tip->moveTo( e->globalPos(), *this, ( p.y() < 0 ) ); //updates tooltip psuedo-tranparent background } else if( oldFocus && oldFocus->file() != m_tree ) { unsetCursor(); m_tip->hide(); update(); emit mouseHover( QString::null ); } }
void SLine::writeProperties(Xml& xml, const SLine* proto) const { Element::writeProperties(xml); if (_diagonal && (proto == 0 || proto->diagonal() != _diagonal)) xml.tag("diagonal", _diagonal); if (anchor() != ANCHOR_SEGMENT && (proto == 0 || proto->anchor() != anchor())) xml.tag("anchor", anchor()); if (score() == gscore) { // when used as icon if (!spannerSegments().isEmpty()) { LineSegment* s = frontSegment(); xml.tag("length", s->pos2().x()); } else xml.tag("length", spatium() * 4); return; } // // check if user has modified the default layout // bool modified = false; int n = spannerSegments().size(); for (int i = 0; i < n; ++i) { const LineSegment* seg = segmentAt(i); if (!seg->userOff().isNull() || !seg->userOff2().isNull() || !seg->visible()) { modified = true; break; } } if (!modified) return; // // write user modified layout // qreal _spatium = spatium(); for (int i = 0; i < n; ++i) { const LineSegment* seg = segmentAt(i); xml.stag("Segment"); xml.tag("subtype", seg->subtype()); xml.tag("off2", seg->userOff2() / _spatium); seg->Element::writeProperties(xml); xml.etag(); } }
const QRectF& SLine::bbox() const { if (spannerSegments().isEmpty()) setbbox(QRectF()); else setbbox(segmentAt(0)->bbox()); return Element::bbox(); }
void QtSegmentControl::mouseMoveEvent(QMouseEvent *event) { int index = segmentAt(event->pos()); if (index != d->wasPressed) { d->pressedIndex = -1; d->postUpdate(d->wasPressed); } else if (index == d->wasPressed && d->pressedIndex == -1) { d->pressedIndex = d->wasPressed; d->postUpdate(d->wasPressed); } }
/*! \fn QString QVersionNumber::toString() const Returns a string with all of the segments delimited by a '.'. \sa majorVersion(), minorVersion(), microVersion(), segments() */ QString QVersionNumber::toString() const { QString version; version.reserve(qMax(segmentCount() * 2 - 1, 0)); bool first = true; for (int i = 0; i < segmentCount(); ++i) { if (!first) version += QLatin1Char('.'); version += QString::number(segmentAt(i)); first = false; } return version; }
void QtSegmentControl::mouseReleaseEvent(QMouseEvent *event) { int index = segmentAt(event->pos()); // This order of reset is important. d->pressedIndex = -1; if (index == d->wasPressed && d->selectionBehavior != SelectNone) { if (d->selectionBehavior == SelectAll) { setSegmentSelected(index, !d->segments[index].selected); } else { setSegmentSelected(index, true); } } d->postUpdate(index); d->wasPressed = -1; }
void SLine::layout() { if (parent() == 0) { // // when used in a palette, SLine has no parent and // tick and tick2 has no meaning so no layout is // possible and needed // if (!spannerSegments().isEmpty()) { LineSegment* s = frontSegment(); s->layout(); setbbox(s->bbox()); } return; } if (startElement() == 0 || endElement() == 0) { qDebug("SLine::layout() failed: %s %s\n", parent()->name(), name()); qDebug(" start %p end %p\n", startElement(), endElement()); return; } System* s1; System* s2; QPointF p1 = linePos(GRIP_LINE_START, &s1); QPointF p2 = linePos(GRIP_LINE_END, &s2); QList<System*>* systems = score()->systems(); int sysIdx1 = systems->indexOf(s1); int sysIdx2 = systems->indexOf(s2); int segmentsNeeded = 0; for (int i = sysIdx1; i < sysIdx2+1; ++i) { if (systems->at(i)->isVbox()) continue; ++segmentsNeeded; } int segCount = spannerSegments().size(); if (segmentsNeeded != segCount) { if (segmentsNeeded > segCount) { int n = segmentsNeeded - segCount; for (int i = 0; i < n; ++i) { LineSegment* ls = createLineSegment(); add(ls); // set user offset to previous segment's offset if (segCount > 0) ls->setUserOff(QPointF(0, segmentAt(segCount+i-1)->userOff().y())); } } else { int n = segCount - segmentsNeeded; qDebug("SLine: segments %d needed %d, remove %d\n", segCount, segmentsNeeded, n); for (int i = 0; i < n; ++i) { if (spannerSegments().isEmpty()) { qDebug("SLine::layout(): no segment %d, %d expected\n", i, n); break; } else { // LineSegment* seg = takeLastSegment(); // TODO delete seg; } } } } int segIdx = 0; int si = staffIdx(); for (int i = sysIdx1; i <= sysIdx2; ++i) { System* system = systems->at(i); if (system->isVbox()) continue; LineSegment* seg = segmentAt(segIdx++); seg->setSystem(system); Measure* m = system->firstMeasure(); qreal x1 = m->first(SegChordRest)->pos().x() + m->pos().x(); qreal x2 = system->bbox().right(); qreal y = system->staff(si)->y(); if (sysIdx1 == sysIdx2) { // single segment seg->setSubtype(SEGMENT_SINGLE); seg->setPos(p1); seg->setPos2(QPointF(p2.x() - p1.x(), 0.0)); } else if (i == sysIdx1) { // start segment seg->setSubtype(SEGMENT_BEGIN); seg->setPos(p1); seg->setPos2(QPointF(x2 - p1.x(), 0.0)); } else if (i > 0 && i != sysIdx2) { // middle segment seg->setSubtype(SEGMENT_MIDDLE); seg->setPos(QPointF(x1, y)); seg->setPos2(QPointF(x2 - x1, 0.0)); } else if (i == sysIdx2) { // end segment seg->setSubtype(SEGMENT_END); seg->setPos(QPointF(x1, y)); seg->setPos2(QPointF(p2.x() - x1, 0.0)); } seg->layout(); seg->rypos() += (_yoffset * spatium()); seg->adjustReadPos(); } }
void Tie::layout() { qreal _spatium = spatium(); // // show short bow // if (startNote() == 0 || endNote() == 0) { if (startNote() == 0) { qDebug("Tie::layout(): no start note"); return; } Chord* c1 = startNote()->chord(); if (_slurDirection == MScore::Direction::AUTO) { if (c1->measure()->mstaff(c1->staffIdx())->hasVoices) { // in polyphonic passage, ties go on the stem side _up = c1->up(); } else _up = !c1->up(); } else _up = _slurDirection == MScore::Direction::UP ? true : false; fixupSegments(1); SlurSegment* segment = segmentAt(0); segment->setSpannerSegmentType(SpannerSegmentType::SINGLE); segment->setSystem(startNote()->chord()->segment()->measure()->system()); SlurPos sPos; slurPos(&sPos); segment->layout(sPos.p1, sPos.p2); return; } calculateDirection(); qreal w = startNote()->headWidth(); qreal xo1 = w * 1.12; qreal h = w * 0.3; qreal yo = _up ? -h : h; QPointF off1(xo1, yo); QPointF off2(0.0, yo); #if 0 // yet(?) unused QPointF ppos(pagePos()); #endif // TODO: cleanup SlurPos sPos; slurPos(&sPos); // p1, p2, s1, s2 QList<System*>* systems = score()->systems(); setPos(0, 0); //--------------------------------------------------------- // count number of segments, if no change, all // user offsets (drags) are retained //--------------------------------------------------------- int sysIdx1 = systems->indexOf(sPos.system1); if (sysIdx1 == -1) { qDebug("system not found"); foreach(System* s, *systems) qDebug(" search %p in %p", sPos.system1, s); return; } int sysIdx2 = systems->indexOf(sPos.system2); if (sysIdx2 < 0) sysIdx2 = sysIdx1; unsigned nsegs = sysIdx2 - sysIdx1 + 1; fixupSegments(nsegs); int i = 0; for (uint ii = 0; ii < nsegs; ++ii) { System* system = (*systems)[sysIdx1++]; if (system->isVbox()) continue; SlurSegment* segment = segmentAt(i); segment->setSystem(system); // case 1: one segment if (sPos.system1 == sPos.system2) { segment->layout(sPos.p1, sPos.p2); segment->setSpannerSegmentType(SpannerSegmentType::SINGLE); } // case 2: start segment else if (i == 0) { qreal x = system->bbox().width(); segment->layout(sPos.p1, QPointF(x, sPos.p1.y())); segment->setSpannerSegmentType(SpannerSegmentType::BEGIN); } // case 4: end segment else { qreal x = firstNoteRestSegmentX(system) - 2 * _spatium; segment->layout(QPointF(x, sPos.p2.y()), sPos.p2); segment->setSpannerSegmentType(SpannerSegmentType::END); } ++i; } }
void Glissando::layout() { qreal _spatium = spatium(); if (score() == gscore // for use in palettes || startElement() == nullptr || endElement() == nullptr) { // or while dragging if (spannerSegments().isEmpty()) add(createLineSegment()); LineSegment* s = frontSegment(); s->setPos(QPointF()); s->setPos2(QPointF(_spatium * GLISS_PALETTE_WIDTH, -_spatium * GLISS_PALETTE_HEIGHT)); s->layout(); return; } SLine::layout(); setPos(0.0, 0.0); adjustReadPos(); Note* anchor1 = static_cast<Note*>(startElement()); Note* anchor2 = static_cast<Note*>(endElement()); Chord* cr1 = anchor1->chord(); Chord* cr2 = anchor2->chord(); GlissandoSegment* segm1 = static_cast<GlissandoSegment*>(frontSegment()); GlissandoSegment* segm2 = static_cast<GlissandoSegment*>(backSegment()); // Note: line segments are defined by // initial point: ipos() (relative to system origin) // ending point: pos2() (relative to initial point) // LINE ENDING POINTS TO NOTE HEAD CENTRES // assume gliss. line goes from centre of initial note centre to centre of ending note: // move first segment origin and last segment ending point from note head origin to note head centre QPointF offs1 = QPointF(anchor1->headWidth() * 0.5, 0.0); QPointF offs2 = QPointF(anchor2->headWidth() * 0.5, 0.0); // AVOID HORIZONTAL LINES int upDown = (0 < (anchor2->pitch() - anchor1->pitch())) - ((anchor2->pitch() - anchor1->pitch()) < 0); // on TAB's, glissando are by necessity on the same string, this gives an horizontal glissando line; // make bottom end point lower and top ending point higher if (cr1->staff()->isTabStaff()) { qreal yOff = cr1->staff()->lineDistance() * 0.3 * _spatium; offs1.ry() += yOff * upDown; offs2.ry() -= yOff * upDown; } // if not TAB, angle glissando between notes on the same line else { if (anchor1->line() == anchor2->line()) { offs1.ry() += _spatium * 0.25 * upDown; offs2.ry() -= _spatium * 0.25 * upDown; } } // move initial point of first segment and adjust its length accordingly segm1->setPos (segm1->ipos() + offs1); segm1->setPos2(segm1->ipos2() - offs1); // adjust ending point of last segment segm2->setPos2(segm2->ipos2() + offs2); // FINAL SYSTEM-INITIAL NOTE // if the last gliss. segment attaches to a system-initial note, some extra width has to be added if (cr2->segment()->measure() == cr2->segment()->system()->firstMeasure() && cr2->rtick() == 0) { segm2->rxpos() -= GLISS_STARTOFSYSTEM_WIDTH * _spatium; segm2->rxpos2()+= GLISS_STARTOFSYSTEM_WIDTH * _spatium; } // INTERPOLATION OF INTERMEDIATE POINTS // This probably belongs to SLine class itself; currently it does not seem // to be needed for anything else than Glissando, though // get total x-width and total y-height of all segments qreal xTot = 0.0; for (SpannerSegment* segm : spannerSegments()) xTot += segm->ipos2().x(); qreal y0 = segm1->ipos().y(); qreal yTot = segm2->ipos().y() + segm2->ipos2().y() - y0; qreal ratio = yTot / xTot; // interpolate y-coord of intermediate points across total width and height qreal xCurr = 0.0; qreal yCurr; for (int i = 0; i < spannerSegments().count()-1; i++) { SpannerSegment* segm = segmentAt(i); xCurr += segm->ipos2().x(); yCurr = y0 + ratio * xCurr; segm->rypos2() = yCurr - segm->ipos().y(); // position segm. end point at yCurr // next segment shall start where this segment stopped segm = segmentAt(i+1); segm->rypos2() += segm->ipos().y() - yCurr; // adjust next segm. vertical length segm->rypos() = yCurr; // position next segm. start point at yCurr } // STAY CLEAR OF NOTE APPENDAGES // initial note dots / ledger line / note head offs1 *= -1.0; // discount changes already applied int dots = cr1->dots(); LedgerLine * ledLin = cr1->ledgerLines(); // if dots, start at right of last dot // if no dots, from right of ledger line, if any; from right of note head, if no ledger line offs1.rx() += (dots && anchor1->dot(dots-1) ? anchor1->dot(dots-1)->pos().x() + anchor1->dot(dots-1)->width() : (ledLin ? ledLin->pos().x() + ledLin->width() : anchor1->headWidth()) ); // final note arpeggio / accidental / ledger line / accidental / arpeggio (i.e. from outermost to innermost) offs2 *= -1.0; // discount changes already applied if (Arpeggio* a = cr2->arpeggio()) offs2.rx() += a->pos().x() + a->userOff().x(); else if (Accidental* a = anchor2->accidental()) offs2.rx() += a->pos().x() + a->userOff().x(); else if ( (ledLin = cr2->ledgerLines()) != nullptr) offs2.rx() += ledLin->pos().x(); // add another a quarter spatium of 'air' offs1.rx() += _spatium * 0.25; offs2.rx() -= _spatium * 0.25; // apply offsets: shorten first segment by x1 (and proportionally y) and adjust its length accordingly offs1.ry() = segm1->ipos2().y() * offs1.x() / segm1->ipos2().x(); segm1->setPos(segm1->ipos() + offs1); segm1->setPos2(segm1->ipos2() - offs1); // adjust last segment length by x2 (and proportionally y) offs2.ry() = segm2->ipos2().y() * offs2.x() / segm2->ipos2().x(); segm2->setPos2(segm2->ipos2() + offs2); for (SpannerSegment* segm : spannerSegments()) static_cast<GlissandoSegment*>(segm)->layout(); // compute glissando bbox as the bbox of the last segment, relative to the end anchor note QPointF anchor2PagePos = anchor2->pagePos(); QPointF system2PagePos = cr2->segment()->system()->pagePos(); QPointF anchor2SystPos = anchor2PagePos - system2PagePos; QRectF r = QRectF(anchor2SystPos - segm2->pos(), anchor2SystPos - segm2->pos() - segm2->pos2()).normalized(); qreal lw = _spatium * lineWidth().val() * .5; setbbox(r.adjusted(-lw, -lw, lw, lw)); }
void LyricsLine::layout() { bool tempMelismaTicks = (lyrics()->ticks() == Lyrics::TEMP_MELISMA_TICKS); if (lyrics()->ticks()) { // melisma setLineWidth(score()->styleP(Sid::lyricsLineThickness)); // if lyrics has a temporary one-chord melisma, set to 0 ticks (just its own chord) if (tempMelismaTicks) lyrics()->setTicks(0); // Lyrics::_ticks points to the beginning of the last spanned segment, // but the line shall include it: // include the duration of this last segment in the melisma duration Segment* lyricsSegment = lyrics()->segment(); int lyricsStartTick = lyricsSegment->tick(); int lyricsEndTick = lyrics()->endTick(); int lyricsTrack = lyrics()->track(); // find segment with tick >= endTick Segment* s = lyricsSegment; while (s && s->tick() < lyricsEndTick) s = s->nextCR(lyricsTrack, true); if (!s) { // user probably deleted measures at end of score, leaving this melisma too long // set s to last segment and reset lyricsEndTick to trigger FIXUP code below s = score()->lastSegment(); lyricsEndTick = -1; } Element* se = s->element(lyricsTrack); // everything is OK if we have reached a chord at right tick on right track if (s->tick() == lyricsEndTick && se && se->type() == ElementType::CHORD) { // advance to next CR, or last segment if no next CR s = s->nextCR(lyricsTrack, true); if (!s) s = score()->lastSegment(); } else { // FIXUP - lyrics tick count not valid // this happens if edits to score have removed the original end segment // so let's fix it here // s is already pointing to segment past endTick (or to last segment) // we should shorten the lyrics tick count to make this work Segment* ns = s; Segment* ps = s->prev1(SegmentType::ChordRest); while (ps && ps != lyricsSegment) { Element* pe = ps->element(lyricsTrack); // we're looking for an actual chord on this track if (pe && pe->type() == ElementType::CHORD) break; s = ps; ps = ps->prev1(SegmentType::ChordRest); } if (!ps || ps == lyricsSegment) { // no valid previous CR, so try to lengthen melisma instead ps = ns; s = ps->nextCR(lyricsTrack, true); Element* e = s ? s->element(lyricsTrack) : nullptr; // check to make sure we have a chord if (!e || e->type() != ElementType::CHORD) { // nothing to do but set ticks to 0 // this will result in melisma being deleted later lyrics()->undoChangeProperty(Pid::LYRIC_TICKS, 0); setTicks(0); return; } } lyrics()->undoChangeProperty(Pid::LYRIC_TICKS, ps->tick() - lyricsStartTick); } setTicks(s->tick() - lyricsStartTick); } else { // dash(es) _nextLyrics = searchNextLyrics(lyrics()->segment(), staffIdx(), lyrics()->no(), lyrics()->placement()); setTick2(_nextLyrics ? _nextLyrics->segment()->tick() : tick()); } if (ticks()) { // only do layout if some time span // do layout with non-0 duration if (tempMelismaTicks) lyrics()->setTicks(Lyrics::TEMP_MELISMA_TICKS); SLine::layout(); // if temp melisma and there is a first line segment, // extend it to be after the lyrics syllable (otherwise // the melisma segment will be often covered by the syllable itself) if (tempMelismaTicks && segments.size() > 0) segmentAt(0)->rxpos2() += lyrics()->width(); } }
void RadialMap::Widget::mouseMoveEvent(QMouseEvent *e) { //set m_focus to what we hover over, update UI if it's a new segment Segment const * const oldFocus = m_focus; QPoint p = e->pos(); m_focus = segmentAt(p); //NOTE p is passed by non-const reference if (m_focus) { m_tooltip.move(e->globalX() + 20, e->globalY() + 20); if (m_focus != oldFocus) //if not same as last time { setCursor(Qt::PointingHandCursor); QString string = m_focus->file()->fullPath(m_tree) + QLatin1Char('\n') + m_focus->file()->humanReadableSize(); if (m_focus->file()->isFolder()) { int files = static_cast<const Folder*>(m_focus->file())->children(); const uint percent = uint((100 * files) / (double)m_tree->children()); string += QLatin1Char('\n'); string += i18np("File: %1", "Files: %1", files); if (percent > 0) string += QString(QLatin1String(" (%1%)")).arg(percent); } const QUrl url = Widget::url(m_focus->file()); if (m_focus == m_rootSegment && url != KIO::upUrl(url)) { string += i18n("\nClick to go up to parent directory"); } // Calculate a semi-sane size for the tooltip QFontMetrics fontMetrics(font()); int tooltipWidth = 0; int tooltipHeight = 0; for (const QString &part : string.split(QLatin1Char('\n'))) { tooltipHeight += fontMetrics.height(); tooltipWidth = qMax(tooltipWidth, fontMetrics.width(part)); } // Limit it to the window size, probably should find something better tooltipWidth = qMin(tooltipWidth, window()->width()); tooltipWidth += 10; tooltipHeight += 10; m_tooltip.resize(tooltipWidth, tooltipHeight); m_tooltip.setText(string); m_tooltip.show(); emit mouseHover(m_focus->file()->fullPath()); update(); } } else if (oldFocus && oldFocus->file() != m_tree) { m_tooltip.hide(); unsetCursor(); update(); emit mouseHover(QString()); } }
QT_BEGIN_NAMESPACE /*! \class QVersionNumber \inmodule QtCore \since 5.6 \brief The QVersionNumber class contains a version number with an arbitrary number of segments. \snippet qversionnumber/main.cpp 0 */ /*! \fn QVersionNumber::QVersionNumber() Produces a null version. \sa isNull() */ /*! \fn QVersionNumber::QVersionNumber(int maj) Constructs a QVersionNumber consisting of just the major version number \a maj. */ /*! \fn QVersionNumber::QVersionNumber(int maj, int min) Constructs a QVersionNumber consisting of the major and minor version numbers \a maj and \a min, respectively. */ /*! \fn QVersionNumber::QVersionNumber(int maj, int min, int mic) Constructs a QVersionNumber consisting of the major, minor, and micro version numbers \a maj, \a min and \a mic, respectively. */ /*! \fn QVersionNumber::QVersionNumber(const QVector<int> &seg) Constructs a version number from the list of numbers contained in \a seg. */ /*! \fn QVersionNumber::QVersionNumber(QVector<int> &&seg) Move-constructs a version number from the list of numbers contained in \a seg. This constructor is only enabled if the compiler supports C++11 move semantics. */ /*! \fn QVersionNumber::QVersionNumber(std::initializer_list<int> args) Construct a version number from the std::initializer_list specified by \a args. This constructor is only enabled if the compiler supports C++11 initializer lists. */ /*! \fn bool QVersionNumber::isNull() const Returns \c true if there are zero numerical segments, otherwise returns \c false. \sa segments() */ /*! \fn bool QVersionNumber::isNormalized() const Returns \c true if the version number does not contain any trailing zeros, otherwise returns \c false. \sa normalized() */ /*! \fn int QVersionNumber::majorVersion() const Returns the major version number, that is, the first segment. This function is equivalent to segmentAt(0). If this QVersionNumber object is null, this function returns 0. \sa isNull(), segmentAt() */ /*! \fn int QVersionNumber::minorVersion() const Returns the minor version number, that is, the second segment. This function is equivalent to segmentAt(1). If this QVersionNumber object does not contain a minor number, this function returns 0. \sa isNull(), segmentAt() */ /*! \fn int QVersionNumber::microVersion() const Returns the micro version number, that is, the third segment. This function is equivalent to segmentAt(2). If this QVersionNumber object does not contain a micro number, this function returns 0. \sa isNull(), segmentAt() */ /*! \fn const QVector<int>& QVersionNumber::segments() const Returns all of the numerical segments. \sa majorVersion(), minorVersion(), microVersion() */ QVector<int> QVersionNumber::segments() const { if (m_segments.isUsingPointer()) return *m_segments.pointer_segments; QVector<int> result; result.resize(segmentCount()); for (int i = 0; i < segmentCount(); ++i) result[i] = segmentAt(i); return result; }