changeset 1325:bc2cb82050a0 zoom

Gradual ZoomLevel updates
author Chris Cannam
date Wed, 19 Sep 2018 15:42:22 +0100
parents 13d9b422f7fe
children 97c68bffbda6
files layer/Colour3DPlotRenderer.cpp layer/LayerGeometryProvider.h layer/ScrollableImageCache.h layer/ScrollableMagRangeCache.h layer/TimeRulerLayer.cpp layer/WaveformLayer.cpp layer/WaveformLayer.h view/Overview.cpp view/Overview.h
diffstat 9 files changed, 73 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Colour3DPlotRenderer.cpp	Mon Sep 17 13:51:31 2018 +0100
+++ b/layer/Colour3DPlotRenderer.cpp	Wed Sep 19 15:42:22 2018 +0100
@@ -32,7 +32,10 @@
 
 #include <vector>
 
-//#define DEBUG_COLOUR_PLOT_REPAINT 1
+#include <utility>
+using namespace std::rel_ops;
+
+#define DEBUG_COLOUR_PLOT_REPAINT 1
 
 using namespace std;
 
@@ -315,7 +318,7 @@
     }
 
     int binResolution = model->getResolution();
-    int zoomLevel = v->getZoomLevel();
+    ZoomLevel zoomLevel = v->getZoomLevel();
     sv_samplerate_t modelRate = model->getSampleRate();
 
     double rateRatio = v->getViewManager()->getMainModelSampleRate() / modelRate;
@@ -332,12 +335,14 @@
         // explicitly requested opaque & sufficiently zoomed-in
         
         if (model->getHeight() * 3 < v->getPaintHeight() &&
-            relativeBinResolution >= 3 * zoomLevel) {
+            zoomLevel < ZoomLevel(ZoomLevel::FramesPerPixel,
+                                  int(round(relativeBinResolution / 3)))) {
             return DirectTranslucent;
         }
     }
 
-    if (relativeBinResolution > zoomLevel) {
+    if (ZoomLevel(ZoomLevel::FramesPerPixel,
+                  int(round(relativeBinResolution))) > zoomLevel) {
         return DrawBufferBinResolution;
     } else {
         return DrawBufferPixelResolution;
@@ -555,12 +560,12 @@
     if (m_params.binDisplay == BinDisplay::PeakFrequencies) return;
     if (m_params.colourScale.getScale() == ColourScaleType::Phase) return;
     
-    int zoomLevel = v->getZoomLevel();
+    ZoomLevel zoomLevel = v->getZoomLevel();
     int binResolution = model->getResolution();
     
     for (int ix = 0; in_range_for(m_sources.peakCaches, ix); ++ix) {
         int bpp = m_sources.peakCaches[ix]->getColumnsPerPeak();
-        int equivZoom = binResolution * bpp;
+        ZoomLevel equivZoom(ZoomLevel::FramesPerPixel, binResolution * bpp);
         if (zoomLevel >= equivZoom) {
             // this peak cache would work, though it might not be best
             if (bpp > binsPerPeak) {
--- a/layer/LayerGeometryProvider.h	Mon Sep 17 13:51:31 2018 +0100
+++ b/layer/LayerGeometryProvider.h	Wed Sep 19 15:42:22 2018 +0100
@@ -12,10 +12,11 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef LAYER_GEOMETRY_PROVIDER_H
-#define LAYER_GEOMETRY_PROVIDER_H
+#ifndef SV_LAYER_GEOMETRY_PROVIDER_H
+#define SV_LAYER_GEOMETRY_PROVIDER_H
 
 #include "base/BaseTypes.h"
+#include "base/ZoomLevel.h"
 
 #include <QMutex>
 #include <QMutexLocker>
--- a/layer/ScrollableImageCache.h	Mon Sep 17 13:51:31 2018 +0100
+++ b/layer/ScrollableImageCache.h	Wed Sep 19 15:42:22 2018 +0100
@@ -40,8 +40,7 @@
     ScrollableImageCache() :
         m_validLeft(0),
         m_validWidth(0),
-        m_startFrame(0),
-        m_zoomLevel(0)
+        m_startFrame(0)
     {}
 
     void invalidate() {
@@ -83,7 +82,7 @@
         return QRect(m_validLeft, 0, m_validWidth, m_image.height());
     }
     
-    int getZoomLevel() const {
+    ZoomLevel getZoomLevel() const {
         return m_zoomLevel;
     }
 
@@ -93,7 +92,8 @@
      * invalidate the cache here is the only thing the zoom level is
      * used for.)
      */
-    void setZoomLevel(int zoom) {
+    void setZoomLevel(ZoomLevel zoom) {
+        using namespace std::rel_ops;
         if (m_zoomLevel != zoom) {
             m_zoomLevel = zoom;
             invalidate();
@@ -157,7 +157,7 @@
     int m_validLeft;
     int m_validWidth;
     sv_frame_t m_startFrame;
-    int m_zoomLevel;
+    ZoomLevel m_zoomLevel;
 };
 
 #endif
--- a/layer/ScrollableMagRangeCache.h	Mon Sep 17 13:51:31 2018 +0100
+++ b/layer/ScrollableMagRangeCache.h	Wed Sep 19 15:42:22 2018 +0100
@@ -36,8 +36,7 @@
 {
 public:
     ScrollableMagRangeCache() :
-        m_startFrame(0),
-        m_zoomLevel(0)
+        m_startFrame(0)
     {}
 
     void invalidate() {
@@ -58,7 +57,7 @@
         }
     }
         
-    int getZoomLevel() const {
+    ZoomLevel getZoomLevel() const {
         return m_zoomLevel;
     }
 
@@ -68,7 +67,8 @@
      * invalidate the cache here is the only thing the zoom level is
      * used for.)
      */
-    void setZoomLevel(int zoom) {
+    void setZoomLevel(ZoomLevel zoom) {
+        using namespace std::rel_ops;
         if (m_zoomLevel != zoom) {
             m_zoomLevel = zoom;
             invalidate();
@@ -133,7 +133,7 @@
 private:
     std::vector<MagnitudeRange> m_ranges;
     sv_frame_t m_startFrame;
-    int m_zoomLevel;
+    ZoomLevel m_zoomLevel;
 };
 
 #endif
--- a/layer/TimeRulerLayer.cpp	Mon Sep 17 13:51:31 2018 +0100
+++ b/layer/TimeRulerLayer.cpp	Wed Sep 19 15:42:22 2018 +0100
@@ -230,7 +230,7 @@
 
     int minPixelSpacing = 50;
     sv_frame_t incFrame = lrint((incms * sampleRate) / 1000);
-    int incX = int(incFrame / v->getZoomLevel());
+    int incX = int(round(v->getZoomLevel().framesToPixels(incFrame)));
     int ticks = 10;
     if (incX < minPixelSpacing * 2) {
         ticks = quarter ? 4 : 5;
@@ -256,8 +256,11 @@
 
         double dms = ms;
         sv_frame_t frame = lrint((dms * sampleRate) / 1000.0);
-        frame /= v->getZoomLevel();
-        frame *= v->getZoomLevel(); // so frame corresponds to an exact pixel
+        ZoomLevel zoom = v->getZoomLevel();
+        if (zoom.zone == ZoomLevel::FramesPerPixel) {
+            frame /= zoom.level;
+            frame *= zoom.level; // so frame corresponds to an exact pixel
+        }
 
         if (frame == prevframe && prevframe != 0) {
             cerr << "ERROR: frame == prevframe (== " << frame
@@ -337,8 +340,10 @@
 
             dms = ms + (i * double(incms)) / ticks;
             frame = lrint((dms * sampleRate) / 1000.0);
-            frame /= v->getZoomLevel();
-            frame *= v->getZoomLevel(); // exact pixel as above
+            if (zoom.zone == ZoomLevel::FramesPerPixel) {
+                frame /= zoom.level;
+                frame *= zoom.level; // exact pixel as above
+            } 
 
             x = v->getXForFrame(frame);
 
--- a/layer/WaveformLayer.cpp	Mon Sep 17 13:51:31 2018 +0100
+++ b/layer/WaveformLayer.cpp	Wed Sep 19 15:42:22 2018 +0100
@@ -49,8 +49,7 @@
     m_middleLineHeight(0.5),
     m_aggressive(false),
     m_cache(0),
-    m_cacheValid(false),
-    m_cacheZoomLevel(0)
+    m_cacheValid(false)
 {
     
 }
@@ -482,7 +481,7 @@
         return;
     }
   
-    int zoomLevel = v->getZoomLevel();
+    ZoomLevel zoomLevel = v->getZoomLevel();
 
 #ifdef DEBUG_WAVEFORM_PAINT
     Profiler profiler("WaveformLayer::paint", true);
@@ -509,6 +508,8 @@
         cerr << "WaveformLayer::paint: aggressive is true" << endl;
 #endif
 
+        using namespace std::rel_ops;
+        
         if (m_cacheValid && (zoomLevel != m_cacheZoomLevel)) {
             m_cacheValid = false;
         }
@@ -572,18 +573,22 @@
     // the range being drawn is.  And that set of underlying frames
     // must remain the same when we scroll one or more pixels left or
     // right.
-            
-    int modelZoomLevel = m_model->getSummaryBlockSize(zoomLevel);
+
+    int desiredBlockSize = 1;
+    if (zoomLevel.zone == ZoomLevel::FramesPerPixel) {
+        desiredBlockSize = zoomLevel.level;
+    }
+    int blockSize = m_model->getSummaryBlockSize(desiredBlockSize);
 
     sv_frame_t frame0;
     sv_frame_t frame1;
     sv_frame_t spare;
 
-    getSourceFramesForX(v, x0, modelZoomLevel, frame0, spare);
-    getSourceFramesForX(v, x1, modelZoomLevel, spare, frame1);
+    getSourceFramesForX(v, x0, blockSize, frame0, spare);
+    getSourceFramesForX(v, x1, blockSize, spare, frame1);
     
 #ifdef DEBUG_WAVEFORM_PAINT
-    cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << " and model zoom " << modelZoomLevel << ")" <<  endl;
+    cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << " and model zoom " << blockSize << ")" <<  endl;
 #endif
 
     RangeSummarisableTimeValueModel::RangeBlock *ranges = 
@@ -688,10 +693,10 @@
         }
   
         m_model->getSummaries(ch, frame0, frame1 - frame0,
-                              *ranges, modelZoomLevel);
+                              *ranges, blockSize);
 
 #ifdef DEBUG_WAVEFORM_PAINT
-        cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << modelZoomLevel << endl;
+        cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl;
 #endif
 
         if (mergingChannels || mixingChannels) {
@@ -702,7 +707,7 @@
                 }
                 m_model->getSummaries
                     (1, frame0, frame1 - frame0, *otherChannelRanges,
-                     modelZoomLevel);
+                     blockSize);
             } else {
                 if (otherChannelRanges != ranges) delete otherChannelRanges;
                 otherChannelRanges = ranges;
@@ -714,7 +719,7 @@
             range = RangeSummarisableTimeValueModel::Range();
 
             sv_frame_t f0, f1;
-            if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) continue;
+            if (!getSourceFramesForX(v, x, blockSize, f0, f1)) continue;
             f1 = f1 - 1;
 
             if (f0 < frame0) {
@@ -722,15 +727,15 @@
                 continue;
             }
 
-            sv_frame_t i0 = (f0 - frame0) / modelZoomLevel;
-            sv_frame_t i1 = (f1 - frame0) / modelZoomLevel;
+            sv_frame_t i0 = (f0 - frame0) / blockSize;
+            sv_frame_t i1 = (f1 - frame0) / blockSize;
 
 #ifdef DEBUG_WAVEFORM_PAINT
             cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << endl;
 #endif
 
             if (i1 > i0 + 1) {
-                cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << modelZoomLevel << ")" << endl;
+                cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << blockSize << ")" << endl;
             }
 
             if (ranges && i0 < (sv_frame_t)ranges->size()) {
@@ -968,12 +973,17 @@
 
     if (!m_model || !m_model->isOK()) return "";
 
-    int zoomLevel = v->getZoomLevel();
+    ZoomLevel zoomLevel = v->getZoomLevel();
 
-    int modelZoomLevel = m_model->getSummaryBlockSize(zoomLevel);
+    int desiredBlockSize = 1;
+    if (zoomLevel.zone == ZoomLevel::FramesPerPixel) {
+        desiredBlockSize = zoomLevel.level;
+    }
+
+    int blockSize = m_model->getSummaryBlockSize(desiredBlockSize);
 
     sv_frame_t f0, f1;
-    if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) return "";
+    if (!getSourceFramesForX(v, x, blockSize, f0, f1)) return "";
     
     QString text;
 
@@ -998,7 +1008,6 @@
 
     for (int ch = minChannel; ch <= maxChannel; ++ch) {
 
-        int blockSize = v->getZoomLevel();
         RangeSummarisableTimeValueModel::RangeBlock ranges;
         m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize);
 
--- a/layer/WaveformLayer.h	Mon Sep 17 13:51:31 2018 +0100
+++ b/layer/WaveformLayer.h	Wed Sep 19 15:42:22 2018 +0100
@@ -238,7 +238,7 @@
 
     mutable QPixmap *m_cache;
     mutable bool m_cacheValid;
-    mutable int m_cacheZoomLevel;
+    mutable ZoomLevel m_cacheZoomLevel;
 };
 
 #endif
--- a/view/Overview.cpp	Mon Sep 17 13:51:31 2018 +0100
+++ b/view/Overview.cpp	Wed Sep 19 15:42:22 2018 +0100
@@ -44,12 +44,14 @@
 void
 Overview::modelChangedWithin(sv_frame_t startFrame, sv_frame_t endFrame)
 {
+    using namespace std::rel_ops;
+    
     bool zoomChanged = false;
 
     sv_frame_t frameCount = getModelsEndFrame() - getModelsStartFrame();
     ZoomLevel zoomLevel { ZoomLevel::FramesPerPixel, int(frameCount / width()) };
     if (zoomLevel.level < 1) zoomLevel.level = 1;
-    zoomLevel = getZoomConstraintBlockSize(zoomLevel, ZoomConstraint::RoundUp);
+    zoomLevel = getZoomConstraintLevel(zoomLevel, ZoomConstraint::RoundUp);
     if (zoomLevel != m_zoomLevel) {
         zoomChanged = true;
     }
@@ -170,6 +172,8 @@
 void
 Overview::paintEvent(QPaintEvent *e)
 {
+    using namespace std::rel_ops;
+    
     // Recalculate zoom in case the size of the widget has changed.
 
 #ifdef DEBUG_OVERVIEW
@@ -178,10 +182,9 @@
 
     sv_frame_t startFrame = getModelsStartFrame();
     sv_frame_t frameCount = getModelsEndFrame() - getModelsStartFrame();
-    int zoomLevel = int(frameCount / width());
-    if (zoomLevel < 1) zoomLevel = 1;
-    zoomLevel = getZoomConstraintBlockSize(zoomLevel,
-                                           ZoomConstraint::RoundUp);
+    ZoomLevel zoomLevel { ZoomLevel::FramesPerPixel, int(frameCount / width()) };
+    if (zoomLevel.level < 1) zoomLevel.level = 1;
+    zoomLevel = getZoomConstraintLevel(zoomLevel, ZoomConstraint::RoundUp);
     if (zoomLevel != m_zoomLevel) {
         m_zoomLevel = zoomLevel;
         emit zoomLevelChanged(m_zoomLevel, m_followZoom);
--- a/view/Overview.h	Mon Sep 17 13:51:31 2018 +0100
+++ b/view/Overview.h	Wed Sep 19 15:42:22 2018 +0100
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _OVERVIEW_H_
-#define _OVERVIEW_H_
+#ifndef SV_OVERVIEW_H
+#define SV_OVERVIEW_H
 
 #include "View.h"