18 #include "data/model/Model.h" 19 #include "base/ZoomConstraint.h" 20 #include "base/RealTime.h" 21 #include "base/Profiler.h" 25 #include "base/Preferences.h" 34 #include "data/model/WaveFileModel.h" 36 #include <QPaintEvent> 39 #include <QDragEnterEvent> 42 #include <QTextStream> 44 #include <QApplication> 51 #include <QGridLayout> 52 #include <QPushButton> 70 m_identifyFeatures(false),
71 m_clickedInRange(false),
72 m_shiftPressed(false),
79 m_centreLineVisible(true),
81 m_pendingWheelAngle(0),
87 m_mouseInWidget(false),
88 m_playbackFrameMoveScheduled(false),
89 m_playbackFrameMoveTo(0)
91 setObjectName(
"Pane");
92 setMouseTracking(
true);
100 cerr <<
"Pane::Pane(" <<
this <<
") returning" << endl;
106 Profiler profiler(
"Pane::updateHeadsUpDisplay");
108 if (!isVisible())
return;
134 QGridLayout *layout =
new QGridLayout;
135 layout->setMargin(0);
136 layout->setSpacing(0);
140 m_hthumb->setObjectName(tr(
"Horizontal Zoom"));
141 m_hthumb->setCursor(Qt::ArrowCursor);
142 layout->addWidget(
m_hthumb, 1, 0, 1, 2);
147 connect(
m_hthumb, SIGNAL(valueChanged(
int)),
this,
153 m_vpan->setCursor(Qt::ArrowCursor);
154 layout->addWidget(
m_vpan, 0, 1);
155 m_vpan->setFixedWidth(12);
156 m_vpan->setFixedHeight(70);
158 connect(
m_vpan, SIGNAL(rectExtentsChanged(
float,
float,
float,
float)),
160 connect(
m_vpan, SIGNAL(doubleClicked()),
166 m_vthumb->setObjectName(tr(
"Vertical Zoom"));
167 m_vthumb->setCursor(Qt::ArrowCursor);
171 connect(
m_vthumb, SIGNAL(valueChanged(
int)),
this,
183 m_reset->setCursor(Qt::ArrowCursor);
186 m_reset->setIcon(QPixmap(
":/icons/zoom-reset.png"));
187 m_reset->setToolTip(tr(
"Reset zoom to default"));
188 layout->addWidget(
m_reset, 1, 2);
190 layout->setColumnStretch(0, 20);
194 connect(
m_reset, SIGNAL(clicked()),
m_vpan, SLOT(resetToDefault()));
204 bool haveConstraint =
false;
207 if ((*i)->getZoomConstraint() && !(*i)->supportsOtherZoomLevels()) {
208 haveConstraint =
true;
213 if (haveConstraint) {
217 ZoomConstraint::RoundUp);
218 if (newLevel == level)
break;
220 if (++count == 50)
break;
226 int step = level / 10;
239 if (++count == 100 || level > 262144)
break;
258 bool haveVThumb =
false;
285 width() > 120 && height() > 100) {
323 float vmin, vmax, dmin, dmax;
325 float y0 = (dmin - vmin) / (vmax - vmin);
326 float y1 = (dmax - vmin) / (vmax - vmin);
327 m_vpan->blockSignals(
true);
329 m_vpan->blockSignals(
false);
363 bool &closeToRight)
const 372 closeToLeft, closeToRight));
413 if (e) r = e->rect();
420 if (e) paint.setClipRect(r);
432 std::vector<QRect> crosshairExtents;
438 }
else if ((*vi)->isLayerOpaque()) {
445 bool haveSomeTimeXAxis =
false;
447 const Model *waveformModel = 0;
448 const Model *workModel = 0;
452 if (!haveSomeTimeXAxis && (*vi)->hasTimeXAxis()) {
453 haveSomeTimeXAxis =
true;
455 if (dynamic_cast<WaveformLayer *>(*vi)) {
456 waveformModel = (*vi)->getModel();
457 workModel = waveformModel;
459 Model *m = (*vi)->getModel();
460 if (dynamic_cast<WaveFileModel *>(m)) {
462 }
else if (m && dynamic_cast<WaveFileModel *>(m->getSourceModel())) {
463 workModel = m->getSourceModel();
467 if (waveformModel && workModel && haveSomeTimeXAxis)
break;
487 paint.setBrush(Qt::NoBrush);
495 paint.setPen(QColor(50, 50, 50));
504 bool haveWorkTitle =
false;
510 haveWorkTitle =
true;
530 paint.setPen(Qt::blue);
539 bool showFocus =
false;
561 Layer *scaleLayer = 0;
578 scaleLayer = topLayer;
586 if (!hasDisplayExtents) {
588 if (!hasValueExtents) {
595 if ((*vi) == topLayer)
continue;
597 sw = (*vi)->getVerticalScaleWidth
606 }
else if (unit !=
"") {
608 QString requireUnit = unit;
615 if ((*vi) == topLayer)
continue;
617 if ((*vi)->getDisplayExtents(min, max)) {
624 if ((*vi)->getValueExtents(min, max, log, unit) &&
625 unit == requireUnit) {
627 sw = (*vi)->getVerticalScaleWidth
654 paint.setBrush(Qt::NoBrush);
674 paint.fontMetrics().width(tr(
"Some lengthy prefix:"));
677 paint.fontMetrics().boundingRect
679 Qt::AlignRight | Qt::AlignTop | Qt::TextExpandTabs,
683 paint.setPen(Qt::NoPen);
684 paint.setBrush(QColor(250, 250, 250, 200));
686 paint.setPen(Qt::NoPen);
687 paint.setBrush(QColor(50, 50, 50, 200));
690 int extra = paint.fontMetrics().descent();
691 paint.drawRect(width() - boundingRect.width() - 10 - extra,
693 boundingRect.width() + 2 * extra,
694 boundingRect.height() + extra);
697 paint.setPen(QColor(150, 20, 0));
699 paint.setPen(QColor(255, 150, 100));
703 option.setWrapMode(QTextOption::NoWrap);
704 option.setAlignment(Qt::AlignRight | Qt::AlignTop);
705 option.setTabStop(tabStop);
706 paint.drawText(QRectF(width() - boundingRect.width() - 10, 10,
707 boundingRect.width(),
708 boundingRect.height()),
719 int fontHeight = paint.fontMetrics().height();
720 int fontAscent = paint.fontMetrics().ascent();
722 QColor c = QColor(0, 0, 0);
724 c = QColor(240, 240, 240);
731 paint.drawLine(x, 0, x, height() - 1);
732 paint.drawLine(x-1, 1, x+1, 1);
733 paint.drawLine(x-2, 0, x+2, 0);
734 paint.drawLine(x-1, height() - 2, x+1, height() - 2);
735 paint.drawLine(x-2, height() - 1, x+2, height() - 1);
738 paint.setPen(QColor(50, 50, 50));
740 int y = height() - fontHeight + fontAscent - 6;
746 switch ((*--vi)->getPreferredFrameCountPosition()) {
753 y = (height() - fontHeight) / 2
767 QString text(QString::fromStdString
768 (RealTime::frame2RealTime
772 int tw = paint.fontMetrics().width(text);
773 int x = width()/2 - 4 - tw;
780 int x = width()/2 + 4;
797 brush = QBrush(QColor(
"#f8f8f8"));
798 paint.setPen(Qt::black);
800 brush = QBrush(QColor(
"#101010"));
801 paint.setPen(Qt::white);
805 paint.fillRect(0, 0, x0, height(), brush);
806 paint.drawLine(x0, 0, x0, height());
809 if (x1 < r.x() + r.width()) {
810 paint.fillRect(x1, 0, width() - x1, height(), brush);
811 paint.drawLine(x1, 0, x1, height());
821 const Model *reference = model->getAlignmentReference();
832 int completion = 100;
834 if (reference == model) {
835 text = tr(
"Reference");
836 }
else if (!reference) {
837 text = tr(
"Unaligned");
839 completion = model->getAlignmentCompletion();
840 if (completion == 0) {
841 text = tr(
"Unaligned");
842 }
else if (completion < 100) {
843 text = tr(
"Aligning: %1%").arg(completion);
845 text = tr(
"Aligned");
850 QFont font(paint.font());
853 if (completion < 100) paint.setBrush(Qt::red);
856 if (down) y += paint.fontMetrics().height();
857 int w = paint.fontMetrics().width(text);
858 int h = paint.fontMetrics().height();
859 if (r.top() > h + y || r.left() > w +
m_scaleWidth + 5) {
874 update(QRect(0, 0, 300, 100));
880 QString title = model->getTitle();
881 QString maker = model->getMaker();
883 if (title ==
"")
return;
885 QString text = title;
887 text = tr(
"%1 - %2").arg(title).arg(maker);
891 QFont font(paint.font());
892 font.setItalic(
true);
896 int w = paint.fontMetrics().width(text);
897 int h = paint.fontMetrics().height();
898 if (r.top() > h + y || r.left() > w +
m_scaleWidth + 5) {
912 int fontHeight = paint.fontMetrics().height();
913 int fontAscent = paint.fontMetrics().ascent();
915 int lly = height() - 6;
920 if (r.y() + r.height() < lly - int(
m_layerStack.size()) * fontHeight) {
925 std::vector<QPixmap> pixmaps;
927 texts.push_back((*i)->getLayerPresentationName());
930 pixmaps.push_back((*i)->getLayerPresentationPixmap
931 (QSize(fontAscent, fontAscent)));
934 int maxTextWidth = width() / 3;
937 int llx = width() - maxTextWidth - 5;
942 if (r.x() + r.width() >= llx - fontAscent - 3) {
944 for (
int i = 0; i < texts.size(); ++i) {
948 if (i + 1 == texts.size()) {
953 lly - fontHeight + fontAscent,
956 if (!pixmaps[i].isNull()) {
957 paint.drawPixmap(llx - fontAscent - 3,
958 lly - fontHeight + (fontHeight-fontAscent)/2,
989 int fontHeight = paint.fontMetrics().height();
990 int fontAscent = paint.fontMetrics().ascent();
992 QString startText, endText, offsetText;
993 startText = QString(
"%1").arg(newStart);
994 endText = QString(
"%1").arg(newEnd);
995 offsetText = QString(
"%1").arg(newStart - origStart);
996 if (newStart >= origStart) {
997 offsetText = tr(
"+%1").arg(offsetText);
1000 startText = QString(
"%1 / %2")
1001 .arg(QString::fromStdString
1002 (RealTime::frame2RealTime(newStart, sampleRate).toText()))
1004 endText = QString(
"%1 / %2")
1005 .arg(QString::fromStdString
1006 (RealTime::frame2RealTime(newEnd, sampleRate).toText()))
1008 offsetText = QString(
"%1 / %2")
1009 .arg(QString::fromStdString
1010 (RealTime::frame2RealTime(newStart - origStart, sampleRate).toText()))
1012 if (newStart >= origStart) {
1013 offsetText = tr(
"+%1").arg(offsetText);
1024 paint.drawLine(p0, 1, p1, 1);
1025 paint.drawLine(p0, 0, p0, height());
1026 paint.drawLine(p0, height() - 1, p1, height() - 1);
1028 paint.drawLine(p0, 1, p1, 1);
1029 paint.drawLine(p1, 0, p1, height());
1030 paint.drawLine(p0, height() - 1, p1, height() - 1);
1032 paint.setBrush(Qt::NoBrush);
1033 paint.drawRect(p0, 1, p1 - p0, height() - 2);
1040 int sampleRate, QPainter &paint)
1042 int fontHeight = paint.fontMetrics().height();
1043 int fontAscent = paint.fontMetrics().ascent();
1045 if (r.y() + r.height() < height() - fontHeight - 6)
return;
1047 int modelRate = waveformModel->getSampleRate();
1048 int nativeRate = waveformModel->getNativeRate();
1052 QString srNote =
"";
1060 if (playbackRate != 0) {
1061 if (modelRate == playbackRate) {
1062 if (modelRate != outputRate || modelRate != nativeRate) {
1063 srNote =
" " + tr(
"(R)");
1066 srNote =
" " + tr(
"(X)");
1070 QString desc = tr(
"%1 / %2Hz%3")
1071 .arg(RealTime::frame2RealTime(waveformModel->getEndFrame(),
1073 .toText(
false).c_str())
1079 if (x < pbw + 5) x = pbw + 5;
1081 if (r.x() < x + paint.fontMetrics().width(desc)) {
1083 height() - fontHeight + fontAscent - 6,
1107 paint.setBrush(Qt::NoBrush);
1126 height(), QImage::Format_RGB32);
1133 QPainter paint(image);
1144 height(), QImage::Format_RGB32);
1147 QPainter *paint =
new QPainter(image);
1148 if (!
render(*paint, 0, f0, f1)) {
1162 QImage *image =
new QImage(100, 100, QImage::Format_RGB32);
1163 QPainter paint(image);
1174 return QSize(sw + s.width(), s.height());
1182 if (f0 < 0 || f0 <
long(f))
return f;
1189 closeToLeftEdge = closeToRightEdge =
false;
1194 if (testFrame < 0) {
1196 if (testFrame < 0)
return Selection();
1200 if (selection.isEmpty())
return selection;
1206 if (x < lx - fuzz || x > rx + fuzz)
return Selection();
1208 int width = rx - lx;
1210 if (width < 12) fuzz = width / 4;
1211 if (fuzz < 1) fuzz = 1;
1213 if (x < lx + fuzz) closeToLeftEdge =
true;
1214 if (x > rx - fuzz) closeToRightEdge =
true;
1222 float vmin, vmax, dmin, dmax;
1224 if (dmin <= vmin && dmax >= vmax)
return false;
1230 float &dmin,
float &dmax,
1234 if (!layer)
return false;
1239 if (unit) *unit = vunit;
1247 if (!layer)
return false;
1261 tr(
"Zoom in or out in time axis"));
1263 tr(
"Scroll rapidly left or right in time axis"));
1265 tr(
"Zoom in or out in the vertical axis"));
1267 tr(
"Scroll up or down in the vertical axis"));
1269 tr(
"Click middle button and drag to navigate with any tool"));
1271 tr(
"Double-click middle button to relocate with any tool"));
1273 tr(
"Show pane context menu"));
1279 for (
int i =
int(
m_layerStack.size()) - 1; i >= 0; --i) {
1291 if (e->buttons() & Qt::RightButton) {
1318 (e->buttons() & Qt::MidButton) ||
1323 setCursor(Qt::PointingHandCursor);
1330 float vmin, vmax, dmin, dmax;
1347 bool closeToLeft =
false, closeToRight =
false;
1348 Selection selection =
getSelectionAt(e->x(), closeToLeft, closeToRight);
1350 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
1367 int snapFrame = mouseFrame;
1375 if (snapFrame < 0) snapFrame = 0;
1414 std::cerr <<
"mouse pressed in note edit mode" << std::endl;
1440 QTimer::singleShot(QApplication::doubleClickInterval() + 10,
this,
1456 if (e && (e->buttons() & Qt::RightButton)) {
1472 if (mouseFrame < 0) mouseFrame = 0;
1507 if (selection.getEndFrame() < selection.getStartFrame() + 2) {
1508 selection = Selection();
1584 if (!e || (e->buttons() & Qt::RightButton)) {
1590 QPoint pos = e->pos();
1600 if (!(e->buttons() & Qt::LeftButton) &&
1601 !(e->buttons() & Qt::MidButton)) {
1627 bool closeToLeft =
false, closeToRight =
false;
1629 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
1630 setCursor(Qt::SizeHorCursor);
1632 setCursor(Qt::ArrowCursor);
1638 bool updating =
false;
1703 if ((e->modifiers() & Qt::ShiftModifier)) {
1724 QMouseEvent clickEvent(QEvent::MouseButtonPress,
1733 std::cerr <<
"calling edit start" << std::endl;
1752 QMouseEvent moveEvent(QEvent::MouseMove,
1757 std::cerr <<
"calling editDrag" << std::endl;
1767 if ((e->modifiers() & Qt::ShiftModifier)) {
1791 QMouseEvent clickEvent(QEvent::MouseButtonPress,
1818 QMouseEvent moveEvent(QEvent::MouseMove,
1852 int x1 = r.x() + r.width();
1853 int y1 = r.y() + r.height();
1860 if (newStartFrame <= -visibleFrames) {
1861 newStartFrame = -visibleFrames + 1;
1868 float ratio = float(w) / float(width());
1870 int newZoomLevel = (int)nearbyint(
m_zoomLevel * ratio);
1871 if (newZoomLevel < 1) newZoomLevel = 1;
1881 for (LayerList::const_iterator i =
m_layerStack.begin();
1883 if ((*i)->getValueExtents(min, max, log, unit) &&
1884 (*i)->getDisplayExtents(min, max)) {
1892 min = (min < 0.0) ? -log10f(-min) : (min == 0.0) ? 0.0 : log10f(min);
1893 max = (max < 0.0) ? -log10f(-max) : (max == 0.0) ? 0.0 : log10f(max);
1895 float rmin = min + ((max - min) * (height() - y1)) / height();
1896 float rmax = min + ((max - min) * (height() - y0)) / height();
1897 cerr <<
"min: " << min <<
", max: " << max <<
", y0: " << y0 <<
", y1: " << y1 <<
", h: " << height() <<
", rmin: " << rmin <<
", rmax: " << rmax << endl;
1899 rmin = powf(10, rmin);
1900 rmax = powf(10, rmax);
1902 cerr <<
"finally: rmin: " << rmin <<
", rmax: " << rmax <<
" " << unit << endl;
1953 newCentreFrame -= frameOff;
1954 }
else if (newCentreFrame >= frameOff) {
1955 newCentreFrame -= frameOff;
1961 SVDEBUG <<
"Pane::dragTopLayer: newCentreFrame = " << newCentreFrame <<
1967 if (newCentreFrame > 0) --newCentreFrame;
1978 float vmin = 0.f, vmax = 0.f;
1979 float dmin = 0.f, dmax = 0.f;
1986 float perpix = (dmax - dmin) / height();
1987 float valdiff = ydiff * perpix;
1996 if (newmin < vmin) {
1997 newmax += vmin - newmin;
1998 newmin += vmin - newmin;
2000 if (newmax > vmax) {
2001 newmin -= newmax - vmax;
2002 newmax -= newmax - vmax;
2017 bool canMoveHorizontal,
2018 bool canMoveVertical,
2019 bool resistHorizontal,
2020 bool resistVertical)
2022 int xdiff = point.x() - origin.x();
2023 int ydiff = point.y() - origin.y();
2025 int smallThreshold = 10, bigThreshold = 80;
2032 if (abs(ydiff) > smallThreshold &&
2033 abs(ydiff) > abs(xdiff) * 2 &&
2037 }
else if (abs(xdiff) > smallThreshold &&
2038 abs(xdiff) > abs(ydiff) * 2 &&
2039 canMoveHorizontal) {
2042 }
else if (abs(xdiff) > smallThreshold &&
2043 abs(ydiff) > smallThreshold &&
2045 canMoveHorizontal) {
2052 if (abs(xdiff) > bigThreshold) dragMode =
FreeDrag;
2056 if (abs(ydiff) > bigThreshold) dragMode =
FreeDrag;
2060 if (!resistHorizontal && xdiff != 0) {
2063 if (!resistVertical && ydiff != 0) {
2077 int snapFrameLeft = mouseFrame;
2078 int snapFrameRight = mouseFrame;
2090 if (snapFrameLeft < 0) snapFrameLeft = 0;
2091 if (snapFrameRight < 0) snapFrameRight = 0;
2096 min = snapFrameLeft;
2100 max = snapFrameRight;
2102 min = snapFrameLeft;
2103 max = snapFrameRight;
2126 bool doScroll =
false;
2136 if (offset >= available * 0.95) {
2137 move = int(offset - available * 0.95) + 1;
2138 }
else if (offset <= available * 0.10) {
2139 move = int(available * 0.10 - offset) + 1;
2152 if (e->buttons() & Qt::RightButton) {
2156 cerr <<
"mouseDoubleClickEvent" << endl;
2171 (e->buttons() & Qt::MidButton));
2185 if (layer->
editOpen(
this, e)) relocate =
false;
2205 float vmin, vmax, dmin, dmax;
2212 std::cerr <<
"double click in note edit mode" << std::endl;
2234 if (previouslyIdentifying) update();
2247 cerr <<
"wheelEvent, delta " << e->delta() <<
", angleDelta " << e->angleDelta().x() <<
"," << e->angleDelta().y() <<
", pixelDelta " << e->pixelDelta().x() <<
"," << e->pixelDelta().y() <<
", modifiers " << e->modifiers() << endl;
2249 int dx = e->angleDelta().x();
2250 int dy = e->angleDelta().y();
2252 if (dx == 0 && dy == 0) {
2257 bool horizontal =
false;
2259 if (abs(dx) > abs(dy)) {
2262 }
else if (e->modifiers() & Qt::ControlModifier) {
2267 if (e->phase() == Qt::ScrollBegin ||
2270 (d < 0 && m_pendingWheelAngle > 0)) {
2276 if (horizontal && e->pixelDelta().x() != 0) {
2307 cerr <<
"wheelVertical: sign = " << sign << endl;
2309 if (mods & Qt::ShiftModifier) {
2317 }
else if (mods & Qt::AltModifier) {
2332 if (newZoomLevel <= 2) {
2336 (newZoomLevel - 1, ZoomConstraint::RoundDown);
2340 (newZoomLevel + 1, ZoomConstraint::RoundUp);
2354 cerr <<
"wheelHorizontal: sign = " << sign << endl;
2364 cerr <<
"wheelHorizontalFine: pixels = " << pixels << endl;
2394 bool haveConstraint =
false;
2397 if ((*i)->getZoomConstraint() && !(*i)->supportsOtherZoomLevels()) {
2398 haveConstraint =
true;
2403 if (haveConstraint) {
2407 ZoomConstraint::RoundUp);
2408 if (newLevel == level)
break;
2410 if (++count == 50)
break;
2415 int step = level / 10;
2428 if (++count == 100 || level > 262144)
break;
2442 int defaultStep = 0;
2459 float vmin, vmax, dmin, dmax;
2462 float newmax = vmin + ((1.0 - y0) * (vmax - vmin));
2463 float newmin = vmin + ((1.0 - y1) * (vmax - vmin));
2474 float vmin, vmax, dmin, dmax;
2482 tr(
"New vertical display range, from %1 to %2 %4:")
2483 .arg(vmin).arg(vmax).arg(unit),
2484 unit, vmin, vmax,
this);
2487 if (dialog.exec() == QDialog::Accepted) {
2504 QStringList formats(e->mimeData()->formats());
2505 cerr <<
"dragEnterEvent: format: " 2506 << formats.join(
",")
2507 <<
", possibleActions: " << e->possibleActions()
2508 <<
", proposedAction: " << e->proposedAction() << endl;
2510 if (e->mimeData()->hasFormat(
"text/uri-list") ||
2511 e->mimeData()->hasFormat(
"text/plain")) {
2513 if (e->proposedAction() & Qt::CopyAction) {
2514 e->acceptProposedAction();
2516 e->setDropAction(Qt::CopyAction);
2525 cerr <<
"dropEvent: text: \"" << e->mimeData()->text()
2528 if (e->mimeData()->hasFormat(
"text/uri-list") ||
2529 e->mimeData()->hasFormat(
"text/plain")) {
2531 if (e->proposedAction() & Qt::CopyAction) {
2532 e->acceptProposedAction();
2534 e->setDropAction(Qt::CopyAction);
2538 if (e->mimeData()->hasFormat(
"text/uri-list")) {
2540 SVDEBUG <<
"accepting... data is \"" << e->mimeData()->data(
"text/uri-list").data() <<
"\"" << endl;
2542 (e->mimeData()->data(
"text/uri-list").data())
2543 .split(QRegExp(
"[\\r\\n]+"),
2544 QString::SkipEmptyParts));
2547 (e->mimeData()->data(
"text/plain").data()));
2561 bool closeToLeft, closeToRight;
2563 if (s.isEmpty())
return false;
2587 if (offset == 0 || !layer) {
2598 Selection newSelection(f0, f1);
2603 (tr(
"Drag Selection"),
true);
2610 (tr(
"Resize Selection"),
true);
2618 newSelection = Selection(f0, f1);
2639 QBitmap(
":/icons/measure1mask.xbm"),
2642 QBitmap(
":/icons/measure2mask.xbm"),
2649 setCursor(Qt::PointingHandCursor);
2653 setCursor(Qt::ArrowCursor);
2657 setCursor(Qt::UpArrowCursor);
2661 setCursor(Qt::CrossCursor);
2665 setCursor(Qt::CrossCursor);
2674 setCursor(Qt::UpArrowCursor);
2726 RangeMapper *rm = 0;
2766 bool editable =
false;
2774 help = tr(
"Click and drag to navigate");
2782 if (haveSelection) {
2785 help = tr(
"Click and drag to select a range; hold Shift to avoid snapping to items; hold Cmd for multi-select; middle-click and drag to navigate");
2787 help = tr(
"Click and drag to select a range; hold Cmd for multi-select; middle-click and drag to navigate");
2791 help = tr(
"Click and drag to select a range; hold Shift to avoid snapping to items; hold Ctrl for multi-select; middle-click and drag to navigate");
2793 help = tr(
"Click and drag to select a range; hold Ctrl for multi-select; middle-click and drag to navigate");
2798 bool closeToLeft =
false, closeToRight =
false;
2799 Selection selection =
getSelectionAt(pos->x(), closeToLeft, closeToRight);
2800 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
2802 help = tr(
"Click and drag to move the selection boundary");
2807 help = tr(
"Click and drag to select a range; hold Shift to avoid snapping to items; middle-click to navigate");
2809 help = tr(
"Click and drag to select a range; middle-click and drag to navigate");
2817 help = tr(
"Click to add a new item in the active layer");
2824 help = tr(
"Click to erase an item from the active layer");
2831 help = tr(
"Click and drag an item in the active layer to move it; hold Shift to override initial resistance");
2833 bool closeToLeft =
false, closeToRight =
false;
2834 Selection selection =
getSelectionAt(pos->x(), closeToLeft, closeToRight);
2835 if (!selection.isEmpty()) {
2836 help = tr(
"Click and drag to move all items in the selected range");
2848 QWidget *w = dynamic_cast<QWidget *>(sender());
2852 emit
contextHelpChanged(tr(
"Click and drag to adjust the visible range of the vertical scale"));
2858 emit
contextHelpChanged(tr(
"Reset horizontal and vertical zoom levels to their defaults"));
2870 QString indent, QString extraAttributes)
const 2874 QString(
"type=\"pane\" centreLineVisible=\"%1\" height=\"%2\" %3")
void setDefaultValue(int deft)
static QCursor * m_measureCursor1
!! ugh
void drawFeatureDescription(Layer *, QPainter &)
static LayerFactory * getInstance()
int getFrameForX(int x) const
Return the closest frame to the given pixel x-coordinate.
static void registerShortcuts(KeyReference &kr)
virtual QImage * toNewImage()
bool m_playbackFrameMoveScheduled
int getModelsSampleRate() const
virtual int getFirstVisibleFrame() const
bool shouldShowDuration() const
The base class for visual representations of the data found in a Model.
virtual void paintVerticalScale(View *, bool, QPainter &, QRect) const
void setRangeMapper(RangeMapper *mapper)
ToolMode getToolModeFor(const View *v) const
Return override mode if it exists for this view or global mode otherwise.
virtual void wheelEvent(QWheelEvent *e)
int getZoomConstraintBlockSize(int blockSize, ZoomConstraint::RoundingDirection dir=ZoomConstraint::RoundNearest) const
virtual bool hasTimeXAxis() const
virtual void drawStart(View *, QMouseEvent *)
virtual void layerParametersChanged()
View scrolls continuously during playback, keeping the playback position at the centre.
NotifyingPushButton * m_reset
void zoomToRegion(QRect r)
virtual void enterEvent(QEvent *e)
void propertyContainerSelected(PropertyContainer *pc)
virtual bool snapToFeatureFrame(View *, int &, int &resolution, SnapType) const
Adjust the given frame to snap to the nearest feature, if possible.
virtual void eraseDrag(View *, QMouseEvent *)
virtual void splitEnd(View *, QMouseEvent *)
virtual void mouseMoveEvent(QMouseEvent *e)
virtual int getCurrentVerticalZoomStep() const
Get the current vertical zoom step.
bool haveInProgressSelection() const
virtual int getVerticalScaleWidth() const
void drawLayerNames(QRect, QPainter &)
virtual void resizeEvent(QResizeEvent *e)
int getDefaultValue() const
static QCursor * m_measureCursor2
virtual QColor getForeground() const
virtual bool render(QPainter &paint, int x0, int f0, int f1)
virtual void dragEnterEvent(QDragEnterEvent *e)
Selection m_editingSelection
virtual void measureDoubleClick(View *, QMouseEvent *)
virtual int getLayerCount() const
Return the number of layers, regardless of whether visible or dormant, i.e.
static QString abbreviate(QString text, int maxLength, Policy policy=ElideEnd, bool fuzzy=true, QString ellipsis="")
Abbreviate the given text to the given maximum length (including ellipsis), using the given abbreviat...
bool shouldShowVerticalScale() const
void startCompoundOperation(QString name, bool execute)
Start recording commands to batch up into a single compound command.
bool setTopLayerDisplayExtents(float displayMin, float displayMax)
void endCompoundOperation()
Finish recording commands and store the compound command.
void edgeScrollMaybe(int x)
virtual void mouseReleaseEvent(QMouseEvent *e)
void mouseEnteredWidget()
void dragTopLayer(QMouseEvent *e)
virtual bool nearestMeasurementRectChanged(View *, QPoint prev, QPoint now) const
virtual void measureDrag(View *, QMouseEvent *)
void scroll(bool up)
Move up (if up is true) or down a bit.
void dropAccepted(QStringList uriList)
int m_selectionStartFrame
bool shouldIlluminateLocalFeatures() const
int m_editingSelectionEdge
virtual void propertyContainerSelected(View *, PropertyContainer *pc)
virtual void paintEvent(QPaintEvent *e)
virtual bool hasLightBackground() const
void drawVerticalScale(QRect r, Layer *, QPainter &)
void doubleClickSelectInvoked(int frame)
void removeSelection(const Selection &selection)
void addSelection(const Selection &selection)
virtual void drawEnd(View *, QMouseEvent *)
Selection getSelectionAt(int x, bool &closeToLeft, bool &closeToRight) const
virtual Layer * getTopLayer()
Return the "top" layer in the view, whether visible or dormant.
virtual void viewZoomLevelChanged(View *v, int z, bool locked)
virtual void eraseStart(View *, QMouseEvent *)
bool shouldShowFrameCount() const
int getZoomLevel() const
Return the zoom level, i.e.
virtual void splitStart(View *, QMouseEvent *)
virtual void mouseDoubleClickEvent(QMouseEvent *e)
bool hasTopLayerTimeXAxis() const
void setMinimumValue(int min)
virtual bool isLayerEditable() const
This should return true if the layer can be edited by the user.
virtual void addNote(View *, QMouseEvent *)
virtual void setPaintFont(QPainter &paint)
virtual void mousePressEvent(QMouseEvent *e)
void setMaximumValue(int max)
virtual int getFirstVisibleFrame() const
int alignToReference(int) const
void drawEditingSelection(QPainter &)
virtual void moveSelection(Selection, int)
void setPlaybackFrame(int)
void regionOutlined(QRect rect)
virtual void horizontalThumbwheelMoved(int value)
virtual void modelAlignmentCompletionChanged()
virtual bool getDisplayExtents(float &, float &) const
Return the minimum and maximum values within the displayed range for the y axis, if only a subset of ...
void paneInteractedWith()
virtual void toolModeChanged()
virtual bool shouldIlluminateLocalSelection(QPoint &pos, bool &closeToLeft, bool &closeToRight) const
virtual void leaveEvent(QEvent *e)
virtual void paintMeasurementRects(View *, QPainter &, bool showFocus, QPoint focusPoint) const
const Selection & getInProgressSelection(bool &exclusive) const
void setInProgressSelection(const Selection &selection, bool exclusive)
virtual QSize getImageSize()
virtual void setVerticalZoomStep(int)
Set the vertical zoom step.
int getStartFrame() const
Retrieve the first visible sample frame on the widget.
virtual void paintEvent(QPaintEvent *e)
bool shouldShowLayerNames() const
float m_dragStartMinValue
virtual void editVerticalPannerExtents()
Layer * getTopFlexiNoteLayer()
virtual void layerParametersChanged()
bool editSelectionDrag(QMouseEvent *e)
void playbackScheduleTimerElapsed()
virtual bool setDisplayExtents(float, float)
Set the displayed minimum and maximum values for the y axis to the given range, if supported.
bool editSelectionStart(QMouseEvent *e)
void updateVerticalPanner()
void setCategory(QString category)
int getEndFrame() const
Retrieve the last visible sample frame on the widget.
void wheelVertical(int sign, Qt::KeyboardModifiers)
void setSpeed(float speed)
bool getTopLayerDisplayExtents(float &valueMin, float &valueMax, float &displayMin, float &displayMax, QString *unit=0)
bool selectionIsBeingEdited() const
void rightButtonMenuRequested(QPoint position)
bool canTopLayerMoveVertical()
virtual void verticalZoomChanged()
static CommandHistory * getInstance()
virtual QSize getImageSize()
QWidget * m_headsUpDisplay
int getOutputSampleRate() const
The sample rate of the audio output device.
int getProgressBarWidth() const
virtual void eraseEnd(View *, QMouseEvent *)
virtual Layer * getLayer(int n)
Return the nth layer, counted in stacking order.
void drawAlignmentStatus(QRect, QPainter &, const Model *, bool down)
virtual RangeMapper * getNewVerticalZoomRangeMapper() const
Create and return a range mapper for vertical zoom step values.
bool editSelectionEnd(QMouseEvent *e)
bool shouldShowWorkTitle() const
PlaybackFollowMode m_followPlay
void contextHelpChanged(const QString &)
void clearInProgressSelection()
void schedulePlaybackFrameMove(int frame)
virtual void measureEnd(View *, QMouseEvent *)
virtual int getVerticalZoomSteps(int &) const
Get the number of vertical zoom steps available for this layer.
void drawModelTimeExtents(QRect, QPainter &, const Model *)
virtual void editDrag(View *, QMouseEvent *)
void updateHeadsUpDisplay()
virtual bool shouldIlluminateLocalFeatures(const Layer *layer, QPoint &pos) const
int getMaximumValue() const
int getModelsEndFrame() const
LayerType getLayerType(const Layer *)
virtual bool getValueExtents(float &min, float &max, bool &logarithmic, QString &unit) const =0
Return the minimum and maximum values for the y axis of the model in this layer, as well as whether t...
int m_playbackFrameMoveTo
void setSelection(const Selection &selection)
virtual void modelAlignmentCompletionChanged()
void wheelHorizontal(int sign, Qt::KeyboardModifiers)
View is the base class of widgets that display one or more overlaid views of data against a horizonta...
virtual void editStart(View *, QMouseEvent *)
int getPlaybackSampleRate() const
The sample rate that is used for playback.
virtual void mouseMoveEvent(View *v, QMouseEvent *)
void wheelHorizontalFine(int pixels, Qt::KeyboardModifiers)
void drawCentreLine(int, QPainter &, bool omitLine)
virtual void setZoomLevel(int z)
Set the zoom level, i.e.
virtual QString getFeatureDescription(View *, QPoint &) const
virtual void verticalThumbwheelMoved(int value)
virtual void viewZoomLevelChanged(View *, int, bool)
virtual void drawVisibleText(QPainter &p, int x, int y, QString text, TextStyle style) const
bool shouldShowCentreLine() const
const MultiSelection::SelectionList & getSelections() const
virtual void verticalPannerMoved(float x, float y, float w, float h)
virtual void dropEvent(QDropEvent *e)
virtual void measureStart(View *, QMouseEvent *)
void setRectExtents(float x0, float y0, float width, float height)
Set the extents of the panned rectangle within the overall panner widget.
void registerAlternativeShortcut(QAction *, QString alternative)
virtual void resizeSelection(Selection, Selection)
void setCentreFrame(int f)
Set the centre frame of the visible widget.
View follows playback page-by-page, and the play head is moved (by the user) separately from dragging...
virtual void drawDrag(View *, QMouseEvent *)
virtual void editEnd(View *, QMouseEvent *)
DragMode updateDragMode(DragMode currentMode, QPoint origin, QPoint currentPoint, bool canMoveHorizontal, bool canMoveVertical, bool resistHorizontal, bool resistVertical)
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
virtual bool render(QPainter &paint, int x0, int f0, int f1)
void updateContextHelp(const QPoint *pos)
virtual int getVerticalScaleWidth(View *, bool detailed, QPainter &) const =0
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Selection getContainingSelection(int frame, bool defaultToFollowing) const
Return the selection that contains a given frame.
void setStartFrame(int)
Set the widget pan based on the given first visible frame.
virtual void zoomWheelsEnabledChanged()
bool getAlignMode() const
virtual QColor getBackground() const
virtual bool editOpen(View *, QMouseEvent *)
Open an editor on the item under the mouse (e.g.
void registerShortcut(QAction *, QString overrideName="")
void dragExtendSelection(QMouseEvent *e)
virtual Layer * getInteractionLayer()
Return the layer currently active for tool interaction.
void setAlpha(int backgroundAlpha, int thumbAlpha)
bool shouldShowVerticalColourScale() const
void drawWorkTitle(QRect, QPainter &, const Model *)
int getXForFrame(int frame) const
Return the pixel x-coordinate corresponding to a given sample frame (which may be negative).
bool getZoomWheelsEnabled() const
void setCentreLineVisible(bool visible)
void drawDurationAndRate(QRect, const Model *, int, QPainter &)