2 * This file is part of the PulseView project.
4 * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 #include <QApplication>
31 #include <QFormLayout>
32 #include <QGridLayout>
37 #include "analogsignal.hpp"
38 #include "pv/data/analog.hpp"
39 #include "pv/data/analogsegment.hpp"
40 #include "pv/data/logic.hpp"
41 #include "pv/data/logicsegment.hpp"
42 #include "pv/data/signalbase.hpp"
43 #include "pv/view/view.hpp"
44 #include "pv/view/logicsignal.hpp"
45 #include "pv/globalsettings.hpp"
47 #include <libsigrokcxx/libsigrokcxx.hpp>
55 using std::numeric_limits
;
57 using std::shared_ptr
;
64 const QColor
AnalogSignal::SignalColours
[4] = {
65 QColor(0xC4, 0xA0, 0x00), // Yellow
66 QColor(0x87, 0x20, 0x7A), // Magenta
67 QColor(0x20, 0x4A, 0x87), // Blue
68 QColor(0x4E, 0x9A, 0x06) // Green
71 const QColor
AnalogSignal::GridMajorColor
= QColor(0, 0, 0, 40*256/100);
72 const QColor
AnalogSignal::GridMinorColor
= QColor(0, 0, 0, 20*256/100);
74 const QColor
AnalogSignal::SamplingPointColour(0x77, 0x77, 0x77);
76 const float AnalogSignal::EnvelopeThreshold
= 256.0f
;
78 const int AnalogSignal::MaximumVDivs
= 10;
79 const int AnalogSignal::MinScaleIndex
= -6;
80 const int AnalogSignal::MaxScaleIndex
= 7;
82 const int AnalogSignal::InfoTextMarginRight
= 20;
83 const int AnalogSignal::InfoTextMarginBottom
= 5;
85 AnalogSignal::AnalogSignal(
87 shared_ptr
<data::SignalBase
> base
) :
88 Signal(session
, base
),
89 scale_index_(4), // 20 per div
90 scale_index_drag_offset_(0),
91 div_height_(3 * QFontMetrics(QApplication::font()).height()),
95 conversion_type_(data::SignalBase::NoConversion
),
96 display_type_(DisplayBoth
),
99 pv::data::Analog
* analog_data
=
100 dynamic_cast<pv::data::Analog
*>(data().get());
102 connect(analog_data
, SIGNAL(samples_added(QObject
*, uint64_t, uint64_t)),
103 this, SLOT(on_samples_added()));
105 base_
->set_colour(SignalColours
[base_
->index() % countof(SignalColours
)]);
109 shared_ptr
<pv::data::SignalData
> AnalogSignal::data() const
111 return base_
->analog_data();
114 void AnalogSignal::save_settings(QSettings
&settings
) const
116 settings
.setValue("pos_vdivs", pos_vdivs_
);
117 settings
.setValue("neg_vdivs", neg_vdivs_
);
118 settings
.setValue("scale_index", scale_index_
);
119 settings
.setValue("conversion_type", conversion_type_
);
120 settings
.setValue("display_type", display_type_
);
121 settings
.setValue("autoranging", autoranging_
);
124 void AnalogSignal::restore_settings(QSettings
&settings
)
126 if (settings
.contains("pos_vdivs"))
127 pos_vdivs_
= settings
.value("pos_vdivs").toInt();
129 if (settings
.contains("neg_vdivs"))
130 neg_vdivs_
= settings
.value("neg_vdivs").toInt();
132 if (settings
.contains("scale_index")) {
133 scale_index_
= settings
.value("scale_index").toInt();
137 if (settings
.contains("conversion_type")) {
138 conversion_type_
= (data::SignalBase::ConversionType
)(settings
.value("conversion_type").toInt());
139 update_conversion_type();
142 if (settings
.contains("display_type"))
143 display_type_
= (DisplayType
)(settings
.value("display_type").toInt());
145 if (settings
.contains("autoranging"))
146 autoranging_
= settings
.value("autoranging").toBool();
149 pair
<int, int> AnalogSignal::v_extents() const
151 const int ph
= pos_vdivs_
* div_height_
;
152 const int nh
= neg_vdivs_
* div_height_
;
153 return make_pair(-ph
, nh
);
156 int AnalogSignal::scale_handle_offset() const
158 const int h
= (pos_vdivs_
+ neg_vdivs_
) * div_height_
;
160 return ((scale_index_drag_offset_
- scale_index_
) *
164 void AnalogSignal::scale_handle_dragged(int offset
)
166 const int h
= (pos_vdivs_
+ neg_vdivs_
) * div_height_
;
168 scale_index_
= scale_index_drag_offset_
-
169 (offset
+ h
/ 2) / (h
/ 4);
174 void AnalogSignal::scale_handle_drag_release()
176 scale_index_drag_offset_
= scale_index_
;
180 void AnalogSignal::paint_back(QPainter
&p
, const ViewItemPaintParams
&pp
)
182 if (base_
->enabled()) {
183 Trace::paint_back(p
, pp
);
184 paint_axis(p
, pp
, get_visual_y());
188 void AnalogSignal::paint_mid(QPainter
&p
, const ViewItemPaintParams
&pp
)
190 assert(base_
->analog_data());
193 const int y
= get_visual_y();
195 if (!base_
->enabled())
198 if ((display_type_
== DisplayAnalog
) || (display_type_
== DisplayBoth
)) {
199 paint_grid(p
, y
, pp
.left(), pp
.right());
201 const deque
< shared_ptr
<pv::data::AnalogSegment
> > &segments
=
202 base_
->analog_data()->analog_segments();
203 if (segments
.empty())
206 const shared_ptr
<pv::data::AnalogSegment
> &segment
=
209 const double pixels_offset
= pp
.pixels_offset();
210 const double samplerate
= max(1.0, segment
->samplerate());
211 const pv::util::Timestamp
& start_time
= segment
->start_time();
212 const int64_t last_sample
= segment
->get_sample_count() - 1;
213 const double samples_per_pixel
= samplerate
* pp
.scale();
214 const pv::util::Timestamp start
= samplerate
* (pp
.offset() - start_time
);
215 const pv::util::Timestamp end
= start
+ samples_per_pixel
* pp
.width();
217 const int64_t start_sample
= min(max(floor(start
).convert_to
<int64_t>(),
218 (int64_t)0), last_sample
);
219 const int64_t end_sample
= min(max((ceil(end
) + 1).convert_to
<int64_t>(),
220 (int64_t)0), last_sample
);
222 if (samples_per_pixel
< EnvelopeThreshold
)
223 paint_trace(p
, segment
, y
, pp
.left(),
224 start_sample
, end_sample
,
225 pixels_offset
, samples_per_pixel
);
227 paint_envelope(p
, segment
, y
, pp
.left(),
228 start_sample
, end_sample
,
229 pixels_offset
, samples_per_pixel
);
232 if ((display_type_
== DisplayConverted
) || (display_type_
== DisplayBoth
)) {
233 if (((conversion_type_
== data::SignalBase::A2LConversionByTreshold
) ||
234 (conversion_type_
== data::SignalBase::A2LConversionBySchmittTrigger
))) {
236 paint_logic_mid(p
, pp
);
241 void AnalogSignal::paint_fore(QPainter
&p
, const ViewItemPaintParams
&pp
)
246 if ((display_type_
== DisplayAnalog
) || (display_type_
== DisplayBoth
)) {
247 const int y
= get_visual_y();
249 // Show the info section on the right side of the trace
250 const QString infotext
= QString("%1 V/div").arg(resolution_
);
252 p
.setPen(base_
->colour());
253 p
.setFont(QApplication::font());
255 const QRectF bounding_rect
= QRectF(pp
.left(),
256 y
+ v_extents().first
,
257 pp
.width() - InfoTextMarginRight
,
258 v_extents().second
- v_extents().first
- InfoTextMarginBottom
);
260 p
.drawText(bounding_rect
, Qt::AlignRight
| Qt::AlignBottom
, infotext
);
264 void AnalogSignal::paint_grid(QPainter
&p
, int y
, int left
, int right
)
266 p
.setRenderHint(QPainter::Antialiasing
, false);
268 if (pos_vdivs_
> 0) {
269 p
.setPen(QPen(GridMajorColor
, 1, Qt::DashLine
));
270 for (int i
= 1; i
<= pos_vdivs_
; i
++) {
271 const float dy
= i
* div_height_
;
272 p
.drawLine(QLineF(left
, y
- dy
, right
, y
- dy
));
275 p
.setPen(QPen(GridMinorColor
, 1, Qt::DashLine
));
276 for (int i
= 0; i
< pos_vdivs_
; i
++) {
277 const float dy
= i
* div_height_
;
278 const float dy25
= dy
+ (0.25 * div_height_
);
279 const float dy50
= dy
+ (0.50 * div_height_
);
280 const float dy75
= dy
+ (0.75 * div_height_
);
281 p
.drawLine(QLineF(left
, y
- dy25
, right
, y
- dy25
));
282 p
.drawLine(QLineF(left
, y
- dy50
, right
, y
- dy50
));
283 p
.drawLine(QLineF(left
, y
- dy75
, right
, y
- dy75
));
287 if (neg_vdivs_
> 0) {
288 p
.setPen(QPen(GridMajorColor
, 1, Qt::DashLine
));
289 for (int i
= 1; i
<= neg_vdivs_
; i
++) {
290 const float dy
= i
* div_height_
;
291 p
.drawLine(QLineF(left
, y
+ dy
, right
, y
+ dy
));
294 p
.setPen(QPen(GridMinorColor
, 1, Qt::DashLine
));
295 for (int i
= 0; i
< neg_vdivs_
; i
++) {
296 const float dy
= i
* div_height_
;
297 const float dy25
= dy
+ (0.25 * div_height_
);
298 const float dy50
= dy
+ (0.50 * div_height_
);
299 const float dy75
= dy
+ (0.75 * div_height_
);
300 p
.drawLine(QLineF(left
, y
+ dy25
, right
, y
+ dy25
));
301 p
.drawLine(QLineF(left
, y
+ dy50
, right
, y
+ dy50
));
302 p
.drawLine(QLineF(left
, y
+ dy75
, right
, y
+ dy75
));
306 p
.setRenderHint(QPainter::Antialiasing
, true);
309 void AnalogSignal::paint_trace(QPainter
&p
,
310 const shared_ptr
<pv::data::AnalogSegment
> &segment
,
311 int y
, int left
, const int64_t start
, const int64_t end
,
312 const double pixels_offset
, const double samples_per_pixel
)
314 p
.setPen(base_
->colour());
316 const int64_t points_count
= end
- start
;
318 QPointF
*points
= new QPointF
[points_count
];
319 QPointF
*point
= points
;
321 QRectF
*const sampling_points
= new QRectF
[points_count
];
322 QRectF
*sampling_point
= sampling_points
;
324 pv::data::SegmentAnalogDataIterator
* it
=
325 segment
->begin_sample_iteration(start
);
328 for (int64_t sample
= start
; sample
!= end
; sample
++) {
329 const float x
= (sample
/ samples_per_pixel
-
330 pixels_offset
) + left
;
332 *point
++ = QPointF(x
, y
- *((float*)it
->value
) * scale_
);
333 *sampling_point
++ = QRectF(x
- (w
/ 2), y
- *((float*)it
->value
) * scale_
- (w
/ 2), w
, w
);
335 segment
->continue_sample_iteration(it
, 1);
337 segment
->end_sample_iteration(it
);
339 p
.drawPolyline(points
, points_count
);
341 // Paint the sampling points if enabled
342 GlobalSettings settings
;
343 const bool show_sampling_points
=
344 settings
.value(GlobalSettings::Key_View_ShowSamplingPoints
).toBool();
346 if (show_sampling_points
&& (samples_per_pixel
< 0.25)) {
347 p
.setPen(SamplingPointColour
);
348 p
.drawRects(sampling_points
, points_count
);
352 delete[] sampling_points
;
355 void AnalogSignal::paint_envelope(QPainter
&p
,
356 const shared_ptr
<pv::data::AnalogSegment
> &segment
,
357 int y
, int left
, const int64_t start
, const int64_t end
,
358 const double pixels_offset
, const double samples_per_pixel
)
360 using pv::data::AnalogSegment
;
362 AnalogSegment::EnvelopeSection e
;
363 segment
->get_envelope_section(e
, start
, end
, samples_per_pixel
);
368 p
.setPen(QPen(Qt::NoPen
));
369 p
.setBrush(base_
->colour());
371 QRectF
*const rects
= new QRectF
[e
.length
];
372 QRectF
*rect
= rects
;
374 for (uint64_t sample
= 0; sample
< e
.length
-1; sample
++) {
375 const float x
= ((e
.scale
* sample
+ e
.start
) /
376 samples_per_pixel
- pixels_offset
) + left
;
377 const AnalogSegment::EnvelopeSample
*const s
=
380 // We overlap this sample with the next so that vertical
381 // gaps do not appear during steep rising or falling edges
382 const float b
= y
- max(s
->max
, (s
+1)->min
) * scale_
;
383 const float t
= y
- min(s
->min
, (s
+1)->max
) * scale_
;
386 if (h
>= 0.0f
&& h
<= 1.0f
)
388 if (h
<= 0.0f
&& h
>= -1.0f
)
391 *rect
++ = QRectF(x
, t
, 1.0f
, h
);
394 p
.drawRects(rects
, e
.length
);
400 void AnalogSignal::paint_logic_mid(QPainter
&p
, const ViewItemPaintParams
&pp
)
404 vector
< pair
<int64_t, bool> > edges
;
408 const int y
= get_visual_y();
410 if (!base_
->enabled())
413 const int signal_margin
=
414 QFontMetrics(QApplication::font()).height() / 2;
416 const int ph
= min(pos_vdivs_
, 1) * div_height_
;
417 const int nh
= min(neg_vdivs_
, 1) * div_height_
;
418 const float high_offset
= y
- ph
+ signal_margin
+ 0.5f
;
419 const float low_offset
= y
+ nh
- signal_margin
- 0.5f
;
421 const deque
< shared_ptr
<pv::data::LogicSegment
> > &segments
=
422 base_
->logic_data()->logic_segments();
423 if (segments
.empty())
426 const shared_ptr
<pv::data::LogicSegment
> &segment
=
429 double samplerate
= segment
->samplerate();
431 // Show sample rate as 1Hz when it is unknown
432 if (samplerate
== 0.0)
435 const double pixels_offset
= pp
.pixels_offset();
436 const pv::util::Timestamp
& start_time
= segment
->start_time();
437 const int64_t last_sample
= segment
->get_sample_count() - 1;
438 const double samples_per_pixel
= samplerate
* pp
.scale();
439 const pv::util::Timestamp start
= samplerate
* (pp
.offset() - start_time
);
440 const pv::util::Timestamp end
= start
+ samples_per_pixel
* pp
.width();
442 const int64_t start_sample
= min(max(floor(start
).convert_to
<int64_t>(),
443 (int64_t)0), last_sample
);
444 const uint64_t end_sample
= min(max(ceil(end
).convert_to
<int64_t>(),
445 (int64_t)0), last_sample
);
447 segment
->get_subsampled_edges(edges
, start_sample
, end_sample
,
448 samples_per_pixel
/ LogicSignal::Oversampling
, 0);
449 assert(edges
.size() >= 2);
452 const unsigned int edge_count
= edges
.size() - 2;
453 QLineF
*const edge_lines
= new QLineF
[edge_count
];
456 for (auto i
= edges
.cbegin() + 1; i
!= edges
.cend() - 1; i
++) {
457 const float x
= ((*i
).first
/ samples_per_pixel
-
458 pixels_offset
) + pp
.left();
459 *line
++ = QLineF(x
, high_offset
, x
, low_offset
);
462 p
.setPen(LogicSignal::EdgeColour
);
463 p
.drawLines(edge_lines
, edge_count
);
467 const unsigned int max_cap_line_count
= edges
.size();
468 QLineF
*const cap_lines
= new QLineF
[max_cap_line_count
];
470 p
.setPen(LogicSignal::HighColour
);
471 paint_logic_caps(p
, cap_lines
, edges
, true, samples_per_pixel
,
472 pixels_offset
, pp
.left(), high_offset
);
473 p
.setPen(LogicSignal::LowColour
);
474 paint_logic_caps(p
, cap_lines
, edges
, false, samples_per_pixel
,
475 pixels_offset
, pp
.left(), low_offset
);
479 // Return if we don't need to paint the sampling points
480 GlobalSettings settings
;
481 const bool show_sampling_points
=
482 settings
.value(GlobalSettings::Key_View_ShowSamplingPoints
).toBool();
484 if (!show_sampling_points
|| (samples_per_pixel
>= 0.25))
487 // Paint the sampling points
488 const uint64_t sampling_points_count
= end_sample
- start_sample
+ 1;
489 QRectF
*const sampling_points
= new QRectF
[sampling_points_count
];
490 QRectF
*sampling_point
= sampling_points
;
493 const float y_middle
= high_offset
- ((high_offset
- low_offset
) / 2);
494 for (uint64_t i
= start_sample
; i
< end_sample
+ 1; ++i
) {
495 const float x
= (i
/ samples_per_pixel
- pixels_offset
) + pp
.left();
496 *sampling_point
++ = QRectF(x
- (w
/ 2), y_middle
- (w
/ 2), w
, w
);
499 p
.setPen(SamplingPointColour
);
500 p
.drawRects(sampling_points
, sampling_points_count
);
501 delete[] sampling_points
;
504 void AnalogSignal::paint_logic_caps(QPainter
&p
, QLineF
*const lines
,
505 vector
< pair
<int64_t, bool> > &edges
, bool level
,
506 double samples_per_pixel
, double pixels_offset
, float x_offset
,
509 QLineF
*line
= lines
;
511 for (auto i
= edges
.begin(); i
!= (edges
.end() - 1); i
++)
512 if ((*i
).second
== level
) {
514 ((*i
).first
/ samples_per_pixel
-
515 pixels_offset
) + x_offset
, y_offset
,
516 ((*(i
+1)).first
/ samples_per_pixel
-
517 pixels_offset
) + x_offset
, y_offset
);
520 p
.drawLines(lines
, line
- lines
);
523 float AnalogSignal::get_resolution(int scale_index
)
525 const float seq
[] = {1.0f
, 2.0f
, 5.0f
};
527 const int offset
= numeric_limits
<int>::max() / (2 * countof(seq
));
528 const div_t d
= div((int)(scale_index
+ countof(seq
) * offset
),
531 return powf(10.0f
, d
.quot
- offset
) * seq
[d
.rem
];
534 void AnalogSignal::update_scale()
536 resolution_
= get_resolution(scale_index_
);
537 scale_
= div_height_
/ resolution_
;
540 void AnalogSignal::update_conversion_type()
542 base_
->set_conversion_type(conversion_type_
);
545 owner_
->row_item_appearance_changed(false, true);
548 void AnalogSignal::perform_autoranging(bool force_update
)
550 const deque
< shared_ptr
<pv::data::AnalogSegment
> > &segments
=
551 base_
->analog_data()->analog_segments();
553 if (segments
.empty())
556 static double prev_min
= 0, prev_max
= 0;
557 double min
= 0, max
= 0;
559 for (shared_ptr
<pv::data::AnalogSegment
> segment
: segments
) {
560 pair
<double, double> mm
= segment
->get_min_max();
561 min
= std::min(min
, mm
.first
);
562 max
= std::max(max
, mm
.second
);
565 if ((min
== prev_min
) && (max
== prev_max
) && !force_update
)
571 // Use all divs for the positive range if there are no negative values
572 if ((min
== 0) && (neg_vdivs_
> 0)) {
573 pos_vdivs_
+= neg_vdivs_
;
577 // Split up the divs if there are negative values but no negative divs
578 if ((min
< 0) && (neg_vdivs_
== 0)) {
579 neg_vdivs_
= pos_vdivs_
/ 2;
580 pos_vdivs_
-= neg_vdivs_
;
583 double min_value_per_div
;
584 if ((pos_vdivs_
> 0) && (neg_vdivs_
> 0))
585 min_value_per_div
= std::max(max
/ pos_vdivs_
, -min
/ neg_vdivs_
);
586 else if (pos_vdivs_
> 0)
587 min_value_per_div
= max
/ pos_vdivs_
;
589 min_value_per_div
= -min
/ neg_vdivs_
;
591 // Find first scale value that is bigger than the value we need
592 for (int i
= MinScaleIndex
; i
< MaxScaleIndex
; i
++)
593 if (get_resolution(i
) > min_value_per_div
) {
601 void AnalogSignal::populate_popup_form(QWidget
*parent
, QFormLayout
*form
)
603 // Add the standard options
604 Signal::populate_popup_form(parent
, form
);
606 QFormLayout
*const layout
= new QFormLayout
;
608 // Add the number of vdivs
609 QSpinBox
*pvdiv_sb
= new QSpinBox(parent
);
610 pvdiv_sb
->setRange(0, MaximumVDivs
);
611 pvdiv_sb
->setValue(pos_vdivs_
);
612 connect(pvdiv_sb
, SIGNAL(valueChanged(int)),
613 this, SLOT(on_pos_vdivs_changed(int)));
614 layout
->addRow(tr("Number of pos vertical divs"), pvdiv_sb
);
616 QSpinBox
*nvdiv_sb
= new QSpinBox(parent
);
617 nvdiv_sb
->setRange(0, MaximumVDivs
);
618 nvdiv_sb
->setValue(neg_vdivs_
);
619 connect(nvdiv_sb
, SIGNAL(valueChanged(int)),
620 this, SLOT(on_neg_vdivs_changed(int)));
621 layout
->addRow(tr("Number of neg vertical divs"), nvdiv_sb
);
623 // Add the vertical resolution
624 resolution_cb_
= new QComboBox(parent
);
626 for (int i
= MinScaleIndex
; i
< MaxScaleIndex
; i
++) {
627 const QString label
= QString("%1").arg(get_resolution(i
));
628 resolution_cb_
->insertItem(0, label
, QVariant(i
));
631 int cur_idx
= resolution_cb_
->findData(QVariant(scale_index_
));
632 resolution_cb_
->setCurrentIndex(cur_idx
);
634 connect(resolution_cb_
, SIGNAL(currentIndexChanged(int)),
635 this, SLOT(on_resolution_changed(int)));
637 QGridLayout
*const vdiv_layout
= new QGridLayout
;
638 QLabel
*const vdiv_unit
= new QLabel(tr("V/div"));
639 vdiv_layout
->addWidget(resolution_cb_
, 0, 0);
640 vdiv_layout
->addWidget(vdiv_unit
, 0, 1);
642 layout
->addRow(tr("Vertical resolution"), vdiv_layout
);
644 // Add the autoranging checkbox
645 QCheckBox
* autoranging_cb
= new QCheckBox();
646 autoranging_cb
->setCheckState(autoranging_
? Qt::Checked
: Qt::Unchecked
);
648 connect(autoranging_cb
, SIGNAL(stateChanged(int)),
649 this, SLOT(on_autoranging_changed(int)));
651 layout
->addRow(tr("Autoranging"), autoranging_cb
);
653 // Add the conversion type dropdown
654 conversion_cb_
= new QComboBox();
656 conversion_cb_
->addItem("none", data::SignalBase::NoConversion
);
657 conversion_cb_
->addItem("to logic via threshold", data::SignalBase::A2LConversionByTreshold
);
658 conversion_cb_
->addItem("to logic via schmitt-trigger", data::SignalBase::A2LConversionBySchmittTrigger
);
660 cur_idx
= conversion_cb_
->findData(QVariant(conversion_type_
));
661 conversion_cb_
->setCurrentIndex(cur_idx
);
663 layout
->addRow(tr("Conversion"), conversion_cb_
);
665 connect(conversion_cb_
, SIGNAL(currentIndexChanged(int)),
666 this, SLOT(on_conversion_changed(int)));
668 // Add the display type dropdown
669 display_type_cb_
= new QComboBox();
671 display_type_cb_
->addItem(tr("Analog"), DisplayAnalog
);
672 display_type_cb_
->addItem(tr("Converted"), DisplayConverted
);
673 display_type_cb_
->addItem(tr("Both"), DisplayBoth
);
675 cur_idx
= display_type_cb_
->findData(QVariant(display_type_
));
676 display_type_cb_
->setCurrentIndex(cur_idx
);
678 layout
->addRow(tr("Traces to show:"), display_type_cb_
);
680 connect(display_type_cb_
, SIGNAL(currentIndexChanged(int)),
681 this, SLOT(on_display_type_changed(int)));
683 form
->addRow(layout
);
686 void AnalogSignal::on_samples_added()
688 perform_autoranging();
691 // Call order is important, otherwise the lazy event handler won't work
692 owner_
->extents_changed(false, true);
693 owner_
->row_item_appearance_changed(false, true);
697 void AnalogSignal::on_pos_vdivs_changed(int vdivs
)
702 perform_autoranging(true);
705 // Call order is important, otherwise the lazy event handler won't work
706 owner_
->extents_changed(false, true);
707 owner_
->row_item_appearance_changed(false, true);
711 void AnalogSignal::on_neg_vdivs_changed(int vdivs
)
716 perform_autoranging(true);
719 // Call order is important, otherwise the lazy event handler won't work
720 owner_
->extents_changed(false, true);
721 owner_
->row_item_appearance_changed(false, true);
725 void AnalogSignal::on_resolution_changed(int index
)
727 scale_index_
= resolution_cb_
->itemData(index
).toInt();
731 owner_
->row_item_appearance_changed(false, true);
734 void AnalogSignal::on_autoranging_changed(int state
)
736 autoranging_
= (state
== Qt::Checked
);
739 perform_autoranging(true);
742 // Call order is important, otherwise the lazy event handler won't work
743 owner_
->extents_changed(false, true);
744 owner_
->row_item_appearance_changed(false, true);
748 void AnalogSignal::on_conversion_changed(int index
)
750 data::SignalBase::ConversionType old_conv_type
= conversion_type_
;
752 conversion_type_
= (data::SignalBase::ConversionType
)(conversion_cb_
->itemData(index
).toInt());
754 if (conversion_type_
!= old_conv_type
) {
755 base_
->set_conversion_type(conversion_type_
);
756 update_conversion_type();
760 void AnalogSignal::on_display_type_changed(int index
)
762 display_type_
= (DisplayType
)(display_type_cb_
->itemData(index
).toInt());
765 owner_
->row_item_appearance_changed(false, true);
768 } // namespace TraceView