From: Jens Steinhauser Date: Fri, 23 May 2014 19:36:54 +0000 (+0200) Subject: Use a separate widget to hold the cursor labels. X-Git-Tag: pulseview-0.3.0~604 X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=84a0d458a4b04141dd45af6dec44d36782ee163e Use a separate widget to hold the cursor labels. This way the cursor labels don't overlap with the ruler. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c66e4e6..a6c0445b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,6 +135,7 @@ set(pulseview_SOURCES pv/toolbars/samplingbar.cpp pv/view/analogsignal.cpp pv/view/cursor.cpp + pv/view/cursorheader.cpp pv/view/cursorpair.cpp pv/view/header.cpp pv/view/marginwidget.cpp @@ -174,6 +175,7 @@ set(pulseview_HEADERS pv/prop/string.h pv/toolbars/samplingbar.h pv/view/cursor.h + pv/view/cursorheader.h pv/view/header.h pv/view/logicsignal.h pv/view/marginwidget.h diff --git a/pv/view/cursorheader.cpp b/pv/view/cursorheader.cpp new file mode 100644 index 00000000..d1660276 --- /dev/null +++ b/pv/view/cursorheader.cpp @@ -0,0 +1,127 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "cursorheader.h" + +#include "view.h" + +#include +#include + +#include + +using std::shared_ptr; + +namespace pv { +namespace view { + +const int CursorHeader::CursorHeaderHeight = 26; + +CursorHeader::CursorHeader(View &parent) : + MarginWidget(parent), + _dragging(false) +{ + setMouseTracking(true); +} + +QSize CursorHeader::sizeHint() const +{ + return QSize(0, CursorHeaderHeight); +} + +void CursorHeader::clear_selection() +{ + CursorPair &cursors = _view.cursors(); + cursors.first()->select(false); + cursors.second()->select(false); + update(); +} + +void CursorHeader::paintEvent(QPaintEvent*) +{ + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + + // Draw the cursors + if (_view.cursors_shown()) { + _view.cursors().draw_markers(p, rect(), 0); //prefix); + } +} + +void CursorHeader::mouseMoveEvent(QMouseEvent *e) +{ + if (!(e->buttons() & Qt::LeftButton)) + return; + + if ((e->pos() - _mouse_down_point).manhattanLength() < + QApplication::startDragDistance()) + return; + + _dragging = true; + + if (shared_ptr m = _grabbed_marker.lock()) + m->set_time(_view.offset() + + ((double)e->x() + 0.5) * _view.scale()); +} + +void CursorHeader::mousePressEvent(QMouseEvent *e) +{ + if (e->buttons() & Qt::LeftButton) { + _mouse_down_point = e->pos(); + + _grabbed_marker.reset(); + + clear_selection(); + + if (_view.cursors_shown()) { + CursorPair &cursors = _view.cursors(); + if (cursors.first()->get_label_rect( + rect()).contains(e->pos())) + _grabbed_marker = cursors.first(); + else if (cursors.second()->get_label_rect( + rect()).contains(e->pos())) + _grabbed_marker = cursors.second(); + } + + if (shared_ptr m = _grabbed_marker.lock()) + m->select(); + + selection_changed(); + } +} + +void CursorHeader::mouseReleaseEvent(QMouseEvent *) +{ + using pv::widgets::Popup; + + if (!_dragging) + if (shared_ptr m = _grabbed_marker.lock()) { + Popup *const p = m->create_popup(&_view); + p->set_position(mapToGlobal(QPoint(m->get_x(), + height())), Popup::Bottom); + p->show(); + } + + _dragging = false; + _grabbed_marker.reset(); +} + +} // namespace view +} // namespace pv diff --git a/pv/view/cursorheader.h b/pv/view/cursorheader.h new file mode 100644 index 00000000..bab25191 --- /dev/null +++ b/pv/view/cursorheader.h @@ -0,0 +1,64 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2012 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PULSEVIEW_PV_VIEW_CURSORHEADER_H +#define PULSEVIEW_PV_VIEW_CURSORHEADER_H + +#include + +#include "marginwidget.h" + +namespace pv { +namespace view { + +class TimeMarker; + +/** + * Widget to hold the labels over the cursors. + */ +class CursorHeader : public MarginWidget +{ + Q_OBJECT + +public: + CursorHeader(View &parent); + + QSize sizeHint() const; + + void clear_selection(); + +private: + void paintEvent(QPaintEvent *event); + + void mouseMoveEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *); + + static const int CursorHeaderHeight; + + std::weak_ptr _grabbed_marker; + QPoint _mouse_down_point; + bool _dragging; +}; + +} // namespace view +} // namespace pv + +#endif // PULSEVIEW_PV_VIEW_CURSORHEADER_H diff --git a/pv/view/marginwidget.cpp b/pv/view/marginwidget.cpp index 539551dd..063dc9fd 100644 --- a/pv/view/marginwidget.cpp +++ b/pv/view/marginwidget.cpp @@ -31,5 +31,9 @@ MarginWidget::MarginWidget(View &parent) : { } +void MarginWidget::clear_selection() +{ +} + } // namespace view } // namespace pv diff --git a/pv/view/marginwidget.h b/pv/view/marginwidget.h index 42dffa7a..89eb3de1 100644 --- a/pv/view/marginwidget.h +++ b/pv/view/marginwidget.h @@ -36,7 +36,7 @@ public: MarginWidget(pv::view::View &parent); public slots: - virtual void clear_selection() = 0; + virtual void clear_selection(); signals: void selection_changed(); diff --git a/pv/view/ruler.cpp b/pv/view/ruler.cpp index 934b0a67..86f73f95 100644 --- a/pv/view/ruler.cpp +++ b/pv/view/ruler.cpp @@ -20,22 +20,12 @@ #include "ruler.h" -#include "cursor.h" #include "view.h" -#include "viewport.h" #include "pv/util.h" #include -#include -#include -#include -#include - -#include - using namespace Qt; -using std::shared_ptr; namespace pv { namespace view { @@ -47,8 +37,7 @@ const int Ruler::ScaleUnits[3] = {1, 2, 5}; const int Ruler::HoverArrowSize = 5; Ruler::Ruler(View &parent) : - MarginWidget(parent), - _dragging(false) + MarginWidget(parent) { setMouseTracking(true); @@ -56,15 +45,6 @@ Ruler::Ruler(View &parent) : this, SLOT(hover_point_changed())); } -void Ruler::clear_selection() -{ - CursorPair &cursors = _view.cursors(); - cursors.first()->select(false); - cursors.second()->select(false); - update(); -} - - QSize Ruler::sizeHint() const { return QSize(0, RulerHeight); @@ -72,7 +52,6 @@ QSize Ruler::sizeHint() const void Ruler::paintEvent(QPaintEvent*) { - const double SpacingIncrement = 32.0f; const double MinValueSpacing = 32.0f; const int ValueMargin = 3; @@ -156,80 +135,15 @@ void Ruler::paintEvent(QPaintEvent*) } while (x < width()); - // Draw the cursors - if (_view.cursors_shown()) - _view.cursors().draw_markers(p, rect(), prefix); - // Draw the hover mark draw_hover_mark(p); - - p.end(); -} - -void Ruler::mouseMoveEvent(QMouseEvent *e) -{ - if (!(e->buttons() & Qt::LeftButton)) - return; - - if ((e->pos() - _mouse_down_point).manhattanLength() < - QApplication::startDragDistance()) - return; - - _dragging = true; - - if (shared_ptr m = _grabbed_marker.lock()) - m->set_time(_view.offset() + - ((double)e->x() + 0.5) * _view.scale()); -} - -void Ruler::mousePressEvent(QMouseEvent *e) -{ - if (e->buttons() & Qt::LeftButton) - { - _mouse_down_point = e->pos(); - - _grabbed_marker.reset(); - - clear_selection(); - - if (_view.cursors_shown()) { - CursorPair &cursors = _view.cursors(); - if (cursors.first()->get_label_rect( - rect()).contains(e->pos())) - _grabbed_marker = cursors.first(); - else if (cursors.second()->get_label_rect( - rect()).contains(e->pos())) - _grabbed_marker = cursors.second(); - } - - if (shared_ptr m = _grabbed_marker.lock()) - m->select(); - - selection_changed(); - } -} - -void Ruler::mouseReleaseEvent(QMouseEvent *) -{ - using pv::widgets::Popup; - - if (!_dragging) - if (shared_ptr m = _grabbed_marker.lock()) { - Popup *const p = m->create_popup(&_view); - p->set_position(mapToGlobal(QPoint(m->get_x(), - height())), Popup::Bottom); - p->show(); - } - - _dragging = false; - _grabbed_marker.reset(); } void Ruler::draw_hover_mark(QPainter &p) { const int x = _view.hover_point().x(); - if (x == -1 || _dragging) + if (x == -1) return; p.setPen(QPen(Qt::NoPen)); diff --git a/pv/view/ruler.h b/pv/view/ruler.h index e7575db1..cee76c68 100644 --- a/pv/view/ruler.h +++ b/pv/view/ruler.h @@ -28,9 +28,6 @@ namespace pv { namespace view { -class TimeMarker; -class View; - class Ruler : public MarginWidget { Q_OBJECT @@ -45,18 +42,12 @@ private: public: Ruler(View &parent); - void clear_selection(); - public: QSize sizeHint() const; private: void paintEvent(QPaintEvent *event); - void mouseMoveEvent(QMouseEvent *e); - void mousePressEvent(QMouseEvent *e); - void mouseReleaseEvent(QMouseEvent *); - private: /** * Draw a hover arrow under the cursor position. @@ -65,11 +56,6 @@ private: private slots: void hover_point_changed(); - -private: - std::weak_ptr _grabbed_marker; - QPoint _mouse_down_point; - bool _dragging; }; } // namespace view diff --git a/pv/view/view.cpp b/pv/view/view.cpp index d33d4ec9..6c7df488 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -30,6 +30,7 @@ #include #include +#include "cursorheader.h" #include "decodetrace.h" #include "header.h" #include "ruler.h" @@ -74,6 +75,7 @@ View::View(SigSession &session, QWidget *parent) : _session(session), _viewport(new Viewport(*this)), _ruler(new Ruler(*this)), + _cursorheader(new CursorHeader(*this)), _header(new Header(*this)), _scale(1e-6), _offset(0), @@ -106,24 +108,28 @@ View::View(SigSession &session, QWidget *parent) : this, SLOT(on_signals_moved())); connect(_header, SIGNAL(selection_changed()), - _ruler, SLOT(clear_selection())); - connect(_ruler, SIGNAL(selection_changed()), + _cursorheader, SLOT(clear_selection())); + connect(_cursorheader, SIGNAL(selection_changed()), _header, SLOT(clear_selection())); connect(_header, SIGNAL(selection_changed()), this, SIGNAL(selection_changed())); - connect(_ruler, SIGNAL(selection_changed()), + connect(_cursorheader, SIGNAL(selection_changed()), this, SIGNAL(selection_changed())); setViewport(_viewport); _viewport->installEventFilter(this); _ruler->installEventFilter(this); + _cursorheader->installEventFilter(this); _header->installEventFilter(this); // Trigger the initial event manually. The default device has signals // which were created before this object came into being signals_changed(); + + // make sure the cursorheader is over the ruler + _cursorheader->raise(); } SigSession& View::session() @@ -213,6 +219,7 @@ void View::set_scale_offset(double scale, double offset) update_scroll(); _ruler->update(); + _cursorheader->update(); _viewport->update(); scale_offset_changed(); } @@ -305,7 +312,7 @@ bool View::cursors_shown() const void View::show_cursors(bool show) { _show_cursors = show; - _ruler->update(); + _cursorheader->update(); _viewport->update(); } @@ -314,7 +321,7 @@ void View::centre_cursors() const double time_width = _scale * _viewport->width(); _cursors.first()->set_time(_offset + time_width * 0.4); _cursors.second()->set_time(_offset + time_width * 0.6); - _ruler->update(); + _cursorheader->update(); _viewport->update(); } @@ -409,6 +416,10 @@ void View::update_layout() _ruler->sizeHint().height(), 0, 0); _ruler->setGeometry(_viewport->x(), 0, _viewport->width(), _viewport->y()); + _cursorheader->setGeometry( + _viewport->x(), + _ruler->sizeHint().height() - _cursorheader->sizeHint().height() / 2, + _viewport->width(), _cursorheader->sizeHint().height()); _header->setGeometry(0, _viewport->y(), _viewport->x(), _viewport->height()); update_scroll(); @@ -430,7 +441,7 @@ bool View::eventFilter(QObject *object, QEvent *event) const QMouseEvent *const mouse_event = (QMouseEvent*)event; if (object == _viewport) _hover_point = mouse_event->pos(); - else if (object == _ruler) + else if (object == _ruler || object == _cursorheader) _hover_point = QPoint(mouse_event->x(), 0); else if (object == _header) _hover_point = QPoint(0, mouse_event->y()); @@ -483,6 +494,7 @@ void View::h_scroll_value_changed(int value) } _ruler->update(); + _cursorheader->update(); _viewport->update(); } @@ -518,7 +530,7 @@ void View::data_updated() void View::marker_time_changed() { - _ruler->update(); + _cursorheader->update(); _viewport->update(); } diff --git a/pv/view/view.h b/pv/view/view.h index 83a6fe2d..85e990f7 100644 --- a/pv/view/view.h +++ b/pv/view/view.h @@ -40,6 +40,7 @@ class SigSession; namespace view { +class CursorHeader; class Header; class Ruler; class Trace; @@ -189,6 +190,7 @@ private: Viewport *_viewport; Ruler *_ruler; + CursorHeader *_cursorheader; Header *_header; /// The view time scale in seconds per pixel.