From: Joel Holdsworth Date: Fri, 26 Dec 2014 23:42:53 +0000 (+0000) Subject: ViewWidget: Moved in mouse handlers X-Git-Tag: pulseview-0.3.0~301 X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=e9e4e5e7ea46132262fbd53f708dafc039b3b24f ViewWidget: Moved in mouse handlers --- diff --git a/pv/view/marginwidget.cpp b/pv/view/marginwidget.cpp index fcbb31bf..2d663cdc 100644 --- a/pv/view/marginwidget.cpp +++ b/pv/view/marginwidget.cpp @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include #include @@ -34,12 +33,15 @@ namespace pv { namespace view { MarginWidget::MarginWidget(View &parent) : - ViewWidget(parent), - dragging_(false) + ViewWidget(parent) { setAttribute(Qt::WA_NoSystemBackground, true); - setFocusPolicy(Qt::ClickFocus); - setMouseTracking(true); +} + +void MarginWidget::item_clicked(const shared_ptr &item) +{ + if (item && item->enabled()) + show_popup(item); } void MarginWidget::show_popup(const shared_ptr &item) @@ -49,116 +51,6 @@ void MarginWidget::show_popup(const shared_ptr &item) p->show(); } -void MarginWidget::mouse_left_press_event(QMouseEvent *event) -{ - (void)event; - - const bool ctrl_pressed = - QApplication::keyboardModifiers() & Qt::ControlModifier; - - // Clear selection if control is not pressed and this item is unselected - if ((!mouse_down_item_ || !mouse_down_item_->selected()) && - !ctrl_pressed) - clear_selection(); - - // Set the signal selection state if the item has been clicked - if (mouse_down_item_) { - if (ctrl_pressed) - mouse_down_item_->select(!mouse_down_item_->selected()); - else - mouse_down_item_->select(true); - } - - // Save the offsets of any signals which will be dragged - const auto items = this->items(); - for (auto &i : items) - if (i->selected()) - i->drag(); - - selection_changed(); - update(); -} - -void MarginWidget::mouse_left_release_event(QMouseEvent *event) -{ - assert(event); - - auto items = this->items(); - const bool ctrl_pressed = - QApplication::keyboardModifiers() & Qt::ControlModifier; - - // Unselect everything if control is not pressed - const shared_ptr mouse_over = - get_mouse_over_item(event->pos()); - - for (auto &i : items) - i->drag_release(); - - if (dragging_) - view_.restack_all_row_items(); - else - { - if (!ctrl_pressed) { - for (shared_ptr i : items) - if (mouse_down_item_ != i) - i->select(false); - - if (mouse_down_item_) - show_popup(mouse_down_item_); - } - } - - dragging_ = false; -} - -void MarginWidget::mousePressEvent(QMouseEvent *event) -{ - assert(event); - - mouse_down_point_ = event->pos(); - mouse_down_item_ = get_mouse_over_item(event->pos()); - - if (event->button() & Qt::LeftButton) - mouse_left_press_event(event); -} - -void MarginWidget::mouseReleaseEvent(QMouseEvent *event) -{ - assert(event); - if (event->button() & Qt::LeftButton) - mouse_left_release_event(event); - - mouse_down_item_ = nullptr; -} - -void MarginWidget::mouseMoveEvent(QMouseEvent *event) -{ - assert(event); - mouse_point_ = event->pos(); - - if (!(event->buttons() & Qt::LeftButton)) - return; - - if ((event->pos() - mouse_down_point_).manhattanLength() < - QApplication::startDragDistance()) - return; - - if (!accept_drag()) - return; - - // Do the drag - dragging_ = true; - drag_items(event->pos() - mouse_down_point_); - - update(); -} - -void MarginWidget::leaveEvent(QEvent*) -{ - mouse_point_ = QPoint(-1, -1); - update(); -} - void MarginWidget::contextMenuEvent(QContextMenuEvent *event) { const shared_ptr r = get_mouse_over_item(mouse_point_); @@ -183,13 +75,5 @@ void MarginWidget::keyPressEvent(QKeyEvent *e) } } -void MarginWidget::clear_selection() -{ - const auto items = this->items(); - for (auto &i : items) - i->select(false); - update(); -} - } // namespace view } // namespace pv diff --git a/pv/view/marginwidget.hpp b/pv/view/marginwidget.hpp index 029d68e5..0a24ad2e 100644 --- a/pv/view/marginwidget.hpp +++ b/pv/view/marginwidget.hpp @@ -48,18 +48,11 @@ public: protected: /** - * Gets the items in the margin widget. + * Indicates the event an a view item has been clicked. + * @param item the view item that has been clicked. */ - virtual std::vector< std::shared_ptr > items() = 0; - - /** - * Gets the first view item which has a label that contains @c pt . - * @param pt the point to search with. - * @return the view item that has been found, or and empty - * @c shared_ptr if no item was found. - */ - virtual std::shared_ptr get_mouse_over_item( - const QPoint &pt) = 0; + virtual void item_clicked( + const std::shared_ptr &item); /** * Shows the popup of a the specified @c ViewItem . @@ -67,40 +60,10 @@ protected: */ void show_popup(const std::shared_ptr &item); - /** - * Handles left mouse button press events. - * @param event the mouse event that triggered this handler. - */ - void mouse_left_press_event(QMouseEvent *event); - - /** - * Handles left mouse button release events. - * @param event the mouse event that triggered this handler. - */ - void mouse_left_release_event(QMouseEvent *event); - protected: - void mousePressEvent(QMouseEvent * event); - void mouseReleaseEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - - void leaveEvent(QEvent *event); - virtual void contextMenuEvent(QContextMenuEvent *event); virtual void keyPressEvent(QKeyEvent *e); - -public Q_SLOTS: - void clear_selection(); - -Q_SIGNALS: - void selection_changed(); - -protected: - QPoint mouse_point_; - QPoint mouse_down_point_; - std::shared_ptr mouse_down_item_; - bool dragging_; }; } // namespace view diff --git a/pv/view/viewport.cpp b/pv/view/viewport.cpp index c33af44b..83df7aa4 100644 --- a/pv/view/viewport.cpp +++ b/pv/view/viewport.cpp @@ -32,6 +32,8 @@ #include using std::abs; +using std::back_inserter; +using std::copy; using std::max; using std::min; using std::none_of; @@ -53,6 +55,24 @@ Viewport::Viewport(View &parent) : setBackgroundRole(QPalette::Base); } +shared_ptr Viewport::get_mouse_over_item(const QPoint &pt) +{ + const vector< shared_ptr > items(this->items()); + for (auto i = items.rbegin(); i != items.rend(); i++) + if ((*i)->enabled() && + (*i)->hit_box_rect(rect()).contains(pt)) + return *i; + return nullptr; +} + +vector< shared_ptr > Viewport::items() +{ + vector< shared_ptr > items(view_.begin(), view_.end()); + const vector< shared_ptr > time_items(view_.time_items()); + copy(time_items.begin(), time_items.end(), back_inserter(items)); + return items; +} + void Viewport::paintEvent(QPaintEvent*) { vector< shared_ptr > row_items(view_.begin(), view_.end()); diff --git a/pv/view/viewport.hpp b/pv/view/viewport.hpp index 3cc59c94..be3e7d32 100644 --- a/pv/view/viewport.hpp +++ b/pv/view/viewport.hpp @@ -42,10 +42,23 @@ class Viewport : public ViewWidget public: explicit Viewport(View &parent); -protected: +private: + /** + * Gets the first view item which has a hit-box that contains @c pt . + * @param pt the point to search with. + * @return the view item that has been found, or and empty + * @c shared_ptr if no item was found. + */ + std::shared_ptr get_mouse_over_item( + const QPoint &pt); + + /** + * Gets the items in the view widget. + */ + std::vector< std::shared_ptr > items(); + void paintEvent(QPaintEvent *event); -private: bool event(QEvent *event); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); diff --git a/pv/view/viewwidget.cpp b/pv/view/viewwidget.cpp index 9c4c56ff..0b3b2fd1 100644 --- a/pv/view/viewwidget.cpp +++ b/pv/view/viewwidget.cpp @@ -18,10 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include +#include #include "rowitem.hpp" -#include "timeitem.hpp" #include "view.hpp" #include "viewwidget.hpp" @@ -34,8 +34,24 @@ namespace view { ViewWidget::ViewWidget(View &parent) : QWidget(&parent), - view_(parent) + view_(parent), + dragging_(false) { + setFocusPolicy(Qt::ClickFocus); + setMouseTracking(true); +} + +void ViewWidget::clear_selection() +{ + const auto items = this->items(); + for (auto &i : items) + i->select(false); + update(); +} + +void ViewWidget::item_clicked(const shared_ptr &item) +{ + (void)item; } bool ViewWidget::accept_drag() const @@ -96,5 +112,115 @@ void ViewWidget::drag_items(const QPoint &delta) i->drag_by(delta); } +void ViewWidget::mouse_left_press_event(QMouseEvent *event) +{ + (void)event; + + const bool ctrl_pressed = + QApplication::keyboardModifiers() & Qt::ControlModifier; + + // Clear selection if control is not pressed and this item is unselected + if ((!mouse_down_item_ || !mouse_down_item_->selected()) && + !ctrl_pressed) + clear_selection(); + + // Set the signal selection state if the item has been clicked + if (mouse_down_item_) { + if (ctrl_pressed) + mouse_down_item_->select(!mouse_down_item_->selected()); + else + mouse_down_item_->select(true); + } + + // Save the offsets of any signals which will be dragged + const auto items = this->items(); + for (auto &i : items) + if (i->selected()) + i->drag(); + + selection_changed(); + update(); +} + +void ViewWidget::mouse_left_release_event(QMouseEvent *event) +{ + assert(event); + + auto items = this->items(); + const bool ctrl_pressed = + QApplication::keyboardModifiers() & Qt::ControlModifier; + + // Unselect everything if control is not pressed + const shared_ptr mouse_over = + get_mouse_over_item(event->pos()); + + for (auto &i : items) + i->drag_release(); + + if (dragging_) + view_.restack_all_row_items(); + else + { + if (!ctrl_pressed) { + for (shared_ptr i : items) + if (mouse_down_item_ != i) + i->select(false); + + if (mouse_down_item_) + item_clicked(mouse_down_item_); + } + } + + dragging_ = false; +} + +void ViewWidget::mousePressEvent(QMouseEvent *event) +{ + assert(event); + + mouse_down_point_ = event->pos(); + mouse_down_item_ = get_mouse_over_item(event->pos()); + + if (event->button() & Qt::LeftButton) + mouse_left_press_event(event); +} + +void ViewWidget::mouseReleaseEvent(QMouseEvent *event) +{ + assert(event); + if (event->button() & Qt::LeftButton) + mouse_left_release_event(event); + + mouse_down_item_ = nullptr; +} + +void ViewWidget::mouseMoveEvent(QMouseEvent *event) +{ + assert(event); + mouse_point_ = event->pos(); + + if (!(event->buttons() & Qt::LeftButton)) + return; + + if ((event->pos() - mouse_down_point_).manhattanLength() < + QApplication::startDragDistance()) + return; + + if (!accept_drag()) + return; + + // Do the drag + dragging_ = true; + drag_items(event->pos() - mouse_down_point_); + + update(); +} + +void ViewWidget::leaveEvent(QEvent*) +{ + mouse_point_ = QPoint(-1, -1); + update(); +} + } // namespace view } // namespace pv diff --git a/pv/view/viewwidget.hpp b/pv/view/viewwidget.hpp index 3b22441a..fc724762 100644 --- a/pv/view/viewwidget.hpp +++ b/pv/view/viewwidget.hpp @@ -21,12 +21,15 @@ #ifndef PULSEVIEW_PV_VIEWWIDGET_H #define PULSEVIEW_PV_VIEWWIDGET_H +#include + #include namespace pv { namespace view { class View; +class ViewItem; class ViewWidget : public QWidget { @@ -35,6 +38,14 @@ class ViewWidget : public QWidget protected: ViewWidget(View &parent); + /** + * Indicates the event an a view item has been clicked. + * @param item the view item that has been clicked. + * @remarks the default implementation does nothing. + */ + virtual void item_clicked( + const std::shared_ptr &item); + /** * Returns true if the selection of row items allows dragging. * @return Returns true if the drag is acceptable. @@ -47,8 +58,51 @@ protected: */ void drag_items(const QPoint &delta); + /** + * Gets the items in the view widget. + */ + virtual std::vector< std::shared_ptr > items() = 0; + + /** + * Gets the first view item which has a hit-box that contains @c pt . + * @param pt the point to search with. + * @return the view item that has been found, or and empty + * @c shared_ptr if no item was found. + */ + virtual std::shared_ptr get_mouse_over_item( + const QPoint &pt) = 0; + + /** + * Handles left mouse button press events. + * @param event the mouse event that triggered this handler. + */ + void mouse_left_press_event(QMouseEvent *event); + + /** + * Handles left mouse button release events. + * @param event the mouse event that triggered this handler. + */ + void mouse_left_release_event(QMouseEvent *event); + +protected: + void mousePressEvent(QMouseEvent * event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + void leaveEvent(QEvent *event); + +public Q_SLOTS: + void clear_selection(); + +Q_SIGNALS: + void selection_changed(); + protected: pv::view::View &view_; + QPoint mouse_point_; + QPoint mouse_down_point_; + std::shared_ptr mouse_down_item_; + bool dragging_; }; } // namespace view