From 361c560ed9ef67278916e086ed0b0649ae01b583 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sun, 30 Nov 2014 12:33:18 +0000 Subject: [PATCH] Ruler: Moved calculate_tick_spacing into View --- pv/view/cursor.cpp | 5 ++-- pv/view/cursor.hpp | 4 +-- pv/view/cursorheader.cpp | 5 +--- pv/view/cursorpair.cpp | 9 +++--- pv/view/cursorpair.hpp | 3 +- pv/view/ruler.cpp | 44 ++--------------------------- pv/view/ruler.hpp | 13 --------- pv/view/timemarker.hpp | 4 +-- pv/view/view.cpp | 61 ++++++++++++++++++++++++++++++++++++++++ pv/view/view.hpp | 21 ++++++++++++++ 10 files changed, 96 insertions(+), 73 deletions(-) diff --git a/pv/view/cursor.cpp b/pv/view/cursor.cpp index 03df0543..07196799 100644 --- a/pv/view/cursor.cpp +++ b/pv/view/cursor.cpp @@ -74,12 +74,13 @@ QRectF Cursor::get_label_rect(const QRect &rect) const label_size.width(), height); } -void Cursor::paint_label(QPainter &p, const QRect &rect, - unsigned int prefix) +void Cursor::paint_label(QPainter &p, const QRect &rect) { const shared_ptr other(get_other_cursor()); assert(other); + const unsigned int prefix = view_.tick_prefix(); + compute_text_size(p, prefix); const QRectF r(get_label_rect(rect)); diff --git a/pv/view/cursor.hpp b/pv/view/cursor.hpp index 8679a286..5df0ca2c 100644 --- a/pv/view/cursor.hpp +++ b/pv/view/cursor.hpp @@ -66,10 +66,8 @@ public: * Paints the cursor's label to the ruler. * @param p The painter to draw with. * @param rect The rectangle of the ruler client area. - * @param prefix The index of the SI prefix to use. */ - void paint_label(QPainter &p, const QRect &rect, - unsigned int prefix); + void paint_label(QPainter &p, const QRect &rect); private: void compute_text_size(QPainter &p, unsigned int prefix); diff --git a/pv/view/cursorheader.cpp b/pv/view/cursorheader.cpp index 3fa0b0c5..3e2944e0 100644 --- a/pv/view/cursorheader.cpp +++ b/pv/view/cursorheader.cpp @@ -70,16 +70,13 @@ void CursorHeader::paintEvent(QPaintEvent*) QPainter p(this); p.setRenderHint(QPainter::Antialiasing); - unsigned int prefix = pv::view::Ruler::calculate_tick_spacing( - p, view_.scale(), view_.offset()).second; - // Draw the cursors if (view_.cursors_shown()) { // The cursor labels are not drawn with the arrows exactly on the // bottom line of the widget, because then the selection shadow // would be clipped away. const QRect r = rect().adjusted(0, 0, 0, -BaselineOffset); - view_.cursors().draw_markers(p, r, prefix); + view_.cursors().draw_markers(p, r); } } diff --git a/pv/view/cursorpair.cpp b/pv/view/cursorpair.cpp index 0fb0d8d1..8aba0abd 100644 --- a/pv/view/cursorpair.cpp +++ b/pv/view/cursorpair.cpp @@ -74,12 +74,13 @@ QRectF CursorPair::get_label_rect(const QRect &rect) const right - left, height); } -void CursorPair::draw_markers(QPainter &p, - const QRect &rect, unsigned int prefix) +void CursorPair::draw_markers(QPainter &p, const QRect &rect) { assert(first_); assert(second_); + const unsigned int prefix = view_.tick_prefix(); + compute_text_size(p, prefix); QRectF delta_rect(get_label_rect(rect)); @@ -104,8 +105,8 @@ void CursorPair::draw_markers(QPainter &p, } // Paint the cursor markers - first_->paint_label(p, rect, prefix); - second_->paint_label(p, rect, prefix); + first_->paint_label(p, rect); + second_->paint_label(p, rect); } void CursorPair::draw_viewport_background(QPainter &p, diff --git a/pv/view/cursorpair.hpp b/pv/view/cursorpair.hpp index dd37b0ed..84737d21 100644 --- a/pv/view/cursorpair.hpp +++ b/pv/view/cursorpair.hpp @@ -57,8 +57,7 @@ public: public: QRectF get_label_rect(const QRect &rect) const; - void draw_markers(QPainter &p, - const QRect &rect, unsigned int prefix); + void draw_markers(QPainter &p, const QRect &rect); void draw_viewport_background(QPainter &p, const QRect &rect); diff --git a/pv/view/ruler.cpp b/pv/view/ruler.cpp index 56651169..ee521f0e 100644 --- a/pv/view/ruler.cpp +++ b/pv/view/ruler.cpp @@ -32,7 +32,6 @@ namespace view { const int Ruler::RulerHeight = 30; const int Ruler::MinorTickSubdivision = 4; -const int Ruler::ScaleUnits[3] = {1, 2, 5}; const int Ruler::HoverArrowSize = 5; @@ -57,11 +56,8 @@ void Ruler::paintEvent(QPaintEvent*) QPainter p(this); p.setRenderHint(QPainter::Antialiasing); - std::pair spacing = - calculate_tick_spacing(p, view_.scale(), view_.offset()); - - double tick_period = spacing.first; - unsigned int prefix = spacing.second; + const double tick_period = view_.tick_period(); + const unsigned int prefix = view_.tick_prefix(); const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, AlignLeft | AlignTop, "8").height(); @@ -137,41 +133,5 @@ void Ruler::hover_point_changed() update(); } -std::pair Ruler::calculate_tick_spacing( - QPainter& p, double scale, double offset) -{ - const double SpacingIncrement = 32.0f; - const double MinValueSpacing = 32.0f; - - double min_width = SpacingIncrement, typical_width; - - double tick_period; - unsigned int prefix; - - 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)); - - prefix = (order - pv::util::FirstSIPrefixPower) / 3; - - typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, pv::util::format_time(offset, - prefix)).width() + MinValueSpacing; - - min_width += SpacingIncrement; - - } while(typical_width > tick_period / scale); - - return std::make_pair(tick_period, prefix); -} - } // namespace view } // namespace pv diff --git a/pv/view/ruler.hpp b/pv/view/ruler.hpp index 438b862c..073c86c9 100644 --- a/pv/view/ruler.hpp +++ b/pv/view/ruler.hpp @@ -35,25 +35,12 @@ class Ruler : public MarginWidget private: static const int RulerHeight; static const int MinorTickSubdivision; - static const int ScaleUnits[3]; static const int HoverArrowSize; public: Ruler(View &parent); - /** - * Find a tick spacing and number formatting that does not cause - * the values to collide. - * @param p A QPainter used to determine the needed space for the values. - * @param scale A pv::view::View's scale. - * @param offset A pv::view::View's offset. - * - * @return The tick period to use in 'first' and the prefix in 'second'. - */ - static std::pair calculate_tick_spacing( - QPainter& p, double scale, double offset); - public: QSize sizeHint() const; diff --git a/pv/view/timemarker.hpp b/pv/view/timemarker.hpp index 0103fb04..1c0703a4 100644 --- a/pv/view/timemarker.hpp +++ b/pv/view/timemarker.hpp @@ -86,10 +86,8 @@ public: * Paints the marker's label to the ruler. * @param p The painter to draw with. * @param rect The rectangle of the ruler client area. - * @param prefix The SI prefix to paint time value with. */ - virtual void paint_label(QPainter &p, const QRect &rect, - unsigned int prefix) = 0; + virtual void paint_label(QPainter &p, const QRect &rect) = 0; pv::widgets::Popup* create_popup(QWidget *parent); diff --git a/pv/view/view.cpp b/pv/view/view.cpp index a5114027..fce5b18c 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 @@ -47,10 +51,14 @@ #include "pv/session.hpp" #include "pv/data/logic.hpp" #include "pv/data/logicsnapshot.hpp" +#include "pv/util.hpp" using boost::shared_lock; using boost::shared_mutex; + using pv::data::SignalData; +using pv::util::format_time; + using std::back_inserter; using std::deque; using std::dynamic_pointer_cast; @@ -75,6 +83,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,6 +100,8 @@ 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), hover_point_(-1, -1) @@ -147,6 +159,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() @@ -199,6 +214,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); @@ -256,6 +281,8 @@ void View::set_scale_offset(double scale, double offset) scale_ = scale; offset_ = offset; + calculate_tick_spacing(); + update_scroll(); ruler_->update(); cursorheader_->update(); @@ -379,6 +406,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_); diff --git a/pv/view/view.hpp b/pv/view/view.hpp index e763da7e..4561cec6 100644 --- a/pv/view/view.hpp +++ b/pv/view/view.hpp @@ -63,6 +63,8 @@ private: static const int MaxScrollValue; + static const int ScaleUnits[3]; + public: static const QColor CursorAreaColour; @@ -100,6 +102,16 @@ public: double offset() const; int owner_visual_v_offset() const; + /** + * Returns the SI prefix to apply to the graticule time markings. + */ + unsigned int tick_prefix() const; + + /** + * Returns period of the graticule time markings. + */ + double tick_period() const; + /** * Returns the number of nested parents that this row item owner has. */ @@ -175,6 +187,12 @@ private: */ void set_zoom(double scale, int offset); + /** + * Find a tick spacing and number formatting that does not cause + * the values to collide. + */ + void calculate_tick_spacing(); + void update_scroll(); void update_layout(); @@ -252,6 +270,9 @@ private: int v_offset_; bool updating_scroll_; + double tick_period_; + unsigned int tick_prefix_; + bool show_cursors_; CursorPair cursors_; -- 2.30.2