Moved Signal and LogicSignal into pv::view
authorJoel Holdsworth <joel@airwebreathe.org.uk>
Sat, 3 Nov 2012 09:18:16 +0000 (09:18 +0000)
committerJoel Holdsworth <joel@airwebreathe.org.uk>
Sat, 3 Nov 2012 09:50:34 +0000 (09:50 +0000)
14 files changed:
CMakeLists.txt
pv/logicsignal.cpp [deleted file]
pv/logicsignal.h [deleted file]
pv/signal.cpp [deleted file]
pv/signal.h [deleted file]
pv/sigsession.cpp
pv/sigsession.h
pv/view/header.cpp
pv/view/header.h
pv/view/logicsignal.cpp [new file with mode: 0644]
pv/view/logicsignal.h [new file with mode: 0644]
pv/view/signal.cpp [new file with mode: 0644]
pv/view/signal.h [new file with mode: 0644]
pv/view/viewport.cpp

index 1513d6dd1f14da578c66561859142628b6ed85ce..812176ec6e8b52d17e1729c23d8e9beadbd82e77 100644 (file)
@@ -84,15 +84,15 @@ set(pulseview_SOURCES
        pv/datasnapshot.cpp
        pv/logicdata.cpp
        pv/logicdatasnapshot.cpp
        pv/datasnapshot.cpp
        pv/logicdata.cpp
        pv/logicdatasnapshot.cpp
-       pv/logicsignal.cpp
        pv/mainwindow.cpp
        pv/samplingbar.cpp
        pv/signaldata.cpp
        pv/sigsession.cpp
        pv/mainwindow.cpp
        pv/samplingbar.cpp
        pv/signaldata.cpp
        pv/sigsession.cpp
-       pv/signal.cpp
        pv/view/cursor.cpp
        pv/view/header.cpp
        pv/view/cursor.cpp
        pv/view/header.cpp
+       pv/view/logicsignal.cpp
        pv/view/ruler.cpp
        pv/view/ruler.cpp
+       pv/view/signal.cpp
        pv/view/timemarker.cpp
        pv/view/view.cpp
        pv/view/viewport.cpp
        pv/view/timemarker.cpp
        pv/view/view.cpp
        pv/view/viewport.cpp
diff --git a/pv/logicsignal.cpp b/pv/logicsignal.cpp
deleted file mode 100644 (file)
index 0c1933d..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * 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 <extdef.h>
-
-#include <math.h>
-
-#include "logicdata.h"
-#include "logicdatasnapshot.h"
-#include "logicsignal.h"
-
-using namespace boost;
-using namespace std;
-
-namespace pv {
-
-const float LogicSignal::Margin = 10.0f;
-const float LogicSignal::Oversampling = 2.0f;
-
-const QColor LogicSignal::EdgeColour(0x80, 0x80, 0x80);
-const QColor LogicSignal::HighColour(0x00, 0xC0, 0x00);
-const QColor LogicSignal::LowColour(0xC0, 0x00, 0x00);
-
-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<LogicData> data,
-       int probe_index) :
-       Signal(name),
-       _probe_index(probe_index),
-       _data(data)
-{
-       assert(_probe_index >= 0);
-       _colour = LogicSignalColours[
-               _probe_index % countof(LogicSignalColours)];
-}
-
-void LogicSignal::paint(QPainter &p, const QRect &rect, double scale,
-       double offset)
-{
-       QLineF *line;
-
-       vector< pair<int64_t, bool> > edges;
-
-       assert(scale > 0);
-       assert(_data);
-
-       const float high_offset = rect.top() + Margin + 0.5f;
-       const float low_offset = rect.bottom() - Margin + 0.5f;
-
-       const deque< shared_ptr<LogicDataSnapshot> > &snapshots =
-               _data->get_snapshots();
-       if(snapshots.empty())
-               return;
-
-       const shared_ptr<LogicDataSnapshot> &snapshot = snapshots.front();
-
-       const double pixels_offset = offset / scale;
-       const double samplerate = _data->get_samplerate();
-       const double start_time = _data->get_start_time();
-       const int64_t last_sample = snapshot->get_sample_count() - 1;
-       const double samples_per_pixel = samplerate * scale;
-       const double start = samplerate * (offset - start_time);
-       const double end = start + samples_per_pixel * rect.width();
-
-       snapshot->get_subsampled_edges(edges,
-               min(max((int64_t)floor(start), (int64_t)0), last_sample),
-               min(max((int64_t)ceil(end), (int64_t)0), last_sample),
-               samples_per_pixel / Oversampling, _probe_index);
-       assert(edges.size() >= 2);
-
-       // Paint the edges
-       const unsigned int edge_count = edges.size() - 2;
-       QLineF *const edge_lines = new QLineF[edge_count];
-       line = edge_lines;
-
-       for(vector<LogicDataSnapshot::EdgePair>::const_iterator i =
-                       edges.begin() + 1;
-               i != edges.end() - 1; i++) {
-               const float x = ((*i).first / samples_per_pixel -
-                       pixels_offset) + rect.left();
-               *line++ = QLineF(x, high_offset, x, low_offset);
-       }
-
-       p.setPen(EdgeColour);
-       p.drawLines(edge_lines, edge_count);
-       delete[] edge_lines;
-
-       // Paint the caps
-       const unsigned int max_cap_line_count = (edges.size() - 1);
-       QLineF *const cap_lines = new QLineF[max_cap_line_count];
-
-       p.setPen(HighColour);
-       paint_caps(p, cap_lines, edges, true, samples_per_pixel,
-               pixels_offset, rect.left(), high_offset);
-       p.setPen(LowColour);
-       paint_caps(p, cap_lines, edges, false, samples_per_pixel,
-               pixels_offset, rect.left(), low_offset);
-
-       delete[] cap_lines;
-}
-
-void LogicSignal::paint_caps(QPainter &p, QLineF *const lines,
-       vector< pair<int64_t, bool> > &edges, bool level,
-       double samples_per_pixel, double pixels_offset, float x_offset,
-       float y_offset)
-{
-       QLineF *line = lines;
-
-       for(vector<LogicDataSnapshot::EdgePair>::const_iterator i = edges.begin();
-           i != (edges.end() - 1); i++)
-               if((*i).second == level) {
-                       *line++ = QLineF(
-                               ((*i).first / samples_per_pixel -
-                                       pixels_offset) + x_offset, y_offset,
-                               ((*(i+1)).first / samples_per_pixel -
-                                       pixels_offset) + x_offset, y_offset);
-               }
-
-       p.drawLines(lines, line - lines);
-}
-
-int LogicSignal::get_nominal_offset(const QRect &rect) const
-{
-       return rect.bottom() - Margin;
-}
-
-} // namespace pv
diff --git a/pv/logicsignal.h b/pv/logicsignal.h
deleted file mode 100644 (file)
index b1ef777..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * 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 PULSEVIEW_PV_LOGICSIGNAL_H
-#define PULSEVIEW_PV_LOGICSIGNAL_H
-
-#include "signal.h"
-
-#include <boost/shared_ptr.hpp>
-
-namespace pv {
-
-class LogicData;
-
-class LogicSignal : public Signal
-{
-private:
-       static const float Margin;
-       static const float Oversampling;
-
-       static const QColor EdgeColour;
-       static const QColor HighColour;
-       static const QColor LowColour;
-
-       static const QColor LogicSignalColours[10];
-
-public:
-       LogicSignal(QString name,
-               boost::shared_ptr<LogicData> data,
-               int probe_index);
-
-       /**
-        * Paints the signal with a QPainter
-        * @param p the QPainter to paint into.
-        * @param rect the rectangular area to draw the trace into.
-        * @param scale the scale in seconds per pixel.
-        * @param offset the time to show at the left hand edge of
-        *   the view in seconds.
-        **/
-       void paint(QPainter &p, const QRect &rect, double scale, double offset);
-
-private:
-
-       void paint_caps(QPainter &p, QLineF *const lines,
-               std::vector< std::pair<int64_t, bool> > &edges,
-               bool level, double samples_per_pixel, double pixels_offset,
-               float x_offset, float y_offset);
-
-       /**
-        * 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<LogicData> _data;
-};
-
-} // namespace pv
-
-#endif // PULSEVIEW_PV_LOGICSIGNAL_H
diff --git a/pv/signal.cpp b/pv/signal.cpp
deleted file mode 100644 (file)
index 04c5792..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * 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 <extdef.h>
-
-#include "signal.h"
-#include "view/view.h"
-
-namespace pv {
-
-const int Signal::LabelHitPadding = 2;
-
-Signal::Signal(QString name) :
-       _name(name)
-{
-}
-
-QString Signal::get_name() const
-{
-       return _name;
-}
-
-void Signal::set_name(QString name)
-{
-       _name = name;
-}
-
-QColor Signal::get_colour() const
-{
-       return _colour;
-}
-
-void Signal::set_colour(QColor colour)
-{
-       _colour = colour;
-}
-
-void Signal::paint_label(QPainter &p, const QRect &rect, bool hover)
-{
-       p.setBrush(_colour);
-
-       const QColor colour = get_colour();
-       const float nominal_offset = get_nominal_offset(rect);
-
-       compute_text_size(p);
-       const QRectF label_rect = get_label_rect(rect);
-
-       // Paint the label
-       const QPointF points[] = {
-               label_rect.topLeft(),
-               label_rect.topRight(),
-               QPointF(rect.right(), nominal_offset),
-               label_rect.bottomRight(),
-               label_rect.bottomLeft()
-       };
-
-       const QPointF highlight_points[] = {
-               QPointF(label_rect.left() + 1, label_rect.top() + 1),
-               QPointF(label_rect.right(), label_rect.top() + 1),
-               QPointF(rect.right() - 1, nominal_offset),
-               QPointF(label_rect.right(), label_rect.bottom() - 1),
-               QPointF(label_rect.left() + 1, label_rect.bottom() - 1)
-       };
-
-       p.setPen(Qt::transparent);
-       p.setBrush(hover ? colour.lighter() : colour);
-       p.drawPolygon(points, countof(points));
-
-       p.setPen(colour.lighter());
-       p.setBrush(Qt::transparent);
-       p.drawPolygon(highlight_points, countof(highlight_points));
-
-       p.setPen(colour.darker());
-       p.setBrush(Qt::transparent);
-       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, _name);
-}
-
-bool Signal::pt_in_label_rect(const QRect &rect, const QPoint &point)
-{
-       const QRectF label = get_label_rect(rect);
-       return QRectF(
-               QPointF(label.left() - LabelHitPadding,
-                       label.top() - LabelHitPadding),
-               QPointF(rect.right(),
-                       label.bottom() + LabelHitPadding)
-               ).contains(point);
-}
-
-void Signal::compute_text_size(QPainter &p)
-{
-       _text_size = p.boundingRect(QRectF(), 0, _name).size();
-}
-
-QRectF Signal::get_label_rect(const QRect &rect)
-{
-       using pv::view::View;
-
-       const float nominal_offset = get_nominal_offset(rect) + 0.5;
-       const QSizeF label_size(
-               _text_size.width() + View::LabelPadding.width() * 2,
-               _text_size.height() + View::LabelPadding.height() * 2);
-       const float label_arrow_length = label_size.height() / 2;
-       return QRectF(
-               rect.right() - label_arrow_length -
-                       label_size.width() - 0.5,
-               nominal_offset - label_size.height() / 2,
-               label_size.width(), label_size.height());
-}
-
-} // namespace pv
diff --git a/pv/signal.h b/pv/signal.h
deleted file mode 100644 (file)
index 2afe952..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * 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 PULSEVIEW_PV_SIGNAL_H
-#define PULSEVIEW_PV_SIGNAL_H
-
-#include <boost/shared_ptr.hpp>
-
-#include <QColor>
-#include <QPainter>
-#include <QRect>
-#include <QString>
-
-#include <stdint.h>
-
-namespace pv {
-
-class SignalData;
-
-class Signal
-{
-private:
-       static const int LabelHitPadding;
-
-protected:
-       Signal(QString name);
-
-public:
-       /**
-        * Gets the name of this signal.
-        */
-       QString get_name() const;
-
-       /**
-        * Sets the name of the signal.
-        */
-       void set_name(QString name);
-
-       /**
-        * Get the colour of the signal.
-        */
-       QColor get_colour() const;
-
-       /**
-        * Set the colour of the signal.
-        */
-       void set_colour(QColor colour);
-
-       /**
-        * Paints the signal with a QPainter
-        * @param p the QPainter to paint into.
-        * @param rect the rectangular area to draw the trace into.
-        * @param scale the scale in seconds per pixel.
-        * @param offset the time to show at the left hand edge of
-        *   the view in seconds.
-        **/
-       virtual void paint(QPainter &p, 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.
-        * @param hover true if the label is being hovered over by the mouse.
-        */
-       virtual void paint_label(QPainter &p, const QRect &rect,
-               bool hover);
-
-       /**
-        * Determines if a point is in the header label rect.
-        * @param rect the rectangular area to draw the label into.
-        * @param point the point to test.
-        */
-       bool pt_in_label_rect(const QRect &rect, const QPoint &point);
-
-private:
-
-       /**
-        * Computes an caches the size of the label text.
-        */
-       void compute_text_size(QPainter &p);
-
-       /**
-        * Computes the outline rectangle of a label.
-        * @param p the QPainter to lay out text with.
-        * @param rect The rectangle of the signal header.
-        * @return Returns the rectangle of the signal label.
-        */
-       QRectF get_label_rect(const QRect &rect);
-
-protected:
-       /**
-        * 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;
-       QColor _colour;
-
-       QSizeF _text_size;
-};
-
-} // namespace pv
-
-#endif // PULSEVIEW_PV_SIGNAL_H
index 40c46f04e57278993cba2ec01cfa486a5feb398f..81ccca720a0b38ca7d5d0a2b58b926f8e91c51ed 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "logicdata.h"
 #include "logicdatasnapshot.h"
 
 #include "logicdata.h"
 #include "logicdatasnapshot.h"
-#include "logicsignal.h"
+#include "view/logicsignal.h"
 
 #include <QDebug>
 
 
 #include <QDebug>
 
@@ -94,7 +94,7 @@ void SigSession::start_capture(struct sr_dev_inst *sdi,
        sr_session_destroy();
 }
 
        sr_session_destroy();
 }
 
-vector< shared_ptr<Signal> >& SigSession::get_signals()
+vector< shared_ptr<view::Signal> >& SigSession::get_signals()
 {
        return _signals;
 }
 {
        return _signals;
 }
@@ -107,6 +107,8 @@ boost::shared_ptr<LogicData> SigSession::get_data()
 void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
        struct sr_datafeed_packet *packet)
 {
 void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
        struct sr_datafeed_packet *packet)
 {
+       using view::LogicSignal;
+
        assert(sdi);
        assert(packet);
 
        assert(sdi);
        assert(packet);
 
@@ -136,7 +138,7 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
                                                sdi->probes, i);
                                if(probe->enabled)
                                {
                                                sdi->probes, i);
                                if(probe->enabled)
                                {
-                                       boost::shared_ptr<LogicSignal> signal(
+                                       shared_ptr<LogicSignal> signal(
                                                new LogicSignal(probe->name,
                                                        _logic_data,
                                                        probe->index));
                                                new LogicSignal(probe->name,
                                                        _logic_data,
                                                        probe->index));
index b6e5a56842c5c79def1356532001823e3eb3cd69..29929a9dde63d1b1bbc4520885d28cc3e719370e 100644 (file)
@@ -36,7 +36,10 @@ namespace pv {
 
 class LogicData;
 class LogicDataSnapshot;
 
 class LogicData;
 class LogicDataSnapshot;
+
+namespace view {
 class Signal;
 class Signal;
+}
 
 class SigSession : public QObject
 {
 
 class SigSession : public QObject
 {
@@ -52,7 +55,7 @@ public:
        void start_capture(struct sr_dev_inst* sdi, uint64_t record_length,
                uint64_t sample_rate);
 
        void start_capture(struct sr_dev_inst* sdi, uint64_t record_length,
                uint64_t sample_rate);
 
-       std::vector< boost::shared_ptr<Signal> >&
+       std::vector< boost::shared_ptr<view::Signal> >&
                get_signals();
 
        boost::shared_ptr<LogicData> get_data();
                get_signals();
 
        boost::shared_ptr<LogicData> get_data();
@@ -65,7 +68,7 @@ private:
                struct sr_datafeed_packet *packet);
 
 private:
                struct sr_datafeed_packet *packet);
 
 private:
-       std::vector< boost::shared_ptr<Signal> > _signals;
+       std::vector< boost::shared_ptr<view::Signal> > _signals;
        boost::shared_ptr<LogicData> _logic_data;
        boost::shared_ptr<LogicDataSnapshot> _cur_logic_snapshot;
 
        boost::shared_ptr<LogicData> _logic_data;
        boost::shared_ptr<LogicDataSnapshot> _cur_logic_snapshot;
 
index 284bb37284cfe7e1a49ce6b11d8662f28d387df8..2f02e7744782e330107c2484bd116536d0e7f506 100644 (file)
@@ -21,7 +21,7 @@
 #include "header.h"
 #include "view.h"
 
 #include "header.h"
 #include "view.h"
 
-#include "../signal.h"
+#include "signal.h"
 #include "../sigsession.h"
 
 #include <assert.h>
 #include "../sigsession.h"
 
 #include <assert.h>
@@ -126,7 +126,7 @@ void Header::contextMenuEvent(QContextMenuEvent *event)
 
 void Header::on_action_set_name_triggered()
 {
 
 void Header::on_action_set_name_triggered()
 {
-       boost::shared_ptr<Signal> context_signal = _context_signal;
+       shared_ptr<view::Signal> context_signal = _context_signal;
        if(!context_signal)
                return;
 
        if(!context_signal)
                return;
 
@@ -139,7 +139,7 @@ void Header::on_action_set_name_triggered()
 
 void Header::on_action_set_colour_triggered()
 {
 
 void Header::on_action_set_colour_triggered()
 {
-       boost::shared_ptr<Signal> context_signal = _context_signal;
+       shared_ptr<view::Signal> context_signal = _context_signal;
        if(!context_signal)
                return;
 
        if(!context_signal)
                return;
 
index b9cf8da3e76560bc21b0ded392ab85417458acc8..efc126e9aa36d305bba37a39dd11b10cd5ad10a3 100644 (file)
 #include <QWidget>
 
 namespace pv {
 #include <QWidget>
 
 namespace pv {
-
-class Signal;
-
 namespace view {
 
 namespace view {
 
+class Signal;
 class View;
 
 class Header : public QWidget
 class View;
 
 class Header : public QWidget
@@ -60,7 +58,7 @@ private:
 
        QPoint _mouse_point;
 
 
        QPoint _mouse_point;
 
-       boost::shared_ptr<pv::Signal> _context_signal;
+       boost::shared_ptr<Signal> _context_signal;
        QAction *_action_set_name;
        QAction *_action_set_colour;
 };
        QAction *_action_set_name;
        QAction *_action_set_colour;
 };
diff --git a/pv/view/logicsignal.cpp b/pv/view/logicsignal.cpp
new file mode 100644 (file)
index 0000000..cf3f3e5
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * 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 <extdef.h>
+
+#include <math.h>
+
+#include "logicsignal.h"
+#include "../logicdata.h"
+#include "../logicdatasnapshot.h"
+
+using namespace boost;
+using namespace std;
+
+namespace pv {
+namespace view {
+
+const float LogicSignal::Margin = 10.0f;
+const float LogicSignal::Oversampling = 2.0f;
+
+const QColor LogicSignal::EdgeColour(0x80, 0x80, 0x80);
+const QColor LogicSignal::HighColour(0x00, 0xC0, 0x00);
+const QColor LogicSignal::LowColour(0xC0, 0x00, 0x00);
+
+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<LogicData> data,
+       int probe_index) :
+       Signal(name),
+       _probe_index(probe_index),
+       _data(data)
+{
+       assert(_probe_index >= 0);
+       _colour = LogicSignalColours[
+               _probe_index % countof(LogicSignalColours)];
+}
+
+void LogicSignal::paint(QPainter &p, const QRect &rect, double scale,
+       double offset)
+{
+       QLineF *line;
+
+       vector< pair<int64_t, bool> > edges;
+
+       assert(scale > 0);
+       assert(_data);
+
+       const float high_offset = rect.top() + Margin + 0.5f;
+       const float low_offset = rect.bottom() - Margin + 0.5f;
+
+       const deque< shared_ptr<pv::LogicDataSnapshot> > &snapshots =
+               _data->get_snapshots();
+       if(snapshots.empty())
+               return;
+
+       const shared_ptr<pv::LogicDataSnapshot> &snapshot =
+               snapshots.front();
+
+       const double pixels_offset = offset / scale;
+       const double samplerate = _data->get_samplerate();
+       const double start_time = _data->get_start_time();
+       const int64_t last_sample = snapshot->get_sample_count() - 1;
+       const double samples_per_pixel = samplerate * scale;
+       const double start = samplerate * (offset - start_time);
+       const double end = start + samples_per_pixel * rect.width();
+
+       snapshot->get_subsampled_edges(edges,
+               min(max((int64_t)floor(start), (int64_t)0), last_sample),
+               min(max((int64_t)ceil(end), (int64_t)0), last_sample),
+               samples_per_pixel / Oversampling, _probe_index);
+       assert(edges.size() >= 2);
+
+       // Paint the edges
+       const unsigned int edge_count = edges.size() - 2;
+       QLineF *const edge_lines = new QLineF[edge_count];
+       line = edge_lines;
+
+       for(vector<pv::LogicDataSnapshot::EdgePair>::const_iterator i =
+                       edges.begin() + 1;
+               i != edges.end() - 1; i++) {
+               const float x = ((*i).first / samples_per_pixel -
+                       pixels_offset) + rect.left();
+               *line++ = QLineF(x, high_offset, x, low_offset);
+       }
+
+       p.setPen(EdgeColour);
+       p.drawLines(edge_lines, edge_count);
+       delete[] edge_lines;
+
+       // Paint the caps
+       const unsigned int max_cap_line_count = (edges.size() - 1);
+       QLineF *const cap_lines = new QLineF[max_cap_line_count];
+
+       p.setPen(HighColour);
+       paint_caps(p, cap_lines, edges, true, samples_per_pixel,
+               pixels_offset, rect.left(), high_offset);
+       p.setPen(LowColour);
+       paint_caps(p, cap_lines, edges, false, samples_per_pixel,
+               pixels_offset, rect.left(), low_offset);
+
+       delete[] cap_lines;
+}
+
+void LogicSignal::paint_caps(QPainter &p, QLineF *const lines,
+       vector< pair<int64_t, bool> > &edges, bool level,
+       double samples_per_pixel, double pixels_offset, float x_offset,
+       float y_offset)
+{
+       QLineF *line = lines;
+
+       for(vector<pv::LogicDataSnapshot::EdgePair>::const_iterator i =
+               edges.begin(); i != (edges.end() - 1); i++)
+               if((*i).second == level) {
+                       *line++ = QLineF(
+                               ((*i).first / samples_per_pixel -
+                                       pixels_offset) + x_offset, y_offset,
+                               ((*(i+1)).first / samples_per_pixel -
+                                       pixels_offset) + x_offset, y_offset);
+               }
+
+       p.drawLines(lines, line - lines);
+}
+
+int LogicSignal::get_nominal_offset(const QRect &rect) const
+{
+       return rect.bottom() - Margin;
+}
+
+} // namespace view
+} // namespace pv
diff --git a/pv/view/logicsignal.h b/pv/view/logicsignal.h
new file mode 100644 (file)
index 0000000..dd4a030
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * 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 PULSEVIEW_PV_LOGICSIGNAL_H
+#define PULSEVIEW_PV_LOGICSIGNAL_H
+
+#include "signal.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace pv {
+
+class LogicData;
+
+namespace view {
+
+class LogicSignal : public Signal
+{
+private:
+       static const float Margin;
+       static const float Oversampling;
+
+       static const QColor EdgeColour;
+       static const QColor HighColour;
+       static const QColor LowColour;
+
+       static const QColor LogicSignalColours[10];
+
+public:
+       LogicSignal(QString name,
+               boost::shared_ptr<pv::LogicData> data,
+               int probe_index);
+
+       /**
+        * Paints the signal with a QPainter
+        * @param p the QPainter to paint into.
+        * @param rect the rectangular area to draw the trace into.
+        * @param scale the scale in seconds per pixel.
+        * @param offset the time to show at the left hand edge of
+        *   the view in seconds.
+        **/
+       void paint(QPainter &p, const QRect &rect, double scale, double offset);
+
+private:
+
+       void paint_caps(QPainter &p, QLineF *const lines,
+               std::vector< std::pair<int64_t, bool> > &edges,
+               bool level, double samples_per_pixel, double pixels_offset,
+               float x_offset, float y_offset);
+
+       /**
+        * 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<pv::LogicData> _data;
+};
+
+} // namespace view
+} // namespace pv
+
+#endif // PULSEVIEW_PV_LOGICSIGNAL_H
diff --git a/pv/view/signal.cpp b/pv/view/signal.cpp
new file mode 100644 (file)
index 0000000..3e951b3
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * 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 <extdef.h>
+
+#include "signal.h"
+#include "view.h"
+
+namespace pv {
+namespace view {
+
+const int Signal::LabelHitPadding = 2;
+
+Signal::Signal(QString name) :
+       _name(name)
+{
+}
+
+QString Signal::get_name() const
+{
+       return _name;
+}
+
+void Signal::set_name(QString name)
+{
+       _name = name;
+}
+
+QColor Signal::get_colour() const
+{
+       return _colour;
+}
+
+void Signal::set_colour(QColor colour)
+{
+       _colour = colour;
+}
+
+void Signal::paint_label(QPainter &p, const QRect &rect, bool hover)
+{
+       p.setBrush(_colour);
+
+       const QColor colour = get_colour();
+       const float nominal_offset = get_nominal_offset(rect);
+
+       compute_text_size(p);
+       const QRectF label_rect = get_label_rect(rect);
+
+       // Paint the label
+       const QPointF points[] = {
+               label_rect.topLeft(),
+               label_rect.topRight(),
+               QPointF(rect.right(), nominal_offset),
+               label_rect.bottomRight(),
+               label_rect.bottomLeft()
+       };
+
+       const QPointF highlight_points[] = {
+               QPointF(label_rect.left() + 1, label_rect.top() + 1),
+               QPointF(label_rect.right(), label_rect.top() + 1),
+               QPointF(rect.right() - 1, nominal_offset),
+               QPointF(label_rect.right(), label_rect.bottom() - 1),
+               QPointF(label_rect.left() + 1, label_rect.bottom() - 1)
+       };
+
+       p.setPen(Qt::transparent);
+       p.setBrush(hover ? colour.lighter() : colour);
+       p.drawPolygon(points, countof(points));
+
+       p.setPen(colour.lighter());
+       p.setBrush(Qt::transparent);
+       p.drawPolygon(highlight_points, countof(highlight_points));
+
+       p.setPen(colour.darker());
+       p.setBrush(Qt::transparent);
+       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, _name);
+}
+
+bool Signal::pt_in_label_rect(const QRect &rect, const QPoint &point)
+{
+       const QRectF label = get_label_rect(rect);
+       return QRectF(
+               QPointF(label.left() - LabelHitPadding,
+                       label.top() - LabelHitPadding),
+               QPointF(rect.right(),
+                       label.bottom() + LabelHitPadding)
+               ).contains(point);
+}
+
+void Signal::compute_text_size(QPainter &p)
+{
+       _text_size = p.boundingRect(QRectF(), 0, _name).size();
+}
+
+QRectF Signal::get_label_rect(const QRect &rect)
+{
+       using pv::view::View;
+
+       const float nominal_offset = get_nominal_offset(rect) + 0.5;
+       const QSizeF label_size(
+               _text_size.width() + View::LabelPadding.width() * 2,
+               _text_size.height() + View::LabelPadding.height() * 2);
+       const float label_arrow_length = label_size.height() / 2;
+       return QRectF(
+               rect.right() - label_arrow_length -
+                       label_size.width() - 0.5,
+               nominal_offset - label_size.height() / 2,
+               label_size.width(), label_size.height());
+}
+
+} // namespace view
+} // namespace pv
diff --git a/pv/view/signal.h b/pv/view/signal.h
new file mode 100644 (file)
index 0000000..8adee96
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * 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 PULSEVIEW_PV_SIGNAL_H
+#define PULSEVIEW_PV_SIGNAL_H
+
+#include <boost/shared_ptr.hpp>
+
+#include <QColor>
+#include <QPainter>
+#include <QRect>
+#include <QString>
+
+#include <stdint.h>
+
+namespace pv {
+namespace view {
+
+class SignalData;
+
+class Signal
+{
+private:
+       static const int LabelHitPadding;
+
+protected:
+       Signal(QString name);
+
+public:
+       /**
+        * Gets the name of this signal.
+        */
+       QString get_name() const;
+
+       /**
+        * Sets the name of the signal.
+        */
+       void set_name(QString name);
+
+       /**
+        * Get the colour of the signal.
+        */
+       QColor get_colour() const;
+
+       /**
+        * Set the colour of the signal.
+        */
+       void set_colour(QColor colour);
+
+       /**
+        * Paints the signal with a QPainter
+        * @param p the QPainter to paint into.
+        * @param rect the rectangular area to draw the trace into.
+        * @param scale the scale in seconds per pixel.
+        * @param offset the time to show at the left hand edge of
+        *   the view in seconds.
+        **/
+       virtual void paint(QPainter &p, 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.
+        * @param hover true if the label is being hovered over by the mouse.
+        */
+       virtual void paint_label(QPainter &p, const QRect &rect,
+               bool hover);
+
+       /**
+        * Determines if a point is in the header label rect.
+        * @param rect the rectangular area to draw the label into.
+        * @param point the point to test.
+        */
+       bool pt_in_label_rect(const QRect &rect, const QPoint &point);
+
+private:
+
+       /**
+        * Computes an caches the size of the label text.
+        */
+       void compute_text_size(QPainter &p);
+
+       /**
+        * Computes the outline rectangle of a label.
+        * @param p the QPainter to lay out text with.
+        * @param rect The rectangle of the signal header.
+        * @return Returns the rectangle of the signal label.
+        */
+       QRectF get_label_rect(const QRect &rect);
+
+protected:
+       /**
+        * 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;
+       QColor _colour;
+
+       QSizeF _text_size;
+};
+
+} // namespace view
+} // namespace pv
+
+#endif // PULSEVIEW_PV_SIGNAL_H
index 2dcf9dc78f83ac740b3d3051d639ee8caa88c288..d9b0ff1b85af41c44aa32a4212974470e437dfe5 100644 (file)
@@ -21,8 +21,8 @@
 #include "view.h"
 #include "viewport.h"
 
 #include "view.h"
 #include "viewport.h"
 
+#include "signal.h"
 #include "../sigsession.h"
 #include "../sigsession.h"
-#include "../signal.h"
 
 #include <QMouseEvent>
 
 
 #include <QMouseEvent>