X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=pv%2Fview%2Fview.cpp;h=1aa7b7292da842b660865c821d6a884b929c18c9;hb=f32905530347e1020d5ce7959123cf797c9a4829;hp=2ae0a7144cba4b9b15abbc34f3e9265e14f43250;hpb=cf124e472f9b5be7f85ecf708fe5290d6a6d1c9e;p=pulseview.git diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 2ae0a714..1aa7b729 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -86,6 +86,7 @@ const double View::MaxScale = 1e9; const double View::MinScale = 1e-15; const int View::MaxScrollValue = INT_MAX / 2; +const int View::MaxViewAutoUpdateRate = 25; // No more than 25 Hz with sticky scrolling const int View::ScaleUnits[3] = {1, 2, 5}; @@ -98,6 +99,8 @@ View::View(Session &session, QWidget *parent) : scale_(1e-3), offset_(0), updating_scroll_(false), + sticky_scrolling_(false), // Default setting is set in MainWindow::setup_ui() + always_zoom_to_fit_(false), tick_period_(0.0), tick_prefix_(0), show_cursors_(false), @@ -136,6 +139,11 @@ View::View(Session &session, QWidget *parent) : this, SLOT(process_sticky_events())); lazy_event_handler_.setSingleShot(true); + connect(&delayed_view_updater_, SIGNAL(timeout()), + this, SLOT(perform_delayed_view_update())); + delayed_view_updater_.setSingleShot(true); + delayed_view_updater_.setInterval(1000 / MaxViewAutoUpdateRate); + setViewport(viewport_); viewport_->installEventFilter(this); @@ -241,8 +249,17 @@ void View::zoom(double steps, int offset) set_zoom(scale_ * pow(3.0/2.0, -steps), offset); } -void View::zoom_fit() +void View::zoom_fit(bool gui_state) { + // Act as one-shot when stopped, toggle along with the GUI otherwise + if (session_.get_capture_state() == Session::Stopped) { + always_zoom_to_fit_ = false; + always_zoom_to_fit_changed(false); + } else { + always_zoom_to_fit_ = gui_state; + always_zoom_to_fit_changed(gui_state); + } + const pair extents = get_time_extents(); const double delta = extents.second - extents.first; if (delta < 1e-12) @@ -288,6 +305,22 @@ void View::zoom_one_to_one() void View::set_scale_offset(double scale, double offset) { + // Disable sticky scrolling / always zoom to fit when acquisition runs + // and user drags the viewport + if ((scale_ == scale) && (offset_ != offset) && + (session_.get_capture_state() == Session::Running)) { + + if (sticky_scrolling_) { + sticky_scrolling_ = false; + sticky_scrolling_changed(false); + } + + if (always_zoom_to_fit_) { + always_zoom_to_fit_ = false; + always_zoom_to_fit_changed(false); + } + } + scale_ = scale; offset_ = offset; @@ -339,6 +372,11 @@ pair View::get_time_extents() const return make_pair(left_time, right_time); } +void View::enable_sticky_scrolling(bool state) +{ + sticky_scrolling_ = state; +} + bool View::cursors_shown() const { return show_cursors_; @@ -430,6 +468,10 @@ void View::get_scroll_layout(double &length, double &offset) const void View::set_zoom(double scale, int offset) { + // Reset the "always zoom to fit" feature as the user changed the zoom + always_zoom_to_fit_ = false; + always_zoom_to_fit_changed(false); + const double cursor_offset = offset_ + scale_ * offset; const double new_scale = max(min(scale, MaxScale), MinScale); const double new_offset = cursor_offset - new_scale * offset; @@ -467,7 +509,7 @@ void View::calculate_tick_spacing() min_width += SpacingIncrement; - } while(typical_width > tick_period_ / scale_); + } while (typical_width > tick_period_ / scale_); } void View::update_scroll() @@ -674,6 +716,13 @@ void View::h_scroll_value_changed(int value) if (updating_scroll_) return; + // Disable sticky scrolling when user moves the horizontal scroll bar + // during a running acquisition + if (sticky_scrolling_ && (session_.get_capture_state() == Session::Running)) { + sticky_scrolling_ = false; + sticky_scrolling_changed(false); + } + const int range = horizontalScrollBar()->maximum(); if (range < MaxScrollValue) offset_ = scale_ * value; @@ -821,10 +870,40 @@ void View::signals_changed() void View::data_updated() { - // Update the scroll bars - update_scroll(); + // Reset "always zoom to fit" when we change to the stopped state + if (always_zoom_to_fit_ && (session_.get_capture_state() == Session::Stopped)) { + always_zoom_to_fit_ = false; + always_zoom_to_fit_changed(false); + } - // Repaint the view + if (always_zoom_to_fit_ || sticky_scrolling_) { + if (!delayed_view_updater_.isActive()) + delayed_view_updater_.start(); + } else { + update_scroll(); + ruler_->update(); + viewport_->update(); + } +} + +void View::perform_delayed_view_update() +{ + if (always_zoom_to_fit_) + zoom_fit(true); + + if (sticky_scrolling_) { + // Make right side of the view sticky + double length = 0, offset; + get_scroll_layout(length, offset); + + const QSize areaSize = viewport_->size(); + length = max(length - areaSize.width(), 0.0); + + offset_ = scale_ * length; + } + + update_scroll(); + ruler_->update(); viewport_->update(); }