diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index ef1e2f69..dfb54480 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -226,10 +226,7 @@ void View::zoom(double steps, int offset) } } _offset = cursor_offset - _scale * offset; - const double MinOffset = -(_scale * (get_view_width() * (1 - MaxViewRate))); - const double MaxOffset = _session.get_device()->get_sample_time() - - _scale * (get_view_width() * MaxViewRate); - _offset = max(min(_offset, MaxOffset), MinOffset); + _offset = max(min(_offset, get_max_offset()), get_min_offset()); if (_scale != _preScale || _offset != _preOffset) { _header->update(); @@ -248,11 +245,7 @@ void View::set_scale_offset(double scale, double offset) _preOffset = _offset; _scale = max(min(scale, _maxscale), _minscale); - - const double MinOffset = -(_scale * (get_view_width() * (1 - MaxViewRate))); - const double MaxOffset = _session.get_device()->get_sample_time() - - _scale * (get_view_width() * MaxViewRate); - _offset = max(min(offset, MaxOffset), MinOffset); + _offset = max(min(offset, get_max_offset()), get_min_offset()); if (_scale != _preScale || _offset != _preOffset) { update_scroll(); @@ -604,10 +597,6 @@ void View::h_scroll_value_changed(int value) _preOffset = _offset; - const double MinOffset = -(_scale * (get_view_width() * (1 - MaxViewRate))); - const double MaxOffset = _session.get_device()->get_sample_time() - - _scale * (get_view_width() * MaxViewRate); - const int range = horizontalScrollBar()->maximum(); if (range < MaxScrollValue) _offset = _scale * value; @@ -617,7 +606,7 @@ void View::h_scroll_value_changed(int value) _offset = _scale * length * value / MaxScrollValue; } - _offset = max(min(_offset, MaxOffset), MinOffset); + _offset = max(min(_offset, get_max_offset()), get_min_offset()); if (_offset != _preOffset) { _ruler->update(); @@ -796,5 +785,16 @@ int View::get_view_width() return view_width; } +double View::get_min_offset() +{ + return -(_scale * (get_view_width() * (1 - MaxViewRate))); +} + +double View::get_max_offset() +{ + return _session.get_device()->get_sample_time() + - _scale * (get_view_width() * MaxViewRate); +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index 81bffcb2..460de3b8 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -95,6 +95,9 @@ public: double offset() const; int v_offset() const; + double get_min_offset(); + double get_max_offset(); + void zoom(double steps); void zoom(double steps, int offset); diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index d8d8351f..ba36d329 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -46,6 +46,9 @@ using namespace std; namespace pv { namespace view { +const double Viewport::DragDamping = 1.05; +const double Viewport::MinorDragRateUp = 10; + Viewport::Viewport(View &parent) : QWidget(&parent), _view(parent), @@ -74,10 +77,16 @@ Viewport::Viewport(View &parent) : triggered = false; timer_cnt = 0; + // drag inertial + _drag_strength = 0; + _drag_timer.setSingleShot(true); + connect(&_view, SIGNAL(traces_moved()), this, SLOT(on_traces_moved())); connect(&trigger_timer, SIGNAL(timeout()), this, SLOT(on_trigger_timer())); + connect(&_drag_timer, SIGNAL(timeout()), + this, SLOT(on_drag_timer())); connect(&_view.session(), &SigSession::receive_data, this, &Viewport::set_receive_len); @@ -355,6 +364,8 @@ void Viewport::mousePressEvent(QMouseEvent *event) _mouse_down_point = event->pos(); _mouse_down_offset = _view.offset(); _measure_shown = false; + _drag_strength = 0; + _time.start(); if (event->buttons() & Qt::LeftButton) { if (_view.cursors_shown()) { @@ -392,7 +403,6 @@ void Viewport::mousePressEvent(QMouseEvent *event) void Viewport::mouseMoveEvent(QMouseEvent *event) { assert(event); - _mouse_point = event->pos(); _hover_hit = false; if (event->buttons() & Qt::RightButton) { _zoom_rect = QRectF(_mouse_down_point, event->pos()); @@ -403,12 +413,13 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) if (_drag_sig) { boost::shared_ptr dsoSig; if (dsoSig = dynamic_pointer_cast(_drag_sig)) - dsoSig->set_trig_vpos(_mouse_point.y()); + dsoSig->set_trig_vpos(event->pos().y()); } else { _view.set_scale_offset(_view.scale(), _mouse_down_offset + (_mouse_down_point - event->pos()).x() * _view.scale()); + _drag_strength = (_mouse_down_point - event->pos()).x(); measure(); } } @@ -428,6 +439,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) measure(); } + _mouse_point = event->pos(); update(); } @@ -454,6 +466,18 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) _hover_hit = false; } + const double strength = _drag_strength*DragTimerInterval*1.0/_time.elapsed(); + if (_drag_strength < MinorDragOffsetUp && abs(strength) > MinorDragRateUp) { + _drag_strength = _drag_strength; + _drag_timer.start(DragTimerInterval); + } else if (abs(strength) > 0.5*DragTimerInterval) { + _drag_strength = strength * 5; + _drag_timer.start(DragTimerInterval); + } else { + _drag_strength = 0; + _drag_timer.stop(); + } + update(); } @@ -520,7 +544,8 @@ void Viewport::set_receive_len(quint64 length) void Viewport::measure() { - if (_view.session().get_capture_state() == SigSession::Running) + if (_view.session().get_capture_state() == SigSession::Running || + _drag_strength != 0) return; _measure_shown = false; const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); @@ -723,5 +748,22 @@ void Viewport::on_trigger_timer() update(); } +void Viewport::on_drag_timer() +{ + const double offset = _view.offset(); + const double scale = _view.scale(); + if (_view.session().get_capture_state() == SigSession::Stopped && + _drag_strength != 0 && + offset < _view.get_max_offset() && + offset > _view.get_min_offset()) { + _view.set_scale_offset(scale, offset + _drag_strength * scale); + _drag_strength /= DragDamping; + if (_drag_strength != 0) + _drag_timer.start(DragTimerInterval); + } else { + _drag_timer.stop(); + } +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/viewport.h b/DSView/pv/view/viewport.h index 4899577b..fb959d2f 100644 --- a/DSView/pv/view/viewport.h +++ b/DSView/pv/view/viewport.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,10 @@ class Viewport : public QWidget public: static const int HitCursorMargin = 10; static const double HitCursorTimeMargin; + static const int DragTimerInterval = 100; + static const int MinorDragOffsetUp = 100; + static const double MinorDragRateUp; + static const double DragDamping; public: explicit Viewport(View &parent); @@ -83,6 +88,7 @@ private: private slots: void on_traces_moved(); void on_trigger_timer(); + void on_drag_timer(); void set_receive_len(quint64 length); signals: @@ -127,6 +133,10 @@ private: uint64_t _hover_index; bool _hover_hit; + + QTime _time; + QTimer _drag_timer; + int _drag_strength; }; } // namespace view