From d7c0ca4a965c5f9cb2ae9aea584bb2547f4baca1 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 9 Dec 2013 15:39:55 +0000 Subject: [PATCH] Make header width responsive to label text --- pv/view/decodetrace.cpp | 4 +++- pv/view/header.cpp | 22 ++++++++++++++++++- pv/view/header.h | 7 ++++++ pv/view/marginwidget.h | 2 ++ pv/view/trace.cpp | 48 +++++++++++++++++++---------------------- pv/view/trace.h | 28 +++++++++--------------- pv/view/view.cpp | 26 ++++++++++++++++------ pv/view/view.h | 5 ++++- 8 files changed, 88 insertions(+), 54 deletions(-) diff --git a/pv/view/decodetrace.cpp b/pv/view/decodetrace.cpp index 1a629f2c..2d641827 100644 --- a/pv/view/decodetrace.cpp +++ b/pv/view/decodetrace.cpp @@ -27,6 +27,7 @@ extern "C" { #include #include +#include #include #include #include @@ -117,7 +118,8 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) _decoder_stack->get_start_time()) / scale; const double samples_per_pixel = samplerate * scale; - const int h = (_text_size.height() * 5) / 4; + QFontMetrics m(QApplication::font()); + const int h = (m.boundingRect(QRect(), 0, "Tg").height() * 5) / 4; assert(_decoder_stack); const QString err = _decoder_stack->error_message(); diff --git a/pv/view/header.cpp b/pv/view/header.cpp index dec5c20c..ca5df96f 100644 --- a/pv/view/header.cpp +++ b/pv/view/header.cpp @@ -42,6 +42,8 @@ using namespace std; namespace pv { namespace view { +const int Header::Padding = 12; + Header::Header(View &parent) : MarginWidget(parent), _dragging(false) @@ -56,6 +58,19 @@ Header::Header(View &parent) : this, SLOT(on_signals_moved())); } +QSize Header::sizeHint() const +{ + int max_width = 0; + + const vector< shared_ptr > traces(_view.get_traces()); + BOOST_FOREACH(shared_ptr t, traces) { + assert(t); + max_width = max(max_width, (int)t->get_label_rect(0).width()); + } + + return QSize(max_width + Padding, 0); +} + shared_ptr Header::get_mouse_over_trace(const QPoint &pt) { const int w = width(); @@ -261,7 +276,7 @@ void Header::on_signals_changed() connect(t.get(), SIGNAL(visibility_changed()), this, SLOT(update())); connect(t.get(), SIGNAL(text_changed()), - this, SLOT(update())); + this, SLOT(on_trace_text_changed())); connect(t.get(), SIGNAL(colour_changed()), this, SLOT(update())); } @@ -272,6 +287,11 @@ void Header::on_signals_moved() update(); } +void Header::on_trace_text_changed() +{ + update(); + geometry_updated(); +} } // namespace view } // namespace pv diff --git a/pv/view/header.h b/pv/view/header.h index 806cc985..5474f10e 100644 --- a/pv/view/header.h +++ b/pv/view/header.h @@ -39,9 +39,14 @@ class Header : public MarginWidget { Q_OBJECT +private: + static const int Padding; + public: Header(View &parent); + QSize sizeHint() const; + private: boost::shared_ptr get_mouse_over_trace( const QPoint &pt); @@ -69,6 +74,8 @@ private slots: void on_signals_moved(); + void on_trace_text_changed(); + signals: void signals_moved(); diff --git a/pv/view/marginwidget.h b/pv/view/marginwidget.h index 8fbebcf4..42dffa7a 100644 --- a/pv/view/marginwidget.h +++ b/pv/view/marginwidget.h @@ -41,6 +41,8 @@ public slots: signals: void selection_changed(); + void geometry_updated(); + protected: pv::view::View &_view; }; diff --git a/pv/view/trace.cpp b/pv/view/trace.cpp index d06c24b5..ae8ee901 100644 --- a/pv/view/trace.cpp +++ b/pv/view/trace.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -88,8 +89,6 @@ void Trace::paint_back(QPainter &p, int left, int right) (void)p; (void)left; (void)right; - - compute_text_size(p); } void Trace::paint_mid(QPainter &p, int left, int right) @@ -118,7 +117,6 @@ void Trace::paint_label(QPainter &p, int right, bool hover) const QColor colour = get_colour(); - compute_text_size(p); const QRectF label_rect = get_label_rect(right); // Paint the label @@ -158,6 +156,7 @@ void Trace::paint_label(QPainter &p, int right, bool hover) // Paint the text p.setPen(get_text_colour()); + p.setFont(QApplication::font()); p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, _name); } @@ -199,6 +198,26 @@ int Trace::get_y() const return _v_offset - _view->v_offset(); } +QRectF Trace::get_label_rect(int right) +{ + using pv::view::View; + + assert(_view); + + QFontMetrics m(QApplication::font()); + const QSize text_size( + m.boundingRect(QRect(), 0, _name).width(), + m.boundingRect(QRect(), 0, "Tg").height()); + const QSizeF label_size( + text_size.width() + View::LabelPadding.width() * 2, + ceilf((text_size.height() + View::LabelPadding.height() * 2) / 2) * 2); + const float label_arrow_length = label_size.height() / 2; + return QRectF( + right - label_arrow_length - label_size.width() - 0.5, + get_y() + 0.5f - label_size.height() / 2, + label_size.width(), label_size.height()); +} + QColor Trace::get_text_colour() const { return (_colour.lightness() > 64) ? Qt::black : Qt::white; @@ -251,29 +270,6 @@ void Trace::populate_popup_form(QWidget *parent, QFormLayout *form) add_colour_option(parent, form); } -void Trace::compute_text_size(QPainter &p) -{ - _text_size = QSize( - p.boundingRect(QRectF(), 0, _name).width(), - p.boundingRect(QRectF(), 0, "Tg").height()); -} - -QRectF Trace::get_label_rect(int right) -{ - using pv::view::View; - - assert(_view); - - const QSizeF label_size( - _text_size.width() + View::LabelPadding.width() * 2, - ceilf((_text_size.height() + View::LabelPadding.height() * 2) / 2) * 2); - const float label_arrow_length = label_size.height() / 2; - return QRectF( - right - label_arrow_length - label_size.width() - 0.5, - get_y() + 0.5f - label_size.height() / 2, - label_size.width(), label_size.height()); -} - void Trace::on_popup_closed() { _popup = NULL; diff --git a/pv/view/trace.h b/pv/view/trace.h index 72f8e8a8..2d8c7cf1 100644 --- a/pv/view/trace.h +++ b/pv/view/trace.h @@ -142,7 +142,17 @@ public: */ int get_y() const; + /** + * Computes the outline rectangle of a label. + * @param p the QPainter to lay out text with. + * @param right the x-coordinate of the right edge of the header + * area. + * @return Returns the rectangle of the signal label. + */ + QRectF get_label_rect(int right); + protected: + /** * Gets the text colour. * @remarks This colour is computed by comparing the lightness @@ -166,22 +176,6 @@ protected: virtual void populate_popup_form(QWidget *parent, QFormLayout *form); -private: - - /** - * Computes an caches the size of the label text. - */ - void compute_text_size(QPainter &p); - - /** - * Computes the outline rectangle of a label. - * @param p the QPainter to lay out text with. - * @param right the x-coordinate of the right edge of the header - * area. - * @return Returns the rectangle of the signal label. - */ - QRectF get_label_rect(int right); - private slots: void on_text_changed(const QString &text); @@ -202,8 +196,6 @@ protected: QColor _colour; int _v_offset; - QSizeF _text_size; - private: pv::widgets::Popup *_popup; QFormLayout *_popup_form; diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 3137dd0c..c2d97f07 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -52,7 +52,6 @@ namespace view { const double View::MaxScale = 1e9; const double View::MinScale = 1e-15; -const int View::LabelMarginWidth = 70; const int View::RulerHeight = 30; const int View::MaxScrollValue = INT_MAX / 2; @@ -95,6 +94,8 @@ View::View(SigSession &session, QWidget *parent) : connect(_cursors.second().get(), SIGNAL(time_changed()), this, SLOT(marker_time_changed())); + connect(_header, SIGNAL(geometry_updated()), + this, SLOT(on_geometry_updated())); connect(_header, SIGNAL(signals_moved()), this, SLOT(on_signals_moved())); @@ -108,7 +109,6 @@ View::View(SigSession &session, QWidget *parent) : connect(_ruler, SIGNAL(selection_changed()), this, SIGNAL(selection_changed())); - setViewportMargins(LabelMarginWidth, RulerHeight, 0, 0); setViewport(_viewport); _viewport->installEventFilter(this); @@ -381,6 +381,16 @@ void View::update_scroll() areaSize.height()); } +void View::update_layout() +{ + setViewportMargins(_header->sizeHint().width(), RulerHeight, 0, 0); + _ruler->setGeometry(_viewport->x(), 0, + _viewport->width(), _viewport->y()); + _header->setGeometry(0, _viewport->y(), + _viewport->x(), _viewport->height()); + update_scroll(); +} + bool View::compare_trace_v_offsets(const shared_ptr &a, const shared_ptr &b) { @@ -432,11 +442,7 @@ bool View::viewportEvent(QEvent *e) void View::resizeEvent(QResizeEvent*) { - _ruler->setGeometry(_viewport->x(), 0, - _viewport->width(), _viewport->y()); - _header->setGeometry(0, _viewport->y(), - _viewport->x(), _viewport->height()); - update_scroll(); + update_layout(); } void View::h_scroll_value_changed(int value) @@ -474,6 +480,7 @@ void View::signals_changed() offset += SignalHeight + 2 * SignalMargin; } + setViewportMargins(_header->sizeHint().width(), RulerHeight, 0, 0); normalize_layout(); } @@ -510,5 +517,10 @@ void View::on_signals_moved() signals_moved(); } +void View::on_geometry_updated() +{ + update_layout(); +} + } // namespace view } // namespace pv diff --git a/pv/view/view.h b/pv/view/view.h index db03ce9b..886aa830 100644 --- a/pv/view/view.h +++ b/pv/view/view.h @@ -51,7 +51,6 @@ private: static const double MaxScale; static const double MinScale; - static const int LabelMarginWidth; static const int RulerHeight; static const int MaxScrollValue; @@ -148,6 +147,8 @@ private: void update_scroll(); + void update_layout(); + static bool compare_trace_v_offsets( const boost::shared_ptr &a, const boost::shared_ptr &b); @@ -171,6 +172,8 @@ private slots: void on_signals_moved(); + void on_geometry_updated(); + private: SigSession &_session; -- 2.30.2