]> sigrok.org Git - pulseview.git/blobdiff - pv/views/trace/view.cpp
TabularDecView: Remove unnecessary stuff
[pulseview.git] / pv / views / trace / view.cpp
index 6159cdd997053b921dedb6158860796e0195cac1..0a51a96fb5398a590997e558a9fc7427c9e3679b 100644 (file)
@@ -52,6 +52,7 @@
 #include "view.hpp"
 #include "viewport.hpp"
 
+#include "pv/metadata_obj.hpp"
 #include "pv/data/logic.hpp"
 #include "pv/data/logicsegment.hpp"
 #include "pv/devices/device.hpp"
@@ -94,8 +95,10 @@ const Timestamp View::MinScale("1e-12");
 
 const int View::MaxScrollValue = INT_MAX / 2;
 
-const int View::ScaleUnits[3] = {1, 2, 5};
+/* Area at the top and bottom of the view that can't be scrolled out of sight */
+const int View::ViewScrollMargin = 50;
 
+const int View::ScaleUnits[3] = {1, 2, 5};
 
 CustomScrollArea::CustomScrollArea(QWidget *parent) :
        QAbstractScrollArea(parent)
@@ -180,6 +183,12 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) :
 
        GlobalSettings::add_change_handler(this);
 
+       // Set up metadata objects and event handlers
+       if (is_main_view)
+               session_.metadata_obj_manager()->create_object(MetadataObjMainViewRange);
+
+
+       // Set up UI event handlers
        connect(scrollarea_->horizontalScrollBar(), SIGNAL(valueChanged(int)),
                this, SLOT(h_scroll_value_changed(int)));
        connect(scrollarea_->verticalScrollBar(), SIGNAL(valueChanged(int)),
@@ -201,6 +210,7 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) :
        connect(&lazy_event_handler_, SIGNAL(timeout()),
                this, SLOT(process_sticky_events()));
        lazy_event_handler_.setSingleShot(true);
+       lazy_event_handler_.setInterval(1000 / ViewBase::MaxViewAutoUpdateRate);
 
        // Set up local keyboard shortcuts
        zoom_in_shortcut_ = new QShortcut(QKeySequence(Qt::Key_Plus), this,
@@ -315,7 +325,7 @@ const Session& View::session() const
        return session_;
 }
 
-unordered_set< shared_ptr<Signal> > View::signals() const
+vector< shared_ptr<Signal> > View::signals() const
 {
        return signals_;
 }
@@ -342,7 +352,7 @@ void View::clear_signals()
 void View::add_signal(const shared_ptr<Signal> signal)
 {
        ViewBase::add_signalbase(signal->base());
-       signals_.insert(signal);
+       signals_.push_back(signal);
 
        signal->set_segment_display_mode(segment_display_mode_);
        signal->set_current_segment(current_segment_);
@@ -522,6 +532,22 @@ void View::set_offset(const pv::util::Timestamp& offset, bool force_update)
        if ((offset_ != offset) || force_update) {
                offset_ = offset;
                ruler_offset_ = offset_ + zero_offset_;
+
+               const int w = viewport_->width();
+               if (w > 0) {
+                       const double samplerate = session_.get_samplerate();
+                       // Note: sample_num = time * samplerate
+                       // Note: samples_per_pixel = samplerate * scale
+                       int64_t start_sample = (offset_ * samplerate).convert_to<int64_t>();
+                       int64_t end_sample = (offset_ * samplerate).convert_to<int64_t>() +
+                               (w * session_.get_samplerate() * scale_);
+
+                       MetadataObject* md_obj =
+                               session_.metadata_obj_manager()->find_object_by_type(MetadataObjMainViewRange);
+                       md_obj->set_value(MetadataValueStartSample, QVariant((qlonglong)start_sample));
+                       md_obj->set_value(MetadataValueEndSample, QVariant((qlonglong)end_sample));
+               }
+
                offset_changed();
        }
 }
@@ -780,6 +806,26 @@ void View::zoom_fit(bool gui_state)
        set_scale_offset(scale.convert_to<double>(), extents.first);
 }
 
+void View::focus_on_range(uint64_t start_sample, uint64_t end_sample)
+{
+       assert(viewport_);
+       const int w = viewport_->width();
+       if (w <= 0)
+               return;
+
+       const double samplerate = session_.get_samplerate();
+
+       const uint64_t sample_delta = (end_sample - start_sample);
+
+       // Note: We add 20% margin on the left and 5% on the right
+       const Timestamp delta = (sample_delta * 1.25) / samplerate;
+
+       const Timestamp scale = max(min(delta / w, MaxScale), MinScale);
+       const Timestamp offset = (start_sample - sample_delta * 0.20) / samplerate;
+
+       set_scale_offset(scale.convert_to<double>(), offset);
+}
+
 void View::set_scale_offset(double scale, const Timestamp& offset)
 {
        // Disable sticky scrolling / always zoom to fit when acquisition runs
@@ -808,13 +854,13 @@ void View::set_scale_offset(double scale, const Timestamp& offset)
        viewport_->update();
 }
 
-set< shared_ptr<SignalData> > View::get_visible_data() const
+vector< shared_ptr<SignalData> > View::get_visible_data() const
 {
        // Make a set of all the visible data objects
-       set< shared_ptr<SignalData> > visible_data;
+       vector< shared_ptr<SignalData> > visible_data;
        for (const shared_ptr<Signal>& sig : signals_)
                if (sig->enabled())
-                       visible_data.insert(sig->data());
+                       visible_data.push_back(sig->data());
 
        return visible_data;
 }
@@ -822,8 +868,14 @@ set< shared_ptr<SignalData> > View::get_visible_data() const
 pair<Timestamp, Timestamp> View::get_time_extents() const
 {
        boost::optional<Timestamp> left_time, right_time;
-       const set< shared_ptr<SignalData> > visible_data = get_visible_data();
-       for (const shared_ptr<SignalData>& d : visible_data) {
+
+       vector< shared_ptr<SignalData> > data;
+       if (signals_.size() == 0)
+               return make_pair(0, 0);
+
+       data.push_back(signals_.front()->data());
+
+       for (const shared_ptr<SignalData>& d : data) {
                const vector< shared_ptr<Segment> > segments = d->segments();
                for (const shared_ptr<Segment>& s : segments) {
                        double samplerate = s->samplerate();
@@ -1245,9 +1297,13 @@ void View::update_scroll()
        const pair<int, int> extents = v_extents();
 
        // Don't change the scrollbar range if there are no traces
-       if (extents.first != extents.second)
-               vscrollbar->setRange(extents.first - areaSize.height(),
-                       extents.second);
+       if (extents.first != extents.second) {
+               int top_margin = ViewScrollMargin;
+               int btm_margin = ViewScrollMargin;
+
+               vscrollbar->setRange(extents.first - areaSize.height() + top_margin,
+                       extents.second - btm_margin);
+       }
 
        if (scroll_needs_defaults_) {
                set_scroll_default();
@@ -1547,8 +1603,8 @@ void View::extents_changed(bool horz, bool vert)
                (horz ? TraceTreeItemHExtentsChanged : 0) |
                (vert ? TraceTreeItemVExtentsChanged : 0);
 
-       lazy_event_handler_.stop();
-       lazy_event_handler_.start();
+       if (!lazy_event_handler_.isActive())
+               lazy_event_handler_.start();
 }
 
 void View::on_signal_name_changed()