##// END OF EJS Templates
Moves the class DragDropScroller in its own file
trabillard -
r885:dd73a5040007
parent child
Show More
@@ -0,0 +1,32
1 #ifndef SCIQLOP_DRAGDROPSCROLLER_H
2 #define SCIQLOP_DRAGDROPSCROLLER_H
3
4 #include <Common/spimpl.h>
5 #include <QScrollArea>
6
7 /**
8 * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation.
9 * @note A QScrollArea inside an other QScrollArea is not fully supported.
10 */
11 class DragDropScroller : public QObject {
12 Q_OBJECT
13
14 public:
15 DragDropScroller(QObject *parent = nullptr);
16
17 void addScrollArea(QScrollArea *scrollArea);
18 void removeScrollArea(QScrollArea *scrollArea);
19
20 protected:
21 bool eventFilter(QObject *obj, QEvent *event);
22
23 private:
24 class DragDropScrollerPrivate;
25 spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl;
26
27 private slots:
28 void onTimer();
29 };
30
31
32 #endif // SCIQLOP_DRAGDROPSCROLLER_H
@@ -0,0 +1,125
1 #include "DragAndDrop/DragDropScroller.h"
2
3 #include <QDragEnterEvent>
4 #include <QDragMoveEvent>
5 #include <QScrollBar>
6 #include <QTimer>
7
8 const int SCROLL_SPEED = 5;
9 const int SCROLL_ZONE_SIZE = 50;
10
11 struct DragDropScroller::DragDropScrollerPrivate {
12
13 QList<QScrollArea *> m_ScrollAreas;
14 QScrollArea *m_CurrentScrollArea = nullptr;
15 std::unique_ptr<QTimer> m_Timer = nullptr;
16
17 enum class ScrollDirection { up, down, unknown };
18 ScrollDirection m_Direction = ScrollDirection::unknown;
19
20 explicit DragDropScrollerPrivate() : m_Timer{std::make_unique<QTimer>()}
21 {
22 m_Timer->setInterval(0);
23 }
24 };
25
26 DragDropScroller::DragDropScroller(QObject *parent)
27 : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()}
28 {
29 connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer);
30 }
31
32 void DragDropScroller::addScrollArea(QScrollArea *scrollArea)
33 {
34 impl->m_ScrollAreas << scrollArea;
35 scrollArea->viewport()->setAcceptDrops(true);
36 }
37
38 void DragDropScroller::removeScrollArea(QScrollArea *scrollArea)
39 {
40 impl->m_ScrollAreas.removeAll(scrollArea);
41 scrollArea->viewport()->setAcceptDrops(false);
42 }
43
44 bool DragDropScroller::eventFilter(QObject *obj, QEvent *event)
45 {
46 if (event->type() == QEvent::DragMove) {
47 auto w = static_cast<QWidget *>(obj);
48
49 if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) {
50 auto moveEvent = static_cast<QDragMoveEvent *>(event);
51
52 auto pos = moveEvent->pos();
53 if (impl->m_CurrentScrollArea->viewport() != w) {
54 auto globalPos = w->mapToGlobal(moveEvent->pos());
55 pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos);
56 }
57
58 auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height()
59 - SCROLL_ZONE_SIZE;
60 auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE;
61
62 if (!isInTopZone && !isInBottomZone) {
63 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
64 impl->m_Timer->stop();
65 }
66 else if (!impl->m_Timer->isActive()) {
67 impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up
68 : DragDropScrollerPrivate::ScrollDirection::down;
69 impl->m_Timer->start();
70 }
71 }
72 }
73 else if (event->type() == QEvent::DragEnter) {
74 auto w = static_cast<QWidget *>(obj);
75
76 for (auto scrollArea : impl->m_ScrollAreas) {
77 if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) {
78 auto enterEvent = static_cast<QDragEnterEvent *>(event);
79 enterEvent->acceptProposedAction();
80 enterEvent->setDropAction(Qt::IgnoreAction);
81 impl->m_CurrentScrollArea = scrollArea;
82 break;
83 }
84 }
85 }
86 else if (event->type() == QEvent::DragLeave) {
87 if (impl->m_CurrentScrollArea) {
88 if (!QRect(QPoint(), impl->m_CurrentScrollArea->size())
89 .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) {
90 impl->m_CurrentScrollArea = nullptr;
91 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
92 impl->m_Timer->stop();
93 }
94 }
95 }
96 else if (event->type() == QEvent::Drop) {
97 if (impl->m_CurrentScrollArea) {
98 impl->m_CurrentScrollArea = nullptr;
99 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
100 impl->m_Timer->stop();
101 }
102 }
103
104 return false;
105 }
106
107 void DragDropScroller::onTimer()
108 {
109 if (impl->m_CurrentScrollArea) {
110 auto mvt = 0;
111 switch (impl->m_Direction) {
112 case DragDropScrollerPrivate::ScrollDirection::up:
113 mvt = SCROLL_SPEED;
114 break;
115 case DragDropScrollerPrivate::ScrollDirection::down:
116 mvt = -SCROLL_SPEED;
117 break;
118 default:
119 break;
120 }
121
122 impl->m_CurrentScrollArea->verticalScrollBar()->setValue(
123 impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt);
124 }
125 }
@@ -64,28 +64,4 private:
64 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
64 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
65 };
65 };
66
66
67 /**
68 * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation.
69 * @note A QScrollArea inside an other QScrollArea is not fully supported.
70 */
71 class DragDropScroller : public QObject {
72 Q_OBJECT
73
74 public:
75 DragDropScroller(QObject *parent = nullptr);
76
77 void addScrollArea(QScrollArea *scrollArea);
78 void removeScrollArea(QScrollArea *scrollArea);
79
80 protected:
81 bool eventFilter(QObject *obj, QEvent *event);
82
83 private:
84 class DragDropScrollerPrivate;
85 spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl;
86
87 private slots:
88 void onTimer();
89 };
90
91 #endif // SCIQLOP_DRAGDROPHELPER_H
67 #endif // SCIQLOP_DRAGDROPHELPER_H
@@ -7,6 +7,7 gui_moc_headers = [
7 'include/SidePane/SqpSidePane.h',
7 'include/SidePane/SqpSidePane.h',
8 'include/SqpApplication.h',
8 'include/SqpApplication.h',
9 'include/DragAndDrop/DragDropHelper.h',
9 'include/DragAndDrop/DragDropHelper.h',
10 'include/DragAndDrop/DragDropScroller.h',
10 'include/TimeWidget/TimeWidget.h',
11 'include/TimeWidget/TimeWidget.h',
11 'include/Variable/VariableInspectorWidget.h',
12 'include/Variable/VariableInspectorWidget.h',
12 'include/Variable/VariableInspectorTableView.h',
13 'include/Variable/VariableInspectorTableView.h',
@@ -44,6 +45,7 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
44 gui_sources = [
45 gui_sources = [
45 'src/SqpApplication.cpp',
46 'src/SqpApplication.cpp',
46 'src/DragAndDrop/DragDropHelper.cpp',
47 'src/DragAndDrop/DragDropHelper.cpp',
48 'src/DragAndDrop/DragDropScroller.cpp',
47 'src/Common/ColorUtils.cpp',
49 'src/Common/ColorUtils.cpp',
48 'src/Common/VisualizationDef.cpp',
50 'src/Common/VisualizationDef.cpp',
49 'src/DataSource/DataSourceTreeWidgetItem.cpp',
51 'src/DataSource/DataSourceTreeWidgetItem.cpp',
@@ -1,4 +1,5
1 #include "DragAndDrop/DragDropHelper.h"
1 #include "DragAndDrop/DragDropHelper.h"
2 #include "DragAndDrop/DragDropScroller.h"
2 #include "SqpApplication.h"
3 #include "SqpApplication.h"
3 #include "Visualization/VisualizationDragDropContainer.h"
4 #include "Visualization/VisualizationDragDropContainer.h"
4 #include "Visualization/VisualizationDragWidget.h"
5 #include "Visualization/VisualizationDragWidget.h"
@@ -12,134 +13,13
12 #include "Common/VisualizationDef.h"
13 #include "Common/VisualizationDef.h"
13
14
14 #include <QDir>
15 #include <QDir>
15 #include <QDragEnterEvent>
16 #include <QDragMoveEvent>
17 #include <QLabel>
16 #include <QLabel>
18 #include <QScrollArea>
17 #include <QUrl>
19 #include <QScrollBar>
20 #include <QTimer>
21 #include <QVBoxLayout>
18 #include <QVBoxLayout>
22
19
23 const int SCROLL_SPEED = 5;
24 const int SCROLL_ZONE_SIZE = 50;
25
20
26 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper")
21 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper")
27
22
28 struct DragDropScroller::DragDropScrollerPrivate {
29
30 QList<QScrollArea *> m_ScrollAreas;
31 QScrollArea *m_CurrentScrollArea = nullptr;
32 std::unique_ptr<QTimer> m_Timer = nullptr;
33
34 enum class ScrollDirection { up, down, unknown };
35 ScrollDirection m_Direction = ScrollDirection::unknown;
36
37 explicit DragDropScrollerPrivate() : m_Timer{std::make_unique<QTimer>()}
38 {
39 m_Timer->setInterval(0);
40 }
41 };
42
43 DragDropScroller::DragDropScroller(QObject *parent)
44 : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()}
45 {
46 connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer);
47 }
48
49 void DragDropScroller::addScrollArea(QScrollArea *scrollArea)
50 {
51 impl->m_ScrollAreas << scrollArea;
52 scrollArea->viewport()->setAcceptDrops(true);
53 }
54
55 void DragDropScroller::removeScrollArea(QScrollArea *scrollArea)
56 {
57 impl->m_ScrollAreas.removeAll(scrollArea);
58 scrollArea->viewport()->setAcceptDrops(false);
59 }
60
61 bool DragDropScroller::eventFilter(QObject *obj, QEvent *event)
62 {
63 if (event->type() == QEvent::DragMove) {
64 auto w = static_cast<QWidget *>(obj);
65
66 if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) {
67 auto moveEvent = static_cast<QDragMoveEvent *>(event);
68
69 auto pos = moveEvent->pos();
70 if (impl->m_CurrentScrollArea->viewport() != w) {
71 auto globalPos = w->mapToGlobal(moveEvent->pos());
72 pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos);
73 }
74
75 auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height()
76 - SCROLL_ZONE_SIZE;
77 auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE;
78
79 if (!isInTopZone && !isInBottomZone) {
80 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
81 impl->m_Timer->stop();
82 }
83 else if (!impl->m_Timer->isActive()) {
84 impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up
85 : DragDropScrollerPrivate::ScrollDirection::down;
86 impl->m_Timer->start();
87 }
88 }
89 }
90 else if (event->type() == QEvent::DragEnter) {
91 auto w = static_cast<QWidget *>(obj);
92
93 for (auto scrollArea : impl->m_ScrollAreas) {
94 if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) {
95 auto enterEvent = static_cast<QDragEnterEvent *>(event);
96 enterEvent->acceptProposedAction();
97 enterEvent->setDropAction(Qt::IgnoreAction);
98 impl->m_CurrentScrollArea = scrollArea;
99 break;
100 }
101 }
102 }
103 else if (event->type() == QEvent::DragLeave) {
104 if (impl->m_CurrentScrollArea) {
105 if (!QRect(QPoint(), impl->m_CurrentScrollArea->size())
106 .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) {
107 impl->m_CurrentScrollArea = nullptr;
108 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
109 impl->m_Timer->stop();
110 }
111 }
112 }
113 else if (event->type() == QEvent::Drop) {
114 if (impl->m_CurrentScrollArea) {
115 impl->m_CurrentScrollArea = nullptr;
116 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
117 impl->m_Timer->stop();
118 }
119 }
120
121 return false;
122 }
123
124 void DragDropScroller::onTimer()
125 {
126 if (impl->m_CurrentScrollArea) {
127 auto mvt = 0;
128 switch (impl->m_Direction) {
129 case DragDropScrollerPrivate::ScrollDirection::up:
130 mvt = SCROLL_SPEED;
131 break;
132 case DragDropScrollerPrivate::ScrollDirection::down:
133 mvt = -SCROLL_SPEED;
134 break;
135 default:
136 break;
137 }
138
139 impl->m_CurrentScrollArea->verticalScrollBar()->setValue(
140 impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt);
141 }
142 }
143
23
144 struct DragDropHelper::DragDropHelperPrivate {
24 struct DragDropHelper::DragDropHelperPrivate {
145
25
General Comments 0
You need to be logged in to leave comments. Login now