forked from Ivasoft/DSView
v0.4 release
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
833
DSLogic-gui/pv/view/decodetrace.cpp
Normal file
833
DSLogic-gui/pv/view/decodetrace.cpp
Normal 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
|
||||
204
DSLogic-gui/pv/view/decodetrace.h
Normal file
204
DSLogic-gui/pv/view/decodetrace.h
Normal 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
|
||||
194
DSLogic-gui/pv/view/devmode.cpp
Normal file
194
DSLogic-gui/pv/view/devmode.cpp
Normal 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
|
||||
90
DSLogic-gui/pv/view/devmode.h
Normal file
90
DSLogic-gui/pv/view/devmode.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
57
DSLogic-gui/pv/view/selectableitem.cpp
Normal file
57
DSLogic-gui/pv/view/selectableitem.cpp
Normal 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
|
||||
69
DSLogic-gui/pv/view/selectableitem.h
Normal file
69
DSLogic-gui/pv/view/selectableitem.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
474
DSLogic-gui/pv/view/trace.cpp
Normal file
474
DSLogic-gui/pv/view/trace.cpp
Normal 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
314
DSLogic-gui/pv/view/trace.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user