X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fview%2Flogicsignal.cpp;h=6eb68db381357835fe8fc3feb1d0ff2fb95697a3;hp=b1aaae8f2ddbdf26e2724c1b99787d87d7fd8b0d;hb=d60820d865b8044aa6447a49861eac0dd0a6a4d4;hpb=ff008de665c7990d5f3408f918ff090d8e6c60b2 diff --git a/pv/view/logicsignal.cpp b/pv/view/logicsignal.cpp index b1aaae8f..6eb68db3 100644 --- a/pv/view/logicsignal.cpp +++ b/pv/view/logicsignal.cpp @@ -25,6 +25,7 @@ #include +#include #include #include @@ -33,11 +34,12 @@ #include #include +#include #include -#include +#include #include -#include +#include using std::deque; using std::max; @@ -49,7 +51,7 @@ using std::vector; using sigrok::Channel; using sigrok::ConfigKey; -using sigrok::Device; +using sigrok::Capability; using sigrok::Error; using sigrok::Trigger; using sigrok::TriggerStage; @@ -59,9 +61,6 @@ using sigrok::TriggerMatchType; namespace pv { namespace view { -const int LogicSignal::SignalHeight = 30; -const int LogicSignal::SignalMargin = 10; - const float LogicSignal::Oversampling = 2.0f; const QColor LogicSignal::EdgeColour(0x80, 0x80, 0x80); @@ -99,22 +98,23 @@ QCache LogicSignal::pixmap_cache_; LogicSignal::LogicSignal( pv::Session &session, - shared_ptr device, + shared_ptr device, shared_ptr channel, shared_ptr data) : Signal(session, channel), + signal_height_(QFontMetrics(QApplication::font()).height() * 2), device_(device), data_(data), - trigger_none_(NULL), - trigger_rising_(NULL), - trigger_high_(NULL), - trigger_falling_(NULL), - trigger_low_(NULL), - trigger_change_(NULL) + trigger_none_(nullptr), + trigger_rising_(nullptr), + trigger_high_(nullptr), + trigger_falling_(nullptr), + trigger_low_(nullptr), + trigger_change_(nullptr) { shared_ptr trigger; - colour_ = SignalColours[channel->index() % countof(SignalColours)]; + set_colour(SignalColours[channel->index() % countof(SignalColours)]); /* Populate this channel's trigger setting with whatever we * find in the current session trigger, if anything. */ @@ -126,10 +126,6 @@ LogicSignal::LogicSignal( trigger_match_ = match->type(); } -LogicSignal::~LogicSignal() -{ -} - shared_ptr LogicSignal::data() const { return data_; @@ -140,18 +136,31 @@ shared_ptr LogicSignal::logic_data() const return data_; } +void LogicSignal::set_logic_data(std::shared_ptr data) +{ + data_ = data; +} + std::pair LogicSignal::v_extents() const { - return make_pair(-SignalHeight - SignalMargin, SignalMargin); + const int signal_margin = + QFontMetrics(QApplication::font()).height() / 2; + return make_pair(-signal_height_ - signal_margin, signal_margin); } -void LogicSignal::paint_back(QPainter &p, const RowItemPaintParams &pp) +int LogicSignal::scale_handle_offset() const { - if (channel_->enabled()) - paint_axis(p, pp, get_visual_y()); + return -signal_height_; } -void LogicSignal::paint_mid(QPainter &p, const RowItemPaintParams &pp) +void LogicSignal::scale_handle_dragged(int offset) +{ + const int font_height = QFontMetrics(QApplication::font()).height(); + const int units = (-offset / font_height); + signal_height_ = ((units < 1) ? 1 : units) * font_height; +} + +void LogicSignal::paint_mid(QPainter &p, const ViewItemPaintParams &pp) { QLineF *line; @@ -166,33 +175,36 @@ void LogicSignal::paint_mid(QPainter &p, const RowItemPaintParams &pp) if (!channel_->enabled()) return; - const float high_offset = y - SignalHeight + 0.5f; + const float high_offset = y - signal_height_ + 0.5f; const float low_offset = y + 0.5f; - const deque< shared_ptr > &snapshots = - data_->logic_snapshots(); - if (snapshots.empty()) + const deque< shared_ptr > &segments = + data_->logic_segments(); + if (segments.empty()) return; - const shared_ptr &snapshot = - snapshots.front(); + const shared_ptr &segment = + segments.front(); - double samplerate = snapshot->samplerate(); + double samplerate = segment->samplerate(); // Show sample rate as 1Hz when it is unknown if (samplerate == 0.0) samplerate = 1.0; const double pixels_offset = pp.pixels_offset(); - const double start_time = snapshot->start_time(); - const int64_t last_sample = snapshot->get_sample_count() - 1; + 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 start = samplerate * (pp.offset() - start_time); - const double end = start + samples_per_pixel * pp.width(); + const pv::util::Timestamp start = samplerate * (pp.offset() - start_time); + const pv::util::Timestamp end = start + samples_per_pixel * pp.width(); - snapshot->get_subsampled_edges(edges, - min(max((int64_t)floor(start), (int64_t)0), last_sample), - min(max((int64_t)ceil(end), (int64_t)0), last_sample), + const int64_t start_sample = min(max(floor(start).convert_to(), + (int64_t)0), last_sample); + const uint64_t end_sample = min(max(ceil(end).convert_to(), + (int64_t)0), last_sample); + + segment->get_subsampled_edges(edges, start_sample, end_sample, samples_per_pixel / Oversampling, channel_->index()); assert(edges.size() >= 2); @@ -225,10 +237,10 @@ void LogicSignal::paint_mid(QPainter &p, const RowItemPaintParams &pp) delete[] cap_lines; } -void LogicSignal::paint_fore(QPainter &p, const RowItemPaintParams &pp) +void LogicSignal::paint_fore(QPainter &p, const ViewItemPaintParams &pp) { // Draw the trigger marker - if (!trigger_match_) + if (!trigger_match_ || !channel_->enabled()) return; const int y = get_visual_y(); @@ -246,15 +258,15 @@ void LogicSignal::paint_fore(QPainter &p, const RowItemPaintParams &pp) if (!pixmap) continue; - const int pad = TriggerMarkerPadding; + const float pad = TriggerMarkerPadding - 0.5f; const QSize size = pixmap->size(); const QPoint point( pp.right() - size.width() - pad * 2, - y - (SignalHeight + size.height()) / 2); + y - (signal_height_ + size.height()) / 2); - p.setPen(QPen(Qt::NoPen)); + p.setPen(QPen(TriggerMarkerBackgroundColour.darker())); p.setBrush(TriggerMarkerBackgroundColour); - p.drawRoundedRect(QRect(point, size).adjusted( + p.drawRoundedRect(QRectF(point, size).adjusted( -pad, -pad, pad, pad), pad, pad); p.drawPixmap(point, *pixmap); @@ -316,12 +328,25 @@ void LogicSignal::init_trigger_actions(QWidget *parent) const vector LogicSignal::get_trigger_types() const { - try { + const auto sr_dev = device_->device(); + if (sr_dev->config_check(ConfigKey::TRIGGER_MATCH, Capability::LIST)) { const Glib::VariantContainerBase gvar = - device_->config_list(ConfigKey::TRIGGER_MATCH); - return Glib::VariantBase::cast_dynamic< - Glib::Variant>>(gvar).get(); - } catch (Error e) { + sr_dev->config_list(ConfigKey::TRIGGER_MATCH); + + vector ttypes; + + for (unsigned int i = 0; i < gvar.get_n_children(); i++) { + Glib::VariantBase tmp_vb; + gvar.get_child(tmp_vb, i); + + Glib::Variant tmp_v = + Glib::VariantBase::cast_dynamic< Glib::Variant >(tmp_vb); + + ttypes.push_back(tmp_v.get()); + } + + return ttypes; + } else { return vector(); } } @@ -376,21 +401,23 @@ void LogicSignal::populate_popup_form(QWidget *parent, QFormLayout *form) { Signal::populate_popup_form(parent, form); - trigger_bar_ = new QToolBar(parent); - init_trigger_actions(trigger_bar_); - trigger_bar_->addAction(trigger_none_); - trigger_none_->setChecked(!trigger_match_); - const vector trig_types = get_trigger_types(); - for (auto type_id : trig_types) { - const TriggerMatchType *const type = - TriggerMatchType::get(type_id); - QAction *const action = action_from_trigger_type(type); - trigger_bar_->addAction(action); - action->setChecked(trigger_match_ == type); - } - form->addRow(tr("Trigger"), trigger_bar_); + if (!trig_types.empty()) { + trigger_bar_ = new QToolBar(parent); + init_trigger_actions(trigger_bar_); + trigger_bar_->addAction(trigger_none_); + trigger_none_->setChecked(!trigger_match_); + + for (auto type_id : trig_types) { + const TriggerMatchType *const type = + TriggerMatchType::get(type_id); + QAction *const action = action_from_trigger_type(type); + trigger_bar_->addAction(action); + action->setChecked(trigger_match_ == type); + } + form->addRow(tr("Trigger"), trigger_bar_); + } } void LogicSignal::modify_trigger() @@ -401,7 +428,7 @@ void LogicSignal::modify_trigger() if (trigger) { for (auto stage : trigger->stages()) { const auto &matches = stage->matches(); - if (std::none_of(begin(matches), end(matches), + if (std::none_of(matches.begin(), matches.end(), [&](shared_ptr match) { return match->channel() != channel_; })) continue; @@ -415,36 +442,41 @@ void LogicSignal::modify_trigger() } } - if (trigger_match_) - new_trigger->add_stage()->add_match(channel_, trigger_match_); + if (trigger_match_) { + // Until we can let the user decide how to group trigger matches + // into stages, put all of the matches into a single stage -- + // most devices only support a single trigger stage. + if (new_trigger->stages().empty()) + new_trigger->add_stage(); + + new_trigger->stages().back()->add_match(channel_, trigger_match_); + } session_.session()->set_trigger( new_trigger->stages().empty() ? nullptr : new_trigger); if (owner_) - owner_->appearance_changed(false, true); + owner_->row_item_appearance_changed(false, true); } const QIcon* LogicSignal::get_icon(const char *path) { - const QIcon *icon = icon_cache_.take(path); - if (!icon) { - icon = new QIcon(path); + if (!icon_cache_.contains(path)) { + const QIcon *icon = new QIcon(path); icon_cache_.insert(path, icon); } - return icon; + return icon_cache_.take(path); } const QPixmap* LogicSignal::get_pixmap(const char *path) { - const QPixmap *pixmap = pixmap_cache_.take(path); - if (!pixmap) { - pixmap = new QPixmap(path); + if (!pixmap_cache_.contains(path)) { + const QPixmap *pixmap = new QPixmap(path); pixmap_cache_.insert(path, pixmap); } - return pixmap; + return pixmap_cache_.take(path); } void LogicSignal::on_trigger()