AnalogSignal: Enforce min neg/pos div count for logic
authorSoeren Apel <soeren@apelpie.net>
Mon, 14 Dec 2020 13:23:00 +0000 (14:23 +0100)
committerSoeren Apel <soeren@apelpie.net>
Tue, 15 Dec 2020 14:57:23 +0000 (15:57 +0100)
pv/views/trace/analogsignal.cpp

index 53eeaf138a2a174e08323f454f0df61237c37cef..ba5adebf90fab3f7562db305f1f49d38276d1801 100644 (file)
@@ -101,7 +101,7 @@ AnalogSignal::AnalogSignal(pv::Session &session, shared_ptr<data::SignalBase> ba
        pos_vdivs_(1),
        neg_vdivs_(1),
        resolution_(0),
-       display_type_(DisplayBoth),
+       display_type_(DisplayAnalog),
        autoranging_(true)
 {
        axis_pen_ = AxisPen;
@@ -190,6 +190,7 @@ pair<int, int> AnalogSignal::v_extents() const
 {
        const int ph = pos_vdivs_ * div_height_;
        const int nh = neg_vdivs_ * div_height_;
+
        return make_pair(-ph, nh);
 }
 
@@ -694,16 +695,18 @@ void AnalogSignal::perform_autoranging(bool keep_divs, bool force_update)
                }
        }
 
+       const bool showing_logic = (display_type_ == DisplayConverted) || (display_type_ == DisplayBoth);
+
        // 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)) {
+       if (((max > 0) && (pos_vdivs_ == 0)) || showing_logic) {
                pos_vdivs_ = 1;
                owner_->extents_changed(false, true);
        }
 
        // 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)) {
+       if (((min < 0) && (neg_vdivs_ == 0)) || showing_logic) {
                neg_vdivs_ = 1;
                owner_->extents_changed(false, true);
        }
@@ -793,6 +796,7 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form)
        pvdiv_sb_ = new QSpinBox(parent);
        pvdiv_sb_->setRange(0, MaximumVDivs);
        pvdiv_sb_->setValue(pos_vdivs_);
+       pvdiv_sb_->setEnabled(!autoranging_);
        connect(pvdiv_sb_, SIGNAL(valueChanged(int)),
                this, SLOT(on_pos_vdivs_changed(int)));
        form->addRow(tr("Number of pos vertical divs"), pvdiv_sb_);
@@ -800,6 +804,7 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form)
        nvdiv_sb_ = new QSpinBox(parent);
        nvdiv_sb_->setRange(0, MaximumVDivs);
        nvdiv_sb_->setValue(neg_vdivs_);
+       nvdiv_sb_->setEnabled(!autoranging_);
        connect(nvdiv_sb_, SIGNAL(valueChanged(int)),
                this, SLOT(on_neg_vdivs_changed(int)));
        form->addRow(tr("Number of neg vertical divs"), nvdiv_sb_);
@@ -815,6 +820,7 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form)
 
        // Add the vertical resolution
        resolution_cb_ = new QComboBox(parent);
+       resolution_cb_->setEnabled(!autoranging_);
 
        for (int i = MinScaleIndex; i < MaxScaleIndex; i++) {
                const QString label = QString("%1").arg(get_resolution(i));
@@ -1034,6 +1040,13 @@ void AnalogSignal::on_autoranging_changed(int state)
 {
        autoranging_ = (state == Qt::Checked);
 
+       if (pvdiv_sb_)
+               pvdiv_sb_->setEnabled(!autoranging_);
+       if (nvdiv_sb_)
+               nvdiv_sb_->setEnabled(!autoranging_);
+       if (resolution_cb_)
+               resolution_cb_->setEnabled(!autoranging_);
+
        if (autoranging_)
                perform_autoranging(false, true);
 
@@ -1055,6 +1068,11 @@ void AnalogSignal::on_conversion_changed(int index)
                base_->set_conversion_type(conv_type);
                update_conversion_widgets();
 
+               if (conv_type == SignalBase::ConversionType::NoConversion)
+                       on_display_type_changed(DisplayType::DisplayAnalog);
+               else
+                       on_display_type_changed(DisplayType::DisplayBoth);
+
                if (owner_)
                        owner_->row_item_appearance_changed(false, true);
        }
@@ -1145,8 +1163,21 @@ void AnalogSignal::on_delayed_conversion_starter()
 
 void AnalogSignal::on_display_type_changed(int index)
 {
+       const bool prev_showing_logic = (display_type_ == DisplayConverted) || (display_type_ == DisplayBoth);
+
        display_type_ = (DisplayType)(display_type_cb_->itemData(index).toInt());
 
+       const bool showing_logic = (display_type_ == DisplayConverted) || (display_type_ == DisplayBoth);
+
+       // If we show a logic trace, make sure we have at least one div for each
+       // polarity as that's where we paint it
+       if (showing_logic && !prev_showing_logic) {
+               if (pos_vdivs_ == 0)
+                       on_pos_vdivs_changed(1);
+               if (neg_vdivs_ == 0)
+                       on_neg_vdivs_changed(1);
+       }
+
        if (owner_)
                owner_->row_item_appearance_changed(false, true);
 }