From: Joel Holdsworth Date: Sun, 9 Sep 2012 09:44:43 +0000 (+0100) Subject: Initial work moving ruler into the pv::view::Ruler widget X-Git-Tag: pulseview-0.1.0~305 X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=ccdd3ef548ce34f25c6c168598556a350831aa37 Initial work moving ruler into the pv::view::Ruler widget --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d5818694..3d26b236 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ set(pulseview_SOURCES sigsession.cpp signal.cpp pv/view/header.cpp + pv/view/ruler.cpp pv/view/view.cpp pv/view/viewport.cpp ) @@ -37,6 +38,7 @@ set(pulseview_HEADERS samplingbar.h sigsession.h pv/view/header.h + pv/view/ruler.h pv/view/view.h pv/view/viewport.h ) diff --git a/pv/view/ruler.cpp b/pv/view/ruler.cpp new file mode 100644 index 00000000..27db2f4e --- /dev/null +++ b/pv/view/ruler.cpp @@ -0,0 +1,118 @@ +/* + * This file is part of the sigrok project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ruler.h" +#include "view.h" + +#include "../../extdef.h" + +#include +#include + +#include +#include + +namespace pv { +namespace view { + +const int Ruler::MinorTickSubdivision = 4; +const int Ruler::ScaleUnits[3] = {1, 2, 5}; + +const QString Ruler::SIPrefixes[9] = + {"f", "p", "n", QChar(0x03BC), "m", "", "k", "M", "G"}; +const int Ruler::FirstSIPrefixPower = -15; + +Ruler::Ruler(View &parent) : + QWidget(&parent), + _view(parent) +{ +} + +void Ruler::paintEvent(QPaintEvent *event) +{ + QPainter p(this); + + const double MinSpacing = 80; + + const double min_period = _view.scale() * MinSpacing; + + const int order = (int)floorf(log10f(min_period)); + const double order_decimal = pow(10, order); + + int unit = 0; + double tick_period = 0.0f; + + do + { + tick_period = order_decimal * ScaleUnits[unit++]; + } while(tick_period < min_period && unit < countof(ScaleUnits)); + + const int prefix = (order - FirstSIPrefixPower) / 3; + assert(prefix >= 0); + assert(prefix < countof(SIPrefixes)); + + const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, "8").height(); + + // Draw the tick marks + p.setPen(Qt::black); + + const double minor_tick_period = tick_period / MinorTickSubdivision; + const double first_major_division = + floor(_view.offset() / tick_period); + const double first_minor_division = + ceil(_view.offset() / minor_tick_period); + const double t0 = first_major_division * tick_period; + + int division = (int)round(first_minor_division - + first_major_division * MinorTickSubdivision); + while(1) + { + const double t = t0 + division * minor_tick_period; + const double x = (t - _view.offset()) / _view.scale(); + + if(x >= width()) + break; + + if(division % MinorTickSubdivision == 0) + { + // Draw a major tick + QString s; + QTextStream ts(&s); + ts << (t / order_decimal) << SIPrefixes[prefix] << "s"; + p.drawText(x, 0, 0, text_height, Qt::AlignCenter | + Qt::AlignTop | Qt::TextDontClip, s); + p.drawLine(x, text_height, x, height()); + } + else + { + // Draw a minor tick + p.drawLine(x, (text_height + height()) / 2, + x, height()); + } + + division++; + } + + p.end(); +} + +} // namespace view +} // namespace pv diff --git a/pv/view/ruler.h b/pv/view/ruler.h new file mode 100644 index 00000000..7eccc8cd --- /dev/null +++ b/pv/view/ruler.h @@ -0,0 +1,55 @@ +/* + * This file is part of the sigrok project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PV_VIEW_RULER_H +#define PV_VIEW_RULER_H + +#include + +namespace pv { +namespace view { + +class View; + +class Ruler : public QWidget +{ + Q_OBJECT + +private: + static const int MinorTickSubdivision; + static const int ScaleUnits[3]; + + static const QString SIPrefixes[9]; + static const int FirstSIPrefixPower; + +public: + Ruler(View &parent); + +private: + void paintEvent(QPaintEvent *event); + +private: + View &_view; +}; + +} // namespace view +} // namespace pv + +#endif // PV_VIEW_HEADER_H diff --git a/pv/view/view.cpp b/pv/view/view.cpp index e319b4fc..4e0fed06 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -27,6 +27,7 @@ #include #include "header.h" +#include "ruler.h" #include "view.h" #include "viewport.h" @@ -52,6 +53,7 @@ View::View(SigSession &session, QWidget *parent) : QAbstractScrollArea(parent), _session(session), _viewport(new Viewport(*this)), + _ruler(new Ruler(*this)), _header(new Header(*this)), _data_length(0), _scale(1e-6), @@ -65,7 +67,7 @@ View::View(SigSession &session, QWidget *parent) : connect(&_session, SIGNAL(data_updated()), this, SLOT(data_updated())); - setViewportMargins(LabelMarginWidth, 0, 0, 0); + setViewportMargins(LabelMarginWidth, RulerHeight, 0, 0); setViewport(_viewport); } @@ -98,7 +100,9 @@ void View::set_scale_offset(double scale, double offset) { _scale = scale; _offset = offset; + update_scroll(); + _ruler->update(); _viewport->update(); } @@ -134,6 +138,8 @@ void View::zoom(double steps, int offset) _scale *= pow(3.0/2.0, -steps); _scale = max(min(_scale, MaxScale), MinScale); _offset = cursor_offset - _scale * offset; + + _ruler->update(); _viewport->update(); update_scroll(); } @@ -156,7 +162,9 @@ bool View::viewportEvent(QEvent *e) void View::resizeEvent(QResizeEvent *e) { - _header->setGeometry(0, RulerHeight, + _ruler->setGeometry(_viewport->x(), 0, + _viewport->width(), _viewport->y()); + _header->setGeometry(0, _viewport->y(), _viewport->x(), _viewport->height()); update_scroll(); } @@ -164,6 +172,7 @@ void View::resizeEvent(QResizeEvent *e) void View::h_scroll_value_changed(int value) { _offset = _scale * value; + _ruler->update(); _viewport->update(); } diff --git a/pv/view/view.h b/pv/view/view.h index ad607b5a..d7fc6356 100644 --- a/pv/view/view.h +++ b/pv/view/view.h @@ -31,6 +31,7 @@ namespace pv { namespace view { class Header; +class Ruler; class Viewport; class View : public QAbstractScrollArea { @@ -79,6 +80,7 @@ private: SigSession &_session; Viewport *_viewport; + Ruler *_ruler; Header *_header; uint64_t _data_length; diff --git a/pv/view/viewport.cpp b/pv/view/viewport.cpp index ee30965d..b437175f 100644 --- a/pv/view/viewport.cpp +++ b/pv/view/viewport.cpp @@ -24,12 +24,7 @@ #include "../../sigsession.h" #include "../../signal.h" -#include "../../extdef.h" - #include -#include - -#include #include @@ -39,13 +34,6 @@ using namespace std; namespace pv { namespace view { -const int Viewport::MinorTickSubdivision = 4; -const int Viewport::ScaleUnits[3] = {1, 2, 5}; - -const QString Viewport::SIPrefixes[9] = - {"f", "p", "n", QChar(0x03BC), "m", "", "k", "M", "G"}; -const int Viewport::FirstSIPrefixPower = -15; - Viewport::Viewport(View &parent) : QGLWidget(&parent), _view(parent) @@ -95,7 +83,7 @@ void Viewport::paintEvent(QPaintEvent *event) // Plot the signal glEnable(GL_SCISSOR_TEST); glScissor(0, 0, width(), height()); - offset = View::RulerHeight - _view.v_offset(); + offset = -_view.v_offset(); BOOST_FOREACH(const shared_ptr s, sigs) { assert(s); @@ -115,11 +103,6 @@ void Viewport::paintEvent(QPaintEvent *event) glPopMatrix(); QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - - // Paint the ruler - paint_ruler(painter); - painter.end(); } @@ -164,71 +147,5 @@ void Viewport::setup_viewport(int width, int height) glMatrixMode(GL_MODELVIEW); } -void Viewport::paint_ruler(QPainter &p) -{ - const double MinSpacing = 80; - - const double min_period = _view.scale() * MinSpacing; - - const int order = (int)floorf(log10f(min_period)); - const double order_decimal = pow(10, order); - - int unit = 0; - double tick_period = 0.0f; - - do - { - tick_period = order_decimal * ScaleUnits[unit++]; - } while(tick_period < min_period && unit < countof(ScaleUnits)); - - const int prefix = (order - FirstSIPrefixPower) / 3; - assert(prefix >= 0); - assert(prefix < countof(SIPrefixes)); - - const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignTop, "8").height(); - - // Draw the tick marks - p.setPen(Qt::black); - - const double minor_tick_period = tick_period / MinorTickSubdivision; - const double first_major_division = - floor(_view.offset() / tick_period); - const double first_minor_division = - ceil(_view.offset() / minor_tick_period); - const double t0 = first_major_division * tick_period; - - int division = (int)round(first_minor_division - - first_major_division * MinorTickSubdivision); - while(1) - { - const double t = t0 + division * minor_tick_period; - const double x = (t - _view.offset()) / _view.scale(); - - if(x >= width()) - break; - - if(division % MinorTickSubdivision == 0) - { - // Draw a major tick - QString s; - QTextStream ts(&s); - ts << (t / order_decimal) << SIPrefixes[prefix] << "s"; - p.drawText(x, 0, 0, text_height, Qt::AlignCenter | Qt::AlignTop | - Qt::TextDontClip, s); - p.drawLine(x, text_height, x, View::RulerHeight); - } - else - { - // Draw a minor tick - p.drawLine(x, - (text_height + View::RulerHeight) / 2, x, - View::RulerHeight); - } - - division++; - } -} - } // namespace view } // namespace pv diff --git a/pv/view/viewport.h b/pv/view/viewport.h index 690642c2..b79526ac 100644 --- a/pv/view/viewport.h +++ b/pv/view/viewport.h @@ -37,13 +37,6 @@ class Viewport : public QGLWidget { Q_OBJECT -private: - static const int MinorTickSubdivision; - static const int ScaleUnits[3]; - - static const QString SIPrefixes[9]; - static const int FirstSIPrefixPower; - public: explicit Viewport(View &parent); @@ -65,8 +58,6 @@ private: private: void setup_viewport(int width, int height); - void paint_ruler(QPainter &p); - private: View &_view;