From dd73a5040007bfd14aa54b0c6874e4c93b563379 2017-11-06 15:58:12 From: Thibaud Rabillard Date: 2017-11-06 15:58:12 Subject: [PATCH] Moves the class DragDropScroller in its own file --- diff --git a/gui/include/DragAndDrop/DragDropHelper.h b/gui/include/DragAndDrop/DragDropHelper.h index f33fdba..2c116f7 100644 --- a/gui/include/DragAndDrop/DragDropHelper.h +++ b/gui/include/DragAndDrop/DragDropHelper.h @@ -64,28 +64,4 @@ private: spimpl::unique_impl_ptr impl; }; -/** - * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation. - * @note A QScrollArea inside an other QScrollArea is not fully supported. - */ -class DragDropScroller : public QObject { - Q_OBJECT - -public: - DragDropScroller(QObject *parent = nullptr); - - void addScrollArea(QScrollArea *scrollArea); - void removeScrollArea(QScrollArea *scrollArea); - -protected: - bool eventFilter(QObject *obj, QEvent *event); - -private: - class DragDropScrollerPrivate; - spimpl::unique_impl_ptr impl; - -private slots: - void onTimer(); -}; - #endif // SCIQLOP_DRAGDROPHELPER_H diff --git a/gui/include/DragAndDrop/DragDropScroller.h b/gui/include/DragAndDrop/DragDropScroller.h new file mode 100644 index 0000000..eb84baf --- /dev/null +++ b/gui/include/DragAndDrop/DragDropScroller.h @@ -0,0 +1,32 @@ +#ifndef SCIQLOP_DRAGDROPSCROLLER_H +#define SCIQLOP_DRAGDROPSCROLLER_H + +#include +#include + +/** + * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation. + * @note A QScrollArea inside an other QScrollArea is not fully supported. + */ +class DragDropScroller : public QObject { + Q_OBJECT + +public: + DragDropScroller(QObject *parent = nullptr); + + void addScrollArea(QScrollArea *scrollArea); + void removeScrollArea(QScrollArea *scrollArea); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: + class DragDropScrollerPrivate; + spimpl::unique_impl_ptr impl; + +private slots: + void onTimer(); +}; + + +#endif // SCIQLOP_DRAGDROPSCROLLER_H diff --git a/gui/meson.build b/gui/meson.build index d372234..2c6d92d 100644 --- a/gui/meson.build +++ b/gui/meson.build @@ -7,6 +7,7 @@ gui_moc_headers = [ 'include/SidePane/SqpSidePane.h', 'include/SqpApplication.h', 'include/DragAndDrop/DragDropHelper.h', + 'include/DragAndDrop/DragDropScroller.h', 'include/TimeWidget/TimeWidget.h', 'include/Variable/VariableInspectorWidget.h', 'include/Variable/VariableInspectorTableView.h', @@ -44,6 +45,7 @@ gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers, gui_sources = [ 'src/SqpApplication.cpp', 'src/DragAndDrop/DragDropHelper.cpp', + 'src/DragAndDrop/DragDropScroller.cpp', 'src/Common/ColorUtils.cpp', 'src/Common/VisualizationDef.cpp', 'src/DataSource/DataSourceTreeWidgetItem.cpp', diff --git a/gui/src/DragAndDrop/DragDropHelper.cpp b/gui/src/DragAndDrop/DragDropHelper.cpp index 37b296b..dd95d42 100644 --- a/gui/src/DragAndDrop/DragDropHelper.cpp +++ b/gui/src/DragAndDrop/DragDropHelper.cpp @@ -1,4 +1,5 @@ #include "DragAndDrop/DragDropHelper.h" +#include "DragAndDrop/DragDropScroller.h" #include "SqpApplication.h" #include "Visualization/VisualizationDragDropContainer.h" #include "Visualization/VisualizationDragWidget.h" @@ -12,134 +13,13 @@ #include "Common/VisualizationDef.h" #include -#include -#include #include -#include -#include -#include +#include #include -const int SCROLL_SPEED = 5; -const int SCROLL_ZONE_SIZE = 50; Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper") -struct DragDropScroller::DragDropScrollerPrivate { - - QList m_ScrollAreas; - QScrollArea *m_CurrentScrollArea = nullptr; - std::unique_ptr m_Timer = nullptr; - - enum class ScrollDirection { up, down, unknown }; - ScrollDirection m_Direction = ScrollDirection::unknown; - - explicit DragDropScrollerPrivate() : m_Timer{std::make_unique()} - { - m_Timer->setInterval(0); - } -}; - -DragDropScroller::DragDropScroller(QObject *parent) - : QObject{parent}, impl{spimpl::make_unique_impl()} -{ - connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer); -} - -void DragDropScroller::addScrollArea(QScrollArea *scrollArea) -{ - impl->m_ScrollAreas << scrollArea; - scrollArea->viewport()->setAcceptDrops(true); -} - -void DragDropScroller::removeScrollArea(QScrollArea *scrollArea) -{ - impl->m_ScrollAreas.removeAll(scrollArea); - scrollArea->viewport()->setAcceptDrops(false); -} - -bool DragDropScroller::eventFilter(QObject *obj, QEvent *event) -{ - if (event->type() == QEvent::DragMove) { - auto w = static_cast(obj); - - if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) { - auto moveEvent = static_cast(event); - - auto pos = moveEvent->pos(); - if (impl->m_CurrentScrollArea->viewport() != w) { - auto globalPos = w->mapToGlobal(moveEvent->pos()); - pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos); - } - - auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height() - - SCROLL_ZONE_SIZE; - auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE; - - if (!isInTopZone && !isInBottomZone) { - impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; - impl->m_Timer->stop(); - } - else if (!impl->m_Timer->isActive()) { - impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up - : DragDropScrollerPrivate::ScrollDirection::down; - impl->m_Timer->start(); - } - } - } - else if (event->type() == QEvent::DragEnter) { - auto w = static_cast(obj); - - for (auto scrollArea : impl->m_ScrollAreas) { - if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) { - auto enterEvent = static_cast(event); - enterEvent->acceptProposedAction(); - enterEvent->setDropAction(Qt::IgnoreAction); - impl->m_CurrentScrollArea = scrollArea; - break; - } - } - } - else if (event->type() == QEvent::DragLeave) { - if (impl->m_CurrentScrollArea) { - if (!QRect(QPoint(), impl->m_CurrentScrollArea->size()) - .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) { - impl->m_CurrentScrollArea = nullptr; - impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; - impl->m_Timer->stop(); - } - } - } - else if (event->type() == QEvent::Drop) { - if (impl->m_CurrentScrollArea) { - impl->m_CurrentScrollArea = nullptr; - impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; - impl->m_Timer->stop(); - } - } - - return false; -} - -void DragDropScroller::onTimer() -{ - if (impl->m_CurrentScrollArea) { - auto mvt = 0; - switch (impl->m_Direction) { - case DragDropScrollerPrivate::ScrollDirection::up: - mvt = SCROLL_SPEED; - break; - case DragDropScrollerPrivate::ScrollDirection::down: - mvt = -SCROLL_SPEED; - break; - default: - break; - } - - impl->m_CurrentScrollArea->verticalScrollBar()->setValue( - impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt); - } -} struct DragDropHelper::DragDropHelperPrivate { diff --git a/gui/src/DragAndDrop/DragDropScroller.cpp b/gui/src/DragAndDrop/DragDropScroller.cpp new file mode 100644 index 0000000..0e8ac8e --- /dev/null +++ b/gui/src/DragAndDrop/DragDropScroller.cpp @@ -0,0 +1,125 @@ +#include "DragAndDrop/DragDropScroller.h" + +#include +#include +#include +#include + +const int SCROLL_SPEED = 5; +const int SCROLL_ZONE_SIZE = 50; + +struct DragDropScroller::DragDropScrollerPrivate { + + QList m_ScrollAreas; + QScrollArea *m_CurrentScrollArea = nullptr; + std::unique_ptr m_Timer = nullptr; + + enum class ScrollDirection { up, down, unknown }; + ScrollDirection m_Direction = ScrollDirection::unknown; + + explicit DragDropScrollerPrivate() : m_Timer{std::make_unique()} + { + m_Timer->setInterval(0); + } +}; + +DragDropScroller::DragDropScroller(QObject *parent) + : QObject{parent}, impl{spimpl::make_unique_impl()} +{ + connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer); +} + +void DragDropScroller::addScrollArea(QScrollArea *scrollArea) +{ + impl->m_ScrollAreas << scrollArea; + scrollArea->viewport()->setAcceptDrops(true); +} + +void DragDropScroller::removeScrollArea(QScrollArea *scrollArea) +{ + impl->m_ScrollAreas.removeAll(scrollArea); + scrollArea->viewport()->setAcceptDrops(false); +} + +bool DragDropScroller::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::DragMove) { + auto w = static_cast(obj); + + if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) { + auto moveEvent = static_cast(event); + + auto pos = moveEvent->pos(); + if (impl->m_CurrentScrollArea->viewport() != w) { + auto globalPos = w->mapToGlobal(moveEvent->pos()); + pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos); + } + + auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height() + - SCROLL_ZONE_SIZE; + auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE; + + if (!isInTopZone && !isInBottomZone) { + impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; + impl->m_Timer->stop(); + } + else if (!impl->m_Timer->isActive()) { + impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up + : DragDropScrollerPrivate::ScrollDirection::down; + impl->m_Timer->start(); + } + } + } + else if (event->type() == QEvent::DragEnter) { + auto w = static_cast(obj); + + for (auto scrollArea : impl->m_ScrollAreas) { + if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) { + auto enterEvent = static_cast(event); + enterEvent->acceptProposedAction(); + enterEvent->setDropAction(Qt::IgnoreAction); + impl->m_CurrentScrollArea = scrollArea; + break; + } + } + } + else if (event->type() == QEvent::DragLeave) { + if (impl->m_CurrentScrollArea) { + if (!QRect(QPoint(), impl->m_CurrentScrollArea->size()) + .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) { + impl->m_CurrentScrollArea = nullptr; + impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; + impl->m_Timer->stop(); + } + } + } + else if (event->type() == QEvent::Drop) { + if (impl->m_CurrentScrollArea) { + impl->m_CurrentScrollArea = nullptr; + impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; + impl->m_Timer->stop(); + } + } + + return false; +} + +void DragDropScroller::onTimer() +{ + if (impl->m_CurrentScrollArea) { + auto mvt = 0; + switch (impl->m_Direction) { + case DragDropScrollerPrivate::ScrollDirection::up: + mvt = SCROLL_SPEED; + break; + case DragDropScrollerPrivate::ScrollDirection::down: + mvt = -SCROLL_SPEED; + break; + default: + break; + } + + impl->m_CurrentScrollArea->verticalScrollBar()->setValue( + impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt); + } +}