diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index c2f18adf..51f760b2 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -184,8 +184,6 @@ void MainWindow::setup_ui() SLOT(hide_calibration())); connect(_dso_trigger_widget, SIGNAL(set_trig_pos(int)), _view, SLOT(set_trig_pos(int))); - connect(_sampling_bar, SIGNAL(hori_res_changed(double)), _view, - SLOT(hori_res_changed(double))); setIconSize(QSize(40,40)); addToolBar(_sampling_bar); diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index 9fa0e713..5517d96d 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -578,20 +578,22 @@ void SamplingBar::on_samplecount_sel(int index) sample_count_changed(); } -void SamplingBar::hori_knob(int dir) +double SamplingBar::hori_knob(int dir) { + double hori_res = -1; if (0 == dir) { - commit_hori_res(); + hori_res = commit_hori_res(); } else if ((dir > 0) && (_sample_count.currentIndex() > 0)) { _sample_count.setCurrentIndex(_sample_count.currentIndex() - 1); - commit_hori_res(); + hori_res = commit_hori_res(); } else if ((dir < 0) && (_sample_count.currentIndex() < _sample_count.count() - 1)) { _sample_count.setCurrentIndex(_sample_count.currentIndex() + 1); - commit_hori_res(); + hori_res = commit_hori_res(); } + return hori_res; } -void SamplingBar::commit_hori_res() +double SamplingBar::commit_hori_res() { const double hori_res = _sample_count.itemData( _sample_count.currentIndex()).value(); @@ -608,7 +610,7 @@ void SamplingBar::commit_hori_res() g_variant_unref(gvar); } else { qDebug() << "ERROR: config_get SR_CONF_MAX_DSO_SAMPLERATE failed."; - return; + return -1; } const uint64_t sample_rate = min((uint64_t)(sample_limit * SR_SEC(1) / @@ -622,7 +624,7 @@ void SamplingBar::commit_hori_res() dev_inst->set_config(NULL, NULL, SR_CONF_TIMEBASE, g_variant_new_uint64(hori_res)); - hori_res_changed(hori_res); + return hori_res; } void SamplingBar::commit_settings() diff --git a/DSView/pv/toolbars/samplingbar.h b/DSView/pv/toolbars/samplingbar.h index 4e47a002..eb1670f3 100644 --- a/DSView/pv/toolbars/samplingbar.h +++ b/DSView/pv/toolbars/samplingbar.h @@ -88,8 +88,8 @@ public: void enable_instant(bool enable); - void hori_knob(int dir); - void commit_hori_res(); + double hori_knob(int dir); + double commit_hori_res(); public slots: void set_sample_rate(uint64_t sample_rate); @@ -102,7 +102,6 @@ signals: void sample_count_changed(); void show_calibration(); void hide_calibration(); - void hori_res_changed(double hori_res); private: void update_sample_rate_selector_value(); diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index 093781f5..2b22ef67 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -356,6 +356,59 @@ bool LogicSignal::measure(const QPointF &p, uint64_t &index0, uint64_t &index1, return false; } +bool LogicSignal::edge(const QPointF &p, uint64_t &index, int radius) const +{ + uint64_t pre_index, nxt_index; + const float gap = abs(p.y() - get_y()); + if (gap < get_totalHeight() * 0.5) { + const deque< boost::shared_ptr > &snapshots = + _data->get_snapshots(); + if (snapshots.empty()) + return false; + + const boost::shared_ptr &snapshot = + snapshots.front(); + if (snapshot->empty() || !snapshot->has_data(_probe->index)) + return false; + + const uint64_t end = snapshot->get_sample_count() - 1; + const + double pos = _data->samplerate() * _view->scale() * (_view->offset() + p.x()); + index = floor(pos + 0.5); + if (index > end) + return false; + + bool sample = snapshot->get_sample(index, get_index()); + if (index == 0) + pre_index = index; + else { + index--; + if (snapshot->get_pre_edge(index, sample, 1, get_index())) + pre_index = index; + else + pre_index = 0; + } + + sample = snapshot->get_sample(index, get_index()); + index++; + if (snapshot->get_nxt_edge(index, sample, end, 1, get_index())) + nxt_index = index; + else + nxt_index = 0; + + if (pre_index == 0 || nxt_index == 0) + return false; + + if (pos - pre_index > nxt_index - pos) + index = nxt_index; + else + index = pre_index; + + if (radius > abs((index-pos) / _view->scale() / _data->samplerate())) + return true; + } + return false; +} bool LogicSignal::edges(const QPointF &p, uint64_t start, uint64_t &rising, uint64_t &falling) const { diff --git a/DSView/pv/view/logicsignal.h b/DSView/pv/view/logicsignal.h index b34f5646..09b4e98b 100644 --- a/DSView/pv/view/logicsignal.h +++ b/DSView/pv/view/logicsignal.h @@ -98,6 +98,8 @@ public: bool measure(const QPointF &p, uint64_t &index0, uint64_t &index1, uint64_t &index2) const; + bool edge(const QPointF &p, uint64_t &index, int radius) const; + bool edges(const QPointF &p, uint64_t start, uint64_t &rising, uint64_t &falling) const; bool edges(uint64_t end, uint64_t start, uint64_t &rising, uint64_t &falling) const; diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index 42bcce56..efa5703a 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -254,7 +254,8 @@ void View::set_all_update(bool need_update) void View::update_hori_res() { - _sampling_bar->hori_knob(0); + if (_session.get_device()->dev_inst()->mode == DSO) + _sampling_bar->hori_knob(0); const uint64_t final_limit = _session.get_device()->get_sample_limit(); _trig_cursor->set_index(_trig_cursor->index() * 1.0 / _session.cur_samplelimits() * final_limit); @@ -276,10 +277,16 @@ void View::zoom(double steps, int offset) _session.get_instant()) return; + double hori_res = -1; if(steps > 0.5) - _sampling_bar->hori_knob(-1); + hori_res = _sampling_bar->hori_knob(-1); else if (steps < -0.5) - _sampling_bar->hori_knob(1); + hori_res = _sampling_bar->hori_knob(1); + + if (hori_res > 0) { + const double scale = hori_res * DS_CONF_DSO_HDIVS / SR_SEC(1) / get_view_width(); + _scale = max(min(scale, _maxscale), _minscale); + } } _offset = floor((_offset + offset) * (_preScale / _scale) - offset); @@ -294,15 +301,6 @@ void View::zoom(double steps, int offset) //} } -void View::hori_res_changed(double hori_res) -{ - if (hori_res > 0) { - const double scale = hori_res * DS_CONF_DSO_HDIVS / SR_SEC(1) / get_view_width(); - set_scale_offset(scale, this->offset()); - } -} - - void View::set_scale_offset(double scale, int64_t offset) { //if (_session.get_capture_state() == SigSession::Stopped) { @@ -949,6 +947,15 @@ QString View::get_cm_delta(int index1, int index2) return _ruler->format_real_time(delta_sample, _session.cur_samplerate()); } +QString View::get_index_delta(uint64_t start, uint64_t end) +{ + if (start == end) + return "0"; + + uint64_t delta_sample = (start > end) ? start - end : end - start; + return _ruler->format_real_time(delta_sample, _session.cur_samplerate()); +} + uint64_t View::get_cursor_samples(int index) { assert(index < (int)_cursorList.size()); diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index 2bc4bb29..032f21d6 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -175,6 +175,7 @@ public: uint64_t get_cursor_samples(int index); QString get_cm_time(int index); QString get_cm_delta(int index1, int index2); + QString get_index_delta(uint64_t start, uint64_t end); void on_state_changed(bool stop); @@ -240,8 +241,6 @@ public slots: void repeat_unshow(); // -- repeat void repeat_show(); - // -- hori resolution - void hori_res_changed(double hori_res); private slots: diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index aaa2f820..00a93975 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -82,6 +82,7 @@ Viewport::Viewport(View &parent, View_type type) : _mm_freq = "#####"; _mm_duty = "#####"; _measure_en = true; + _edge_hit = false; transfer_started = false; timer_cnt = 0; @@ -641,6 +642,30 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) } // priority 2 + if (_action_type == NO_ACTION) { + if (_mouse_down_point.x() == event->pos().x()) { + const vector< boost::shared_ptr > sigs(_view.session().get_signals()); + BOOST_FOREACH(const boost::shared_ptr s, sigs) { + assert(s); + boost::shared_ptr logicSig; + if ((logicSig = dynamic_pointer_cast(s))) { + if (logicSig->edge(event->pos(), _edge_start, 10)) { + _action_type = LOGIC_JUMP; + const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale(); + _cur_preX = _edge_start / samples_per_pixel - _view.offset(); + _cur_preY = logicSig->get_y(); + _cur_preY_top = logicSig->get_y() - logicSig->get_totalHeight()/2 - 12; + _cur_preY_bottom = logicSig->get_y() + logicSig->get_totalHeight()/2 + 2; + _cur_aftX = _cur_preX; + _cur_aftY = _cur_preY; + break; + } + } + } + } + } + + // priority 3 if (_action_type == NO_ACTION) { if (_mouse_down_point.x() == event->pos().x()) { const vector< boost::shared_ptr > sigs(_view.session().get_signals()); @@ -738,6 +763,11 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) _action_type = NO_ACTION; _edge_rising = 0; _edge_falling = 0; + } else if (_action_type == LOGIC_JUMP) { + _action_type = NO_ACTION; + _edge_rising = 0; + _edge_falling = 0; + _edge_hit = false; } else if (_action_type == LOGIC_MOVE) { if (_mouse_down_point == event->pos()) { _drag_strength = 0; @@ -884,6 +914,10 @@ void Viewport::leaveEvent(QEvent *) _edge_rising = 0; _edge_falling = 0; _action_type = NO_ACTION; + } else if (_action_type == LOGIC_JUMP) { + _edge_rising = 0; + _edge_falling = 0; + _action_type = NO_ACTION; } else if (_action_type == LOGIC_MOVE) { _drag_strength = 0; _drag_timer.stop(); @@ -975,6 +1009,18 @@ void Viewport::measure() break; } + } else if (_action_type == LOGIC_JUMP) { + const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale(); + if (logicSig->edge(_view.hover_point(), _edge_end, 10)) { + _cur_aftX = _edge_end / samples_per_pixel - _view.offset(); + _cur_aftY = logicSig->get_y(); + _edge_hit = true; + break; + } + _cur_preX = _edge_start / samples_per_pixel - _view.offset(); + _cur_aftX = _view.hover_point().x(); + _cur_aftY = _view.hover_point().y(); + _edge_hit = false; } } else if (dsoSig = dynamic_pointer_cast(s)) { if (_measure_en && dsoSig->measure(_view.hover_point())) { @@ -1287,6 +1333,56 @@ void Viewport::paintMeasure(QPainter &p) p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter, _em_falling); } + + if (_action_type == LOGIC_JUMP) { + p.setPen(QColor(238, 178, 17, 255)); + const QPoint pre_points[] = { + QPoint(_cur_preX, _cur_preY), + QPoint(_cur_preX-1, _cur_preY-1), + QPoint(_cur_preX+1, _cur_preY-1), + QPoint(_cur_preX-1, _cur_preY+1), + QPoint(_cur_preX+1, _cur_preY+1), + QPoint(_cur_preX-2, _cur_preY-2), + QPoint(_cur_preX+2, _cur_preY-2), + QPoint(_cur_preX-2, _cur_preY+2), + QPoint(_cur_preX+2, _cur_preY+2), + }; + p.drawPoints(pre_points, countof(pre_points)); + if (abs(_cur_aftX - _cur_preX) + abs(_cur_aftY - _cur_preY) > 20) { + if (_edge_hit) { + const QPoint aft_points[] = { + QPoint(_cur_aftX, _cur_aftY), + QPoint(_cur_aftX-1, _cur_aftY-1), + QPoint(_cur_aftX+1, _cur_aftY-1), + QPoint(_cur_aftX-1, _cur_aftY+1), + QPoint(_cur_aftX+1, _cur_aftY+1), + QPoint(_cur_aftX-2, _cur_aftY-2), + QPoint(_cur_aftX+2, _cur_aftY-2), + QPoint(_cur_aftX-2, _cur_aftY+2), + QPoint(_cur_aftX+2, _cur_aftY+2), + }; + p.drawPoints(aft_points, countof(aft_points)); + + int64_t delta = max(_edge_start, _edge_end) - min(_edge_start, _edge_end); + QString delta_text = _view.get_index_delta(_edge_start, _edge_end) + + "/" + QString::number(delta); + QFontMetrics fm = this->fontMetrics(); + const int rectW = fm.width(delta_text); + const int rectY = (_cur_aftY >= _cur_preY) ? _cur_preY_top : _cur_preY_bottom; + const int rectX = (_cur_aftX >= _cur_preX) ? _cur_preX : _cur_preX - rectW; + QRectF jump_rect = QRectF(rectX, rectY, rectW, 10); + p.drawText(jump_rect, Qt::AlignCenter | Qt::AlignVCenter, delta_text); + + } + + QPainterPath path(QPoint(_cur_preX, _cur_preY)); + QPoint c1((_cur_preX+_cur_aftX)/2, _cur_preY); + QPoint c2((_cur_preX+_cur_aftX)/2, _cur_aftY); + path.cubicTo(c1, c2, QPoint(_cur_aftX, _cur_aftY)); + p.drawPath(path); + + } + } } QString Viewport::get_measure(QString option) diff --git a/DSView/pv/view/viewport.h b/DSView/pv/view/viewport.h index 594c4d81..5cdce1e1 100644 --- a/DSView/pv/view/viewport.h +++ b/DSView/pv/view/viewport.h @@ -68,6 +68,7 @@ public: LOGIC_EDGE, LOGIC_MOVE, LOGIC_ZOOM, + LOGIC_JUMP, DSO_XM_STEP0, DSO_XM_STEP1, @@ -158,6 +159,11 @@ private: int64_t _cur_aftX; int64_t _cur_thdX; int _cur_midY; + int _cur_preY; + int _cur_preY_top; + int _cur_preY_bottom; + int _cur_aftY; + bool _edge_hit; QString _mm_width; QString _mm_period; QString _mm_freq; @@ -166,6 +172,7 @@ private: uint64_t _edge_rising; uint64_t _edge_falling; uint64_t _edge_start; + uint64_t _edge_end; QString _em_rising; QString _em_falling; QString _em_edges;