Fix #770 by adding a vertical hover line and a setting for it
authorSoeren Apel <soeren@apelpie.net>
Tue, 5 Jun 2018 21:11:03 +0000 (23:11 +0200)
committerUwe Hermann <uwe@hermann-uwe.de>
Tue, 5 Jun 2018 23:10:32 +0000 (01:10 +0200)
pv/dialogs/settings.cpp
pv/dialogs/settings.hpp
pv/globalsettings.cpp
pv/globalsettings.hpp
pv/views/trace/analogsignal.cpp
pv/views/trace/analogsignal.hpp
pv/views/trace/decodetrace.cpp
pv/views/trace/logicsignal.cpp
pv/views/trace/trace.cpp
pv/views/trace/trace.hpp

index 4744567f6b0eef1d6eee0cc14e99e23e447cfae5..04565a3f850446da9966a942e5bce2a2ae1aa368 100644 (file)
@@ -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;
index f1925b45a65ab2767db1c87e6991c7e74aa6af4a..40142056487c8fcc509437d76d1c9629b2986589 100644 (file)
@@ -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);
index cd356ae631f70c4f1ec3d83d1ae29fad302a8b4d..cd69591a8cbae45f6808a3cf2338197ef3ceb4fb 100644 (file)
@@ -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";
index 276a968247b11b585d8583e3a0a2423eecb1108c..40dc1b3c5e94d0cda96e8078a7f166f45609b254 100644 (file)
@@ -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;
index 655954a4812380eb5128a8b442ca4dbf405756d1..a106be4694c5f52c884a2f1130bb34a1adbab7bc 100644 (file)
@@ -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)
index 6afc394227170c99151acc9d8220daa3fed63def..f4cc17845e120284710f5bdda0044bcd7f1e389b 100644 (file)
@@ -25,7 +25,6 @@
 #include <QComboBox>
 #include <QSpinBox>
 
-#include <pv/globalsettings.hpp>
 #include <pv/views/trace/signal.hpp>
 
 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
index 46ccc8122c7adf7b3a71ba5635cb15517cea04ce..d2b7463612b6514bbbc31b8837bcdc6bb3d5cedb 100644 (file)
@@ -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)
index 38f204b6e255c2bf93940a7b3b70d2baac91cd9e..870af9c5fce2caa04dc718afd66209ae7b1c23e9 100644 (file)
@@ -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<int32_t> trig_types = get_trigger_types();
 
-       const int y = get_visual_y();
-       const vector<int32_t> 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,
index 0e15480022c9d83cc82a397b449c490bfd65bc30..5977bc2c5c701c59bb0901274b6de6534fe0d377 100644 (file)
@@ -60,6 +60,12 @@ Trace::Trace(shared_ptr<data::SignalBase> 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<data::SignalBase> Trace::base() const
@@ -67,6 +73,20 @@ shared_ptr<data::SignalBase> 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<int, int> 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 */
index 410d82cd14e8c9121e9a758024dee4c5d540204f..758b2e97c46e0142238b842e8b3d42c013fda747 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "tracetreeitem.hpp"
 
+#include <pv/globalsettings.hpp>
 #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_;