From: Joel Holdsworth Date: Sat, 3 Nov 2012 09:18:16 +0000 (+0000) Subject: Moved Signal and LogicSignal into pv::view X-Git-Tag: pulseview-0.1.0~221 X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=8d634081d8b0cc741dd34d8c646474ff6754aea8;hp=b3b57abc4fcfea1471529e9d116eaf11905f6639 Moved Signal and LogicSignal into pv::view --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 1513d6dd..812176ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,15 +84,15 @@ set(pulseview_SOURCES 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/signal.cpp pv/view/cursor.cpp pv/view/header.cpp + pv/view/logicsignal.cpp pv/view/ruler.cpp + pv/view/signal.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 index 0c1933d5..00000000 --- a/pv/logicsignal.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of the PulseView 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 - -#include - -#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 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 > 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 > &snapshots = - _data->get_snapshots(); - if(snapshots.empty()) - return; - - const shared_ptr &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::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 > &edges, bool level, - double samples_per_pixel, double pixels_offset, float x_offset, - float y_offset) -{ - QLineF *line = lines; - - for(vector::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 index b1ef777a..00000000 --- a/pv/logicsignal.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the PulseView 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 PULSEVIEW_PV_LOGICSIGNAL_H -#define PULSEVIEW_PV_LOGICSIGNAL_H - -#include "signal.h" - -#include - -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 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 > &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 _data; -}; - -} // namespace pv - -#endif // PULSEVIEW_PV_LOGICSIGNAL_H diff --git a/pv/signal.cpp b/pv/signal.cpp deleted file mode 100644 index 04c57923..00000000 --- a/pv/signal.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * This file is part of the PulseView 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 - -#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 index 2afe9528..00000000 --- a/pv/signal.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of the PulseView 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 PULSEVIEW_PV_SIGNAL_H -#define PULSEVIEW_PV_SIGNAL_H - -#include - -#include -#include -#include -#include - -#include - -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 diff --git a/pv/sigsession.cpp b/pv/sigsession.cpp index 40c46f04..81ccca72 100644 --- a/pv/sigsession.cpp +++ b/pv/sigsession.cpp @@ -22,7 +22,7 @@ #include "logicdata.h" #include "logicdatasnapshot.h" -#include "logicsignal.h" +#include "view/logicsignal.h" #include @@ -94,7 +94,7 @@ void SigSession::start_capture(struct sr_dev_inst *sdi, sr_session_destroy(); } -vector< shared_ptr >& SigSession::get_signals() +vector< shared_ptr >& SigSession::get_signals() { return _signals; } @@ -107,6 +107,8 @@ boost::shared_ptr SigSession::get_data() void SigSession::data_feed_in(const struct sr_dev_inst *sdi, struct sr_datafeed_packet *packet) { + using view::LogicSignal; + 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) { - boost::shared_ptr signal( + shared_ptr signal( new LogicSignal(probe->name, _logic_data, probe->index)); diff --git a/pv/sigsession.h b/pv/sigsession.h index b6e5a568..29929a9d 100644 --- a/pv/sigsession.h +++ b/pv/sigsession.h @@ -36,7 +36,10 @@ namespace pv { class LogicData; class LogicDataSnapshot; + +namespace view { class Signal; +} 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); - std::vector< boost::shared_ptr >& + std::vector< boost::shared_ptr >& get_signals(); boost::shared_ptr get_data(); @@ -65,7 +68,7 @@ private: struct sr_datafeed_packet *packet); private: - std::vector< boost::shared_ptr > _signals; + std::vector< boost::shared_ptr > _signals; boost::shared_ptr _logic_data; boost::shared_ptr _cur_logic_snapshot; diff --git a/pv/view/header.cpp b/pv/view/header.cpp index 284bb372..2f02e774 100644 --- a/pv/view/header.cpp +++ b/pv/view/header.cpp @@ -21,7 +21,7 @@ #include "header.h" #include "view.h" -#include "../signal.h" +#include "signal.h" #include "../sigsession.h" #include @@ -126,7 +126,7 @@ void Header::contextMenuEvent(QContextMenuEvent *event) void Header::on_action_set_name_triggered() { - boost::shared_ptr context_signal = _context_signal; + shared_ptr context_signal = _context_signal; if(!context_signal) return; @@ -139,7 +139,7 @@ void Header::on_action_set_name_triggered() void Header::on_action_set_colour_triggered() { - boost::shared_ptr context_signal = _context_signal; + shared_ptr context_signal = _context_signal; if(!context_signal) return; diff --git a/pv/view/header.h b/pv/view/header.h index b9cf8da3..efc126e9 100644 --- a/pv/view/header.h +++ b/pv/view/header.h @@ -26,11 +26,9 @@ #include namespace pv { - -class Signal; - namespace view { +class Signal; class View; class Header : public QWidget @@ -60,7 +58,7 @@ private: QPoint _mouse_point; - boost::shared_ptr _context_signal; + boost::shared_ptr _context_signal; QAction *_action_set_name; QAction *_action_set_colour; }; diff --git a/pv/view/logicsignal.cpp b/pv/view/logicsignal.cpp new file mode 100644 index 00000000..cf3f3e5a --- /dev/null +++ b/pv/view/logicsignal.cpp @@ -0,0 +1,158 @@ +/* + * This file is part of the PulseView 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 + +#include + +#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 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 > 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 > &snapshots = + _data->get_snapshots(); + if(snapshots.empty()) + return; + + const shared_ptr &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::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 > &edges, bool level, + double samples_per_pixel, double pixels_offset, float x_offset, + float y_offset) +{ + QLineF *line = lines; + + for(vector::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 index 00000000..dd4a030a --- /dev/null +++ b/pv/view/logicsignal.h @@ -0,0 +1,82 @@ +/* + * This file is part of the PulseView 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 PULSEVIEW_PV_LOGICSIGNAL_H +#define PULSEVIEW_PV_LOGICSIGNAL_H + +#include "signal.h" + +#include + +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 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 > &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 _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 index 00000000..3e951b33 --- /dev/null +++ b/pv/view/signal.cpp @@ -0,0 +1,133 @@ +/* + * This file is part of the PulseView 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 + +#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 index 00000000..8adee96f --- /dev/null +++ b/pv/view/signal.h @@ -0,0 +1,127 @@ +/* + * This file is part of the PulseView 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 PULSEVIEW_PV_SIGNAL_H +#define PULSEVIEW_PV_SIGNAL_H + +#include + +#include +#include +#include +#include + +#include + +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 diff --git a/pv/view/viewport.cpp b/pv/view/viewport.cpp index 2dcf9dc7..d9b0ff1b 100644 --- a/pv/view/viewport.cpp +++ b/pv/view/viewport.cpp @@ -21,8 +21,8 @@ #include "view.h" #include "viewport.h" +#include "signal.h" #include "../sigsession.h" -#include "../signal.h" #include