X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fview%2Fdecodesignal.cpp;h=9f81ab42567dd5e58f2cc59a741bb565e58044bd;hp=33ea33f381e484391c82ec7cb83427b45d3a252f;hb=4e5a4405482a296ebb6014e627298ad156c78d55;hpb=9472f4476b27336e9187635015169e308bfe8af7 diff --git a/pv/view/decodesignal.cpp b/pv/view/decodesignal.cpp index 33ea33f3..9f81ab42 100644 --- a/pv/view/decodesignal.cpp +++ b/pv/view/decodesignal.cpp @@ -22,9 +22,21 @@ extern "C" { #include } +#include + +#include + +#include +#include +#include +#include +#include + #include "decodesignal.h" +#include #include +#include #include #include @@ -34,19 +46,27 @@ using namespace std; namespace pv { namespace view { +const QColor DecodeSignal::DecodeColours[4] = { + QColor(0xEF, 0x29, 0x29), // Red + QColor(0xFC, 0xE9, 0x4F), // Yellow + QColor(0x8A, 0xE2, 0x34), // Green + QColor(0x72, 0x9F, 0xCF) // Blue +}; + +const QColor DecodeSignal::ErrorBgColour = QColor(0xEF, 0x29, 0x29); + DecodeSignal::DecodeSignal(pv::SigSession &session, - boost::shared_ptr decoder) : - Trace(session, QString(decoder->get_decoder()->name)), - _decoder(decoder) + boost::shared_ptr decoder, int index) : + Trace(session, QString(decoder->decoder()->name)), + _decoder(decoder), + _binding(decoder) { assert(_decoder); - _colour = Qt::red; -} + _colour = DecodeColours[index % countof(DecodeColours)]; -void DecodeSignal::init_context_bar_actions(QWidget *parent) -{ - (void)parent; + connect(_decoder.get(), SIGNAL(new_decode_data()), + this, SLOT(on_new_decode_data())); } bool DecodeSignal::enabled() const @@ -54,18 +74,35 @@ bool DecodeSignal::enabled() const return true; } +const boost::shared_ptr& DecodeSignal::decoder() const +{ + return _decoder; +} + void DecodeSignal::set_view(pv::view::View *view) { assert(view); Trace::set_view(view); } -void DecodeSignal::paint(QPainter &p, int left, int right) +void DecodeSignal::paint_back(QPainter &p, int left, int right) +{ + paint_axis(p, get_y(), left, right); +} + +void DecodeSignal::paint_mid(QPainter &p, int left, int right) { using namespace pv::view::decode; + assert(_decoder); + const QString err = _decoder->error_message(); + if (!err.isEmpty()) { + draw_error(p, err, left, right); + return; + } + assert(_view); - const int y = _v_offset - _view->v_offset(); + const int y = get_y(); const double scale = _view->scale(); assert(scale > 0); @@ -84,14 +121,180 @@ void DecodeSignal::paint(QPainter &p, int left, int right) vector< shared_ptr > annotations(_decoder->annotations()); BOOST_FOREACH(shared_ptr a, annotations) { assert(a); - a->paint(p, left, right, samples_per_pixel, pixels_offset, y); + a->paint(p, get_text_colour(), _text_size.height(), + left, right, samples_per_pixel, pixels_offset, y); + } +} + +void DecodeSignal::populate_popup_form(QWidget *parent, QFormLayout *form) +{ + const GSList *probe; + + assert(form); + assert(parent); + assert(_decoder); + + const srd_decoder *const decoder = _decoder->decoder(); + + assert(decoder); + + Trace::populate_popup_form(parent, form); + + form->addRow(new QLabel(tr("

Probes

"), parent)); + + _probe_selector_map.clear(); + + // 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, p); + connect(combo, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_probe_selected(int))); + form->addRow(tr("%1 (%2) *") + .arg(p->name).arg(p->desc), combo); + + _probe_selector_map[p] = combo; + } + + // 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, p); + connect(combo, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_probe_selected(int))); + form->addRow(tr("%1 (%2)") + .arg(p->name).arg(p->desc), combo); + + _probe_selector_map[p] = combo; + } + + form->addRow(new QLabel( + tr("* Required Probes"), parent)); + + // Add the options + if (!_binding.properties().empty()) { + form->addRow(new QLabel(tr("

Options

"), + parent)); + _binding.add_properties_to_form(form, true); + } +} + +QMenu* DecodeSignal::create_context_menu(QWidget *parent) +{ + QMenu *const menu = Trace::create_context_menu(parent); + + menu->addSeparator(); + + QAction *const del = new QAction(tr("Delete"), this); + del->setShortcuts(QKeySequence::Delete); + connect(del, SIGNAL(triggered()), this, SLOT(on_delete())); + menu->addAction(del); + + return menu; +} + +void DecodeSignal::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()); + p.drawText(text_rect, message); +} + +QComboBox* DecodeSignal::create_probe_selector( + QWidget *parent, const srd_probe *const probe) +{ + const vector< shared_ptr > sigs = _session.get_signals(); + + assert(_decoder); + const map >::const_iterator probe_iter = + _decoder->probes().find(probe); + + QComboBox *selector = new QComboBox(parent); + + selector->addItem("-", qVariantFromValue((void*)NULL)); + + if (probe_iter == _decoder->probes().end()) + selector->setCurrentIndex(0); + + for(size_t i = 0; i < sigs.size(); i++) { + const shared_ptr s(sigs[i]); + assert(s); + + if (dynamic_pointer_cast(s) && s->enabled()) + { + selector->addItem(s->get_name(), + qVariantFromValue((void*)s.get())); + if ((*probe_iter).second == s) + selector->setCurrentIndex(i + 1); + } } + + return selector; +} + +void DecodeSignal::commit_probes() +{ + assert(_decoder); + + map > probe_map; + const vector< shared_ptr > sigs = _session.get_signals(); + + for(map::const_iterator i = + _probe_selector_map.begin(); + i != _probe_selector_map.end(); i++) + { + const QComboBox *const combo = (*i).second; + const LogicSignal *const selection = + (LogicSignal*)combo->itemData(combo->currentIndex()). + value(); + + BOOST_FOREACH(shared_ptr s, sigs) + if(s.get() == selection) { + probe_map[(*i).first] = + dynamic_pointer_cast(s); + break; + } + } + + _decoder->set_probes(probe_map); +} + +void DecodeSignal::on_new_decode_data() +{ + if (_view) + _view->update_viewport(); +} + +void DecodeSignal::delete_pressed() +{ + on_delete(); +} + +void DecodeSignal::on_delete() +{ + _session.remove_decode_signal(this); } -const list DecodeSignal::get_context_bar_actions() +void DecodeSignal::on_probe_selected(int) { - list actions; - return actions; + commit_probes(); } } // namespace view