connect(analog_data, SIGNAL(min_max_changed(float, float)),
this, SLOT(on_min_max_changed(float, float)));
- GlobalSettings gs;
+ GlobalSettings settings;
+ show_sampling_points_ =
+ settings.value(GlobalSettings::Key_View_ShowSamplingPoints).toBool();
+ fill_high_areas_ =
+ settings.value(GlobalSettings::Key_View_FillSignalHighAreas).toBool();
+ high_fill_color_ = QColor::fromRgba(settings.value(
+ GlobalSettings::Key_View_FillSignalHighAreaColor).value<uint32_t>());
+ show_analog_minor_grid_ =
+ settings.value(GlobalSettings::Key_View_ShowAnalogMinorGrid).toBool();
conversion_threshold_disp_mode_ =
- gs.value(GlobalSettings::Key_View_ConversionThresholdDispMode).toInt();
-
- div_height_ = gs.value(GlobalSettings::Key_View_DefaultDivHeight).toInt();
+ settings.value(GlobalSettings::Key_View_ConversionThresholdDispMode).toInt();
+ div_height_ = settings.value(GlobalSettings::Key_View_DefaultDivHeight).toInt();
base_->set_color(SignalColors[base_->index() % countof(SignalColors)]);
update_scale();
return make_pair(-ph, nh);
}
-void AnalogSignal::on_setting_changed(const QString &key, const QVariant &value)
-{
- Signal::on_setting_changed(key, value);
-
- if (key == GlobalSettings::Key_View_ConversionThresholdDispMode)
- on_settingViewConversionThresholdDispMode_changed(value);
-}
-
void AnalogSignal::paint_back(QPainter &p, ViewItemPaintParams &pp)
{
if (!base_->enabled())
paint_axis(p, pp, get_visual_y());
} else {
- Trace::paint_back(p, pp);
+ Signal::paint_back(p, pp);
paint_axis(p, pp, get_visual_y());
}
}
{
p.setRenderHint(QPainter::Antialiasing, false);
- GlobalSettings settings;
- const bool show_analog_minor_grid =
- settings.value(GlobalSettings::Key_View_ShowAnalogMinorGrid).toBool();
-
if (pos_vdivs_ > 0) {
p.setPen(QPen(GridMajorColor, 1, Qt::DashLine));
for (int i = 1; i <= pos_vdivs_; i++) {
}
}
- if ((pos_vdivs_ > 0) && show_analog_minor_grid) {
+ if ((pos_vdivs_ > 0) && show_analog_minor_grid_) {
p.setPen(QPen(GridMinorColor, 1, Qt::DashLine));
for (int i = 0; i < pos_vdivs_; i++) {
const float dy = i * div_height_;
}
}
- if ((pos_vdivs_ > 0) && show_analog_minor_grid) {
+ if ((pos_vdivs_ > 0) && show_analog_minor_grid_) {
p.setPen(QPen(GridMinorColor, 1, Qt::DashLine));
for (int i = 0; i < neg_vdivs_; i++) {
const float dy = i * div_height_;
// Calculate and paint the sampling points if enabled and useful
GlobalSettings settings;
const bool show_sampling_points =
- (settings.value(GlobalSettings::Key_View_ShowSamplingPoints).toBool() ||
- paint_thr_dots) && (samples_per_pixel < 0.25);
+ (show_sampling_points_ || paint_thr_dots) && (samples_per_pixel < 0.25);
p.setPen(base_->color());
const int nh = min(neg_vdivs_, 1) * div_height_;
const float high_offset = y - ph + signal_margin + 0.5f;
const float low_offset = y + nh - signal_margin - 0.5f;
+ const float signal_height = low_offset - high_offset;
shared_ptr<pv::data::LogicSegment> segment = get_logic_segment_to_paint();
if (!segment || (segment->get_sample_count() == 0))
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);
+ const float first_sample_x =
+ pp.left() + (edges.front().first / samples_per_pixel - pixels_offset);
+ const float last_sample_x =
+ pp.left() + (edges.back().first / samples_per_pixel - pixels_offset);
+ // Check whether we need to paint the sampling points
+ const bool show_sampling_points = show_sampling_points_ && (samples_per_pixel < 0.25);
vector<QRectF> sampling_points;
- float sampling_point_x = 0.0f;
+ float sampling_point_x = first_sample_x;
int64_t sampling_point_sample = start_sample;
const int w = 2;
- if (show_sampling_points) {
+ 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();
- }
+
+ vector<QRectF> high_rects;
+ float rising_edge_x;
+ bool rising_edge_seen = false;
// Paint the edges
const unsigned int edge_count = edges.size() - 2;
QLineF *const edge_lines = new QLineF[edge_count];
line = edge_lines;
+ if (edges.front().second) {
+ // Beginning of trace is high
+ rising_edge_x = first_sample_x;
+ rising_edge_seen = true;
+ }
+
for (auto i = edges.cbegin() + 1; i != edges.cend() - 1; i++) {
- const float x = ((*i).first / samples_per_pixel -
- pixels_offset) + pp.left();
+ // Note: multiple edges occupying a single pixel are represented by an edge
+ // with undefined logic level. This means that only the first falling edge
+ // after a rising edge corresponds to said rising edge - and vice versa. If
+ // more edges with the same logic level follow, they denote multiple edges.
+
+ const float x = pp.left() + ((*i).first / samples_per_pixel - pixels_offset);
*line++ = QLineF(x, high_offset, x, low_offset);
+ if (fill_high_areas_) {
+ // Any edge terminates a high area
+ if (rising_edge_seen) {
+ const int width = x - rising_edge_x;
+ if (width > 0)
+ high_rects.emplace_back(rising_edge_x, high_offset,
+ width, signal_height);
+ rising_edge_seen = false;
+ }
+
+ // Only rising edges start high areas
+ if ((*i).second) {
+ rising_edge_x = x;
+ rising_edge_seen = true;
+ }
+ }
+
if (show_sampling_points)
while (sampling_point_sample < (*i).first) {
const float y = (*i).second ? low_offset : high_offset;
sampling_point_x += pixels_per_sample;
};
+ if (fill_high_areas_) {
+ // Add last high rectangle if the signal is still high at the end of the trace
+ if (rising_edge_seen && (edges.cend() - 1)->second)
+ high_rects.emplace_back(rising_edge_x, high_offset,
+ last_sample_x - rising_edge_x, signal_height);
+
+ p.setPen(high_fill_color_);
+ p.setBrush(high_fill_color_);
+ p.drawRects((const QRectF*)(high_rects.data()), high_rects.size());
+ }
+
p.setPen(LogicSignal::EdgeColor);
p.drawLines(edge_lines, edge_count);
delete[] edge_lines;
conv_threshold_cb_->blockSignals(true);
// Set available options depending on chosen conversion
- for (pair<QString, int> preset : presets)
+ for (pair<QString, int>& preset : presets)
conv_threshold_cb_->addItem(preset.first, preset.second);
map < QString, QVariant > options = base_->get_conversion_options();
static double prev_min = 0, prev_max = 0;
double min = 0, max = 0;
- for (shared_ptr<pv::data::AnalogSegment> segment : segments) {
+ for (const shared_ptr<pv::data::AnalogSegment>& segment : segments) {
pair<double, double> mm = segment->get_min_max();
min = std::min(min, mm.first);
max = std::max(max, mm.second);
}
}
+void AnalogSignal::on_setting_changed(const QString &key, const QVariant &value)
+{
+ Signal::on_setting_changed(key, value);
+
+ if (key == GlobalSettings::Key_View_ShowSamplingPoints)
+ show_sampling_points_ = value.toBool();
+
+ if (key == GlobalSettings::Key_View_FillSignalHighAreas)
+ fill_high_areas_ = value.toBool();
+
+ if (key == GlobalSettings::Key_View_FillSignalHighAreaColor)
+ high_fill_color_ = QColor::fromRgba(value.value<uint32_t>());
+
+ if (key == GlobalSettings::Key_View_ShowAnalogMinorGrid)
+ show_analog_minor_grid_ = value.toBool();
+
+ if (key == GlobalSettings::Key_View_ConversionThresholdDispMode) {
+ conversion_threshold_disp_mode_ = value.toInt();
+
+ if (owner_)
+ owner_->row_item_appearance_changed(false, true);
+ }
+}
+
void AnalogSignal::on_min_max_changed(float min, float max)
{
(void)min;
owner_->row_item_appearance_changed(false, true);
}
-void AnalogSignal::on_settingViewConversionThresholdDispMode_changed(const QVariant new_value)
-{
- conversion_threshold_disp_mode_ = new_value.toInt();
-
- if (owner_)
- owner_->row_item_appearance_changed(false, true);
-}
-
} // namespace trace
} // namespace views
} // namespace pv