]> sigrok.org Git - pulseview.git/commitdiff
Ruler: Moved calculate_tick_spacing into View
authorJoel Holdsworth <redacted>
Sun, 30 Nov 2014 12:33:18 +0000 (12:33 +0000)
committerJoel Holdsworth <redacted>
Wed, 3 Dec 2014 22:57:22 +0000 (22:57 +0000)
pv/view/cursor.cpp
pv/view/cursor.hpp
pv/view/cursorheader.cpp
pv/view/cursorpair.cpp
pv/view/cursorpair.hpp
pv/view/ruler.cpp
pv/view/ruler.hpp
pv/view/timemarker.hpp
pv/view/view.cpp
pv/view/view.hpp

index 03df054304f698132120674363f30d0753f5dde9..071967998eac0047d894bca3e8edf712af736878 100644 (file)
@@ -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<Cursor> 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));
 
index 8679a2866c3b986e33532b71a660abc651dba031..5df0ca2c3e4b34e176717a1175c0f6febdcec560 100644 (file)
@@ -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);
index 3fa0b0c58793410cb579bba9136b0fe0e934d841..3e2944e09269304a823db91b49fe6ecaef06f2da 100644 (file)
@@ -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);
        }
 }
 
index 0fb0d8d19ac681d1f1a44ec642730c769863528d..8aba0abd1274a7fc778d89a70d8df06fe67347a3 100644 (file)
@@ -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,
index dd37b0edf72ed6250cfdce8f1f9d3224028d4f26..84737d21693ffc048e13db86f0abddb8c83f404f 100644 (file)
@@ -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);
 
index 56651169afee06f96813d2625475e0d717add254..ee521f0e82a1203438d8a7420ec2336baec89af4 100644 (file)
@@ -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<double, unsigned int> 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<double, unsigned int> 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
index 438b862c53440c12d41e3f8fce33c76d6e98c05a..073c86c9e600533f66ae3389f99a7e29660ee8ec 100644 (file)
@@ -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<double, unsigned int> calculate_tick_spacing(
-               QPainter& p, double scale, double offset);
-
 public:
        QSize sizeHint() const;
 
index 0103fb041dfbdbede975ee4753de759c5d89546b..1c0703a43adf2fc2a409fcd3a1a72692591cdebd 100644 (file)
@@ -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);
 
index a5114027713c0ffa63aab9f754d4855cc9815230..fce5b18c2fc487b52a3cb365b47e2d4a9f76c65c 100644 (file)
 #include <libsigrokdecode/libsigrokdecode.h>
 #endif
 
+#include <extdef.h>
+
 #include <cassert>
 #include <climits>
 #include <cmath>
 #include <mutex>
 #include <unordered_set>
 
+#include <QApplication>
 #include <QEvent>
+#include <QFontMetrics>
 #include <QMouseEvent>
 #include <QScrollBar>
 
 #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_);
index e763da7e398a9b563b8fc5927088ad3ed391a2aa..4561cec661f95c546dd979129460f2b089d74249 100644 (file)
@@ -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_;