From: Joel Holdsworth Date: Sat, 23 Jun 2012 10:32:07 +0000 (+0100) Subject: Initial implementation of labels X-Git-Tag: pulseview-0.1.0~338 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=3e46726aaf1cfe749c8f3fced7b455cf01a03c86;p=pulseview.git Initial implementation of labels --- diff --git a/logicsignal.cpp b/logicsignal.cpp index 67d72bef..486c002d 100644 --- a/logicsignal.cpp +++ b/logicsignal.cpp @@ -24,6 +24,8 @@ #include +#include "extdef.h" + #include "logicdata.h" #include "logicdatasnapshot.h" #include "logicsignal.h" @@ -39,6 +41,19 @@ const float LogicSignal::EdgeColour[3] = {0.50f, 0.50f, 0.50f}; const float LogicSignal::HighColour[3] = {0.00f, 0.75f, 0.00f}; const float LogicSignal::LowColour[3] = {0.75f, 0.00f, 0.00f}; +const QColor LogicSignal::LogicSignalColours[10] = { + QColor(0x16, 0x19, 0x1A), // Black + QColor(0x8F, 0x52, 0x02), // Brown + QColor(0xCC, 0x00, 0x00), // Red + QColor(0xF5, 0x79, 0x00), // Orange + QColor(0xED, 0xD4, 0x00), // Yellow + QColor(0x73, 0xD2, 0x16), // Green + QColor(0x34, 0x65, 0xA4), // Blue + QColor(0x75, 0x50, 0x7B), // Violet + QColor(0x88, 0x8A, 0x85), // Grey + QColor(0xEE, 0xEE, 0xEC), // White +}; + LogicSignal::LogicSignal(QString name, shared_ptr data, int probe_index) : Signal(name), @@ -166,3 +181,13 @@ void LogicSignal::paint_lines(Point2F *points, int count) glDeleteBuffers(1, &vbo_id); } + +QColor LogicSignal::get_colour() const +{ + return LogicSignalColours[_probe_index % countof(LogicSignalColours)]; +} + +int LogicSignal::get_nominal_offset(const QRect &rect) const +{ + return rect.bottom() - Margin; +} diff --git a/logicsignal.h b/logicsignal.h index 60250b1e..8677afe3 100644 --- a/logicsignal.h +++ b/logicsignal.h @@ -39,6 +39,8 @@ private: static const float HighColour[3]; static const float LowColour[3]; + static const QColor LogicSignalColours[10]; + public: LogicSignal(QString name, boost::shared_ptr data, @@ -64,6 +66,17 @@ private: static void paint_lines(Point2F *points, int count); + /** + * Get the colour of the logic signal + */ + QColor get_colour() const; + + /** + * When painting into the rectangle, calculate the y + * offset of the zero point. + **/ + int get_nominal_offset(const QRect &rect) const; + private: int _probe_index; boost::shared_ptr _data; diff --git a/signal.cpp b/signal.cpp index d35be6bf..24d1e523 100644 --- a/signal.cpp +++ b/signal.cpp @@ -20,7 +20,9 @@ #include "signal.h" -#include +#include "extdef.h" + +const QSizeF Signal::LabelPadding(4, 0); Signal::Signal(QString name) : _name(name) @@ -31,3 +33,41 @@ QString Signal::get_name() const { return _name; } + +void Signal::paint_label(QPainter &p, const QRect &rect) +{ + p.setBrush(get_colour()); + + const QString text(_name); + const QColor colour = get_colour(); + + const QSizeF text_size = p.boundingRect( + QRectF(0, 0, rect.width(), 0), 0, text).size(); + + const float nominal_offset = get_nominal_offset(rect); + const QSizeF label_size( + text_size.width() + LabelPadding.width() * 2, + text_size.height() + LabelPadding.height() * 2); + const float label_arrow_length = label_size.height() / 2; + const QRectF label_rect( + rect.right() - label_arrow_length - label_size.width(), + nominal_offset - label_size.height() / 2, + label_size.width(), label_size.height()); + + // Paint the label + const QPointF points[] = { + label_rect.topLeft(), + label_rect.topRight(), + QPointF(rect.right(), nominal_offset), + label_rect.bottomRight(), + label_rect.bottomLeft() + }; + + p.setPen(Qt::black); + p.setBrush(colour); + p.drawPolygon(points, countof(points)); + + // Paint the text + p.setPen((colour.lightness() > 64) ? Qt::black : Qt::white); + p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, text); +} diff --git a/signal.h b/signal.h index ac23a3fa..edab476d 100644 --- a/signal.h +++ b/signal.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -30,6 +31,9 @@ class SignalData; class Signal { +private: + static const QSizeF LabelPadding; + protected: Signal(QString name); @@ -47,6 +51,26 @@ public: virtual void paint(QGLWidget &widget, const QRect &rect, double scale, double offset) = 0; + /** + * Paints the signal label into a QGLWidget. + * @param p the QPainter to paint into. + * @param rect the rectangular area to draw the label into. + */ + virtual void paint_label(QPainter &p, const QRect &rect); + +protected: + + /** + * Get the colour of the logic signal + */ + virtual QColor get_colour() const = 0; + + /** + * When painting into the rectangle, calculate the y + * offset of the zero point. + **/ + virtual int get_nominal_offset(const QRect &rect) const = 0; + protected: QString _name; }; diff --git a/sigview.cpp b/sigview.cpp index 4097ae5c..cf0983d9 100644 --- a/sigview.cpp +++ b/sigview.cpp @@ -31,6 +31,7 @@ using namespace boost; using namespace std; const int SigView::SignalHeight = 50; +const int SigView::LabelMarginWidth = 70; SigView::SigView(SigSession &session, QWidget *parent) : QGLWidget(parent), @@ -42,41 +43,70 @@ SigView::SigView(SigSession &session, QWidget *parent) : this, SLOT(dataUpdated())); setMouseTracking(true); + setAutoFillBackground(false); } void SigView::initializeGL() { - glDisable(GL_TEXTURE_2D); - glDisable(GL_DEPTH_TEST); - glDisable(GL_COLOR_MATERIAL); - glEnable(GL_BLEND); - glEnable(GL_POLYGON_SMOOTH); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClearColor(1.0, 1.0, 1.0, 0); } void SigView::resizeGL(int width, int height) { - glViewport(0, 0, (GLint)width, (GLint)height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, height, 0, -1, 1); - glMatrixMode(GL_MODELVIEW); + setupViewport(width, height); } -void SigView::paintGL() +void SigView::paintEvent(QPaintEvent *event) { - glClear(GL_COLOR_BUFFER_BIT); + int offset; - QRect rect(0, 0, width(), SignalHeight); const vector< shared_ptr > &sigs = _session.get_signals(); + + // Prepare for OpenGL rendering + makeCurrent(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + setupViewport(width(), height()); + + qglClearColor(Qt::white); + glClear(GL_COLOR_BUFFER_BIT); + + // Plot the signal + offset = 0; + BOOST_FOREACH(const shared_ptr s, sigs) + { + assert(s); + + const QRect signal_rect(LabelMarginWidth, offset, + width() - LabelMarginWidth, SignalHeight); + + s->paint(*this, signal_rect, _scale, _offset); + + offset += SignalHeight; + } + + // Prepare for QPainter rendering + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + // Paint the label + offset = 0; BOOST_FOREACH(const shared_ptr s, sigs) { assert(s); - s->paint(*this, rect, _scale, _offset); - rect.translate(0, SignalHeight); + + const QRect label_rect(0, offset, + LabelMarginWidth, SignalHeight); + s->paint_label(painter, label_rect); + + offset += SignalHeight; } + + painter.end(); } void SigView::dataUpdated() @@ -113,6 +143,14 @@ void SigView::mouseReleaseEvent(QMouseEvent *event) _offset = cursor_offset - _scale * (double)event->x(); - updateGL(); + update(); } +void SigView::setupViewport(int width, int height) +{ + glViewport(0, 0, (GLint)width, (GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, height, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); +} diff --git a/sigview.h b/sigview.h index c4ddc15b..e2d9543a 100644 --- a/sigview.h +++ b/sigview.h @@ -24,6 +24,7 @@ #include #include +class QPaintEvent; class SigSession; class SigView : public QGLWidget @@ -32,6 +33,7 @@ class SigView : public QGLWidget private: static const int SignalHeight; + static const int LabelMarginWidth; public: explicit SigView(SigSession &session, QWidget *parent = 0); @@ -42,13 +44,16 @@ protected: void resizeGL(int width, int height); - void paintGL(); + void paintEvent(QPaintEvent *event); private: void mouseMoveEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); +private: + void setupViewport(int width, int height); + private slots: void dataUpdated();