X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fview%2Fview.cpp;h=3df87e540b986b0e08b1242c9139950f65f12a5b;hp=c96063536c0e917bc86336bbf2d7cb071a63b3c6;hb=b3f44329f5846bfb800ee53c15c65b2395d3ba0c;hpb=2b81ae4682ade4109ffa442794de36ceb32045eb diff --git a/pv/view/view.cpp b/pv/view/view.cpp index c9606353..3df87e54 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -22,13 +22,17 @@ #include #endif +#include + #include #include #include #include #include +#include #include +#include #include #include @@ -44,13 +48,18 @@ #include "view.hpp" #include "viewport.hpp" -#include "pv/sigsession.hpp" +#include "pv/session.hpp" #include "pv/data/logic.hpp" -#include "pv/data/logicsnapshot.hpp" +#include "pv/data/logicsegment.hpp" +#include "pv/util.hpp" using boost::shared_lock; using boost::shared_mutex; + using pv::data::SignalData; +using pv::data::Segment; +using pv::util::format_time; + using std::back_inserter; using std::deque; using std::dynamic_pointer_cast; @@ -75,6 +84,8 @@ const double View::MinScale = 1e-15; const int View::MaxScrollValue = INT_MAX / 2; +const int View::ScaleUnits[3] = {1, 2, 5}; + const QColor View::CursorAreaColour(220, 231, 243); const QSizeF View::LabelPadding(4, 0); @@ -90,8 +101,10 @@ View::View(Session &session, QWidget *parent) : offset_(0), v_offset_(0), updating_scroll_(false), + tick_period_(0.0), + tick_prefix_(0), show_cursors_(false), - cursors_(*this), + cursors_(new CursorPair(*this)), hover_point_(-1, -1) { connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), @@ -108,9 +121,9 @@ View::View(Session &session, QWidget *parent) : connect(&session_, SIGNAL(frame_ended()), this, SLOT(data_updated())); - connect(cursors_.first().get(), SIGNAL(time_changed()), + connect(cursors_->first().get(), SIGNAL(time_changed()), this, SLOT(marker_time_changed())); - connect(cursors_.second().get(), SIGNAL(time_changed()), + connect(cursors_->second().get(), SIGNAL(time_changed()), this, SLOT(marker_time_changed())); connect(header_, SIGNAL(signals_moved()), @@ -147,6 +160,9 @@ View::View(Session &session, QWidget *parent) : // make sure the transparent widgets are on the top cursorheader_->raise(); header_->raise(); + + // Update the zoom state + calculate_tick_spacing(); } Session& View::session() @@ -179,6 +195,14 @@ const Viewport* View::viewport() const return viewport_; } +vector< shared_ptr > View::time_items() const +{ + vector< shared_ptr > items; + items.push_back(cursors_->first()); + items.push_back(cursors_->second()); + return items; +} + double View::scale() const { return scale_; @@ -199,6 +223,16 @@ unsigned int View::depth() const return 0; } +unsigned int View::tick_prefix() const +{ + return tick_prefix_; +} + +double View::tick_period() const +{ + return tick_period_; +} + void View::zoom(double steps) { zoom(steps, viewport_->width() / 2); @@ -237,7 +271,10 @@ void View::zoom_one_to_one() double samplerate = 0.0; for (const shared_ptr d : visible_data) { assert(d); - samplerate = max(samplerate, d->samplerate()); + const vector< shared_ptr > segments = + d->segments(); + for (const shared_ptr &s : segments) + samplerate = max(samplerate, s->samplerate()); } if (samplerate == 0.0) @@ -256,6 +293,8 @@ void View::set_scale_offset(double scale, double offset) scale_ = scale; offset_ = offset; + calculate_tick_spacing(); + update_scroll(); ruler_->update(); cursorheader_->update(); @@ -279,22 +318,26 @@ set< shared_ptr > View::get_visible_data() const pair View::get_time_extents() const { - const set< shared_ptr > visible_data = get_visible_data(); - if (visible_data.empty()) - return make_pair(0.0, 0.0); - double left_time = DBL_MAX, right_time = DBL_MIN; + const set< shared_ptr > visible_data = get_visible_data(); for (const shared_ptr d : visible_data) { - const double start_time = d->get_start_time(); - double samplerate = d->samplerate(); - samplerate = (samplerate <= 0.0) ? 1.0 : samplerate; - - left_time = min(left_time, start_time); - right_time = max(right_time, start_time + - d->get_max_sample_count() / samplerate); + const vector< shared_ptr > segments = + d->segments(); + for (const shared_ptr &s : segments) { + double samplerate = s->samplerate(); + samplerate = (samplerate <= 0.0) ? 1.0 : samplerate; + + const double start_time = s->start_time(); + left_time = min(left_time, start_time); + right_time = max(right_time, start_time + + d->get_max_sample_count() / samplerate); + } } + if (left_time == DBL_MAX && right_time == DBL_MIN) + return make_pair(0.0, 0.0); + assert(left_time < right_time); return make_pair(left_time, right_time); } @@ -314,18 +357,13 @@ void View::show_cursors(bool show) void View::centre_cursors() { const double time_width = scale_ * viewport_->width(); - cursors_.first()->set_time(offset_ + time_width * 0.4); - cursors_.second()->set_time(offset_ + time_width * 0.6); + cursors_->first()->set_time(offset_ + time_width * 0.4); + cursors_->second()->set_time(offset_ + time_width * 0.6); cursorheader_->update(); viewport_->update(); } -CursorPair& View::cursors() -{ - return cursors_; -} - -const CursorPair& View::cursors() const +std::shared_ptr View::cursors() const { return cursors_; } @@ -379,6 +417,40 @@ void View::set_zoom(double scale, int offset) set_scale_offset(new_scale, new_offset); } +void View::calculate_tick_spacing() +{ + const double SpacingIncrement = 32.0f; + const double MinValueSpacing = 32.0f; + + double min_width = SpacingIncrement, typical_width; + + QFontMetrics m(QApplication::font()); + + do { + const double min_period = scale_ * min_width; + + const int order = (int)floorf(log10f(min_period)); + const double order_decimal = pow(10.0, order); + + unsigned int unit = 0; + + do { + tick_period_ = order_decimal * ScaleUnits[unit++]; + } while (tick_period_ < min_period && + unit < countof(ScaleUnits)); + + tick_prefix_ = (order - pv::util::FirstSIPrefixPower) / 3; + + typical_width = m.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, + format_time(offset_, tick_prefix_)).width() + + MinValueSpacing; + + min_width += SpacingIncrement; + + } while(typical_width > tick_period_ / scale_); +} + void View::update_scroll() { assert(viewport_); @@ -390,7 +462,10 @@ void View::update_scroll() get_scroll_layout(length, offset); length = max(length - areaSize.width(), 0.0); + int major_tick_distance = tick_period_ / scale_; + horizontalScrollBar()->setPageStep(areaSize.width() / 2); + horizontalScrollBar()->setSingleStep(major_tick_distance); updating_scroll_ = true; @@ -430,16 +505,16 @@ void View::update_layout() update_scroll(); } -void View::paint_label(QPainter &p, int right, bool hover) +void View::paint_label(QPainter &p, const QRect &rect, bool hover) { (void)p; - (void)right; + (void)rect; (void)hover; } -QRectF View::label_rect(int right) +QRectF View::label_rect(const QRectF &rect) { - (void)right; + (void)rect; return QRectF(); }