X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fview%2Fview.cpp;h=6cd274b0dc8f74605f480baaadfb61e7a725cfd3;hp=5af8d28c7f072e07e97200bcad543a0c3ed8aaec;hb=76fea660eea8a2e1963b4703906392a0999669d0;hpb=8dbbc7f0b9ea59d0f0d62225772f8a56eee125f5 diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 5af8d28c..6cd274b0 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -22,35 +22,44 @@ #include #endif +#include + #include #include #include #include #include +#include #include +#include #include #include #include -#include "cursorheader.h" -#include "decodetrace.h" -#include "header.h" -#include "logicsignal.h" -#include "ruler.h" -#include "signal.h" -#include "tracegroup.h" -#include "view.h" -#include "viewport.h" - -#include "pv/sigsession.h" -#include "pv/data/logic.h" -#include "pv/data/logicsnapshot.h" +#include "cursorheader.hpp" +#include "decodetrace.hpp" +#include "header.hpp" +#include "logicsignal.hpp" +#include "ruler.hpp" +#include "signal.hpp" +#include "tracegroup.hpp" +#include "view.hpp" +#include "viewport.hpp" + +#include "pv/session.hpp" +#include "pv/data/logic.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,11 +84,13 @@ 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); -View::View(SigSession &session, QWidget *parent) : +View::View(Session &session, QWidget *parent) : QAbstractScrollArea(parent), session_(session), viewport_(new Viewport(*this)), @@ -90,8 +101,10 @@ View::View(SigSession &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(SigSession &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,14 +160,17 @@ View::View(SigSession &session, QWidget *parent) : // make sure the transparent widgets are on the top cursorheader_->raise(); header_->raise(); + + // Update the zoom state + calculate_tick_spacing(); } -SigSession& View::session() +Session& View::session() { return session_; } -const SigSession& View::session() const +const Session& View::session() const { return session_; } @@ -179,6 +195,15 @@ const Viewport* View::viewport() const return viewport_; } +vector< shared_ptr > View::time_items() const +{ + vector< shared_ptr > items; + items.push_back(cursors_); + items.push_back(cursors_->first()); + items.push_back(cursors_->second()); + return items; +} + double View::scale() const { return scale_; @@ -199,6 +224,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 +272,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 +294,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 +319,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 +358,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 +418,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 +463,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; @@ -407,11 +483,11 @@ void View::update_scroll() // Set the vertical scrollbar verticalScrollBar()->setPageStep(areaSize.height()); + verticalScrollBar()->setSingleStep(areaSize.height() / 8); const pair extents = v_extents(); - const int extra_scroll_height = (extents.second - extents.first) / 4; - verticalScrollBar()->setRange(extents.first - extra_scroll_height, - extents.first + extra_scroll_height); + verticalScrollBar()->setRange(extents.first - (areaSize.height() / 2), + extents.second - (areaSize.height() / 2)); } void View::update_layout() @@ -430,16 +506,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(); } @@ -542,8 +618,8 @@ void View::appearance_changed(bool label, bool content) void View::extents_changed(bool horz, bool vert) { sticky_events_ |= - (horz ? SelectableItemHExtentsChanged : 0) | - (vert ? SelectableItemVExtentsChanged : 0); + (horz ? RowItemHExtentsChanged : 0) | + (vert ? RowItemVExtentsChanged : 0); lazy_event_handler_.start(); } @@ -666,9 +742,9 @@ void View::on_signals_moved() void View::process_sticky_events() { - if (sticky_events_ & SelectableItemHExtentsChanged) + if (sticky_events_ & RowItemHExtentsChanged) update_layout(); - if (sticky_events_ & SelectableItemVExtentsChanged) + if (sticky_events_ & RowItemVExtentsChanged) restack_all_row_items(); // Clear the sticky events