X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=pv%2Fviews%2Ftrace%2Ftrace.cpp;h=1f77598d609c04235dfb3d0e3282b693edf6ee32;hb=f6a93932056dab5e2f75207b65197b436d4141a5;hp=fe5cc281d46984c27aa331910f84e926b11f2dee;hpb=cbd9ec7f751a5403d1465e966ccecd31b7086e8a;p=pulseview.git diff --git a/pv/views/trace/trace.cpp b/pv/views/trace/trace.cpp index fe5cc281..1f77598d 100644 --- a/pv/views/trace/trace.cpp +++ b/pv/views/trace/trace.cpp @@ -26,7 +26,9 @@ #include #include #include +#include +#include "ruler.hpp" #include "trace.hpp" #include "tracepalette.hpp" #include "view.hpp" @@ -47,19 +49,22 @@ const int Trace::LabelHitPadding = 2; const QColor Trace::BrightGrayBGColor = QColor(0, 0, 0, 10 * 255 / 100); const QColor Trace::DarkGrayBGColor = QColor(0, 0, 0, 15 * 255 / 100); +const QColor Trace::ErrorBgColor = QColor(0xEF, 0x29, 0x29); -Trace::Trace(shared_ptr channel) : - base_(channel), +Trace::Trace(shared_ptr signal) : + base_(signal), axis_pen_(AxisPen), segment_display_mode_(ShowLastSegmentOnly), // Will be overwritten by View current_segment_(0), popup_(nullptr), popup_form_(nullptr) { - connect(channel.get(), SIGNAL(name_changed(const QString&)), + connect(signal.get(), SIGNAL(name_changed(const QString&)), this, SLOT(on_name_changed(const QString&))); - connect(channel.get(), SIGNAL(color_changed(const QColor&)), + connect(signal.get(), SIGNAL(color_changed(const QColor&)), this, SLOT(on_color_changed(const QColor&))); + connect(signal.get(), SIGNAL(error_message_changed(const QString&)), + this, SLOT(on_error_message_changed(const QString&))); GlobalSettings::add_change_handler(this); @@ -87,11 +92,15 @@ bool Trace::is_selectable(QPoint pos) const return (pos.x() <= view->header_width()); } -bool Trace::is_draggable() const +bool Trace::is_draggable(QPoint pos) const { // While the header label that belongs to this trace is draggable, - // the trace itself shall not be - return false; + // the trace itself shall not be. Hence we return true if the header + // was clicked and false if the trace area was clicked + const View *view = owner_->view(); + assert(view); + + return (pos.x() <= view->header_width()); } void Trace::set_segment_display_mode(SegmentDisplayMode mode) @@ -106,6 +115,10 @@ void Trace::on_setting_changed(const QString &key, const QVariant &value) { if (key == GlobalSettings::Key_View_ShowHoverMarker) show_hover_marker_ = value.toBool(); + + // Force a repaint since many options alter the way traces look + if (owner_) + owner_->row_item_appearance_changed(false, true); } void Trace::paint_label(QPainter &p, const QRect &rect, bool hover) @@ -165,6 +178,26 @@ void Trace::paint_label(QPainter &p, const QRect &rect, bool hover) Qt::AlignCenter | Qt::AlignVCenter, base_->name()); } +void Trace::paint_error(QPainter &p, const ViewItemPaintParams &pp) +{ + const QString message = base_->get_error_message(); + + const int y = get_visual_y(); + + p.setPen(ErrorBgColor.darker()); + p.setBrush(ErrorBgColor); + + const QRectF bounding_rect = QRectF(pp.left(), INT_MIN / 2 + y, pp.right(), INT_MAX); + + const QRectF text_rect = p.boundingRect(bounding_rect, Qt::AlignCenter, message); + const qreal r = text_rect.height() / 4; + + p.drawRoundedRect(text_rect.adjusted(-r, -r, r, r), r, r, Qt::AbsoluteSize); + + p.setPen(Qt::black); + p.drawText(text_rect, message); +} + QMenu* Trace::create_header_context_menu(QWidget *parent) { QMenu *const menu = ViewItem::create_header_context_menu(parent); @@ -172,6 +205,34 @@ QMenu* Trace::create_header_context_menu(QWidget *parent) return menu; } +QMenu* Trace::create_view_context_menu(QWidget *parent, QPoint &click_pos) +{ + context_menu_x_pos_ = click_pos.x(); + + // Get entries from default menu before adding our own + QMenu *const menu = new QMenu(parent); + + QMenu* default_menu = TraceTreeItem::create_view_context_menu(parent, click_pos); + if (default_menu) { + for (QAction *action : default_menu->actions()) { // clazy:exclude=range-loop + menu->addAction(action); + if (action->parent() == default_menu) + action->setParent(menu); + } + delete default_menu; + + // Add separator if needed + if (menu->actions().length() > 0) + menu->addSeparator(); + } + + QAction *const create_marker_here = new QAction(tr("Create marker here"), this); + connect(create_marker_here, SIGNAL(triggered()), this, SLOT(on_create_marker_here())); + menu->addAction(create_marker_here); + + return menu; +} + pv::widgets::Popup* Trace::create_popup(QWidget *parent) { using pv::widgets::Popup; @@ -254,12 +315,13 @@ void Trace::paint_back(QPainter &p, ViewItemPaintParams &pp) void Trace::paint_axis(QPainter &p, ViewItemPaintParams &pp, int y) { + bool was_antialiased = p.testRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::Antialiasing, false); p.setPen(axis_pen_); p.drawLine(QPointF(pp.left(), y), QPointF(pp.right(), y)); - p.setRenderHint(QPainter::Antialiasing, true); + p.setRenderHint(QPainter::Antialiasing, was_antialiased); } void Trace::add_color_option(QWidget *parent, QFormLayout *form) @@ -290,10 +352,11 @@ void Trace::paint_hover_marker(QPainter &p) const pair extents = v_extents(); + bool was_antialiased = p.testRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::Antialiasing, false); p.drawLine(x, get_visual_y() + extents.first, x, get_visual_y() + extents.second); - p.setRenderHint(QPainter::Antialiasing, true); + p.setRenderHint(QPainter::Antialiasing, was_antialiased); } void Trace::create_popup_form() @@ -306,13 +369,28 @@ void Trace::create_popup_form() // handled, leaving the parent popup_ time to handle the change. if (popup_form_) { QWidget *suicidal = new QWidget(); - suicidal->setLayout(popup_form_); + suicidal->setLayout(popup_->layout()); suicidal->deleteLater(); } // Repopulate the popup - popup_form_ = new QFormLayout(popup_); - popup_->setLayout(popup_form_); + widgets::QWidthAdjustingScrollArea* scrollarea = new widgets::QWidthAdjustingScrollArea(); + QWidget* scrollarea_content = new QWidget(scrollarea); + + scrollarea->setWidget(scrollarea_content); + scrollarea->setWidgetResizable(true); + scrollarea->setContentsMargins(0, 0, 0, 0); + scrollarea->setFrameShape(QFrame::NoFrame); + scrollarea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollarea_content->setContentsMargins(0, 0, 0, 0); + + popup_->setLayout(new QVBoxLayout()); + popup_->layout()->addWidget(scrollarea); + popup_->layout()->setContentsMargins(0, 0, 0, 0); + + popup_form_ = new QFormLayout(scrollarea_content); + popup_form_->setSizeConstraint(QLayout::SetMinAndMaxSize); + populate_popup_form(popup_, popup_form_); } @@ -347,6 +425,14 @@ void Trace::on_color_changed(const QColor &color) owner_->row_item_appearance_changed(true, true); } +void Trace::on_error_message_changed(const QString &msg) +{ + (void)msg; + + if (owner_) + owner_->row_item_appearance_changed(false, true); +} + void Trace::on_popup_closed() { popup_ = nullptr; @@ -365,6 +451,17 @@ void Trace::on_coloredit_changed(const QColor &color) base_->set_color(color); } +void Trace::on_create_marker_here() const +{ + View *view = owner_->view(); + assert(view); + + const Ruler *ruler = view->ruler(); + QPoint p = ruler->mapFrom(view, QPoint(context_menu_x_pos_, 0)); + + view->add_flag(ruler->get_absolute_time_from_x_pos(p.x())); +} + } // namespace trace } // namespace views } // namespace pv