]> sigrok.org Git - pulseview.git/blobdiff - pv/view/view.cpp
Fix wrong ruler scale after loading a file
[pulseview.git] / pv / view / view.cpp
index 032546dba034eda4cea63cc3f60489127cd28d9d..d32a23da07e3bb30c8553f494636bdda959c6c06 100644 (file)
@@ -84,7 +84,7 @@ namespace pv {
 namespace view {
 
 const double View::MaxScale = 1e9;
-const double View::MinScale = 1e-15;
+const double View::MinScale = 1e-12;
 
 const int View::MaxScrollValue = INT_MAX / 2;
 const int View::MaxViewAutoUpdateRate = 25; // No more than 25 Hz with sticky scrolling
@@ -493,8 +493,13 @@ void View::set_zoom(double scale, int offset)
 
 void View::calculate_tick_spacing()
 {
-       const double SpacingIncrement = 32.0f;
-       const double MinValueSpacing = 32.0f;
+       const double SpacingIncrement = 10.0f;
+       const double MinValueSpacing = 25.0f;
+
+       // Figure out the highest numeric value visible on a label
+       const QSize areaSize = viewport_->size();
+       const double max_time = max(fabs(offset_),
+               fabs(offset_ + scale_ * areaSize.width()));
 
        double min_width = SpacingIncrement;
        double label_width, tick_period_width;
@@ -507,13 +512,19 @@ void View::calculate_tick_spacing()
                const int order = (int)floorf(log10f(min_period));
                const double order_decimal = pow(10.0, order);
 
+               // Allow for a margin of error so that a scale unit of 1 can be used.
+               // Otherwise, for a SU of 1 the tick period will almost always be below
+               // the min_period by a small amount - and thus skipped in favor of 2.
+               // Note: margin assumes that SU[0] and SU[1] contain the smallest values
+               double tp_margin = (ScaleUnits[0] + ScaleUnits[1]) / 2.0;
+               double tp_with_margin;
                unsigned int unit = 0;
 
                do {
-                       tick_period_ = order_decimal * ScaleUnits[unit++];
-               } while (tick_period_ < min_period &&
-                       unit < countof(ScaleUnits));
+                       tp_with_margin = order_decimal * (ScaleUnits[unit++] + tp_margin);
+               } while (tp_with_margin < min_period && unit < countof(ScaleUnits));
 
+               tick_period_ = order_decimal * ScaleUnits[unit - 1];
                tick_prefix_ = (order - pv::util::FirstSIPrefixPower) / 3;
 
                // Precision is the number of fractional digits required, not
@@ -523,7 +534,7 @@ void View::calculate_tick_spacing()
                tick_period_width = tick_period_ / scale_;
 
                const QString label_text =
-                       format_time(offset_, tick_prefix_, time_unit_, tick_precision_);
+                       format_time(max_time, tick_prefix_, time_unit_, tick_precision_);
 
                label_width = m.boundingRect(0, 0, INT_MAX, INT_MAX,
                        Qt::AlignLeft | Qt::AlignTop, label_text).width() +
@@ -914,14 +925,20 @@ void View::signals_changed()
 
 void View::capture_state_updated(int state)
 {
-       // Reset "always zoom to fit" when we change to the stopped state
-       if (always_zoom_to_fit_ && (state == Session::Stopped)) {
-               always_zoom_to_fit_ = false;
-               always_zoom_to_fit_changed(false);
-       }
-
        if (state == Session::Running)
                time_unit_ = util::Samples;
+
+       if (state == Session::Stopped) {
+               // After acquisition has stopped we need to re-calculate the ticks once
+               // as it's otherwise done when the user pans or zooms, which is too late
+               calculate_tick_spacing();
+
+               // Reset "always zoom to fit", the acquisition has stopped
+               if (always_zoom_to_fit_) {
+                       always_zoom_to_fit_ = false;
+                       always_zoom_to_fit_changed(false);
+               }
+       }
 }
 
 void View::data_updated()