X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=pv%2Fview%2Fanalogsignal.cpp;h=e0e0b16aafb24389ff6a56d12fee978793c67c7b;hb=4c7a19d3d7049bcc9fb3185ce2bc91333a7ca9e1;hp=b9d73126527a3f0a1820d8ce60a94e228a42fd14;hpb=60938e0430a0d08792ba53b86ca94153baaed74d;p=pulseview.git diff --git a/pv/view/analogsignal.cpp b/pv/view/analogsignal.cpp index b9d7312..e0e0b16 100644 --- a/pv/view/analogsignal.cpp +++ b/pv/view/analogsignal.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "analogsignal.hpp" @@ -430,7 +429,7 @@ void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp) const int y = get_visual_y(); - if (!base_->enabled()) + if (!base_->enabled() || !base_->logic_data()) return; const int signal_margin = @@ -443,6 +442,7 @@ void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp) const deque< shared_ptr > &segments = base_->logic_data()->logic_segments(); + if (segments.empty()) return; @@ -459,6 +459,7 @@ void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp) const pv::util::Timestamp& start_time = segment->start_time(); const int64_t last_sample = segment->get_sample_count() - 1; const double samples_per_pixel = samplerate * pp.scale(); + const double pixels_per_sample = 1 / samples_per_pixel; const pv::util::Timestamp start = samplerate * (pp.offset() - start_time); const pv::util::Timestamp end = start + samples_per_pixel * pp.width(); @@ -471,6 +472,22 @@ void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp) samples_per_pixel / LogicSignal::Oversampling, 0); assert(edges.size() >= 2); + // Check whether we need to paint the sampling points + GlobalSettings settings; + const bool show_sampling_points = + settings.value(GlobalSettings::Key_View_ShowSamplingPoints).toBool() && + (samples_per_pixel < 0.25); + + vector sampling_points; + float sampling_point_x = 0.0f; + int64_t sampling_point_sample = start_sample; + const int w = 2; + + if (show_sampling_points) { + sampling_points.reserve(end_sample - start_sample + 1); + sampling_point_x = (edges.cbegin()->first / samples_per_pixel - pixels_offset) + pp.left(); + } + // Paint the edges const unsigned int edge_count = edges.size() - 2; QLineF *const edge_lines = new QLineF[edge_count]; @@ -480,8 +497,28 @@ void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp) const float x = ((*i).first / samples_per_pixel - pixels_offset) + pp.left(); *line++ = QLineF(x, high_offset, x, low_offset); + + if (show_sampling_points) + while (sampling_point_sample < (*i).first) { + const float y = (*i).second ? low_offset : high_offset; + sampling_points.emplace_back( + QRectF(sampling_point_x - (w / 2), y - (w / 2), w, w)); + sampling_point_sample++; + sampling_point_x += pixels_per_sample; + }; } + // Calculate the sample points from the last edge to the end of the trace + if (show_sampling_points) + while ((uint64_t)sampling_point_sample <= end_sample) { + // Signal changed after the last edge, so the level is inverted + const float y = (edges.cend() - 1)->second ? high_offset : low_offset; + sampling_points.emplace_back( + QRectF(sampling_point_x - (w / 2), y - (w / 2), w, w)); + sampling_point_sample++; + sampling_point_x += pixels_per_sample; + }; + p.setPen(LogicSignal::EdgeColour); p.drawLines(edge_lines, edge_count); delete[] edge_lines; @@ -499,29 +536,11 @@ void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp) delete[] cap_lines; - // Return if we don't need to paint the sampling points - GlobalSettings settings; - const bool show_sampling_points = - settings.value(GlobalSettings::Key_View_ShowSamplingPoints).toBool(); - - if (!show_sampling_points || (samples_per_pixel >= 0.25)) - return; - // Paint the sampling points - const uint64_t sampling_points_count = end_sample - start_sample + 1; - QRectF *const sampling_points = new QRectF[sampling_points_count]; - QRectF *sampling_point = sampling_points; - - const int w = 1; - const float y_middle = high_offset - ((high_offset - low_offset) / 2); - for (uint64_t i = start_sample; i < end_sample + 1; ++i) { - const float x = (i / samples_per_pixel - pixels_offset) + pp.left(); - *sampling_point++ = QRectF(x - (w / 2), y_middle - (w / 2), w, w); + if (show_sampling_points) { + p.setPen(SamplingPointColour); + p.drawRects(sampling_points.data(), sampling_points.size()); } - - p.setPen(SamplingPointColour); - p.drawRects(sampling_points, sampling_points_count); - delete[] sampling_points; } void AnalogSignal::paint_logic_caps(QPainter &p, QLineF *const lines, @@ -568,7 +587,7 @@ void AnalogSignal::update_conversion_type() owner_->row_item_appearance_changed(false, true); } -void AnalogSignal::perform_autoranging(bool force_update) +void AnalogSignal::perform_autoranging(bool keep_divs, bool force_update) { const deque< shared_ptr > &segments = base_->analog_data()->analog_segments(); @@ -591,16 +610,33 @@ void AnalogSignal::perform_autoranging(bool force_update) prev_min = min; prev_max = max; - // Use all divs for the positive range if there are no negative values - if ((min == 0) && (neg_vdivs_ > 0)) { - pos_vdivs_ += neg_vdivs_; - neg_vdivs_ = 0; + // If we're allowed to alter the div assignment... + if (!keep_divs) { + // Use all divs for the positive range if there are no negative values + if ((min == 0) && (neg_vdivs_ > 0)) { + pos_vdivs_ += neg_vdivs_; + neg_vdivs_ = 0; + } + + // Split up the divs if there are negative values but no negative divs + if ((min < 0) && (neg_vdivs_ == 0)) { + neg_vdivs_ = pos_vdivs_ / 2; + pos_vdivs_ -= neg_vdivs_; + } + } + + // If there is still no positive div when we need it, add one + // (this can happen when pos_vdivs==neg_vdivs==0) + if ((max > 0) && (pos_vdivs_ == 0)) { + pos_vdivs_ = 1; + owner_->extents_changed(false, true); } - // Split up the divs if there are negative values but no negative divs + // If there is still no negative div when we need it, add one + // (this can happen when pos_vdivs was 0 or 1 when trying to split) if ((min < 0) && (neg_vdivs_ == 0)) { - neg_vdivs_ = pos_vdivs_ / 2; - pos_vdivs_ -= neg_vdivs_; + neg_vdivs_ = 1; + owner_->extents_changed(false, true); } double min_value_per_div; @@ -629,19 +665,19 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form) QFormLayout *const layout = new QFormLayout; // Add the number of vdivs - QSpinBox *pvdiv_sb = new QSpinBox(parent); - pvdiv_sb->setRange(0, MaximumVDivs); - pvdiv_sb->setValue(pos_vdivs_); - connect(pvdiv_sb, SIGNAL(valueChanged(int)), + pvdiv_sb_ = new QSpinBox(parent); + pvdiv_sb_->setRange(0, MaximumVDivs); + pvdiv_sb_->setValue(pos_vdivs_); + connect(pvdiv_sb_, SIGNAL(valueChanged(int)), this, SLOT(on_pos_vdivs_changed(int))); - layout->addRow(tr("Number of pos vertical divs"), pvdiv_sb); + layout->addRow(tr("Number of pos vertical divs"), pvdiv_sb_); - QSpinBox *nvdiv_sb = new QSpinBox(parent); - nvdiv_sb->setRange(0, MaximumVDivs); - nvdiv_sb->setValue(neg_vdivs_); - connect(nvdiv_sb, SIGNAL(valueChanged(int)), + nvdiv_sb_ = new QSpinBox(parent); + nvdiv_sb_->setRange(0, MaximumVDivs); + nvdiv_sb_->setValue(neg_vdivs_); + connect(nvdiv_sb_, SIGNAL(valueChanged(int)), this, SLOT(on_neg_vdivs_changed(int))); - layout->addRow(tr("Number of neg vertical divs"), nvdiv_sb); + layout->addRow(tr("Number of neg vertical divs"), nvdiv_sb_); // Add the vertical resolution resolution_cb_ = new QComboBox(parent); @@ -683,7 +719,7 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form) cur_idx = conversion_cb_->findData(QVariant(conversion_type_)); conversion_cb_->setCurrentIndex(cur_idx); - layout->addRow(tr("Conversion"), conversion_cb_); +// layout->addRow(tr("Conversion"), conversion_cb_); connect(conversion_cb_, SIGNAL(currentIndexChanged(int)), this, SLOT(on_conversion_changed(int))); @@ -698,7 +734,7 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form) cur_idx = display_type_cb_->findData(QVariant(display_type_)); display_type_cb_->setCurrentIndex(cur_idx); - layout->addRow(tr("Traces to show:"), display_type_cb_); +// layout->addRow(tr("Traces to show:"), display_type_cb_); connect(display_type_cb_, SIGNAL(currentIndexChanged(int)), this, SLOT(on_display_type_changed(int))); @@ -708,21 +744,32 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form) void AnalogSignal::on_samples_added() { - perform_autoranging(); - - if (owner_) { - // Call order is important, otherwise the lazy event handler won't work - owner_->extents_changed(false, true); - owner_->row_item_appearance_changed(false, true); - } + perform_autoranging(false, false); } void AnalogSignal::on_pos_vdivs_changed(int vdivs) { + if (vdivs == pos_vdivs_) + return; + pos_vdivs_ = vdivs; - if (autoranging_) - perform_autoranging(true); + // There has to be at least one div, positive or negative + if ((neg_vdivs_ == 0) && (pos_vdivs_ == 0)) { + pos_vdivs_ = 1; + if (pvdiv_sb_) + pvdiv_sb_->setValue(pos_vdivs_); + } + + if (autoranging_) { + perform_autoranging(true, true); + + // It could be that a positive or negative div was added, so update + if (pvdiv_sb_) { + pvdiv_sb_->setValue(pos_vdivs_); + nvdiv_sb_->setValue(neg_vdivs_); + } + } if (owner_) { // Call order is important, otherwise the lazy event handler won't work @@ -733,10 +780,27 @@ void AnalogSignal::on_pos_vdivs_changed(int vdivs) void AnalogSignal::on_neg_vdivs_changed(int vdivs) { + if (vdivs == neg_vdivs_) + return; + neg_vdivs_ = vdivs; - if (autoranging_) - perform_autoranging(true); + // There has to be at least one div, positive or negative + if ((neg_vdivs_ == 0) && (pos_vdivs_ == 0)) { + pos_vdivs_ = 1; + if (pvdiv_sb_) + pvdiv_sb_->setValue(pos_vdivs_); + } + + if (autoranging_) { + perform_autoranging(true, true); + + // It could be that a positive or negative div was added, so update + if (pvdiv_sb_) { + pvdiv_sb_->setValue(pos_vdivs_); + nvdiv_sb_->setValue(neg_vdivs_); + } + } if (owner_) { // Call order is important, otherwise the lazy event handler won't work @@ -759,7 +823,7 @@ void AnalogSignal::on_autoranging_changed(int state) autoranging_ = (state == Qt::Checked); if (autoranging_) - perform_autoranging(true); + perform_autoranging(false, true); if (owner_) { // Call order is important, otherwise the lazy event handler won't work