#include <extdef.h>
#include <boost/foreach.hpp>
+#include <boost/functional/hash.hpp>
#include <QAction>
#include <QApplication>
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;
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;
samples_per_pixel, pixels_offset, y,
base_colour);
y += row_height;
+
+ _cur_row_headings.push_back(row.title());
}
}
samples_per_pixel, pixels_offset);
}
+void DecodeTrace::paint_fore(QPainter &p, int left, int right)
+{
+ using namespace pv::data::decode;
+
+ (void)right;
+
+ QFontMetrics m(QApplication::font());
+ const int text_height = m.boundingRect(QRect(), 0, "Tg").height();
+ const int row_height = (text_height * 6) / 4;
+
+ for (size_t i = 0; i < _cur_row_headings.size(); i++)
+ {
+ const int y = i * row_height + get_y();
+
+ 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
+ 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);
+ }
+}
+
void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
{
using pv::data::decode::Decoder;
}
form->addRow(new QLabel(
- tr("<i>* Required Probes</i>"), parent));
+ tr("<i>* Required channels</i>"), parent));
}
// Add stacking button
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
// This works because we are currently assuming all
// LogicSignals have the same data/snapshot
BOOST_FOREACH (const shared_ptr<Decoder> &dec, stack)
- if (dec && !dec->probes().empty() &&
- ((logic_signal = (*dec->probes().begin()).second)) &&
+ if (dec && !dec->channels().empty() &&
+ ((logic_signal = (*dec->channels().begin()).second)) &&
((data = logic_signal->logic_data())))
break;
shared_ptr<data::decode::Decoder> &dec, QWidget *parent,
QFormLayout *form)
{
- const GSList *probe;
+ const GSList *l;
assert(dec);
const srd_decoder *const decoder = dec->decoder();
QFormLayout *const decoder_form = new QFormLayout;
group->add_layout(decoder_form);
- // Add the mandatory probes
- for(probe = decoder->probes; probe; probe = probe->next) {
- const struct srd_probe *const p =
- (struct srd_probe *)probe->data;
- QComboBox *const combo = create_probe_selector(parent, dec, p);
+ // 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(p->name))
- .arg(QString::fromUtf8(p->desc)), combo);
+ .arg(QString::fromUtf8(pdch->name))
+ .arg(QString::fromUtf8(pdch->desc)), combo);
- const ProbeSelector s = {combo, dec, p};
+ const ProbeSelector s = {combo, dec, pdch};
_probe_selectors.push_back(s);
}
- // Add the optional probes
- for(probe = decoder->opt_probes; probe; probe = probe->next) {
- const struct srd_probe *const p =
- (struct srd_probe *)probe->data;
- QComboBox *const combo = create_probe_selector(parent, dec, p);
+ // 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(p->name))
- .arg(QString::fromUtf8(p->desc)), combo);
+ .arg(QString::fromUtf8(pdch->name))
+ .arg(QString::fromUtf8(pdch->desc)), combo);
- const ProbeSelector s = {combo, dec, p};
+ const ProbeSelector s = {combo, dec, pdch};
_probe_selectors.push_back(s);
}
QComboBox* DecodeTrace::create_probe_selector(
QWidget *parent, const shared_ptr<data::decode::Decoder> &dec,
- const srd_probe *const probe)
+ const srd_channel *const pdch)
{
assert(dec);
const vector< shared_ptr<Signal> > sigs = _session.get_signals();
assert(_decoder_stack);
- const map<const srd_probe*,
+ const map<const srd_channel*,
shared_ptr<LogicSignal> >::const_iterator probe_iter =
- dec->probes().find(probe);
+ dec->channels().find(pdch);
QComboBox *selector = new QComboBox(parent);
selector->addItem("-", qVariantFromValue((void*)NULL));
- if (probe_iter == dec->probes().end())
+ if (probe_iter == dec->channels().end())
selector->setCurrentIndex(0);
for(size_t i = 0; i < sigs.size(); i++) {
{
assert(dec);
- map<const srd_probe*, shared_ptr<LogicSignal> > probe_map;
+ map<const srd_channel*, shared_ptr<LogicSignal> > probe_map;
const vector< shared_ptr<Signal> > sigs = _session.get_signals();
BOOST_FOREACH(const ProbeSelector &s, _probe_selectors)
BOOST_FOREACH(shared_ptr<Signal> sig, sigs)
if(sig.get() == selection) {
- probe_map[s._probe] =
+ probe_map[s._pdch] =
dynamic_pointer_cast<LogicSignal>(sig);
break;
}