X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=pv%2Fview%2Fview.cpp;h=d32a23da07e3bb30c8553f494636bdda959c6c06;hb=fd03a2797f0352892a8068a0d27da3c420c73973;hp=0844b6a47e6fd13c16d34ba85eddfc7850ec3974;hpb=7ee199a77ecbb7edd6decca4786648cfe07e6eec;p=pulseview.git diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 0844b6a4..d32a23da 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -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 @@ -104,6 +104,7 @@ View::View(Session &session, QWidget *parent) : always_zoom_to_fit_(false), tick_period_(0.0), tick_prefix_(0), + tick_precision_(0), time_unit_(util::Time), show_cursors_(false), cursors_(new CursorPair(*this)), @@ -236,6 +237,11 @@ unsigned int View::tick_prefix() const return tick_prefix_; } +unsigned int View::tick_precision() const +{ + return tick_precision_; +} + double View::tick_period() const { return tick_period_; @@ -487,10 +493,16 @@ 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, typical_width; + double min_width = SpacingIncrement; + double label_width, tick_period_width; QFontMetrics m(QApplication::font()); @@ -500,23 +512,37 @@ 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; - typical_width = m.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignTop, - format_time(offset_, tick_prefix_, time_unit_)).width() + + // Precision is the number of fractional digits required, not + // taking the prefix into account (and it must never be negative) + tick_precision_ = std::max((int)ceil(log10f(1 / tick_period_)), 0); + + tick_period_width = tick_period_ / scale_; + + const QString label_text = + 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() + MinValueSpacing; min_width += SpacingIncrement; - } while (typical_width > tick_period_ / scale_); + } while (tick_period_width < label_width); } void View::update_scroll() @@ -899,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()