From 1931b5f932cf068d073bc798f11dd21ede5389a2 Mon Sep 17 00:00:00 2001 From: Soeren Apel Date: Tue, 5 Jun 2018 23:11:03 +0200 Subject: [PATCH] Fix #770 by adding a vertical hover line and a setting for it --- pv/dialogs/settings.cpp | 10 ++++++ pv/dialogs/settings.hpp | 1 + pv/globalsettings.cpp | 1 + pv/globalsettings.hpp | 1 + pv/views/trace/analogsignal.cpp | 7 ++-- pv/views/trace/analogsignal.hpp | 5 ++- pv/views/trace/decodetrace.cpp | 3 ++ pv/views/trace/logicsignal.cpp | 63 +++++++++++++++++---------------- pv/views/trace/trace.cpp | 56 ++++++++++++++++++++++++----- pv/views/trace/trace.hpp | 14 +++++++- 10 files changed, 117 insertions(+), 44 deletions(-) diff --git a/pv/dialogs/settings.cpp b/pv/dialogs/settings.cpp index 4744567f..04565a3f 100644 --- a/pv/dialogs/settings.cpp +++ b/pv/dialogs/settings.cpp @@ -233,6 +233,10 @@ QWidget *Settings::get_view_settings_form(QWidget *parent) const SLOT(on_view_showAnalogMinorGrid_changed(int))); trace_view_layout->addRow(tr("Show analog minor grid in addition to div grid"), cb); + cb = create_checkbox(GlobalSettings::Key_View_ShowHoverMarker, + SLOT(on_view_showHoverMarker_changed(int))); + trace_view_layout->addRow(tr("Highlight mouse cursor using a vertical marker line"), cb); + QComboBox *thr_disp_mode_cb = new QComboBox(); thr_disp_mode_cb->addItem(tr("None"), GlobalSettings::ConvThrDispMode_None); thr_disp_mode_cb->addItem(tr("Background"), GlobalSettings::ConvThrDispMode_Background); @@ -595,6 +599,12 @@ void Settings::on_view_showAnalogMinorGrid_changed(int state) settings.setValue(GlobalSettings::Key_View_ShowAnalogMinorGrid, state ? true : false); } +void Settings::on_view_showHoverMarker_changed(int state) +{ + GlobalSettings settings; + settings.setValue(GlobalSettings::Key_View_ShowHoverMarker, state ? true : false); +} + void Settings::on_view_conversionThresholdDispMode_changed(int state) { GlobalSettings settings; diff --git a/pv/dialogs/settings.hpp b/pv/dialogs/settings.hpp index f1925b45..40142056 100644 --- a/pv/dialogs/settings.hpp +++ b/pv/dialogs/settings.hpp @@ -62,6 +62,7 @@ private Q_SLOTS: void on_view_stickyScrolling_changed(int state); void on_view_showSamplingPoints_changed(int state); void on_view_showAnalogMinorGrid_changed(int state); + void on_view_showHoverMarker_changed(int state); void on_view_conversionThresholdDispMode_changed(int state); void on_view_defaultDivHeight_changed(int value); void on_view_defaultLogicHeight_changed(int value); diff --git a/pv/globalsettings.cpp b/pv/globalsettings.cpp index cd356ae6..cd69591a 100644 --- a/pv/globalsettings.cpp +++ b/pv/globalsettings.cpp @@ -40,6 +40,7 @@ const QString GlobalSettings::Key_View_ShowAnalogMinorGrid = "View_ShowAnalogMin const QString GlobalSettings::Key_View_ConversionThresholdDispMode = "View_ConversionThresholdDispMode"; const QString GlobalSettings::Key_View_DefaultDivHeight = "View_DefaultDivHeight"; const QString GlobalSettings::Key_View_DefaultLogicHeight = "View_DefaultLogicHeight"; +const QString GlobalSettings::Key_View_ShowHoverMarker = "View_ShowHoverMarker"; const QString GlobalSettings::Key_Dec_InitialStateConfigurable = "Dec_InitialStateConfigurable"; const QString GlobalSettings::Key_Log_BufferSize = "Log_BufferSize"; const QString GlobalSettings::Key_Log_NotifyOfStacktrace = "Log_NotifyOfStacktrace"; diff --git a/pv/globalsettings.hpp b/pv/globalsettings.hpp index 276a9682..40dc1b3c 100644 --- a/pv/globalsettings.hpp +++ b/pv/globalsettings.hpp @@ -56,6 +56,7 @@ public: static const QString Key_View_ConversionThresholdDispMode; static const QString Key_View_DefaultDivHeight; static const QString Key_View_DefaultLogicHeight; + static const QString Key_View_ShowHoverMarker; static const QString Key_Dec_InitialStateConfigurable; static const QString Key_Log_BufferSize; static const QString Key_Log_NotifyOfStacktrace; diff --git a/pv/views/trace/analogsignal.cpp b/pv/views/trace/analogsignal.cpp index 655954a4..a106be46 100644 --- a/pv/views/trace/analogsignal.cpp +++ b/pv/views/trace/analogsignal.cpp @@ -116,8 +116,6 @@ AnalogSignal::AnalogSignal( connect(analog_data, SIGNAL(min_max_changed(float, float)), this, SLOT(on_min_max_changed(float, float))); - GlobalSettings::add_change_handler(this); - GlobalSettings gs; conversion_threshold_disp_mode_ = gs.value(GlobalSettings::Key_View_ConversionThresholdDispMode).toInt(); @@ -210,6 +208,8 @@ void AnalogSignal::scale_handle_drag_release() void AnalogSignal::on_setting_changed(const QString &key, const QVariant &value) { + Signal::on_setting_changed(key, value); + if (key == GlobalSettings::Key_View_ConversionThresholdDispMode) on_settingViewConversionThresholdDispMode_changed(value); } @@ -328,6 +328,9 @@ void AnalogSignal::paint_fore(QPainter &p, ViewItemPaintParams &pp) p.drawText(bounding_rect, Qt::AlignRight | Qt::AlignBottom, infotext); } + + if (show_hover_marker_) + paint_hover_marker(p); } void AnalogSignal::paint_grid(QPainter &p, int y, int left, int right) diff --git a/pv/views/trace/analogsignal.hpp b/pv/views/trace/analogsignal.hpp index 6afc3942..f4cc1784 100644 --- a/pv/views/trace/analogsignal.hpp +++ b/pv/views/trace/analogsignal.hpp @@ -25,7 +25,6 @@ #include #include -#include #include using std::pair; @@ -42,7 +41,7 @@ class SignalBase; namespace views { namespace trace { -class AnalogSignal : public Signal, public GlobalSettingsInterface +class AnalogSignal : public Signal { Q_OBJECT @@ -105,7 +104,7 @@ public: */ void scale_handle_drag_release(); - void on_setting_changed(const QString &key, const QVariant &value); + virtual void on_setting_changed(const QString &key, const QVariant &value); /** * Paints the background layer of the signal with a QPainter diff --git a/pv/views/trace/decodetrace.cpp b/pv/views/trace/decodetrace.cpp index 46ccc812..d2b74636 100644 --- a/pv/views/trace/decodetrace.cpp +++ b/pv/views/trace/decodetrace.cpp @@ -255,6 +255,9 @@ void DecodeTrace::paint_fore(QPainter &p, ViewItemPaintParams &pp) p.setPen(QApplication::palette().color(QPalette::WindowText)); p.drawText(r, f, h); } + + if (show_hover_marker_) + paint_hover_marker(p); } void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) diff --git a/pv/views/trace/logicsignal.cpp b/pv/views/trace/logicsignal.cpp index 38f204b6..870af9c5 100644 --- a/pv/views/trace/logicsignal.cpp +++ b/pv/views/trace/logicsignal.cpp @@ -293,38 +293,41 @@ void LogicSignal::paint_mid(QPainter &p, ViewItemPaintParams &pp) void LogicSignal::paint_fore(QPainter &p, ViewItemPaintParams &pp) { // Draw the trigger marker - if (!trigger_match_ || !base_->enabled()) - return; + if (base_->enabled() && trigger_match_) { + const int y = get_visual_y(); + const vector trig_types = get_trigger_types(); - const int y = get_visual_y(); - const vector trig_types = get_trigger_types(); - for (int32_t type_id : trig_types) { - const TriggerMatchType *const type = - TriggerMatchType::get(type_id); - if (trigger_match_ != type || type_id < 0 || - (size_t)type_id >= countof(TriggerMarkerIcons) || - !TriggerMarkerIcons[type_id]) - continue; - - const QPixmap *const pixmap = get_pixmap( - TriggerMarkerIcons[type_id]); - if (!pixmap) - continue; - - const float pad = TriggerMarkerPadding - 0.5f; - const QSize size = pixmap->size(); - const QPoint point( - pp.right() - size.width() - pad * 2, - y - (signal_height_ + size.height()) / 2); - - p.setPen(QPen(TriggerMarkerBackgroundColor.darker())); - p.setBrush(TriggerMarkerBackgroundColor); - p.drawRoundedRect(QRectF(point, size).adjusted( - -pad, -pad, pad, pad), pad, pad); - p.drawPixmap(point, *pixmap); - - break; + for (int32_t type_id : trig_types) { + const TriggerMatchType *const type = + TriggerMatchType::get(type_id); + if (trigger_match_ != type || type_id < 0 || + (size_t)type_id >= countof(TriggerMarkerIcons) || + !TriggerMarkerIcons[type_id]) + continue; + + const QPixmap *const pixmap = get_pixmap( + TriggerMarkerIcons[type_id]); + if (!pixmap) + continue; + + const float pad = TriggerMarkerPadding - 0.5f; + const QSize size = pixmap->size(); + const QPoint point( + pp.right() - size.width() - pad * 2, + y - (signal_height_ + size.height()) / 2); + + p.setPen(QPen(TriggerMarkerBackgroundColor.darker())); + p.setBrush(TriggerMarkerBackgroundColor); + p.drawRoundedRect(QRectF(point, size).adjusted( + -pad, -pad, pad, pad), pad, pad); + p.drawPixmap(point, *pixmap); + + break; + } } + + if (show_hover_marker_) + paint_hover_marker(p); } void LogicSignal::paint_caps(QPainter &p, QLineF *const lines, diff --git a/pv/views/trace/trace.cpp b/pv/views/trace/trace.cpp index 0e154800..5977bc2c 100644 --- a/pv/views/trace/trace.cpp +++ b/pv/views/trace/trace.cpp @@ -60,6 +60,12 @@ Trace::Trace(shared_ptr channel) : this, SLOT(on_name_changed(const QString&))); connect(channel.get(), SIGNAL(color_changed(const QColor&)), this, SLOT(on_color_changed(const QColor&))); + + GlobalSettings::add_change_handler(this); + + GlobalSettings settings; + show_hover_marker_ = + settings.value(GlobalSettings::Key_View_ShowHoverMarker).toBool(); } shared_ptr Trace::base() const @@ -67,6 +73,20 @@ shared_ptr Trace::base() const return base_; } +void Trace::set_segment_display_mode(SegmentDisplayMode mode) +{ + segment_display_mode_ = mode; + + if (owner_) + owner_->row_item_appearance_changed(true, true); +} + +void Trace::on_setting_changed(const QString &key, const QVariant &value) +{ + if (key == GlobalSettings::Key_View_ShowHoverMarker) + show_hover_marker_ = value.toBool(); +} + void Trace::paint_label(QPainter &p, const QRect &rect, bool hover) { const int y = get_visual_y(); @@ -172,6 +192,14 @@ int Trace::get_current_segment() const return current_segment_; } +void Trace::hover_point_changed(const QPoint &hp) +{ + (void)hp; + + if (owner_) + owner_->row_item_appearance_changed(false, true); +} + void Trace::paint_back(QPainter &p, ViewItemPaintParams &pp) { const View *view = owner_->view(); @@ -213,6 +241,26 @@ void Trace::add_color_option(QWidget *parent, QFormLayout *form) form->addRow(tr("Color"), color_button); } +void Trace::paint_hover_marker(QPainter &p) +{ + const View *view = owner_->view(); + assert(view); + + const int x = view->hover_point().x(); + + if (x == -1) + return; + + p.setPen(QPen(QColor(Qt::lightGray))); + + const pair extents = v_extents(); + + p.setRenderHint(QPainter::Antialiasing, false); + p.drawLine(x, get_visual_y() + extents.first, + x, get_visual_y() + extents.second); + p.setRenderHint(QPainter::Antialiasing, true); +} + void Trace::create_popup_form() { // Clear the layout @@ -244,14 +292,6 @@ void Trace::populate_popup_form(QWidget *parent, QFormLayout *form) add_color_option(parent, form); } -void Trace::set_segment_display_mode(SegmentDisplayMode mode) -{ - segment_display_mode_ = mode; - - if (owner_) - owner_->row_item_appearance_changed(true, true); -} - void Trace::on_name_changed(const QString &text) { /* This event handler is called by SignalBase when the name was changed there */ diff --git a/pv/views/trace/trace.hpp b/pv/views/trace/trace.hpp index 410d82cd..758b2e97 100644 --- a/pv/views/trace/trace.hpp +++ b/pv/views/trace/trace.hpp @@ -30,6 +30,7 @@ #include "tracetreeitem.hpp" +#include #include "pv/data/signalbase.hpp" using std::shared_ptr; @@ -59,7 +60,7 @@ namespace trace { * For this reason, Trace is more generic and contains properties and helpers * that benefit any kind of time series items. */ -class Trace : public TraceTreeItem +class Trace : public TraceTreeItem, public GlobalSettingsInterface { Q_OBJECT @@ -105,6 +106,8 @@ public: */ virtual void set_segment_display_mode(SegmentDisplayMode mode); + virtual void on_setting_changed(const QString &key, const QVariant &value); + /** * Paints the signal label. * @param p the QPainter to paint into. @@ -128,6 +131,8 @@ public: int get_current_segment() const; + virtual void hover_point_changed(const QPoint &hp); + protected: /** * Paints the background layer of the signal with a QPainter. @@ -144,6 +149,12 @@ protected: */ void paint_axis(QPainter &p, ViewItemPaintParams &pp, int y); + /** + * Draw a hover marker under the cursor position. + * @param p The painter to draw into. + */ + void paint_hover_marker(QPainter &p); + void add_color_option(QWidget *parent, QFormLayout *form); void create_popup_form(); @@ -167,6 +178,7 @@ protected: QPen axis_pen_; SegmentDisplayMode segment_display_mode_; + bool show_hover_marker_; /// The ID of the currently displayed segment int current_segment_; -- 2.30.2