From 581724de334181fc5338f1efa87954264cf90520 Mon Sep 17 00:00:00 2001 From: Soeren Apel Date: Fri, 19 Oct 2018 23:36:13 +0200 Subject: [PATCH] Fix #1222 by adding a tooltip for when there isn't enough space Also fixes #870 by always using 12 digits for precision --- pv/views/trace/cursorpair.cpp | 92 ++++++++++++++++++++--------------- pv/views/trace/cursorpair.hpp | 13 +++-- pv/views/trace/ruler.cpp | 7 +-- pv/views/trace/ruler.hpp | 2 +- pv/views/trace/view.cpp | 32 +++++++----- pv/views/trace/view.hpp | 4 +- 6 files changed, 90 insertions(+), 60 deletions(-) diff --git a/pv/views/trace/cursorpair.cpp b/pv/views/trace/cursorpair.cpp index b67609da..0135c457 100644 --- a/pv/views/trace/cursorpair.cpp +++ b/pv/views/trace/cursorpair.cpp @@ -17,15 +17,18 @@ * along with this program; if not, see . */ +#include +#include + +#include +#include + #include "cursorpair.hpp" #include "pv/util.hpp" #include "ruler.hpp" #include "view.hpp" -#include -#include - using std::max; using std::make_pair; using std::min; @@ -44,6 +47,8 @@ CursorPair::CursorPair(View &view) : first_(new Cursor(view, 0.0)), second_(new Cursor(view, 1.0)) { + connect(&view_, SIGNAL(hover_point_changed(const QWidget*, QPoint)), + this, SLOT(on_hover_point_changed(const QWidget*, QPoint))); } bool CursorPair::enabled() const @@ -110,38 +115,41 @@ void CursorPair::paint_label(QPainter &p, const QRect &rect, bool hover) if (!enabled()) return; - const QColor text_color = - ViewItem::select_text_color(Cursor::FillColor); - + const QColor text_color = ViewItem::select_text_color(Cursor::FillColor); p.setPen(text_color); - compute_text_size(p); - QRectF delta_rect(label_rect(rect)); + QString text = format_string(); + text_size_ = p.boundingRect(QRectF(), 0, text).size(); + + QRectF delta_rect(label_rect(rect)); const int radius = delta_rect.height() / 2; - const QRectF text_rect(delta_rect.intersected( - rect).adjusted(radius, 0, -radius, 0)); - if (text_rect.width() >= text_size_.width()) { - const int highlight_radius = delta_rect.height() / 2 - 2; - - if (selected()) { - p.setBrush(Qt::transparent); - p.setPen(highlight_pen()); - p.drawRoundedRect(delta_rect, radius, radius); - } - - p.setBrush(hover ? Cursor::FillColor.lighter() : - Cursor::FillColor); - p.setPen(Cursor::FillColor.darker()); + QRectF text_rect(delta_rect.intersected(rect).adjusted(radius, 0, -radius, 0)); + + if (text_rect.width() < text_size_.width()) { + text = "..."; + text_size_ = p.boundingRect(QRectF(), 0, text).size(); + label_incomplete_ = true; + } else + label_incomplete_ = false; + + if (selected()) { + p.setBrush(Qt::transparent); + p.setPen(highlight_pen()); p.drawRoundedRect(delta_rect, radius, radius); + } - delta_rect.adjust(1, 1, -1, -1); - p.setPen(Cursor::FillColor.lighter()); - p.drawRoundedRect(delta_rect, highlight_radius, highlight_radius); + p.setBrush(hover ? Cursor::FillColor.lighter() : Cursor::FillColor); + p.setPen(Cursor::FillColor.darker()); + p.drawRoundedRect(delta_rect, radius, radius); - p.setPen(text_color); - p.drawText(text_rect, Qt::AlignCenter | Qt::AlignVCenter, - format_string()); - } + delta_rect.adjust(1, 1, -1, -1); + p.setPen(Cursor::FillColor.lighter()); + const int highlight_radius = delta_rect.height() / 2 - 2; + p.drawRoundedRect(delta_rect, highlight_radius, highlight_radius); + label_area_ = delta_rect; + + p.setPen(text_color); + p.drawText(text_rect, Qt::AlignCenter | Qt::AlignVCenter, text); } void CursorPair::paint_back(QPainter &p, ViewItemPaintParams &pp) @@ -153,10 +161,8 @@ void CursorPair::paint_back(QPainter &p, ViewItemPaintParams &pp) p.setBrush(QBrush(ViewportFillColor)); const pair offsets(get_cursor_offsets()); - const int l = (int)max(min( - offsets.first, offsets.second), 0.0f); - const int r = (int)min(max( - offsets.first, offsets.second), (float)pp.width()); + const int l = (int)max(min(offsets.first, offsets.second), 0.0f); + const int r = (int)min(max(offsets.first, offsets.second), (float)pp.width()); p.drawRect(l, pp.top(), r - l, pp.height()); } @@ -167,27 +173,33 @@ QString CursorPair::format_string() const pv::util::Timestamp diff = abs(second_->time() - first_->time()); const QString s1 = Ruler::format_time_with_distance( - diff, diff, prefix, view_.time_unit(), view_.tick_precision(), false); + diff, diff, prefix, view_.time_unit(), 12, false); /* Always use 12 precision digits */ const QString s2 = util::format_time_si( 1 / diff, pv::util::SIPrefix::unspecified, 4, "Hz", false); return QString("%1 / %2").arg(s1, s2); } -void CursorPair::compute_text_size(QPainter &p) +pair CursorPair::get_cursor_offsets() const { assert(first_); assert(second_); - text_size_ = p.boundingRect(QRectF(), 0, format_string()).size(); + return pair(first_->get_x(), second_->get_x()); } -pair CursorPair::get_cursor_offsets() const +void CursorPair::on_hover_point_changed(const QWidget* widget, const QPoint& hp) { - assert(first_); - assert(second_); + if (widget != view_.ruler()) + return; - return pair(first_->get_x(), second_->get_x()); + if (!label_incomplete_) + return; + + if (label_area_.contains(hp)) + QToolTip::showText(view_.mapToGlobal(hp), format_string()); + else + QToolTip::hideText(); // TODO Will break other tooltips when there can be others } } // namespace trace diff --git a/pv/views/trace/cursorpair.hpp b/pv/views/trace/cursorpair.hpp index 12a9d7ff..67282680 100644 --- a/pv/views/trace/cursorpair.hpp +++ b/pv/views/trace/cursorpair.hpp @@ -25,6 +25,7 @@ #include #include +#include using std::pair; using std::shared_ptr; @@ -35,8 +36,12 @@ namespace pv { namespace views { namespace trace { +class View; + class CursorPair : public TimeItem { + Q_OBJECT + private: static const int DeltaPadding; static const QColor ViewportFillColor; @@ -48,7 +53,6 @@ public: */ CursorPair(View &view); -public: /** * Returns true if the item is visible and enabled. */ @@ -98,14 +102,17 @@ public: */ QString format_string(); - void compute_text_size(QPainter &p); - pair get_cursor_offsets() const; +public Q_SLOTS: + void on_hover_point_changed(const QWidget* widget, const QPoint &hp); + private: shared_ptr first_, second_; QSizeF text_size_; + QRectF label_area_; + bool label_incomplete_; }; } // namespace trace diff --git a/pv/views/trace/ruler.cpp b/pv/views/trace/ruler.cpp index 675a39f9..1204559c 100644 --- a/pv/views/trace/ruler.cpp +++ b/pv/views/trace/ruler.cpp @@ -50,8 +50,8 @@ Ruler::Ruler(View &parent) : { setMouseTracking(true); - connect(&view_, SIGNAL(hover_point_changed(QPoint)), - this, SLOT(hover_point_changed(QPoint))); + connect(&view_, SIGNAL(hover_point_changed(const QWidget*, QPoint)), + this, SLOT(on_hover_point_changed(const QWidget*, QPoint))); connect(&view_, SIGNAL(offset_changed()), this, SLOT(invalidate_tick_position_cache())); connect(&view_, SIGNAL(scale_changed()), @@ -304,8 +304,9 @@ TickPositions Ruler::calculate_tick_positions( return tp; } -void Ruler::hover_point_changed(const QPoint &hp) +void Ruler::on_hover_point_changed(const QWidget* widget, const QPoint &hp) { + (void)widget; (void)hp; update(); diff --git a/pv/views/trace/ruler.hpp b/pv/views/trace/ruler.hpp index 40aa31bf..d7cab4d7 100644 --- a/pv/views/trace/ruler.hpp +++ b/pv/views/trace/ruler.hpp @@ -171,7 +171,7 @@ private: function format_function); private Q_SLOTS: - void hover_point_changed(const QPoint &hp); + void on_hover_point_changed(const QWidget* widget, const QPoint &hp); void invalidate_tick_position_cache(); diff --git a/pv/views/trace/view.cpp b/pv/views/trace/view.cpp index aee84a20..54c6fae6 100644 --- a/pv/views/trace/view.cpp +++ b/pv/views/trace/view.cpp @@ -241,6 +241,7 @@ void View::reset_view_state() cursors_ = make_shared(*this); next_flag_text_ = 'A'; trigger_markers_.clear(); + hover_widget_ = nullptr; hover_point_ = QPoint(-1, -1); scroll_needs_defaults_ = true; saved_v_offset_ = 0; @@ -865,6 +866,11 @@ const QPoint& View::hover_point() const return hover_point_; } +const QWidget* View::hover_widget() const +{ + return hover_widget_; +} + int64_t View::get_nearest_level_change(const QPoint &p) { // Is snapping disabled? @@ -1329,14 +1335,14 @@ bool View::eventFilter(QObject *object, QEvent *event) const QEvent::Type type = event->type(); if (type == QEvent::MouseMove) { + if (object) + hover_widget_ = qobject_cast(object); + const QMouseEvent *const mouse_event = (QMouseEvent*)event; if (object == viewport_) hover_point_ = mouse_event->pos(); else if (object == ruler_) - // Adjust the hover point's y coordinate so that it's relative to - // the top of the viewport. The result may be negative. - hover_point_ = QPoint(mouse_event->pos().x(), - mouse_event->pos().y() - ruler_->sizeHint().height()); + hover_point_ = mouse_event->pos(); else if (object == header_) hover_point_ = QPoint(0, mouse_event->y()); else @@ -1403,13 +1409,15 @@ void View::update_hover_point() { // Determine signal that the mouse cursor is hovering over signal_under_mouse_cursor_.reset(); - for (shared_ptr s : signals_) { - const pair extents = s->v_extents(); - const int top = s->get_visual_y() + extents.first; - const int btm = s->get_visual_y() + extents.second; - if ((hover_point_.y() >= top) && (hover_point_.y() <= btm) - && s->base()->enabled()) - signal_under_mouse_cursor_ = s; + if (hover_widget_ == this) { + for (shared_ptr s : signals_) { + const pair extents = s->v_extents(); + const int top = s->get_visual_y() + extents.first; + const int btm = s->get_visual_y() + extents.second; + if ((hover_point_.y() >= top) && (hover_point_.y() <= btm) + && s->base()->enabled()) + signal_under_mouse_cursor_ = s; + } } // Update all trace tree items @@ -1419,7 +1427,7 @@ void View::update_hover_point() r->hover_point_changed(hover_point_); // Notify any other listeners - hover_point_changed(hover_point_); + hover_point_changed(hover_widget_, hover_point_); } void View::row_item_appearance_changed(bool label, bool content) diff --git a/pv/views/trace/view.hpp b/pv/views/trace/view.hpp index 7b63d064..7e1122a4 100644 --- a/pv/views/trace/view.hpp +++ b/pv/views/trace/view.hpp @@ -304,6 +304,7 @@ public: vector< shared_ptr > flags() const; const QPoint& hover_point() const; + const QWidget* hover_widget() const; /** * Determines the closest level change (i.e. edge) to a given point, which @@ -321,7 +322,7 @@ public: void on_setting_changed(const QString &key, const QVariant &value); Q_SIGNALS: - void hover_point_changed(const QPoint &hp); + void hover_point_changed(const QWidget* widget, const QPoint &hp); void selection_changed(); @@ -529,6 +530,7 @@ private: vector< shared_ptr > trigger_markers_; + QWidget* hover_widget_; QPoint hover_point_; shared_ptr signal_under_mouse_cursor_; uint16_t snap_distance_; -- 2.30.2