2
0
forked from Ivasoft/DSView

v0.4 release

This commit is contained in:
DreamSourceLab
2014-09-24 18:43:42 +08:00
parent 5d7e3237b7
commit 9eb36b33b9
170 changed files with 10539 additions and 4321 deletions

View File

@@ -28,6 +28,7 @@
#include "analogsignal.h"
#include "pv/data/analog.h"
#include "pv/data/analogsnapshot.h"
#include "view.h"
using namespace boost;
using namespace std;
@@ -50,12 +51,13 @@ const QColor AnalogSignal::SignalColours[4] = {
const float AnalogSignal::EnvelopeThreshold = 256.0f;
AnalogSignal::AnalogSignal(QString name, boost::shared_ptr<data::Analog> data,
int probe_index, int order) :
Signal(name, probe_index, DS_ANALOG, order),
AnalogSignal::AnalogSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
boost::shared_ptr<data::Analog> data,
const sr_channel * const probe) :
Signal(dev_inst, probe, DS_ANALOG),
_data(data)
{
_colour = SignalColours[probe_index % countof(SignalColours)];
_colour = SignalColours[probe->index % countof(SignalColours)];
_scale = _signalHeight * 1.0f / 65536;
}
@@ -63,18 +65,9 @@ AnalogSignal::~AnalogSignal()
{
}
void AnalogSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
shared_ptr<pv::data::SignalData> AnalogSignal::data() const
{
(void)_dso_data;
(void)_logic_data;
(void)_group_data;
assert(_analog_data);
_data = _analog_data;
return _data;
}
void AnalogSignal::set_scale(float scale)
@@ -82,16 +75,18 @@ void AnalogSignal::set_scale(float scale)
_scale = scale;
}
void AnalogSignal::paint(QPainter &p, int y, int left, int right, double scale,
double offset)
void AnalogSignal::paint_mid(QPainter &p, int left, int right)
{
assert(scale > 0);
assert(_data);
assert(right >= left);
assert(_data);
assert(_view);
assert(right >= left);
//paint_axis(p, y, left, right);
const int y = get_y() + _signalHeight * 0.5;
const double scale = _view->scale();
assert(scale > 0);
const double offset = _view->offset();
const deque< boost::shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
const deque< shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
@@ -104,7 +99,7 @@ void AnalogSignal::paint(QPainter &p, int y, int left, int right, double scale,
return;
const double pixels_offset = offset / scale;
const double samplerate = _data->get_samplerate();
const double samplerate = _data->samplerate();
const double start_time = _data->get_start_time();
const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0);
const double samples_per_pixel = samplerate * scale;
@@ -210,19 +205,5 @@ const std::vector< std::pair<uint64_t, bool> > AnalogSignal::cur_edges() const
}
void AnalogSignal::set_decoder(pv::decoder::Decoder *decoder)
{
(void)decoder;
}
decoder::Decoder *AnalogSignal::get_decoder()
{
return NULL;
}
void AnalogSignal::del_decoder()
{
}
} // namespace view
} // namespace pv

View File

@@ -42,43 +42,31 @@ class AnalogSignal : public Signal
{
private:
static const QColor SignalColours[4];
static const float EnvelopeThreshold;
static const int NumSpanY = 5;
static const int NumMiniSpanY = 5;
static const int NumSpanX = 10;
public:
AnalogSignal(QString name,
boost::shared_ptr<pv::data::Analog> data, int probe_index, int order);
AnalogSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
boost::shared_ptr<pv::data::Analog> data,
const sr_channel * const probe);
virtual ~AnalogSignal();
boost::shared_ptr<pv::data::SignalData> data() const;
void set_scale(float scale);
/**
* Paints the signal with a QPainter
* @param p the QPainter to paint into.
* @param y the y-coordinate to draw the signal at.
* @param left the x-coordinate of the left edge of the signal.
* @param right the x-coordinate of the right edge of the signal.
* @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, int y, int left, int right, double scale,
double offset);
void paint_mid(QPainter &p, int left, int right);
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
void set_decoder(pv::decoder::Decoder *decoder);
pv::decoder::Decoder* get_decoder();
void del_decoder();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
private:
void paint_trace(QPainter &p,
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,

View File

@@ -0,0 +1,833 @@
/*
* 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
*/
extern "C" {
#include <libsigrokdecode/libsigrokdecode.h>
}
#include <extdef.h>
#include <boost/foreach.hpp>
#include <boost/functional/hash.hpp>
#include <QAction>
#include <QApplication>
#include <QComboBox>
#include <QFormLayout>
#include <QLabel>
#include <QMenu>
#include <QPushButton>
#include <QDialog>
#include <QDialogButtonBox>
#include <QScrollArea>
#include "decodetrace.h"
#include "../sigsession.h"
#include "../data/decoderstack.h"
#include "../data/decode/decoder.h"
#include "../data/logic.h"
#include "../data/logicsnapshot.h"
#include "../data/decode/annotation.h"
#include "../view/logicsignal.h"
#include "../view/view.h"
#include "../widgets/decodergroupbox.h"
#include "../widgets/decodermenu.h"
#include "../device/devinst.h"
using boost::dynamic_pointer_cast;
using boost::shared_ptr;
using std::list;
using std::max;
using std::map;
using std::min;
using std::vector;
namespace pv {
namespace view {
const QColor DecodeTrace::DecodeColours[4] = {
QColor(0xEF, 0x29, 0x29), // Red
QColor(0xFC, 0xE9, 0x4F), // Yellow
QColor(0x8A, 0xE2, 0x34), // Green
QColor(0x72, 0x9F, 0xCF) // Blue
};
const QColor DecodeTrace::ErrorBgColour = QColor(0xEF, 0x29, 0x29);
const QColor DecodeTrace::NoDecodeColour = QColor(0x88, 0x8A, 0x85);
const int DecodeTrace::ArrowSize = 4;
const double DecodeTrace::EndCapWidth = 5;
const int DecodeTrace::DrawPadding = 100;
const QColor DecodeTrace::Colours[16] = {
QColor(0xEF, 0x29, 0x29),
QColor(0xF6, 0x6A, 0x32),
QColor(0xFC, 0xAE, 0x3E),
QColor(0xFB, 0xCA, 0x47),
QColor(0xFC, 0xE9, 0x4F),
QColor(0xCD, 0xF0, 0x40),
QColor(0x8A, 0xE2, 0x34),
QColor(0x4E, 0xDC, 0x44),
QColor(0x55, 0xD7, 0x95),
QColor(0x64, 0xD1, 0xD2),
QColor(0x72, 0x9F, 0xCF),
QColor(0xD4, 0x76, 0xC4),
QColor(0x9D, 0x79, 0xB9),
QColor(0xAD, 0x7F, 0xA8),
QColor(0xC2, 0x62, 0x9B),
QColor(0xD7, 0x47, 0x6F)
};
const QColor DecodeTrace::OutlineColours[16] = {
QColor(0x77, 0x14, 0x14),
QColor(0x7B, 0x35, 0x19),
QColor(0x7E, 0x57, 0x1F),
QColor(0x7D, 0x65, 0x23),
QColor(0x7E, 0x74, 0x27),
QColor(0x66, 0x78, 0x20),
QColor(0x45, 0x71, 0x1A),
QColor(0x27, 0x6E, 0x22),
QColor(0x2A, 0x6B, 0x4A),
QColor(0x32, 0x68, 0x69),
QColor(0x39, 0x4F, 0x67),
QColor(0x6A, 0x3B, 0x62),
QColor(0x4E, 0x3C, 0x5C),
QColor(0x56, 0x3F, 0x54),
QColor(0x61, 0x31, 0x4D),
QColor(0x6B, 0x23, 0x37)
};
DecodeTrace::DecodeTrace(pv::SigSession &session,
boost::shared_ptr<pv::data::DecoderStack> decoder_stack, int index) :
Trace(QString::fromUtf8(
decoder_stack->stack().front()->decoder()->name), Trace::DS_DECODER),
_session(session),
_decoder_stack(decoder_stack),
_show_hide_mapper(this)
{
assert(_decoder_stack);
_colour = DecodeColours[index % countof(DecodeColours)];
connect(_decoder_stack.get(), SIGNAL(new_decode_data()),
this, SLOT(on_new_decode_data()));
connect(_decoder_stack.get(), SIGNAL(decode_done()),
this, SLOT(on_decode_done()));
connect(&_show_hide_mapper, SIGNAL(mapped(int)),
this, SLOT(on_show_hide_decoder(int)));
}
bool DecodeTrace::enabled() const
{
return true;
}
const boost::shared_ptr<pv::data::DecoderStack>& DecodeTrace::decoder() const
{
return _decoder_stack;
}
void DecodeTrace::set_view(pv::view::View *view)
{
assert(view);
Trace::set_view(view);
}
void DecodeTrace::paint_back(QPainter &p, int left, int right)
{
QPen pen(Signal::dsGray);
pen.setStyle(Qt::DotLine);
p.setPen(pen);
const double sigY = get_y() - (_signalHeight - _view->get_signalHeight())*0.5;
p.drawLine(left, sigY, right, sigY);
}
void DecodeTrace::paint_mid(QPainter &p, int left, int right)
{
using namespace pv::data::decode;
const double scale = _view->scale();
assert(scale > 0);
double samplerate = _decoder_stack->samplerate();
_cur_row_headings.clear();
// Show sample rate as 1Hz when it is unknown
if (samplerate == 0.0)
samplerate = 1.0;
const double pixels_offset = (_view->offset() -
_decoder_stack->get_start_time()) / scale;
const double samples_per_pixel = samplerate * scale;
const uint64_t start_sample = (uint64_t)max((left + pixels_offset) *
samples_per_pixel, 0.0);
const uint64_t end_sample = (uint64_t)max((right + pixels_offset) *
samples_per_pixel, 0.0);
const int annotation_height = _view->get_signalHeight();
assert(_decoder_stack);
const QString err = _decoder_stack->error_message();
if (!err.isEmpty())
{
//draw_unresolved_period(p, _view->get_signalHeight(), left, right,
// samples_per_pixel, pixels_offset);
draw_error(p, err, left, right);
return;
}
// Draw the hatching
if (draw_unresolved_period(p, _view->get_signalHeight(), left, right))
return;
// Iterate through the rows
assert(_view);
int y = get_y() - (_signalHeight - _view->get_signalHeight())*0.5;
assert(_decoder_stack);
const std::vector< std::pair<Row, bool> > rows(_decoder_stack->get_visible_rows());
for (size_t i = 0; i < rows.size(); i++)
{
const Row &row = rows[i].first;
const bool shown = rows[i].second;
if (!shown && _decoder_stack->has_annotations(row)) {
draw_unshown_row(p, y, _view->get_signalHeight(), left, right);
y += _view->get_signalHeight();
_cur_row_headings.push_back(row.title());
continue;
}
size_t base_colour = 0x13579BDF;
boost::hash_combine(base_colour, this);
boost::hash_combine(base_colour, row.decoder());
boost::hash_combine(base_colour, row.row());
base_colour >>= 16;
const uint64_t max_annotation =
_decoder_stack->get_max_annotation(row);
const double max_annWidth = max_annotation / samples_per_pixel;
if (max_annWidth > 5) {
vector<Annotation> annotations;
_decoder_stack->get_annotation_subset(annotations, row,
start_sample, end_sample);
if (!annotations.empty()) {
BOOST_FOREACH(const Annotation &a, annotations)
draw_annotation(a, p, get_text_colour(),
annotation_height, left, right,
samples_per_pixel, pixels_offset, y,
base_colour);
}
} else if (max_annWidth != 0){
draw_nodetail(p, annotation_height, left, right, y, base_colour);
}
if (max_annWidth != 0) {
y += _view->get_signalHeight();
_cur_row_headings.push_back(row.title());
}
}
}
void DecodeTrace::paint_fore(QPainter &p, int left, int right)
{
using namespace pv::data::decode;
(void)right;
const int row_height = _view->get_signalHeight();
for (size_t i = 0; i < _cur_row_headings.size(); i++)
{
const int y = (i + 0.5) * row_height + get_y() - _signalHeight * 0.5;
p.setPen(QPen(Qt::NoPen));
p.setBrush(QApplication::palette().brush(QPalette::WindowText));
if (i != 0)
{
const QPointF points[] = {
QPointF(left, y - ArrowSize),
QPointF(left + ArrowSize, y),
QPointF(left, y + ArrowSize)
};
p.drawPolygon(points, countof(points));
}
const QRect r(left + ArrowSize * 2, y - row_height / 2,
right - left, row_height);
const QString h(_cur_row_headings[i]);
const int f = Qt::AlignLeft | Qt::AlignVCenter |
Qt::TextDontClip;
// Draw the outline
QFont font=p.font();
font.setPointSize(DefaultFontSize);
p.setFont(font);
p.setPen(QApplication::palette().color(QPalette::Base));
for (int dx = -1; dx <= 1; dx++)
for (int dy = -1; dy <= 1; dy++)
if (dx != 0 && dy != 0)
p.drawText(r.translated(dx, dy), f, h);
// Draw the text
p.setPen(QApplication::palette().color(QPalette::WindowText));
p.drawText(r, f, h);
}
}
bool DecodeTrace::create_popup()
{
// Clear the layout
// Transfer the layout and the child widgets to a temporary widget
// which then goes out of scope destroying the layout and all the child
// widgets.
//if (_popup_form)
// QWidget().setLayout(_popup_form);
int ret = false;
QDialog popup;
QFormLayout popup_form;
popup.setLayout(&popup_form);
populate_popup_form(&popup, &popup_form);
if (QDialog::Accepted == popup.exec())
{
BOOST_FOREACH(shared_ptr<data::decode::Decoder> dec,
_decoder_stack->stack())
{
dec->commit_show();
if (dec->commit()) {
_decoder_stack->options_changed(true);
ret = true;
}
}
return ret;
}
else
return false;
}
void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
{
using pv::data::decode::Decoder;
assert(form);
assert(parent);
assert(_decoder_stack);
// Add the decoder options
_bindings.clear();
_probe_selectors.clear();
_decoder_forms.clear();
const list< shared_ptr<Decoder> >& stack = _decoder_stack->stack();
if (stack.empty())
{
QLabel *const l = new QLabel(
tr("<p><i>No decoders in the stack</i></p>"));
l->setAlignment(Qt::AlignCenter);
form->addRow(l);
}
else
{
list< shared_ptr<Decoder> >::const_iterator iter =
stack.begin();
for (int i = 0; i < (int)stack.size(); i++, iter++) {
shared_ptr<Decoder> dec(*iter);
create_decoder_form(i, dec, parent, form);
}
form->addRow(new QLabel(
tr("<i>* Required channels</i>"), parent));
}
// Add stacking button
pv::widgets::DecoderMenu *const decoder_menu =
new pv::widgets::DecoderMenu(parent);
connect(decoder_menu, SIGNAL(decoder_selected(srd_decoder*)),
this, SLOT(on_stack_decoder(srd_decoder*)));
connect(decoder_menu, SIGNAL(selected()),
parent, SLOT(accept()));
QPushButton *const stack_button =
new QPushButton(tr("Stack Decoder"), parent);
stack_button->setMenu(decoder_menu);
QHBoxLayout *stack_button_box = new QHBoxLayout;
stack_button_box->addWidget(stack_button, 0, Qt::AlignLeft);
form->addRow(stack_button_box);
// Add ButtonBox (OK/Cancel)
QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, parent);
connect(button_box, SIGNAL(accepted()), parent, SLOT(accept()));
connect(button_box, SIGNAL(rejected()), parent, SLOT(reject()));
QHBoxLayout *confirm_button_box = new QHBoxLayout;
confirm_button_box->addWidget(button_box, 0, Qt::AlignRight);
form->addRow(confirm_button_box);
}
void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a,
QPainter &p, QColor text_color, int h, int left, int right,
double samples_per_pixel, double pixels_offset, int y,
size_t base_colour) const
{
const double start = max(a.start_sample() / samples_per_pixel -
pixels_offset, (double)left);
const double end = min(a.end_sample() / samples_per_pixel -
pixels_offset, (double)right);
const size_t colour = (base_colour + a.format()) % countof(Colours);
const QColor &fill = Colours[colour];
const QColor &outline = OutlineColours[colour];
if (start > right + DrawPadding || end < left - DrawPadding)
return;
if (a.start_sample() == a.end_sample())
draw_instant(a, p, fill, outline, text_color, h,
start, y);
else
draw_range(a, p, fill, outline, text_color, h,
start, end, y);
}
void DecodeTrace::draw_nodetail(QPainter &p,
int h, int left, int right, int y,
size_t base_colour) const
{
const QRectF nodetail_rect(left, y - h/2 + 0.5, right - left, h);
const size_t colour = base_colour % countof(Colours);
const QColor &fill = Colours[colour];
p.setPen(Qt::white);
p.setBrush(fill);
p.drawRect(nodetail_rect);
p.drawText(nodetail_rect, Qt::AlignCenter | Qt::AlignVCenter, "Zoom in for more detials");
}
void DecodeTrace::draw_instant(const pv::data::decode::Annotation &a, QPainter &p,
QColor fill, QColor outline, QColor text_color, int h, double x, int y) const
{
const QString text = a.annotations().empty() ?
QString() : a.annotations().back();
const double w = min((double)p.boundingRect(QRectF(), 0, text).width(),
0.0) + h;
const QRectF rect(x - w / 2, y - h / 2, w, h);
p.setPen(outline);
p.setBrush(fill);
p.drawRoundedRect(rect, h / 2, h / 2);
p.setPen(text_color);
QFont font=p.font();
font.setPointSize(DefaultFontSize);
p.setFont(font);
p.drawText(rect, Qt::AlignCenter | Qt::AlignVCenter, text);
}
void DecodeTrace::draw_range(const pv::data::decode::Annotation &a, QPainter &p,
QColor fill, QColor outline, QColor text_color, int h, double start,
double end, int y) const
{
const double top = y + .5 - h / 2;
const double bottom = y + .5 + h / 2;
const vector<QString> annotations = a.annotations();
p.setPen(outline);
p.setBrush(fill);
// If the two ends are within 2 pixel, draw a vertical line
if (start + 2.0 > end)
{
p.drawLine(QPointF(start, top), QPointF(start, bottom));
return;
}
double cap_width = min((end - start) / 4, EndCapWidth);
QPointF pts[] = {
QPointF(start, y + .5f),
QPointF(start + cap_width, top),
QPointF(end - cap_width, top),
QPointF(end, y + .5f),
QPointF(end - cap_width, bottom),
QPointF(start + cap_width, bottom)
};
p.setPen(Qt::white);
p.drawConvexPolygon(pts, countof(pts));
if (annotations.empty())
return;
QRectF rect(start + cap_width, y - h / 2,
end - start - cap_width * 2, h);
if (rect.width() <= 4)
return;
p.setPen(text_color);
// Try to find an annotation that will fit
QString best_annotation;
int best_width = 0;
BOOST_FOREACH(const QString &a, annotations) {
const int w = p.boundingRect(QRectF(), 0, a).width();
if (w <= rect.width() && w > best_width)
best_annotation = a, best_width = w;
}
if (best_annotation.isEmpty())
best_annotation = annotations.back();
// If not ellide the last in the list
QFont font=p.font();
font.setPointSize(DefaultFontSize);
p.setFont(font);
p.drawText(rect, Qt::AlignCenter, p.fontMetrics().elidedText(
best_annotation, Qt::ElideRight, rect.width()));
}
void DecodeTrace::draw_error(QPainter &p, const QString &message,
int left, int right)
{
const int y = get_y();
p.setPen(ErrorBgColour.darker());
p.setBrush(ErrorBgColour);
const QRectF bounding_rect =
QRectF(left, INT_MIN / 2 + y, right - left, INT_MAX);
const QRectF text_rect = p.boundingRect(bounding_rect,
Qt::AlignCenter, message);
const float r = text_rect.height() / 4;
p.drawRoundedRect(text_rect.adjusted(-r, -r, r, r), r, r,
Qt::AbsoluteSize);
p.setPen(get_text_colour());
QFont font=p.font();
font.setPointSize(DefaultFontSize);
p.setFont(font);
p.drawText(text_rect, message);
}
bool DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left,
int right)
{
using namespace pv::data;
using pv::data::decode::Decoder;
assert(_decoder_stack);
shared_ptr<Logic> data;
shared_ptr<LogicSignal> logic_signal;
const int64_t sample_count = _session.get_device()->get_sample_limit();
if (sample_count == 0)
return true;
const int64_t samples_decoded = _decoder_stack->samples_decoded();
if (sample_count == samples_decoded)
return false;
const int y = get_y();
// const double start = max(samples_decoded /
// samples_per_pixel - pixels_offset, left - 1.0);
// const double end = min(sample_count / samples_per_pixel -
// pixels_offset, right + 1.0);
const QRectF no_decode_rect(left, y - h/2 + 0.5, right - left, h);
p.setPen(QPen(Qt::NoPen));
p.setBrush(Qt::white);
p.drawRect(no_decode_rect);
p.setPen(NoDecodeColour);
p.setBrush(QBrush(NoDecodeColour, Qt::Dense7Pattern));
p.drawRect(no_decode_rect);
const int progress100 = ceil(samples_decoded * 100.0 / sample_count);
p.setPen(dsLightBlue);
QFont font=p.font();
font.setPointSize(_view->get_signalHeight()*2/3);
font.setBold(true);
p.setFont(font);
p.drawText(no_decode_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(progress100)+"%");
return true;
}
void DecodeTrace::draw_unshown_row(QPainter &p, int y, int h, int left,
int right)
{
const QRectF unshown_rect(left, y - h/2 + 0.5, right - left, h);
p.setPen(QPen(Qt::NoPen));
p.setBrush(QBrush(NoDecodeColour, Qt::Dense7Pattern));
p.drawRect(unshown_rect);
p.setPen(dsLightBlue);
QFont font=p.font();
font.setPointSize(_view->get_signalHeight()*2/3);
font.setBold(true);
p.setFont(font);
p.drawText(unshown_rect, Qt::AlignCenter | Qt::AlignVCenter, "Unshown");
}
void DecodeTrace::create_decoder_form(int index,
shared_ptr<data::decode::Decoder> &dec, QWidget *parent,
QFormLayout *form)
{
const GSList *l;
assert(dec);
const srd_decoder *const decoder = dec->decoder();
assert(decoder);
pv::widgets::DecoderGroupBox *const group =
new pv::widgets::DecoderGroupBox(
QString::fromUtf8(decoder->name));
group->set_decoder_visible(dec->shown());
_show_hide_mapper.setMapping(group, index);
connect(group, SIGNAL(show_hide_decoder()),
&_show_hide_mapper, SLOT(map()));
QFormLayout *const decoder_form = new QFormLayout;
group->add_layout(decoder_form);
// Add the mandatory channels
for(l = decoder->channels; l; l = l->next) {
const struct srd_channel *const pdch =
(struct srd_channel *)l->data;
QComboBox *const combo = create_probe_selector(parent, dec, pdch);
connect(combo, SIGNAL(currentIndexChanged(int)),
this, SLOT(on_probe_selected(int)));
decoder_form->addRow(tr("<b>%1</b> (%2) *")
.arg(QString::fromUtf8(pdch->name))
.arg(QString::fromUtf8(pdch->desc)), combo);
const ProbeSelector s = {combo, dec, pdch};
_probe_selectors.push_back(s);
}
// Add the optional channels
for(l = decoder->opt_channels; l; l = l->next) {
const struct srd_channel *const pdch =
(struct srd_channel *)l->data;
QComboBox *const combo = create_probe_selector(parent, dec, pdch);
connect(combo, SIGNAL(currentIndexChanged(int)),
this, SLOT(on_probe_selected(int)));
decoder_form->addRow(tr("<b>%1</b> (%2)")
.arg(QString::fromUtf8(pdch->name))
.arg(QString::fromUtf8(pdch->desc)), combo);
const ProbeSelector s = {combo, dec, pdch};
_probe_selectors.push_back(s);
}
// Add the options
shared_ptr<prop::binding::DecoderOptions> binding(
new prop::binding::DecoderOptions(_decoder_stack, dec));
binding->add_properties_to_form(decoder_form, true);
_bindings.push_back(binding);
form->addRow(group);
_decoder_forms.push_back(group);
}
QComboBox* DecodeTrace::create_probe_selector(
QWidget *parent, const shared_ptr<data::decode::Decoder> &dec,
const srd_channel *const pdch)
{
assert(dec);
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
assert(_decoder_stack);
const map<const srd_channel*,
shared_ptr<LogicSignal> >::const_iterator probe_iter =
dec->channels().find(pdch);
QComboBox *selector = new QComboBox(parent);
selector->addItem("-", qVariantFromValue((void*)NULL));
if (probe_iter == dec->channels().end())
selector->setCurrentIndex(0);
for(size_t i = 0; i < sigs.size(); i++) {
const shared_ptr<view::Signal> s(sigs[i]);
assert(s);
if (dynamic_pointer_cast<LogicSignal>(s) && s->enabled())
{
selector->addItem(s->get_name(),
qVariantFromValue((void*)s.get()));
if ((*probe_iter).second == s)
selector->setCurrentIndex(i + 1);
}
}
return selector;
}
void DecodeTrace::commit_decoder_probes(shared_ptr<data::decode::Decoder> &dec)
{
assert(dec);
map<const srd_channel*, shared_ptr<LogicSignal> > probe_map;
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
_index_list.clear();
BOOST_FOREACH(const ProbeSelector &s, _probe_selectors)
{
if(s._decoder != dec)
break;
const LogicSignal *const selection =
(LogicSignal*)s._combo->itemData(
s._combo->currentIndex()).value<void*>();
BOOST_FOREACH(shared_ptr<Signal> sig, sigs)
if(sig.get() == selection) {
probe_map[s._pdch] =
dynamic_pointer_cast<LogicSignal>(sig);
_index_list.push_back(sig->get_index());
break;
}
}
dec->set_probes(probe_map);
}
void DecodeTrace::commit_probes()
{
assert(_decoder_stack);
BOOST_FOREACH(shared_ptr<data::decode::Decoder> dec,
_decoder_stack->stack())
commit_decoder_probes(dec);
//_decoder_stack->begin_decode();
}
void DecodeTrace::on_new_decode_data()
{
if (_view && _view->session().get_capture_state() == SigSession::Stopped)
_view->data_updated();
}
void DecodeTrace::on_decode_done()
{
if (_view) {
_view->set_need_update(true);
_view->signals_changed();
}
}
void DecodeTrace::on_delete()
{
_session.remove_decode_signal(this);
}
void DecodeTrace::on_probe_selected(int)
{
commit_probes();
}
void DecodeTrace::on_stack_decoder(srd_decoder *decoder)
{
assert(decoder);
assert(_decoder_stack);
_decoder_stack->push(shared_ptr<data::decode::Decoder>(
new data::decode::Decoder(decoder)));
//_decoder_stack->begin_decode();
create_popup();
}
void DecodeTrace::on_show_hide_decoder(int index)
{
using pv::data::decode::Decoder;
const list< shared_ptr<Decoder> > stack(_decoder_stack->stack());
// Find the decoder in the stack
list< shared_ptr<Decoder> >::const_iterator iter = stack.begin();
for(int i = 0; i < index; i++, iter++)
assert(iter != stack.end());
shared_ptr<Decoder> dec = *iter;
assert(dec);
const bool show = !dec->shown();
dec->show(show);
assert(index < (int)_decoder_forms.size());
_decoder_forms[index]->set_decoder_visible(show);
//_view->set_need_update(true);
}
int DecodeTrace::rows_size()
{
return _decoder_stack->cur_rows_size();
}
void DecodeTrace::paint_type_options(QPainter &p, int right, bool hover, int action)
{
(void)hover;
(void)action;
int y = get_y();
const QRectF group_index_rect = get_rect("groupIndex", y, right);
QString index_string;
int last_index;
p.setPen(Qt::transparent);
p.setBrush(dsBlue);
p.drawRect(group_index_rect);
std::list<int>::iterator i = _index_list.begin();
last_index = (*i);
index_string = QString::number(last_index);
while (++i != _index_list.end()) {
if ((*i) == last_index + 1 && index_string.indexOf("-") < 3 && index_string.indexOf("-") > 0)
index_string.replace(QString::number(last_index), QString::number((*i)));
else if ((*i) == last_index + 1)
index_string = QString::number((*i)) + "-" + index_string;
else
index_string = QString::number((*i)) + "," + index_string;
last_index = (*i);
}
p.setPen(Qt::white);
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
}
} // namespace view
} // namespace pv

View File

@@ -0,0 +1,204 @@
/*
* 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 DSLOGIC_PV_VIEW_DECODETRACE_H
#define DSLOGIC_PV_VIEW_DECODETRACE_H
#include "trace.h"
#include <list>
#include <map>
#include <QSignalMapper>
#include <QFormLayout>
#include <QDialog>
#include <boost/shared_ptr.hpp>
#include <pv/prop/binding/decoderoptions.h>
struct srd_channel;
struct srd_decoder;
class QComboBox;
namespace pv {
class SigSession;
namespace data {
class DecoderStack;
namespace decode {
class Annotation;
class Decoder;
class Row;
}
}
namespace widgets {
class DecoderGroupBox;
}
namespace view {
class DecodeTrace : public Trace
{
Q_OBJECT
private:
struct ProbeSelector
{
const QComboBox *_combo;
const boost::shared_ptr<pv::data::decode::Decoder> _decoder;
const srd_channel *_pdch;
};
private:
static const QColor DecodeColours[4];
static const QColor ErrorBgColour;
static const QColor NoDecodeColour;
static const int ArrowSize;
static const double EndCapWidth;
static const int DrawPadding;
static const QColor Colours[16];
static const QColor OutlineColours[16];
static const int DefaultFontSize = 8;
public:
DecodeTrace(pv::SigSession &session,
boost::shared_ptr<pv::data::DecoderStack> decoder_stack,
int index);
bool enabled() const;
const boost::shared_ptr<pv::data::DecoderStack>& decoder() const;
void set_view(pv::view::View *view);
/**
* Paints the background layer of the trace with a QPainter
* @param p the QPainter to paint into.
* @param left the x-coordinate of the left edge of the signal.
* @param right the x-coordinate of the right edge of the signal.
**/
void paint_back(QPainter &p, int left, int right);
/**
* Paints the mid-layer of the trace with a QPainter
* @param p the QPainter to paint into.
* @param left the x-coordinate of the left edge of the signal
* @param right the x-coordinate of the right edge of the signal
**/
void paint_mid(QPainter &p, int left, int right);
/**
* Paints the foreground layer of the trace with a QPainter
* @param p the QPainter to paint into.
* @param left the x-coordinate of the left edge of the signal
* @param right the x-coordinate of the right edge of the signal
**/
void paint_fore(QPainter &p, int left, int right);
bool create_popup();
int rows_size();
protected:
void paint_type_options(QPainter &p, int right, bool hover, int action);
private:
void populate_popup_form(QWidget *parent, QFormLayout *form);
void draw_annotation(const pv::data::decode::Annotation &a, QPainter &p,
QColor text_colour, int text_height, int left, int right,
double samples_per_pixel, double pixels_offset, int y,
size_t base_colour) const;
void draw_nodetail(QPainter &p,
int text_height, int left, int right, int y,
size_t base_colour) const;
void draw_instant(const pv::data::decode::Annotation &a, QPainter &p,
QColor fill, QColor outline, QColor text_color, int h, double x,
int y) const;
void draw_range(const pv::data::decode::Annotation &a, QPainter &p,
QColor fill, QColor outline, QColor text_color, int h, double start,
double end, int y) const;
void draw_error(QPainter &p, const QString &message,
int left, int right);
bool draw_unresolved_period(QPainter &p, int h, int left,
int right);
void draw_unshown_row(QPainter &p, int y, int h, int left,
int right);
void create_decoder_form(int index,
boost::shared_ptr<pv::data::decode::Decoder> &dec,
QWidget *parent, QFormLayout *form);
QComboBox* create_probe_selector(QWidget *parent,
const boost::shared_ptr<pv::data::decode::Decoder> &dec,
const srd_channel *const pdch);
void commit_decoder_probes(
boost::shared_ptr<data::decode::Decoder> &dec);
void commit_probes();
private slots:
void on_new_decode_data();
void on_delete();
void on_probe_selected(int);
void on_stack_decoder(srd_decoder *decoder);
void on_show_hide_decoder(int index);
void on_decode_done();
private:
pv::SigSession &_session;
boost::shared_ptr<pv::data::DecoderStack> _decoder_stack;
uint64_t _decode_start, _decode_end;
std::list< boost::shared_ptr<pv::prop::binding::DecoderOptions> >
_bindings;
std::list<ProbeSelector> _probe_selectors;
std::vector<pv::widgets::DecoderGroupBox*> _decoder_forms;
std::vector<QString> _cur_row_headings;
QSignalMapper _show_hide_mapper;
};
} // namespace view
} // namespace pv
#endif // DSLOGIC_PV_VIEW_DECODETRACE_H

View File

@@ -0,0 +1,194 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2014 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
*
* 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 "devmode.h"
#include "view.h"
#include "trace.h"
#include "../sigsession.h"
#include "../device/devinst.h"
#include <assert.h>
#include <boost/foreach.hpp>
#include <QApplication>
#include <QStyleOption>
#include <QMouseEvent>
#include <QPainter>
#include <QRect>
#include <QMessageBox>
#include <QDebug>
using boost::shared_ptr;
using namespace std;
namespace pv {
namespace view {
DevMode::DevMode(View &parent) :
QWidget(&parent),
_view(parent),
layout(new QGridLayout(this))
{
setLayout(layout);
}
void DevMode::set_device()
{
int index = 0;
const boost::shared_ptr<device::DevInst> dev_inst = _view.session().get_device();
assert(dev_inst);
_mode_button_list.clear();
delete layout;
layout = new QGridLayout(this);
for (GSList *l = dev_inst->get_dev_mode_list();
l; l = l->next) {
sr_dev_mode *mode = (sr_dev_mode *)l->data;
shared_ptr<QPushButton> mode_button = shared_ptr<QPushButton>(new QPushButton(NULL));
mode_button->setFlat(true);
mode_button->setText(mode->name);
_mode_button_list[mode_button] = mode;
connect(mode_button.get(), SIGNAL(clicked()), this, SLOT(on_mode_change()));
layout->addWidget(mode_button.get(), index / GRID_COLS, index % GRID_COLS);
layout->addWidget(new QWidget(), index / GRID_COLS, GRID_COLS);
layout->setColumnStretch(GRID_COLS, 1);
index++;
}
setLayout(layout);
update();
}
void DevMode::paintEvent(QPaintEvent*)
{
using pv::view::Trace;
QStyleOption o;
o.initFrom(this);
QPainter painter(this);
style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::NoPen);
for(std::map<shared_ptr<QPushButton>, sr_dev_mode *>::const_iterator i = _mode_button_list.begin();
i != _mode_button_list.end(); i++) {
const boost::shared_ptr<device::DevInst> dev_inst = _view.session().get_device();
assert(dev_inst);
if (dev_inst->dev_inst()->mode == (*i).second->mode)
painter.setBrush(Trace::dsBlue);
else
painter.setBrush(Trace::dsGray);
painter.drawRoundedRect((*i).first->geometry(), 4, 4);
}
painter.end();
}
void DevMode::on_mode_change()
{
const boost::shared_ptr<device::DevInst> dev_inst = _view.session().get_device();
assert(dev_inst);
QPushButton *button = qobject_cast<QPushButton *>(sender());
for(std::map<shared_ptr<QPushButton>, sr_dev_mode *>::const_iterator i = _mode_button_list.begin();
i != _mode_button_list.end(); i++) {
if ((*i).first.get() == button) {
if (dev_inst->dev_inst()->mode != (*i).second->mode) {
dev_inst->set_config(NULL, NULL,
SR_CONF_DEVICE_MODE,
g_variant_new_int16((*i).second->mode));
mode_changed();
if (dev_inst->dev_inst()->mode == DSO &&
strcmp(dev_inst->dev_inst()->driver->name, "DSLogic") == 0) {
bool zero_adjusted = false;
GVariant *gvar = dev_inst->get_config(NULL, NULL, SR_CONF_ZERO);
if (gvar != NULL) {
zero_adjusted = g_variant_get_boolean(gvar);
g_variant_unref(gvar);
} else {
qDebug() << "ERROR: config_get SR_CONF_ZERO failed.";
}
if (!zero_adjusted) {
QMessageBox msg(this);
msg.setText("Zero Adjustment");
msg.setInformativeText("Please left both of channels unconnect for zero adjustment!");
msg.setStandardButtons(QMessageBox::Ok);
msg.setIcon(QMessageBox::Warning);
msg.exec();
int ret = dev_inst->set_config(NULL, NULL,
SR_CONF_ZERO,
g_variant_new_boolean(TRUE));
if (!ret) {
QMessageBox msg(this);
msg.setText("Zero Adjustment Issue");
msg.setInformativeText("Can't send out the command of zero adjustment!");
msg.setStandardButtons(QMessageBox::Ok);
msg.setIcon(QMessageBox::Warning);
msg.exec();
}
}
}
}
}
}
}
void DevMode::mousePressEvent(QMouseEvent *event)
{
assert(event);
(void)event;
}
void DevMode::mouseReleaseEvent(QMouseEvent *event)
{
assert(event);
(void)event;
}
void DevMode::mouseMoveEvent(QMouseEvent *event)
{
assert(event);
_mouse_point = event->pos();
update();
}
void DevMode::leaveEvent(QEvent*)
{
_mouse_point = QPoint(-1, -1);
update();
}
} // namespace view
} // namespace pv

View File

@@ -0,0 +1,90 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2014 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
*
* 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 DSLOGIC_PV_VIEW_DEVMODE_H
#define DSLOGIC_PV_VIEW_DEVMODE_H
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <list>
#include <utility>
#include <map>
#include <set>
#include <QWidget>
#include <QPushButton>
#include <QGridLayout>
#include <QVector>
#include <libsigrok4DSLogic/libsigrok.h>
namespace pv {
namespace device{
class DevInst;
}
namespace view {
class View;
class DevMode : public QWidget
{
Q_OBJECT
private:
static const int GRID_COLS = 3;
public:
DevMode(View &parent);
private:
void paintEvent(QPaintEvent *event);
private:
void mousePressEvent(QMouseEvent * event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void leaveEvent(QEvent *event);
public slots:
void set_device();
void on_mode_change();
private slots:
signals:
void mode_changed();
private:
View &_view;
QGridLayout * layout;
std::map <boost::shared_ptr<QPushButton>, sr_dev_mode *> _mode_button_list;
QPoint _mouse_point;
};
} // namespace view
} // namespace pv
#endif // DSLOGIC_PV_VIEW_DEVMODE_H

View File

@@ -27,6 +27,11 @@
#include "dsosignal.h"
#include "pv/data/dso.h"
#include "pv/data/dsosnapshot.h"
#include "view.h"
#include "../sigsession.h"
#include "../device/devinst.h"
#include <QDebug>
using namespace boost;
using namespace std;
@@ -34,6 +39,55 @@ using namespace std;
namespace pv {
namespace view {
const uint64_t DsoSignal::vDialValue[DsoSignal::vDialValueCount] = {
5,
10,
20,
50,
100,
200,
500,
1000,
2000,
5000,
};
const QString DsoSignal::vDialUnit[DsoSignal::vDialUnitCount] = {
"mv",
"v",
};
const uint64_t DsoSignal::hDialValue[DsoSignal::hDialValueCount] = {
10,
20,
50,
100,
200,
500,
1000,
2000,
5000,
10000,
20000,
50000,
100000,
200000,
500000,
1000000,
2000000,
5000000,
10000000,
20000000,
50000000,
100000000,
};
const QString DsoSignal::hDialUnit[DsoSignal::hDialUnitCount] = {
"ns",
"us",
"ms",
"s",
};
const QColor DsoSignal::SignalColours[4] = {
QColor(238, 178, 17, 200), // dsYellow
QColor(0, 153, 37, 200), // dsGreen
@@ -44,35 +98,74 @@ const QColor DsoSignal::SignalColours[4] = {
const float DsoSignal::EnvelopeThreshold = 256.0f;
DsoSignal::DsoSignal(QString name, boost::shared_ptr<data::Dso> data,
int probe_index, int order, uint64_t vdiv, uint64_t timebase, bool coupling, bool active) :
Signal(name, probe_index, DS_DSO, order),
_data(data)
const int DsoSignal::UpMargin = 30;
const int DsoSignal::DownMargin = 30;
const int DsoSignal::RightMargin = 30;
DsoSignal::DsoSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
shared_ptr<data::Dso> data,
const sr_channel * const probe):
Signal(dev_inst, probe, DS_DSO),
_data(data),
_scale(0),
_vDialActive(false),
_hDialActive(false),
_trig_vpos(probe->index * 0.5 + 0.25),
_zeroPos(probe->index * 0.5 + 0.25)
{
_colour = SignalColours[probe_index % countof(SignalColours)];
_scale = _windowHeight * 1.0f / 256;
_vDial->set_value(vdiv);
_hDial->set_value(timebase);
_acCoupling = coupling;
_active = active;
QVector<uint64_t> vValue;
QVector<QString> vUnit;
QVector<uint64_t> hValue;
QVector<QString> hUnit;
for(quint64 i = 0; i < vDialValueCount; i++)
vValue.append(vDialValue[i]);
for(quint64 i = 0; i < vDialUnitCount; i++)
vUnit.append(vDialUnit[i]);
for(quint64 i = 0; i < hDialValueCount; i++)
hValue.append(hDialValue[i]);
for(quint64 i = 0; i < hDialUnitCount; i++)
hUnit.append(hDialUnit[i]);
_vDial = new dslDial(vDialValueCount, vDialValueStep, vValue, vUnit);
_hDial = new dslDial(hDialValueCount, hDialValueStep, hValue, hUnit);
_colour = SignalColours[probe->index % countof(SignalColours)];
GVariant* gvar;
gvar = dev_inst->get_config(probe, NULL, SR_CONF_VDIV);
if (gvar != NULL) {
_vDial->set_value(g_variant_get_uint64(gvar));
g_variant_unref(gvar);
} else {
qDebug() << "ERROR: config_get SR_CONF_VDIV failed.";
}
gvar = dev_inst->get_config(NULL, NULL, SR_CONF_TIMEBASE);
if (gvar != NULL) {
_hDial->set_value(g_variant_get_uint64(gvar));
g_variant_unref(gvar);
} else {
qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed.";
}
gvar = dev_inst->get_config(probe, NULL, SR_CONF_COUPLING);
if (gvar != NULL) {
_acCoupling = g_variant_get_boolean(gvar);
g_variant_unref(gvar);
} else {
qDebug() << "ERROR: config_get SR_CONF_COUPLING failed.";
}
}
DsoSignal::~DsoSignal()
{
}
void DsoSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
shared_ptr<pv::data::SignalData> DsoSignal::data() const
{
(void)_analog_data;
(void)_logic_data;
(void)_group_data;
assert(_dso_data);
_data = _dso_data;
return _data;
}
void DsoSignal::set_scale(float scale)
@@ -80,47 +173,333 @@ void DsoSignal::set_scale(float scale)
_scale = scale;
}
void DsoSignal::paint(QPainter &p, int y, int left, int right, double scale,
double offset)
void DsoSignal::set_enable(bool enable)
{
assert(scale > 0);
assert(_data);
assert(right >= left);
_dev_inst->set_config(_probe, NULL, SR_CONF_EN_CH,
g_variant_new_boolean(enable));
_view->set_need_update(true);
_view->update();
}
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
bool DsoSignal::get_vDialActive() const
{
return _vDialActive;
}
_scale = _windowHeight * 1.0f / 256;
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
void DsoSignal::set_vDialActive(bool active)
{
if (enabled())
_vDialActive = active;
}
const uint16_t number_channels = snapshot->get_channel_num();
if ((unsigned int)get_index() >= number_channels)
return;
bool DsoSignal::go_vDialPre()
{
if (enabled() && !_vDial->isMin()) {
_vDial->set_sel(_vDial->get_sel() - 1);
_dev_inst->set_config(_probe, NULL, SR_CONF_VDIV,
g_variant_new_uint64(_vDial->get_value()));
return true;
} else {
return false;
}
}
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 = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0);
const double samples_per_pixel = samplerate * scale;
const double start = samplerate * (offset - start_time);
const double end = start + samples_per_pixel * (right - left);
bool DsoSignal::go_vDialNext()
{
if (enabled() && !_vDial->isMax()) {
_vDial->set_sel(_vDial->get_sel() + 1);
_dev_inst->set_config(_probe, NULL, SR_CONF_VDIV,
g_variant_new_uint64(_vDial->get_value()));
return true;
} else {
return false;
}
}
const int64_t start_sample = min(max((int64_t)floor(start),
(int64_t)0), last_sample);
const int64_t end_sample = min(max((int64_t)ceil(end) + 1,
(int64_t)0), last_sample);
bool DsoSignal::get_hDialActive() const
{
return _hDialActive;
}
if (samples_per_pixel < EnvelopeThreshold)
paint_trace(p, snapshot, y, left,
start_sample, end_sample,
pixels_offset, samples_per_pixel, number_channels);
else
paint_envelope(p, snapshot, y, left,
start_sample, end_sample,
pixels_offset, samples_per_pixel);
void DsoSignal::set_hDialActive(bool active)
{
if (enabled())
_hDialActive = active;
}
bool DsoSignal::go_hDialPre()
{
if (!_hDial->isMin()) {
_hDial->set_sel(_hDial->get_sel() - 1);
int ch_num = _view->session().get_dso_ch_num();
uint64_t sample_limit = _view->session().get_device()->get_sample_limit();
uint64_t sample_rate = min((uint64_t)(sample_limit * pow(10, 9) / (_hDial->get_value() * DS_CONF_DSO_HDIVS)),
(uint64_t)(DS_MAX_DSO_SAMPLERATE / ch_num));
_view->session().set_sample_rate(sample_rate);
const double scale = _hDial->get_value() * pow(10, -9) * DS_CONF_DSO_HDIVS / get_view_rect().width();
_view->set_scale_offset(scale, _view->offset());
_dev_inst->set_config(_probe, NULL, SR_CONF_TIMEBASE,
g_variant_new_uint64(_hDial->get_value()));
return true;
} else {
return false;
}
}
bool DsoSignal::go_hDialNext()
{
if (!_hDial->isMax()) {
_hDial->set_sel(_hDial->get_sel() + 1);
int ch_num = _view->session().get_dso_ch_num();
uint64_t sample_limit = _view->session().get_device()->get_sample_limit();
uint64_t sample_rate = min((uint64_t)(sample_limit * pow(10, 9) / (_hDial->get_value() * DS_CONF_DSO_HDIVS)),
(uint64_t)(DS_MAX_DSO_SAMPLERATE / ch_num));
_view->session().set_sample_rate(sample_rate);
const double scale = _hDial->get_value() * pow(10, -9) * DS_CONF_DSO_HDIVS / get_view_rect().width();
_view->set_scale_offset(scale, _view->offset());
_dev_inst->set_config(_probe, NULL, SR_CONF_TIMEBASE,
g_variant_new_uint64(_hDial->get_value()));
return true;
} else {
return false;
}
}
uint64_t DsoSignal::get_vDialValue() const
{
return _vDial->get_value();
}
uint64_t DsoSignal::get_hDialValue() const
{
return _hDial->get_value();
}
uint16_t DsoSignal::get_vDialSel() const
{
return _vDial->get_sel();
}
uint16_t DsoSignal::get_hDialSel() const
{
return _hDial->get_sel();
}
bool DsoSignal::get_acCoupling() const
{
return _acCoupling;
}
void DsoSignal::set_acCoupling(bool coupling)
{
if (enabled()) {
_acCoupling = coupling;
_dev_inst->set_config(_probe, NULL, SR_CONF_COUPLING,
g_variant_new_boolean(_acCoupling));
}
}
int DsoSignal::get_trig_vpos() const
{
return _trig_vpos * get_view_rect().height() + UpMargin;
}
void DsoSignal::set_trig_vpos(int pos)
{
assert(_view);
if (enabled()) {
double delta = min((double)max(pos - UpMargin, 0), get_view_rect().height()) * 1.0f / get_view_rect().height() - _zeroPos;
delta = min(delta, 0.5);
delta = max(delta, -0.5);
_trig_vpos = _zeroPos + delta;
int trig_value = (-delta * 255.0f + 0x80);
_dev_inst->set_config(_probe, NULL, SR_CONF_TRIGGER_VALUE,
g_variant_new_uint16(trig_value));
}
}
int DsoSignal::get_zeroPos()
{
return _zeroPos * get_view_rect().height() + UpMargin;
}
void DsoSignal::set_zeroPos(int pos)
{
if (enabled()) {
double delta = _trig_vpos - _zeroPos;
_zeroPos = min((double)max(pos - UpMargin, 0), get_view_rect().height()) * 1.0f / get_view_rect().height();
_trig_vpos = min(max(_zeroPos + delta, 0.0), 1.0);
}
}
QRectF DsoSignal::get_view_rect() const
{
assert(_view);
return QRectF(0, UpMargin,
_view->viewport()->width() - RightMargin,
_view->viewport()->height() - UpMargin - DownMargin);
}
void DsoSignal::paint_back(QPainter &p, int left, int right)
{
assert(_view);
int i, j;
const int height = _view->viewport()->height() - UpMargin - DownMargin;
const int width = right - left - RightMargin;
p.setPen(Qt::NoPen);
p.setBrush(Trace::dsBack);
p.drawRect(left, UpMargin, width, height);
p.setPen(Trace::dsLightBlue);
p.drawLine(left, UpMargin/2, left + width, UpMargin/2);
const uint64_t sample_len = _dev_inst->get_sample_limit();
const double samplerate = _dev_inst->get_sample_rate();
const double samples_per_pixel = samplerate * _view->scale();
const double shown_rate = min(samples_per_pixel * width * 1.0f / sample_len, 1.0);
const double start_time = _data->get_start_time();
const double start = samplerate * (_view->offset() - start_time);
const double shown_offset = min(start / sample_len, 1.0) * width;
const double shown_len = shown_rate * width;
const QPointF left_edge[] = {QPoint(shown_offset + 3, UpMargin/2 - 6),
QPoint(shown_offset, UpMargin/2 - 6),
QPoint(shown_offset, UpMargin/2 + 6),
QPoint(shown_offset + 3, UpMargin/2 + 6)};
const QPointF right_edge[] = {QPoint(shown_offset + shown_len - 3, UpMargin/2 - 6),
QPoint(shown_offset + shown_len , UpMargin/2 - 6),
QPoint(shown_offset + shown_len , UpMargin/2 + 6),
QPoint(shown_offset + shown_len - 3, UpMargin/2 + 6)};
p.drawPolyline(left_edge, countof(left_edge));
p.drawPolyline(right_edge, countof(right_edge));
p.setBrush(Trace::dsBlue);
p.drawRect(shown_offset, UpMargin/2 - 3, shown_len, 6);
QPen pen(Signal::dsFore);
pen.setStyle(Qt::DotLine);
p.setPen(pen);
const double spanY =height * 1.0f / 10;
for (i = 1; i <= DS_CONF_DSO_VDIVS; i++) {
const double posY = spanY * i + UpMargin;
p.drawLine(left, posY, right - RightMargin, posY);
const double miniSpanY = spanY / 5;
for (j = 1; j < 5; j++) {
p.drawLine(width / 2.0f - 10, posY - miniSpanY * j,
width / 2.0f + 10, posY - miniSpanY * j);
}
}
const double spanX = width * 1.0f / 10;
for (i = 1; i <= DS_CONF_DSO_HDIVS; i++) {
const double posX = spanX * i;
p.drawLine(posX, UpMargin,
posX, height + UpMargin);
const double miniSpanX = spanX / 5;
for (j = 1; j < 5; j++) {
p.drawLine(posX - miniSpanX * j, height / 2.0f + UpMargin - 10,
posX - miniSpanX * j, height / 2.0f + UpMargin + 10);
}
}
}
void DsoSignal::paint_mid(QPainter &p, int left, int right)
{
assert(_data);
assert(_view);
assert(right >= left);
if (enabled()) {
const int height = _view->viewport()->height() - UpMargin - DownMargin;
const int width = right - left - RightMargin;
const int y = get_zeroPos() + height * 0.5;
const double scale = _view->scale();
assert(scale > 0);
const double offset = _view->offset();
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
_scale = height * 1.0f / 256;
const shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
const uint16_t number_channels = snapshot->get_channel_num();
if ((unsigned int)get_index() >= number_channels)
return;
const double pixels_offset = offset / scale;
//const double samplerate = _data->samplerate();
const double samplerate = _dev_inst->get_sample_rate();
const double start_time = _data->get_start_time();
const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0);
const double samples_per_pixel = samplerate * scale;
const double start = samplerate * (offset - start_time);
const double end = start + samples_per_pixel * width;
const int64_t start_sample = min(max((int64_t)floor(start),
(int64_t)0), last_sample);
const int64_t end_sample = min(max((int64_t)ceil(end) + 1,
(int64_t)0), last_sample);
if (samples_per_pixel < EnvelopeThreshold)
paint_trace(p, snapshot, y, left,
start_sample, end_sample,
pixels_offset, samples_per_pixel, number_channels);
else
paint_envelope(p, snapshot, y, left,
start_sample, end_sample,
pixels_offset, samples_per_pixel);
}
}
void DsoSignal::paint_fore(QPainter &p, int left, int right)
{
assert(_view);
QPen pen(Signal::dsGray);
pen.setStyle(Qt::DotLine);
p.setPen(pen);
p.drawLine(left, get_zeroPos(), right - RightMargin, get_zeroPos());
if(enabled()) {
const QPointF mouse_point = _view->hover_point();
const QRectF label_rect = get_trig_rect(left, right);
const bool hover = label_rect.contains(mouse_point);
// Paint the trig line
const QPointF points[] = {
QPointF(right - label_rect.width()*1.5, get_trig_vpos()),
label_rect.topLeft(),
label_rect.topRight(),
label_rect.bottomRight(),
label_rect.bottomLeft()
};
p.setPen(Qt::transparent);
p.setBrush(hover ? _colour.dark() : _colour);
p.drawPolygon(points, countof(points));
// paint the _trig_vpos line
p.setPen(QPen(_colour, 1, Qt::DashLine));
p.drawLine(left, get_trig_vpos(), right - label_rect.width()*1.5, get_trig_vpos());
// Paint the text
p.setPen(Qt::white);
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "T");
}
}
QRectF DsoSignal::get_trig_rect(int left, int right) const
{
(void)left;
return QRectF(right - SquareWidth,
get_trig_vpos() - SquareWidth / 2,
SquareWidth, SquareWidth);
}
void DsoSignal::paint_trace(QPainter &p,
@@ -140,11 +519,15 @@ void DsoSignal::paint_trace(QPainter &p,
QPointF *points = new QPointF[sample_count];
QPointF *point = points;
float top = get_view_rect().top();
float bottom = get_view_rect().bottom();
for (int64_t sample = start; sample < end; sample++) {
const float x = (sample / samples_per_pixel - pixels_offset) + left;
uint8_t offset = samples[(sample - start)*num_channels];
*point++ = QPointF(x,
y - offset * _scale);
if (offset >0 && offset < 0xff) {
const float yp = min(bottom, max(top, y - offset * _scale));
*point++ = QPointF(x, yp);
}
}
p.drawPolyline(points, point - points);
@@ -206,18 +589,30 @@ const std::vector< std::pair<uint64_t, bool> > DsoSignal::cur_edges() const
}
void DsoSignal::set_decoder(pv::decoder::Decoder *decoder)
void DsoSignal::paint_type_options(QPainter &p, int right, bool hover, int action)
{
(void)decoder;
}
int y = get_y();
const QRectF vDial_rect = get_rect("vDial", y, right);
const QRectF hDial_rect = get_rect("hDial", y, right);
const QRectF acdc_rect = get_rect("acdc", y, right);
const QRectF chEn_rect = get_rect("chEn", y, right);
decoder::Decoder *DsoSignal::get_decoder()
{
return NULL;
}
QColor vDial_color = _vDialActive ? dsActive : dsDisable;
QColor hDial_color = _hDialActive ? dsActive : dsDisable;
_vDial->paint(p, vDial_rect, vDial_color);
_hDial->paint(p, hDial_rect, hDial_color);
void DsoSignal::del_decoder()
{
p.setPen(Qt::transparent);
p.setBrush((hover && action == CHEN) ? _colour.darker() : _colour);
p.drawRect(chEn_rect);
p.setPen(Qt::white);
p.drawText(chEn_rect, Qt::AlignCenter | Qt::AlignVCenter, enabled() ? "EN" : "DIS");
p.setPen(Qt::transparent);
p.setBrush(enabled() ? ((hover && action == ACDC) ? _colour.darker() : _colour) : dsDisable);
p.drawRect(acdc_rect);
p.setPen(Qt::white);
p.drawText(acdc_rect, Qt::AlignCenter | Qt::AlignVCenter, _acCoupling ? "AC" : "DC");
}
} // namespace view

View File

@@ -42,43 +42,99 @@ class DsoSignal : public Signal
{
private:
static const QColor SignalColours[4];
static const float EnvelopeThreshold;
static const int HitCursorMargin = 3;
static const uint64_t vDialValueCount = 10;
static const uint64_t vDialValueStep = 1000;
static const uint64_t vDialUnitCount = 2;
static const uint64_t hDialValueCount = 22;
static const uint64_t hDialValueStep = 1000;
static const uint64_t hDialUnitCount = 4;
static const uint64_t vDialValue[vDialValueCount];
static const QString vDialUnit[vDialUnitCount];
static const uint64_t hDialValue[hDialValueCount];
static const QString hDialUnit[hDialUnitCount];
static const int UpMargin;
static const int DownMargin;
static const int RightMargin;
public:
DsoSignal(QString name,
boost::shared_ptr<pv::data::Dso> data, int probe_index, int order,
uint64_t vdiv, uint64_t timebase, bool coupling, bool active);
DsoSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
boost::shared_ptr<pv::data::Dso> data,
const sr_channel * const probe);
virtual ~DsoSignal();
boost::shared_ptr<pv::data::SignalData> data() const;
void set_scale(float scale);
/**
*
*/
void set_enable(bool enable);
bool get_vDialActive() const;
void set_vDialActive(bool active);
bool get_hDialActive() const;
void set_hDialActive(bool active);
bool go_vDialPre();
bool go_vDialNext();
bool go_hDialPre();
bool go_hDialNext();
uint64_t get_vDialValue() const;
uint64_t get_hDialValue() const;
uint16_t get_vDialSel() const;
uint16_t get_hDialSel() const;
bool get_acCoupling() const;
void set_acCoupling(bool coupling);
void set_trig_vpos(int pos);
int get_trig_vpos() const;
/**
* Gets the mid-Y position of this signal.
*/
int get_zeroPos();
/**
* Sets the mid-Y position of this signal.
*/
void set_zeroPos(int pos);
/**
* Paints the background layer of the trace with a QPainter
* @param p the QPainter to paint into.
* @param left the x-coordinate of the left edge of the signal
* @param right the x-coordinate of the right edge of the signal
**/
void paint_back(QPainter &p, int left, int right);
/**
* Paints the signal with a QPainter
* @param p the QPainter to paint into.
* @param y the y-coordinate to draw the signal at.
* @param left the x-coordinate of the left edge of the signal.
* @param right the x-coordinate of the right edge of the signal.
* @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, int y, int left, int right, double scale,
double offset);
void paint_mid(QPainter &p, int left, int right);
/**
* Paints the signal with a QPainter
* @param p the QPainter to paint into.
* @param left the x-coordinate of the left edge of the signal.
* @param right the x-coordinate of the right edge of the signal.
**/
void paint_fore(QPainter &p, int left, int right);
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
void set_decoder(pv::decoder::Decoder *decoder);
QRectF get_view_rect() const;
pv::decoder::Decoder* get_decoder();
QRectF get_trig_rect(int left, int right) const;
void del_decoder();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
protected:
void paint_type_options(QPainter &p, int right, bool hover, int action);
private:
void paint_trace(QPainter &p,
@@ -95,6 +151,15 @@ private:
private:
boost::shared_ptr<pv::data::Dso> _data;
float _scale;
dslDial *_vDial;
dslDial *_hDial;
bool _vDialActive;
bool _hDialActive;
bool _acCoupling;
double _trig_vpos;
double _zeroPos;
};
} // namespace view

View File

@@ -28,6 +28,7 @@
#include "groupsignal.h"
#include "pv/data/group.h"
#include "pv/data/groupsnapshot.h"
#include "view.h"
using namespace boost;
using namespace std;
@@ -45,8 +46,8 @@ const QColor GroupSignal::SignalColours[4] = {
const float GroupSignal::EnvelopeThreshold = 256.0f;
GroupSignal::GroupSignal(QString name, boost::shared_ptr<data::Group> data,
std::list<int> probe_index_list, int order, int group_index) :
Signal(name, probe_index_list, DS_GROUP, order, group_index),
std::list<int> probe_index_list, int group_index) :
Trace(name, probe_index_list, DS_GROUP, group_index),
_data(data)
{
_colour = SignalColours[probe_index_list.front() % countof(SignalColours)];
@@ -57,18 +58,14 @@ GroupSignal::~GroupSignal()
{
}
void GroupSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
bool GroupSignal::enabled() const
{
(void)_logic_data;
(void)_dso_data;
(void)_analog_data;
return true;
}
assert(_group_data);
_data = _group_data;
shared_ptr<pv::data::SignalData> GroupSignal::data() const
{
return _data;
}
void GroupSignal::set_scale(float scale)
@@ -76,15 +73,18 @@ void GroupSignal::set_scale(float scale)
_scale = scale;
}
void GroupSignal::paint(QPainter &p, int y, int left, int right, double scale,
double offset)
void GroupSignal::paint_mid(QPainter &p, int left, int right)
{
assert(scale > 0);
assert(_data);
assert(right >= left);
assert(_data);
assert(_view);
assert(right >= left);
const int y = get_y() + _signalHeight * 0.5;
const double scale = _view->scale();
assert(scale > 0);
const double offset = _view->offset();
_scale = _signalHeight * 1.0f / pow(2, _index_list.size());
paint_axis(p, y, left, right);
const deque< boost::shared_ptr<pv::data::GroupSnapshot> > &snapshots =
_data->get_snapshots();
@@ -95,7 +95,7 @@ void GroupSignal::paint(QPainter &p, int y, int left, int right, double scale,
snapshots.at(_sec_index);
const double pixels_offset = offset / scale;
const double samplerate = _data->get_samplerate();
const double samplerate = _data->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;
@@ -196,18 +196,32 @@ const std::vector< std::pair<uint64_t, bool> > GroupSignal::cur_edges() const
}
void GroupSignal::set_decoder(pv::decoder::Decoder *decoder)
void GroupSignal::paint_type_options(QPainter &p, int right, bool hover, int action)
{
(void)decoder;
}
(void)hover;
(void)action;
decoder::Decoder *GroupSignal::get_decoder()
{
return NULL;
}
void GroupSignal::del_decoder()
{
int y = get_y();
const QRectF group_index_rect = get_rect("groupIndex", y, right);
QString index_string;
int last_index;
p.setPen(Qt::transparent);
p.setBrush(dsBlue);
p.drawRect(group_index_rect);
std::list<int>::iterator i = _index_list.begin();
last_index = (*i);
index_string = QString::number(last_index);
while (++i != _index_list.end()) {
if ((*i) == last_index + 1 && index_string.indexOf("-") < 3 && index_string.indexOf("-") > 0)
index_string.replace(QString::number(last_index), QString::number((*i)));
else if ((*i) == last_index + 1)
index_string = QString::number((*i)) + "-" + index_string;
else
index_string = QString::number((*i)) + "," + index_string;
last_index = (*i);
}
p.setPen(Qt::white);
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
}
} // namespace view

View File

@@ -41,7 +41,7 @@ class GroupSnapshot;
namespace view {
class GroupSignal : public Signal
class GroupSignal : public Trace
{
private:
static const QColor SignalColours[4];
@@ -51,37 +51,31 @@ private:
public:
GroupSignal(QString name,
boost::shared_ptr<pv::data::Group> data,
std::list<int> probe_index_list, int order, int group_index);
std::list<int> probe_index_list, int group_index);
virtual ~GroupSignal();
/**
* Returns true if the trace is visible and enabled.
*/
bool enabled() const;
boost::shared_ptr<pv::data::SignalData> data() const;
void set_scale(float scale);
/**
* Paints the signal with a QPainter
* @param p the QPainter to paint into.
* @param y the y-coordinate to draw the signal at.
* @param left the x-coordinate of the left edge of the signal.
* @param right the x-coordinate of the right edge of the signal.
* @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, int y, int left, int right, double scale,
double offset);
void paint_mid(QPainter &p, int left, int right);
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
void set_decoder(pv::decoder::Decoder *decoder);
pv::decoder::Decoder* get_decoder();
void del_decoder();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
protected:
void paint_type_options(QPainter &p, int right, bool hover, int action);
private:
void paint_trace(QPainter &p,

View File

@@ -24,8 +24,14 @@
#include "header.h"
#include "view.h"
#include "signal.h"
#include "trace.h"
#include "dsosignal.h"
#include "logicsignal.h"
#include "analogsignal.h"
#include "groupsignal.h"
#include "decodetrace.h"
#include "../sigsession.h"
#include "../device/devinst.h"
#include <assert.h>
@@ -70,8 +76,8 @@ Header::Header(View &parent) :
connect(nameEdit, SIGNAL(editingFinished()),
this, SLOT(on_action_set_name_triggered()));
connect(&_view, SIGNAL(signals_moved()),
this, SLOT(on_signals_moved()));
connect(&_view, SIGNAL(traces_moved()),
this, SLOT(on_traces_moved()));
}
@@ -83,30 +89,28 @@ int Header::get_nameEditWidth()
return 0;
}
boost::shared_ptr<pv::view::Signal> Header::get_mSig(
boost::shared_ptr<pv::view::Trace> Header::get_mTrace(
int &action,
const QPoint &pt)
{
const int w = width();
const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
const vector< boost::shared_ptr<Trace> > traces(
_view.get_traces());
const int v_offset = _view.v_offset();
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
{
assert(s);
assert(t);
if ((action = s->pt_in_rect(s->get_v_offset() - v_offset - _view.get_signalHeight() / 2,
w, pt)))
return s;
if ((action = t->pt_in_rect(t->get_y(), w, pt)))
return t;
}
return boost::shared_ptr<Signal>();
return boost::shared_ptr<Trace>();
}
void Header::paintEvent(QPaintEvent*)
{
using pv::view::Signal;
using pv::view::Trace;
QStyleOption o;
o.initFrom(this);
@@ -114,47 +118,22 @@ void Header::paintEvent(QPaintEvent*)
style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this);
const int w = width();
int action;
const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
int action = 0;
const vector< boost::shared_ptr<Trace> > traces(
_view.get_traces());
//QPainter painter(this);
//painter.setRenderHint(QPainter::Antialiasing);
const int v_offset = _view.v_offset();
const bool dragging = !_drag_sigs.empty();
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
const bool dragging = !_drag_traces.empty();
BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
{
assert(s);
assert(t);
const int y = s->get_v_offset() - v_offset - _view.get_signalHeight() / 2;
const int y = t->get_y();
const bool highlight = !dragging &&
(action = s->pt_in_rect(y, w, _mouse_point));
s->paint_label(painter, y, w, highlight, action);
// Paint the Backgroud
painter.setRenderHint(QPainter::Antialiasing, false);
painter.setPen(Signal::dsGray);
if (s->selected() && _moveFlag) {
if (s->get_type() == Signal::DS_ANALOG) {
painter.drawLine(0, s->get_old_v_offset() - v_offset - s->get_signalHeight(),
w, s->get_old_v_offset() - v_offset - s->get_signalHeight());
painter.drawLine(0, s->get_old_v_offset() - v_offset,
w, s->get_old_v_offset() - v_offset);
} else if (s->get_type() == Signal::DS_LOGIC){
painter.drawLine(0, s->get_old_v_offset() - v_offset + 10,
w, s->get_old_v_offset() - v_offset + 10);
}
} else {
if (s->get_type() == Signal::DS_ANALOG) {
painter.drawLine(0, s->get_v_offset() - v_offset,
w, s->get_v_offset() - v_offset);
painter.drawLine(0, s->get_v_offset() - v_offset - s->get_signalHeight(),
w, s->get_v_offset() - v_offset - s->get_signalHeight());
} else if (s->get_type() == Signal::DS_LOGIC) {
painter.drawLine(0, s->get_v_offset() - v_offset + 10,
w, s->get_v_offset() - v_offset + 10);
}
}
(action = t->pt_in_rect(y, w, _mouse_point));
t->paint_label(painter, w, highlight, action);
}
painter.end();
@@ -164,126 +143,116 @@ void Header::mousePressEvent(QMouseEvent *event)
{
assert(event);
const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
const vector< boost::shared_ptr<Trace> > traces(
_view.get_traces());
int action;
if (event->button() & Qt::LeftButton) {
_mouse_down_point = event->pos();
// Save the offsets of any signals which will be dragged
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
if (s->selected())
_drag_sigs.push_back(
make_pair(s, s->get_v_offset()));
// Save the offsets of any Traces which will be dragged
BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
if (t->selected())
_drag_traces.push_back(
make_pair(t, t->get_v_offset()));
// Select the signal if it has been clicked
const boost::shared_ptr<Signal> mSig =
get_mSig(action, event->pos());
if (action == Signal::COLOR && mSig) {
// Select the Trace if it has been clicked
const boost::shared_ptr<Trace> mTrace =
get_mTrace(action, event->pos());
if (action == Trace::COLOR && mTrace) {
_colorFlag = true;
} else if (action == Signal::NAME && mSig) {
} else if (action == Trace::NAME && mTrace) {
_nameFlag = true;
} else if (action == Signal::LABEL && mSig) {
if (mSig->selected())
mSig->select(false);
} else if (action == Trace::LABEL && mTrace) {
if (mTrace->selected())
mTrace->select(false);
else {
if (mSig->get_type() != Signal::DS_DSO)
mSig->select(true);
if (mTrace->get_type() != Trace::DS_DSO)
mTrace->select(true);
if (~QApplication::keyboardModifiers() &
Qt::ControlModifier)
_drag_sigs.clear();
_drag_traces.clear();
// Add the signal to the drag list
if (event->button() & Qt::LeftButton)
_drag_sigs.push_back(
make_pair(mSig,
(mSig->get_type() == Signal::DS_DSO) ? mSig->get_zeroPos() : mSig->get_v_offset()));
}
mSig->set_old_v_offset(mSig->get_v_offset());
} else if (action == Signal::POSTRIG && mSig) {
if (mSig->get_trig() == Signal::POSTRIG)
mSig->set_trig(0);
else
mSig->set_trig(Signal::POSTRIG);
} else if (action == Signal::HIGTRIG && mSig) {
if (mSig->get_trig() == Signal::HIGTRIG)
mSig->set_trig(0);
else
mSig->set_trig(Signal::HIGTRIG);
} else if (action == Signal::NEGTRIG && mSig) {
if (mSig->get_trig() == Signal::NEGTRIG)
mSig->set_trig(0);
else
mSig->set_trig(Signal::NEGTRIG);
} else if (action == Signal::LOWTRIG && mSig) {
if (mSig->get_trig() == Signal::LOWTRIG)
mSig->set_trig(0);
else
mSig->set_trig(Signal::LOWTRIG);
} else if (action == Signal::EDGETRIG && mSig) {
if (mSig->get_trig() == Signal::EDGETRIG)
mSig->set_trig(0);
else
mSig->set_trig(Signal::EDGETRIG);
} else if (action == Signal::VDIAL && mSig) {
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
s->set_hDialActive(false);
if (s != mSig) {
s->set_vDialActive(false);
// Add the Trace to the drag list
if (event->button() & Qt::LeftButton) {
_drag_traces.push_back(make_pair(mTrace, mTrace->get_zeroPos()));
}
}
mSig->set_vDialActive(!mSig->get_vDialActive());
} else if (action == Signal::HDIAL && mSig) {
if (mSig->get_hDialActive()) {
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
s->set_vDialActive(false);
s->set_hDialActive(false);
}
} else {
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
s->set_vDialActive(false);
s->set_hDialActive(true);
}
}
} else if (action == Signal::CHEN && mSig) {
int channel;
if (mSig->get_index() == 0) {
bool last = 1;
channel = 0;
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
if (s->get_index() != 0 && s->get_active()) {
QMessageBox msg(this);
msg.setText("Tips");
msg.setInformativeText("If only one channel want, Channel0 has a higher maximum sample rate!");
msg.setStandardButtons(QMessageBox::Ok);
msg.setIcon(QMessageBox::Information);
msg.exec();
s->set_active(!s->get_active());
last = 0;
channel = s->get_index();
break;
mTrace->set_old_v_offset(mTrace->get_v_offset());
} else if (action == Trace::POSTRIG && mTrace) {
if (mTrace->get_trig() == Trace::POSTRIG)
mTrace->set_trig(0);
else
mTrace->set_trig(Trace::POSTRIG);
} else if (action == Trace::HIGTRIG && mTrace) {
if (mTrace->get_trig() == Trace::HIGTRIG)
mTrace->set_trig(0);
else
mTrace->set_trig(Trace::HIGTRIG);
} else if (action == Trace::NEGTRIG && mTrace) {
if (mTrace->get_trig() == Trace::NEGTRIG)
mTrace->set_trig(0);
else
mTrace->set_trig(Trace::NEGTRIG);
} else if (action == Trace::LOWTRIG && mTrace) {
if (mTrace->get_trig() == Trace::LOWTRIG)
mTrace->set_trig(0);
else
mTrace->set_trig(Trace::LOWTRIG);
} else if (action == Trace::EDGETRIG && mTrace) {
if (mTrace->get_trig() == Trace::EDGETRIG)
mTrace->set_trig(0);
else
mTrace->set_trig(Trace::EDGETRIG);
} else if (action == Trace::VDIAL && mTrace) {
shared_ptr<view::DsoSignal> dsoSig;
BOOST_FOREACH(const shared_ptr<Trace> t, traces) {
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(t)) {
dsoSig->set_hDialActive(false);
if (t != mTrace) {
dsoSig->set_vDialActive(false);
}
}
if (last)
mSig->set_active(!mSig->get_active());
} else {
mSig->set_active(!mSig->get_active());
channel = mSig->get_index();
}
ch_changed(channel);
} else if (action == Signal::ACDC && mSig) {
mSig->set_acCoupling(!mSig->get_acCoupling());
acdc_changed(mSig->get_index());
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace))
dsoSig->set_vDialActive(!dsoSig->get_vDialActive());
} else if (action == Trace::HDIAL && mTrace) {
shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace)) {
if (dsoSig->get_hDialActive()) {
BOOST_FOREACH(const shared_ptr<Trace> t, traces) {
if(dsoSig = dynamic_pointer_cast<view::DsoSignal>(t)) {
dsoSig->set_vDialActive(false);
dsoSig->set_hDialActive(false);
}
}
} else {
BOOST_FOREACH(const shared_ptr<Trace> t, traces) {
if(dsoSig = dynamic_pointer_cast<view::DsoSignal>(t)) {
dsoSig->set_vDialActive(false);
dsoSig->set_hDialActive(true);
}
}
}
}
} else if (action == Trace::CHEN && mTrace) {
shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace)) {
dsoSig->set_enable(!dsoSig->enabled());
}
} else if (action == Trace::ACDC && mTrace) {
shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace))
dsoSig->set_acCoupling(!dsoSig->get_acCoupling());
}
if (~QApplication::keyboardModifiers() & Qt::ControlModifier) {
// Unselect all other signals because the Ctrl is not
// Unselect all other Traces because the Ctrl is not
// pressed
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
if (s != mSig)
s->select(false);
BOOST_FOREACH(const shared_ptr<Trace> t, traces)
if (t != mTrace)
t->select(false);
}
update();
}
@@ -295,26 +264,27 @@ void Header::mouseReleaseEvent(QMouseEvent *event)
// judge for color / name / trigger / move
int action;
const boost::shared_ptr<Signal> mSig =
get_mSig(action, event->pos());
if (mSig){
if (action == Signal::COLOR && _colorFlag) {
_context_signal = mSig;
const boost::shared_ptr<Trace> mTrace =
get_mTrace(action, event->pos());
if (mTrace){
if (action == Trace::COLOR && _colorFlag) {
_context_trace = mTrace;
changeColor(event);
_view.set_need_update(true);
} else if (action == Signal::NAME && _nameFlag) {
_context_signal = mSig;
} else if (action == Trace::NAME && _nameFlag) {
_context_trace = mTrace;
changeName(event);
}
}
if (_moveFlag) {
move(event);
//move(event);
_view.signals_changed();
_view.set_need_update(true);
}
_colorFlag = false;
_nameFlag = false;
_moveFlag = false;
_drag_sigs.clear();
_drag_traces.clear();
_view.normalize_layout();
}
@@ -323,30 +293,24 @@ void Header::wheelEvent(QWheelEvent *event)
assert(event);
if (event->orientation() == Qt::Vertical) {
const vector< shared_ptr<Signal> > sigs(
_view.session().get_signals());
const vector< shared_ptr<Trace> > traces(
_view.get_traces());
// Vertical scrolling
double shift = event->delta() / 20.0;
if (shift > 1.0) {
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
if (s->get_vDialActive()) {
if(s->go_vDialNext())
vDial_changed(s->get_index());
BOOST_FOREACH(const shared_ptr<Trace> t, traces) {
shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(t)) {
if (dsoSig->get_vDialActive()) {
if (shift > 1.0)
dsoSig->go_vDialNext();
else if (shift < -1.0)
dsoSig->go_vDialPre();
break;
} else if (s->get_hDialActive()) {
if(s->go_hDialNext())
hDial_changed(0);
}
}
} else if (shift < -1.0) {
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
if (s->get_vDialActive()) {
if(s->go_vDialPre())
vDial_changed(s->get_index());
break;
} else if (s->get_hDialActive()) {
if(s->go_hDialPre())
hDial_changed(0);
} else if (dsoSig->get_hDialActive()) {
if (shift > 1.0)
dsoSig->go_hDialNext();
else if (shift < -1.0)
dsoSig->go_hDialPre();
}
}
}
@@ -354,145 +318,11 @@ void Header::wheelEvent(QWheelEvent *event)
}
}
void Header::move(QMouseEvent *event)
{
bool _moveValid = false;
bool _moveUp = false;
bool firstCheck = true;
const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
boost::shared_ptr<Signal> minDragSig;
boost::shared_ptr<Signal> maxDragSig;
int minOffset;
int minOldOffset;
int maxOffset;
int maxOldOffset;
int targetOffset;
std::list<std::pair<boost::weak_ptr<Signal>,
int> >::iterator minJ;
std::list<std::pair<boost::weak_ptr<Signal>,
int> >::iterator maxJ;
int targetOrder;
// reCalculate _v_offset of all signals after dragging release
if ((event->button() == Qt::LeftButton)) {
while (!_drag_sigs.empty()) {
minOffset = INT_MAX;
maxOffset = 0;
for (std::list<std::pair<boost::weak_ptr<Signal>,
int> >::iterator i = _drag_sigs.begin();
i != _drag_sigs.end(); i++) {
const boost::shared_ptr<Signal> sig((*i).first);
if (sig) {
if (sig->get_v_offset() < minOffset) {
minDragSig = sig;
minOldOffset = (*i).second;
minOffset = sig->get_v_offset();
minJ = i;
}
if (sig->get_v_offset() > maxOffset) {
maxDragSig = sig;
maxOldOffset = (*i).second;
maxOffset = sig->get_v_offset();
maxJ = i;
}
}
}
if (minOffset > minOldOffset) {
_moveUp = false;
_drag_sigs.erase(maxJ);
} else {
_moveUp = true;
_drag_sigs.erase(minJ);
}
if (!_moveValid && firstCheck){
firstCheck = false;
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
if (_moveUp) {
if (s->selected()) {
if ((minOffset <= s->get_old_v_offset()) && (minOffset > (s->get_old_v_offset() - _view.get_spanY()))) {
_moveValid = true;
targetOffset = s->get_old_v_offset();
targetOrder = s->get_order();
break;
}
} else {
if ((minOffset <= s->get_v_offset()) && (minOffset > (s->get_v_offset() - _view.get_spanY()))) {
_moveValid = true;
targetOffset = s->get_v_offset();
targetOrder = s->get_order();
break;
}
}
} else {
if (s->selected()) {
if ((maxOffset >= s->get_old_v_offset()) && (maxOffset < (s->get_old_v_offset() + _view.get_spanY()))) {
_moveValid = true;
targetOffset = s->get_old_v_offset();
targetOrder = s->get_order();
break;
}
} else {
if ((maxOffset >= s->get_v_offset()) && (maxOffset < (s->get_v_offset() + _view.get_spanY()))) {
_moveValid = true;
targetOffset = s->get_v_offset();
targetOrder = s->get_order();
break;
}
}
}
}
}
if (_moveValid) {
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
if (_moveUp) {
if (s->selected() && s == minDragSig) {
s->set_v_offset(targetOffset);
s->set_order(targetOrder);
s->select(false);
} else if (!s->selected() && s->get_v_offset() >= targetOffset && s->get_v_offset() < minOldOffset) {
s->set_v_offset(s->get_v_offset() + _view.get_spanY());
s->set_order(s->get_order() + 1);
}
} else {
if (s->selected() && s == maxDragSig) {
s->set_v_offset(targetOffset);
s->set_order(targetOrder);
s->select(false);
} else if (!s->selected() && s->get_v_offset() <= targetOffset && s->get_v_offset() > maxOldOffset) {
s->set_v_offset(s->get_v_offset() - _view.get_spanY());
s->set_order(s->get_order() - 1);
}
}
}
if (_moveUp) {
targetOffset += _view.get_spanY();
targetOrder++;
} else {
targetOffset -= _view.get_spanY();
targetOrder--;
}
}
}
if (_moveValid) {
signals_moved();
} else {
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
if (s->selected()) {
s->set_v_offset(s->get_old_v_offset());
s->select(false);
}
}
}
}
_moveValid = false;
}
void Header::changeName(QMouseEvent *event)
{
if ((event->button() == Qt::LeftButton)) {
header_resize();
nameEdit->setText(_context_signal->get_name());
nameEdit->setText(_context_trace->get_name());
nameEdit->selectAll();
nameEdit->setFocus();
nameEdit->show();
@@ -503,9 +333,9 @@ void Header::changeName(QMouseEvent *event)
void Header::changeColor(QMouseEvent *event)
{
if ((event->button() == Qt::LeftButton)) {
const QColor new_color = QColorDialog::getColor(_context_signal->get_colour(), this, tr("Set Channel Colour"));
const QColor new_color = QColorDialog::getColor(_context_trace->get_colour(), this, tr("Set Channel Colour"));
if (new_color.isValid())
_context_signal->set_colour(new_color);
_context_trace->set_colour(new_color);
}
}
@@ -514,17 +344,17 @@ void Header::mouseMoveEvent(QMouseEvent *event)
assert(event);
_mouse_point = event->pos();
// Move the signals if we are dragging
if (!_drag_sigs.empty()) {
// Move the Traces if we are dragging
if (!_drag_traces.empty()) {
const int delta = event->pos().y() - _mouse_down_point.y();
for (std::list<std::pair<boost::weak_ptr<Signal>,
int> >::iterator i = _drag_sigs.begin();
i != _drag_sigs.end(); i++) {
const boost::shared_ptr<Signal> sig((*i).first);
for (std::list<std::pair<boost::weak_ptr<Trace>,
int> >::iterator i = _drag_traces.begin();
i != _drag_traces.end(); i++) {
const boost::shared_ptr<Trace> sig((*i).first);
if (sig) {
int y = (*i).second + delta;
if (sig->get_type() != Signal::DS_DSO) {
if (sig->get_type() != Trace::DS_DSO) {
const int y_snap =
((y + View::SignalSnapGridSize / 2) /
View::SignalSnapGridSize) *
@@ -533,20 +363,19 @@ void Header::mouseMoveEvent(QMouseEvent *event)
_moveFlag = true;
sig->set_v_offset(y_snap);
}
// Ensure the signal is selected
// Ensure the Trace is selected
sig->select(true);
} else {
if (y < 0)
y = 0;
else if (y > height())
y = height();
sig->set_zeroPos(y);
sig->select(false);
signals_moved();
shared_ptr<DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<DsoSignal>(sig)) {
dsoSig->set_zeroPos(y);
dsoSig->select(false);
traces_moved();
}
}
}
}
//signals_moved();
//traces_moved();
}
update();
}
@@ -561,33 +390,33 @@ void Header::contextMenuEvent(QContextMenuEvent *event)
{
int action;
const boost::shared_ptr<Signal> s = get_mSig(action, _mouse_point);
const boost::shared_ptr<Trace> t = get_mTrace(action, _mouse_point);
if (!s || !s->selected() || action != Signal::LABEL)
if (!t || !t->selected() || action != Trace::LABEL)
return;
QMenu menu(this);
if (s->get_type() == Signal::DS_LOGIC)
if (t->get_type() == Trace::DS_LOGIC)
menu.addAction(_action_add_group);
else if (s->get_type() == Signal::DS_GROUP)
else if (t->get_type() == Trace::DS_GROUP)
menu.addAction(_action_del_group);
_context_signal = s;
_context_trace = t;
menu.exec(event->globalPos());
_context_signal.reset();
_context_trace.reset();
}
void Header::on_action_set_name_triggered()
{
boost::shared_ptr<view::Signal> context_signal = _context_signal;
if (!context_signal)
boost::shared_ptr<view::Trace> context_Trace = _context_trace;
if (!context_Trace)
return;
if (nameEdit->isModified()) {
context_signal->set_name(nameEdit->text());
if (context_signal->get_type() == Signal::DS_LOGIC ||
context_signal->get_type() == Signal::DS_ANALOG)
sr_dev_probe_name_set(_view.session().get_device(), context_signal->get_index(), nameEdit->text().toUtf8().constData());
context_Trace->set_name(nameEdit->text());
if (context_Trace->get_type() == Trace::DS_LOGIC ||
context_Trace->get_type() == Trace::DS_ANALOG)
sr_dev_probe_name_set(_view.session().get_device()->dev_inst(), context_Trace->get_index(), nameEdit->text().toUtf8().constData());
}
nameEdit->hide();
@@ -604,7 +433,7 @@ void Header::on_action_del_group_triggered()
_view.session().del_group();
}
void Header::on_signals_moved()
void Header::on_traces_moved()
{
update();
}
@@ -612,9 +441,9 @@ void Header::on_signals_moved()
void Header::header_resize()
{
//if (nameEdit->isVisible()) {
if (_context_signal) {
const int y = _context_signal->get_v_offset() - _view.v_offset() - _view.get_signalHeight() / 2;
nameEdit->move(QPoint(_context_signal->get_leftWidth(), y - nameEdit->height() / 2));
if (_context_trace) {
const int y = _context_trace->get_y();
nameEdit->move(QPoint(_context_trace->get_leftWidth(), y - nameEdit->height() / 2));
}
}

View File

@@ -36,7 +36,7 @@
namespace pv {
namespace view {
class Signal;
class Trace;
class View;
class Header : public QWidget
@@ -47,7 +47,7 @@ public:
Header(View &parent);
private:
boost::shared_ptr<pv::view::Signal> get_mSig(
boost::shared_ptr<pv::view::Trace> get_mTrace(
int &action,
const QPoint &pt);
@@ -62,7 +62,6 @@ private:
void wheelEvent(QWheelEvent *event);
void contextMenuEvent(QContextMenuEvent *event);
void move(QMouseEvent *event);
void changeName(QMouseEvent *event);
void changeColor(QMouseEvent *event);
@@ -77,13 +76,12 @@ private slots:
void on_action_del_group_triggered();
void on_signals_moved();
void on_traces_moved();
signals:
void signals_moved();
void traces_moved();
void header_updated();
void vDial_changed(quint16);
void hDial_changed(quint16);
void acdc_changed(quint16);
void ch_changed(quint16);
@@ -99,10 +97,10 @@ private:
QLineEdit *nameEdit;
std::list<std::pair<boost::weak_ptr<Signal>, int> >
_drag_sigs;
std::list<std::pair<boost::weak_ptr<Trace>, int> >
_drag_traces;
boost::shared_ptr<Signal> _context_signal;
boost::shared_ptr<Trace> _context_trace;
QAction *_action_add_group;
QAction *_action_del_group;

View File

@@ -29,6 +29,7 @@
#include "view.h"
#include "pv/data/logic.h"
#include "pv/data/logicsnapshot.h"
#include "view.h"
using namespace boost;
using namespace std;
@@ -65,50 +66,50 @@ const QColor LogicSignal::SignalColours[8] = {
const int LogicSignal::StateHeight = 12;
const int LogicSignal::StateRound = 5;
LogicSignal::LogicSignal(QString name, boost::shared_ptr<data::Logic> data,
int probe_index, int order) :
Signal(name, probe_index, DS_LOGIC, order),
_probe_index(probe_index),
_data(data),
_need_decode(false),
_decoder(NULL)
LogicSignal::LogicSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
boost::shared_ptr<data::Logic> data,
const sr_channel * const probe) :
Signal(dev_inst, probe, DS_LOGIC),
_data(data)
{
assert(_probe_index >= 0);
_colour = SignalColours[_probe_index % countof(SignalColours)];
assert(probe->index >= 0);
_colour = SignalColours[probe->index % countof(SignalColours)];
}
LogicSignal::~LogicSignal()
{
}
void LogicSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
const sr_channel* LogicSignal::probe() const
{
(void)_dso_data;
(void)_analog_data;
(void)_group_data;
assert(_logic_data);
if (!_cur_edges.empty())
_cur_edges.clear();
_data = _logic_data;
return _probe;
}
void LogicSignal::paint(QPainter &p, int y, int left, int right,
double scale, double offset)
shared_ptr<pv::data::SignalData> LogicSignal::data() const
{
return _data;
}
shared_ptr<pv::data::Logic> LogicSignal::logic_data() const
{
return _data;
}
void LogicSignal::paint_mid(QPainter &p, int left, int right)
{
using pv::view::View;
QLineF *line;
assert(scale > 0);
assert(_data);
assert(_view);
assert(right >= left);
const int y = get_y() + _signalHeight * 0.5;
const double scale = _view->scale();
assert(scale > 0);
const double offset = _view->offset();
const float high_offset = y - _signalHeight + 0.5f;
const float low_offset = y + 0.5f;
@@ -119,8 +120,10 @@ void LogicSignal::paint(QPainter &p, int y, int left, int right,
const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
if (snapshot->buf_null())
return;
double samplerate = _data->get_samplerate();
double samplerate = _data->samplerate();
// Show sample rate as 1Hz when it is unknown
if (samplerate == 0.0)
@@ -136,8 +139,9 @@ void LogicSignal::paint(QPainter &p, int y, int left, int right,
snapshot->get_subsampled_edges(_cur_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(_cur_edges.size() >= 2);
samples_per_pixel / Oversampling, _probe->index);
if (_cur_edges.size() < 2)
return;
// Paint the edges
const unsigned int edge_count = 2 * _cur_edges.size() - 3;
@@ -163,61 +167,6 @@ void LogicSignal::paint(QPainter &p, int y, int left, int right,
p.setPen(_colour);
p.drawLines(edge_lines, edge_count);
delete[] edge_lines;
if (_need_decode) {
assert(_decoder);
_decoder->get_subsampled_states(_cur_states,
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);
const float top_offset = y - (_signalHeight + StateHeight) / 2.0f;
const uint64_t sig_mask = 1ULL << _probe_index;
const uint8_t *const init_ptr = (uint8_t*)snapshot->get_data();
const uint8_t *src_ptr;
const int unit_size = snapshot->get_unit_size();
uint64_t value;
uint64_t finalValue = 0;
if (!_cur_states.empty()) {
_decoder->fill_color_table(_color_table);
_decoder->fill_state_table(_state_table);
vector<pv::decoder::ds_view_state>::const_iterator i;
for ( i = _cur_states.begin(); i != _cur_states.end(); i++) {
finalValue = 0;
const uint64_t index = (*i).index;
const uint64_t samples = (*i).samples;
const int64_t x = (index / samples_per_pixel -
pixels_offset) + left;
const int64_t width = samples / samples_per_pixel;
if ((*i).type == decoder::DEC_DATA) {
src_ptr = init_ptr + index * unit_size;
for (uint64_t j = 0; j < samples; j++) {
value = (*(uint64_t*)src_ptr & sig_mask);
if (_probe_index - j > 0)
value = value >> (_probe_index - j);
else
value = value << (j - _probe_index);
finalValue |= value;
src_ptr += unit_size;
}
}
p.setBrush(_color_table.at((*i).state));
const QRectF state_rect = QRectF(x, top_offset, width, StateHeight);
p.drawRoundedRect(state_rect, StateRound, StateRound);
p.setPen(Qt::black);
if ((*i).type == decoder::DEC_CMD)
p.drawText(state_rect, Qt::AlignCenter | Qt::AlignVCenter,
_state_table.at((*i).state));
else if ((*i).type == decoder::DEC_DATA)
p.drawText(state_rect, Qt::AlignCenter | Qt::AlignVCenter,
_state_table.at((*i).state) + "0x" + QString::number(finalValue, 16).toUpper());
}
}
}
}
void LogicSignal::paint_caps(QPainter &p, QLineF *const lines,
@@ -248,22 +197,80 @@ const std::vector< std::pair<uint64_t, bool> > LogicSignal::cur_edges() const
return _cur_edges;
}
void LogicSignal::set_decoder(pv::decoder::Decoder *decoder)
void LogicSignal::paint_type_options(QPainter &p, int right, bool hover, int action)
{
assert(decoder);
_need_decode = true;
_decoder = decoder;
}
int y = get_y();
const QRectF posTrig_rect = get_rect("posTrig", y, right);
const QRectF higTrig_rect = get_rect("higTrig", y, right);
const QRectF negTrig_rect = get_rect("negTrig", y, right);
const QRectF lowTrig_rect = get_rect("lowTrig", y, right);
const QRectF edgeTrig_rect = get_rect("edgeTrig", y, right);
decoder::Decoder *LogicSignal::get_decoder()
{
return _decoder;
}
p.setPen(Qt::transparent);
p.setBrush(((hover && action == POSTRIG) || (_trig == POSTRIG)) ?
dsYellow :
dsBlue);
p.drawRect(posTrig_rect);
p.setBrush(((hover && action == HIGTRIG) || (_trig == HIGTRIG)) ?
dsYellow :
dsBlue);
p.drawRect(higTrig_rect);
p.setBrush(((hover && action == NEGTRIG) || (_trig == NEGTRIG)) ?
dsYellow :
dsBlue);
p.drawRect(negTrig_rect);
p.setBrush(((hover && action == LOWTRIG) || (_trig == LOWTRIG)) ?
dsYellow :
dsBlue);
p.drawRect(lowTrig_rect);
p.setBrush(((hover && action == EDGETRIG) || (_trig == EDGETRIG)) ?
dsYellow :
dsBlue);
p.drawRect(edgeTrig_rect);
void LogicSignal::del_decoder()
{
_need_decode = false;
_decoder = NULL;
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
p.setBrush(Qt::transparent);
p.drawLine(posTrig_rect.right(), posTrig_rect.top() + 3,
posTrig_rect.right(), posTrig_rect.bottom() - 3);
p.drawLine(higTrig_rect.right(), higTrig_rect.top() + 3,
higTrig_rect.right(), higTrig_rect.bottom() - 3);
p.drawLine(negTrig_rect.right(), negTrig_rect.top() + 3,
negTrig_rect.right(), negTrig_rect.bottom() - 3);
p.drawLine(lowTrig_rect.right(), lowTrig_rect.top() + 3,
lowTrig_rect.right(), lowTrig_rect.bottom() - 3);
p.setPen(QPen(Qt::white, 2, Qt::SolidLine));
p.setBrush(Qt::transparent);
p.drawLine(posTrig_rect.left() + 5, posTrig_rect.bottom() - 5,
posTrig_rect.center().x(), posTrig_rect.bottom() - 5);
p.drawLine(posTrig_rect.center().x(), posTrig_rect.bottom() - 5,
posTrig_rect.center().x(), posTrig_rect.top() + 5);
p.drawLine(posTrig_rect.center().x(), posTrig_rect.top() + 5,
posTrig_rect.right() - 5, posTrig_rect.top() + 5);
p.drawLine(higTrig_rect.left() + 5, higTrig_rect.top() + 5,
higTrig_rect.right() - 5, higTrig_rect.top() + 5);
p.drawLine(negTrig_rect.left() + 5, negTrig_rect.top() + 5,
negTrig_rect.center().x(), negTrig_rect.top() + 5);
p.drawLine(negTrig_rect.center().x(), negTrig_rect.top() + 5,
negTrig_rect.center().x(), negTrig_rect.bottom() - 5);
p.drawLine(negTrig_rect.center().x(), negTrig_rect.bottom() - 5,
negTrig_rect.right() - 5, negTrig_rect.bottom() - 5);
p.drawLine(lowTrig_rect.left() + 5, lowTrig_rect.bottom() - 5,
lowTrig_rect.right() - 5, lowTrig_rect.bottom() - 5);
p.drawLine(edgeTrig_rect.left() + 5, edgeTrig_rect.top() + 5,
edgeTrig_rect.center().x() - 2, edgeTrig_rect.top() + 5);
p.drawLine(edgeTrig_rect.center().x() + 2 , edgeTrig_rect.top() + 5,
edgeTrig_rect.right() - 5, edgeTrig_rect.top() + 5);
p.drawLine(edgeTrig_rect.center().x(), edgeTrig_rect.top() + 7,
edgeTrig_rect.center().x(), edgeTrig_rect.bottom() - 7);
p.drawLine(edgeTrig_rect.left() + 5, edgeTrig_rect.bottom() - 5,
edgeTrig_rect.center().x() - 2, edgeTrig_rect.bottom() - 5);
p.drawLine(edgeTrig_rect.center().x() + 2, edgeTrig_rect.bottom() - 5,
edgeTrig_rect.right() - 5, edgeTrig_rect.bottom() - 5);
}
} // namespace view

View File

@@ -25,7 +25,6 @@
#define DSLOGIC_PV_LOGICSIGNAL_H
#include "signal.h"
#include "../decoder/decoder.h"
#include <vector>
@@ -55,36 +54,30 @@ private:
static const int StateRound;
public:
LogicSignal(QString name,
boost::shared_ptr<pv::data::Logic> data,
int probe_index, int order);
LogicSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
boost::shared_ptr<pv::data::Logic> data,
const sr_channel * const probe);
virtual ~LogicSignal();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
const sr_channel* probe() const;
boost::shared_ptr<pv::data::SignalData> data() const;
boost::shared_ptr<pv::data::Logic> logic_data() const;
/**
* Paints the signal with a QPainter
* @param p the QPainter to paint into.
* @param y the y-coordinate to draw the signal at.
* @param left the x-coordinate of the left edge of the signal.
* @param right the x-coordinate of the right edge of the signal.
* @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, int y, int left, int right, double scale,
double offset);
void paint_mid(QPainter &p, int left, int right);
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
void set_decoder(pv::decoder::Decoder *decoder);
pv::decoder::Decoder* get_decoder();
void del_decoder();
protected:
void paint_type_options(QPainter &p, int right, bool hover, int action);
private:
@@ -94,15 +87,8 @@ private:
float x_offset, float y_offset);
private:
int _probe_index;
boost::shared_ptr<pv::data::Logic> _data;
std::vector< std::pair<uint64_t, bool> > _cur_edges;
bool _need_decode;
pv::decoder::Decoder * _decoder;
std::vector<pv::decoder::ds_view_state > _cur_states;
std::vector< QColor > _color_table;
std::vector< QString > _state_table;
};
} // namespace view

View File

@@ -27,6 +27,8 @@
#include "view.h"
#include "viewport.h"
#include "../sigsession.h"
#include "../device/devinst.h"
#include "dsosignal.h"
#include <extdef.h>
@@ -39,6 +41,9 @@
#include <QTextStream>
#include <QStyleOption>
#include <boost/shared_ptr.hpp>
using namespace boost;
using namespace std;
namespace pv {
@@ -63,7 +68,7 @@ const QColor Ruler::CursorColor[8] =
QColor(46, 205, 113, 200),
QColor(53, 152, 220, 200),
QColor(154, 89, 181, 200),
QColor(52, 73, 94 , 200),
QColor(52, 73, 94, 200),
QColor(242, 196, 15, 200),
QColor(231, 126, 34, 200),
QColor(232, 76, 61, 200)};
@@ -405,7 +410,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
const double MinValueSpacing = 16.0f;
const int ValueMargin = 5;
const double abs_min_period = 10.0f / _view.session().get_last_sample_rate();
const double abs_min_period = 10.0f / _view.session().get_device()->get_sample_rate();
double min_width = SpacingIncrement;
double typical_width;
@@ -415,7 +420,11 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
// Find tick spacing, and number formatting that does not cause
// value to collide.
_min_period = cur_period_scale * abs_min_period;
if (_view.session().get_device()->dev_inst()->mode == DSO) {
_min_period = _view.session().get_device()->get_time_base() * pow(10, -9);
} else {
_min_period = cur_period_scale * abs_min_period;
}
const int order = (int)floorf(log10f(_min_period));
//const double order_decimal = pow(10, order);
const unsigned int prefix = (order - FirstSIPrefixPower) / 3;
@@ -459,7 +468,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
const double inc_text_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
AlignLeft | AlignTop,
format_time(tick_period - minor_tick_period,
format_time(minor_tick_period,
minor_prefix)).width() + MinValueSpacing;
do {
const double t = t0 + division * minor_tick_period;
@@ -485,7 +494,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
AlignCenter | AlignTop | TextDontClip,
format_time(t, prefix));
//else if ((tick_period / _view.scale() > width() / 4) && (minor_tick_period / _view.scale() > inc_text_width))
else if (minor_tick_period / _view.scale() > 1.2 * inc_text_width)
else if (minor_tick_period / _view.scale() > 1.1 * inc_text_width)
p.drawText(x, 2 * ValueMargin, 0, minor_tick_y1 + ValueMargin,
AlignCenter | AlignTop | TextDontClip,
format_time(t - major_t, minor_prefix));
@@ -495,7 +504,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
division++;
} while (x < width());
} while (x < _view.get_max_width());
// Draw the cursors
if (!_view.get_cursorList().empty()) {
@@ -509,10 +518,10 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
_view.on_cursor_moved();
}
if (_view.trig_cursor_shown()) {
_view.get_trig_cursor()->paint_fix_label(p, rect(), prefix, 'T', Signal::dsLightRed);
_view.get_trig_cursor()->paint_fix_label(p, rect(), prefix, 'T', Trace::dsLightRed);
}
if (_view.search_cursor_shown()) {
_view.get_search_cursor()->paint_fix_label(p, rect(), prefix, 'S', Signal::dsLightBlue);
_view.get_search_cursor()->paint_fix_label(p, rect(), prefix, 'S', Trace::dsLightBlue);
}
}

View File

@@ -0,0 +1,57 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>
* Copyright (C) 2014 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
*
* 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 "selectableitem.h"
#include <QApplication>
#include <QMenu>
#include <QPalette>
namespace pv {
namespace view {
const int SelectableItem::HighlightRadius = 6;
SelectableItem::SelectableItem() :
_selected(false)
{
}
bool SelectableItem::selected() const
{
return _selected;
}
void SelectableItem::select(bool select)
{
_selected = select;
}
QPen SelectableItem::highlight_pen()
{
return QPen(QApplication::palette().brush(
QPalette::Highlight), HighlightRadius,
Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
}
} // namespace view
} // namespace pv

View File

@@ -0,0 +1,69 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>
* Copyright (C) 2014 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
*
* 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 DSLOGIC_PV_SELECTABLEITEM_H
#define DSLOGIC_PV_SELECTABLEITEM_H
#include <list>
#include <QPen>
class QAction;
class QMenu;
class QWidget;
namespace pv {
namespace view {
class SelectableItem : public QObject
{
Q_OBJECT
private:
static const int HighlightRadius;
public:
SelectableItem();
public:
/**
* Returns true if the signal has been selected by the user.
*/
bool selected() const;
/**
* Selects or deselects the signal.
*/
void select(bool select = true);
protected:
static QPen highlight_pen();
private:
bool _selected;
};
} // namespace view
} // namespace pv
#endif // DSLOGIC_PV_SELECTABLEITEM_H

View File

@@ -29,673 +29,22 @@
#include "signal.h"
#include "view.h"
#include "../device/devinst.h"
namespace pv {
namespace view {
const QColor Signal::dsBlue = QColor(17, 133, 209, 255);
const QColor Signal::dsYellow = QColor(238, 178, 17, 255);
const QColor Signal::dsRed = QColor(213, 15, 37, 255);
const QColor Signal::dsGreen = QColor(0, 153, 37, 255);
const QColor Signal::dsGray = QColor(0x88, 0x8A, 0x85, 100);
const QColor Signal::dsDisable = QColor(0x88, 0x8A, 0x85, 200);
const QColor Signal::dsActive = QColor(17, 133, 209, 255);
const QColor Signal::dsLightBlue = QColor(17, 133, 209, 150);
const QColor Signal::dsLightRed = QColor(213, 15, 37, 150);
const QPen Signal::SignalAxisPen = QColor(128, 128, 128, 64);
const quint64 Signal::vDialValue[Signal::vDialValueCount] = {
5,
10,
20,
50,
100,
200,
500,
1000,
2000,
5000,
};
const QString Signal::vDialUnit[Signal::vDialUnitCount] = {
"mv",
"v",
};
const quint64 Signal::hDialValue[Signal::hDialValueCount] = {
10,
20,
50,
100,
200,
500,
1000,
2000,
5000,
10000,
20000,
50000,
100000,
200000,
500000,
1000000,
2000000,
5000000,
10000000,
20000000,
50000000,
100000000,
200000000,
500000000,
1000000000,
};
const QString Signal::hDialUnit[Signal::hDialUnitCount] = {
"ns",
"us",
"ms",
"s",
};
Signal::Signal(QString name, int index, int type, int order) :
_type(type),
_order(order),
_sec_index(0),
_name(name),
_v_offset(0),
_signalHeight(30),
_selected(false),
_trig(0),
_vDialActive(false),
_hDialActive(false),
_acCoupling(false),
_active(true),
_windowHeight(0)
Signal::Signal(boost::shared_ptr<pv::device::DevInst> dev_inst,
const sr_channel *const probe, int type) :
Trace(probe->name, probe->index, type),
_dev_inst(dev_inst),
_probe(probe)
{
_index_list.push_back(index);
if (_type == DS_DSO) {
QVector<quint64> vValue;
QVector<QString> vUnit;
QVector<quint64> hValue;
QVector<QString> hUnit;
for(quint64 i = 0; i < Signal::vDialValueCount; i++)
vValue.append(Signal::vDialValue[i]);
for(quint64 i = 0; i < Signal::vDialUnitCount; i++)
vUnit.append(Signal::vDialUnit[i]);
for(quint64 i = 0; i < Signal::hDialValueCount; i++)
hValue.append(Signal::hDialValue[i]);
for(quint64 i = 0; i < Signal::hDialUnitCount; i++)
hUnit.append(Signal::hDialUnit[i]);
_vDial = new dslDial(vDialValueCount, vDialValueStep, vValue, vUnit);
_hDial = new dslDial(hDialValueCount, hDialValueStep, hValue, hUnit);
_vDial->set_sel(0);
_hDial->set_sel(0);
_trig_vpos = 0;
_trig_en = true;
}
}
Signal::Signal(QString name, std::list<int> index_list, int type, int order, int sec_index) :
_type(type),
_index_list(index_list),
_order(order),
_sec_index(sec_index),
_name(name),
_v_offset(0),
_signalHeight(30),
_selected(false),
_trig(0),
_vDialActive(false),
_hDialActive(false),
_acCoupling(false),
_active(true)
bool Signal::enabled() const
{
if (_type == DS_DSO) {
QVector<quint64> vValue;
QVector<QString> vUnit;
QVector<quint64> hValue;
QVector<QString> hUnit;
for(quint64 i = 0; i < Signal::vDialValueCount; i++)
vValue.append(Signal::vDialValue[i]);
for(quint64 i = 0; i < Signal::vDialUnitCount; i++)
vUnit.append(Signal::vDialUnit[i]);
for(quint64 i = 0; i < Signal::hDialValueCount; i++)
hValue.append(Signal::hDialValue[i]);
for(quint64 i = 0; i < Signal::hDialUnitCount; i++)
hUnit.append(Signal::hDialUnit[i]);
_vDial = new dslDial(Signal::vDialValueCount, Signal::vDialValueStep, vValue, vUnit);
_hDial = new dslDial(Signal::hDialValueCount, Signal::hDialValueStep, hValue, hUnit);
_vDial->set_sel(0);
_hDial->set_sel(0);
}
}
int Signal::get_type() const
{
return _type;
}
int Signal::get_order() const
{
return _order;
}
void Signal::set_order(int order)
{
assert(order >= 0);
_order = order;
}
int Signal::get_leftWidth() const
{
return SquareWidth + Margin;
}
int Signal::get_rightWidth() const
{
return 2 * Margin + SquareNum * SquareWidth + 1.5 * SquareWidth;
}
int Signal::get_headerHeight() const
{
return SquareWidth;
}
int Signal::get_index() const
{
return _index_list.front();
}
std::list<int> &Signal::get_index_list()
{
return _index_list;
}
void Signal::set_index_list(std::list<int> index_list)
{
assert(index_list.size() != 0);
_index_list = index_list;
}
int Signal::get_sec_index() const
{
return _sec_index;
}
void Signal::set_sec_index(int sec_index)
{
_sec_index = sec_index;
}
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;
}
int Signal::get_v_offset() const
{
return _v_offset;
}
void Signal::set_v_offset(int v_offset)
{
_v_offset = v_offset;
}
int Signal::get_old_v_offset() const
{
return _old_v_offset;
}
void Signal::set_old_v_offset(int v_offset)
{
_old_v_offset = v_offset;
}
int Signal::get_signalHeight() const
{
return _signalHeight;
}
void Signal::set_signalHeight(int height)
{
_signalHeight = height;
}
bool Signal::selected() const
{
return _selected;
}
void Signal::select(bool select)
{
_selected = select;
}
int Signal::get_trig() const
{
return _trig;
}
void Signal::set_trig(int trig)
{
_trig = trig;
if (trig == 0)
ds_trigger_probe_set(_index_list.front(), 'X', 'X');
else if (trig == POSTRIG)
ds_trigger_probe_set(_index_list.front(), 'R', 'X');
else if (trig == HIGTRIG)
ds_trigger_probe_set(_index_list.front(), '1', 'X');
else if (trig == NEGTRIG)
ds_trigger_probe_set(_index_list.front(), 'F', 'X');
else if (trig == LOWTRIG)
ds_trigger_probe_set(_index_list.front(), '0', 'X');
else if (trig == EDGETRIG)
ds_trigger_probe_set(_index_list.front(), 'C', 'X');
}
bool Signal::get_vDialActive() const
{
return _vDialActive;
}
void Signal::set_vDialActive(bool active)
{
_vDialActive = active;
}
bool Signal::go_vDialPre()
{
assert(_type == DS_DSO);
if (!_vDial->isMin()) {
_vDial->set_sel(_vDial->get_sel() - 1);
return true;
} else {
return false;
}
}
bool Signal::go_vDialNext()
{
assert(_type == DS_DSO);
if (!_vDial->isMax()) {
_vDial->set_sel(_vDial->get_sel() + 1);
return true;
} else {
return false;
}
}
bool Signal::get_hDialActive() const
{
return _hDialActive;
}
void Signal::set_hDialActive(bool active)
{
_hDialActive = active;
}
bool Signal::go_hDialPre()
{
assert(_type == DS_DSO);
if (!_hDial->isMin()) {
_hDial->set_sel(_hDial->get_sel() - 1);
return true;
} else {
return false;
}
}
bool Signal::go_hDialNext()
{
assert(_type == DS_DSO);
if (!_hDial->isMax()) {
_hDial->set_sel(_hDial->get_sel() + 1);
return true;
} else {
return false;
}
}
quint64 Signal::get_vDialValue() const
{
return _vDial->get_value();
}
quint64 Signal::get_hDialValue() const
{
return _hDial->get_value();
}
uint16_t Signal::get_vDialSel() const
{
return _vDial->get_sel();
}
uint16_t Signal::get_hDialSel() const
{
return _hDial->get_sel();
}
bool Signal::get_acCoupling() const
{
return _acCoupling;
}
void Signal::set_acCoupling(bool coupling)
{
_acCoupling = coupling;
}
bool Signal::get_active() const
{
return _active;
}
void Signal::set_active(bool active)
{
_active = active;
}
int Signal::get_zeroPos() const
{
return _zeroPos;
}
void Signal::set_zeroPos(int pos)
{
_zeroPos = pos;
}
int Signal::get_windowHeight() const
{
return _windowHeight;
}
void Signal::set_windowHeight(int height)
{
_windowHeight = height;
}
int Signal::get_trig_vpos() const
{
return _trig_vpos;
}
void Signal::set_trig_vpos(int value)
{
_trig_vpos = value;
}
void Signal::paint_label(QPainter &p, int y, int right, bool hover, int action)
{
compute_text_size(p);
const QRectF color_rect = get_rect("color", y, right);
const QRectF name_rect = get_rect("name", y, right);
const QRectF label_rect = get_rect("label", (_type == DS_DSO) ? _zeroPos : y, right);
p.setRenderHint(QPainter::Antialiasing);
// Paint the ColorButton
p.setPen(Qt::transparent);
p.setBrush(_active ? _colour : dsDisable);
p.drawRect(color_rect);
// Paint the signal name
p.setPen(_active ? Qt::black : dsDisable);
p.drawText(name_rect, Qt::AlignLeft | Qt::AlignVCenter, _name);
// Paint the trigButton
if (_type == DS_LOGIC) {
const QRectF posTrig_rect = get_rect("posTrig", y, right);
const QRectF higTrig_rect = get_rect("higTrig", y, right);
const QRectF negTrig_rect = get_rect("negTrig", y, right);
const QRectF lowTrig_rect = get_rect("lowTrig", y, right);
const QRectF edgeTrig_rect = get_rect("edgeTrig", y, right);
p.setPen(Qt::transparent);
p.setBrush(((hover && action == POSTRIG) || (_trig == POSTRIG)) ?
dsYellow :
dsBlue);
p.drawRect(posTrig_rect);
p.setBrush(((hover && action == HIGTRIG) || (_trig == HIGTRIG)) ?
dsYellow :
dsBlue);
p.drawRect(higTrig_rect);
p.setBrush(((hover && action == NEGTRIG) || (_trig == NEGTRIG)) ?
dsYellow :
dsBlue);
p.drawRect(negTrig_rect);
p.setBrush(((hover && action == LOWTRIG) || (_trig == LOWTRIG)) ?
dsYellow :
dsBlue);
p.drawRect(lowTrig_rect);
p.setBrush(((hover && action == EDGETRIG) || (_trig == EDGETRIG)) ?
dsYellow :
dsBlue);
p.drawRect(edgeTrig_rect);
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
p.setBrush(Qt::transparent);
p.drawLine(posTrig_rect.right(), posTrig_rect.top() + 3,
posTrig_rect.right(), posTrig_rect.bottom() - 3);
p.drawLine(higTrig_rect.right(), higTrig_rect.top() + 3,
higTrig_rect.right(), higTrig_rect.bottom() - 3);
p.drawLine(negTrig_rect.right(), negTrig_rect.top() + 3,
negTrig_rect.right(), negTrig_rect.bottom() - 3);
p.drawLine(lowTrig_rect.right(), lowTrig_rect.top() + 3,
lowTrig_rect.right(), lowTrig_rect.bottom() - 3);
p.setPen(QPen(Qt::white, 2, Qt::SolidLine));
p.setBrush(Qt::transparent);
p.drawLine(posTrig_rect.left() + 5, posTrig_rect.bottom() - 5,
posTrig_rect.center().x(), posTrig_rect.bottom() - 5);
p.drawLine(posTrig_rect.center().x(), posTrig_rect.bottom() - 5,
posTrig_rect.center().x(), posTrig_rect.top() + 5);
p.drawLine(posTrig_rect.center().x(), posTrig_rect.top() + 5,
posTrig_rect.right() - 5, posTrig_rect.top() + 5);
p.drawLine(higTrig_rect.left() + 5, higTrig_rect.top() + 5,
higTrig_rect.right() - 5, higTrig_rect.top() + 5);
p.drawLine(negTrig_rect.left() + 5, negTrig_rect.top() + 5,
negTrig_rect.center().x(), negTrig_rect.top() + 5);
p.drawLine(negTrig_rect.center().x(), negTrig_rect.top() + 5,
negTrig_rect.center().x(), negTrig_rect.bottom() - 5);
p.drawLine(negTrig_rect.center().x(), negTrig_rect.bottom() - 5,
negTrig_rect.right() - 5, negTrig_rect.bottom() - 5);
p.drawLine(lowTrig_rect.left() + 5, lowTrig_rect.bottom() - 5,
lowTrig_rect.right() - 5, lowTrig_rect.bottom() - 5);
p.drawLine(edgeTrig_rect.left() + 5, edgeTrig_rect.top() + 5,
edgeTrig_rect.center().x() - 2, edgeTrig_rect.top() + 5);
p.drawLine(edgeTrig_rect.center().x() + 2 , edgeTrig_rect.top() + 5,
edgeTrig_rect.right() - 5, edgeTrig_rect.top() + 5);
p.drawLine(edgeTrig_rect.center().x(), edgeTrig_rect.top() + 7,
edgeTrig_rect.center().x(), edgeTrig_rect.bottom() - 7);
p.drawLine(edgeTrig_rect.left() + 5, edgeTrig_rect.bottom() - 5,
edgeTrig_rect.center().x() - 2, edgeTrig_rect.bottom() - 5);
p.drawLine(edgeTrig_rect.center().x() + 2, edgeTrig_rect.bottom() - 5,
edgeTrig_rect.right() - 5, edgeTrig_rect.bottom() - 5);
} else if (_type == DS_GROUP || _type == DS_PROTOCOL) {
const QRectF group_index_rect = get_rect("groupIndex", y, right);
QString index_string;
int last_index;
p.setPen(Qt::transparent);
p.setBrush(dsBlue);
p.drawRect(group_index_rect);
std::list<int>::iterator i = _index_list.begin();
last_index = (*i);
index_string = QString::number(last_index);
while (++i != _index_list.end()) {
if ((*i) == last_index + 1 && index_string.indexOf("-") < 3 && index_string.indexOf("-") > 0)
index_string.replace(QString::number(last_index), QString::number((*i)));
else if ((*i) == last_index + 1)
index_string = QString::number((*i)) + "-" + index_string;
else
index_string = QString::number((*i)) + "," + index_string;
last_index = (*i);
}
p.setPen(Qt::white);
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
} else if (_type == DS_DSO) {
const QRectF vDial_rect = get_rect("vDial", y, right);
const QRectF hDial_rect = get_rect("hDial", y, right);
const QRectF acdc_rect = get_rect("acdc", y, right);
const QRectF chEn_rect = get_rect("chEn", y, right);
QColor vDial_color = _vDialActive ? dsActive : dsDisable;
QColor hDial_color = _hDialActive ? dsActive : dsDisable;
_vDial->paint(p, vDial_rect, vDial_color);
_hDial->paint(p, hDial_rect, hDial_color);
p.setPen(Qt::transparent);
p.setBrush((hover && action == CHEN) ? _colour.darker() : _colour);
p.drawRect(chEn_rect);
p.setPen(Qt::white);
p.drawText(chEn_rect, Qt::AlignCenter | Qt::AlignVCenter, _active ? "EN" : "DIS");
p.setPen(Qt::transparent);
p.setBrush(_active ? ((hover && action == ACDC) ? _colour.darker() : _colour) : dsDisable);
p.drawRect(acdc_rect);
p.setPen(Qt::white);
p.drawText(acdc_rect, Qt::AlignCenter | Qt::AlignVCenter, _acCoupling ? "AC" : "DC");
}
// Paint the label
if (_active) {
const QPointF points[] = {
label_rect.topLeft(),
label_rect.topRight(),
QPointF(right, (_type == DS_DSO) ? _zeroPos : y),
label_rect.bottomRight(),
label_rect.bottomLeft()
};
p.setPen(Qt::transparent);
if (_type == DS_DSO)
p.setBrush(((hover && action == LABEL) || _selected) ? _colour.darker() : _colour);
else
p.setBrush(((hover && action == LABEL) || _selected) ? dsYellow : dsBlue);
p.drawPolygon(points, countof(points));
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
p.setBrush(Qt::transparent);
p.drawLine(label_rect.right(), label_rect.top() + 3,
label_rect.right(), label_rect.bottom() - 3);
// Paint the text
p.setPen(Qt::white);
if (_type == DS_GROUP)
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "G");
else if (_type == DS_ANALOG)
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "A");
else if (_type == DS_PROTOCOL)
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "D");
else
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(_index_list.front()));
}
}
void Signal::paint_trig(QPainter &p, int left, int right, bool hover)
{
if (_type == DS_DSO) {
const QRectF label_rect = get_rect("dsoTrig", -1, right);
// Paint the trig line
if (_trig_en) {
const QPointF points[] = {
QPointF(right - label_rect.width()*1.5, _trig_vpos),
label_rect.topLeft(),
label_rect.topRight(),
label_rect.bottomRight(),
label_rect.bottomLeft()
};
p.setPen(Qt::transparent);
p.setBrush(_colour);
p.drawPolygon(points, countof(points));
// paint the _trig_vpos line
p.setPen(QPen(_colour, hover ? 2 : 1, Qt::DashLine));
p.drawLine(left, _trig_vpos, right - label_rect.width()*1.5, _trig_vpos);
// Paint the text
p.setPen(Qt::white);
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "T");
}
}
}
int Signal::pt_in_rect(int y, int right, const QPoint &point)
{
const QRectF color = get_rect("color", y, right);
const QRectF name = get_rect("name", y, right);
const QRectF posTrig = get_rect("posTrig", y, right);
const QRectF higTrig = get_rect("higTrig", y, right);
const QRectF negTrig = get_rect("negTrig", y, right);
const QRectF lowTrig = get_rect("lowTrig", y, right);
const QRectF edgeTrig = get_rect("edgeTrig", y, right);
const QRectF label = get_rect("label", (_type == DS_DSO) ? _zeroPos : y, right);
const QRectF vDial = get_rect("vDial", y, right);
const QRectF hDial = get_rect("hDial", y, right);
const QRectF chEn = get_rect("chEn", y, right);
const QRectF acdc = get_rect("acdc", y, right);
const QRectF dsoTrig = get_rect("dsoTrig", 0, right);
if (color.contains(point) && _active)
return COLOR;
else if (name.contains(point) && _active)
return NAME;
else if (posTrig.contains(point) && _type == DS_LOGIC)
return POSTRIG;
else if (higTrig.contains(point) && _type == DS_LOGIC)
return HIGTRIG;
else if (negTrig.contains(point) && _type == DS_LOGIC)
return NEGTRIG;
else if (lowTrig.contains(point) && _type == DS_LOGIC)
return LOWTRIG;
else if (edgeTrig.contains(point) && _type == DS_LOGIC)
return EDGETRIG;
else if (label.contains(point) && _active)
return LABEL;
else if (vDial.contains(point) && _type == DS_DSO && _active)
return VDIAL;
else if (hDial.contains(point) && _type == DS_DSO && _active)
return HDIAL;
else if (chEn.contains(point) && _type == DS_DSO)
return CHEN;
else if (acdc.contains(point) && _type == DS_DSO && _active)
return ACDC;
else if (dsoTrig.contains(point) && _type == DS_DSO && _active)
return DSOTRIG;
else
return 0;
return _probe->enabled;
}
void Signal::paint_axis(QPainter &p, int y, int left, int right)
@@ -704,91 +53,5 @@ void Signal::paint_axis(QPainter &p, int y, int left, int right)
p.drawLine(QPointF(left, y + 0.5f), QPointF(right, y + 0.5f));
}
void Signal::compute_text_size(QPainter &p)
{
_text_size = QSize(
p.boundingRect(QRectF(), 0, "99").width(),
p.boundingRect(QRectF(), 0, "99").height());
}
QRectF Signal::get_rect(const char *s, int y, int right)
{
const QSizeF color_size(SquareWidth, SquareWidth);
const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth);
//const QSizeF label_size(_text_size.width() + Margin, SquareWidth);
const QSizeF label_size(SquareWidth, SquareWidth);
if (!strcmp(s, "name"))
return QRectF(
get_leftWidth(),
y - name_size.height() / 2,
name_size.width(), name_size.height());
else if (!strcmp(s, "label"))
return QRectF(
right - 1.5f * label_size.width(),
y - SquareWidth / 2,
label_size.width(), label_size.height());
else if (!strcmp(s, "posTrig"))
return QRectF(
get_leftWidth() + name_size.width() + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "higTrig"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "negTrig"))
return QRectF(
get_leftWidth() + name_size.width() + 2 * SquareWidth + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "lowTrig"))
return QRectF(
get_leftWidth() + name_size.width() + 3 * SquareWidth + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "edgeTrig"))
return QRectF(
get_leftWidth() + name_size.width() + 4 * SquareWidth + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "groupIndex"))
return QRectF(
get_leftWidth() + name_size.width() + Margin,
y - SquareWidth / 2,
SquareWidth * SquareNum, SquareWidth);
else if (!strcmp(s, "vDial"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
y - SquareWidth * SquareNum,
SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1));
else if (!strcmp(s, "hDial"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
y + SquareWidth * 1.5,
SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1));
else if (!strcmp(s, "chEn"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.75 + Margin,
y - SquareWidth / 2,
SquareWidth * 1.5, SquareWidth);
else if (!strcmp(s, "acdc"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*2.75 + Margin,
y - SquareWidth / 2,
SquareWidth * 1.5, SquareWidth);
else if (!strcmp(s, "dsoTrig"))
return QRectF(
right - label_size.width(),
_trig_vpos - SquareWidth / 2,
label_size.width(), label_size.height());
else
return QRectF(
2,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
}
} // namespace view
} // namespace pv

View File

@@ -36,251 +36,48 @@
#include <list>
#include "libsigrok4DSLogic/libsigrok.h"
#include "dsldial.h"
#include "trace.h"
namespace pv {
namespace data {
class SignalData;
class Logic;
class Dso;
class Analog;
class Group;
}
namespace decoder {
class Decoder;
namespace device {
class DevInst;
}
namespace view {
class Signal
class Signal : public Trace
{
private:
static const int SquareWidth = 20;
static const int Margin = 3;
static const int SquareNum = 5;
static const quint64 vDialValueCount = 10;
static const quint64 vDialValueStep = 1000;
static const quint64 vDialUnitCount = 2;
static const quint64 hDialValueCount = 25;
static const quint64 hDialValueStep = 1000;
static const quint64 hDialUnitCount = 4;
static const quint64 vDialValue[vDialValueCount];
static const QString vDialUnit[vDialUnitCount];
static const quint64 hDialValue[hDialValueCount];
static const QString hDialUnit[hDialUnitCount];
public:
static const int COLOR = 1;
static const int NAME = 2;
static const int POSTRIG = 3;
static const int HIGTRIG = 4;
static const int NEGTRIG = 5;
static const int LOWTRIG = 6;
static const int EDGETRIG = 7;
static const int LABEL = 8;
static const int VDIAL = 9;
static const int HDIAL = 10;
static const int CHEN = 11;
static const int ACDC = 12;
static const int DSOTRIG = 13;
static const QColor dsBlue;
static const QColor dsYellow;
static const QColor dsRed;
static const QColor dsGreen;
static const QColor dsGray;
static const QColor dsDisable;
static const QColor dsActive;
static const QColor dsLightBlue;
static const QColor dsLightRed;
static const QPen SignalAxisPen;
enum {DS_LOGIC = 0, DS_ANALOG, DS_GROUP, DS_PROTOCOL, DS_DSO};
protected:
Signal(QString name, int index, int type, int order);
Signal(QString name, std::list<int> index_list, int type, int order, int sec_index);
Signal(boost::shared_ptr<pv::device::DevInst> dev_inst,
const sr_channel * const probe, int type);
public:
int get_type() const;
int get_order() const;
void set_order(int order);
/**
* Gets the header area size
*/
int get_leftWidth() const;
int get_rightWidth() const;
int get_headerHeight() const;
int get_index() const;
std::list<int> &get_index_list();
void set_index_list(std::list<int> index_list);
int get_sec_index() const;
void set_sec_index(int sec_index);
/**
* 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);
/**
* Gets the vertical layout offset of this signal.
*/
int get_v_offset() const;
/**
* Sets the vertical layout offset of this signal.
*/
void set_v_offset(int v_offset);
/**
* Gets the height of this signal.
*/
int get_signalHeight() const;
/**
* Sets the height of this signal.
*/
void set_signalHeight(int height);
/**
* Gets the old vertical layout offset of this signal.
*/
int get_old_v_offset() const;
/**
* Sets the old vertical layout offset of this signal.
*/
void set_old_v_offset(int v_offset);
/**
* Returns true if the signal has been selected by the user.
*/
bool selected() const;
/**
* Selects or deselects the signal.
*/
void select(bool select = true);
/*
*
*/
int get_trig() const;
void set_trig(int trig);
/*
*
*/
bool get_vDialActive() const;
void set_vDialActive(bool active);
bool get_hDialActive() const;
void set_hDialActive(bool active);
bool go_vDialPre();
bool go_vDialNext();
bool go_hDialPre();
bool go_hDialNext();
quint64 get_vDialValue() const;
quint64 get_hDialValue() const;
uint16_t get_vDialSel() const;
uint16_t get_hDialSel() const;
bool get_acCoupling() const;
void set_acCoupling(bool coupling);
bool get_active() const;
void set_active(bool active);
int get_zeroPos() const;
void set_zeroPos(int pos);
int get_windowHeight() const;
void set_windowHeight(int height);
void set_trig_vpos(int value);
int get_trig_vpos() const;
/**
* Paints the signal with a QPainter
* @param p the QPainter to paint into.
* @param y the y-coordinate to draw the signal at
* @param left the x-coordinate of the left edge of the signal
* @param right the x-coordinate of the right edge of the signal
* @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, int y, int left, int right,
double scale, double offset) = 0;
virtual boost::shared_ptr<pv::data::SignalData> data() const = 0;
virtual const std::vector< std::pair<uint64_t, bool> > cur_edges() const = 0;
virtual void set_decoder(pv::decoder::Decoder *decoder) = 0;
virtual pv::decoder::Decoder* get_decoder() = 0;
virtual void del_decoder() = 0;
virtual void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data) = 0;
/**
* Returns true if the trace is visible and enabled.
*/
bool enabled() const;
/**
* Paints the signal label into a QGLWidget.
* @param p the QPainter to paint into.
* @param y the y-coordinate of the signal.
* @param right the x-coordinate of the right edge of the header
* area.
* @param hover true if the label is being hovered over by the mouse.
* @param action mouse position for hover
*/
virtual void paint_label(QPainter &p, int y, int right,
bool hover, int action);
virtual void paint_trig(QPainter &p, int left, int right,
bool hover);
/**
* Determines if a point is in the header rect.
* 1 - in color rect
* 2 - in name rect
* 3 - in posTrig rect
* 4 - in higTrig rect
* 5 - in negTrig rect
* 6 - in lowTrig rect
* 7 - in label rect
* 0 - not
* @param y the y-coordinate of the signal.
* @param right the x-coordinate of the right edge of the header
* area.
* @param point the point to test.
*/
int pt_in_rect(int y, int right,
const QPoint &point);
/**
* Computes the outline rectangle of a label.
* @param p the QPainter to lay out text with.
* @param y the y-coordinate of the signal.
* @param right the x-coordinate of the right edge of the header
* area.
* @return Returns the rectangle of the signal label.
*/
QRectF get_rect(const char *s, int y, int right);
//virtual void paint_label(QPainter &p, int right, bool hover, int action);
protected:
@@ -293,41 +90,9 @@ protected:
*/
void paint_axis(QPainter &p, int y, int left, int right);
private:
/**
* Computes an caches the size of the label text.
*/
void compute_text_size(QPainter &p);
protected:
int _type;
std::list<int> _index_list;
int _order;
int _sec_index;
QString _name;
QColor _colour;
int _v_offset;
int _old_v_offset;
int _signalHeight;
bool _selected;
int _trig;
QSizeF _text_size;
dslDial *_vDial;
dslDial *_hDial;
bool _vDialActive;
bool _hDialActive;
bool _acCoupling;
bool _active;
int _zeroPos;
int _windowHeight;
int _trig_vpos;
bool _trig_en;
boost::shared_ptr<pv::device::DevInst> _dev_inst;
const sr_channel *const _probe;
};
} // namespace view

View File

@@ -0,0 +1,474 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>
* Copyright (C) 2014 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
*
* 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 <assert.h>
#include <math.h>
#include <QApplication>
#include <QFormLayout>
#include <QLineEdit>
#include "trace.h"
#include "view.h"
#include "../device/devinst.h"
#include "../sigsession.h"
namespace pv {
namespace view {
const QColor Trace::dsBlue = QColor(17, 133, 209, 255);
const QColor Trace::dsYellow = QColor(238, 178, 17, 255);
const QColor Trace::dsRed = QColor(213, 15, 37, 255);
const QColor Trace::dsGreen = QColor(0, 153, 37, 200);
const QColor Trace::dsGray = QColor(0x88, 0x8A, 0x85, 60);
const QColor Trace::dsFore = QColor(0xff, 0xff, 0xff, 255);
const QColor Trace::dsBack = QColor(0x16, 0x18, 0x23, 255);
const QColor Trace::dsDisable = QColor(0x88, 0x8A, 0x85, 200);
const QColor Trace::dsActive = QColor(17, 133, 209, 255);
const QColor Trace::dsLightBlue = QColor(17, 133, 209, 150);
const QColor Trace::dsLightRed = QColor(213, 15, 37, 150);
const QPen Trace::SignalAxisPen = QColor(128, 128, 128, 64);
const QPen Trace::AxisPen(QColor(128, 128, 128, 64));
const int Trace::LabelHitPadding = 2;
Trace::Trace(QString name, int type) :
_name(name),
_v_offset(0),
_type(type),
_sec_index(0),
_signalHeight(30),
_trig(0)
{
}
Trace::Trace(QString name, int index, int type) :
_name(name),
_v_offset(0),
_type(type),
_sec_index(0),
_signalHeight(30),
_trig(0)
{
_index_list.push_back(index);
}
Trace::Trace(QString name, std::list<int> index_list, int type, int sec_index) :
_name(name),
_v_offset(0),
_type(type),
_index_list(index_list),
_sec_index(sec_index),
_signalHeight(30),
_trig(0)
{
}
QString Trace::get_name() const
{
return _name;
}
void Trace::set_name(QString name)
{
_name = name;
}
QColor Trace::get_colour() const
{
return _colour;
}
void Trace::set_colour(QColor colour)
{
_colour = colour;
}
int Trace::get_v_offset() const
{
return _v_offset;
}
void Trace::set_v_offset(int v_offset)
{
_v_offset = v_offset;
}
int Trace::get_type() const
{
return _type;
}
int Trace::get_index() const
{
return _index_list.front();
}
std::list<int> &Trace::get_index_list()
{
return _index_list;
}
void Trace::set_index_list(std::list<int> index_list)
{
assert(index_list.size() != 0);
_index_list = index_list;
}
int Trace::get_sec_index() const
{
return _sec_index;
}
void Trace::set_sec_index(int sec_index)
{
_sec_index = sec_index;
}
int Trace::get_old_v_offset() const
{
return _old_v_offset;
}
void Trace::set_old_v_offset(int v_offset)
{
_old_v_offset = v_offset;
}
int Trace::get_zeroPos()
{
return _v_offset - _view->v_offset();
}
int Trace::get_signalHeight() const
{
return _signalHeight;
}
void Trace::set_signalHeight(int height)
{
_signalHeight = height;
}
int Trace::get_trig() const
{
return _trig;
}
void Trace::set_trig(int trig)
{
_trig = trig;
if (trig == 0)
ds_trigger_probe_set(_index_list.front(), 'X', 'X');
else if (trig == POSTRIG)
ds_trigger_probe_set(_index_list.front(), 'R', 'X');
else if (trig == HIGTRIG)
ds_trigger_probe_set(_index_list.front(), '1', 'X');
else if (trig == NEGTRIG)
ds_trigger_probe_set(_index_list.front(), 'F', 'X');
else if (trig == LOWTRIG)
ds_trigger_probe_set(_index_list.front(), '0', 'X');
else if (trig == EDGETRIG)
ds_trigger_probe_set(_index_list.front(), 'C', 'X');
}
void Trace::set_view(pv::view::View *view)
{
assert(view);
_view = view;
}
void Trace::paint_back(QPainter &p, int left, int right)
{
QPen pen(Signal::dsGray);
pen.setStyle(Qt::DotLine);
p.setPen(pen);
const double sigY = get_y();
p.drawLine(left, sigY, right, sigY);
}
void Trace::paint_mid(QPainter &p, int left, int right)
{
(void)p;
(void)left;
(void)right;
}
void Trace::paint_fore(QPainter &p, int left, int right)
{
(void)p;
(void)left;
(void)right;
}
void Trace::paint_label(QPainter &p, int right, bool hover, int action)
{
compute_text_size(p);
const int y = get_y();
const QRectF color_rect = get_rect("color", y, right);
const QRectF name_rect = get_rect("name", y, right);
const QRectF label_rect = get_rect("label", get_zeroPos(), right);
p.setRenderHint(QPainter::Antialiasing);
// Paint the ColorButton
p.setPen(Qt::transparent);
p.setBrush(enabled() ? _colour : dsDisable);
p.drawRect(color_rect);
// Paint the signal name
p.setPen(enabled() ? Qt::black : dsDisable);
p.drawText(name_rect, Qt::AlignLeft | Qt::AlignVCenter, _name);
// Paint the trigButton
paint_type_options(p, right, hover, action);
// Paint the label
if (enabled()) {
const QPointF points[] = {
label_rect.topLeft(),
label_rect.topRight(),
QPointF(right, get_zeroPos()),
label_rect.bottomRight(),
label_rect.bottomLeft()
};
p.setPen(Qt::transparent);
if (_type == DS_DSO)
p.setBrush(((hover && action == LABEL) || selected()) ? _colour.darker() : _colour);
else
p.setBrush(((hover && action == LABEL) || selected()) ? dsYellow : dsBlue);
p.drawPolygon(points, countof(points));
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
p.setBrush(Qt::transparent);
p.drawLine(label_rect.right(), label_rect.top() + 3,
label_rect.right(), label_rect.bottom() - 3);
// Paint the text
p.setPen(Qt::white);
if (_type == DS_GROUP)
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "G");
else if (_type == DS_ANALOG)
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "A");
else if (_type == DS_DECODER)
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "D");
else
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(_index_list.front()));
}
}
void Trace::paint_type_options(QPainter &p, int right, bool hover, int action)
{
(void)p;
(void)right;
(void)hover;
(void)action;
}
int Trace::pt_in_rect(int y, int right, const QPoint &point)
{
const QRectF color = get_rect("color", y, right);
const QRectF name = get_rect("name", y, right);
const QRectF posTrig = get_rect("posTrig", y, right);
const QRectF higTrig = get_rect("higTrig", y, right);
const QRectF negTrig = get_rect("negTrig", y, right);
const QRectF lowTrig = get_rect("lowTrig", y, right);
const QRectF edgeTrig = get_rect("edgeTrig", y, right);
const QRectF label = get_rect("label", get_zeroPos(), right);
const QRectF vDial = get_rect("vDial", y, right);
const QRectF hDial = get_rect("hDial", y, right);
const QRectF chEn = get_rect("chEn", y, right);
const QRectF acdc = get_rect("acdc", y, right);
const QRectF dsoTrig = get_rect("dsoTrig", 0, right);
if (color.contains(point) && enabled())
return COLOR;
else if (name.contains(point) && enabled())
return NAME;
else if (posTrig.contains(point) && _type == DS_LOGIC)
return POSTRIG;
else if (higTrig.contains(point) && _type == DS_LOGIC)
return HIGTRIG;
else if (negTrig.contains(point) && _type == DS_LOGIC)
return NEGTRIG;
else if (lowTrig.contains(point) && _type == DS_LOGIC)
return LOWTRIG;
else if (edgeTrig.contains(point) && _type == DS_LOGIC)
return EDGETRIG;
else if (label.contains(point) && enabled())
return LABEL;
else if (vDial.contains(point) && _type == DS_DSO && enabled())
return VDIAL;
else if (hDial.contains(point) && _type == DS_DSO && enabled())
return HDIAL;
else if (chEn.contains(point) && _type == DS_DSO)
return CHEN;
else if (acdc.contains(point) && _type == DS_DSO && enabled())
return ACDC;
else if (dsoTrig.contains(point) && _type == DS_DSO && enabled())
return DSOTRIG;
else
return 0;
}
void Trace::paint_axis(QPainter &p, int y, int left, int right)
{
p.setPen(SignalAxisPen);
p.drawLine(QPointF(left, y + 0.5f), QPointF(right, y + 0.5f));
}
void Trace::compute_text_size(QPainter &p)
{
_text_size = QSize(
p.boundingRect(QRectF(), 0, "99").width(),
p.boundingRect(QRectF(), 0, "99").height());
}
QRectF Trace::get_rect(const char *s, int y, int right)
{
const QSizeF color_size(SquareWidth, SquareWidth);
const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth);
//const QSizeF label_size(_text_size.width() + Margin, SquareWidth);
const QSizeF label_size(SquareWidth, SquareWidth);
if (!strcmp(s, "name"))
return QRectF(
get_leftWidth(),
y - name_size.height() / 2,
name_size.width(), name_size.height());
else if (!strcmp(s, "label"))
return QRectF(
right - 1.5f * label_size.width(),
y - SquareWidth / 2,
label_size.width(), label_size.height());
else if (!strcmp(s, "posTrig"))
return QRectF(
get_leftWidth() + name_size.width() + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "higTrig"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "negTrig"))
return QRectF(
get_leftWidth() + name_size.width() + 2 * SquareWidth + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "lowTrig"))
return QRectF(
get_leftWidth() + name_size.width() + 3 * SquareWidth + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "edgeTrig"))
return QRectF(
get_leftWidth() + name_size.width() + 4 * SquareWidth + Margin,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
else if (!strcmp(s, "groupIndex"))
return QRectF(
get_leftWidth() + name_size.width() + Margin,
y - SquareWidth / 2,
SquareWidth * SquareNum, SquareWidth);
else if (!strcmp(s, "vDial"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
y - SquareWidth * SquareNum,
SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1));
else if (!strcmp(s, "hDial"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
y + SquareWidth * 1.5,
SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1));
else if (!strcmp(s, "chEn"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.75 + Margin,
y - SquareWidth / 2,
SquareWidth * 1.5, SquareWidth);
else if (!strcmp(s, "acdc"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*2.75 + Margin,
y - SquareWidth / 2,
SquareWidth * 1.5, SquareWidth);
else
return QRectF(
2,
y - SquareWidth / 2,
SquareWidth, SquareWidth);
}
QRectF Trace::get_view_rect() const
{
assert(_view);
return QRectF(0, 0, _view->viewport()->width(), _view->viewport()->height());
}
int Trace::get_y() const
{
return _v_offset - _view->v_offset();
}
QColor Trace::get_text_colour() const
{
return (_colour.lightness() > 64) ? Qt::black : Qt::white;
}
void Trace::on_text_changed(const QString &text)
{
set_name(text);
text_changed();
}
void Trace::on_colour_changed(const QColor &colour)
{
set_colour(colour);
colour_changed();
}
int Trace::rows_size()
{
return 1;
}
int Trace::get_leftWidth() const
{
return SquareWidth + Margin;
}
int Trace::get_rightWidth() const
{
return 2 * Margin + SquareNum * SquareWidth + 1.5 * SquareWidth;
}
int Trace::get_headerHeight() const
{
return SquareWidth;
}
} // namespace view
} // namespace pv

314
DSLogic-gui/pv/view/trace.h Normal file
View File

@@ -0,0 +1,314 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>
* Copyright (C) 2014 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
*
* 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 DSLOGIC_PV_VIEW_TRACE_H
#define DSLOGIC_PV_VIEW_TRACE_H
#include <QColor>
#include <QPainter>
#include <QPen>
#include <QRect>
#include <QString>
#include <stdint.h>
#include "selectableitem.h"
#include "dsldial.h"
class QFormLayout;
namespace pv {
namespace view {
class View;
class Trace : public SelectableItem
{
Q_OBJECT
private:
static const int Margin = 3;
static const int SquareNum = 5;
static const QPen AxisPen;
static const int LabelHitPadding;
public:
static const int SquareWidth = 20;
static const int COLOR = 1;
static const int NAME = 2;
static const int POSTRIG = 3;
static const int HIGTRIG = 4;
static const int NEGTRIG = 5;
static const int LOWTRIG = 6;
static const int EDGETRIG = 7;
static const int LABEL = 8;
static const int VDIAL = 9;
static const int HDIAL = 10;
static const int CHEN = 11;
static const int ACDC = 12;
static const int DSOTRIG = 13;
static const QColor dsBlue;
static const QColor dsYellow;
static const QColor dsRed;
static const QColor dsGreen;
static const QColor dsGray;
static const QColor dsFore;
static const QColor dsBack;
static const QColor dsDisable;
static const QColor dsActive;
static const QColor dsLightBlue;
static const QColor dsLightRed;
static const QPen SignalAxisPen;
protected:
Trace(QString name, int type);
Trace(QString name, int index, int type);
Trace(QString name, std::list<int> index_list, int type, int sec_index);
public:
enum {DS_LOGIC = 0, DS_ANALOG, DS_GROUP, DS_DSO, DS_DECODER};
public:
/**
* Gets the name of this signal.
*/
QString get_name() const;
/**
* Sets the name of the signal.
*/
virtual 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);
/**
* Gets the vertical layout offset of this signal.
*/
int get_v_offset() const;
/**
* Sets the vertical layout offset of this signal.
*/
void set_v_offset(int v_offset);
/**
* Gets trace type
*/
int get_type() const;
/**
* Index process
*/
int get_index() const;
std::list<int> &get_index_list();
void set_index_list(std::list<int> index_list);
int get_sec_index() const;
void set_sec_index(int sec_index);
/**
* Gets the height of this signal.
*/
int get_signalHeight() const;
/**
* Sets the height of this signal.
*/
void set_signalHeight(int height);
/**
* Geom
*/
int get_leftWidth() const;
int get_rightWidth() const;
int get_headerHeight() const;
/**
* Gets the old vertical layout offset of this signal.
*/
int get_old_v_offset() const;
/**
* Sets the old vertical layout offset of this signal.
*/
void set_old_v_offset(int v_offset);
virtual int get_zeroPos();
/**
*
*/
int get_trig() const;
void set_trig(int trig);
/**
* Returns true if the trace is visible and enabled.
*/
virtual bool enabled() const = 0;
virtual void set_view(pv::view::View *view);
/**
* Paints the background layer of the trace with a QPainter
* @param p the QPainter to paint into.
* @param left the x-coordinate of the left edge of the signal
* @param right the x-coordinate of the right edge of the signal
**/
virtual void paint_back(QPainter &p, int left, int right);
/**
* Paints the mid-layer of the trace with a QPainter
* @param p the QPainter to paint into.
* @param left the x-coordinate of the left edge of the signal
* @param right the x-coordinate of the right edge of the signal
**/
virtual void paint_mid(QPainter &p, int left, int right);
/**
* Paints the foreground layer of the trace with a QPainter
* @param p the QPainter to paint into.
* @param left the x-coordinate of the left edge of the signal
* @param right the x-coordinate of the right edge of the signal
**/
virtual void paint_fore(QPainter &p, int left, int right);
/**
* Paints the trace label.
* @param p the QPainter to paint into.
* @param right the x-coordinate of the right edge of the header
* area.
* @param hover true if the label is being hovered over by the mouse.
* @param action mouse position for hover
*/
virtual void paint_label(QPainter &p, int right, bool hover, int action);
/**
* Gets the y-offset of the axis.
*/
int get_y() const;
/**
* Determines if a point is in the header rect.
* 1 - in color rect
* 2 - in name rect
* 3 - in posTrig rect
* 4 - in higTrig rect
* 5 - in negTrig rect
* 6 - in lowTrig rect
* 7 - in label rect
* 0 - not
* @param y the y-coordinate of the signal.
* @param right the x-coordinate of the right edge of the header
* area.
* @param point the point to test.
*/
int pt_in_rect(int y, int right,
const QPoint &point);
/**
* Computes the outline rectangle of a label.
* @param p the QPainter to lay out text with.
* @param y the y-coordinate of the signal.
* @param right the x-coordinate of the right edge of the header
* area.
* @return Returns the rectangle of the signal label.
*/
QRectF get_rect(const char *s, int y, int right);
virtual int rows_size();
virtual QRectF get_view_rect() const;
protected:
/**
* Gets the text colour.
* @remarks This colour is computed by comparing the lightness
* of the trace colour against a threshold to determine whether
* white or black would be more visible.
*/
QColor get_text_colour() const;
/**
* Paints a zero axis across the viewport.
* @param p the QPainter to paint into.
* @param y the y-offset of the axis.
* @param left the x-coordinate of the left edge of the view.
* @param right the x-coordinate of the right edge of the view.
*/
void paint_axis(QPainter &p, int y, int left, int right);
/**
* Paints optoins for different trace type.
* @param p the QPainter to paint into.
* @param right the x-coordinate of the right edge of the header
* area.
* @param hover true if the label is being hovered over by the mouse.
* @param action mouse position for hover
*/
virtual void paint_type_options(QPainter &p, int right, bool hover, int action);
private:
/**
* Computes an caches the size of the label text.
*/
void compute_text_size(QPainter &p);
private slots:
void on_text_changed(const QString &text);
void on_colour_changed(const QColor &colour);
signals:
void visibility_changed();
void text_changed();
void colour_changed();
protected:
pv::view::View *_view;
QString _name;
QColor _colour;
int _v_offset;
int _type;
std::list<int> _index_list;
int _sec_index;
int _old_v_offset;
int _signalHeight;
int _trig;
QSizeF _text_size;
};
} // namespace view
} // namespace pv
#endif // DSLOGIC_PV_VIEW_TRACE_H

View File

@@ -32,12 +32,16 @@
#include <QMouseEvent>
#include <QScrollBar>
#include "decodetrace.h"
#include "header.h"
#include "devmode.h"
#include "ruler.h"
#include "signal.h"
#include "dsosignal.h"
#include "view.h"
#include "viewport.h"
#include "../device/devinst.h"
#include "pv/sigsession.h"
#include "pv/data/logic.h"
#include "pv/data/logicsnapshot.h"
@@ -61,16 +65,13 @@ const QColor View::CursorAreaColour(220, 231, 243);
const QSizeF View::LabelPadding(4, 4);
const int View::WellPixelsPerSample = 1.0f;
const double View::MaxViewRate = 1.0f;
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),
_devmode(new DevMode(*this)),
_scale(1e-8),
_preScale(1e-6),
_maxscale(1e9),
@@ -81,6 +82,7 @@ View::View(SigSession &session, QWidget *parent) :
_updating_scroll(false),
_need_update(false),
_show_cursors(false),
_trig_pos(0),
_hover_point(-1, -1)
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
@@ -90,46 +92,42 @@ View::View(SigSession &session, QWidget *parent) :
connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
this, SLOT(v_scroll_value_changed(int)));
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
setViewport(_viewport);
connect(&_session, SIGNAL(signals_changed()),
this, SLOT(signals_changed()));
connect(&_session, SIGNAL(data_updated()),
this, SLOT(data_updated()));
connect(&_session, SIGNAL(sample_rate_changed(quint64)),
this, SLOT(sample_rate_changed(quint64)));
connect(&_session, SIGNAL(receive_data(quint64)),
this, SLOT(receive_data(quint64)));
connect(&_session, SIGNAL(receive_trigger(quint64)),
this, SLOT(set_trig_pos(quint64)));
connect(_header, SIGNAL(signals_moved()),
this, SLOT(on_signals_moved()));
connect(&_session, SIGNAL(device_setted()),
_devmode, SLOT(set_device()));
connect(_devmode, SIGNAL(mode_changed()),
this, SIGNAL(mode_changed()));
connect(_header, SIGNAL(traces_moved()),
this, SLOT(on_traces_moved()));
connect(_header, SIGNAL(header_updated()),
this, SLOT(header_updated()));
connect(_header, SIGNAL(vDial_changed(quint16)),
this, SLOT(vDial_changed(quint16)));
connect(_header, SIGNAL(hDial_changed(quint16)),
this, SLOT(hDial_changed(quint16)));
connect(_header, SIGNAL(acdc_changed(quint16)),
this, SLOT(acdc_changed(quint16)));
connect(_header, SIGNAL(ch_changed(quint16)),
this, SLOT(ch_changed(quint16)));
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
setViewport(_viewport);
_viewport->installEventFilter(this);
_ruler->installEventFilter(this);
_header->installEventFilter(this);
_devmode->installEventFilter(this);
_viewport->setObjectName(tr("ViewArea_viewport"));
_ruler->setObjectName(tr("ViewArea_ruler"));
_header->setObjectName(tr("ViewArea_header"));
_show_trig_cursor = false;
_trig_cursor = new Cursor(*this, Signal::dsLightRed, 0);
_trig_cursor = new Cursor(*this, Trace::dsLightRed, 0);
_show_search_cursor = false;
_search_pos = 0;
_search_cursor = new Cursor(*this, Signal::dsLightBlue, _search_pos);
_search_cursor = new Cursor(*this, Trace::dsLightBlue, _search_pos);
}
SigSession& View::session()
@@ -184,23 +182,24 @@ void View::zoom(double steps, int offset)
_preOffset = _offset;
const double cursor_offset = _offset + _scale * offset;
if (_session.get_device()->mode != DSO) {
if (_session.get_device()->dev_inst()->mode != DSO) {
_scale *= pow(3.0/2.0, -steps);
_scale = max(min(_scale, _maxscale), _minscale);
} else {
}else {
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
if (steps > 0.5) {
BOOST_FOREACH(const shared_ptr<Signal> s, sigs)
s->go_hDialNext();
} else if(steps < -0.5) {
BOOST_FOREACH(const shared_ptr<Signal> s, sigs)
s->go_hDialPre();
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
shared_ptr<DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<DsoSignal>(s)) {
if(steps > 0.5)
dsoSig->go_hDialPre();
else if (steps < -0.5)
dsoSig->go_hDialNext();
}
}
_scale = sigs.at(0)->get_hDialValue() * pow(10, -9) * Viewport::NumSpanX / _viewport->width();
}
_offset = cursor_offset - _scale * offset;
const double MinOffset = -(_scale * (_viewport->width() * (1 - MaxViewRate)));
const double MaxOffset = _data_length * 1.0f / _session.get_last_sample_rate() -
const double MaxOffset = _session.get_device()->get_sample_time() -
_scale * (_viewport->width() * MaxViewRate);
_offset = max(min(_offset, MaxOffset), MinOffset);
@@ -220,16 +219,16 @@ void View::set_scale_offset(double scale, double offset)
_preScale = _scale;
_preOffset = _offset;
if (_session.get_device()->mode != DSO)
_scale = max(min(scale, _maxscale), _minscale);
_scale = max(min(scale, _maxscale), _minscale);
const double MinOffset = -(_scale * (_viewport->width() * (1 - MaxViewRate)));
const double MaxOffset = _data_length * 1.0f / _session.get_last_sample_rate()
const double MaxOffset = _session.get_device()->get_sample_time()
- _scale * (_viewport->width() * MaxViewRate);
_offset = max(min(offset, MaxOffset), MinOffset);
if (_scale != _preScale || _offset != _preOffset) {
update_scroll();
_header->update();
_ruler->update();
_viewport->update();
}
@@ -245,6 +244,36 @@ void View::set_preScale_preOffset()
set_scale_offset(_preScale, _preOffset);
}
vector< shared_ptr<Trace> > View::get_traces() const
{
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
#ifdef ENABLE_DECODE
const vector< shared_ptr<DecodeTrace> > decode_sigs(
_session.get_decode_signals());
vector< shared_ptr<Trace> > traces(
sigs.size() + decode_sigs.size());
#else
vector< shared_ptr<Trace> > traces(sigs.size());
#endif
vector< shared_ptr<Trace> >::iterator i = traces.begin();
i = copy(sigs.begin(), sigs.end(), i);
#ifdef ENABLE_DECODE
i = copy(decode_sigs.begin(), decode_sigs.end(), i);
#endif
stable_sort(traces.begin(), traces.end(), compare_trace_v_offsets);
return traces;
}
bool View::compare_trace_v_offsets(const shared_ptr<Trace> &a,
const shared_ptr<Trace> &b)
{
assert(a);
assert(b);
return a->get_v_offset() < b->get_v_offset();
}
bool View::cursors_shown() const
{
return _show_cursors;
@@ -283,7 +312,7 @@ void View::show_search_cursor(bool show)
void View::set_trig_pos(quint64 trig_pos)
{
const double time = trig_pos * 1.0f / _session.get_last_sample_rate();
const double time = trig_pos * 1.0f / _session.get_device()->get_sample_rate();
_trig_pos = trig_pos;
_trig_cursor->set_time(time);
_show_trig_cursor = true;
@@ -296,7 +325,7 @@ void View::set_search_pos(uint64_t search_pos)
{
//assert(search_pos >= 0);
const double time = search_pos * 1.0f / _session.get_last_sample_rate();
const double time = search_pos * 1.0f / _session.get_device()->get_sample_rate();
_search_pos = search_pos;
_search_cursor->set_time(time);
set_scale_offset(_scale, time - _scale * _viewport->width() / 2);
@@ -321,15 +350,15 @@ const QPointF& View::hover_point() const
void View::normalize_layout()
{
const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
const vector< shared_ptr<Trace> > traces(get_traces());
int v_min = INT_MAX;
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
v_min = min(s->get_v_offset(), v_min);
BOOST_FOREACH(const shared_ptr<Trace> t, traces)
v_min = min(t->get_v_offset(), v_min);
const int delta = -min(v_min, 0);
BOOST_FOREACH(boost::shared_ptr<Signal> s, sigs)
s->set_v_offset(s->get_v_offset() + delta);
BOOST_FOREACH(shared_ptr<Trace> t, traces)
t->set_v_offset(t->get_v_offset() + delta);
verticalScrollBar()->setSliderPosition(_v_offset + delta);
v_scroll_value_changed(verticalScrollBar()->sliderPosition());
@@ -343,16 +372,16 @@ int View::get_spanY()
int View::get_signalHeight()
{
return SignalHeight;
return _signalHeight;
}
void View::get_scroll_layout(double &length, double &offset) const
{
const boost::shared_ptr<data::SignalData> sig_data = _session.get_data();
if (!sig_data)
const set< shared_ptr<data::SignalData> > data_set = _session.get_data();
if (data_set.empty())
return;
length = _data_length / (sig_data->get_samplerate() * _scale);
length = _session.get_device()->get_sample_time() / _scale;
offset = _offset / _scale;
}
@@ -385,31 +414,63 @@ void View::update_scroll()
// Set the vertical scrollbar
verticalScrollBar()->setPageStep(areaSize.height());
verticalScrollBar()->setRange(0,
_viewport->get_total_height() + SignalMargin -
areaSize.height());
_viewport->get_total_height() - areaSize.height());
}
void View::reset_signal_layout()
void View::update_scale()
{
if (_session.get_signals().size())
SignalHeight =
((_viewport->height() - horizontalScrollBar()->height()) /
_session.get_signals().size())
- 2 * SignalMargin;
const uint64_t sample_rate = _session.get_device()->get_sample_rate();
assert(sample_rate > 0);
int offset = SignalMargin + SignalHeight;
_spanY = SignalHeight + 2 * SignalMargin;
if (_session.get_device()->dev_inst()->mode != DSO) {
_scale = (1.0f / sample_rate) / WellPixelsPerSample;
_maxscale = _session.get_device()->get_sample_time() / (get_max_width() * MaxViewRate);
} else {
_scale = _session.get_device()->get_time_base() * 10.0f / get_max_width() * pow(10, -9);
_maxscale = 1e9;
}
const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
BOOST_FOREACH(boost::shared_ptr<Signal> s, sigs) {
s->set_signalHeight(SignalHeight);
s->set_windowHeight(_viewport->height());
//s->set_v_offset(offset);
//offset += SignalHeight + 2 * SignalMargin;
s->set_v_offset(offset + s->get_order() * _spanY);
s->set_zeroPos(_viewport->height()*0.5);
_minscale = (1.0f / sample_rate) / MaxPixelsPerSample;
_offset = 0;
_preScale = _scale;
_preOffset = _offset;
const double time = _trig_pos * 1.0f / sample_rate;
_trig_cursor->set_time(time);
_ruler->update();
_viewport->update();
}
void View::signals_changed()
{
int total_rows = 0;
const vector< shared_ptr<Trace> > traces(get_traces());
BOOST_FOREACH(const shared_ptr<Trace> t, traces)
{
assert(t);
if (dynamic_pointer_cast<DsoSignal>(t) ||
t->enabled())
total_rows += t->rows_size();
}
const double height = (_viewport->height()
- horizontalScrollBar()->height()
- 2 * SignalMargin * traces.size()) * 1.0 / total_rows;
_signalHeight = (int)((height <= 0) ? 1 : height);
_spanY = _signalHeight + 2 * SignalMargin;
int next_v_offset = SignalMargin;
BOOST_FOREACH(shared_ptr<Trace> t, traces) {
t->set_view(this);
const double traceHeight = _signalHeight*t->rows_size();
t->set_signalHeight((int)traceHeight);
t->set_v_offset(next_v_offset + 0.5 * traceHeight + SignalMargin);
next_v_offset += traceHeight + 2 * SignalMargin;
}
normalize_layout();
header_updated();
normalize_layout();
}
bool View::eventFilter(QObject *object, QEvent *event)
@@ -467,14 +528,13 @@ int View::headerWidth()
QFont font = QApplication::font();
QFontMetrics fm(font);
int fontWidth=fm.width("A");
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
if (!sigs.empty()){
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
maxNameWidth = max(s->get_name().length() * fontWidth, maxNameWidth);
maxLeftWidth = max(s->get_leftWidth(), maxLeftWidth);
maxRightWidth = max(s->get_rightWidth(), maxRightWidth);
const vector< shared_ptr<Trace> > traces(get_traces());
if (!traces.empty()){
BOOST_FOREACH(const shared_ptr<Trace> t, traces) {
maxNameWidth = max(fm.boundingRect(t->get_name()).width(), maxNameWidth);
maxLeftWidth = max(t->get_leftWidth(), maxLeftWidth);
maxRightWidth = max(t->get_rightWidth(), maxRightWidth);
}
}
maxNameWidth = max(_header->get_nameEditWidth(), maxNameWidth);
@@ -489,11 +549,14 @@ void View::resizeEvent(QResizeEvent*)
{
update_margins();
update_scroll();
if (_session.get_capture_state() == SigSession::Stopped) {
_maxscale = (_data_length * 1.0f / _session.get_last_sample_rate()) / (_viewport->width() * MaxViewRate);
_scale = min(_scale, _maxscale);
}
reset_signal_layout();
if (_session.get_device()->dev_inst()->mode == DSO)
_scale = _session.get_device()->get_time_base() * pow(10, -9) * DS_CONF_DSO_HDIVS / get_max_width();
_maxscale = _session.get_device()->get_sample_time() / (get_max_width() * MaxViewRate);
_scale = min(_scale, _maxscale);
signals_changed();
_ruler->update();
_header->header_resize();
_need_update = true;
}
@@ -506,7 +569,7 @@ void View::h_scroll_value_changed(int value)
_preOffset = _offset;
const double MinOffset = -(_scale * (_viewport->width() * (1 - MaxViewRate)));
const double MaxOffset = _data_length * 1.0f / _session.get_last_sample_rate()
const double MaxOffset = _session.get_device()->get_sample_time()
- _scale * (_viewport->width() * MaxViewRate);
const int range = horizontalScrollBar()->maximum();
@@ -533,19 +596,8 @@ void View::v_scroll_value_changed(int value)
_viewport->update();
}
void View::signals_changed()
{
reset_signal_layout();
}
void View::data_updated()
{
// Get the new data length
_data_length = max(_session.get_total_sample_len(), (quint64)1000);
_maxscale = (_data_length * 1.0f / _session.get_last_sample_rate()) / (_viewport->width() * MaxViewRate);
if(_session.get_device()->mode != DSO)
_scale = min(_scale, _maxscale);
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
update_margins();
@@ -563,6 +615,8 @@ void View::update_margins()
_viewport->width(), _viewport->y());
_header->setGeometry(0, _viewport->y(),
_viewport->x(), _viewport->height());
_devmode->setGeometry(0, 0,
_viewport->x(), _viewport->y());
}
void View::header_updated()
@@ -577,33 +631,18 @@ void View::header_updated()
_header->update();
}
void View::sample_rate_changed(quint64 sample_rate)
{
assert(sample_rate > 0);
if (_session.get_device()->mode != DSO)
_scale = (1.0f / sample_rate) / WellPixelsPerSample;
_minscale = (1.0f / sample_rate) / (_viewport->width() * MaxViewRate);
_offset = 0;
_preScale = _scale;
_preOffset = _offset;
_ruler->update();
_viewport->update();
}
void View::marker_time_changed()
{
_ruler->update();
_viewport->update();
}
void View::on_signals_moved()
void View::on_traces_moved()
{
update_scroll();
_need_update = true;
_viewport->update();
//signals_moved();
//traces_moved();
}
/*
@@ -689,16 +728,6 @@ QString View::get_cm_delta(int index1, int index2)
get_cursor_time(index2)));
}
QString View::get_cm_delta_cnt(int index1, int index2)
{
if (index1 == index2)
return "0";
return QString::number(
floor(abs(get_cursor_time(index1) -
get_cursor_time(index2)) * _session.get_data()->get_samplerate()));
}
double View::get_cursor_time(int index)
{
assert(index < (int)_cursorList.size());
@@ -713,6 +742,15 @@ double View::get_cursor_time(int index)
}
}
uint64_t View::get_cursor_samples(int index)
{
const double time = get_cursor_time(index);
const uint64_t sample_rate = _session.get_device()->get_sample_limit();
assert(sample_rate !=0);
return time*sample_rate;
}
void View::on_mouse_moved()
{
mouse_moved();
@@ -733,38 +771,15 @@ void View::on_state_changed(bool stop)
_viewport->stop_trigger_timer();
}
void View::vDial_changed(uint16_t channel)
{
if (channel == 0)
_session.set_dso_ctrl(SR_CONF_VDIV0);
else
_session.set_dso_ctrl(SR_CONF_VDIV1);
}
void View::hDial_changed(uint16_t channel)
int View::get_max_width()
{
int max_width = 0;
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
_session.set_dso_ctrl(SR_CONF_TIMEBASE);
_scale = sigs.at(channel)->get_hDialValue() * pow(10, -9) * Viewport::NumSpanX / _viewport->width();
_ruler->update();
_viewport->update();
update_scroll();
}
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
max_width = max((double)max_width, s->get_view_rect().width());
}
void View::acdc_changed(uint16_t channel)
{
if (channel == 0)
_session.set_dso_ctrl(SR_CONF_COUPLING0);
else
_session.set_dso_ctrl(SR_CONF_COUPLING1);
}
void View::ch_changed(uint16_t channel)
{
if (channel == 0)
_session.set_dso_ctrl(SR_CONF_EN_CH0);
else
_session.set_dso_ctrl(SR_CONF_EN_CH1);
return max_width;
}
} // namespace view

View File

@@ -26,9 +26,16 @@
#include <stdint.h>
#include <set>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <QAbstractScrollArea>
#include <QSizeF>
#include "../data/signaldata.h"
#include "cursor.h"
#include "signal.h"
@@ -39,7 +46,9 @@ class SigSession;
namespace view {
class Header;
class DevMode;
class Ruler;
class Trace;
class Viewport;
class View : public QAbstractScrollArea {
@@ -60,9 +69,9 @@ public:
static const QSizeF LabelPadding;
static const int WellPixelsPerSample;
static const double MaxViewRate;
static const int WellPixelsPerSample = 10.0f;
static const double MaxViewRate = 1.0f;
static const int MaxPixelsPerSample = 100.0f;
public:
explicit View(SigSession &session, QWidget *parent = 0);
@@ -92,6 +101,8 @@ public:
void set_scale_offset(double scale, double offset);
void set_preScale_preOffset();
std::vector< boost::shared_ptr<Trace> > get_traces() const;
/**
* Returns true if cursors are displayed. false otherwise.
*/
@@ -146,39 +157,45 @@ public:
void set_need_update(bool need_update);
bool need_update() const;
uint64_t get_cursor_samples(int index);
QString get_mm_width();
QString get_mm_period();
QString get_mm_freq();
QString get_cm_time(int index);
QString get_cm_delta(int index1, int index2);
QString get_cm_delta_cnt(int index1, int index2);
void on_mouse_moved();
void on_cursor_moved();
void on_state_changed(bool stop);
int get_max_width();
signals:
void hover_point_changed();
void signals_moved();
void traces_moved();
void cursor_update();
void mouse_moved();
void cursor_moved();
void mode_changed();
private:
void get_scroll_layout(double &length, double &offset) const;
void update_scroll();
void reset_signal_layout();
void update_margins();
double get_cursor_time(int index);
static bool compare_trace_v_offsets(
const boost::shared_ptr<pv::view::Trace> &a,
const boost::shared_ptr<pv::view::Trace> &b);
private:
bool eventFilter(QObject *object, QEvent *event);
@@ -188,32 +205,25 @@ private:
public slots:
void set_measure_en(int enable);
void hDial_changed(quint16 channel);
void signals_changed();
void data_updated();
void update_scale();
private slots:
void h_scroll_value_changed(int value);
void v_scroll_value_changed(int value);
void signals_changed();
void data_updated();
void marker_time_changed();
void on_signals_moved();
void on_traces_moved();
void header_updated();
void sample_rate_changed(quint64 sample_rate);
void receive_data(quint64 length);
void set_trig_pos(quint64 trig_pos);
void vDial_changed(quint16 channel);
void acdc_changed(quint16 channel);
void ch_changed(quint16 channel);
private:
SigSession &_session;
@@ -221,8 +231,7 @@ private:
Viewport *_viewport;
Ruler *_ruler;
Header *_header;
uint64_t _data_length;
DevMode *_devmode;
/// The view time scale in seconds per pixel.
double _scale;
@@ -235,7 +244,7 @@ private:
double _preOffset;
int _spanY;
int SignalHeight;
int _signalHeight;
int _v_offset;
bool _updating_scroll;

View File

@@ -26,6 +26,8 @@
#include "ruler.h"
#include "signal.h"
#include "dsosignal.h"
#include "../device/devinst.h"
#include "../data/logic.h"
#include "../data/logicsnapshot.h"
#include "../sigsession.h"
@@ -41,11 +43,6 @@ using namespace std;
namespace pv {
namespace view {
const int Viewport::HitCursorMargin = 3;
const int Viewport::NumSpanY = 5;
const int Viewport::NumMiniSpanY = 5;
const int Viewport::NumSpanX = 10;
Viewport::Viewport(View &parent) :
QWidget(&parent),
_view(parent),
@@ -70,8 +67,8 @@ Viewport::Viewport(View &parent) :
triggered = false;
timer_cnt = 0;
connect(&_view, SIGNAL(signals_moved()),
this, SLOT(on_signals_moved()));
connect(&_view, SIGNAL(traces_moved()),
this, SLOT(on_traces_moved()));
connect(&trigger_timer, SIGNAL(timeout()),
this, SLOT(on_trigger_timer()));
}
@@ -79,32 +76,42 @@ Viewport::Viewport(View &parent) :
int Viewport::get_total_height() const
{
int h = 0;
const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
assert(s);
//h = max(s->get_v_offset() + _view.get_signalHeight(), h);
h = max(s->get_v_offset(), h);
}
const vector< shared_ptr<Trace> > traces(_view.get_traces());
BOOST_FOREACH(const shared_ptr<Trace> t, traces) {
assert(t);
h += (int)(t->get_signalHeight());
}
h += 2 * View::SignalMargin;
return h;
}
QPoint Viewport::get_mouse_point() const
{
return _mouse_point;
}
void Viewport::paintEvent(QPaintEvent *event)
{
(void)event;
using pv::view::Signal;
int i, j;
QStyleOption o;
o.initFrom(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
//QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
const vector< shared_ptr<Trace> > traces(_view.get_traces());
BOOST_FOREACH(const shared_ptr<Trace> t, traces)
{
assert(t);
t->paint_back(p, 0, width());
}
if (_view.session().get_device()->mode == LOGIC) {
p.setRenderHint(QPainter::Antialiasing);
if (_view.session().get_device()->dev_inst()->mode == LOGIC) {
switch(_view.session().get_capture_state()) {
case SigSession::Init:
break;
@@ -122,79 +129,23 @@ void Viewport::paintEvent(QPaintEvent *event)
paintSignals(p);
}
BOOST_FOREACH(const shared_ptr<Trace> t, traces)
{
assert(t);
if (t->enabled())
t->paint_fore(p, 0, width());
}
p.setRenderHint(QPainter::Antialiasing, false);
if (_view.get_signalHeight() != _curSignalHeight)
_curSignalHeight = _view.get_signalHeight();
const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
assert(s);
//paint_axis(p, y, left, right);
p.setPen(Signal::dsGray);
const double sigY = s->get_v_offset() - _view.v_offset();
if (s->get_type() == Signal::DS_ANALOG) {
p.drawLine(0, sigY, width(), sigY);
const double spanY = (s->get_signalHeight()) * 1.0f / NumSpanY;
for (i = 1; i <= NumSpanY; i++) {
const double posY = sigY - spanY * i;
p.drawLine(0, posY, width(), posY);
const double miniSpanY = spanY / NumMiniSpanY;
for (j = 1; j < NumMiniSpanY; j++) {
p.drawLine(width() / 2.0f - 10, posY + miniSpanY * j,
width() / 2.0f + 10, posY + miniSpanY * j);
}
}
const double spanX = width() * 1.0f / NumSpanX;
for (i = 1; i < NumSpanX; i++) {
p.drawLine(0 + spanX * i, sigY,
0 + spanX * i, sigY - s->get_signalHeight());
}
} else if (s->get_type() == Signal::DS_LOGIC) {
p.drawLine(0, sigY + 10, width(), sigY + 10);
}
}
if (_view.session().get_device()->mode == DSO) {
p.setPen(Signal::dsGray);
p.setPen(Qt::DotLine);
const double spanY =height() * 1.0f / 10;
for (i = 1; i < 11; i++) {
const double posY = spanY * i;
p.drawLine(0, posY, width(), posY);
const double miniSpanY = spanY / 5;
for (j = 1; j < 5; j++) {
p.drawLine(width() / 2.0f - 10, posY - miniSpanY * j,
width() / 2.0f + 10, posY - miniSpanY * j);
}
}
const double spanX = width() * 1.0f / 10;
for (i = 1; i < 11; i++) {
const double posX = spanX * i;
p.drawLine(posX, 0,
posX, height());
const double miniSpanX = spanX / 5;
for (j = 1; j < 5; j++) {
p.drawLine(posX - miniSpanX * j, height() / 2.0f - 10,
posX - miniSpanX * j, height() / 2.0f + 10);
}
}
}
p.end();
}
void Viewport::paintSignals(QPainter &p)
{
const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
// const vector< boost::shared_ptr<Signal> > pro_sigs(
// _view.session().get_pro_signals());
// Plot the signal
const int v_offset = _view.v_offset();
const vector< shared_ptr<Trace> > traces(_view.get_traces());
if (_view.scale() != _curScale ||
_view.offset() != _curOffset ||
_view.get_signalHeight() != _curSignalHeight ||
@@ -208,29 +159,17 @@ void Viewport::paintSignals(QPainter &p)
QPainter dbp(&pixmap);
dbp.initFrom(this);
p.setRenderHint(QPainter::Antialiasing, false);
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
assert(s);
if (s->get_active())
s->paint(dbp, ((s->get_type() == Signal::DS_DSO) ? s->get_zeroPos() + height()*0.5 : s->get_v_offset() - v_offset), 0, width(),
_view.scale(), _view.offset());
BOOST_FOREACH(const shared_ptr<Trace> t, traces)
{
assert(t);
if (t->enabled())
t->paint_mid(dbp, 0, width());
}
// p.setRenderHint(QPainter::Antialiasing);
// BOOST_FOREACH(const boost::shared_ptr<Signal> s, pro_sigs) {
// assert(s);
// s->paint(dbp, s->get_v_offset() - v_offset, 0, width(),
// _view.scale(), _view.offset());
// }
_view.set_need_update(false);
}
p.drawPixmap(0, 0, pixmap);
// plot trig line in DSO mode
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
assert(s);
if (s->get_active() && s->get_type() == Signal::DS_DSO)
s->paint_trig(p, 0, width(), qAbs(_mouse_point.y() - s->get_trig_vpos()) <= HitCursorMargin );
}
// plot cursors
if (_view.cursors_shown()) {
list<Cursor*>::iterator i = _view.get_cursorList().begin();
@@ -242,21 +181,6 @@ void Viewport::paintSignals(QPainter &p)
(*i)->paint(p, rect(), 1);
else
(*i)->paint(p, rect(), 0);
if (!_view.session().get_data()->get_snapshots().empty()) {
uint64_t _hit_sample = floor((*i)->time() * _view.session().get_last_sample_rate());
if (_hit_sample > _total_receive_len) {
(*i)->set_time(0);
} else {
QRectF valueRect = QRectF(cursorX + 3, height()-20, 100, 20);
p.setPen(Qt::black);
p.drawLine(cursorX, height()-13, cursorX + 3, height()-10);
p.drawLine(cursorX, height()-7, cursorX + 3, height()-10);
p.drawText(valueRect, Qt::AlignLeft | Qt::AlignVCenter,
"Value: " +
QString::number((uint16_t)_view.session().get_data()->get_snapshots().front()->get_sample(_hit_sample)));
}
}
i++;
}
}
@@ -270,7 +194,7 @@ void Viewport::paintSignals(QPainter &p)
// plot zoom rect
if (_zoom_rect_visible) {
p.setPen(Qt::NoPen);
p.setBrush(Signal::dsLightBlue);
p.setBrush(Trace::dsLightBlue);
p.drawRect(_zoom_rect);
}
@@ -284,14 +208,15 @@ void Viewport::paintProgress(QPainter &p)
{
using pv::view::Signal;
const quint64 _total_sample_len = _view.session().get_total_sample_len();
const quint64 _total_sample_len = _view.session().get_device()->get_sample_limit();
double progress = -(_total_receive_len * 1.0f / _total_sample_len * 360 * 16);
int captured_progress = 0;
p.setPen(Qt::gray);
const QPoint cenPos = QPoint(width() / 2, height() / 2);
const int radius = min(0.3 * width(), 0.3 * height());
p.drawEllipse(cenPos, radius - 2, radius - 2);
p.setPen(QPen(Signal::dsGreen, 4, Qt::SolidLine));
p.setPen(QPen(Trace::dsGreen, 4, Qt::SolidLine));
p.drawArc(cenPos.x() - radius, cenPos.y() - radius, 2* radius, 2 * radius, 180 * 16, progress);
p.setPen(Qt::gray);
@@ -356,21 +281,53 @@ void Viewport::paintProgress(QPainter &p)
const int trigger_radius = min(0.02 * width(), 0.02 * height());
p.setPen(Qt::NoPen);
p.setBrush((timer_cnt % 3) == 0 ? Signal::dsLightBlue : Signal::dsGray);
p.setBrush((timer_cnt % 3) == 0 ? Trace::dsLightBlue : Trace::dsGray);
p.drawEllipse(cenLeftPos, trigger_radius, trigger_radius);
p.setBrush((timer_cnt % 3) == 1 ? Signal::dsLightBlue : Signal::dsGray);
p.setBrush((timer_cnt % 3) == 1 ? Trace::dsLightBlue : Trace::dsGray);
p.drawEllipse(cenPos, trigger_radius, trigger_radius);
p.setBrush((timer_cnt % 3) == 2 ? Signal::dsLightBlue : Signal::dsGray);
p.setBrush((timer_cnt % 3) == 2 ? Trace::dsLightBlue : Trace::dsGray);
p.drawEllipse(cenRightPos, trigger_radius, trigger_radius);
sr_status status;
if (sr_status_get(_view.session().get_device()->dev_inst(), &status) == SR_OK){
const bool triggred = status.trig_hit & 0x01;
const uint32_t captured_cnt = (status.captured_cnt0 +
(status.captured_cnt1 << 8) +
(status.captured_cnt2 << 16) +
(status.captured_cnt3 << 24));
captured_progress = captured_cnt * 100.0 / _total_sample_len;
p.setPen(Trace::dsLightBlue);
QFont font=p.font();
font.setPointSize(10);
font.setBold(true);
p.setFont(font);
QRect status_rect = QRect(cenPos.x() - radius, cenPos.y() + radius * 0.4, radius * 2, radius * 0.5);
if (triggred)
p.drawText(status_rect,
Qt::AlignCenter | Qt::AlignVCenter,
"Triggered! " + QString::number(captured_progress)+"% Captured");
else
p.drawText(status_rect,
Qt::AlignCenter | Qt::AlignVCenter,
"Waiting for Trigger! " + QString::number(captured_progress)+"% Captured");
}
} else {
const int progress100 = ceil(progress / -3.6 / 16);
p.setPen(QColor(0, 0, 0, 50));
p.setPen(Trace::dsGreen);
QFont font=p.font();
font.setPointSize(50);
font.setBold(true);
p.setFont(font);
p.drawText(rect(), Qt::AlignCenter | Qt::AlignVCenter, QString::number(progress100)+"%");
}
p.setPen(QPen(Trace::dsLightBlue, 4, Qt::SolidLine));
const int int_radius = max(radius - 4, 0);
p.drawArc(cenPos.x() - int_radius, cenPos.y() - int_radius, 2* int_radius, 2 * int_radius, 180 * 16, -captured_progress*3.6*16);
}
void Viewport::mousePressEvent(QMouseEvent *event)
@@ -403,16 +360,14 @@ void Viewport::mousePressEvent(QMouseEvent *event)
const vector< shared_ptr<Signal> > sigs(_view.session().get_signals());
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
assert(s);
if (s->get_active() &&
s->get_type() == Signal::DS_DSO &&
qAbs(_mouse_point.y() - s->get_trig_vpos()) <= HitCursorMargin) {
if (_drag_sig)
_drag_sig.reset();
else
_drag_sig = s;
shared_ptr<DsoSignal> dsoSig;
if ((dsoSig = dynamic_pointer_cast<DsoSignal>(s)) &&
dsoSig->get_trig_rect(0, width()).contains(_mouse_point)) {
_drag_sig = s;
break;
}
}
update();
}
}
@@ -427,38 +382,32 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
}
if (event->buttons() & Qt::LeftButton) {
_view.set_scale_offset(_view.scale(),
_mouse_down_offset +
(_mouse_down_point - event->pos()).x() *
_view.scale());
measure();
if (_drag_sig) {
shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(_drag_sig))
dsoSig->set_trig_vpos(_mouse_point.y());
} else {
_view.set_scale_offset(_view.scale(),
_mouse_down_offset +
(_mouse_down_point - event->pos()).x() *
_view.scale());
measure();
}
}
if (!(event->buttons() || Qt::NoButton)) {
if (_drag_sig) {
uint16_t trig_value = 0;
int vpos = _mouse_point.y();
if (vpos < 0)
vpos = 0;
else if (vpos > height())
vpos = height();
_drag_sig->set_trig_vpos(vpos);
const vector< shared_ptr<Signal> > sigs(_view.session().get_signals());
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
assert(s);
if (s->get_active() &&
s->get_type() == Signal::DS_DSO) {
trig_value += (((uint16_t)(255 - s->get_trig_vpos()*1.0/height()*255)) << 8*s->get_index());
}
}
sr_config_set(_view.session().get_device(),
SR_CONF_TRIGGER_VALUE, g_variant_new_uint16(trig_value));
}
uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor();
if (_view.cursors_shown() && grabbed_marker) {
grabbed_marker->set_time(_view.offset() + _view.hover_point().x() * _view.scale());
const double cur_time = _view.offset() + _view.hover_point().x() * _view.scale();
const double pos = cur_time * sample_rate;
const double pos_delta = pos - (int)pos;
if ( pos_delta < HitCursorTimeMargin)
grabbed_marker->set_time(1.0 / sample_rate * floor(pos));
else if (pos_delta > (1.0 - HitCursorTimeMargin))
grabbed_marker->set_time(1.0 / sample_rate * ceil(pos));
else
grabbed_marker->set_time(cur_time);
}
measure();
}
@@ -479,12 +428,17 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
_view.set_scale_offset(newScale, newOffset);
}
if(_drag_sig)
_drag_sig.reset();
update();
}
void Viewport::mouseDoubleClickEvent(QMouseEvent *event)
{
assert (event);
(void)event;
if (_view.scale() == _view.get_maxscale())
_view.set_preScale_preOffset();
else
@@ -518,7 +472,7 @@ void Viewport::leaveEvent(QEvent *)
update();
}
void Viewport::on_signals_moved()
void Viewport::on_traces_moved()
{
update();
}
@@ -530,8 +484,8 @@ void Viewport::set_receive_len(quint64 length)
start_trigger_timer(333);
} else {
stop_trigger_timer();
if (_total_receive_len + length > _view.session().get_total_sample_len())
_total_receive_len = _view.session().get_total_sample_len();
if (_total_receive_len + length > _view.session().get_device()->get_sample_limit())
_total_receive_len = _view.session().get_device()->get_sample_limit();
else
_total_receive_len += length;
}
@@ -540,19 +494,21 @@ void Viewport::set_receive_len(quint64 length)
void Viewport::measure()
{
uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
assert(s);
const int curY = _view.hover_point().y();
const double curX = _view.hover_point().x();
if (curY <= View::SignalMargin || s->get_type() != Signal::DS_LOGIC) {
if (curY <= View::SignalMargin || s->get_type() != Trace::DS_LOGIC) {
_measure_shown = false;
break;
} else if ( curY < s->get_v_offset() &&
curY > (s->get_v_offset() - _view.get_signalHeight())) {
} else if ( curY < s->get_y() + _view.get_signalHeight() * 0.5 &&
curY > (s->get_y() - _view.get_signalHeight() * 0.5)) {
if (s->cur_edges().size() > 2) {
const double pixels_offset = _view.offset() / _view.scale();
const double samples_per_pixel = _view.session().get_last_sample_rate() * _view.scale();
const double samples_per_pixel = sample_rate * _view.scale();
uint64_t findIndex = curX / width() * s->cur_edges().size();
uint64_t left_findIndex = 0;
@@ -586,7 +542,7 @@ void Viewport::measure()
_cur_thdX = 0;
}
_cur_midY = s->get_v_offset() - 0.5 * _view.get_signalHeight();
_cur_midY = s->get_y();
break;
}
} else if (curX < pre_edge_x) {
@@ -600,8 +556,8 @@ void Viewport::measure()
}
}
break;
} else if (curY >= s->get_v_offset() &&
curY <= (s->get_v_offset() + 2 * View::SignalMargin)){
} else if (curY >= s->get_y() + _view.get_signalHeight() &&
curY <= (s->get_y() + _view.get_signalHeight() + 2 * View::SignalMargin)){
_measure_shown = false;
break;
}else {
@@ -613,8 +569,8 @@ void Viewport::measure()
const uint64_t delta_sample = _nxt_sample - _cur_sample;
const uint64_t delta1_sample = _thd_sample - _cur_sample;
//assert(delta_sample >= 0);
const double delta_time = delta_sample * 1.0f / _view.session().get_last_sample_rate();
const double delta1_time = delta1_sample * 1.0f / _view.session().get_last_sample_rate();
const double delta_time = delta_sample * 1.0f / sample_rate;
const double delta1_time = delta1_sample * 1.0f / sample_rate;
const int order = (int)floorf(log10f(delta_time));
unsigned int prefix = (15 + order) / 3;
assert(prefix < 9);

View File

@@ -46,16 +46,16 @@ class Viewport : public QWidget
Q_OBJECT
public:
static const int HitCursorMargin;
static const int NumSpanY;
static const int NumMiniSpanY;
static const int NumSpanX;
static const int HitCursorMargin = 10;
static const double HitCursorTimeMargin = 0.3;
public:
explicit Viewport(View &parent);
int get_total_height() const;
QPoint get_mouse_point() const;
void set_receive_len(quint64 length);
QString get_mm_width();
@@ -85,7 +85,7 @@ private:
void measure();
private slots:
void on_signals_moved();
void on_traces_moved();
void on_trigger_timer();
private: