From a5ead17590476fb284d17f3c646dd3bbbcbaa1bd Mon Sep 17 00:00:00 2001 From: DreamSourceLab Date: Sun, 27 Mar 2016 12:03:20 +0800 Subject: [PATCH] Add region decode feature --- DSView/pv/data/decode/decoder.cpp | 21 + DSView/pv/data/decode/decoder.h | 7 + DSView/pv/data/decoderstack.cpp | 92 +++- DSView/pv/data/decoderstack.h | 5 +- DSView/pv/dock/measuredock.cpp | 4 +- DSView/pv/dock/measuredock.h | 2 +- DSView/pv/sigsession.cpp | 10 + DSView/pv/view/analogsignal.cpp | 6 +- DSView/pv/view/decodetrace.cpp | 209 ++++++-- DSView/pv/view/decodetrace.h | 14 + DSView/pv/view/groupsignal.cpp | 6 +- DSView/pv/view/logicsignal.cpp | 8 +- DSView/pv/view/trace.cpp | 19 +- DSView/pv/view/trace.h | 7 +- DSView/pv/view/view.cpp | 2 +- DSView/pv/view/viewport.cpp | 845 +++++++++++++++++------------- DSView/pv/view/viewport.h | 38 +- 17 files changed, 818 insertions(+), 477 deletions(-) diff --git a/DSView/pv/data/decode/decoder.cpp b/DSView/pv/data/decode/decoder.cpp index 00d6a1f5..5c27c085 100644 --- a/DSView/pv/data/decode/decoder.cpp +++ b/DSView/pv/data/decode/decoder.cpp @@ -93,11 +93,32 @@ void Decoder::set_option(const char *id, GVariant *value) _setted = true; } +void Decoder::set_decode_region(uint64_t start, uint64_t end) +{ + _decode_start_back = start; + _decode_end_back = end; + if (_decode_start != start || + _decode_end != end) + _setted = true; +} + +uint64_t Decoder::decode_start() const +{ + return _decode_start; +} + +uint64_t Decoder::decode_end() const +{ + return _decode_end; +} + bool Decoder::commit() { if (_setted) { _probes = _probes_back; _options = _options_back; + _decode_start = _decode_start_back; + _decode_end = _decode_end_back; _setted = false; return true; } else { diff --git a/DSView/pv/data/decode/decoder.h b/DSView/pv/data/decode/decoder.h index ae51c1d3..607bc0b8 100644 --- a/DSView/pv/data/decode/decoder.h +++ b/DSView/pv/data/decode/decoder.h @@ -73,6 +73,10 @@ public: std::set< boost::shared_ptr > get_data(); + void set_decode_region(uint64_t start, uint64_t end); + uint64_t decode_start() const; + uint64_t decode_end() const; + bool commit(); private: @@ -88,6 +92,9 @@ private: _probes_back; std::map _options_back; + uint64_t _decode_start, _decode_end; + uint64_t _decode_start_back, _decode_end_back; + bool _setted; }; diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index 056bdfe7..ed720090 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -333,43 +333,83 @@ boost::optional DecoderStack::wait_for_data() const _sample_count); } +//void DecoderStack::decode_data( +// const uint64_t sample_count, const unsigned int unit_size, +// srd_session *const session) +//{ +// //uint8_t chunk[DecodeChunkLength]; +// uint8_t *chunk = NULL; +// //chunk = (uint8_t *)realloc(chunk, DecodeChunkLength); + +// const uint64_t chunk_sample_count = +// DecodeChunkLength / _snapshot->unit_size(); + +// for (uint64_t i = 0; +// !boost::this_thread::interruption_requested() && +// i < sample_count; +// i += chunk_sample_count) +// { +// //lock_guard decode_lock(_global_decode_mutex); + +// const uint64_t chunk_end = min( +// i + chunk_sample_count, sample_count); +// chunk = _snapshot->get_samples(i, chunk_end); + +// if (srd_session_send(session, i, i + sample_count, chunk, +// (chunk_end - i) * unit_size, unit_size) != SRD_OK) { +// _error_message = tr("Decoder reported an error"); +// break; +// } + +// { +// lock_guard lock(_output_mutex); +// _samples_decoded = chunk_end; +// } + +// if (i % DecodeNotifyPeriod == 0) +// new_decode_data(); + +// } +// _options_changed = false; +// decode_done(); +// //new_decode_data(); +//} + void DecoderStack::decode_data( - const uint64_t sample_count, const unsigned int unit_size, - srd_session *const session) + const uint64_t decode_start, const uint64_t decode_end, + const unsigned int unit_size, srd_session *const session) { - //uint8_t chunk[DecodeChunkLength]; uint8_t *chunk = NULL; - //chunk = (uint8_t *)realloc(chunk, DecodeChunkLength); const uint64_t chunk_sample_count = - DecodeChunkLength / _snapshot->unit_size(); + DecodeChunkLength / _snapshot->unit_size(); - for (uint64_t i = 0; - !boost::this_thread::interruption_requested() && - i < sample_count; - i += chunk_sample_count) - { + for (uint64_t i = decode_start; + !boost::this_thread::interruption_requested() && + i < decode_end; + i += chunk_sample_count) + { //lock_guard decode_lock(_global_decode_mutex); const uint64_t chunk_end = min( - i + chunk_sample_count, sample_count); + i + chunk_sample_count, decode_end); chunk = _snapshot->get_samples(i, chunk_end); - if (srd_session_send(session, i, i + sample_count, chunk, + if (srd_session_send(session, i, chunk_end, chunk, (chunk_end - i) * unit_size, unit_size) != SRD_OK) { - _error_message = tr("Decoder reported an error"); - break; - } + _error_message = tr("Decoder reported an error"); + break; + } - { - lock_guard lock(_output_mutex); - _samples_decoded = chunk_end; - } + { + lock_guard lock(_output_mutex); + _samples_decoded = chunk_end - decode_start + 1; + } if (i % DecodeNotifyPeriod == 0) new_decode_data(); - } + } _options_changed = false; decode_done(); //new_decode_data(); @@ -382,6 +422,8 @@ void DecoderStack::decode_proc() optional sample_count; srd_session *session; srd_decoder_inst *prev_di = NULL; + uint64_t decode_start; + uint64_t decode_end; assert(_snapshot); @@ -409,6 +451,8 @@ void DecoderStack::decode_proc() srd_inst_stack (session, prev_di, di); prev_di = di; + decode_start = dec->decode_start(); + decode_end = min(dec->decode_end(), _snapshot->get_sample_count()); } // Get the intial sample count @@ -429,7 +473,8 @@ void DecoderStack::decode_proc() // do { // decode_data(*sample_count, unit_size, session); // } while(_error_message.isEmpty() && (sample_count = wait_for_data())); - decode_data(*sample_count, unit_size, session); + //decode_data(*sample_count, unit_size, session); + decode_data(decode_start, decode_end, unit_size, session); // Destroy the session srd_session_destroy(session); @@ -439,7 +484,10 @@ void DecoderStack::decode_proc() uint64_t DecoderStack::sample_count() const { - return _sample_count; + if (_snapshot) + return _snapshot->get_sample_count(); + else + return 0; } void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder) diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h index b2cd65f8..0e71dd52 100644 --- a/DSView/pv/data/decoderstack.h +++ b/DSView/pv/data/decoderstack.h @@ -125,7 +125,10 @@ public: private: boost::optional wait_for_data() const; - void decode_data(const uint64_t sample_count, +// void decode_data(const uint64_t sample_count, +// const unsigned int unit_size, srd_session *const session); + + void decode_data(const uint64_t decode_start, const uint64_t decode_end, const unsigned int unit_size, srd_session *const session); void decode_proc(); diff --git a/DSView/pv/dock/measuredock.cpp b/DSView/pv/dock/measuredock.cpp index 03cd4e1f..6a329021 100644 --- a/DSView/pv/dock/measuredock.cpp +++ b/DSView/pv/dock/measuredock.cpp @@ -134,7 +134,7 @@ MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) : connect(_t3_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update())); connect(_fen_checkBox, SIGNAL(stateChanged(int)), &_view, SLOT(set_measure_en(int))); - connect(_view.get_viewport(), SIGNAL(mouse_measure()), this, SLOT(mouse_measure())); + connect(_view.get_viewport(), SIGNAL(measure_updated()), this, SLOT(measure_updated())); this->setWidget(_widget); _widget->setGeometry(0, 0, sizeHint().width(), 2000); @@ -220,7 +220,7 @@ void MeasureDock::cursor_update() update(); } -void MeasureDock::mouse_measure() +void MeasureDock::measure_updated() { _width_label->setText(_view.get_viewport()->get_measure("width")); _period_label->setText(_view.get_viewport()->get_measure("period")); diff --git a/DSView/pv/dock/measuredock.h b/DSView/pv/dock/measuredock.h index 6b13ec7d..8cf455fa 100644 --- a/DSView/pv/dock/measuredock.h +++ b/DSView/pv/dock/measuredock.h @@ -74,7 +74,7 @@ private slots: public slots: void cursor_update(); void cursor_moved(); - void mouse_measure(); + void measure_updated(); private: SigSession &_session; diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index b4dfa217..19bf99f5 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -1104,6 +1104,9 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi, _cur_logic_snapshot.reset(); _cur_dso_snapshot.reset(); _cur_analog_snapshot.reset(); + + BOOST_FOREACH(const boost::shared_ptr d, _decode_traces) + d->frame_ended(); } frame_ended(); @@ -1287,6 +1290,13 @@ bool SigSession::add_decoder(srd_decoder *const dec) boost::shared_ptr d( new view::DecodeTrace(*this, decoder_stack, _decode_traces.size())); + // set view early for decode start/end region setting + BOOST_FOREACH(const boost::shared_ptr s, _signals) { + if (s->get_view()) { + d->set_view(s->get_view()); + break; + } + } if (d->create_popup()) { _decode_traces.push_back(d); ret = true; diff --git a/DSView/pv/view/analogsignal.cpp b/DSView/pv/view/analogsignal.cpp index dbef9c00..595dff32 100644 --- a/DSView/pv/view/analogsignal.cpp +++ b/DSView/pv/view/analogsignal.cpp @@ -58,7 +58,7 @@ AnalogSignal::AnalogSignal(boost::shared_ptr dev_inst, _data(data) { _colour = SignalColours[probe->index % countof(SignalColours)]; - _scale = _signalHeight * 1.0f / 65536; + _scale = _totalHeight * 1.0f / 65536; } AnalogSignal::~AnalogSignal() @@ -81,7 +81,7 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right) assert(_view); assert(right >= left); - const int y = get_y() + _signalHeight * 0.5; + const int y = get_y() + _totalHeight * 0.5; const double scale = _view->scale(); assert(scale > 0); const double offset = _view->offset(); @@ -91,7 +91,7 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right) if (snapshots.empty()) return; - _scale = _signalHeight * 1.0f / 65536; + _scale = _totalHeight * 1.0f / 65536; const boost::shared_ptr &snapshot = snapshots.front(); diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index d08627ea..a8c84244 100644 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -50,14 +50,10 @@ extern "C" { #include "../widgets/decodergroupbox.h" #include "../widgets/decodermenu.h" #include "../device/devinst.h" +#include "../view/cursor.h" -using boost::dynamic_pointer_cast; -using boost::shared_ptr; -using std::list; -using std::max; -using std::map; -using std::min; -using std::vector; +using namespace boost; +using namespace std; namespace pv { namespace view { @@ -114,12 +110,21 @@ const QColor DecodeTrace::OutlineColours[16] = { QColor(0x6B, 0x23, 0x37) }; +const QString DecodeTrace::RegionStart = "Start"; +const QString DecodeTrace::RegionEnd = "End "; + DecodeTrace::DecodeTrace(pv::SigSession &session, boost::shared_ptr decoder_stack, int index) : Trace(QString::fromUtf8( decoder_stack->stack().front()->decoder()->name), index, SR_CHANNEL_DECODER), _session(session), _decoder_stack(decoder_stack), + _decode_start(0), + _decode_end(INT64_MAX), + _start_index(0), + _end_index(0), + _start_count(0), + _end_count(0), _show_hide_mapper(this), _popup_form(NULL), _popup() @@ -169,8 +174,31 @@ void DecodeTrace::paint_back(QPainter &p, int left, int right) QPen pen(Signal::dsGray); pen.setStyle(Qt::DotLine); p.setPen(pen); - const double sigY = get_y() - (_signalHeight - _view->get_signalHeight())*0.5; + const double sigY = get_y() - (_totalHeight - _view->get_signalHeight())*0.5; p.drawLine(left, sigY, right, sigY); + + // --draw decode region control + const double samples_per_pixel = _session.get_device()->get_sample_rate() * _view->scale(); + const double startX = _decode_start/samples_per_pixel - (_view->offset() / _view->scale()); + const double endX = _decode_end/samples_per_pixel - (_view->offset() / _view->scale()); + const double regionY = get_y() - _totalHeight*0.5 - ControlRectWidth; + + p.setBrush(Signal::dsBlue); + p.drawLine(startX, regionY, startX, regionY + _totalHeight + ControlRectWidth); + p.drawLine(endX, regionY, endX, regionY + _totalHeight + ControlRectWidth); + const QPointF start_points[] = { + QPointF(startX-ControlRectWidth, regionY), + QPointF(startX+ControlRectWidth, regionY), + QPointF(startX, regionY+ControlRectWidth) + }; + const QPointF end_points[] = { + QPointF(endX-ControlRectWidth, regionY), + QPointF(endX+ControlRectWidth, regionY), + QPointF(endX, regionY+ControlRectWidth) + }; + p.drawPolygon(start_points, countof(start_points)); + p.drawPolygon(end_points, countof(end_points)); + } void DecodeTrace::paint_mid(QPainter &p, int left, int right) @@ -203,22 +231,24 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) const QString err = _decoder_stack->error_message(); if (!err.isEmpty()) { - //draw_unresolved_period(p, _view->get_signalHeight(), left, right, + //draw_unresolved_period(p, annotation_height, left, right, // samples_per_pixel, pixels_offset); draw_error(p, err, left, right); return; } // Draw the hatching - if (draw_unresolved_period(p, _view->get_signalHeight(), left, right)) + if (draw_unresolved_period(p, annotation_height, left, right)) return; // Iterate through the rows assert(_view); - int y = get_y() - (_signalHeight - _view->get_signalHeight())*0.5; + int y = get_y() - (_totalHeight - annotation_height)*0.5; assert(_decoder_stack); + const double decode_startX = _decode_start/samples_per_pixel - (_view->offset() / _view->scale()); + const double decode_endX = _decode_end/samples_per_pixel - (_view->offset() / _view->scale()); const std::vector< std::pair > rows(_decoder_stack->get_visible_rows()); for (size_t i = 0; i < rows.size(); i++) { @@ -226,8 +256,8 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) const bool shown = rows[i].second; if (!shown && _decoder_stack->has_annotations(row)) { - draw_unshown_row(p, y, _view->get_signalHeight(), left, right); - y += _view->get_signalHeight(); + draw_unshown_row(p, y, annotation_height, decode_startX, decode_endX); + y += annotation_height; _cur_row_headings.push_back(row.title()); continue; } @@ -253,10 +283,10 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) base_colour); } } else if (max_annWidth != 0){ - draw_nodetail(p, annotation_height, left, right, y, base_colour); + draw_nodetail(p, annotation_height, decode_startX, decode_endX, y, base_colour); } if (max_annWidth != 0) { - y += _view->get_signalHeight(); + y += annotation_height; _cur_row_headings.push_back(row.title()); } } @@ -272,7 +302,7 @@ void DecodeTrace::paint_fore(QPainter &p, int left, int right) for (size_t i = 0; i < _cur_row_headings.size(); i++) { - const int y = (i + 0.5) * row_height + get_y() - _signalHeight * 0.5; + const int y = (i + 0.5) * row_height + get_y() - _totalHeight * 0.5; p.setPen(QPen(Qt::NoPen)); p.setBrush(QApplication::palette().brush(QPalette::WindowText)); @@ -317,11 +347,13 @@ bool DecodeTrace::create_popup() if (QDialog::Accepted == _popup->exec()) { - BOOST_FOREACH(shared_ptr dec, + BOOST_FOREACH(boost::shared_ptr dec, _decoder_stack->stack()) { if (dec->commit()) { _decoder_stack->options_changed(true); + _decode_start = dec->decode_start(); + _decode_end = dec->decode_end(); ret = true; } } @@ -361,7 +393,7 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) _probe_selectors.clear(); _decoder_forms.clear(); - const list< shared_ptr >& stack = _decoder_stack->stack(); + const list< boost::shared_ptr >& stack = _decoder_stack->stack(); if (stack.empty()) { @@ -372,10 +404,10 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) } else { - list< shared_ptr >::const_iterator iter = + list< boost::shared_ptr >::const_iterator iter = stack.begin(); for (int i = 0; i < (int)stack.size(); i++, iter++) { - shared_ptr dec(*iter); + boost::shared_ptr dec(*iter); create_decoder_form(i, dec, parent, form); } @@ -383,6 +415,40 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) tr("* Required channels"), parent)); } + // Add region combobox + _start_comboBox = new QComboBox(parent); + _end_comboBox = new QComboBox(parent); + _start_comboBox->addItem(RegionStart); + _end_comboBox->addItem(RegionEnd); + if (_view) { + int index = 1; + for(std::list::iterator i = _view->get_cursorList().begin(); + i != _view->get_cursorList().end(); i++) { + QString curCursor = tr("Cursor ")+QString::number(index); + _start_comboBox->addItem(curCursor); + _end_comboBox->addItem(curCursor); + index++; + } + } + if (_start_count > _start_comboBox->count()) + _start_index = 0; + if (_end_count > _end_comboBox->count()) + _end_index = 0; + _start_count = _start_comboBox->count(); + _end_count = _end_comboBox->count(); + + _start_comboBox->setCurrentIndex(_start_index); + _end_comboBox->setCurrentIndex(_end_index); + connect(_start_comboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_region_set(int))); + connect(_end_comboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_region_set(int))); + on_region_set(_start_index); + form->addRow(_start_comboBox, new QLabel( + tr("Decode Start From"))); + form->addRow(_end_comboBox, new QLabel( + tr("Decode End to"))); + // Add stacking button pv::widgets::DecoderMenu *const decoder_menu = new pv::widgets::DecoderMenu(parent); @@ -564,16 +630,16 @@ bool DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left, assert(_decoder_stack); - shared_ptr data; - shared_ptr logic_signal; + boost::shared_ptr data; + boost::shared_ptr logic_signal; - //const int64_t sample_count = _session.get_device()->get_sample_limit(); - const int64_t sample_count = _decoder_stack->sample_count(); - if (sample_count == 0) + //const int64_t need_sample_count = _decoder_stack->sample_count(); + const uint64_t need_sample_count = _decode_end - _decode_start + 1; + if (need_sample_count == 0) return true; - const int64_t samples_decoded = _decoder_stack->samples_decoded(); - if (sample_count == samples_decoded) + const uint64_t samples_decoded = _decoder_stack->samples_decoded(); + if (need_sample_count == samples_decoded) return false; const int y = get_y(); @@ -591,7 +657,7 @@ bool DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left, p.setBrush(QBrush(NoDecodeColour, Qt::Dense7Pattern)); p.drawRect(no_decode_rect); - const int progress100 = ceil(samples_decoded * 100.0 / sample_count); + const int progress100 = ceil(samples_decoded * 100.0 / need_sample_count); p.setPen(dsLightBlue); QFont font=p.font(); font.setPointSize(_view->get_signalHeight()*2/3); @@ -620,7 +686,7 @@ void DecodeTrace::draw_unshown_row(QPainter &p, int y, int h, int left, } void DecodeTrace::create_decoder_form(int index, - shared_ptr &dec, QWidget *parent, + boost::shared_ptr &dec, QWidget *parent, QFormLayout *form) { const GSList *l; @@ -672,7 +738,7 @@ void DecodeTrace::create_decoder_form(int index, } // Add the options - shared_ptr binding( + boost::shared_ptr binding( new prop::binding::DecoderOptions(_decoder_stack, dec)); binding->add_properties_to_form(decoder_form, true); @@ -683,16 +749,16 @@ void DecodeTrace::create_decoder_form(int index, } QComboBox* DecodeTrace::create_probe_selector( - QWidget *parent, const shared_ptr &dec, + QWidget *parent, const boost::shared_ptr &dec, const srd_channel *const pdch) { assert(dec); - const vector< shared_ptr > sigs(_session.get_signals()); + const vector< boost::shared_ptr > sigs(_session.get_signals()); assert(_decoder_stack); const map >::const_iterator probe_iter = + boost::shared_ptr >::const_iterator probe_iter = dec->channels().find(pdch); QComboBox *selector = new QComboBox(parent); @@ -703,7 +769,7 @@ QComboBox* DecodeTrace::create_probe_selector( selector->setCurrentIndex(0); for(size_t i = 0; i < sigs.size(); i++) { - const shared_ptr s(sigs[i]); + const boost::shared_ptr s(sigs[i]); assert(s); if (dynamic_pointer_cast(s) && s->enabled()) @@ -720,12 +786,12 @@ QComboBox* DecodeTrace::create_probe_selector( return selector; } -void DecodeTrace::commit_decoder_probes(shared_ptr &dec) +void DecodeTrace::commit_decoder_probes(boost::shared_ptr &dec) { assert(dec); - map > probe_map; - const vector< shared_ptr > sigs(_session.get_signals()); + map > probe_map; + const vector< boost::shared_ptr > sigs(_session.get_signals()); _index_list.clear(); BOOST_FOREACH(const ProbeSelector &s, _probe_selectors) @@ -737,7 +803,7 @@ void DecodeTrace::commit_decoder_probes(shared_ptr &dec) (LogicSignal*)s._combo->itemData( s._combo->currentIndex()).value(); - BOOST_FOREACH(shared_ptr sig, sigs) + BOOST_FOREACH(boost::shared_ptr sig, sigs) if(sig.get() == selection) { probe_map[s._pdch] = dynamic_pointer_cast(sig); @@ -752,7 +818,7 @@ void DecodeTrace::commit_decoder_probes(shared_ptr &dec) void DecodeTrace::commit_probes() { assert(_decoder_stack); - BOOST_FOREACH(shared_ptr dec, + BOOST_FOREACH(boost::shared_ptr dec, _decoder_stack->stack()) commit_decoder_probes(dec); @@ -787,7 +853,7 @@ void DecodeTrace::on_stack_decoder(srd_decoder *decoder) { assert(decoder); assert(_decoder_stack); - _decoder_stack->push(shared_ptr( + _decoder_stack->push(boost::shared_ptr( new data::decode::Decoder(decoder))); //_decoder_stack->begin_decode(); @@ -798,14 +864,14 @@ void DecodeTrace::on_show_hide_decoder(int index) { using pv::data::decode::Decoder; - const list< shared_ptr > stack(_decoder_stack->stack()); + const list< boost::shared_ptr > stack(_decoder_stack->stack()); // Find the decoder in the stack - list< shared_ptr >::const_iterator iter = stack.begin(); + list< boost::shared_ptr >::const_iterator iter = stack.begin(); for(int i = 0; i < index; i++, iter++) assert(iter != stack.end()); - shared_ptr dec = *iter; + boost::shared_ptr dec = *iter; assert(dec); const bool show = !dec->shown(); @@ -863,5 +929,62 @@ QRectF DecodeTrace::get_rect(DecodeSetRegions type, int y, int right) return QRectF(0, 0, 0, 0); } +void DecodeTrace::on_region_set(int index) +{ + (void)index; + const uint64_t last_samples = _session.get_device()->get_sample_limit() - 1; + const int index1 = _start_comboBox->currentIndex(); + const int index2 = _end_comboBox->currentIndex(); + uint64_t decode_start, decode_end; + + if (index1 == 0) { + decode_start = 0; + } else { + decode_start = _view->get_cursor_samples(index1-1); + } + if (index2 == 0) { + decode_end = last_samples; + } else { + decode_end = _view->get_cursor_samples(index2-1); + } + + if (decode_start > last_samples) + decode_start = 0; + if (decode_end > last_samples) + decode_end = last_samples; + + if (decode_start > decode_end) { + uint64_t tmp = decode_start; + decode_start = decode_end; + decode_end = tmp; + } + _start_index = index1; + _end_index = index2; + + BOOST_FOREACH(boost::shared_ptr dec, + _decoder_stack->stack()) { + dec->set_decode_region(decode_start, decode_end); + } +} + +void DecodeTrace::frame_ended() +{ + const uint64_t last_samples = _session.get_device()->get_sample_limit() - 1; + if (_decode_start > last_samples) { + _decode_start = 0; + _start_index = 0; + } + if (_end_index ==0 || + _decode_end > last_samples) { + _decode_end = last_samples; + _end_index = 0; + } + BOOST_FOREACH(boost::shared_ptr dec, + _decoder_stack->stack()) { + dec->set_decode_region(_decode_start, _decode_end); + dec->commit(); + } +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h index 03cd6910..32f17bd9 100644 --- a/DSView/pv/view/decodetrace.h +++ b/DSView/pv/view/decodetrace.h @@ -89,6 +89,10 @@ private: static const QColor OutlineColours[16]; static const int DefaultFontSize = 8; + static const int ControlRectWidth = 5; + + static const QString RegionStart; + static const QString RegionEnd; public: DecodeTrace(pv::SigSession &session, @@ -132,6 +136,11 @@ public: QRectF get_rect(DecodeSetRegions type, int y, int right); + /** + * decode region + **/ + void frame_ended(); + protected: void paint_type_options(QPainter &p, int right, const QPoint pt); @@ -191,11 +200,16 @@ private slots: void on_decode_done(); + void on_region_set(int index); + private: pv::SigSession &_session; boost::shared_ptr _decoder_stack; uint64_t _decode_start, _decode_end; + int _start_index, _end_index; + int _start_count, _end_count; + QComboBox *_start_comboBox, *_end_comboBox; std::list< boost::shared_ptr > _bindings; diff --git a/DSView/pv/view/groupsignal.cpp b/DSView/pv/view/groupsignal.cpp index d5402acb..0c674dfd 100644 --- a/DSView/pv/view/groupsignal.cpp +++ b/DSView/pv/view/groupsignal.cpp @@ -51,7 +51,7 @@ GroupSignal::GroupSignal(QString name, boost::shared_ptr data, _data(data) { _colour = SignalColours[probe_index_list.front() % countof(SignalColours)]; - _scale = _signalHeight * 1.0f / std::pow(2.0, static_cast(probe_index_list.size())); + _scale = _totalHeight * 1.0f / std::pow(2.0, static_cast(probe_index_list.size())); } GroupSignal::~GroupSignal() @@ -79,12 +79,12 @@ void GroupSignal::paint_mid(QPainter &p, int left, int right) assert(_view); assert(right >= left); - const int y = get_y() + _signalHeight * 0.5; + const int y = get_y() + _totalHeight * 0.5; const double scale = _view->scale(); assert(scale > 0); const double offset = _view->offset(); - _scale = _signalHeight * 1.0f / std::pow(2.0, static_cast(_index_list.size())); + _scale = _totalHeight * 1.0f / std::pow(2.0, static_cast(_index_list.size())); const deque< boost::shared_ptr > &snapshots = _data->get_snapshots(); diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index 3ae1c9dd..4bbe9ad0 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -148,12 +148,12 @@ void LogicSignal::paint_mid(QPainter &p, int left, int right) assert(_view); assert(right >= left); - const int y = get_y() + _signalHeight * 0.5; + const int y = get_y() + _totalHeight * 0.5; const double scale = _view->scale(); assert(scale > 0); const double offset = _view->offset(); - const float high_offset = y - _signalHeight + 0.5f; + const float high_offset = y - _totalHeight + 0.5f; const float low_offset = y + 0.5f; const deque< boost::shared_ptr > &snapshots = @@ -314,7 +314,7 @@ void LogicSignal::paint_type_options(QPainter &p, int right, const QPoint pt) bool LogicSignal::measure(const QPointF &p, uint64_t &index0, uint64_t &index1, uint64_t &index2) const { const float gap = abs(p.y() - get_y()); - if (gap < get_signalHeight() * 0.5) { + if (gap < get_totalHeight() * 0.5) { const deque< boost::shared_ptr > &snapshots = _data->get_snapshots(); if (snapshots.empty()) @@ -359,7 +359,7 @@ bool LogicSignal::edges(const QPointF &p, uint64_t start, uint64_t &rising, uint { uint64_t index, end; const float gap = abs(p.y() - get_y()); - if (gap < get_signalHeight() * 0.5) { + if (gap < get_totalHeight() * 0.5) { const deque< boost::shared_ptr > &snapshots = _data->get_snapshots(); if (snapshots.empty()) diff --git a/DSView/pv/view/trace.cpp b/DSView/pv/view/trace.cpp index 92b4f210..52d522d5 100644 --- a/DSView/pv/view/trace.cpp +++ b/DSView/pv/view/trace.cpp @@ -59,7 +59,7 @@ Trace::Trace(QString name, uint16_t index, int type) : _v_offset(INT_MAX), _type(type), _sec_index(0), - _signalHeight(30) + _totalHeight(30) { _index_list.push_back(index); } @@ -71,7 +71,7 @@ Trace::Trace(QString name, std::list index_list, int type, int sec_index) : _type(type), _index_list(index_list), _sec_index(sec_index), - _signalHeight(30) + _totalHeight(30) { } @@ -84,7 +84,7 @@ Trace::Trace(const Trace &t) : _index_list(t._index_list), _sec_index(t._sec_index), _old_v_offset(t._old_v_offset), - _signalHeight(t._signalHeight), + _totalHeight(t._totalHeight), _text_size(t._text_size) { } @@ -167,14 +167,14 @@ int Trace::get_zeroPos() return _v_offset - _view->v_offset(); } -int Trace::get_signalHeight() const +int Trace::get_totalHeight() const { - return _signalHeight; + return _totalHeight; } -void Trace::set_signalHeight(int height) +void Trace::set_totalHeight(int height) { - _signalHeight = height; + _totalHeight = height; } void Trace::set_view(pv::view::View *view) @@ -183,6 +183,11 @@ void Trace::set_view(pv::view::View *view) _view = view; } +pv::view::View* Trace::get_view() const +{ + return _view; +} + void Trace::paint_back(QPainter &p, int left, int right) { QPen pen(Signal::dsGray); diff --git a/DSView/pv/view/trace.h b/DSView/pv/view/trace.h index ef3d31f3..329400bd 100644 --- a/DSView/pv/view/trace.h +++ b/DSView/pv/view/trace.h @@ -127,12 +127,12 @@ public: /** * Gets the height of this signal. */ - int get_signalHeight() const; + int get_totalHeight() const; /** * Sets the height of this signal. */ - void set_signalHeight(int height); + void set_totalHeight(int height); /** * Geom @@ -159,6 +159,7 @@ public: virtual bool enabled() const = 0; virtual void set_view(pv::view::View *view); + pv::view::View* get_view() const; /** * Paints the background layer of the trace with a QPainter @@ -291,7 +292,7 @@ protected: std::list _index_list; int _sec_index; int _old_v_offset; - int _signalHeight; + int _totalHeight; QSizeF _text_size; }; diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index 3965524b..eee4c438 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -501,7 +501,7 @@ void View::signals_changed() BOOST_FOREACH(boost::shared_ptr t, traces) { t->set_view(this); const double traceHeight = _signalHeight*t->rows_size(); - t->set_signalHeight((int)traceHeight); + t->set_totalHeight((int)traceHeight); t->set_v_offset(next_v_offset + 0.5 * traceHeight + SignalMargin); next_v_offset += traceHeight + 2 * SignalMargin; } diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index dfa94970..2f70b23e 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -33,6 +33,7 @@ #include "../data/logicsnapshot.h" #include "../sigsession.h" #include "../dialogs/dsomeasure.h" +#include "decodetrace.h" #include #include @@ -55,8 +56,7 @@ Viewport::Viewport(View &parent) : QWidget(&parent), _view(parent), _total_receive_len(0), - _zoom_rect_visible(false), - _measure_shown(false), + _action_type(NO_ACTION), _measure_type(NO_MEASURE), _cur_sample(0), _nxt_sample(1), @@ -65,10 +65,8 @@ Viewport::Viewport(View &parent) : _cur_midY(0), _hover_index(0), _hover_hit(false), - _dso_xm(false), - _dso_xm_stage(0), - _dso_ym(false), - _dso_ym_done(false) + _dso_xm_valid(false), + _dso_ym_valid(false) { setMouseTracking(true); setAutoFillBackground(true); @@ -105,7 +103,7 @@ int Viewport::get_total_height() const const vector< boost::shared_ptr > traces(_view.get_traces()); BOOST_FOREACH(const boost::shared_ptr t, traces) { assert(t); - h += (int)(t->get_signalHeight()); + h += (int)(t->get_totalHeight()); } h += 2 * View::SignalMargin; @@ -220,16 +218,14 @@ void Viewport::paintSignals(QPainter &p) } // plot zoom rect - if (_zoom_rect_visible) { + if (_action_type == LOGIC_ZOOM) { p.setPen(Qt::NoPen); p.setBrush(Trace::dsLightBlue); - p.drawRect(_zoom_rect); + p.drawRect(QRectF(_mouse_down_point, _mouse_point)); } //plot measure arrow - if (_measure_shown) { - paintMeasure(p); - } + paintMeasure(p); } void Viewport::paintProgress(QPainter &p) @@ -369,30 +365,10 @@ void Viewport::mousePressEvent(QMouseEvent *event) _mouse_down_point = event->pos(); _mouse_down_offset = _view.offset(); - _measure_shown = _dso_xm || _dso_ym; - //_dso_xm = false; _drag_strength = 0; _time.start(); - if (event->buttons() & Qt::LeftButton) { - if (_view.cursors_shown()) { - list::iterator i = _view.get_cursorList().begin(); - double cursorX; - const double samples_per_pixel = _view.session().get_device()->get_sample_rate() * _view.scale(); - while (i != _view.get_cursorList().end()) { - cursorX = (*i)->index()/samples_per_pixel - (_view.offset() / _view.scale()); - if ((*i)->grabbed()) { - _view.get_ruler()->rel_grabbed_cursor(); - } else if (qAbs(cursorX - event->pos().x()) <= HitCursorMargin) { - _view.get_ruler()->set_grabbed_cursor(*i); - _measure_type = LOGIC_CURS; - break; - } - i++; - } - - } - + if (event->button() == Qt::LeftButton) { const vector< boost::shared_ptr > sigs(_view.session().get_signals()); BOOST_FOREACH(const boost::shared_ptr s, sigs) { assert(s); @@ -400,10 +376,7 @@ void Viewport::mousePressEvent(QMouseEvent *event) continue; boost::shared_ptr dsoSig; if (dsoSig = dynamic_pointer_cast(s)) { - if (dsoSig->get_trig_rect(0, _view.get_view_width()).contains(_mouse_point)) { - _drag_sig = s; - break; - } else if (dsoSig->get_ms_show_hover()) { + if (dsoSig->get_ms_show_hover()) { dsoSig->set_ms_show(!dsoSig->get_ms_show()); break; } else if (dsoSig->get_ms_gear_hover()) { @@ -414,51 +387,20 @@ void Viewport::mousePressEvent(QMouseEvent *event) } } - if (_measure_type == LOGIC_FREQ) - _measure_type = NO_MEASURE; - update(); } - if (_hover_hit && (event->buttons() & Qt::RightButton)) { - _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], _hover_index); - _view.show_cursors(true); - _hover_hit = false; - } else if (_hover_hit && (event->buttons() & Qt::LeftButton)) { - _dso_ym = true; - _dso_ym_done = false; - _dso_ym_sig_index = _hover_sig_index; - _dso_ym_sig_value = _hover_sig_value; - _dso_ym_index = _hover_index; - _dso_ym_start = event->pos().y(); - } else if (_dso_ym && !_dso_ym_done && (event->buttons() & Qt::LeftButton)) { - _dso_ym_end = event->pos().y(); - _dso_ym_done = true; - } else if (_dso_ym && !_dso_ym_done && (event->buttons() & Qt::RightButton)) { - _dso_ym = false; - _dso_ym_done = false; - } else if (_dso_xm && _dso_xm_stage < DsoMeasureStages && (event->buttons() & Qt::RightButton)) { - _dso_xm = false; - _measure_shown = _dso_ym; - _dso_xm_stage = 0; - _measure_type = NO_MEASURE; - _mm_width = "#####"; - _mm_period = "#####"; - _mm_freq = "#####"; - _mm_duty = "#####"; - mouse_measure(); - } else if (event->buttons() & Qt::LeftButton) { - if (_dso_xm_stage > 0 && _dso_xm_stage < DsoMeasureStages) { - const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); - const double scale = _view.scale(); - const double samples_per_pixel = sample_rate * scale; - _dso_xm_index[_dso_xm_stage] = event->pos().x() * samples_per_pixel + _view.offset() * sample_rate; - for(int i = _dso_xm_stage; i > 0; i--) { - const uint64_t max_index = max(_dso_xm_index[i-1], _dso_xm_index[i]); - _dso_xm_index[i-1] = min(_dso_xm_index[i-1], _dso_xm_index[i]); - _dso_xm_index[i] = max_index; + if (_action_type == NO_ACTION && + event->button() == Qt::RightButton && + _view.session().get_capture_state() == SigSession::Stopped) { + if (_view.session().get_device()->dev_inst()->mode == LOGIC) { + _action_type = LOGIC_ZOOM; + } else if (_view.session().get_device()->dev_inst()->mode == DSO) { + if (_hover_hit) { + uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate(); + _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index); + _view.show_cursors(true); } - _dso_xm_stage = (_dso_xm_stage + 1) % (DsoMeasureStages + 1); } } } @@ -467,41 +409,41 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) { assert(event); _hover_hit = false; - if (!_dso_xm && (_dso_ym_done || !_dso_ym) && - event->buttons() & Qt::RightButton) { - _zoom_rect = QRectF(_mouse_down_point, event->pos()); - _zoom_rect_visible = true; - } if (event->buttons() & Qt::LeftButton) { - if (_drag_sig) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(_drag_sig)) - 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(); - } + _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(); } if (!(event->buttons() || Qt::NoButton)) { - uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); - TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor(); - if (_view.cursors_shown() && grabbed_marker) { - const double cur_time = _view.offset() + _view.hover_point().x() * _view.scale(); - const double pos = cur_time * sample_rate; - const double pos_delta = pos - (uint64_t)pos; - if ( pos_delta < 0.5) - grabbed_marker->set_index((uint64_t)floor(pos)); - else - grabbed_marker->set_index((uint64_t)ceil(pos)); + if (_action_type == DSO_TRIG_MOVE) { + if (_drag_sig) { + boost::shared_ptr dsoSig; + if (dsoSig = dynamic_pointer_cast(_drag_sig)) + dsoSig->set_trig_vpos(event->pos().y()); + } } - if (_dso_ym && !_dso_ym_done) + + if (_action_type == CURS_MOVE) { + uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); + TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor(); + if (_view.cursors_shown() && grabbed_marker) { + const double cur_time = _view.offset() + _view.hover_point().x() * _view.scale(); + const double pos = cur_time * sample_rate; + const double pos_delta = pos - (uint64_t)pos; + if ( pos_delta < 0.5) + grabbed_marker->set_index((uint64_t)floor(pos)); + else + grabbed_marker->set_index((uint64_t)ceil(pos)); + } + } + + if (_action_type == DSO_YM) _dso_ym_end = event->pos().y(); + measure(); } @@ -513,56 +455,176 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) { assert(event); - if (_zoom_rect_visible) { - _zoom_rect_visible = false; - const double newOffset = _view.offset() + (min(event->pos().x(), _mouse_down_point.x()) + 0.5) * _view.scale(); - const double newScale = max(min(_view.scale() * abs(event->pos().x() - _mouse_down_point.x()) / _view.get_view_width(), - _view.get_maxscale()), _view.get_minscale()); - if (newScale != _view.scale()) - _view.set_scale_offset(newScale, newOffset); - } - - if(_drag_sig) - _drag_sig.reset(); - - if ((_measure_type != LOGIC_MOVE && _measure_type != LOGIC_CURS) && - _view.session().get_device()->dev_inst()->mode == LOGIC && - _mouse_down_point.x() == event->pos().x() && - event->button() & Qt::LeftButton) { - if (_measure_type == LOGIC_EDGE) { - _measure_type = NO_MEASURE; - _measure_shown = false; - _edge_rising = 0; - _edge_falling = 0; - } else { - _measure_type = LOGIC_EDGE; - _edge_start = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate(); + if ((_action_type == NO_ACTION) && + (event->button() == Qt::LeftButton)) { + // priority 0 + if (_action_type == NO_ACTION && _view.cursors_shown()) { + list::iterator i = _view.get_cursorList().begin(); + double cursorX; + const double samples_per_pixel = _view.session().get_device()->get_sample_rate() * _view.scale(); + while (i != _view.get_cursorList().end()) { + cursorX = (*i)->index()/samples_per_pixel - (_view.offset() / _view.scale()); + if ((*i)->grabbed()) { + _view.get_ruler()->rel_grabbed_cursor(); + } else if (qAbs(cursorX - event->pos().x()) <= HitCursorMargin) { + _view.get_ruler()->set_grabbed_cursor(*i); + _action_type = CURS_MOVE; + break; + } + i++; + } } - } - if (_view.session().get_device()->dev_inst()->mode == LOGIC && - (_measure_type == NO_MEASURE || _measure_type == LOGIC_MOVE)) { - const double strength = _drag_strength*DragTimerInterval*1.0/_time.elapsed(); - if (_time.elapsed() < 200 && - abs(_drag_strength) < MinorDragOffsetUp && - abs(strength) > MinorDragRateUp) { - _drag_strength = _drag_strength; - _drag_timer.start(DragTimerInterval); - _measure_type = LOGIC_MOVE; - } else if (_time.elapsed() < 200 && - abs(strength) > DragTimerInterval) { - _drag_strength = strength * 5; - _drag_timer.start(DragTimerInterval); - _measure_type = LOGIC_MOVE; - } else { - _drag_strength = 0; - _drag_timer.stop(); - _measure_type = NO_MEASURE; + if (_view.session().get_device()->dev_inst()->mode == LOGIC && + _view.session().get_capture_state() == SigSession::Stopped) { + // priority 1 + if (_action_type == NO_ACTION) { + const double strength = _drag_strength*DragTimerInterval*1.0/_time.elapsed(); + if (_time.elapsed() < 200 && + abs(_drag_strength) < MinorDragOffsetUp && + abs(strength) > MinorDragRateUp) { + _drag_strength = _drag_strength; + _drag_timer.start(DragTimerInterval); + _action_type = LOGIC_MOVE; + } else if (_time.elapsed() < 200 && + abs(strength) > DragTimerInterval) { + _drag_strength = strength * 5; + _drag_timer.start(DragTimerInterval); + _action_type = LOGIC_MOVE; + } + } + + // 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); + if (abs(event->pos().y() - s->get_y()) < _view.get_signalHeight()) { + _action_type = LOGIC_EDGE; + _edge_start = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate(); + break; + } + } + } + } + } else if (_view.session().get_device()->dev_inst()->mode == DSO) { + // priority 0 + if (_action_type == NO_ACTION && _hover_hit) { + _action_type = DSO_YM; + _dso_ym_valid = true; + _dso_ym_sig_index = _hover_sig_index; + _dso_ym_sig_value = _hover_sig_value; + _dso_ym_index = _hover_index; + _dso_ym_start = event->pos().y(); + } + + // priority 1 + if (_action_type == NO_ACTION) { + const vector< boost::shared_ptr > sigs(_view.session().get_signals()); + BOOST_FOREACH(const boost::shared_ptr s, sigs) { + assert(s); + if (!s->enabled()) + continue; + boost::shared_ptr dsoSig; + if (dsoSig = dynamic_pointer_cast(s)) { + if (dsoSig->get_trig_rect(0, _view.get_view_width()).contains(_mouse_point)) { + _drag_sig = s; + _action_type = DSO_TRIG_MOVE; + break; + } + } + } + } } - } + } else if (_action_type == DSO_YM) { + if (event->button() == Qt::LeftButton) { + _dso_ym_end = event->pos().y(); + _action_type = NO_ACTION; + } else if (event->button() == Qt::RightButton) { + _action_type = NO_ACTION; + _dso_ym_valid = false; + } + } else if (_action_type == DSO_TRIG_MOVE) { + if (event->button() == Qt::LeftButton) { + _drag_sig.reset(); + _action_type = NO_ACTION; + } + } else if (_action_type == DSO_XM_STEP0) { + if (event->button() == Qt::LeftButton) { + _action_type = DSO_XM_STEP1; + _dso_xm_valid = true; + } + } else if (_action_type == DSO_XM_STEP1) { + if (event->button() == Qt::LeftButton) { + const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); + const double scale = _view.scale(); + const double samples_per_pixel = sample_rate * scale; - if (!_view.get_ruler()->get_grabbed_cursor() && _measure_type == LOGIC_CURS) - _measure_type = NO_MEASURE; + _dso_xm_index[1] = event->pos().x() * samples_per_pixel + _view.offset() * sample_rate; + const uint64_t max_index = max(_dso_xm_index[0], _dso_xm_index[1]); + _dso_xm_index[0] = min(_dso_xm_index[0], _dso_xm_index[1]); + _dso_xm_index[1] = max_index; + + _action_type = DSO_XM_STEP2; + } else if (event->button() == Qt::RightButton) { + _action_type = NO_ACTION; + _dso_xm_valid = false; + _mm_width = "#####"; + _mm_period = "#####"; + _mm_freq = "#####"; + _mm_duty = "#####"; + measure_updated(); + } + } else if (_action_type == DSO_XM_STEP2) { + if (event->button() == Qt::LeftButton) { + const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); + const double scale = _view.scale(); + const double samples_per_pixel = sample_rate * scale; + _dso_xm_index[2] = event->pos().x() * samples_per_pixel + _view.offset() * sample_rate; + const uint64_t max_index = max(_dso_xm_index[1], _dso_xm_index[2]); + _dso_xm_index[1] = min(_dso_xm_index[1], _dso_xm_index[2]); + _dso_xm_index[2] = max_index; + + _action_type = NO_ACTION; + } else if (event->button() == Qt::RightButton) { + _action_type = NO_ACTION; + _dso_xm_valid = false; + _mm_width = "#####"; + _mm_period = "#####"; + _mm_freq = "#####"; + _mm_duty = "#####"; + measure_updated(); + } + } else if (_action_type == CURS_MOVE) { + _action_type = NO_ACTION; + if (_view.cursors_shown()) { + list::iterator i = _view.get_cursorList().begin(); + while (i != _view.get_cursorList().end()) { + if ((*i)->grabbed()) { + _view.get_ruler()->rel_grabbed_cursor(); + } + i++; + } + } + } else if (_action_type == LOGIC_EDGE) { + _action_type = NO_ACTION; + _edge_rising = 0; + _edge_falling = 0; + } else if (_action_type == LOGIC_MOVE) { + _drag_strength = 0; + _drag_timer.stop(); + _action_type = NO_ACTION; + } else if (_action_type == LOGIC_ZOOM) { + if (event->pos().x() != _mouse_down_point.x()) { + const double newOffset = _view.offset() + (min(event->pos().x(), _mouse_down_point.x()) + 0.5) * _view.scale(); + const double newScale = max(min(_view.scale() * abs(event->pos().x() - _mouse_down_point.x()) / _view.get_view_width(), + _view.get_maxscale()), _view.get_minscale()); + if (newScale != _view.scale()) + _view.set_scale_offset(newScale, newOffset); + } + _action_type = NO_ACTION; + } update(); } @@ -572,13 +634,14 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event) assert (event); (void)event; - if (_view.session().get_device()->dev_inst()->mode == LOGIC) { - if (event->button() & Qt::RightButton) { + if (_view.session().get_device()->dev_inst()->mode == LOGIC && + _view.session().get_capture_state() == SigSession::Stopped) { + if (event->button() == Qt::RightButton) { if (_view.scale() == _view.get_maxscale()) _view.set_preScale_preOffset(); else _view.set_scale_offset(_view.get_maxscale(), 0); - } else if (event->button() & Qt::LeftButton) { + } else if (event->button() == Qt::LeftButton) { uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate(); _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index); _view.show_cursors(true); @@ -586,27 +649,23 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event) update(); } else if (_view.session().get_device()->dev_inst()->mode == DSO && _view.session().get_capture_state() != SigSession::Init && - event->button() & Qt::LeftButton) { - if (_dso_xm_stage == 0) { - uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); - double scale = _view.scale(); - const double samples_per_pixel = sample_rate * scale; - _dso_xm_index[0] = event->pos().x() * samples_per_pixel + - _view.offset() * sample_rate;; - _dso_xm_stage = 1; - _dso_xm_y = event->pos().y(); - _dso_xm = true; - _measure_type = DSO_FREQ; - _measure_shown = true; - } else if (_dso_xm_stage == DsoMeasureStages) { - _dso_xm = false; - _measure_shown = _dso_ym; - _dso_xm_stage = 0; + event->button() == Qt::LeftButton) { + if (_dso_xm_valid) { + _dso_xm_valid = false; + _action_type = NO_ACTION; _mm_width = "#####"; _mm_period = "#####"; _mm_freq = "#####"; _mm_duty = "#####"; - mouse_measure(); + measure_updated(); + } else if (_action_type == NO_ACTION) { + uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); + double scale = _view.scale(); + const double samples_per_pixel = sample_rate * scale; + _dso_xm_index[0] = event->pos().x() * samples_per_pixel + + _view.offset() * sample_rate; + _dso_xm_y = event->pos().y(); + _action_type = DSO_XM_STEP0; } } } @@ -631,13 +690,41 @@ void Viewport::wheelEvent(QWheelEvent *event) void Viewport::leaveEvent(QEvent *) { - _measure_shown = _dso_xm || _dso_ym; _mouse_point = QPoint(-1, -1); //_view.show_cursors(false); - if (_measure_type == LOGIC_EDGE || _measure_type == LOGIC_MOVE) { - _measure_type = NO_MEASURE; - _measure_shown = false; + + if (_action_type == CURS_MOVE) { + if (_view.cursors_shown()) { + list::iterator i = _view.get_cursorList().begin(); + while (i != _view.get_cursorList().end()) { + if ((*i)->grabbed()) { + _view.get_ruler()->rel_grabbed_cursor(); + } + i++; + } + } + } else if (_action_type == LOGIC_EDGE) { + _edge_rising = 0; + _edge_falling = 0; + } else if (_action_type == LOGIC_MOVE) { + _drag_strength = 0; + _drag_timer.stop(); + } else if (_action_type == DSO_TRIG_MOVE) { + _drag_sig.reset(); + } else if (_action_type == DSO_XM_STEP1 || _action_type == DSO_XM_STEP2) { + _dso_xm_valid = false; + _mm_width = "#####"; + _mm_period = "#####"; + _mm_freq = "#####"; + _mm_duty = "#####"; + measure_updated(); + } else if (_action_type == DSO_YM) { + _dso_ym_valid = false; } + + if (_action_type != NO_ACTION) + _action_type = NO_ACTION; + update(); } @@ -669,11 +756,7 @@ void Viewport::clear_measure() void Viewport::measure() { - if ((_view.session().get_device()->dev_inst()->mode == LOGIC && - _view.session().get_capture_state() == SigSession::Running) || - _drag_strength != 0) - return; - _measure_shown = _dso_xm || _dso_ym; + _measure_type = NO_MEASURE; const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); const vector< boost::shared_ptr > sigs(_view.session().get_signals()); BOOST_FOREACH(const boost::shared_ptr s, sigs) { @@ -681,61 +764,64 @@ void Viewport::measure() boost::shared_ptr logicSig; boost::shared_ptr dsoSig; if (logicSig = dynamic_pointer_cast(s)) { - if (_measure_type != LOGIC_EDGE && - logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) { - _measure_shown = true; - _measure_type = LOGIC_FREQ; + if (_action_type == NO_ACTION) { + if (logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) { + _measure_type = LOGIC_FREQ; - _mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate); - _mm_period = _thd_sample != 0 ? _view.get_ruler()->format_real_time(_thd_sample - _cur_sample, sample_rate) : "#####"; - _mm_freq = _thd_sample != 0 ? _view.get_ruler()->format_real_freq(_thd_sample - _cur_sample, sample_rate) : "#####"; + _mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate); + _mm_period = _thd_sample != 0 ? _view.get_ruler()->format_real_time(_thd_sample - _cur_sample, sample_rate) : "#####"; + _mm_freq = _thd_sample != 0 ? _view.get_ruler()->format_real_freq(_thd_sample - _cur_sample, sample_rate) : "#####"; - const double pixels_offset = _view.offset() / _view.scale(); - const double samples_per_pixel = sample_rate * _view.scale(); - _cur_preX = _cur_sample / samples_per_pixel - pixels_offset; - _cur_aftX = _nxt_sample / samples_per_pixel - pixels_offset; - _cur_thdX = _thd_sample / samples_per_pixel - pixels_offset; - _cur_midY = logicSig->get_y(); + const double pixels_offset = _view.offset() / _view.scale(); + const double samples_per_pixel = sample_rate * _view.scale(); + _cur_preX = _cur_sample / samples_per_pixel - pixels_offset; + _cur_aftX = _nxt_sample / samples_per_pixel - pixels_offset; + _cur_thdX = _thd_sample / samples_per_pixel - pixels_offset; + _cur_midY = logicSig->get_y(); - _mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0 / (_thd_sample - _cur_sample), 'f', 2)+"%" : - "#####"; - mouse_measure(); - break; - } else if (_measure_type == LOGIC_EDGE && - logicSig->edges(_view.hover_point(), _edge_start, _edge_rising, _edge_falling)) { - _measure_shown = true; + _mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0 / (_thd_sample - _cur_sample), 'f', 2)+"%" : + "#####"; + break; + } else { + _measure_type = NO_MEASURE; + _mm_width = "#####"; + _mm_period = "#####"; + _mm_freq = "#####"; + _mm_duty = "#####"; + } + } else if (_action_type == LOGIC_EDGE) { + if (logicSig->edges(_view.hover_point(), _edge_start, _edge_rising, _edge_falling)) { + const double pixels_offset = _view.offset() / _view.scale(); + const double samples_per_pixel = sample_rate * _view.scale(); + _cur_preX = _edge_start / samples_per_pixel - pixels_offset; + _cur_aftX = _view.hover_point().x(); + _cur_midY = logicSig->get_y() - logicSig->get_totalHeight()/2 - 5; - const double pixels_offset = _view.offset() / _view.scale(); - const double samples_per_pixel = sample_rate * _view.scale(); - _cur_preX = _edge_start / samples_per_pixel - pixels_offset; - _cur_aftX = _view.hover_point().x(); - _cur_midY = logicSig->get_y() - logicSig->get_signalHeight()/2 - 5; + _em_rising = "Rising: " + QString::number(_edge_rising); + _em_falling = "Falling: " + QString::number(_edge_falling); + _em_edges = "Edges: " + QString::number(_edge_rising + _edge_falling); - _em_rising = "Rising: " + QString::number(_edge_rising); - _em_falling = "Falling: " + QString::number(_edge_falling); - _em_edges = "Edges: " + QString::number(_edge_rising + _edge_falling); - - break; - } else { - _mm_width = "#####"; - _mm_period = "#####"; - _mm_freq = "#####"; - _mm_duty = "#####"; + break; + } } - mouse_measure(); } else if (dsoSig = dynamic_pointer_cast(s)) { if (_measure_en && dsoSig->measure(_view.hover_point())) { - _measure_shown = true; - _measure_type = DSO_FREQ; + _measure_type = DSO_VALUE; + break; + } else { + _measure_type = NO_MEASURE; } } } + if (_measure_type != NO_MEASURE) + measure_updated(); } void Viewport::paintMeasure(QPainter &p) { _hover_hit = false; - if (_measure_type == LOGIC_FREQ) { + if (_action_type == NO_ACTION && + _measure_type == LOGIC_FREQ) { p.setPen(QColor(17, 133, 209, 255)); p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY)); p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY - 2)); @@ -788,45 +874,11 @@ void Viewport::paintMeasure(QPainter &p) p.drawText(measure4_rect, Qt::AlignRight | Qt::AlignVCenter, tr("Duty Cycle: ") + _mm_duty); } - } else if (_measure_type == LOGIC_EDGE) { - p.setPen(QColor(17, 133, 209, 255)); + } - p.drawLine(QLineF(_cur_preX, _cur_midY-5, _cur_preX, _cur_midY+5)); - p.drawLine(QLineF(_cur_aftX, _cur_midY-5, _cur_aftX, _cur_midY+5)); - p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY)); - - int typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignTop, _em_edges).width(); - typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignTop, _em_rising).width()); - typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignTop, _em_falling).width()); - - typical_width = typical_width + 30; - - const double width = _view.get_view_width(); - const double height = _view.viewport()->height(); - const double left = _view.hover_point().x(); - const double top = _view.hover_point().y(); - const double right = left + typical_width; - const double bottom = top + 60; - QPointF org_pos = QPointF(right > width ? left - typical_width : left, bottom > height ? top - 80 : top); - QRectF measure_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 60.0); - QRectF measure1_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 20.0); - QRectF measure2_rect = QRectF(org_pos.x(), org_pos.y()+20, (double)typical_width, 20.0); - QRectF measure3_rect = QRectF(org_pos.x(), org_pos.y()+40, (double)typical_width, 20.0); - - p.setPen(Qt::NoPen); - p.setBrush(QColor(17, 133, 209, 150)); - p.drawRect(measure_rect); - - p.setPen(Qt::black); - p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter, _em_edges); - p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter, _em_rising); - p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter, _em_falling); - - } else if (_measure_type == DSO_FREQ) { - const vector< boost::shared_ptr > sigs(_view.session().get_signals()); + const vector< boost::shared_ptr > sigs(_view.session().get_signals()); + if (_action_type == NO_ACTION && + _measure_type == DSO_VALUE) { BOOST_FOREACH(const boost::shared_ptr s, sigs) { boost::shared_ptr dsoSig; if (dsoSig = dynamic_pointer_cast(s)) { @@ -883,132 +935,177 @@ void Viewport::paintMeasure(QPainter &p) } } } + } - // -- vertical value - if (_dso_ym) { - BOOST_FOREACH(const boost::shared_ptr s, sigs) { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(s)) { - if (dsoSig->get_index() == _dso_ym_sig_index) { - p.setPen(QPen(dsoSig->get_colour(), 1, Qt::DotLine)); - const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignTop, "W").height(); - const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); - const double x = (_dso_ym_index / (sample_rate * _view.scale())) - - _view.offset() /_view.scale(); - p.drawLine(x-10, _dso_ym_start, - x+10, _dso_ym_start); - p.drawLine(x, _dso_ym_start, - x, _dso_ym_end); - p.drawLine(0, _dso_ym_end, - _view.get_view_width(), _dso_ym_end); + if (_dso_ym_valid) { + BOOST_FOREACH(const boost::shared_ptr s, sigs) { + boost::shared_ptr dsoSig; + if (dsoSig = dynamic_pointer_cast(s)) { + if (dsoSig->get_index() == _dso_ym_sig_index) { + p.setPen(QPen(dsoSig->get_colour(), 1, Qt::DotLine)); + const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, "W").height(); + const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); + const double x = (_dso_ym_index / (sample_rate * _view.scale())) - + _view.offset() /_view.scale(); + p.drawLine(x-10, _dso_ym_start, + x+10, _dso_ym_start); + p.drawLine(x, _dso_ym_start, + x, _dso_ym_end); + p.drawLine(0, _dso_ym_end, + _view.get_view_width(), _dso_ym_end); - // -- vertical delta value - double hrate = (_dso_ym_start - _dso_ym_end) * 1.0f / _view.get_view_height(); - double value = hrate * dsoSig->get_vDialValue() * dsoSig->get_factor() * DS_CONF_DSO_VDIVS; - QString value_str = abs(value) > 1000 ? QString::number(value/1000.0, 'f', 2) + "V" : QString::number(value, 'f', 2) + "mV"; - int value_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignVCenter, value_str).width(); - p.drawText(QRect(x+10, abs(_dso_ym_start+_dso_ym_end)/2, value_rect_width, text_height), - value_str); + // -- vertical delta value + double hrate = (_dso_ym_start - _dso_ym_end) * 1.0f / _view.get_view_height(); + double value = hrate * dsoSig->get_vDialValue() * dsoSig->get_factor() * DS_CONF_DSO_VDIVS; + QString value_str = abs(value) > 1000 ? QString::number(value/1000.0, 'f', 2) + "V" : QString::number(value, 'f', 2) + "mV"; + int value_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignVCenter, value_str).width(); + p.drawText(QRect(x+10, abs(_dso_ym_start+_dso_ym_end)/2, value_rect_width, text_height), + value_str); - // -- start value - value_str = abs(_dso_ym_sig_value) > 1000 ? QString::number(_dso_ym_sig_value/1000.0, 'f', 2) + "V" : QString::number(_dso_ym_sig_value, 'f', 2) + "mV"; - value_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignVCenter, value_str).width(); - int str_y = value > 0 ? _dso_ym_start : _dso_ym_start - text_height; - p.drawText(QRect(x-0.5*value_rect_width, str_y, value_rect_width, text_height), - value_str); + // -- start value + value_str = abs(_dso_ym_sig_value) > 1000 ? QString::number(_dso_ym_sig_value/1000.0, 'f', 2) + "V" : QString::number(_dso_ym_sig_value, 'f', 2) + "mV"; + value_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignVCenter, value_str).width(); + int str_y = value > 0 ? _dso_ym_start : _dso_ym_start - text_height; + p.drawText(QRect(x-0.5*value_rect_width, str_y, value_rect_width, text_height), + value_str); - // -- end value - double end_value = _dso_ym_sig_value + value; - value_str = abs(end_value) > 1000 ? QString::number(end_value/1000.0, 'f', 2) + "V" : QString::number(end_value, 'f', 2) + "mV"; - value_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignVCenter, value_str).width(); - str_y = value > 0 ? _dso_ym_end-text_height : _dso_ym_end; - p.drawText(QRect(x-0.5*value_rect_width, str_y, value_rect_width, text_height), - value_str); - break; - } + // -- end value + double end_value = _dso_ym_sig_value + value; + value_str = abs(end_value) > 1000 ? QString::number(end_value/1000.0, 'f', 2) + "V" : QString::number(end_value, 'f', 2) + "mV"; + value_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignVCenter, value_str).width(); + str_y = value > 0 ? _dso_ym_end-text_height : _dso_ym_end; + p.drawText(QRect(x-0.5*value_rect_width, str_y, value_rect_width, text_height), + value_str); + break; } } } + } - // -- width/period/frequency/duty - if (_dso_xm) { - p.setPen(QPen(Qt::red, 1, Qt::DotLine)); - int measure_line_count = 6; - const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignTop, "W").height(); - const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); - QLineF *line; - QLineF *const measure_lines = new QLineF[measure_line_count]; - line = measure_lines; - double x[DsoMeasureStages]; - for (int i = 0; i < _dso_xm_stage; i++) { - x[i] = (_dso_xm_index[i] / (sample_rate * _view.scale())) - - _view.offset() /_view.scale(); - } - measure_line_count = 0; - if (_dso_xm_stage > 0) { - *line++ = QLineF(x[0], _dso_xm_y - 10, - x[0], _dso_xm_y + 10); - measure_line_count += 1; - } - if (_dso_xm_stage > 1) { - *line++ = QLineF(x[1], _dso_xm_y - 10, - x[1], _dso_xm_y + 10); - *line++ = QLineF(x[0], _dso_xm_y, - x[1], _dso_xm_y); - _mm_width = _view.get_ruler()->format_real_time(_dso_xm_index[1] - _dso_xm_index[0], sample_rate); + if (_dso_xm_valid) { + p.setPen(QPen(Qt::red, 1, Qt::DotLine)); + int measure_line_count = 6; + const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, "W").height(); + const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); + QLineF *line; + QLineF *const measure_lines = new QLineF[measure_line_count]; + line = measure_lines; + double x[DsoMeasureStages]; + int dso_xm_stage = 0; + if (_action_type == DSO_XM_STEP1) + dso_xm_stage = 1; + else if(_action_type == DSO_XM_STEP2) + dso_xm_stage = 2; + else + dso_xm_stage = 3; - // -- width show - const QString w_ctr = "W="+_mm_width; - int w_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignVCenter, w_ctr).width(); - p.drawText(QRect(x[0]+10, _dso_xm_y - text_height, w_rect_width, text_height), w_ctr); - measure_line_count += 2; - } - if (_dso_xm_stage > 2) { - *line++ = QLineF(x[0], _dso_xm_y + 20, - x[0], _dso_xm_y + 40); - *line++ = QLineF(x[0], _dso_xm_y + 30, - x[2], _dso_xm_y + 30); - *line++ = QLineF(x[2], _dso_xm_y + 20, - x[2], _dso_xm_y + 40); - _mm_period = _view.get_ruler()->format_real_time(_dso_xm_index[2] - _dso_xm_index[0], sample_rate); - _mm_freq = _view.get_ruler()->format_real_freq(_dso_xm_index[2] - _dso_xm_index[0], sample_rate); - _mm_duty = QString::number((_dso_xm_index[1] - _dso_xm_index[0]) * 100.0 / (_dso_xm_index[2] - _dso_xm_index[0]), 'f', 2)+"%"; - - // -- period show - const QString p_ctr = "P="+_mm_period; - int p_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignVCenter, p_ctr).width(); - p.drawText(QRect(x[0]+10, _dso_xm_y + 30 - text_height, p_rect_width, text_height), p_ctr); - - // -- frequency show - const QString f_ctr = "F="+_mm_freq; - int f_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignVCenter, f_ctr).width(); - p.drawText(QRect(x[0]+20 + p_rect_width, _dso_xm_y + 30 - text_height, f_rect_width, text_height), f_ctr); - - // -- duty show - const QString d_ctr = "D="+_mm_duty; - int d_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignVCenter, d_ctr).width(); - p.drawText(QRect(x[1]+10, _dso_xm_y - 0.5*text_height, d_rect_width, text_height), d_ctr); - - measure_line_count += 3; - } - p.drawLines(measure_lines, measure_line_count); - if (_dso_xm_stage < DsoMeasureStages) { - p.drawLine(x[_dso_xm_stage-1], _dso_xm_y, - _mouse_point.x(), _dso_xm_y); - p.drawLine(_mouse_point.x(), 0, - _mouse_point.x(), _view.get_viewport()->height()); - } - mouse_measure(); + for (int i = 0; i < dso_xm_stage; i++) { + x[i] = (_dso_xm_index[i] / (sample_rate * _view.scale())) - + _view.offset() /_view.scale(); } + measure_line_count = 0; + if (dso_xm_stage > 0) { + *line++ = QLineF(x[0], _dso_xm_y - 10, + x[0], _dso_xm_y + 10); + measure_line_count += 1; + } + if (dso_xm_stage > 1) { + *line++ = QLineF(x[1], _dso_xm_y - 10, + x[1], _dso_xm_y + 10); + *line++ = QLineF(x[0], _dso_xm_y, + x[1], _dso_xm_y); + _mm_width = _view.get_ruler()->format_real_time(_dso_xm_index[1] - _dso_xm_index[0], sample_rate); + + // -- width show + const QString w_ctr = "W="+_mm_width; + int w_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignVCenter, w_ctr).width(); + p.drawText(QRect(x[0]+10, _dso_xm_y - text_height, w_rect_width, text_height), w_ctr); + measure_line_count += 2; + } + if (dso_xm_stage > 2) { + *line++ = QLineF(x[0], _dso_xm_y + 20, + x[0], _dso_xm_y + 40); + *line++ = QLineF(x[0], _dso_xm_y + 30, + x[2], _dso_xm_y + 30); + *line++ = QLineF(x[2], _dso_xm_y + 20, + x[2], _dso_xm_y + 40); + _mm_period = _view.get_ruler()->format_real_time(_dso_xm_index[2] - _dso_xm_index[0], sample_rate); + _mm_freq = _view.get_ruler()->format_real_freq(_dso_xm_index[2] - _dso_xm_index[0], sample_rate); + _mm_duty = QString::number((_dso_xm_index[1] - _dso_xm_index[0]) * 100.0 / (_dso_xm_index[2] - _dso_xm_index[0]), 'f', 2)+"%"; + + // -- period show + const QString p_ctr = "P="+_mm_period; + int p_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignVCenter, p_ctr).width(); + p.drawText(QRect(x[0]+10, _dso_xm_y + 30 - text_height, p_rect_width, text_height), p_ctr); + + // -- frequency show + const QString f_ctr = "F="+_mm_freq; + int f_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignVCenter, f_ctr).width(); + p.drawText(QRect(x[0]+20 + p_rect_width, _dso_xm_y + 30 - text_height, f_rect_width, text_height), f_ctr); + + // -- duty show + const QString d_ctr = "D="+_mm_duty; + int d_rect_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignVCenter, d_ctr).width(); + p.drawText(QRect(x[1]+10, _dso_xm_y - 0.5*text_height, d_rect_width, text_height), d_ctr); + + measure_line_count += 3; + } + p.drawLines(measure_lines, measure_line_count); + if (dso_xm_stage < DsoMeasureStages) { + p.drawLine(x[dso_xm_stage-1], _dso_xm_y, + _mouse_point.x(), _dso_xm_y); + p.drawLine(_mouse_point.x(), 0, + _mouse_point.x(), _view.get_viewport()->height()); + } + measure_updated(); + } + + if (_action_type == LOGIC_EDGE) { + p.setPen(QColor(17, 133, 209, 255)); + + p.drawLine(QLineF(_cur_preX, _cur_midY-5, _cur_preX, _cur_midY+5)); + p.drawLine(QLineF(_cur_aftX, _cur_midY-5, _cur_aftX, _cur_midY+5)); + p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY)); + + int typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, _em_edges).width(); + typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, _em_rising).width()); + typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, _em_falling).width()); + + typical_width = typical_width + 30; + + const double width = _view.get_view_width(); + const double height = _view.viewport()->height(); + const double left = _view.hover_point().x(); + const double top = _view.hover_point().y(); + const double right = left + typical_width; + const double bottom = top + 60; + QPointF org_pos = QPointF(right > width ? left - typical_width : left, bottom > height ? top - 80 : top); + QRectF measure_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 60.0); + QRectF measure1_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 20.0); + QRectF measure2_rect = QRectF(org_pos.x(), org_pos.y()+20, (double)typical_width, 20.0); + QRectF measure3_rect = QRectF(org_pos.x(), org_pos.y()+40, (double)typical_width, 20.0); + + p.setPen(Qt::NoPen); + p.setBrush(QColor(17, 133, 209, 150)); + p.drawRect(measure_rect); + + p.setPen(Qt::black); + p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter, _em_edges); + p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter, _em_rising); + p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter, _em_falling); + } } diff --git a/DSView/pv/view/viewport.h b/DSView/pv/view/viewport.h index 40a15bbc..17dcf51a 100644 --- a/DSView/pv/view/viewport.h +++ b/DSView/pv/view/viewport.h @@ -54,13 +54,30 @@ public: static const int DsoMeasureStages = 3; static const double MinorDragRateUp; static const double DragDamping; + enum ActionType { + NO_ACTION, + + CURS_MOVE, + + LOGIC_EDGE, + LOGIC_MOVE, + LOGIC_ZOOM, + + DSO_XM_STEP0, + DSO_XM_STEP1, + DSO_XM_STEP2, + DSO_XM_STEP3, + DSO_YM, + DSO_TRIG_MOVE, + + DECODE_REGION + }; + enum MeasureType { NO_MEASURE, LOGIC_FREQ, - LOGIC_EDGE, - LOGIC_MOVE, - LOGIC_CURS, - DSO_FREQ + LOGIC_EDGE_CNT, + DSO_VALUE }; public: @@ -103,7 +120,7 @@ private slots: void set_receive_len(quint64 length); signals: - void mouse_measure(); + void measure_updated(); private: View &_view; @@ -118,11 +135,8 @@ private: QPixmap pixmap; - bool _zoom_rect_visible; - QRectF _zoom_rect; - bool _measure_en; - bool _measure_shown; + ActionType _action_type; MeasureType _measure_type; uint64_t _cur_sample; uint64_t _nxt_sample; @@ -158,13 +172,11 @@ private: QTimer _drag_timer; int _drag_strength; - bool _dso_xm; - int _dso_xm_stage; + bool _dso_xm_valid; int _dso_xm_y; uint64_t _dso_xm_index[DsoMeasureStages]; - bool _dso_ym; - bool _dso_ym_done; + bool _dso_ym_valid; uint16_t _dso_ym_sig_index; double _dso_ym_sig_value; uint64_t _dso_ym_index;