From: Soeren Apel Date: Thu, 21 May 2020 21:13:01 +0000 (+0200) Subject: Make the analog value voltage display more sane X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=0efa7f0cc59eab39dccce698d8fb6675feeb3e73 Make the analog value voltage display more sane We do this by choosing the prefix (kV, V, mV) based on the min/max value of the signal, not the value at the cursor position. That way, we won't have the situation where values are printed as e.g. "400 mV" when the values are usually shown as "1.600 V". --- diff --git a/pv/util.cpp b/pv/util.cpp index 9a9a5065..897254e1 100644 --- a/pv/util.cpp +++ b/pv/util.cpp @@ -110,25 +110,31 @@ static QTextStream& operator<<(QTextStream& stream, const Timestamp& t) return stream << QString::fromStdString(str); } -QString format_time_si(const Timestamp& v, SIPrefix prefix, - unsigned int precision, QString unit, bool sign) +SIPrefix determine_value_prefix(double v) { - if (prefix == SIPrefix::unspecified) { - // No prefix given, calculate it - - if (v.is_zero()) { - prefix = SIPrefix::none; - } else { - int exp = exponent(SIPrefix::yotta); - prefix = SIPrefix::yocto; - while ((fabs(v) * pow(Timestamp(10), exp)) > 999 && - prefix < SIPrefix::yotta) { - prefix = successor(prefix); - exp -= 3; - } + SIPrefix prefix; + + if (v == 0) { + prefix = SIPrefix::none; + } else { + int exp = exponent(SIPrefix::yotta); + prefix = SIPrefix::yocto; + while ((fabs(v) * pow(10, exp)) > 999 && + prefix < SIPrefix::yotta) { + prefix = successor(prefix); + exp -= 3; } } + return prefix; +} + +QString format_time_si(const Timestamp& v, SIPrefix prefix, + unsigned int precision, QString unit, bool sign) +{ + if (prefix == SIPrefix::unspecified) + prefix = determine_value_prefix(v.convert_to()); + assert(prefix >= SIPrefix::yocto); assert(prefix <= SIPrefix::yotta); @@ -148,19 +154,7 @@ QString format_value_si(double v, SIPrefix prefix, unsigned precision, QString unit, bool sign) { if (prefix == SIPrefix::unspecified) { - // No prefix given, calculate it - - if (v == 0) { - prefix = SIPrefix::none; - } else { - int exp = exponent(SIPrefix::yotta); - prefix = SIPrefix::yocto; - while ((fabs(v) * pow(Timestamp(10), exp)) > 999 && - prefix < SIPrefix::yotta) { - prefix = successor(prefix); - exp -= 3; - } - } + prefix = determine_value_prefix(v); const int prefix_order = -exponent(prefix); precision = (prefix >= SIPrefix::none) ? max((int)(precision + prefix_order), 0) : diff --git a/pv/util.hpp b/pv/util.hpp index 354013fe..fab29a14 100644 --- a/pv/util.hpp +++ b/pv/util.hpp @@ -62,6 +62,11 @@ typedef boost::multiprecision::number< boost::multiprecision::cpp_dec_float<24>, boost::multiprecision::et_off> Timestamp; +/** + * Chooses a prefix so that the value in front of the decimal point is between 1 and 999. + */ +SIPrefix determine_value_prefix(double v); + /** * Formats a given timestamp with the specified SI prefix. * diff --git a/pv/views/trace/analogsignal.cpp b/pv/views/trace/analogsignal.cpp index a0dd9eb2..5c52ec8a 100644 --- a/pv/views/trace/analogsignal.cpp +++ b/pv/views/trace/analogsignal.cpp @@ -65,6 +65,7 @@ using std::vector; using pv::data::LogicSegment; using pv::data::SignalBase; using pv::util::SIPrefix; +using pv::util::determine_value_prefix; namespace pv { namespace views { @@ -302,12 +303,18 @@ void AnalogSignal::paint_fore(QPainter &p, ViewItemPaintParams &pp) QString infotext; + SIPrefix prefix; + if (fabs(signal_max_) > fabs(signal_min_)) + prefix = determine_value_prefix(fabs(signal_max_)); + else + prefix = determine_value_prefix(fabs(signal_min_)); + // Show the info section on the right side of the trace, including // the value at the hover point when the hover marker is enabled // and we have corresponding data available if (show_hover_marker_ && !std::isnan(value_at_hover_pos_)) { infotext = QString("[%1] %2 V/div") - .arg(format_value_si(value_at_hover_pos_, SIPrefix::unspecified, 2, "V", false)) + .arg(format_value_si(value_at_hover_pos_, prefix, 3, "V", false)) .arg(resolution_); } else infotext = QString("%1 V/div").arg(resolution_); @@ -852,7 +859,6 @@ void AnalogSignal::perform_autoranging(bool keep_divs, bool force_update) if (segments.empty()) return; - double signal_min_ = 0, signal_max_ = 0; double min = 0, max = 0; for (const shared_ptr& segment : segments) { @@ -1126,11 +1132,12 @@ void AnalogSignal::on_setting_changed(const QString &key, const QVariant &value) void AnalogSignal::on_min_max_changed(float min, float max) { - (void)min; - (void)max; - if (autoranging_) perform_autoranging(false, false); + else { + if (min < signal_min_) signal_min_ = min; + if (max > signal_max_) signal_max_ = max; + } } void AnalogSignal::on_pos_vdivs_changed(int vdivs) diff --git a/pv/views/trace/analogsignal.hpp b/pv/views/trace/analogsignal.hpp index b15c4434..1dd9893f 100644 --- a/pv/views/trace/analogsignal.hpp +++ b/pv/views/trace/analogsignal.hpp @@ -197,7 +197,8 @@ private: int current_pixel_pos_; // Only used during lookup table update // --------------------------------------------------------------------------- - // Note: Make sure to update .. when adding a trace-configurable variable here + // Note: Make sure to update save_settings() and restore_settings() when + // adding a trace-configurable variable here float scale_; int scale_index_; diff --git a/pv/views/trace/logicsignal.hpp b/pv/views/trace/logicsignal.hpp index 96e98b4b..e066d403 100644 --- a/pv/views/trace/logicsignal.hpp +++ b/pv/views/trace/logicsignal.hpp @@ -141,7 +141,6 @@ private Q_SLOTS: void on_signal_height_changed(int height); private: - int signal_height_; QColor high_fill_color_; bool show_sampling_points_, fill_high_areas_; @@ -161,6 +160,11 @@ private: static QCache icon_cache_; static QCache pixmap_cache_; + + // --------------------------------------------------------------------------- + // Note: Make sure to update save_settings() and restore_settings() when + // adding a trace-configurable variable here + int signal_height_; }; } // namespace trace