Mercurial > hg > svgui
comparison view/View.cpp @ 374:64e84e5efb76 spectrogram-cache-rejig
* Merge from trunk
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 11:59:42 +0000 |
parents | b6df8b44b98d |
children |
comparison
equal
deleted
inserted
replaced
332:6440e280122e | 374:64e84e5efb76 |
---|---|
17 #include "layer/Layer.h" | 17 #include "layer/Layer.h" |
18 #include "data/model/Model.h" | 18 #include "data/model/Model.h" |
19 #include "base/ZoomConstraint.h" | 19 #include "base/ZoomConstraint.h" |
20 #include "base/Profiler.h" | 20 #include "base/Profiler.h" |
21 #include "base/Pitch.h" | 21 #include "base/Pitch.h" |
22 #include "base/Preferences.h" | |
22 | 23 |
23 #include "layer/TimeRulerLayer.h" | 24 #include "layer/TimeRulerLayer.h" |
24 #include "layer/SingleColourLayer.h" | 25 #include "layer/SingleColourLayer.h" |
25 #include "data/model/PowerOfSqrtTwoZoomConstraint.h" | 26 #include "data/model/PowerOfSqrtTwoZoomConstraint.h" |
26 #include "data/model/RangeSummarisableTimeValueModel.h" | 27 #include "data/model/RangeSummarisableTimeValueModel.h" |
29 #include <QPaintEvent> | 30 #include <QPaintEvent> |
30 #include <QRect> | 31 #include <QRect> |
31 #include <QApplication> | 32 #include <QApplication> |
32 #include <QProgressDialog> | 33 #include <QProgressDialog> |
33 #include <QTextStream> | 34 #include <QTextStream> |
35 #include <QFont> | |
34 | 36 |
35 #include <iostream> | 37 #include <iostream> |
36 #include <cassert> | 38 #include <cassert> |
37 #include <math.h> | 39 #include <math.h> |
38 | 40 |
324 update(); | 326 update(); |
325 | 327 |
326 changeVisible = true; | 328 changeVisible = true; |
327 } | 329 } |
328 | 330 |
329 if (e) emit centreFrameChanged(alignFromReference(f), | 331 if (e) { |
330 m_followPan, m_followPlay); | 332 size_t rf = alignToReference(f); |
333 #ifdef DEBUG_VIEW_WIDGET_PAINT | |
334 std::cerr << "View[" << this << "]::setCentreFrame(" << f | |
335 << "): emitting centreFrameChanged(" | |
336 << rf << ")" << std::endl; | |
337 #endif | |
338 emit centreFrameChanged(rf, m_followPan, m_followPlay); | |
339 } | |
331 } | 340 } |
332 | 341 |
333 return changeVisible; | 342 return changeVisible; |
334 } | 343 } |
335 | 344 |
342 long | 351 long |
343 View::getFrameForX(int x) const | 352 View::getFrameForX(int x) const |
344 { | 353 { |
345 long z = (long)m_zoomLevel; | 354 long z = (long)m_zoomLevel; |
346 long frame = m_centreFrame - (width()/2) * z; | 355 long frame = m_centreFrame - (width()/2) * z; |
356 | |
357 #ifdef DEBUG_VIEW_WIDGET_PAINT | |
358 std::cerr << "View::getFrameForX(" << x << "): z = " << z << ", m_centreFrame = " << m_centreFrame << ", width() = " << width() << ", frame = " << frame << std::endl; | |
359 #endif | |
360 | |
347 frame = (frame / z) * z; // this is start frame | 361 frame = (frame / z) * z; // this is start frame |
348 return frame + x * z; | 362 return frame + x * z; |
349 } | 363 } |
350 | 364 |
351 float | 365 float |
496 } | 510 } |
497 | 511 |
498 View::LayerProgressBar::LayerProgressBar(QWidget *parent) : | 512 View::LayerProgressBar::LayerProgressBar(QWidget *parent) : |
499 QProgressBar(parent) | 513 QProgressBar(parent) |
500 { | 514 { |
501 QFont f(font()); | |
502 f.setPointSize(f.pointSize() * 8 / 10); | |
503 setFont(f); | |
504 } | 515 } |
505 | 516 |
506 void | 517 void |
507 View::addLayer(Layer *layer) | 518 View::addLayer(Layer *layer) |
508 { | 519 { |
516 | 527 |
517 m_progressBars[layer] = new LayerProgressBar(this); | 528 m_progressBars[layer] = new LayerProgressBar(this); |
518 m_progressBars[layer]->setMinimum(0); | 529 m_progressBars[layer]->setMinimum(0); |
519 m_progressBars[layer]->setMaximum(100); | 530 m_progressBars[layer]->setMaximum(100); |
520 m_progressBars[layer]->setMinimumWidth(80); | 531 m_progressBars[layer]->setMinimumWidth(80); |
532 | |
533 QFont f(m_progressBars[layer]->font()); | |
534 int fs = Preferences::getInstance()->getViewFontSize(); | |
535 f.setPointSize(std::min(fs, int(ceil(fs * 0.85)))); | |
536 | |
537 m_progressBars[layer]->setFont(f); | |
521 m_progressBars[layer]->hide(); | 538 m_progressBars[layer]->hide(); |
522 | 539 |
523 connect(layer, SIGNAL(layerParametersChanged()), | 540 connect(layer, SIGNAL(layerParametersChanged()), |
524 this, SLOT(layerParametersChanged())); | 541 this, SLOT(layerParametersChanged())); |
525 connect(layer, SIGNAL(layerParameterRangesChanged()), | 542 connect(layer, SIGNAL(layerParameterRangesChanged()), |
648 PlaybackFollowMode))); | 665 PlaybackFollowMode))); |
649 | 666 |
650 connect(this, SIGNAL(zoomLevelChanged(unsigned long, bool)), | 667 connect(this, SIGNAL(zoomLevelChanged(unsigned long, bool)), |
651 m_manager, SLOT(viewZoomLevelChanged(unsigned long, bool))); | 668 m_manager, SLOT(viewZoomLevelChanged(unsigned long, bool))); |
652 | 669 |
653 if (m_followPlay != PlaybackIgnore) { | 670 if (m_followPlay == PlaybackScrollPage) { |
671 // std::cerr << "View::setViewManager: setting centre frame to global centre frame: " << m_manager->getGlobalCentreFrame() << std::endl; | |
672 setCentreFrame(m_manager->getGlobalCentreFrame(), false); | |
673 } else if (m_followPlay == PlaybackScrollContinuous) { | |
654 // std::cerr << "View::setViewManager: setting centre frame to playback frame: " << m_manager->getPlaybackFrame() << std::endl; | 674 // std::cerr << "View::setViewManager: setting centre frame to playback frame: " << m_manager->getPlaybackFrame() << std::endl; |
655 setCentreFrame(m_manager->getPlaybackFrame(), false); | 675 setCentreFrame(m_manager->getPlaybackFrame(), false); |
656 } else if (m_followPan) { | 676 } else if (m_followPan) { |
657 // std::cerr << "View::setViewManager: setting centre frame to global centre frame: " << m_manager->getGlobalCentreFrame() << std::endl; | 677 // std::cerr << "View::setViewManager: setting centre frame to global centre frame: " << m_manager->getGlobalCentreFrame() << std::endl; |
658 setCentreFrame(m_manager->getGlobalCentreFrame(), false); | 678 setCentreFrame(m_manager->getGlobalCentreFrame(), false); |
743 if (recreate) { | 763 if (recreate) { |
744 delete m_cache; | 764 delete m_cache; |
745 m_cache = 0; | 765 m_cache = 0; |
746 } | 766 } |
747 | 767 |
768 emit layerModelChanged(); | |
769 | |
748 checkProgress(obj); | 770 checkProgress(obj); |
749 | 771 |
750 update(); | 772 update(); |
751 } | 773 } |
752 | 774 |
867 Layer *layer = dynamic_cast<Layer *>(sender()); | 889 Layer *layer = dynamic_cast<Layer *>(sender()); |
868 if (layer) emit propertyContainerNameChanged(layer); | 890 if (layer) emit propertyContainerNameChanged(layer); |
869 } | 891 } |
870 | 892 |
871 void | 893 void |
872 View::globalCentreFrameChanged(unsigned long f) | 894 View::globalCentreFrameChanged(unsigned long rf) |
873 { | 895 { |
874 if (m_followPan) { | 896 if (m_followPan) { |
875 setCentreFrame(alignToReference(f), false); | 897 size_t f = alignFromReference(rf); |
898 #ifdef DEBUG_VIEW_WIDGET_PAINT | |
899 std::cerr << "View[" << this << "]::globalCentreFrameChanged(" << rf | |
900 << "): setting centre frame to " << f << std::endl; | |
901 #endif | |
902 setCentreFrame(f, false); | |
876 } | 903 } |
877 } | 904 } |
878 | 905 |
879 void | 906 void |
880 View::viewCentreFrameChanged(View *, unsigned long ) | 907 View::viewCentreFrameChanged(View *, unsigned long ) |
1096 !m_manager->getPlaybackModel()) { | 1123 !m_manager->getPlaybackModel()) { |
1097 return 0; | 1124 return 0; |
1098 } | 1125 } |
1099 | 1126 |
1100 Model *anyModel = 0; | 1127 Model *anyModel = 0; |
1128 Model *alignedModel = 0; | |
1101 Model *goodModel = 0; | 1129 Model *goodModel = 0; |
1102 | 1130 |
1103 for (LayerList::const_iterator i = m_layers.begin(); | 1131 for (LayerList::const_iterator i = m_layers.begin(); |
1104 i != m_layers.end(); ++i) { | 1132 i != m_layers.end(); ++i) { |
1105 | 1133 |
1109 if (dynamic_cast<TimeRulerLayer *>(layer)) continue; | 1137 if (dynamic_cast<TimeRulerLayer *>(layer)) continue; |
1110 | 1138 |
1111 Model *model = (*i)->getModel(); | 1139 Model *model = (*i)->getModel(); |
1112 if (!model) continue; | 1140 if (!model) continue; |
1113 | 1141 |
1142 anyModel = model; | |
1143 | |
1114 if (model->getAlignmentReference()) { | 1144 if (model->getAlignmentReference()) { |
1115 anyModel = model; | 1145 alignedModel = model; |
1116 if (layer->isLayerOpaque() || | 1146 if (layer->isLayerOpaque() || |
1117 dynamic_cast<RangeSummarisableTimeValueModel *>(model)) { | 1147 dynamic_cast<RangeSummarisableTimeValueModel *>(model)) { |
1118 goodModel = model; | 1148 goodModel = model; |
1119 } | 1149 } |
1120 } | 1150 } |
1121 } | 1151 } |
1122 | 1152 |
1123 if (goodModel) return goodModel; | 1153 if (goodModel) return goodModel; |
1154 else if (alignedModel) return alignedModel; | |
1124 else return anyModel; | 1155 else return anyModel; |
1125 } | 1156 } |
1126 | 1157 |
1127 size_t | 1158 size_t |
1128 View::alignFromReference(size_t f) const | 1159 View::alignFromReference(size_t f) const |
1148 int pf = m_manager->getPlaybackFrame(); | 1179 int pf = m_manager->getPlaybackFrame(); |
1149 if (!m_manager->getAlignMode()) return pf; | 1180 if (!m_manager->getAlignMode()) return pf; |
1150 | 1181 |
1151 Model *aligningModel = getAligningModel(); | 1182 Model *aligningModel = getAligningModel(); |
1152 if (!aligningModel) return pf; | 1183 if (!aligningModel) return pf; |
1153 | 1184 /* |
1154 Model *pm = m_manager->getPlaybackModel(); | 1185 Model *pm = m_manager->getPlaybackModel(); |
1155 | 1186 |
1156 // std::cerr << "View[" << this << "]::getAlignedPlaybackFrame: pf = " << pf; | 1187 // std::cerr << "View[" << this << "]::getAlignedPlaybackFrame: pf = " << pf; |
1157 | 1188 |
1158 if (pm) { | 1189 if (pm) { |
1159 pf = pm->alignFromReference(pf); | 1190 pf = pm->alignToReference(pf); |
1160 // std::cerr << " -> " << pf; | 1191 // std::cerr << " -> " << pf; |
1161 } | 1192 } |
1162 | 1193 */ |
1163 int af = aligningModel->alignToReference(pf); | 1194 int af = aligningModel->alignFromReference(pf); |
1164 | 1195 |
1165 // std::cerr << ", aligned = " << af << std::endl; | 1196 // std::cerr << ", aligned = " << af << std::endl; |
1166 return af; | 1197 return af; |
1167 } | 1198 } |
1168 | 1199 |
1384 if (i->second->isVisible()) { | 1415 if (i->second->isVisible()) { |
1385 ph -= i->second->height(); | 1416 ph -= i->second->height(); |
1386 } | 1417 } |
1387 } | 1418 } |
1388 } | 1419 } |
1420 } | |
1421 | |
1422 void | |
1423 View::setPaintFont(QPainter &paint) | |
1424 { | |
1425 QFont font(paint.font()); | |
1426 font.setPointSize(Preferences::getInstance()->getViewFontSize()); | |
1427 paint.setFont(font); | |
1389 } | 1428 } |
1390 | 1429 |
1391 void | 1430 void |
1392 View::paintEvent(QPaintEvent *e) | 1431 View::paintEvent(QPaintEvent *e) |
1393 { | 1432 { |
1571 | 1610 |
1572 if (!paintedCacheRect) { | 1611 if (!paintedCacheRect) { |
1573 | 1612 |
1574 if (repaintCache) paint.begin(m_cache); | 1613 if (repaintCache) paint.begin(m_cache); |
1575 else paint.begin(this); | 1614 else paint.begin(this); |
1576 | 1615 setPaintFont(paint); |
1577 paint.setClipRect(cacheRect); | 1616 paint.setClipRect(cacheRect); |
1578 | 1617 |
1579 paint.setPen(getBackground()); | 1618 paint.setPen(getBackground()); |
1580 paint.setBrush(getBackground()); | 1619 paint.setBrush(getBackground()); |
1581 paint.drawRect(cacheRect); | 1620 paint.drawRect(cacheRect); |
1612 | 1651 |
1613 nonCacheRect |= cacheRect; | 1652 nonCacheRect |= cacheRect; |
1614 | 1653 |
1615 paint.begin(this); | 1654 paint.begin(this); |
1616 paint.setClipRect(nonCacheRect); | 1655 paint.setClipRect(nonCacheRect); |
1617 | 1656 setPaintFont(paint); |
1618 if (scrollables.empty()) { | 1657 if (scrollables.empty()) { |
1619 paint.setPen(getBackground()); | 1658 paint.setPen(getBackground()); |
1620 paint.setBrush(getBackground()); | 1659 paint.setBrush(getBackground()); |
1621 paint.drawRect(nonCacheRect); | 1660 paint.drawRect(nonCacheRect); |
1622 } | 1661 } |
1630 } | 1669 } |
1631 | 1670 |
1632 paint.end(); | 1671 paint.end(); |
1633 | 1672 |
1634 paint.begin(this); | 1673 paint.begin(this); |
1674 setPaintFont(paint); | |
1635 if (e) paint.setClipRect(e->rect()); | 1675 if (e) paint.setClipRect(e->rect()); |
1636 if (!m_selectionCached) { | 1676 if (!m_selectionCached) { |
1637 drawSelections(paint); | 1677 drawSelections(paint); |
1638 } | 1678 } |
1639 paint.end(); | 1679 paint.end(); |
1712 const QFontMetrics &metrics = paint.fontMetrics(); | 1752 const QFontMetrics &metrics = paint.fontMetrics(); |
1713 | 1753 |
1714 for (MultiSelection::SelectionList::iterator i = selections.begin(); | 1754 for (MultiSelection::SelectionList::iterator i = selections.begin(); |
1715 i != selections.end(); ++i) { | 1755 i != selections.end(); ++i) { |
1716 | 1756 |
1717 int p0 = getXForFrame(i->getStartFrame()); | 1757 int p0 = getXForFrame(alignFromReference(i->getStartFrame())); |
1718 int p1 = getXForFrame(i->getEndFrame()); | 1758 int p1 = getXForFrame(alignFromReference(i->getEndFrame())); |
1719 | 1759 |
1720 if (p1 < 0 || p0 > width()) continue; | 1760 if (p1 < 0 || p0 > width()) continue; |
1721 | 1761 |
1722 #ifdef DEBUG_VIEW_WIDGET_PAINT | 1762 #ifdef DEBUG_VIEW_WIDGET_PAINT |
1723 std::cerr << "View::drawSelections: " << p0 << ",-1 [" << (p1-p0) << "x" << (height()+1) << "]" << std::endl; | 1763 std::cerr << "View::drawSelections: " << p0 << ",-1 [" << (p1-p0) << "x" << (height()+1) << "]" << std::endl; |
1873 int axx, axy, bxx, bxy, dxx, dxy; | 1913 int axx, axy, bxx, bxy, dxx, dxy; |
1874 int aw = 0, bw = 0, dw = 0; | 1914 int aw = 0, bw = 0, dw = 0; |
1875 | 1915 |
1876 int labelCount = 0; | 1916 int labelCount = 0; |
1877 | 1917 |
1918 // top-left point, x-coord | |
1919 | |
1878 if ((b0 = topLayer->getXScaleValue(this, r.x(), v0, u0))) { | 1920 if ((b0 = topLayer->getXScaleValue(this, r.x(), v0, u0))) { |
1879 axs = QString("%1 %2").arg(v0).arg(u0); | 1921 axs = QString("%1 %2").arg(v0).arg(u0); |
1880 if (u0 == "Hz" && Pitch::isFrequencyInMidiRange(v0)) { | 1922 if (u0 == "Hz" && Pitch::isFrequencyInMidiRange(v0)) { |
1881 axs = QString("%1 (%2)").arg(axs) | 1923 axs = QString("%1 (%2)").arg(axs) |
1882 .arg(Pitch::getPitchLabelForFrequency(v0)); | 1924 .arg(Pitch::getPitchLabelForFrequency(v0)); |
1883 } | 1925 } |
1884 aw = paint.fontMetrics().width(axs); | 1926 aw = paint.fontMetrics().width(axs); |
1885 ++labelCount; | 1927 ++labelCount; |
1886 } | 1928 } |
1929 | |
1930 // bottom-right point, x-coord | |
1887 | 1931 |
1888 if (r.width() > 0) { | 1932 if (r.width() > 0) { |
1889 if ((b1 = topLayer->getXScaleValue(this, r.x() + r.width(), v1, u1))) { | 1933 if ((b1 = topLayer->getXScaleValue(this, r.x() + r.width(), v1, u1))) { |
1890 bxs = QString("%1 %2").arg(v1).arg(u1); | 1934 bxs = QString("%1 %2").arg(v1).arg(u1); |
1891 if (u1 == "Hz" && Pitch::isFrequencyInMidiRange(v1)) { | 1935 if (u1 == "Hz" && Pitch::isFrequencyInMidiRange(v1)) { |
1893 .arg(Pitch::getPitchLabelForFrequency(v1)); | 1937 .arg(Pitch::getPitchLabelForFrequency(v1)); |
1894 } | 1938 } |
1895 bw = paint.fontMetrics().width(bxs); | 1939 bw = paint.fontMetrics().width(bxs); |
1896 } | 1940 } |
1897 } | 1941 } |
1942 | |
1943 // dimension, width | |
1898 | 1944 |
1899 if (b0 && b1 && v1 != v0 && u0 == u1) { | 1945 if (b0 && b1 && v1 != v0 && u0 == u1) { |
1900 dxs = QString("(%1 %2)").arg(fabs(v1 - v0)).arg(u1); | 1946 dxs = QString("[%1 %2]").arg(fabs(v1 - v0)).arg(u1); |
1901 dw = paint.fontMetrics().width(dxs); | 1947 dw = paint.fontMetrics().width(dxs); |
1902 } | 1948 } |
1903 | 1949 |
1904 b0 = false; | 1950 b0 = false; |
1905 b1 = false; | 1951 b1 = false; |
1952 | |
1953 // top-left point, y-coord | |
1906 | 1954 |
1907 if ((b0 = topLayer->getYScaleValue(this, r.y(), v0, u0))) { | 1955 if ((b0 = topLayer->getYScaleValue(this, r.y(), v0, u0))) { |
1908 ays = QString("%1 %2").arg(v0).arg(u0); | 1956 ays = QString("%1 %2").arg(v0).arg(u0); |
1909 if (u0 == "Hz" && Pitch::isFrequencyInMidiRange(v0)) { | 1957 if (u0 == "Hz" && Pitch::isFrequencyInMidiRange(v0)) { |
1910 ays = QString("%1 (%2)").arg(ays) | 1958 ays = QString("%1 (%2)").arg(ays) |
1911 .arg(Pitch::getPitchLabelForFrequency(v0)); | 1959 .arg(Pitch::getPitchLabelForFrequency(v0)); |
1912 } | 1960 } |
1913 aw = std::max(aw, paint.fontMetrics().width(ays)); | 1961 aw = std::max(aw, paint.fontMetrics().width(ays)); |
1914 ++labelCount; | 1962 ++labelCount; |
1915 } | 1963 } |
1964 | |
1965 // bottom-right point, y-coord | |
1916 | 1966 |
1917 if (r.height() > 0) { | 1967 if (r.height() > 0) { |
1918 if ((b1 = topLayer->getYScaleValue(this, r.y() + r.height(), v1, u1))) { | 1968 if ((b1 = topLayer->getYScaleValue(this, r.y() + r.height(), v1, u1))) { |
1919 bys = QString("%1 %2").arg(v1).arg(u1); | 1969 bys = QString("%1 %2").arg(v1).arg(u1); |
1920 if (u1 == "Hz" && Pitch::isFrequencyInMidiRange(v1)) { | 1970 if (u1 == "Hz" && Pitch::isFrequencyInMidiRange(v1)) { |
1927 | 1977 |
1928 bool bd = false; | 1978 bool bd = false; |
1929 float dy = 0.f; | 1979 float dy = 0.f; |
1930 QString du; | 1980 QString du; |
1931 | 1981 |
1982 // dimension, height | |
1983 | |
1932 if ((bd = topLayer->getYScaleDifference(this, r.y(), r.y() + r.height(), | 1984 if ((bd = topLayer->getYScaleDifference(this, r.y(), r.y() + r.height(), |
1933 dy, du)) && | 1985 dy, du)) && |
1934 dy != 0) { | 1986 dy != 0) { |
1935 if (du != "") { | 1987 if (du != "") { |
1936 dys = QString("(%1 %2)").arg(dy).arg(du); | 1988 if (du == "Hz") { |
1989 int semis; | |
1990 float cents; | |
1991 semis = Pitch::getPitchForFrequencyDifference(v0, v1, ¢s); | |
1992 dys = QString("[%1 %2 (%3)]") | |
1993 .arg(dy).arg(du) | |
1994 .arg(Pitch::getLabelForPitchRange(semis, cents)); | |
1995 } else { | |
1996 dys = QString("[%1 %2]").arg(dy).arg(du); | |
1997 } | |
1937 } else { | 1998 } else { |
1938 dys = QString("(%1)").arg(dy); | 1999 dys = QString("[%1]").arg(dy); |
1939 } | 2000 } |
1940 dw = std::max(dw, paint.fontMetrics().width(dys)); | 2001 dw = std::max(dw, paint.fontMetrics().width(dys)); |
1941 } | 2002 } |
1942 | 2003 |
1943 int mw = r.width(); | 2004 int mw = r.width(); |