X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fview%2Fview.cpp;h=6ad7dea0822c0d6653a75b6b0ee2dd1e86a07e8b;hp=3f0fe9d1dc9991febf113d45f02f5dc6189c0ace;hb=dcfe0a01f72021aab961245d0ebcc9f8d4504b40;hpb=cef5997ee1e08d713663d2ae02c839a315f41409 diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 3f0fe9d1..6ad7dea0 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -32,6 +32,8 @@ #include #include +#include + #include #include #include @@ -40,12 +42,13 @@ #include -#include "decodetrace.hpp" +#include "analogsignal.hpp" #include "header.hpp" #include "logicsignal.hpp" #include "ruler.hpp" #include "signal.hpp" #include "tracegroup.hpp" +#include "triggermarker.hpp" #include "view.hpp" #include "viewport.hpp" @@ -55,6 +58,10 @@ #include "pv/data/logicsegment.hpp" #include "pv/util.hpp" +#ifdef ENABLE_DECODE +#include "decodetrace.hpp" +#endif + using boost::shared_lock; using boost::shared_mutex; @@ -63,6 +70,8 @@ using pv::data::Segment; using pv::util::TimeUnit; using pv::util::Timestamp; +using std::back_inserter; +using std::copy_if; using std::deque; using std::dynamic_pointer_cast; using std::inserter; @@ -70,6 +79,7 @@ using std::list; using std::lock_guard; using std::max; using std::make_pair; +using std::make_shared; using std::min; using std::pair; using std::set; @@ -109,6 +119,7 @@ View::View(Session &session, QWidget *parent) : show_cursors_(false), cursors_(new CursorPair(*this)), next_flag_text_('A'), + trigger_markers_(), hover_point_(-1, -1) { connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), @@ -202,6 +213,10 @@ vector< shared_ptr > View::time_items() const items.push_back(cursors_); items.push_back(cursors_->first()); items.push_back(cursors_->second()); + + for (auto trigger_marker : trigger_markers_) + items.push_back(trigger_marker); + return items; } @@ -344,24 +359,12 @@ void View::zoom_one_to_one() if (visible_data.empty()) return; - double samplerate = 0.0; - for (const shared_ptr d : visible_data) { - assert(d); - const vector< shared_ptr > segments = - d->segments(); - for (const shared_ptr &s : segments) - samplerate = max(samplerate, s->samplerate()); - } - - if (samplerate == 0.0) - return; - assert(viewport_); const int w = viewport_->width(); if (w <= 0) return; - set_zoom(1.0 / samplerate, w / 2); + set_zoom(1.0 / session_.get_samplerate(), w / 2); } void View::set_scale_offset(double scale, const Timestamp& offset) @@ -394,8 +397,7 @@ void View::set_scale_offset(double scale, const Timestamp& offset) set< shared_ptr > View::get_visible_data() const { - shared_lock lock(session().signals_mutex()); - const unordered_set< shared_ptr > &sigs(session().signals()); + const unordered_set< shared_ptr > sigs(session().signals()); // Make a set of all the visible data objects set< shared_ptr > visible_data; @@ -410,8 +412,7 @@ pair View::get_time_extents() const { boost::optional left_time, right_time; const set< shared_ptr > visible_data = get_visible_data(); - for (const shared_ptr d : visible_data) - { + for (const shared_ptr d : visible_data) { const vector< shared_ptr > segments = d->segments(); for (const shared_ptr &s : segments) { @@ -440,6 +441,33 @@ void View::enable_sticky_scrolling(bool state) sticky_scrolling_ = state; } +void View::enable_coloured_bg(bool state) +{ + const vector> items( + list_by_type()); + + for (shared_ptr i : items) { + // Can't cast to Trace because it's abstract, so we need to + // check for any derived classes individually + + shared_ptr a = dynamic_pointer_cast(i); + if (a) + a->set_coloured_bg(state); + + shared_ptr l = dynamic_pointer_cast(i); + if (l) + l->set_coloured_bg(state); + +#ifdef ENABLE_DECODE + shared_ptr d = dynamic_pointer_cast(i); + if (d) + d->set_coloured_bg(state); +#endif + } + + viewport_->update(); +} + bool View::cursors_shown() const { return show_cursors_; @@ -470,8 +498,10 @@ void View::add_flag(const Timestamp& time) { flags_.push_back(shared_ptr(new Flag(*this, time, QString("%1").arg(next_flag_text_)))); + next_flag_text_ = (next_flag_text_ >= 'Z') ? 'A' : (next_flag_text_ + 1); + time_item_appearance_changed(true, true); } @@ -507,7 +537,11 @@ void View::update_viewport() void View::restack_all_trace_tree_items() { // Make a list of owners that is sorted from deepest first - const auto owners = list_row_item_owners(); + const vector> items( + list_by_type()); + set< TraceTreeItemOwner* > owners; + for (const auto &r : items) + owners.insert(r->owner()); vector< TraceTreeItemOwner* > sorted_owners(owners.begin(), owners.end()); sort(sorted_owners.begin(), sorted_owners.end(), [](const TraceTreeItemOwner* a, const TraceTreeItemOwner *b) { @@ -517,13 +551,23 @@ void View::restack_all_trace_tree_items() for (auto &o : sorted_owners) o->restack_items(); + // Re-assign background colors + bool next_bgcolour_state = 0; + + for (auto &o : sorted_owners) + next_bgcolour_state = o->reassign_bgcolour_states(next_bgcolour_state); + // Animate the items to their destination - const vector< shared_ptr > items( - list_by_type()); for (const auto &i : items) i->animate_to_layout_v_offset(); } +void View::trigger_event(util::Timestamp location) +{ + trigger_markers_.push_back(shared_ptr( + new TriggerMarker(*this, location))); +} + void View::get_scroll_layout(double &length, Timestamp &offset) const { const pair extents = get_time_extents(); @@ -719,8 +763,7 @@ vector< shared_ptr > View::extract_new_traces_for_channels( { vector< shared_ptr > filtered_traces; - for (const auto &channel : channels) - { + for (const auto &channel : channels) { const auto map_iter = signal_map.find(channel); if (map_iter == signal_map.end()) continue; @@ -741,8 +784,7 @@ void View::determine_time_unit() { // Check whether we know the sample rate and hence can use time as the unit if (time_unit_ == util::TimeUnit::Samples) { - shared_lock lock(session().signals_mutex()); - const unordered_set< shared_ptr > &sigs(session().signals()); + const unordered_set< shared_ptr > sigs(session().signals()); // Check all signals but... for (const shared_ptr signal : sigs) { @@ -786,7 +828,7 @@ bool View::eventFilter(QObject *object, QEvent *event) bool View::viewportEvent(QEvent *e) { - switch(e->type()) { + switch (e->type()) { case QEvent::Paint: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: @@ -797,7 +839,6 @@ bool View::viewportEvent(QEvent *e) case QEvent::TouchUpdate: case QEvent::TouchEnd: return false; - default: return QAbstractScrollArea::viewportEvent(e); } @@ -866,6 +907,8 @@ void View::v_scroll_value_changed() void View::signals_changed() { + using sigrok::Channel; + vector< shared_ptr > new_top_level_items; const auto device = session_.device(); @@ -875,14 +918,16 @@ void View::signals_changed() shared_ptr sr_dev = device->device(); assert(sr_dev); + const vector< shared_ptr > channels( + sr_dev->channels()); + // Make a list of traces that are being added, and a list of traces // that are being removed const vector> prev_trace_list = list_by_type(); const set> prev_traces( prev_trace_list.begin(), prev_trace_list.end()); - shared_lock lock(session_.signals_mutex()); - const unordered_set< shared_ptr > &sigs(session_.signals()); + const unordered_set< shared_ptr > sigs(session_.signals()); set< shared_ptr > traces(sigs.begin(), sigs.end()); @@ -909,8 +954,7 @@ void View::signals_changed() signal_map[sig->channel()] = sig; // Populate channel groups - for (auto entry : sr_dev->channel_groups()) - { + for (auto entry : sr_dev->channel_groups()) { const shared_ptr &group = entry.second; if (group->channels().size() <= 1) @@ -954,9 +998,23 @@ void View::signals_changed() new_top_level_items.push_back(new_trace_group); } + // Enqueue the remaining logic channels in a group + vector< shared_ptr > logic_channels; + copy_if(channels.begin(), channels.end(), back_inserter(logic_channels), + [](const shared_ptr& c) { + return c->type() == sigrok::ChannelType::LOGIC; }); + const vector< shared_ptr > non_grouped_logic_signals = + extract_new_traces_for_channels(logic_channels, + signal_map, add_traces); + const shared_ptr non_grouped_trace_group( + make_shared()); + for (shared_ptr trace : non_grouped_logic_signals) + non_grouped_trace_group->add_child_item(trace); + new_top_level_items.push_back(non_grouped_trace_group); + // Enqueue the remaining channels as free ungrouped traces const vector< shared_ptr > new_top_level_signals = - extract_new_traces_for_channels(sr_dev->channels(), + extract_new_traces_for_channels(channels, signal_map, add_traces); new_top_level_items.insert(new_top_level_items.end(), new_top_level_signals.begin(), new_top_level_signals.end()); @@ -994,9 +1052,12 @@ void View::signals_changed() void View::capture_state_updated(int state) { - if (state == Session::Running) + if (state == Session::Running) { set_time_unit(util::TimeUnit::Samples); + trigger_markers_.clear(); + } + if (state == Session::Stopped) { // After acquisition has stopped we need to re-calculate the ticks once // as it's otherwise done when the user pans or zooms, which is too late @@ -1061,7 +1122,9 @@ void View::process_sticky_events() void View::on_hover_point_changed() { - for (shared_ptr r : *this) + const vector> trace_tree_items( + list_by_type()); + for (shared_ptr r : trace_tree_items) r->hover_point_changed(); }